class-inl.h revision 3a0909248e04b22c3981cbf617bc2502ed5b6380
12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/* 22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project 32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License. 62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at 72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software 112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and 142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License. 152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */ 162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_CLASS_INL_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_CLASS_INL_H_ 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class.h" 212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "art_field-inl.h" 23e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method.h" 2498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "art_method-inl.h" 254f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "class_loader.h" 2623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko#include "common_throws.h" 274f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_cache.h" 28f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier#include "dex_file.h" 293b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi#include "gc/heap-inl.h" 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "iftable.h" 3154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier#include "length_prefixed_array.h" 3262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "object_array-inl.h" 3398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "read_barrier-inl.h" 344ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih#include "reference-inl.h" 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "string.h" 3780afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4225023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 43ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint32_t Class::GetObjectSize() { 443481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator. 453481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << " class=" << PrettyTypeOf(this); 46e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi return GetField32(ObjectSizeOffset()); 472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 49ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Class::GetSuperClass() { 502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Can only get super class for loaded classes (hack for when runtime is 512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // initializing) 52073278cd7129ff07dbcd6ccfabd2c34f47ec92adBrian Carlstrom DCHECK(IsLoaded() || IsErroneous() || !Runtime::Current()->IsStarted()) << IsLoaded(); 53b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_)); 542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 56ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ClassLoader* Class::GetClassLoader() { 57b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetFieldObject<ClassLoader>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_)); 584f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers} 594f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 60c2f4d0240b3a9b905dff5b546924865f15241481Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 61ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline DexCache* Class::GetDexCache() { 62b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetFieldObject<DexCache, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_)); 634f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers} 644f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 6554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtMethod>* Class::GetDirectMethodsPtr() { 662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 67e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDirectMethodsPtrUnchecked(); 682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtMethod>* Class::GetDirectMethodsPtrUnchecked() { 7154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>( 7254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier GetField64(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_))); 732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtMethod>* Class::GetVirtualMethodsPtrUnchecked() { 7654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>( 7754d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier GetField64(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_))); 782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 8054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetDirectMethodsPtr(LengthPrefixedArray<ArtMethod>* new_direct_methods) { 81e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(GetDirectMethodsPtrUnchecked() == nullptr); 82e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetDirectMethodsPtrUnchecked(new_direct_methods); 832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 8554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetDirectMethodsPtrUnchecked( 8654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtMethod>* new_direct_methods) { 87e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), 88e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier reinterpret_cast<uint64_t>(new_direct_methods)); 89e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 90e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 91e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetDirectMethodUnchecked(size_t i, size_t pointer_size) { 92e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 93e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* methods = GetDirectMethodsPtrUnchecked(); 94e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(methods != nullptr); 95cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return &methods->At(i, 9614632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Size(pointer_size), 9714632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Alignment(pointer_size)); 98e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 99e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 100e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetDirectMethod(size_t i, size_t pointer_size) { 101e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 102e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* methods = GetDirectMethodsPtr(); 103e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(methods != nullptr); 104cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return &methods->At(i, 10514632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Size(pointer_size), 10614632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Alignment(pointer_size)); 1072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 11054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtMethod>* Class::GetVirtualMethodsPtr() { 111e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>()); 112e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVirtualMethodsPtrUnchecked(); 1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 11554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetVirtualMethodsPtr(LengthPrefixedArray<ArtMethod>* new_virtual_methods) { 1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // TODO: we reassign virtual methods to grow the table for miranda 117d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // methods.. they should really just be assigned once. 118e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), 119e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier reinterpret_cast<uint64_t>(new_virtual_methods)); 1202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 123e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetVirtualMethod(size_t i, size_t pointer_size) { 124e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 125f4c15a18eb055735857a280856be5b142e0c1113Hiroshi Yamauchi DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>()) 126f4c15a18eb055735857a280856be5b142e0c1113Hiroshi Yamauchi << PrettyClass(this) << " status=" << GetStatus(); 127e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVirtualMethodUnchecked(i, pointer_size); 1282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 130e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetVirtualMethodDuringLinking(size_t i, size_t pointer_size) { 131e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 1322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 133e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVirtualMethodUnchecked(i, pointer_size); 1342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 136e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, size_t pointer_size) { 137e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 13854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtMethod>* methods = GetVirtualMethodsPtrUnchecked(); 139e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(methods != nullptr); 140cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return &methods->At(i, 14114632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Size(pointer_size), 14214632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Alignment(pointer_size)); 1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 145e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline PointerArray* Class::GetVTable() { 1462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsResolved() || IsErroneous()); 147e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_)); 1482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 150e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline PointerArray* Class::GetVTableDuringLinking() { 1512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 152e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_)); 1532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 155e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetVTable(PointerArray* new_vtable) { 156b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable); 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 159e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline MemberOffset Class::EmbeddedImTableEntryOffset(uint32_t i, size_t pointer_size) { 160e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK_LT(i, kImtSize); 161e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return MemberOffset( 162e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier EmbeddedImTableOffset(pointer_size).Uint32Value() + i * ImTableEntrySize(pointer_size)); 163e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 164e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 165e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetEmbeddedImTableEntry(uint32_t i, size_t pointer_size) { 166e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(ShouldHaveEmbeddedImtAndVTable()); 167e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetFieldPtrWithSize<ArtMethod*>( 168e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier EmbeddedImTableEntryOffset(i, pointer_size), pointer_size); 16998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 17098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 171e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetEmbeddedImTableEntry(uint32_t i, ArtMethod* method, size_t pointer_size) { 172e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(ShouldHaveEmbeddedImtAndVTable()); 173e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetFieldPtrWithSize<false>(EmbeddedImTableEntryOffset(i, pointer_size), method, pointer_size); 17498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 17598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 1762cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline bool Class::HasVTable() { 177e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVTable() != nullptr || ShouldHaveEmbeddedImtAndVTable(); 1782cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 1792cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 1802cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline int32_t Class::GetVTableLength() { 1812cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang if (ShouldHaveEmbeddedImtAndVTable()) { 1822cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang return GetEmbeddedVTableLength(); 1832cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang } 184e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVTable() != nullptr ? GetVTable()->GetLength() : 0; 1852cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 1862cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 187e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetVTableEntry(uint32_t i, size_t pointer_size) { 1882cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang if (ShouldHaveEmbeddedImtAndVTable()) { 189e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetEmbeddedVTableEntry(i, pointer_size); 1902cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang } 191e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* vtable = GetVTable(); 192e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(vtable != nullptr); 193e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size); 1942cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 1952cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 1962cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline int32_t Class::GetEmbeddedVTableLength() { 197e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetField32(MemberOffset(EmbeddedVTableLengthOffset())); 1982cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 1992cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 2002cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline void Class::SetEmbeddedVTableLength(int32_t len) { 201e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetField32<false>(MemberOffset(EmbeddedVTableLengthOffset()), len); 2022cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 2032cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 204e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, size_t pointer_size) { 205e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return MemberOffset( 206e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier EmbeddedVTableOffset(pointer_size).Uint32Value() + i * VTableEntrySize(pointer_size)); 2072cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 2082cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 209e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i, size_t pointer_size) { 210e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetFieldPtrWithSize<ArtMethod*>(EmbeddedVTableEntryOffset(i, pointer_size), pointer_size); 211e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 212e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 213e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetEmbeddedVTableEntryUnchecked( 214e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t i, ArtMethod* method, size_t pointer_size) { 215e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetFieldPtrWithSize<false>(EmbeddedVTableEntryOffset(i, pointer_size), method, pointer_size); 216e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 217e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 218e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method, size_t pointer_size) { 219e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* vtable = GetVTableDuringLinking(); 220e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CHECK_EQ(method, vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size)); 221e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetEmbeddedVTableEntryUnchecked(i, method, pointer_size); 22298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 22398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 224ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Class::Implements(Class* klass) { 2252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 226693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(klass->IsInterface()) << PrettyClass(this); 227693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // All interfaces implemented directly and by our superclass, and 228693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // recursively all super-interfaces of those interfaces, are listed 229693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // in iftable_, so we can just do a linear scan through that. 230693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers int32_t iftable_count = GetIfTableCount(); 231693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers IfTable* iftable = GetIfTable(); 232693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers for (int32_t i = 0; i < iftable_count; i++) { 233693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (iftable->GetInterface(i) == klass) { 234693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return true; 235693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 236693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 237693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return false; 238693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 239693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 240693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Determine whether "this" is assignable from "src", where both of these 241693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// are array classes. 242693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// 243693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Consider an array class, e.g. Y[][], where Y is a subclass of X. 244693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Y[][] = Y[][] --> true (identity) 245693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// X[][] = Y[][] --> true (element superclass) 246693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Y = Y[][] --> false 247693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Y[] = Y[][] --> false 248693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object = Y[][] --> true (everything is an object) 249693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[] = Y[][] --> true 250693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[][] = Y[][] --> true 251693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[][][] = Y[][] --> false (too many []s) 252693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Serializable = Y[][] --> true (all arrays are Serializable) 253693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Serializable[] = Y[][] --> true 254693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Serializable[][] = Y[][] --> false (unless Y is Serializable) 255693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// 256693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Don't forget about primitive types. 257693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[] = int[] --> false 258693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// 259ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Class::IsArrayAssignableFromArray(Class* src) { 260693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(IsArrayClass()) << PrettyClass(this); 261693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(src->IsArrayClass()) << PrettyClass(src); 262693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return GetComponentType()->IsAssignableFrom(src->GetComponentType()); 263693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 264693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 265ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Class::IsAssignableFromArray(Class* src) { 266693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom 267693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(src->IsArrayClass()) << PrettyClass(src); 268693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (!IsArrayClass()) { 269693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // If "this" is not also an array, it must be Object. 270693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // src's super should be java_lang_Object, since it is an array. 271693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers Class* java_lang_Object = src->GetSuperClass(); 2722cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(java_lang_Object != nullptr) << PrettyClass(src); 2732cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(java_lang_Object->GetSuperClass() == nullptr) << PrettyClass(src); 274693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return this == java_lang_Object; 275693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 276693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return IsArrayAssignableFromArray(src); 277693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 278693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 27989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <bool throw_on_failure, bool use_referrers_cache> 28089786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markoinline bool Class::ResolvedFieldAccessTest(Class* access_to, ArtField* field, 281ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers uint32_t field_idx, DexCache* dex_cache) { 28289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko DCHECK_EQ(use_referrers_cache, dex_cache == nullptr); 28323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(access_to))) { 28423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // The referrer class can't access the field's declaring class but may still be able 28523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // to access the field if the FieldId specifies an accessible subclass of the declaring 28623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // class rather than the declaring class itself. 287ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; 28823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; 28923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // The referenced class has already been resolved with the field, get it from the dex cache. 29023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx); 29123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko DCHECK(dex_access_to != nullptr); 29223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(dex_access_to))) { 29323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 29423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko ThrowIllegalAccessErrorClass(this, dex_access_to); 29523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 29623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 29723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 29823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko DCHECK_EQ(this->CanAccessMember(access_to, field->GetAccessFlags()), 29923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko this->CanAccessMember(dex_access_to, field->GetAccessFlags())); 30023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 30123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) { 30223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return true; 30323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 30423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 30523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko ThrowIllegalAccessErrorField(this, field); 30623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 30723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 30823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko} 30923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko 31089786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type> 31189786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markoinline bool Class::ResolvedMethodAccessTest(Class* access_to, ArtMethod* method, 312ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers uint32_t method_idx, DexCache* dex_cache) { 313575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type"); 31489786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko DCHECK_EQ(use_referrers_cache, dex_cache == nullptr); 31523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(access_to))) { 31623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // The referrer class can't access the method's declaring class but may still be able 31723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // to access the method if the MethodId specifies an accessible subclass of the declaring 31823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // class rather than the declaring class itself. 319ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers DexCache* referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; 32023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko uint32_t class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; 32123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // The referenced class has already been resolved with the method, get it from the dex cache. 32223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko Class* dex_access_to = referrer_dex_cache->GetResolvedType(class_idx); 32323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko DCHECK(dex_access_to != nullptr); 32423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(dex_access_to))) { 32523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 32623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko ThrowIllegalAccessErrorClassForMethodDispatch(this, dex_access_to, 32723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko method, throw_invoke_type); 32823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 32923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 33023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 33123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko DCHECK_EQ(this->CanAccessMember(access_to, method->GetAccessFlags()), 33223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko this->CanAccessMember(dex_access_to, method->GetAccessFlags())); 33323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 33423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) { 33523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return true; 33623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 33723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 33823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko ThrowIllegalAccessErrorMethod(this, method); 33923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 34023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 34123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko} 34223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko 34389786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markoinline bool Class::CanAccessResolvedField(Class* access_to, ArtField* field, 344ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers DexCache* dex_cache, uint32_t field_idx) { 345ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache); 34689786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 34789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 34889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markoinline bool Class::CheckResolvedFieldAccess(Class* access_to, ArtField* field, 34989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko uint32_t field_idx) { 35089786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr); 35189786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 35289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 35389786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markoinline bool Class::CanAccessResolvedMethod(Class* access_to, ArtMethod* method, 354ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers DexCache* dex_cache, uint32_t method_idx) { 355ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache); 35689786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 35789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 35889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <InvokeType throw_invoke_type> 35989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markoinline bool Class::CheckResolvedMethodAccess(Class* access_to, ArtMethod* method, 36089786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko uint32_t method_idx) { 36189786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, method, method_idx, 36289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko nullptr); 36389786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 36489786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 365ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Class::IsSubClass(Class* klass) { 366693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(!IsInterface()) << PrettyClass(this); 367693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(!IsArrayClass()) << PrettyClass(this); 368ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Class* current = this; 369693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers do { 370693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (current == klass) { 371693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return true; 372693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 373693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers current = current->GetSuperClass(); 3742cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier } while (current != nullptr); 375693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return false; 376693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 377693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 378e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method, size_t pointer_size) { 379693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers Class* declaring_class = method->GetDeclaringClass(); 3802cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(declaring_class != nullptr) << PrettyClass(this); 381693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers DCHECK(declaring_class->IsInterface()) << PrettyMethod(method); 382693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // TODO cache to improve lookup speed 383e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const int32_t iftable_count = GetIfTableCount(); 384693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers IfTable* iftable = GetIfTable(); 385693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers for (int32_t i = 0; i < iftable_count; i++) { 386693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (iftable->GetInterface(i) == declaring_class) { 387e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return iftable->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>( 388e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier method->GetMethodIndex(), pointer_size); 389693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 390693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 3912cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return nullptr; 392693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 393693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 394e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method, size_t pointer_size) { 395eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light // Only miranda or default methods may come from interfaces and be used as a virtual. 396eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsDefault() || method->IsMiranda()); 3972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // The argument method may from a super class. 3982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Use the index to a potentially overridden one for this instance's class. 399e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVTableEntry(method->GetMethodIndex(), pointer_size); 4002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 402e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method, size_t pointer_size) { 4032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(!method->GetDeclaringClass()->IsInterface()); 404e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetSuperClass()->GetVTableEntry(method->GetMethodIndex(), pointer_size); 4052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 407e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method, 408e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size_t pointer_size) { 4092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method->IsDirect()) { 4102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 4112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 412201803fb1acd15b9daae51d816e1b08aededdc41Jeff Hao if (method->GetDeclaringClass()->IsInterface() && !method->IsMiranda()) { 413e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return FindVirtualMethodForInterface(method, pointer_size); 4142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 415e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return FindVirtualMethodForVirtual(method, pointer_size); 4162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 418ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline IfTable* Class::GetIfTable() { 419b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetFieldObject<IfTable>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_)); 4202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 422ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline int32_t Class::GetIfTableCount() { 4232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IfTable* iftable = GetIfTable(); 4242cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (iftable == nullptr) { 4252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return 0; 4262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return iftable->Count(); 4282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Class::SetIfTable(IfTable* new_iftable) { 431b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable); 4322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 43454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtr() { 4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 43654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)); 4372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 43976649e8d775519fe19f2b14d18ac488c13296054Vladimir Markoinline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() { 44076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko Class* super_class = GetSuperClass(); 44176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko return (super_class != nullptr) 44276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko ? MemberOffset(RoundUp(super_class->GetObjectSize(), 44376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko sizeof(mirror::HeapReference<mirror::Object>))) 44476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko : ClassOffset(); 44576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko} 44676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko 447e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline MemberOffset Class::GetFirstReferenceStaticFieldOffset(size_t pointer_size) { 44876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko DCHECK(IsResolved()); 44976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko uint32_t base = sizeof(mirror::Class); // Static fields come after the class. 45076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko if (ShouldHaveEmbeddedImtAndVTable()) { 45176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko // Static fields come after the embedded tables. 452e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier base = mirror::Class::ComputeClassSize( 453e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size); 45476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 45576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko return MemberOffset(base); 45676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko} 45776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko 458e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking(size_t pointer_size) { 45976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko DCHECK(IsLoaded()); 46076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko uint32_t base = sizeof(mirror::Class); // Static fields come after the class. 46176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko if (ShouldHaveEmbeddedImtAndVTable()) { 46276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko // Static fields come after the embedded tables. 46376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko base = mirror::Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(), 464e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 0, 0, 0, 0, 0, pointer_size); 46576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 46676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko return MemberOffset(base); 46776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko} 46876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko 46954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields) { 47054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier DCHECK(GetIFieldsPtrUnchecked() == nullptr); 471c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields); 4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 47454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_ifields) { 475c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields); 4762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 47854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtrUnchecked() { 47954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)); 4802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 48254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtrUnchecked() { 48354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)); 4842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 48654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtr() { 487c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK(IsLoaded() || IsErroneous()) << GetStatus(); 48854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetSFieldsPtrUnchecked(); 4892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 49154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields) { 492c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK((IsRetired() && new_sfields == nullptr) || 493c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr); 494c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields); 4952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 49754d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields) { 498c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields); 4992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 501c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* Class::GetStaticField(uint32_t i) { 50254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return &GetSFieldsPtr()->At(i); 5032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 505c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* Class::GetInstanceField(uint32_t i) { 50654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return &GetIFieldsPtr()->At(i); 5072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 509b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 510b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline uint32_t Class::GetReferenceInstanceOffsets() { 511b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>()); 512b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_)); 513b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 514b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 515b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) { 516b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (Runtime::Current()->IsActiveTransaction()) { 517b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id); 518b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } else { 519b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id); 520b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 521b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 522b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 5234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 524ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint32_t Class::GetAccessFlags() { 52598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Check class is loaded/retired or this is java.lang.String that has a 5262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // circularity issue during loading the names of its members 52798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() || 5284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() || 529e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier this == String::GetJavaLangString()) 530a6928661ad617880c99e3d8199b95871736564dbAndreas Gampe << "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>() 531a6928661ad617880c99e3d8199b95871736564dbAndreas Gampe << " IsRetired=" << IsRetired<kVerifyFlags>() 532a6928661ad617880c99e3d8199b95871736564dbAndreas Gampe << " IsErroneous=" << 533a6928661ad617880c99e3d8199b95871736564dbAndreas Gampe IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() 534a6928661ad617880c99e3d8199b95871736564dbAndreas Gampe << " IsString=" << (this == String::GetJavaLangString()) 535a6928661ad617880c99e3d8199b95871736564dbAndreas Gampe << " descriptor=" << PrettyDescriptor(this); 536e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi return GetField32<kVerifyFlags>(AccessFlagsOffset()); 5372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 539ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline String* Class::GetName() { 540b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_)); 5412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 54252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier 5432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Class::SetName(String* name) { 544d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (Runtime::Current()->IsActiveTransaction()) { 545b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name); 546d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 547b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name); 548d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 5492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 551b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 552b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline Primitive::Type Class::GetPrimitiveType() { 55333d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain static_assert(sizeof(Primitive::Type) == sizeof(int32_t), 55433d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain "art::Primitive::Type and int32_t have different sizes."); 555f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)); 556f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi Primitive::Type type = static_cast<Primitive::Type>(v32 & 0xFFFF); 557f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi DCHECK_EQ(static_cast<size_t>(v32 >> 16), Primitive::ComponentSizeShift(type)); 558f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi return type; 559f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi} 560f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi 561f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags> 562f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchiinline size_t Class::GetPrimitiveTypeSizeShift() { 56333d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain static_assert(sizeof(Primitive::Type) == sizeof(int32_t), 56433d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain "art::Primitive::Type and int32_t have different sizes."); 565f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)); 566f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi size_t size_shift = static_cast<Primitive::Type>(v32 >> 16); 567f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi DCHECK_EQ(size_shift, Primitive::ComponentSizeShift(static_cast<Primitive::Type>(v32 & 0xFFFF))); 568f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi return size_shift; 569b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 570b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 5713b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchiinline void Class::CheckObjectAlloc() { 5724cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi DCHECK(!IsArrayClass()) 5734cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << PrettyClass(this) 5744cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "A array shouldn't be allocated through this " 5754cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "as it requires a pre-fence visitor that sets the class size."; 5764cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi DCHECK(!IsClassClass()) 5774cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << PrettyClass(this) 5784cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "A class object shouldn't be allocated through this " 5794cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "as it requires a pre-fence visitor that sets the class size."; 580848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao DCHECK(!IsStringClass()) 581848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao << PrettyClass(this) 582848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao << "A string shouldn't be allocated through this " 583848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao << "as it requires a pre-fence visitor that sets the class size."; 584967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi DCHECK(IsInstantiable()) << PrettyClass(this); 585967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi // TODO: decide whether we want this check. It currently fails during bootstrap. 586967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this); 587967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi DCHECK_GE(this->object_size_, sizeof(Object)); 5883b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi} 5893b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi 5908668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartiertemplate<bool kIsInstrumented, bool kCheckAddFinalizer> 591cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierinline Object* Class::Alloc(Thread* self, gc::AllocatorType allocator_type) { 5923b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi CheckObjectAlloc(); 593590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier gc::Heap* heap = Runtime::Current()->GetHeap(); 5948668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier const bool add_finalizer = kCheckAddFinalizer && IsFinalizable(); 5958668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier if (!kCheckAddFinalizer) { 5968668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier DCHECK(!IsFinalizable()); 5978668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier } 5988668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier mirror::Object* obj = 5998668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, this, this->object_size_, 6008668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier allocator_type, VoidFunctor()); 6018668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier if (add_finalizer && LIKELY(obj != nullptr)) { 6028668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier heap->AddFinalizerReference(self, &obj); 6033ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski if (UNLIKELY(self->IsExceptionPending())) { 6043ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski // Failed to allocate finalizer reference, it means that the whole allocation failed. 6053ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski obj = nullptr; 6063ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski } 6078668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier } 6088668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier return obj; 609cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} 610cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier 611cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierinline Object* Class::AllocObject(Thread* self) { 612cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); 613cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} 614cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier 615cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartierinline Object* Class::AllocNonMovableObject(Thread* self) { 616cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator()); 617967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi} 618967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi 61998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yanginline uint32_t Class::ComputeClassSize(bool has_embedded_tables, 62098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t num_vtable_entries, 62137f05ef45e0393de812d51261dc293240c17294dFred Shih uint32_t num_8bit_static_fields, 62237f05ef45e0393de812d51261dc293240c17294dFred Shih uint32_t num_16bit_static_fields, 62398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t num_32bit_static_fields, 62498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t num_64bit_static_fields, 625e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t num_ref_static_fields, 626e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size_t pointer_size) { 62798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used by java.lang.Class and its instance fields. 62898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t size = sizeof(Class); 62998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used by embedded tables. 63098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang if (has_embedded_tables) { 631e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const uint32_t embedded_imt_size = kImtSize * ImTableEntrySize(pointer_size); 632e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const uint32_t embedded_vtable_size = num_vtable_entries * VTableEntrySize(pointer_size); 633e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size = RoundUp(size + sizeof(uint32_t) /* embedded vtable len */, pointer_size) + 634e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier embedded_imt_size + embedded_vtable_size; 63598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang } 63637f05ef45e0393de812d51261dc293240c17294dFred Shih 63798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used by reference statics. 638e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size += num_ref_static_fields * sizeof(HeapReference<Object>); 63937f05ef45e0393de812d51261dc293240c17294dFred Shih if (!IsAligned<8>(size) && num_64bit_static_fields > 0) { 64037f05ef45e0393de812d51261dc293240c17294dFred Shih uint32_t gap = 8 - (size & 0x7); 64137f05ef45e0393de812d51261dc293240c17294dFred Shih size += gap; // will be padded 64237f05ef45e0393de812d51261dc293240c17294dFred Shih // Shuffle 4-byte fields forward. 64337f05ef45e0393de812d51261dc293240c17294dFred Shih while (gap >= sizeof(uint32_t) && num_32bit_static_fields != 0) { 64437f05ef45e0393de812d51261dc293240c17294dFred Shih --num_32bit_static_fields; 64537f05ef45e0393de812d51261dc293240c17294dFred Shih gap -= sizeof(uint32_t); 64637f05ef45e0393de812d51261dc293240c17294dFred Shih } 64737f05ef45e0393de812d51261dc293240c17294dFred Shih // Shuffle 2-byte fields forward. 64837f05ef45e0393de812d51261dc293240c17294dFred Shih while (gap >= sizeof(uint16_t) && num_16bit_static_fields != 0) { 64937f05ef45e0393de812d51261dc293240c17294dFred Shih --num_16bit_static_fields; 65037f05ef45e0393de812d51261dc293240c17294dFred Shih gap -= sizeof(uint16_t); 65137f05ef45e0393de812d51261dc293240c17294dFred Shih } 65237f05ef45e0393de812d51261dc293240c17294dFred Shih // Shuffle byte fields forward. 65337f05ef45e0393de812d51261dc293240c17294dFred Shih while (gap >= sizeof(uint8_t) && num_8bit_static_fields != 0) { 65437f05ef45e0393de812d51261dc293240c17294dFred Shih --num_8bit_static_fields; 65537f05ef45e0393de812d51261dc293240c17294dFred Shih gap -= sizeof(uint8_t); 6562cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang } 65798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang } 65837f05ef45e0393de812d51261dc293240c17294dFred Shih // Guaranteed to be at least 4 byte aligned. No need for further alignments. 65998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used for primitive static fields. 660e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size += num_8bit_static_fields * sizeof(uint8_t) + num_16bit_static_fields * sizeof(uint16_t) + 661e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier num_32bit_static_fields * sizeof(uint32_t) + num_64bit_static_fields * sizeof(uint64_t); 66298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang return size; 66398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 66498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 665059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate <typename Visitor> 666407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) { 667059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier VisitInstanceFieldsReferences(klass, visitor); 6682cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Right after a class is allocated, but not yet loaded 669c449e8b79aaaf156ce055524c41474cc1200ed5aIgor Murashkin // (kStatusNotReady, see ClassLinker::LoadClass()), GC may find it 6702cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // and scan it. IsTemp() may call Class::GetAccessFlags() but may 6712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // fail in the DCHECK in Class::GetAccessFlags() because the class 6722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // status is kStatusNotReady. To avoid it, rely on IsResolved() 6732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // only. This is fine because a temp class never goes into the 6742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // kStatusResolved state. 6752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (IsResolved()) { 67698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Temp classes don't ever populate imt/vtable or static fields and they are not even 677f4c15a18eb055735857a280856be5b142e0c1113Hiroshi Yamauchi // allocated with the right size for those. Also, unresolved classes don't have fields 678f4c15a18eb055735857a280856be5b142e0c1113Hiroshi Yamauchi // linked yet. 679059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier VisitStaticFieldsReferences(this, visitor); 68098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang } 681da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier // Since this class is reachable, we must also visit the associated roots when we scan it. 682da7c650022a974be10e2f00fa07d5109e3d8826fMathieu Chartier VisitNativeRoots(visitor, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); 683407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 684407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 6854f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchitemplate<ReadBarrierOption kReadBarrierOption> 6864ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline bool Class::IsReferenceClass() const { 6874ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih return this == Reference::GetJavaLangRefReference<kReadBarrierOption>(); 6884ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 6894ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 69025023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 69125023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchiinline bool Class::IsClassClass() { 69225023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()-> 69325023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi template GetClass<kVerifyFlags, kReadBarrierOption>(); 69425023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi return this == java_lang_Class; 69525023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi} 69625023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi 697f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartierinline const DexFile& Class::GetDexFile() { 6983a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return *GetDexCache()->GetDexFile(); 699f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier} 700f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier 701f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartierinline bool Class::DescriptorEquals(const char* match) { 7021ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers if (IsArrayClass()) { 703f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1); 7041ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers } else if (IsPrimitive()) { 705f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0; 7063a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray } else if (IsProxyClass()) { 7073a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return ProxyDescriptorEquals(match); 708f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else { 709f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier const DexFile& dex_file = GetDexFile(); 710f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_); 711f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0; 712f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } 713f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier} 714f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier 7154e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertzinline void Class::AssertInitializedOrInitializingInThread(Thread* self) { 7164e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz if (kIsDebugBuild && !IsInitialized()) { 7174e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz CHECK(IsInitializing()) << PrettyClass(this) << " is not initializing: " << GetStatus(); 7184e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass(this) 7194e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz << " is initializing in a different thread"; 7204e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz } 7214e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz} 7224e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz 7233a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffrayinline ObjectArray<Class>* Class::GetInterfaces() { 7243a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray CHECK(IsProxyClass()); 72598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // First static field. 726c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(0); 727c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "interfaces"); 728c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier MemberOffset field_offset = field->GetOffset(); 7293a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return GetFieldObject<ObjectArray<Class>>(field_offset); 73098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 73198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 7323a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffrayinline ObjectArray<ObjectArray<Class>>* Class::GetThrows() { 7333a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray CHECK(IsProxyClass()); 73498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Second static field. 735c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(1); 736c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "throws"); 737c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier MemberOffset field_offset = field->GetOffset(); 7383a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset); 73998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 74098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 7414ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline MemberOffset Class::GetDisableIntrinsicFlagOffset() { 7424ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih CHECK(IsReferenceClass()); 7434ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih // First static field 744c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(0); 745c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "disableIntrinsic"); 746c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return field->GetOffset(); 7474ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 7484ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 7494ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline MemberOffset Class::GetSlowPathFlagOffset() { 7504ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih CHECK(IsReferenceClass()); 7514ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih // Second static field 752c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(1); 753c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "slowPathEnabled"); 754c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return field->GetOffset(); 7554ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 7564ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 7574ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline bool Class::GetSlowPathEnabled() { 75837f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldBoolean(GetSlowPathFlagOffset()); 7594ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 7604ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 7614ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline void Class::SetSlowPath(bool enabled) { 762310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier SetFieldBoolean<false, false>(GetSlowPathFlagOffset(), enabled); 7634ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 7644ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 76598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yanginline void Class::InitializeClassVisitor::operator()( 76698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang mirror::Object* obj, size_t usable_size) const { 76798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang DCHECK_LE(class_size_, usable_size); 76898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Avoid AsClass as object is not yet in live bitmap or allocation stack. 76998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang mirror::Class* klass = down_cast<mirror::Class*>(obj); 77098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // DCHECK(klass->IsClass()); 77198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetClassSize(class_size_); 77298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive. 77398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index. 77498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetDexTypeIndex(DexFile::kDexNoIndex16); // Default to no valid type index. 77598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 77698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 77748498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampeinline void Class::SetAccessFlags(uint32_t new_access_flags) { 77848498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe // Called inside a transaction when setting pre-verified flag during boot image compilation. 77948498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe if (Runtime::Current()->IsActiveTransaction()) { 78052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<true>(AccessFlagsOffset(), new_access_flags); 78152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 78252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<false>(AccessFlagsOffset(), new_access_flags); 78352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 78452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier} 78552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier 78652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartierinline void Class::SetClassFlags(uint32_t new_flags) { 78752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (Runtime::Current()->IsActiveTransaction()) { 78852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags); 78948498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe } else { 79052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags); 79148498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe } 79248498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe} 79348498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe 7942d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartierinline uint32_t Class::NumDirectInterfaces() { 7952d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier if (IsPrimitive()) { 7962d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return 0; 7972d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } else if (IsArrayClass()) { 7982d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return 2; 7993a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray } else if (IsProxyClass()) { 8003a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray mirror::ObjectArray<mirror::Class>* interfaces = GetInterfaces(); 8012d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return interfaces != nullptr ? interfaces->GetLength() : 0; 8022d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } else { 8032d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier const DexFile::TypeList* interfaces = GetInterfaceTypeList(); 8042d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier if (interfaces == nullptr) { 8052d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return 0; 8062d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } else { 8072d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return interfaces->Size(); 8082d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } 8092d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } 8102d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier} 8112d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier 81205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline void Class::SetDexCacheStrings(GcRoot<String>* new_dex_cache_strings) { 81305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko SetFieldPtr<false>(DexCacheStringsOffset(), new_dex_cache_strings); 814eace45873190a27302b3644c32ec82854b59d299Mathieu Chartier} 815eace45873190a27302b3644c32ec82854b59d299Mathieu Chartier 81605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline GcRoot<String>* Class::GetDexCacheStrings() { 81705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetFieldPtr<GcRoot<String>*>(DexCacheStringsOffset()); 818eace45873190a27302b3644c32ec82854b59d299Mathieu Chartier} 819eace45873190a27302b3644c32ec82854b59d299Mathieu Chartier 820c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartiertemplate<class Visitor> 821e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiervoid mirror::Class::VisitNativeRoots(Visitor& visitor, size_t pointer_size) { 82254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier for (ArtField& field : GetSFieldsUnchecked()) { 82354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier // Visit roots first in case the declaring class gets moved. 82454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier field.VisitRoots(visitor); 82554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier if (kIsDebugBuild && IsResolved()) { 82654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier CHECK_EQ(field.GetDeclaringClass(), this) << GetStatus(); 827c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 828c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 82954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier for (ArtField& field : GetIFieldsUnchecked()) { 83054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier // Visit roots first in case the declaring class gets moved. 83154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier field.VisitRoots(visitor); 83254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier if (kIsDebugBuild && IsResolved()) { 83354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier CHECK_EQ(field.GetDeclaringClass(), this) << GetStatus(); 834c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 835c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier } 83654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier for (ArtMethod& method : GetDirectMethods(pointer_size)) { 8371147b9bd68323c753ed1a0b6106b205fd640c820Mathieu Chartier method.VisitRoots(visitor, pointer_size); 838e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 83954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier for (ArtMethod& method : GetVirtualMethods(pointer_size)) { 8401147b9bd68323c753ed1a0b6106b205fd640c820Mathieu Chartier method.VisitRoots(visitor, pointer_size); 841e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 842e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 843e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 84454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(size_t pointer_size) { 845e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 84654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return MakeIterationRangeFromLengthPrefixedArray(GetDirectMethodsPtrUnchecked(), 84714632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Size(pointer_size), 84814632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Alignment(pointer_size)); 849e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 850e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 85154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods(size_t pointer_size) { 852e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 85354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return MakeIterationRangeFromLengthPrefixedArray(GetVirtualMethodsPtrUnchecked(), 85414632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Size(pointer_size), 85514632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Alignment(pointer_size)); 856e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 857e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 85854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetIFields() { 859cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr()); 860e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 861e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 86254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetSFields() { 863cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr()); 864e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 865e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 86654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() { 867cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked()); 868e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 869e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 87054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() { 871cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked()); 872e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 873e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 874e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline MemberOffset Class::EmbeddedImTableOffset(size_t pointer_size) { 875e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 876e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Round up since we want the embedded imt and vtable to be pointer size aligned in case 64 bits. 877e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Add 32 bits for embedded vtable length. 878e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return MemberOffset( 879e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier RoundUp(EmbeddedVTableLengthOffset().Uint32Value() + sizeof(uint32_t), pointer_size)); 880e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 881e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 882e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline MemberOffset Class::EmbeddedVTableOffset(size_t pointer_size) { 883e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 884e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return MemberOffset(EmbeddedImTableOffset(pointer_size).Uint32Value() + 885e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier kImtSize * ImTableEntrySize(pointer_size)); 886e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 887e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 888e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::CheckPointerSize(size_t pointer_size) { 889e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(ValidPointerSize(pointer_size)) << pointer_size; 890e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); 891c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier} 892c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier 8932e76830f0b3f23825677436c0633714402715099Calin Juravletemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 8942e76830f0b3f23825677436c0633714402715099Calin Juravleinline Class* Class::GetComponentType() { 8952e76830f0b3f23825677436c0633714402715099Calin Juravle return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ComponentTypeOffset()); 8962e76830f0b3f23825677436c0633714402715099Calin Juravle} 8972e76830f0b3f23825677436c0633714402715099Calin Juravle 8982e76830f0b3f23825677436c0633714402715099Calin Juravletemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 8992e76830f0b3f23825677436c0633714402715099Calin Juravleinline bool Class::IsArrayClass() { 9002e76830f0b3f23825677436c0633714402715099Calin Juravle return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr; 9012e76830f0b3f23825677436c0633714402715099Calin Juravle} 9022e76830f0b3f23825677436c0633714402715099Calin Juravle 9032e76830f0b3f23825677436c0633714402715099Calin Juravleinline bool Class::IsAssignableFrom(Class* src) { 9042e76830f0b3f23825677436c0633714402715099Calin Juravle DCHECK(src != nullptr); 9052e76830f0b3f23825677436c0633714402715099Calin Juravle if (this == src) { 9062e76830f0b3f23825677436c0633714402715099Calin Juravle // Can always assign to things of the same type. 9072e76830f0b3f23825677436c0633714402715099Calin Juravle return true; 9082e76830f0b3f23825677436c0633714402715099Calin Juravle } else if (IsObjectClass()) { 9092e76830f0b3f23825677436c0633714402715099Calin Juravle // Can assign any reference to java.lang.Object. 9102e76830f0b3f23825677436c0633714402715099Calin Juravle return !src->IsPrimitive(); 9112e76830f0b3f23825677436c0633714402715099Calin Juravle } else if (IsInterface()) { 9122e76830f0b3f23825677436c0633714402715099Calin Juravle return src->Implements(this); 9132e76830f0b3f23825677436c0633714402715099Calin Juravle } else if (src->IsArrayClass()) { 9142e76830f0b3f23825677436c0633714402715099Calin Juravle return IsAssignableFromArray(src); 9152e76830f0b3f23825677436c0633714402715099Calin Juravle } else { 9162e76830f0b3f23825677436c0633714402715099Calin Juravle return !src->IsInterface() && src->IsSubClass(this); 9172e76830f0b3f23825677436c0633714402715099Calin Juravle } 9182e76830f0b3f23825677436c0633714402715099Calin Juravle} 9192e76830f0b3f23825677436c0633714402715099Calin Juravle 92054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumDirectMethods() { 92154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtMethod>* arr = GetDirectMethodsPtrUnchecked(); 92235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return arr != nullptr ? arr->size() : 0u; 92354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 92454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 92554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumVirtualMethods() { 92654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtMethod>* arr = GetVirtualMethodsPtrUnchecked(); 92735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return arr != nullptr ? arr->size() : 0u; 92854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 92954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 93054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumInstanceFields() { 93154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtField>* arr = GetIFieldsPtrUnchecked(); 93235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return arr != nullptr ? arr->size() : 0u; 93354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 93454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 93554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumStaticFields() { 93654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtField>* arr = GetSFieldsPtrUnchecked(); 93735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return arr != nullptr ? arr->size() : 0u; 93854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 93954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 9404b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartiertemplate <typename Visitor> 9414b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartierinline void Class::FixupNativePointers(mirror::Class* dest, 9424b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier size_t pointer_size, 9434b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier const Visitor& visitor) { 9444b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier // Update the field arrays. 9454b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr(); 9464b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields); 9474b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (sfields != new_sfields) { 9484b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetSFieldsPtrUnchecked(new_sfields); 9494b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9504b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr(); 9514b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields); 9524b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (ifields != new_ifields) { 9534b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetIFieldsPtrUnchecked(new_ifields); 9544b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9554b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier // Update direct and virtual method arrays. 9564b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtMethod>* direct_methods = GetDirectMethodsPtr(); 9574b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtMethod>* new_direct_methods = visitor(direct_methods); 9584b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (direct_methods != new_direct_methods) { 9594b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetDirectMethodsPtrUnchecked(new_direct_methods); 9604b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9614b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtMethod>* virtual_methods = GetVirtualMethodsPtr(); 9624b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtMethod>* new_virtual_methods = visitor(virtual_methods); 9634b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (virtual_methods != new_virtual_methods) { 9644b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetVirtualMethodsPtr(new_virtual_methods); 9654b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9664b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier // Update dex cache strings. 9674b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier GcRoot<mirror::String>* strings = GetDexCacheStrings(); 9684b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier GcRoot<mirror::String>* new_strings = visitor(strings); 9694b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (strings != new_strings) { 9704b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetDexCacheStrings(new_strings); 9714b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9724b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier // Fix up embedded tables. 9734b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (!IsTemp() && ShouldHaveEmbeddedImtAndVTable()) { 9744b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) { 9754b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size); 9764b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier ArtMethod* new_method = visitor(method); 9774b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (method != new_method) { 9784b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size); 9794b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9804b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9814b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier for (size_t i = 0; i < mirror::Class::kImtSize; ++i) { 9824b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier ArtMethod* method = GetEmbeddedImTableEntry(i, pointer_size); 9834b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier ArtMethod* new_method = visitor(method); 9844b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (method != new_method) { 9854b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetEmbeddedImTableEntry(i, new_method, pointer_size); 9864b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9874b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9884b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 9894b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier} 9904b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier 9912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 9922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 9932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 994fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_CLASS_INL_H_ 995