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 17e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#ifndef ART_RUNTIME_ART_METHOD_INL_H_ 18e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define ART_RUNTIME_ART_METHOD_INL_H_ 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 20ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_method.h" 212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2258a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe#include "art_field.h" 237c0fe5e99d1d150b3072a3ae4cd0f0362fe32834Mathieu Chartier#include "base/logging.h" 2400370827646cc21cb370c3e7e93f9c0cff4c30c2Hiroshi Yamauchi#include "class_linker-inl.h" 2505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko#include "common_throws.h" 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "dex_file.h" 27956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes#include "dex_file-inl.h" 28e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "gc_root-inl.h" 295550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray#include "jit/profiling_info.h" 30e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "mirror/class-inl.h" 3105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko#include "mirror/dex_cache-inl.h" 32e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "mirror/object-inl.h" 33e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "mirror/object_array.h" 3496c6ab93336b972a38bd2448bcccf19188b8389bVladimir Marko#include "oat.h" 357624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "quick/quick_method_frame_info.h" 3698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang#include "read_barrier-inl.h" 377624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko#include "runtime-inl.h" 38cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe#include "scoped_thread_state_change.h" 39cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe#include "thread-inl.h" 4080afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 44e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartiertemplate <ReadBarrierOption kReadBarrierOption> 45e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() { 463f64f25151780fdea3511be62b4fe50775f86541Hiroshi Yamauchi GcRootSource gc_root_source(this); 47e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier return declaring_class_.Read<kReadBarrierOption>(&gc_root_source); 4898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 4998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 50e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartiertemplate <ReadBarrierOption kReadBarrierOption> 51e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline mirror::Class* ArtMethod::GetDeclaringClass() { 52e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier mirror::Class* result = GetDeclaringClassUnchecked<kReadBarrierOption>(); 53e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (kIsDebugBuild) { 54e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (!IsRuntimeMethod()) { 55e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CHECK(result != nullptr) << this; 56e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CHECK(result->IsIdxLoaded() || result->IsErroneous()) 57e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << result->GetStatus() << " " << PrettyClass(result); 58e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } else { 59e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CHECK(result == nullptr) << this; 60e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 61e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 65e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline void ArtMethod::SetDeclaringClass(mirror::Class* new_declaring_class) { 66e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier declaring_class_ = GcRoot<mirror::Class>(new_declaring_class); 672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 6910e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartierinline bool ArtMethod::CASDeclaringClass(mirror::Class* expected_class, 7010e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier mirror::Class* desired_class) { 7110e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier GcRoot<mirror::Class> expected_root(expected_class); 7210e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier GcRoot<mirror::Class> desired_root(desired_class); 7310e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier return reinterpret_cast<Atomic<GcRoot<mirror::Class>>*>(&declaring_class_)-> 7410e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier CompareExchangeStrongSequentiallyConsistent( 7510e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier expected_root, desired_root); 7610e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier} 7710e5ea90e20375e5ad2ff26cb760c0e7c586cc16Mathieu Chartier 78cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe// AssertSharedHeld doesn't work in GetAccessFlags, so use a NO_THREAD_SAFETY_ANALYSIS helper. 79cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe// TODO: Figure out why ASSERT_SHARED_CAPABILITY doesn't work. 80e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartiertemplate <ReadBarrierOption kReadBarrierOption> 81e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu ChartierALWAYS_INLINE static inline void DoGetAccessFlagsHelper(ArtMethod* method) 82e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier NO_THREAD_SAFETY_ANALYSIS { 83e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier CHECK(method->IsRuntimeMethod() || 84e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier method->GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() || 85e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier method->GetDeclaringClass<kReadBarrierOption>()->IsErroneous()); 86cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe} 87cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe 88e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartiertemplate <ReadBarrierOption kReadBarrierOption> 89ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint32_t ArtMethod::GetAccessFlags() { 90cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe if (kIsDebugBuild) { 91cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe Thread* self = Thread::Current(); 92cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe if (!Locks::mutator_lock_->IsSharedHeld(self)) { 93cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe ScopedObjectAccess soa(self); 94e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier CHECK(IsRuntimeMethod() || 95e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() || 96e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier GetDeclaringClass<kReadBarrierOption>()->IsErroneous()); 97cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe } else { 98cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe // We cannot use SOA in this case. We might be holding the lock, but may not be in the 99cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe // runnable state (e.g., during GC). 100cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe Locks::mutator_lock_->AssertSharedHeld(self); 101e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier DoGetAccessFlagsHelper<kReadBarrierOption>(this); 102cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe } 103cbc96b802f505ebcc71bb505c9a069ebec66df49Andreas Gampe } 104e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return access_flags_; 1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 107ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint16_t ArtMethod::GetMethodIndex() { 108e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsResolved() || 109e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier GetDeclaringClass()->IsErroneous()); 110e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return method_index_; 1112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1139f3629df89b7f2b4f7a599bdc5f7eeb748330582Mathieu Chartierinline uint16_t ArtMethod::GetMethodIndexDuringLinking() { 114e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return method_index_; 1159f3629df89b7f2b4f7a599bdc5f7eeb748330582Mathieu Chartier} 1169f3629df89b7f2b4f7a599bdc5f7eeb748330582Mathieu Chartier 117ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline uint32_t ArtMethod::GetDexMethodIndex() { 118e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() || 119e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier GetDeclaringClass()->IsErroneous()); 120e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return dex_method_index_; 1212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 12305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline ArtMethod** ArtMethod::GetDexCacheResolvedMethods(size_t pointer_size) { 12405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetNativePointer<ArtMethod**>(DexCacheResolvedMethodsOffset(pointer_size), 12505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko pointer_size); 1264f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers} 1274f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 128e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index, size_t ptr_size) { 12905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here 13005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko // without accessing the DexCache and we don't want to do that in release build. 13105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko DCHECK_LT(method_index, 13205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko GetInterfaceMethodIfProxy(ptr_size)->GetDeclaringClass() 13305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ->GetDexCache()->NumResolvedMethods()); 13405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ArtMethod* method = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(ptr_size), 13505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko method_index, 13605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ptr_size); 137e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (LIKELY(method != nullptr)) { 138e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* declaring_class = method->GetDeclaringClass(); 139e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (LIKELY(declaring_class == nullptr || !declaring_class->IsErroneous())) { 140e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return method; 141e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } 14258a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe } 143e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return nullptr; 14458a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 14558a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 14605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_index, ArtMethod* new_method, 147e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier size_t ptr_size) { 14805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here 14905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko // without accessing the DexCache and we don't want to do that in release build. 15005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko DCHECK_LT(method_index, 15105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko GetInterfaceMethodIfProxy(ptr_size)->GetDeclaringClass() 15205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ->GetDexCache()->NumResolvedMethods()); 153e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr); 15405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::DexCache::SetElementPtrSize(GetDexCacheResolvedMethods(ptr_size), 15505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko method_index, 15605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko new_method, 15705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ptr_size); 15858a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 15958a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 16005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::HasDexCacheResolvedMethods(size_t pointer_size) { 16105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedMethods(pointer_size) != nullptr; 16258a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 16358a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 16405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod** other_cache, 16505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t pointer_size) { 16605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedMethods(pointer_size) == other_cache; 16758a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 16858a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 16905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other, size_t pointer_size) { 17005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedMethods(pointer_size) == 17105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko other->GetDexCacheResolvedMethods(pointer_size); 17258a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 17358a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 17405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline GcRoot<mirror::Class>* ArtMethod::GetDexCacheResolvedTypes(size_t pointer_size) { 17505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetNativePointer<GcRoot<mirror::Class>*>(DexCacheResolvedTypesOffset(pointer_size), 17605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko pointer_size); 1774f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers} 1784f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers 17958a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampetemplate <bool kWithCheck> 18005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index, size_t ptr_size) { 18105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko if (kWithCheck) { 18205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::DexCache* dex_cache = 18305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko GetInterfaceMethodIfProxy(ptr_size)->GetDeclaringClass()->GetDexCache(); 18405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko if (UNLIKELY(type_index >= dex_cache->NumResolvedTypes())) { 18505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ThrowArrayIndexOutOfBoundsException(type_index, dex_cache->NumResolvedTypes()); 18605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return nullptr; 18705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko } 18805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko } 18905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::Class* klass = GetDexCacheResolvedTypes(ptr_size)[type_index].Read(); 19058a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr; 19158a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 19258a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 19305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::HasDexCacheResolvedTypes(size_t pointer_size) { 19405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedTypes(pointer_size) != nullptr; 19558a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 19658a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 19705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::HasSameDexCacheResolvedTypes(GcRoot<mirror::Class>* other_cache, 19805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t pointer_size) { 19905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedTypes(pointer_size) == other_cache; 20058a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 20158a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 20205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other, size_t pointer_size) { 20305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedTypes(pointer_size) == other->GetDexCacheResolvedTypes(pointer_size); 20458a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe} 20558a5af8568d224ca7eccf2483396ff9862f8d1eeAndreas Gampe 20605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::Class* ArtMethod::GetClassFromTypeIndex(uint16_t type_idx, 20705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko bool resolve, 20805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t ptr_size) { 20905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::Class* type = GetDexCacheResolvedType(type_idx, ptr_size); 210a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers if (type == nullptr && resolve) { 211a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, this); 212a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); 213a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers } 214a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers return type; 215a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers} 216a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers 217ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrominline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) { 2182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers switch (type) { 2192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case kStatic: 2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return !IsStatic(); 2212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case kDirect: 2222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return !IsDirect() || IsStatic(); 2232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case kVirtual: { 224eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light // We have an error if we are direct or a non-default, non-miranda interface method. 225e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier mirror::Class* methods_class = GetDeclaringClass(); 226eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light return IsDirect() || (methods_class->IsInterface() && !IsDefault() && !IsMiranda()); 2272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case kSuper: 2298f252e64c75b22dfdfea490751929732653f848cAndreas Gampe // Constructors and static methods are called with invoke-direct. 230705ad49f353d3f90d8b63625aca2c2035bacdbefAlex Light return IsConstructor() || IsStatic(); 2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers case kInterface: { 232e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier mirror::Class* methods_class = GetDeclaringClass(); 2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass()); 2342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers default: 2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers LOG(FATAL) << "Unreachable - invocation type: " << type; 2372c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 2382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 241ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool ArtMethod::IsRuntimeMethod() { 242e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return dex_method_index_ == DexFile::kDexNoIndex; 2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 245ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool ArtMethod::IsCalleeSaveMethod() { 2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (!IsRuntimeMethod()) { 2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return false; 2482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Runtime* runtime = Runtime::Current(); 2502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool result = false; 2512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 2522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) { 2532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers result = true; 2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers break; 2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 2582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 260ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool ArtMethod::IsResolutionMethod() { 2612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers bool result = this == Runtime::Current()->GetResolutionMethod(); 2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Check that if we do think it is phony it looks like the resolution method. 2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(!result || IsRuntimeMethod()); 2642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 2652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 26688474b416eb257078e590bf9bc7957cee604a186Jeff Hao 2672d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartierinline bool ArtMethod::IsImtUnimplementedMethod() { 2682d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier bool result = this == Runtime::Current()->GetImtUnimplementedMethod(); 2692d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier // Check that if we do think it is phony it looks like the imt unimplemented method. 2702d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier DCHECK(!result || IsRuntimeMethod()); 2712d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return result; 2722d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier} 2732d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier 274bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const DexFile* ArtMethod::GetDexFile() { 2752d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier return GetDexCache()->GetDexFile(); 276bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 277bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 278bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const char* ArtMethod::GetDeclaringClassDescriptor() { 279e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t dex_method_idx = GetDexMethodIndex(); 280bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) { 281bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<runtime method>"; 282bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 283e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 284e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 285bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx)); 286bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 287bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 288bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const char* ArtMethod::GetShorty(uint32_t* out_length) { 2893a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray DCHECK(!IsProxyMethod()); 290e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 291e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length); 292bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 293bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 294bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const Signature ArtMethod::GetSignature() { 295e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t dex_method_idx = GetDexMethodIndex(); 296bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier if (dex_method_idx != DexFile::kDexNoIndex) { 297e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 298e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 299bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx)); 300bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 301bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return Signature::NoSignature(); 302bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 303bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 3041ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogersinline const char* ArtMethod::GetName() { 305e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier uint32_t dex_method_idx = GetDexMethodIndex(); 306bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) { 307e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 308e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 309bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx)); 310bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 311e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier Runtime* const runtime = Runtime::Current(); 312e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (this == runtime->GetResolutionMethod()) { 313bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<runtime internal resolution method>"; 314e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } else if (this == runtime->GetImtConflictMethod()) { 315bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<runtime internal imt conflict method>"; 316e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) { 317bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<runtime internal callee-save all registers method>"; 318e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } else if (this == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) { 319bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<runtime internal callee-save reference registers method>"; 320e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier } else if (this == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) { 321bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<runtime internal callee-save reference and argument registers method>"; 322bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } else { 323bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return "<unknown runtime internal method>"; 324bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 325bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 326bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 327bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const DexFile::CodeItem* ArtMethod::GetCodeItem() { 32812b3dd738acd8cfff17fb167e93061dc276936d7Mathieu Chartier return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset()); 329bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 330bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 33105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx, size_t ptr_size) { 332e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 33305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetDexCacheResolvedType(type_idx, ptr_size) != nullptr; 334bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 335bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 336bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) { 337e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 338bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier if (dex_pc == DexFile::kDexNoIndex) { 339e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return IsNative() ? -2 : -1; 340bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 341e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDexFile()->GetLineNumFromPC(this, dex_pc); 342bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 343bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 344bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const DexFile::ProtoId& ArtMethod::GetPrototype() { 345e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 346e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 347e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return dex_file->GetMethodPrototype(dex_file->GetMethodId(GetDexMethodIndex())); 348bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 349bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 350bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const DexFile::TypeList* ArtMethod::GetParameterTypeList() { 3513a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray DCHECK(!IsProxyMethod()); 352e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 3533a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray const DexFile::ProtoId& proto = dex_file->GetMethodPrototype( 3543a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray dex_file->GetMethodId(GetDexMethodIndex())); 355bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return dex_file->GetProtoParameters(proto); 356bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 357bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 358bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const char* ArtMethod::GetDeclaringClassSourceFile() { 359e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 360e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDeclaringClass()->GetSourceFile(); 361bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 362bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 363bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline uint16_t ArtMethod::GetClassDefIndex() { 364e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 365e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDeclaringClass()->GetDexClassDefIndex(); 366bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 367bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 368bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const DexFile::ClassDef& ArtMethod::GetClassDef() { 369e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 370e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDexFile()->GetClassDef(GetClassDefIndex()); 371bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 372bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 373bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const char* ArtMethod::GetReturnTypeDescriptor() { 374e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 375e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 376e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); 377bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 378bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint16_t return_type_idx = proto_id.return_type_idx_; 379bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx)); 380bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 381bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 382bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) { 383e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 384e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile* dex_file = GetDexFile(); 385bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx)); 386bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 387bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 388bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline mirror::ClassLoader* ArtMethod::GetClassLoader() { 389e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(!IsProxyMethod()); 390e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDeclaringClass()->GetClassLoader(); 391bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 392bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 393bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartierinline mirror::DexCache* ArtMethod::GetDexCache() { 3943a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray DCHECK(!IsProxyMethod()); 395e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return GetDeclaringClass()->GetDexCache(); 396bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 397bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 39803b6eafba8ace9a9c4d5ee9c47723d1910ccd7a8Ian Rogersinline bool ArtMethod::IsProxyMethod() { 3993a0909248e04b22c3981cbf617bc2502ed5b6380Nicolas Geoffray return GetDeclaringClass()->IsProxyClass(); 40003b6eafba8ace9a9c4d5ee9c47723d1910ccd7a8Ian Rogers} 40103b6eafba8ace9a9c4d5ee9c47723d1910ccd7a8Ian Rogers 402e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(size_t pointer_size) { 40303b6eafba8ace9a9c4d5ee9c47723d1910ccd7a8Ian Rogers if (LIKELY(!IsProxyMethod())) { 404bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return this; 405bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier } 40603b6eafba8ace9a9c4d5ee9c47723d1910ccd7a8Ian Rogers mirror::Class* klass = GetDeclaringClass(); 40705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize( 40805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko GetDexCacheResolvedMethods(pointer_size), 40905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko GetDexMethodIndex(), 41005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko pointer_size); 411bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier DCHECK(interface_method != nullptr); 412bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier DCHECK_EQ(interface_method, 413bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this)); 414bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier return interface_method; 415bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier} 416bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier 41705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline void ArtMethod::SetDexCacheResolvedMethods(ArtMethod** new_dex_cache_methods, 41805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t ptr_size) { 41905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko SetNativePointer(DexCacheResolvedMethodsOffset(ptr_size), new_dex_cache_methods, ptr_size); 4202d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier} 4212d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier 42205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline void ArtMethod::SetDexCacheResolvedTypes(GcRoot<mirror::Class>* new_dex_cache_types, 42305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t ptr_size) { 42405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko SetNativePointer(DexCacheResolvedTypesOffset(ptr_size), new_dex_cache_types, ptr_size); 4252d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier} 4262d2621a1463d2f3f03fa73503fa42e43657cdcfcMathieu Chartier 42705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::Class* ArtMethod::GetReturnType(bool resolve, size_t ptr_size) { 428ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers DCHECK(!IsProxyMethod()); 429ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers const DexFile* dex_file = GetDexFile(); 430ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); 431ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); 432ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers uint16_t return_type_idx = proto_id.return_type_idx_; 43305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::Class* type = GetDexCacheResolvedType(return_type_idx, ptr_size); 434ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers if (type == nullptr && resolve) { 435ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this); 436ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); 437ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers } 438ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers return type; 439ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers} 440ded66a01f81812e0129d17c3d08d5eda18433062Ian Rogers 441e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<typename RootVisitorType> 4421147b9bd68323c753ed1a0b6106b205fd640c820Mathieu Chartiervoid ArtMethod::VisitRoots(RootVisitorType& visitor, size_t pointer_size) { 44305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko ArtMethod* interface_method = nullptr; 44405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::Class* klass = declaring_class_.Read(); 445dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray if (LIKELY(klass != nullptr)) { 446dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray if (UNLIKELY(klass->IsProxyClass())) { 447dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray // For normal methods, dex cache shortcuts will be visited through the declaring class. 448dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray // However, for proxies we need to keep the interface method alive, so we visit its roots. 449dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray interface_method = mirror::DexCache::GetElementPtrSize( 450dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray GetDexCacheResolvedMethods(pointer_size), 451dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray GetDexMethodIndex(), 452dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray pointer_size); 453dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray DCHECK(interface_method != nullptr); 454dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray DCHECK_EQ(interface_method, 455dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this)); 456dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray interface_method->VisitRoots(visitor, pointer_size); 457dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray } 458dec3a12c45e160097e6938be3778a6175113c42fNicolas Geoffray visitor.VisitRoot(declaring_class_.AddressWithoutBarrier()); 459e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray // We know we don't have profiling information if the class hasn't been verified. Note 460e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray // that this check also ensures the IsNative call can be made, as IsNative expects a fully 461e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray // created class (and not a retired one). 462e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray if (klass->IsVerified()) { 463e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray // Runtime methods and native methods use the same field as the profiling info for 464e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray // storing their own data (jni entrypoint for native methods, and ImtConflictTable for 465e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray // some runtime methods). 466e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray if (!IsNative() && !IsRuntimeMethod()) { 467e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray ProfilingInfo* profiling_info = GetProfilingInfo(pointer_size); 468e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray if (profiling_info != nullptr) { 469e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray profiling_info->VisitRoots(visitor); 470e128d749ce7c1f88ba3e66223d8c69f9dc9255aeNicolas Geoffray } 471b79eb75ba5671b787ac0622ded2de970f8f0d2c1Hiroshi Yamauchi } 472b79eb75ba5671b787ac0622ded2de970f8f0d2c1Hiroshi Yamauchi } 4735550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray } 474e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 475e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 476fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate <typename Visitor> 4770b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartierinline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor, 4780b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier size_t pointer_size) { 479e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier mirror::Class* old_class = GetDeclaringClassUnchecked<kWithoutReadBarrier>(); 480fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier mirror::Class* new_class = visitor(old_class); 481fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (old_class != new_class) { 482fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier SetDeclaringClass(new_class); 483fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 4840b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier ArtMethod** old_methods = GetDexCacheResolvedMethods(pointer_size); 485fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ArtMethod** new_methods = visitor(old_methods); 486fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (old_methods != new_methods) { 4870b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier SetDexCacheResolvedMethods(new_methods, pointer_size); 488fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 4890b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier GcRoot<mirror::Class>* old_types = GetDexCacheResolvedTypes(pointer_size); 490fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier GcRoot<mirror::Class>* new_types = visitor(old_types); 491fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (old_types != new_types) { 4920b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier SetDexCacheResolvedTypes(new_types, pointer_size); 493fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 494fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier} 495fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 496e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartiertemplate <ReadBarrierOption kReadBarrierOption, typename Visitor> 4970b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartierinline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, size_t pointer_size) { 498e7f75f35371cf32954d94f9bb10fc96924f7edb4Mathieu Chartier if (IsNative<kReadBarrierOption>()) { 4990b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier const void* old_native_code = GetEntryPointFromJniPtrSize(pointer_size); 500fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const void* new_native_code = visitor(old_native_code); 501fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (old_native_code != new_native_code) { 5020b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier SetEntryPointFromJniPtrSize(new_native_code, pointer_size); 503fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 504fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } else { 5050b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier DCHECK(GetEntryPointFromJniPtrSize(pointer_size) == nullptr); 506fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 5070b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); 508fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const void* new_code = visitor(old_code); 509fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (old_code != new_code) { 5100b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size); 511fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 512fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier} 513fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 5142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 5152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 516e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#endif // ART_RUNTIME_ART_METHOD_INL_H_ 517