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 22a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "art_field.h" 23e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method.h" 24e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light#include "base/array_slice.h" 25e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light#include "base/length_prefixed_array.h" 26a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "class_linker-inl.h" 274f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "class_loader.h" 2823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko#include "common_throws.h" 29a1d2f957a21319d1110bebb9a52f46fd1c67ffafAndreas Gampe#include "dex_file-inl.h" 303b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi#include "gc/heap-inl.h" 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "iftable.h" 3262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "object_array-inl.h" 33c15a2f4f45661a7f5f542e406282c146ea1a968dAndreas Gampe#include "object-inl.h" 3498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "read_barrier-inl.h" 354ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih#include "reference-inl.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h" 372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "string.h" 3880afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4325023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint32_t Class::GetObjectSize() { 453481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator. 46709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf(); 47e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi return GetField32(ObjectSizeOffset()); 482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 50fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 51161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartierinline uint32_t Class::GetObjectSizeAllocFastPath() { 52161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier // Note: Extra parentheses to avoid the comma being interpreted as macro parameter separator. 53709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK((!IsVariableSize<kVerifyFlags, kReadBarrierOption>())) << "class=" << PrettyTypeOf(); 54161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier return GetField32(ObjectSizeAllocFastPathOffset()); 55161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier} 56161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier 57161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier 58161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 59ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Class::GetSuperClass() { 602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Can only get super class for loaded classes (hack for when runtime is 612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // initializing) 62fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK(IsLoaded<kVerifyFlags>() || 63fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier IsErroneous<kVerifyFlags>() || 64fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier !Runtime::Current()->IsStarted()) << IsLoaded(); 65fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>( 66fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier OFFSET_OF_OBJECT_MEMBER(Class, super_class_)); 672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 698ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillaininline void Class::SetSuperClass(ObjPtr<Class> new_super_class) { 708ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain // Super class is assigned once, except during class linker initialization. 718ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain if (kIsDebugBuild) { 728ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain ObjPtr<Class> old_super_class = 738ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_)); 748ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain DCHECK(old_super_class == nullptr || old_super_class == new_super_class); 758ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain } 768ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain DCHECK(new_super_class != nullptr); 778ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), new_super_class); 788ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain} 798ca4e4e7a55f7a7079ec1f95a3188d9df434704bRoland Levillain 80e51ca8bfa8a193b64901ad214842f213adca92ebNicolas Geoffraytemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ClassLoader* Class::GetClassLoader() { 82e51ca8bfa8a193b64901ad214842f213adca92ebNicolas Geoffray return GetFieldObject<ClassLoader, kVerifyFlags, kReadBarrierOption>( 83e51ca8bfa8a193b64901ad214842f213adca92ebNicolas Geoffray OFFSET_OF_OBJECT_MEMBER(Class, class_loader_)); 844f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers} 854f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 86137cdfa1e8a3810fb86d3298ec10036c0491d13fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 874f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Lightinline ClassExt* Class::GetExtData() { 884f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light return GetFieldObject<ClassExt, kVerifyFlags, kReadBarrierOption>( 894f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light OFFSET_OF_OBJECT_MEMBER(Class, ext_data_)); 904f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light} 914f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Light 924f2e957b07c8b6e48bbd7593bb64f3c5214fa489Alex Lighttemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 93ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline DexCache* Class::GetDexCache() { 94137cdfa1e8a3810fb86d3298ec10036c0491d13fMathieu Chartier return GetFieldObject<DexCache, kVerifyFlags, kReadBarrierOption>( 95137cdfa1e8a3810fb86d3298ec10036c0491d13fMathieu Chartier OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_)); 964f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers} 974f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 98e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::GetCopiedMethodsStartOffset() { 99c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // Object::GetFieldShort returns an int16_t value, but 100c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // Class::copied_methods_offset_ is an uint16_t value; cast the 101c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // latter to int16_t before returning it as an uint32_t value, so 102c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // that uint16_t values between 2^15 and 2^16-1 are correctly 103c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // handled. 104c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain return static_cast<uint16_t>( 105c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_))); 106e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 107e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 108e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::GetDirectMethodsStartOffset() { 109e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return 0; 110e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 111e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 112e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::GetVirtualMethodsStartOffset() { 113c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // Object::GetFieldShort returns an int16_t value, but 114c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // Class::virtual_method_offset_ is an uint16_t value; cast the 115c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // latter to int16_t before returning it as an uint32_t value, so 116c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // that uint16_t values between 2^15 and 2^16-1 are correctly 117c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain // handled. 118c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain return static_cast<uint16_t>( 119c5afe846ac45e59b512e91ec1cd07fff0d513332Roland Levillain GetFieldShort(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_))); 120e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 121e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 122e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags> 123542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDirectMethodsSlice(PointerSize pointer_size) { 1242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 125e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetDirectMethodsSliceUnchecked(pointer_size); 1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 128542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDirectMethodsSliceUnchecked(PointerSize pointer_size) { 129e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return ArraySlice<ArtMethod>(GetMethodsPtr(), 130e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetDirectMethodsStartOffset(), 131e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetVirtualMethodsStartOffset(), 132e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Size(pointer_size), 133e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Alignment(pointer_size)); 1346286a97bea0f584342803a215550038852b24776Alex Light} 1356286a97bea0f584342803a215550038852b24776Alex Light 136e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags> 137542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSlice(PointerSize pointer_size) { 138e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK(IsLoaded() || IsErroneous()); 139e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetDeclaredMethodsSliceUnchecked(pointer_size); 140e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 141e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 142542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredMethodsSliceUnchecked(PointerSize pointer_size) { 143e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return ArraySlice<ArtMethod>(GetMethodsPtr(), 144e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetDirectMethodsStartOffset(), 145e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetCopiedMethodsStartOffset(), 146e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Size(pointer_size), 147e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Alignment(pointer_size)); 148e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 149e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags> 150542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSlice(PointerSize pointer_size) { 151e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK(IsLoaded() || IsErroneous()); 152e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size); 153e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 154e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 155542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetDeclaredVirtualMethodsSliceUnchecked( 156542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 157e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return ArraySlice<ArtMethod>(GetMethodsPtr(), 158e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetVirtualMethodsStartOffset(), 159e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetCopiedMethodsStartOffset(), 160e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Size(pointer_size), 161e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Alignment(pointer_size)); 162e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 163e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 164e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags> 165542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetVirtualMethodsSlice(PointerSize pointer_size) { 166e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK(IsLoaded() || IsErroneous()); 167e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetVirtualMethodsSliceUnchecked(pointer_size); 168e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 169e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 170542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetVirtualMethodsSliceUnchecked(PointerSize pointer_size) { 171e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr(); 172e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return ArraySlice<ArtMethod>(methods, 173e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetVirtualMethodsStartOffset(), 174e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light NumMethods(), 175e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Size(pointer_size), 176e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Alignment(pointer_size)); 177e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 178e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 179e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags> 180542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetCopiedMethodsSlice(PointerSize pointer_size) { 181e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK(IsLoaded() || IsErroneous()); 182e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetCopiedMethodsSliceUnchecked(pointer_size); 183e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 184e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 185542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetCopiedMethodsSliceUnchecked(PointerSize pointer_size) { 186e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr(); 187e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return ArraySlice<ArtMethod>(methods, 188e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light GetCopiedMethodsStartOffset(), 189e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light NumMethods(), 190e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Size(pointer_size), 191e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Alignment(pointer_size)); 192e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 193e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 194e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline LengthPrefixedArray<ArtMethod>* Class::GetMethodsPtr() { 19554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return reinterpret_cast<LengthPrefixedArray<ArtMethod>*>( 196f4b3dbad413023795b92a842aad1c3f2fe4a57e9Mathieu Chartier static_cast<uintptr_t>(GetField64(OFFSET_OF_OBJECT_MEMBER(Class, methods_)))); 1972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 199e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lighttemplate<VerifyObjectFlags kVerifyFlags> 200542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArraySlice<ArtMethod> Class::GetMethodsSlice(PointerSize pointer_size) { 201e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK(IsLoaded() || IsErroneous()); 202e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr(); 203e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return ArraySlice<ArtMethod>(methods, 204e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 0, 205e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light NumMethods(), 206e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Size(pointer_size), 207e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light ArtMethod::Alignment(pointer_size)); 2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 210e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 211e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::NumMethods() { 212e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr(); 213e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return (methods == nullptr) ? 0 : methods->size(); 214e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 215e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 216542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetDirectMethodUnchecked(size_t i, PointerSize pointer_size) { 217e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 218e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return &GetDirectMethodsSliceUnchecked(pointer_size).At(i); 219e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 220e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 221542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetDirectMethod(size_t i, PointerSize pointer_size) { 222e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 223e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return &GetDirectMethodsSlice(pointer_size).At(i); 2246286a97bea0f584342803a215550038852b24776Alex Light} 2256286a97bea0f584342803a215550038852b24776Alex Light 226e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline void Class::SetMethodsPtr(LengthPrefixedArray<ArtMethod>* new_methods, 227e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light uint32_t num_direct, 228e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light uint32_t num_virtual) { 229e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK(GetMethodsPtr() == nullptr); 230e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light SetMethodsPtrUnchecked(new_methods, num_direct, num_virtual); 231e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 232e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 233e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 234e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline void Class::SetMethodsPtrUnchecked(LengthPrefixedArray<ArtMethod>* new_methods, 235e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light uint32_t num_direct, 236e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light uint32_t num_virtual) { 237e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light DCHECK_LE(num_direct + num_virtual, (new_methods == nullptr) ? 0 : new_methods->size()); 238e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light SetMethodsPtrInternal(new_methods); 239e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, copied_methods_offset_), 240e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light dchecked_integral_cast<uint16_t>(num_direct + num_virtual)); 241e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light SetFieldShort<false>(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_offset_), 242e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light dchecked_integral_cast<uint16_t>(num_direct)); 2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 245e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline void Class::SetMethodsPtrInternal(LengthPrefixedArray<ArtMethod>* new_methods) { 246e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light SetField64<false>(OFFSET_OF_OBJECT_MEMBER(Class, methods_), 247f4b3dbad413023795b92a842aad1c3f2fe4a57e9Mathieu Chartier static_cast<uint64_t>(reinterpret_cast<uintptr_t>(new_methods))); 2482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 251542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVirtualMethod(size_t i, PointerSize pointer_size) { 252e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 253f4c15a18eb055735857a280856be5b142e0c1113Hiroshi Yamauchi DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>()) 254709b070044354d9f47641f273edacaeeb0240ab7David Sehr << Class::PrettyClass() << " status=" << GetStatus(); 255e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVirtualMethodUnchecked(i, pointer_size); 2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 258542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVirtualMethodDuringLinking(size_t i, PointerSize pointer_size) { 259e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 261e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVirtualMethodUnchecked(i, pointer_size); 2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 264542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVirtualMethodUnchecked(size_t i, PointerSize pointer_size) { 265e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 266e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return &GetVirtualMethodsSliceUnchecked(pointer_size).At(i); 2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 269fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, 270fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ReadBarrierOption kReadBarrierOption> 271e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline PointerArray* Class::GetVTable() { 272063fc772b5b8aed7d769cd7cccb6ddc7619326eeMingyao Yang DCHECK(IsLoaded<kVerifyFlags>() || IsErroneous<kVerifyFlags>()); 273fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>( 274fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier OFFSET_OF_OBJECT_MEMBER(Class, vtable_)); 2752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 277e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline PointerArray* Class::GetVTableDuringLinking() { 2782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(IsLoaded() || IsErroneous()); 279e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetFieldObject<PointerArray>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_)); 2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 282e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetVTable(PointerArray* new_vtable) { 283b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable); 2842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2862cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline bool Class::HasVTable() { 287a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko return GetVTable() != nullptr || ShouldHaveEmbeddedVTable(); 2882cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 2892cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 2902cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline int32_t Class::GetVTableLength() { 291a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (ShouldHaveEmbeddedVTable()) { 2922cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang return GetEmbeddedVTableLength(); 2932cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang } 294e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVTable() != nullptr ? GetVTable()->GetLength() : 0; 2952cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 2962cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 297542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetVTableEntry(uint32_t i, PointerSize pointer_size) { 298a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (ShouldHaveEmbeddedVTable()) { 299e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetEmbeddedVTableEntry(i, pointer_size); 3002cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang } 301e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* vtable = GetVTable(); 302e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(vtable != nullptr); 303e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size); 3042cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 3052cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 3062cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline int32_t Class::GetEmbeddedVTableLength() { 307e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetField32(MemberOffset(EmbeddedVTableLengthOffset())); 3082cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 3092cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 3102cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yanginline void Class::SetEmbeddedVTableLength(int32_t len) { 311e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetField32<false>(MemberOffset(EmbeddedVTableLengthOffset()), len); 3122cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 3132cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 314542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ImTable* Class::GetImt(PointerSize pointer_size) { 315a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko return GetFieldPtrWithSize<ImTable*>(MemberOffset(ImtPtrOffset(pointer_size)), pointer_size); 316a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko} 317a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko 318542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline void Class::SetImt(ImTable* imt, PointerSize pointer_size) { 319a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko return SetFieldPtrWithSize<false>(MemberOffset(ImtPtrOffset(pointer_size)), imt, pointer_size); 320a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko} 321a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko 322542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::EmbeddedVTableEntryOffset(uint32_t i, PointerSize pointer_size) { 323e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return MemberOffset( 324e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier EmbeddedVTableOffset(pointer_size).Uint32Value() + i * VTableEntrySize(pointer_size)); 3252cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang} 3262cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang 327542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::GetEmbeddedVTableEntry(uint32_t i, PointerSize pointer_size) { 328e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetFieldPtrWithSize<ArtMethod*>(EmbeddedVTableEntryOffset(i, pointer_size), pointer_size); 329e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 330e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 331e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void Class::SetEmbeddedVTableEntryUnchecked( 332542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe uint32_t i, ArtMethod* method, PointerSize pointer_size) { 333e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetFieldPtrWithSize<false>(EmbeddedVTableEntryOffset(i, pointer_size), method, pointer_size); 334e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 335e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 336542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline void Class::SetEmbeddedVTableEntry(uint32_t i, ArtMethod* method, PointerSize pointer_size) { 337e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* vtable = GetVTableDuringLinking(); 338e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CHECK_EQ(method, vtable->GetElementPtrSize<ArtMethod*>(i, pointer_size)); 339e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier SetEmbeddedVTableEntryUnchecked(i, method, pointer_size); 34098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 34198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 34228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::Implements(ObjPtr<Class> klass) { 3432cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 344709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(klass->IsInterface()) << PrettyClass(); 345693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // All interfaces implemented directly and by our superclass, and 346693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // recursively all super-interfaces of those interfaces, are listed 347693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // in iftable_, so we can just do a linear scan through that. 348693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers int32_t iftable_count = GetIfTableCount(); 34928bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<IfTable> iftable = GetIfTable(); 350693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers for (int32_t i = 0; i < iftable_count; i++) { 351693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (iftable->GetInterface(i) == klass) { 352693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return true; 353693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 354693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 355693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return false; 356693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 357693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 358c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 359c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampeinline bool Class::IsVariableSize() { 360c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe // Classes, arrays, and strings vary in size, and so the object_size_ field cannot 361c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe // be used to Get their instance size 362c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe return IsClassClass<kVerifyFlags, kReadBarrierOption>() || 363c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe IsArrayClass<kVerifyFlags, kReadBarrierOption>() || 364c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe IsStringClass(); 365c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe} 366c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe 367c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampeinline void Class::SetObjectSize(uint32_t new_object_size) { 368c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe DCHECK(!IsVariableSize()); 369c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe // Not called within a transaction. 370c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), new_object_size); 371c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe} 372c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe 373693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Determine whether "this" is assignable from "src", where both of these 374693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// are array classes. 375693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// 376693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Consider an array class, e.g. Y[][], where Y is a subclass of X. 377693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Y[][] = Y[][] --> true (identity) 378693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// X[][] = Y[][] --> true (element superclass) 379693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Y = Y[][] --> false 380693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Y[] = Y[][] --> false 381693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object = Y[][] --> true (everything is an object) 382693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[] = Y[][] --> true 383693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[][] = Y[][] --> true 384693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[][][] = Y[][] --> false (too many []s) 385693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Serializable = Y[][] --> true (all arrays are Serializable) 386693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Serializable[] = Y[][] --> true 387693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Serializable[][] = Y[][] --> false (unless Y is Serializable) 388693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// 389693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Don't forget about primitive types. 390693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// Object[] = int[] --> false 391693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers// 3923398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsArrayAssignableFromArray(ObjPtr<Class> src) { 393709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(IsArrayClass()) << PrettyClass(); 394709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(src->IsArrayClass()) << src->PrettyClass(); 395693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return GetComponentType()->IsAssignableFrom(src->GetComponentType()); 396693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 397693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 3983398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsAssignableFromArray(ObjPtr<Class> src) { 399709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(!IsInterface()) << PrettyClass(); // handled first in IsAssignableFrom 400709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(src->IsArrayClass()) << src->PrettyClass(); 401693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (!IsArrayClass()) { 402693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // If "this" is not also an array, it must be Object. 403693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // src's super should be java_lang_Object, since it is an array. 40428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Class> java_lang_Object = src->GetSuperClass(); 405709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(java_lang_Object != nullptr) << src->PrettyClass(); 406709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(java_lang_Object->GetSuperClass() == nullptr) << src->PrettyClass(); 407693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return this == java_lang_Object; 408693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 409693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return IsArrayAssignableFromArray(src); 410693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 411693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 41289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <bool throw_on_failure, bool use_referrers_cache> 413b890130a66e167404a9a60cf0893a015538778caMathieu Chartierinline bool Class::ResolvedFieldAccessTest(ObjPtr<Class> access_to, 4143398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier ArtField* field, 4153398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier uint32_t field_idx, 416b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ObjPtr<DexCache> dex_cache) { 41789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko DCHECK_EQ(use_referrers_cache, dex_cache == nullptr); 41823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(access_to))) { 41923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // The referrer class can't access the field's declaring class but may still be able 42023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // to access the field if the FieldId specifies an accessible subclass of the declaring 42123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // class rather than the declaring class itself. 422b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; 423a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetFieldId(field_idx).class_idx_; 424279ac5c060a1a642c786730e3f2b05d556c00839Mathieu Chartier // The referenced class has already been resolved with the field, but may not be in the dex 425b890130a66e167404a9a60cf0893a015538778caMathieu Chartier // cache. Use LookupResolveType here to search the class table if it is not in the dex cache. 426279ac5c060a1a642c786730e3f2b05d556c00839Mathieu Chartier // should be no thread suspension due to the class being resolved. 427b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType( 428b890130a66e167404a9a60cf0893a015538778caMathieu Chartier *referrer_dex_cache->GetDexFile(), 429b890130a66e167404a9a60cf0893a015538778caMathieu Chartier class_idx, 430b890130a66e167404a9a60cf0893a015538778caMathieu Chartier referrer_dex_cache, 431b890130a66e167404a9a60cf0893a015538778caMathieu Chartier access_to->GetClassLoader()); 43223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko DCHECK(dex_access_to != nullptr); 43323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(dex_access_to))) { 43423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 4356b3d12b3d233734bb6669faccddcba7abeb5ea99Mathieu Chartier ThrowIllegalAccessErrorClass(this, dex_access_to); 43623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 43723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 43823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 43923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 44023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (LIKELY(this->CanAccessMember(access_to, field->GetAccessFlags()))) { 44123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return true; 44223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 44323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 44423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko ThrowIllegalAccessErrorField(this, field); 44523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 44623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 44723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko} 44823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko 44989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <bool throw_on_failure, bool use_referrers_cache, InvokeType throw_invoke_type> 450b890130a66e167404a9a60cf0893a015538778caMathieu Chartierinline bool Class::ResolvedMethodAccessTest(ObjPtr<Class> access_to, 451b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ArtMethod* method, 452b890130a66e167404a9a60cf0893a015538778caMathieu Chartier uint32_t method_idx, 453b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ObjPtr<DexCache> dex_cache) { 454575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe static_assert(throw_on_failure || throw_invoke_type == kStatic, "Non-default throw invoke type"); 45589786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko DCHECK_EQ(use_referrers_cache, dex_cache == nullptr); 45623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(access_to))) { 45723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // The referrer class can't access the method's declaring class but may still be able 45823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // to access the method if the MethodId specifies an accessible subclass of the declaring 45923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko // class rather than the declaring class itself. 460b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ObjPtr<DexCache> referrer_dex_cache = use_referrers_cache ? this->GetDexCache() : dex_cache; 461a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe dex::TypeIndex class_idx = referrer_dex_cache->GetDexFile()->GetMethodId(method_idx).class_idx_; 462279ac5c060a1a642c786730e3f2b05d556c00839Mathieu Chartier // The referenced class has already been resolved with the method, but may not be in the dex 463b890130a66e167404a9a60cf0893a015538778caMathieu Chartier // cache. 464b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ObjPtr<Class> dex_access_to = Runtime::Current()->GetClassLinker()->LookupResolvedType( 465b890130a66e167404a9a60cf0893a015538778caMathieu Chartier *referrer_dex_cache->GetDexFile(), 466b890130a66e167404a9a60cf0893a015538778caMathieu Chartier class_idx, 467b890130a66e167404a9a60cf0893a015538778caMathieu Chartier referrer_dex_cache, 468b890130a66e167404a9a60cf0893a015538778caMathieu Chartier access_to->GetClassLoader()); 46923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko DCHECK(dex_access_to != nullptr); 47023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (UNLIKELY(!this->CanAccess(dex_access_to))) { 47123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 472b890130a66e167404a9a60cf0893a015538778caMathieu Chartier ThrowIllegalAccessErrorClassForMethodDispatch(this, 4731cc62e4ea24828fdb3f3da0b8603f0b107d09a04Mathieu Chartier dex_access_to.Ptr(), 474b890130a66e167404a9a60cf0893a015538778caMathieu Chartier method, 475b890130a66e167404a9a60cf0893a015538778caMathieu Chartier throw_invoke_type); 47623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 47723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 47823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 47923a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 48023a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (LIKELY(this->CanAccessMember(access_to, method->GetAccessFlags()))) { 48123a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return true; 48223a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 48323a282146042a0d171aec2a415176f5d0621a90cVladimir Marko if (throw_on_failure) { 48423a282146042a0d171aec2a415176f5d0621a90cVladimir Marko ThrowIllegalAccessErrorMethod(this, method); 48523a282146042a0d171aec2a415176f5d0621a90cVladimir Marko } 48623a282146042a0d171aec2a415176f5d0621a90cVladimir Marko return false; 48723a282146042a0d171aec2a415176f5d0621a90cVladimir Marko} 48823a282146042a0d171aec2a415176f5d0621a90cVladimir Marko 4893398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CanAccessResolvedField(ObjPtr<Class> access_to, 4903398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier ArtField* field, 4913398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier ObjPtr<DexCache> dex_cache, 4923398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier uint32_t field_idx) { 493b890130a66e167404a9a60cf0893a015538778caMathieu Chartier return ResolvedFieldAccessTest<false, false>(access_to, field, field_idx, dex_cache); 49489786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 49589786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 4963398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CheckResolvedFieldAccess(ObjPtr<Class> access_to, 4973398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier ArtField* field, 49889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko uint32_t field_idx) { 499f8ac97f94aad9ce2d324c2c7c21dde3abf13315bMathieu Chartier return ResolvedFieldAccessTest<true, true>(access_to, field, field_idx, nullptr); 50089786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 50189786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 50228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::CanAccessResolvedMethod(ObjPtr<Class> access_to, 50328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ArtMethod* method, 50428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<DexCache> dex_cache, 50528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier uint32_t method_idx) { 506ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return ResolvedMethodAccessTest<false, false, kStatic>(access_to, method, method_idx, dex_cache); 50789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 50889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 50989786437f4c0176b35ca0376153dd18ab7df4924Vladimir Markotemplate <InvokeType throw_invoke_type> 51028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::CheckResolvedMethodAccess(ObjPtr<Class> access_to, 51128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ArtMethod* method, 51289786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko uint32_t method_idx) { 51328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier return ResolvedMethodAccessTest<true, true, throw_invoke_type>(access_to, 51428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier method, 51528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier method_idx, 51689786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko nullptr); 51789786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko} 51889786437f4c0176b35ca0376153dd18ab7df4924Vladimir Marko 5193398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsSubClass(ObjPtr<Class> klass) { 520709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(!IsInterface()) << PrettyClass(); 521709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(!IsArrayClass()) << PrettyClass(); 5223398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier ObjPtr<Class> current = this; 523693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers do { 524693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (current == klass) { 525693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return true; 526693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 527693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers current = current->GetSuperClass(); 5282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier } while (current != nullptr); 529693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers return false; 530693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 531693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 532542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::FindVirtualMethodForInterface(ArtMethod* method, 533542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 53428bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Class> declaring_class = method->GetDeclaringClass(); 535709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(declaring_class != nullptr) << PrettyClass(); 536709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(declaring_class->IsInterface()) << method->PrettyMethod(); 5370f7e8f59698265d416d40844233bb09d02e7fc33Alex Light DCHECK(!method->IsCopied()); 538693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers // TODO cache to improve lookup speed 539e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const int32_t iftable_count = GetIfTableCount(); 54028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<IfTable> iftable = GetIfTable(); 541693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers for (int32_t i = 0; i < iftable_count; i++) { 542693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers if (iftable->GetInterface(i) == declaring_class) { 543e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return iftable->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>( 544e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier method->GetMethodIndex(), pointer_size); 545693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 546693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers } 5472cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier return nullptr; 548693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers} 549693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers 550542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::FindVirtualMethodForVirtual(ArtMethod* method, PointerSize pointer_size) { 551eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light // Only miranda or default methods may come from interfaces and be used as a virtual. 552eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light DCHECK(!method->GetDeclaringClass()->IsInterface() || method->IsDefault() || method->IsMiranda()); 5532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // The argument method may from a super class. 5542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Use the index to a potentially overridden one for this instance's class. 555e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetVTableEntry(method->GetMethodIndex(), pointer_size); 5562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 558542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline ArtMethod* Class::FindVirtualMethodForSuper(ArtMethod* method, PointerSize pointer_size) { 5592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(!method->GetDeclaringClass()->IsInterface()); 560e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetSuperClass()->GetVTableEntry(method->GetMethodIndex(), pointer_size); 5612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 563e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* Class::FindVirtualMethodForVirtualOrInterface(ArtMethod* method, 564542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 5652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (method->IsDirect()) { 5662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return method; 5672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 5683612149aee482ab7a17da68b0ef5fef3879729a2Alex Light if (method->GetDeclaringClass()->IsInterface() && !method->IsCopied()) { 569e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return FindVirtualMethodForInterface(method, pointer_size); 5702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 571e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return FindVirtualMethodForVirtual(method, pointer_size); 5722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 574fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, 575fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ReadBarrierOption kReadBarrierOption> 576ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline IfTable* Class::GetIfTable() { 5776beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier ObjPtr<IfTable> ret = GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset()); 5786beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier DCHECK(ret != nullptr) << PrettyClass(this); 5796beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier return ret.Ptr(); 5802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 582ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline int32_t Class::GetIfTableCount() { 5836beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier return GetIfTable()->Count(); 5842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 58628bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) { 5876beced4c017826f7c449f12fac7fa42403657f2bMathieu Chartier DCHECK(new_iftable != nullptr) << PrettyClass(this); 5882ecfd270adb29861b493de51cfb8670e276e0c5eMathieu Chartier SetFieldObject<false>(IfTableOffset(), new_iftable); 5892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 59154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtr() { 592fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK(IsLoaded() || IsErroneous()) << GetStatus(); 59354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)); 5942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 5965496f69c0a4c2cc357a065f57b7f4ff5d9ad2fa9Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 59776649e8d775519fe19f2b14d18ac488c13296054Vladimir Markoinline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() { 59828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Class> super_class = GetSuperClass<kVerifyFlags, kReadBarrierOption>(); 59976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko return (super_class != nullptr) 6007a62e6728463237684d3d9834d81bd7bba7ab197Hiroshi Yamauchi ? MemberOffset(RoundUp(super_class->GetObjectSize<kVerifyFlags, kReadBarrierOption>(), 60128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier kHeapReferenceSize)) 60276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko : ClassOffset(); 60376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko} 60476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko 605dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 606542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::GetFirstReferenceStaticFieldOffset(PointerSize pointer_size) { 60776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko DCHECK(IsResolved()); 60828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier uint32_t base = sizeof(Class); // Static fields come after the class. 609a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (ShouldHaveEmbeddedVTable<kVerifyFlags, kReadBarrierOption>()) { 61076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko // Static fields come after the embedded tables. 61128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier base = Class::ComputeClassSize( 612e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier true, GetEmbeddedVTableLength(), 0, 0, 0, 0, 0, pointer_size); 61376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 61476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko return MemberOffset(base); 61576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko} 61676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko 617542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking( 618542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 61976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko DCHECK(IsLoaded()); 62028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier uint32_t base = sizeof(Class); // Static fields come after the class. 621a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (ShouldHaveEmbeddedVTable()) { 62276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko // Static fields come after the embedded tables. 62328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier base = Class::ComputeClassSize(true, GetVTableDuringLinking()->GetLength(), 624e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 0, 0, 0, 0, 0, pointer_size); 62576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 62676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko return MemberOffset(base); 62776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko} 62876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko 62954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetIFieldsPtr(LengthPrefixedArray<ArtField>* new_ifields) { 63054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier DCHECK(GetIFieldsPtrUnchecked() == nullptr); 631c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields); 6322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 63454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetIFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_ifields) { 635c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields); 6362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 63854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtrUnchecked() { 63954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)); 6402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 64254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetIFieldsPtrUnchecked() { 64354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetFieldPtr<LengthPrefixedArray<ArtField>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)); 6442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 64654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline LengthPrefixedArray<ArtField>* Class::GetSFieldsPtr() { 647c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK(IsLoaded() || IsErroneous()) << GetStatus(); 64854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return GetSFieldsPtrUnchecked(); 6492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 65154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetSFieldsPtr(LengthPrefixedArray<ArtField>* new_sfields) { 652c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK((IsRetired() && new_sfields == nullptr) || 653c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr); 654c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields); 6552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 65754d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline void Class::SetSFieldsPtrUnchecked(LengthPrefixedArray<ArtField>* new_sfields) { 658c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields); 6592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 661c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* Class::GetStaticField(uint32_t i) { 66254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return &GetSFieldsPtr()->At(i); 6632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 665c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierinline ArtField* Class::GetInstanceField(uint32_t i) { 66654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier return &GetIFieldsPtr()->At(i); 6672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 669b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 670b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline uint32_t Class::GetReferenceInstanceOffsets() { 671b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers DCHECK(IsResolved<kVerifyFlags>() || IsErroneous<kVerifyFlags>()); 672b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_)); 673b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 674b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 675b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) { 676b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (Runtime::Current()->IsActiveTransaction()) { 677b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id); 678b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } else { 679b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id); 680b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 681b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 682b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 683ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline String* Class::GetName() { 684b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(Class, name_)); 6852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 68652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier 6871a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartierinline void Class::SetName(ObjPtr<String> name) { 688d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (Runtime::Current()->IsActiveTransaction()) { 689b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name); 690d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 691b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, name_), name); 692d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 695b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 696b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline Primitive::Type Class::GetPrimitiveType() { 69733d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain static_assert(sizeof(Primitive::Type) == sizeof(int32_t), 69833d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain "art::Primitive::Type and int32_t have different sizes."); 699f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)); 7008261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier Primitive::Type type = static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask); 7018261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier DCHECK_EQ(static_cast<size_t>(v32 >> kPrimitiveTypeSizeShiftShift), 7028261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier Primitive::ComponentSizeShift(type)); 703f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi return type; 704f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi} 705f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi 706f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags> 707f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchiinline size_t Class::GetPrimitiveTypeSizeShift() { 70833d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain static_assert(sizeof(Primitive::Type) == sizeof(int32_t), 70933d6903e570daf8f3cf7c1f6ebd9a6dd22c7c23cRoland Levillain "art::Primitive::Type and int32_t have different sizes."); 710f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi int32_t v32 = GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_)); 7118261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier size_t size_shift = static_cast<Primitive::Type>(v32 >> kPrimitiveTypeSizeShiftShift); 7128261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier DCHECK_EQ(size_shift, 7138261d02f9523b95013108f271b82bb157ef6f71dMathieu Chartier Primitive::ComponentSizeShift(static_cast<Primitive::Type>(v32 & kPrimitiveTypeMask))); 714f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi return size_shift; 715b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 716b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 7173b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchiinline void Class::CheckObjectAlloc() { 7184cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi DCHECK(!IsArrayClass()) 719709b070044354d9f47641f273edacaeeb0240ab7David Sehr << PrettyClass() 7204cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "A array shouldn't be allocated through this " 7214cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "as it requires a pre-fence visitor that sets the class size."; 7224cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi DCHECK(!IsClassClass()) 723709b070044354d9f47641f273edacaeeb0240ab7David Sehr << PrettyClass() 7244cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "A class object shouldn't be allocated through this " 7254cd662e54440f76fc920cb2c67acab3bba8b33ddHiroshi Yamauchi << "as it requires a pre-fence visitor that sets the class size."; 726848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao DCHECK(!IsStringClass()) 727709b070044354d9f47641f273edacaeeb0240ab7David Sehr << PrettyClass() 728848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao << "A string shouldn't be allocated through this " 729848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao << "as it requires a pre-fence visitor that sets the class size."; 730709b070044354d9f47641f273edacaeeb0240ab7David Sehr DCHECK(IsInstantiable()) << PrettyClass(); 731967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi // TODO: decide whether we want this check. It currently fails during bootstrap. 732709b070044354d9f47641f273edacaeeb0240ab7David Sehr // DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(); 733967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi DCHECK_GE(this->object_size_, sizeof(Object)); 7343b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi} 7353b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi 7368668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartiertemplate<bool kIsInstrumented, bool kCheckAddFinalizer> 73728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline ObjPtr<Object> Class::Alloc(Thread* self, gc::AllocatorType allocator_type) { 7383b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi CheckObjectAlloc(); 739590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier gc::Heap* heap = Runtime::Current()->GetHeap(); 7408668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier const bool add_finalizer = kCheckAddFinalizer && IsFinalizable(); 7418668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier if (!kCheckAddFinalizer) { 7428668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier DCHECK(!IsFinalizable()); 7438668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier } 7449d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier // Note that the this pointer may be invalidated after the allocation. 74528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Object> obj = 7469d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier heap->AllocObjectWithAllocator<kIsInstrumented, false>(self, 7479d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier this, 7489d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier this->object_size_, 7499d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier allocator_type, 7509d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier VoidFunctor()); 7518668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier if (add_finalizer && LIKELY(obj != nullptr)) { 7528668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier heap->AddFinalizerReference(self, &obj); 7533ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski if (UNLIKELY(self->IsExceptionPending())) { 7543ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski // Failed to allocate finalizer reference, it means that the whole allocation failed. 7553ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski obj = nullptr; 7563ac90da48e9cd56eb4b392c7f176e9267d146500Pavel Vyssotski } 7578668c3cbdcf9471bd97e0da68a240051f2973074Mathieu Chartier } 7589d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier return obj.Ptr(); 759cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} 760cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier 76128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline ObjPtr<Object> Class::AllocObject(Thread* self) { 762cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); 763cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier} 764cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier 76528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline ObjPtr<Object> Class::AllocNonMovableObject(Thread* self) { 766cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier return Alloc<true>(self, Runtime::Current()->GetHeap()->GetCurrentNonMovingAllocator()); 767967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi} 768967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi 769a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenkoinline uint32_t Class::ComputeClassSize(bool has_embedded_vtable, 77098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t num_vtable_entries, 77137f05ef45e0393de812d51261dc293240c17294dFred Shih uint32_t num_8bit_static_fields, 77237f05ef45e0393de812d51261dc293240c17294dFred Shih uint32_t num_16bit_static_fields, 77398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t num_32bit_static_fields, 77498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t num_64bit_static_fields, 775e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t num_ref_static_fields, 776542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 77798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used by java.lang.Class and its instance fields. 77898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t size = sizeof(Class); 77998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used by embedded tables. 780a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (has_embedded_vtable) { 781542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe size = RoundUp(size + sizeof(uint32_t), static_cast<size_t>(pointer_size)); 782542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe size += static_cast<size_t>(pointer_size); // size of pointer to IMT 783a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko size += num_vtable_entries * VTableEntrySize(pointer_size); 78498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang } 78537f05ef45e0393de812d51261dc293240c17294dFred Shih 78698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used by reference statics. 78728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier size += num_ref_static_fields * kHeapReferenceSize; 78837f05ef45e0393de812d51261dc293240c17294dFred Shih if (!IsAligned<8>(size) && num_64bit_static_fields > 0) { 78937f05ef45e0393de812d51261dc293240c17294dFred Shih uint32_t gap = 8 - (size & 0x7); 79037f05ef45e0393de812d51261dc293240c17294dFred Shih size += gap; // will be padded 79137f05ef45e0393de812d51261dc293240c17294dFred Shih // Shuffle 4-byte fields forward. 79237f05ef45e0393de812d51261dc293240c17294dFred Shih while (gap >= sizeof(uint32_t) && num_32bit_static_fields != 0) { 79337f05ef45e0393de812d51261dc293240c17294dFred Shih --num_32bit_static_fields; 79437f05ef45e0393de812d51261dc293240c17294dFred Shih gap -= sizeof(uint32_t); 79537f05ef45e0393de812d51261dc293240c17294dFred Shih } 79637f05ef45e0393de812d51261dc293240c17294dFred Shih // Shuffle 2-byte fields forward. 79737f05ef45e0393de812d51261dc293240c17294dFred Shih while (gap >= sizeof(uint16_t) && num_16bit_static_fields != 0) { 79837f05ef45e0393de812d51261dc293240c17294dFred Shih --num_16bit_static_fields; 79937f05ef45e0393de812d51261dc293240c17294dFred Shih gap -= sizeof(uint16_t); 80037f05ef45e0393de812d51261dc293240c17294dFred Shih } 80137f05ef45e0393de812d51261dc293240c17294dFred Shih // Shuffle byte fields forward. 80237f05ef45e0393de812d51261dc293240c17294dFred Shih while (gap >= sizeof(uint8_t) && num_8bit_static_fields != 0) { 80337f05ef45e0393de812d51261dc293240c17294dFred Shih --num_8bit_static_fields; 80437f05ef45e0393de812d51261dc293240c17294dFred Shih gap -= sizeof(uint8_t); 8052cdbad7c62f126581ec5177104de961c4d71adaaMingyao Yang } 80698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang } 80737f05ef45e0393de812d51261dc293240c17294dFred Shih // Guaranteed to be at least 4 byte aligned. No need for further alignments. 80898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Space used for primitive static fields. 809e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size += num_8bit_static_fields * sizeof(uint8_t) + num_16bit_static_fields * sizeof(uint16_t) + 810e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier num_32bit_static_fields * sizeof(uint32_t) + num_64bit_static_fields * sizeof(uint64_t); 81198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang return size; 81298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 81398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 8144f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchitemplate<ReadBarrierOption kReadBarrierOption> 8154ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline bool Class::IsReferenceClass() const { 8164ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih return this == Reference::GetJavaLangRefReference<kReadBarrierOption>(); 8174ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 8184ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 81925023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 82025023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchiinline bool Class::IsClassClass() { 82128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()-> 82225023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi template GetClass<kVerifyFlags, kReadBarrierOption>(); 82325023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi return this == java_lang_Class; 82425023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi} 82525023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi 826f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartierinline const DexFile& Class::GetDexFile() { 827bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier // From-space version is the same as the to-space version since the dex file never changes. 828bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier // Avoiding the read barrier here is important to prevent recursive AssertToSpaceInvariant issues 829bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier // from PrettyTypeOf. 830bc632f05acd06f9000e67517fdeb8296f739e079Mathieu Chartier return *GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetDexFile(); 831f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier} 832f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier 833f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartierinline bool Class::DescriptorEquals(const char* match) { 8341ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers if (IsArrayClass()) { 835f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier return match[0] == '[' && GetComponentType()->DescriptorEquals(match + 1); 8361ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers } else if (IsPrimitive()) { 837f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier return strcmp(Primitive::Descriptor(GetPrimitiveType()), match) == 0; 8383a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray } else if (IsProxyClass()) { 8393a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return ProxyDescriptorEquals(match); 840f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else { 841f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier const DexFile& dex_file = GetDexFile(); 842f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_); 843f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier return strcmp(dex_file.GetTypeDescriptor(type_id), match) == 0; 844f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } 845f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier} 846f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier 8474e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertzinline void Class::AssertInitializedOrInitializingInThread(Thread* self) { 8484e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz if (kIsDebugBuild && !IsInitialized()) { 849709b070044354d9f47641f273edacaeeb0240ab7David Sehr CHECK(IsInitializing()) << PrettyClass() << " is not initializing: " << GetStatus(); 850709b070044354d9f47641f273edacaeeb0240ab7David Sehr CHECK_EQ(GetClinitThreadId(), self->GetTid()) << PrettyClass() 8514e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz << " is initializing in a different thread"; 8524e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz } 8534e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz} 8544e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz 8556b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bdNarayan Kamathinline ObjectArray<Class>* Class::GetProxyInterfaces() { 8563a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray CHECK(IsProxyClass()); 85798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // First static field. 858c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(0); 859c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "interfaces"); 860c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier MemberOffset field_offset = field->GetOffset(); 8613a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return GetFieldObject<ObjectArray<Class>>(field_offset); 86298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 86398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 8646b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bdNarayan Kamathinline ObjectArray<ObjectArray<Class>>* Class::GetProxyThrows() { 8653a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray CHECK(IsProxyClass()); 86698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Second static field. 867c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(1); 868c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "throws"); 869c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier MemberOffset field_offset = field->GetOffset(); 8703a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset); 87198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 87298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 8734ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline MemberOffset Class::GetDisableIntrinsicFlagOffset() { 8744ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih CHECK(IsReferenceClass()); 8754ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih // First static field 876c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(0); 877c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "disableIntrinsic"); 878c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return field->GetOffset(); 8794ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 8804ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 8814ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline MemberOffset Class::GetSlowPathFlagOffset() { 8824ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih CHECK(IsReferenceClass()); 8834ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih // Second static field 884c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier auto* field = GetStaticField(1); 885c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier DCHECK_STREQ(field->GetName(), "slowPathEnabled"); 886c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier return field->GetOffset(); 8874ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 8884ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 8894ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline bool Class::GetSlowPathEnabled() { 89037f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldBoolean(GetSlowPathFlagOffset()); 8914ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 8924ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 8934ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shihinline void Class::SetSlowPath(bool enabled) { 894310008008c90fea246efd00cb99ee7ded97c5209Mathieu Chartier SetFieldBoolean<false, false>(GetSlowPathFlagOffset(), enabled); 8954ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih} 8964ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih 89728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline void Class::InitializeClassVisitor::operator()(ObjPtr<Object> obj, 8989d156d500801accee919b6d51e22d6ddcdcd4a05Mathieu Chartier size_t usable_size) const { 89998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang DCHECK_LE(class_size_, usable_size); 90098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang // Avoid AsClass as object is not yet in live bitmap or allocation stack. 90128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Class> klass = ObjPtr<Class>::DownCast(obj); 90298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetClassSize(class_size_); 90398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive. 90498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index. 905a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe klass->SetDexTypeIndex(dex::TypeIndex(DexFile::kDexNoIndex16)); // Default to no valid type 906a5b09a67034e57a6e10231dd4bd92f4cb50b824cAndreas Gampe // index. 90793bbee0c1c97bd9a5336ed0c9e41cd17613df585Mathieu Chartier // Default to force slow path until initialized. 908161db1dea4808d32db3623cc1a8e91b53df0fb02Mathieu Chartier klass->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max()); 90998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 91098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 91148498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampeinline void Class::SetAccessFlags(uint32_t new_access_flags) { 91248498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe // Called inside a transaction when setting pre-verified flag during boot image compilation. 91348498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe if (Runtime::Current()->IsActiveTransaction()) { 91452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<true>(AccessFlagsOffset(), new_access_flags); 91552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 91652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<false>(AccessFlagsOffset(), new_access_flags); 91752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 91852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier} 91952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier 92052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartierinline void Class::SetClassFlags(uint32_t new_flags) { 92152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (Runtime::Current()->IsActiveTransaction()) { 92252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags); 92348498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe } else { 92452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, class_flags_), new_flags); 92548498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe } 92648498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe} 92748498591b90a8ff7b24b1ce05c220e3bc42013dfAndreas Gampe 9282d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartierinline uint32_t Class::NumDirectInterfaces() { 9292d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier if (IsPrimitive()) { 9302d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return 0; 9312d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } else if (IsArrayClass()) { 9322d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return 2; 9333a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray } else if (IsProxyClass()) { 9346b2dc3156a2140a5bfd9cbbf5d7dad332ab5f5bdNarayan Kamath ObjectArray<Class>* interfaces = GetProxyInterfaces(); 9352d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return interfaces != nullptr ? interfaces->GetLength() : 0; 9362d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } else { 9372d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier const DexFile::TypeList* interfaces = GetInterfaceTypeList(); 9382d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier if (interfaces == nullptr) { 9392d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return 0; 9402d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } else { 9412d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return interfaces->Size(); 9422d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } 9432d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier } 9442d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier} 9452d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier 946542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetDirectMethods(PointerSize pointer_size) { 947e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 948e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetDirectMethodsSliceUnchecked(pointer_size).AsRange(); 949e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 950e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 951e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline IterationRange<StrideIterator<ArtMethod>> Class::GetDeclaredMethods( 952542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 953e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetDeclaredMethodsSliceUnchecked(pointer_size).AsRange(); 954e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 955e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 956e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline IterationRange<StrideIterator<ArtMethod>> Class::GetDeclaredVirtualMethods( 957542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 958e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetDeclaredVirtualMethodsSliceUnchecked(pointer_size).AsRange(); 959e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 960e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 961542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetVirtualMethods( 962542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size) { 963e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 964e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetVirtualMethodsSliceUnchecked(pointer_size).AsRange(); 965e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 966e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 967542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetCopiedMethods(PointerSize pointer_size) { 968e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light CheckPointerSize(pointer_size); 969e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetCopiedMethodsSliceUnchecked(pointer_size).AsRange(); 970e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 971e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 972e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 973542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline IterationRange<StrideIterator<ArtMethod>> Class::GetMethods(PointerSize pointer_size) { 974e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light CheckPointerSize(pointer_size); 975e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return MakeIterationRangeFromLengthPrefixedArray(GetMethodsPtr(), 97614632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Size(pointer_size), 97714632857428b7e37761e6e811c19021715a400f8Vladimir Marko ArtMethod::Alignment(pointer_size)); 978e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 979e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 98054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetIFields() { 981cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtr()); 982e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 983e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 98454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetSFields() { 985cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtr()); 986e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 987e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 98854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetIFieldsUnchecked() { 989cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetIFieldsPtrUnchecked()); 990e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 991e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 99254d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline IterationRange<StrideIterator<ArtField>> Class::GetSFieldsUnchecked() { 993cf36d493124d8048efa0bd6f67d817ce3cd6b725Vladimir Marko return MakeIterationRangeFromLengthPrefixedArray(GetSFieldsPtrUnchecked()); 994e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 995e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 996542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline MemberOffset Class::EmbeddedVTableOffset(PointerSize pointer_size) { 997e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckPointerSize(pointer_size); 998542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe return MemberOffset(ImtPtrOffset(pointer_size).Uint32Value() + static_cast<size_t>(pointer_size)); 999e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 1000e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 1001542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampeinline void Class::CheckPointerSize(PointerSize pointer_size) { 1002e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize()); 1003c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier} 1004c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier 10052e76830f0b3f23825677436c0633714402715099Calin Juravletemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 10062e76830f0b3f23825677436c0633714402715099Calin Juravleinline Class* Class::GetComponentType() { 10072e76830f0b3f23825677436c0633714402715099Calin Juravle return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ComponentTypeOffset()); 10082e76830f0b3f23825677436c0633714402715099Calin Juravle} 10092e76830f0b3f23825677436c0633714402715099Calin Juravle 10102e76830f0b3f23825677436c0633714402715099Calin Juravletemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 10112e76830f0b3f23825677436c0633714402715099Calin Juravleinline bool Class::IsArrayClass() { 10122e76830f0b3f23825677436c0633714402715099Calin Juravle return GetComponentType<kVerifyFlags, kReadBarrierOption>() != nullptr; 10132e76830f0b3f23825677436c0633714402715099Calin Juravle} 10142e76830f0b3f23825677436c0633714402715099Calin Juravle 1015c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 1016c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampeinline bool Class::IsObjectArrayClass() { 1017c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe ObjPtr<Class> const component_type = GetComponentType<kVerifyFlags, kReadBarrierOption>(); 1018c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe return component_type != nullptr && !component_type->IsPrimitive(); 1019c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe} 1020c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe 10213398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::IsAssignableFrom(ObjPtr<Class> src) { 10222e76830f0b3f23825677436c0633714402715099Calin Juravle DCHECK(src != nullptr); 10232e76830f0b3f23825677436c0633714402715099Calin Juravle if (this == src) { 10242e76830f0b3f23825677436c0633714402715099Calin Juravle // Can always assign to things of the same type. 10252e76830f0b3f23825677436c0633714402715099Calin Juravle return true; 10262e76830f0b3f23825677436c0633714402715099Calin Juravle } else if (IsObjectClass()) { 10272e76830f0b3f23825677436c0633714402715099Calin Juravle // Can assign any reference to java.lang.Object. 10282e76830f0b3f23825677436c0633714402715099Calin Juravle return !src->IsPrimitive(); 10292e76830f0b3f23825677436c0633714402715099Calin Juravle } else if (IsInterface()) { 10302e76830f0b3f23825677436c0633714402715099Calin Juravle return src->Implements(this); 10312e76830f0b3f23825677436c0633714402715099Calin Juravle } else if (src->IsArrayClass()) { 10322e76830f0b3f23825677436c0633714402715099Calin Juravle return IsAssignableFromArray(src); 10332e76830f0b3f23825677436c0633714402715099Calin Juravle } else { 10342e76830f0b3f23825677436c0633714402715099Calin Juravle return !src->IsInterface() && src->IsSubClass(this); 10352e76830f0b3f23825677436c0633714402715099Calin Juravle } 10362e76830f0b3f23825677436c0633714402715099Calin Juravle} 10372e76830f0b3f23825677436c0633714402715099Calin Juravle 103854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumDirectMethods() { 1039e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetVirtualMethodsStartOffset(); 1040e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light} 1041e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light 1042e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Lightinline uint32_t Class::NumDeclaredVirtualMethods() { 1043e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return GetCopiedMethodsStartOffset() - GetVirtualMethodsStartOffset(); 104454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 104554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 104654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumVirtualMethods() { 1047e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light return NumMethods() - GetVirtualMethodsStartOffset(); 104854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 104954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 105054d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumInstanceFields() { 105154d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtField>* arr = GetIFieldsPtrUnchecked(); 105235831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return arr != nullptr ? arr->size() : 0u; 105354d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 105454d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 105554d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartierinline uint32_t Class::NumStaticFields() { 105654d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier LengthPrefixedArray<ArtField>* arr = GetSFieldsPtrUnchecked(); 105735831e8bfa1c0944d4c978d99c4c5b9577945170Vladimir Marko return arr != nullptr ? arr->size() : 0u; 105854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier} 105954d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier 1060dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor> 106128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline void Class::FixupNativePointers(Class* dest, 1062542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe PointerSize pointer_size, 10634b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier const Visitor& visitor) { 10644b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier // Update the field arrays. 10654b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const sfields = GetSFieldsPtr(); 10664b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const new_sfields = visitor(sfields); 10674b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (sfields != new_sfields) { 10684b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetSFieldsPtrUnchecked(new_sfields); 10694b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 10704b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const ifields = GetIFieldsPtr(); 10714b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier LengthPrefixedArray<ArtField>* const new_ifields = visitor(ifields); 10724b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (ifields != new_ifields) { 10734b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetIFieldsPtrUnchecked(new_ifields); 10744b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 1075e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light // Update method array. 1076e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light LengthPrefixedArray<ArtMethod>* methods = GetMethodsPtr(); 1077e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light LengthPrefixedArray<ArtMethod>* new_methods = visitor(methods); 1078e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light if (methods != new_methods) { 1079e64300b8488716056775ecbfa2915dd1b4ce7e08Alex Light dest->SetMethodsPtrInternal(new_methods); 10804b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 10814b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier // Fix up embedded tables. 1082a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) { 10834b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) { 10844b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier ArtMethod* method = GetEmbeddedVTableEntry(i, pointer_size); 10858c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier void** dest_addr = reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(dest) + 10868c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier EmbeddedVTableEntryOffset(i, pointer_size).Uint32Value()); 10878c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier ArtMethod* new_method = visitor(method, dest_addr); 10884b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier if (method != new_method) { 10894b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier dest->SetEmbeddedVTableEntryUnchecked(i, new_method, pointer_size); 10904b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 10914b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 1092a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko } 1093a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko if (!IsTemp() && ShouldHaveImt<kVerifyNone, kReadBarrierOption>()) { 1094a62cb9bb6cb2278cb41ab0664191623e178c6a4fArtem Udovichenko dest->SetImt(visitor(GetImt(pointer_size)), pointer_size); 10954b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier } 10964b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier} 10974b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier 10983398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CanAccess(ObjPtr<Class> that) { 10993398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return that->IsPublic() || this->IsInSamePackage(that); 11003398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier} 11013398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier 11023398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier 11033398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartierinline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flags) { 11043398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier // Classes can access all of their own members 11053398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier if (this == access_to) { 11063398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return true; 11073398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier } 11083398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier // Public members are trivially accessible 11093398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier if (member_flags & kAccPublic) { 11103398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return true; 11113398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier } 11123398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier // Private members are trivially not accessible 11133398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier if (member_flags & kAccPrivate) { 11143398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return false; 11153398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier } 11163398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier // Check for protected access from a sub-class, which may or may not be in the same package. 11173398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier if (member_flags & kAccProtected) { 11183398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier if (!this->IsInterface() && this->IsSubClass(access_to)) { 11193398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return true; 11203398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier } 11213398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier } 11223398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier // Allow protected access from other classes in the same package. 11233398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier return this->IsInSamePackage(access_to); 11243398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier} 11253398c7874e002beaa6c2b2fadf183e7d1ddad23aMathieu Chartier 112628bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartierinline bool Class::CannotBeAssignedFromOtherTypes() { 112728bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier if (!IsArrayClass()) { 112828bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier return IsFinal(); 112928bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier } 113028bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier ObjPtr<Class> component = GetComponentType(); 113128bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier return component->IsPrimitive() || component->CannotBeAssignedFromOtherTypes(); 113228bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier} 113328bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier 11342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 11352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 11362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1137fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_CLASS_INL_H_ 1138