Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_ART_METHOD_INL_H_
     18 #define ART_RUNTIME_ART_METHOD_INL_H_
     19 
     20 #include "art_method.h"
     21 
     22 #include "art_field.h"
     23 #include "base/logging.h"
     24 #include "class_linker-inl.h"
     25 #include "common_throws.h"
     26 #include "dex_file.h"
     27 #include "dex_file_annotations.h"
     28 #include "dex_file-inl.h"
     29 #include "gc_root-inl.h"
     30 #include "jit/profiling_info.h"
     31 #include "mirror/class-inl.h"
     32 #include "mirror/dex_cache-inl.h"
     33 #include "mirror/object-inl.h"
     34 #include "mirror/object_array.h"
     35 #include "mirror/string.h"
     36 #include "oat.h"
     37 #include "obj_ptr-inl.h"
     38 #include "quick/quick_method_frame_info.h"
     39 #include "read_barrier-inl.h"
     40 #include "runtime-inl.h"
     41 #include "scoped_thread_state_change-inl.h"
     42 #include "thread-inl.h"
     43 #include "utils.h"
     44 
     45 namespace art {
     46 
     47 template <ReadBarrierOption kReadBarrierOption>
     48 inline mirror::Class* ArtMethod::GetDeclaringClassUnchecked() {
     49   GcRootSource gc_root_source(this);
     50   return declaring_class_.Read<kReadBarrierOption>(&gc_root_source);
     51 }
     52 
     53 template <ReadBarrierOption kReadBarrierOption>
     54 inline mirror::Class* ArtMethod::GetDeclaringClass() {
     55   mirror::Class* result = GetDeclaringClassUnchecked<kReadBarrierOption>();
     56   if (kIsDebugBuild) {
     57     if (!IsRuntimeMethod()) {
     58       CHECK(result != nullptr) << this;
     59       if (kCheckDeclaringClassState) {
     60         if (!(result->IsIdxLoaded() || result->IsErroneous())) {
     61           LOG(FATAL_WITHOUT_ABORT) << "Class status: " << result->GetStatus();
     62           LOG(FATAL) << result->PrettyClass();
     63         }
     64       }
     65     } else {
     66       CHECK(result == nullptr) << this;
     67     }
     68   }
     69   return result;
     70 }
     71 
     72 inline void ArtMethod::SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class) {
     73   declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
     74 }
     75 
     76 inline bool ArtMethod::CASDeclaringClass(mirror::Class* expected_class,
     77                                          mirror::Class* desired_class) {
     78   GcRoot<mirror::Class> expected_root(expected_class);
     79   GcRoot<mirror::Class> desired_root(desired_class);
     80   return reinterpret_cast<Atomic<GcRoot<mirror::Class>>*>(&declaring_class_)->
     81       CompareExchangeStrongSequentiallyConsistent(
     82           expected_root, desired_root);
     83 }
     84 
     85 inline uint16_t ArtMethod::GetMethodIndex() {
     86   DCHECK(IsRuntimeMethod() || GetDeclaringClass()->IsResolved());
     87   return method_index_;
     88 }
     89 
     90 inline uint16_t ArtMethod::GetMethodIndexDuringLinking() {
     91   return method_index_;
     92 }
     93 
     94 inline uint32_t ArtMethod::GetDexMethodIndex() {
     95   if (kCheckDeclaringClassState) {
     96     CHECK(IsRuntimeMethod() || GetDeclaringClass()->IsIdxLoaded() ||
     97           GetDeclaringClass()->IsErroneous());
     98   }
     99   return GetDexMethodIndexUnchecked();
    100 }
    101 
    102 inline ArtMethod** ArtMethod::GetDexCacheResolvedMethods(PointerSize pointer_size) {
    103   return GetNativePointer<ArtMethod**>(DexCacheResolvedMethodsOffset(pointer_size),
    104                                        pointer_size);
    105 }
    106 
    107 inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index,
    108                                                        PointerSize pointer_size) {
    109   // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here
    110   // without accessing the DexCache and we don't want to do that in release build.
    111   DCHECK_LT(method_index,
    112             GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods());
    113   ArtMethod* method = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
    114                                                           method_index,
    115                                                           pointer_size);
    116   if (LIKELY(method != nullptr)) {
    117     auto* declaring_class = method->GetDeclaringClass();
    118     if (LIKELY(declaring_class == nullptr || !declaring_class->IsErroneous())) {
    119       return method;
    120     }
    121   }
    122   return nullptr;
    123 }
    124 
    125 inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_index,
    126                                                  ArtMethod* new_method,
    127                                                  PointerSize pointer_size) {
    128   // NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here
    129   // without accessing the DexCache and we don't want to do that in release build.
    130   DCHECK_LT(method_index,
    131             GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods());
    132   DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr);
    133   mirror::DexCache::SetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
    134                                       method_index,
    135                                       new_method,
    136                                       pointer_size);
    137 }
    138 
    139 inline bool ArtMethod::HasDexCacheResolvedMethods(PointerSize pointer_size) {
    140   return GetDexCacheResolvedMethods(pointer_size) != nullptr;
    141 }
    142 
    143 inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod** other_cache,
    144                                                       PointerSize pointer_size) {
    145   return GetDexCacheResolvedMethods(pointer_size) == other_cache;
    146 }
    147 
    148 inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other, PointerSize pointer_size) {
    149   return GetDexCacheResolvedMethods(pointer_size) ==
    150       other->GetDexCacheResolvedMethods(pointer_size);
    151 }
    152 
    153 inline mirror::Class* ArtMethod::GetClassFromTypeIndex(dex::TypeIndex type_idx, bool resolve) {
    154   // TODO: Refactor this function into two functions, Resolve...() and Lookup...()
    155   // so that we can properly annotate it with no-suspension possible / suspension possible.
    156   ObjPtr<mirror::DexCache> dex_cache = GetDexCache();
    157   ObjPtr<mirror::Class> type = dex_cache->GetResolvedType(type_idx);
    158   if (UNLIKELY(type == nullptr)) {
    159     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    160     if (resolve) {
    161       type = class_linker->ResolveType(type_idx, this);
    162       CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
    163     } else {
    164       type = class_linker->LookupResolvedType(
    165           *dex_cache->GetDexFile(), type_idx, dex_cache, GetClassLoader());
    166     }
    167   }
    168   return type.Ptr();
    169 }
    170 
    171 inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
    172   switch (type) {
    173     case kStatic:
    174       return !IsStatic();
    175     case kDirect:
    176       return !IsDirect() || IsStatic();
    177     case kVirtual: {
    178       // We have an error if we are direct or a non-copied (i.e. not part of a real class) interface
    179       // method.
    180       mirror::Class* methods_class = GetDeclaringClass();
    181       return IsDirect() || (methods_class->IsInterface() && !IsCopied());
    182     }
    183     case kSuper:
    184       // Constructors and static methods are called with invoke-direct.
    185       return IsConstructor() || IsStatic();
    186     case kInterface: {
    187       mirror::Class* methods_class = GetDeclaringClass();
    188       return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
    189     }
    190     default:
    191       LOG(FATAL) << "Unreachable - invocation type: " << type;
    192       UNREACHABLE();
    193   }
    194 }
    195 
    196 inline bool ArtMethod::IsCalleeSaveMethod() {
    197   if (!IsRuntimeMethod()) {
    198     return false;
    199   }
    200   Runtime* runtime = Runtime::Current();
    201   bool result = false;
    202   for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
    203     if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
    204       result = true;
    205       break;
    206     }
    207   }
    208   return result;
    209 }
    210 
    211 inline bool ArtMethod::IsResolutionMethod() {
    212   bool result = this == Runtime::Current()->GetResolutionMethod();
    213   // Check that if we do think it is phony it looks like the resolution method.
    214   DCHECK(!result || IsRuntimeMethod());
    215   return result;
    216 }
    217 
    218 inline bool ArtMethod::IsImtUnimplementedMethod() {
    219   bool result = this == Runtime::Current()->GetImtUnimplementedMethod();
    220   // Check that if we do think it is phony it looks like the imt unimplemented method.
    221   DCHECK(!result || IsRuntimeMethod());
    222   return result;
    223 }
    224 
    225 inline const DexFile* ArtMethod::GetDexFile() {
    226   // It is safe to avoid the read barrier here since the dex file is constant, so if we read the
    227   // from-space dex file pointer it will be equal to the to-space copy.
    228   return GetDexCache<kWithoutReadBarrier>()->GetDexFile();
    229 }
    230 
    231 inline const char* ArtMethod::GetDeclaringClassDescriptor() {
    232   uint32_t dex_method_idx = GetDexMethodIndex();
    233   if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
    234     return "<runtime method>";
    235   }
    236   DCHECK(!IsProxyMethod());
    237   const DexFile* dex_file = GetDexFile();
    238   return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx));
    239 }
    240 
    241 inline const char* ArtMethod::GetShorty() {
    242   uint32_t unused_length;
    243   return GetShorty(&unused_length);
    244 }
    245 
    246 inline const char* ArtMethod::GetShorty(uint32_t* out_length) {
    247   DCHECK(!IsProxyMethod());
    248   const DexFile* dex_file = GetDexFile();
    249   return dex_file->GetMethodShorty(dex_file->GetMethodId(GetDexMethodIndex()), out_length);
    250 }
    251 
    252 inline const Signature ArtMethod::GetSignature() {
    253   uint32_t dex_method_idx = GetDexMethodIndex();
    254   if (dex_method_idx != DexFile::kDexNoIndex) {
    255     DCHECK(!IsProxyMethod());
    256     const DexFile* dex_file = GetDexFile();
    257     return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx));
    258   }
    259   return Signature::NoSignature();
    260 }
    261 
    262 inline const char* ArtMethod::GetName() {
    263   uint32_t dex_method_idx = GetDexMethodIndex();
    264   if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
    265     DCHECK(!IsProxyMethod());
    266     const DexFile* dex_file = GetDexFile();
    267     return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx));
    268   }
    269   Runtime* const runtime = Runtime::Current();
    270   if (this == runtime->GetResolutionMethod()) {
    271     return "<runtime internal resolution method>";
    272   } else if (this == runtime->GetImtConflictMethod()) {
    273     return "<runtime internal imt conflict method>";
    274   } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveAllCalleeSaves)) {
    275     return "<runtime internal callee-save all registers method>";
    276   } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveRefsOnly)) {
    277     return "<runtime internal callee-save reference registers method>";
    278   } else if (this == runtime->GetCalleeSaveMethod(Runtime::kSaveRefsAndArgs)) {
    279     return "<runtime internal callee-save reference and argument registers method>";
    280   } else {
    281     return "<unknown runtime internal method>";
    282   }
    283 }
    284 
    285 inline const DexFile::CodeItem* ArtMethod::GetCodeItem() {
    286   return GetDexFile()->GetCodeItem(GetCodeItemOffset());
    287 }
    288 
    289 inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx) {
    290   DCHECK(!IsProxyMethod());
    291   return GetClassFromTypeIndex(type_idx, /* resolve */ false) != nullptr;
    292 }
    293 
    294 inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) {
    295   DCHECK(!IsProxyMethod());
    296   if (dex_pc == DexFile::kDexNoIndex) {
    297     return IsNative() ? -2 : -1;
    298   }
    299   return annotations::GetLineNumFromPC(GetDexFile(), this, dex_pc);
    300 }
    301 
    302 inline const DexFile::ProtoId& ArtMethod::GetPrototype() {
    303   DCHECK(!IsProxyMethod());
    304   const DexFile* dex_file = GetDexFile();
    305   return dex_file->GetMethodPrototype(dex_file->GetMethodId(GetDexMethodIndex()));
    306 }
    307 
    308 inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() {
    309   DCHECK(!IsProxyMethod());
    310   const DexFile* dex_file = GetDexFile();
    311   const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(
    312       dex_file->GetMethodId(GetDexMethodIndex()));
    313   return dex_file->GetProtoParameters(proto);
    314 }
    315 
    316 inline const char* ArtMethod::GetDeclaringClassSourceFile() {
    317   DCHECK(!IsProxyMethod());
    318   return GetDeclaringClass()->GetSourceFile();
    319 }
    320 
    321 inline uint16_t ArtMethod::GetClassDefIndex() {
    322   DCHECK(!IsProxyMethod());
    323   if (LIKELY(!IsObsolete())) {
    324     return GetDeclaringClass()->GetDexClassDefIndex();
    325   } else {
    326     return FindObsoleteDexClassDefIndex();
    327   }
    328 }
    329 
    330 inline const DexFile::ClassDef& ArtMethod::GetClassDef() {
    331   DCHECK(!IsProxyMethod());
    332   return GetDexFile()->GetClassDef(GetClassDefIndex());
    333 }
    334 
    335 inline const char* ArtMethod::GetReturnTypeDescriptor() {
    336   DCHECK(!IsProxyMethod());
    337   const DexFile* dex_file = GetDexFile();
    338   const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
    339   const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
    340   return dex_file->GetTypeDescriptor(dex_file->GetTypeId(proto_id.return_type_idx_));
    341 }
    342 
    343 inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx) {
    344   DCHECK(!IsProxyMethod());
    345   const DexFile* dex_file = GetDexFile();
    346   return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx));
    347 }
    348 
    349 inline mirror::ClassLoader* ArtMethod::GetClassLoader() {
    350   DCHECK(!IsProxyMethod());
    351   return GetDeclaringClass()->GetClassLoader();
    352 }
    353 
    354 template <ReadBarrierOption kReadBarrierOption>
    355 inline mirror::DexCache* ArtMethod::GetDexCache() {
    356   if (LIKELY(!IsObsolete())) {
    357     mirror::Class* klass = GetDeclaringClass<kReadBarrierOption>();
    358     return klass->GetDexCache<kDefaultVerifyFlags, kReadBarrierOption>();
    359   } else {
    360     DCHECK(!IsProxyMethod());
    361     return GetObsoleteDexCache();
    362   }
    363 }
    364 
    365 inline bool ArtMethod::IsProxyMethod() {
    366   // Avoid read barrier since the from-space version of the class will have the correct proxy class
    367   // flags since they are constant for the lifetime of the class.
    368   return GetDeclaringClass<kWithoutReadBarrier>()->IsProxyClass();
    369 }
    370 
    371 inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy(PointerSize pointer_size) {
    372   if (LIKELY(!IsProxyMethod())) {
    373     return this;
    374   }
    375   ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize(
    376       GetDexCacheResolvedMethods(pointer_size),
    377       GetDexMethodIndex(),
    378       pointer_size);
    379   DCHECK(interface_method != nullptr);
    380   DCHECK_EQ(interface_method,
    381             Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
    382   return interface_method;
    383 }
    384 
    385 inline void ArtMethod::SetDexCacheResolvedMethods(ArtMethod** new_dex_cache_methods,
    386                                                   PointerSize pointer_size) {
    387   SetNativePointer(DexCacheResolvedMethodsOffset(pointer_size),
    388                    new_dex_cache_methods,
    389                    pointer_size);
    390 }
    391 
    392 inline mirror::Class* ArtMethod::GetReturnType(bool resolve) {
    393   DCHECK(!IsProxyMethod());
    394   const DexFile* dex_file = GetDexFile();
    395   const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex());
    396   const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
    397   dex::TypeIndex return_type_idx = proto_id.return_type_idx_;
    398   return GetClassFromTypeIndex(return_type_idx, resolve);
    399 }
    400 
    401 inline bool ArtMethod::HasSingleImplementation() {
    402   if (IsFinal() || GetDeclaringClass()->IsFinal()) {
    403     // We don't set kAccSingleImplementation for these cases since intrinsic
    404     // can use the flag also.
    405     return true;
    406   }
    407   return (GetAccessFlags() & kAccSingleImplementation) != 0;
    408 }
    409 
    410 inline void ArtMethod::SetIntrinsic(uint32_t intrinsic) {
    411   DCHECK(IsUint<8>(intrinsic));
    412   // Currently we only do intrinsics for static/final methods or methods of final
    413   // classes. We don't set kHasSingleImplementation for those methods.
    414   DCHECK(IsStatic() || IsFinal() || GetDeclaringClass()->IsFinal()) <<
    415       "Potential conflict with kAccSingleImplementation";
    416   uint32_t new_value = (GetAccessFlags() & kAccFlagsNotUsedByIntrinsic) |
    417       kAccIntrinsic |
    418       (intrinsic << POPCOUNT(kAccFlagsNotUsedByIntrinsic));
    419   if (kIsDebugBuild) {
    420     uint32_t java_flags = (GetAccessFlags() & kAccJavaFlagsMask);
    421     bool is_constructor = IsConstructor();
    422     bool is_synchronized = IsSynchronized();
    423     bool skip_access_checks = SkipAccessChecks();
    424     bool is_fast_native = IsFastNative();
    425     bool is_copied = IsCopied();
    426     bool is_miranda = IsMiranda();
    427     bool is_default = IsDefault();
    428     bool is_default_conflict = IsDefaultConflicting();
    429     bool is_compilable = IsCompilable();
    430     bool must_count_locks = MustCountLocks();
    431     SetAccessFlags(new_value);
    432     DCHECK_EQ(java_flags, (GetAccessFlags() & kAccJavaFlagsMask));
    433     DCHECK_EQ(is_constructor, IsConstructor());
    434     DCHECK_EQ(is_synchronized, IsSynchronized());
    435     DCHECK_EQ(skip_access_checks, SkipAccessChecks());
    436     DCHECK_EQ(is_fast_native, IsFastNative());
    437     DCHECK_EQ(is_copied, IsCopied());
    438     DCHECK_EQ(is_miranda, IsMiranda());
    439     DCHECK_EQ(is_default, IsDefault());
    440     DCHECK_EQ(is_default_conflict, IsDefaultConflicting());
    441     DCHECK_EQ(is_compilable, IsCompilable());
    442     DCHECK_EQ(must_count_locks, MustCountLocks());
    443   } else {
    444     SetAccessFlags(new_value);
    445   }
    446 }
    447 
    448 template<ReadBarrierOption kReadBarrierOption, typename RootVisitorType>
    449 void ArtMethod::VisitRoots(RootVisitorType& visitor, PointerSize pointer_size) {
    450   if (LIKELY(!declaring_class_.IsNull())) {
    451     visitor.VisitRoot(declaring_class_.AddressWithoutBarrier());
    452     mirror::Class* klass = declaring_class_.Read<kReadBarrierOption>();
    453     if (UNLIKELY(klass->IsProxyClass())) {
    454       // For normal methods, dex cache shortcuts will be visited through the declaring class.
    455       // However, for proxies we need to keep the interface method alive, so we visit its roots.
    456       ArtMethod* interface_method = mirror::DexCache::GetElementPtrSize(
    457           GetDexCacheResolvedMethods(pointer_size),
    458           GetDexMethodIndex(),
    459           pointer_size);
    460       DCHECK(interface_method != nullptr);
    461       DCHECK_EQ(interface_method,
    462                 Runtime::Current()->GetClassLinker()->FindMethodForProxy<kReadBarrierOption>(
    463                     klass, this));
    464       interface_method->VisitRoots(visitor, pointer_size);
    465     }
    466   }
    467 }
    468 
    469 template <typename Visitor>
    470 inline void ArtMethod::UpdateObjectsForImageRelocation(const Visitor& visitor,
    471                                                        PointerSize pointer_size) {
    472   mirror::Class* old_class = GetDeclaringClassUnchecked<kWithoutReadBarrier>();
    473   mirror::Class* new_class = visitor(old_class);
    474   if (old_class != new_class) {
    475     SetDeclaringClass(new_class);
    476   }
    477   ArtMethod** old_methods = GetDexCacheResolvedMethods(pointer_size);
    478   ArtMethod** new_methods = visitor(old_methods);
    479   if (old_methods != new_methods) {
    480     SetDexCacheResolvedMethods(new_methods, pointer_size);
    481   }
    482 }
    483 
    484 template <ReadBarrierOption kReadBarrierOption, typename Visitor>
    485 inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize pointer_size) {
    486   if (IsNative<kReadBarrierOption>()) {
    487     const void* old_native_code = GetEntryPointFromJniPtrSize(pointer_size);
    488     const void* new_native_code = visitor(old_native_code);
    489     if (old_native_code != new_native_code) {
    490       SetEntryPointFromJniPtrSize(new_native_code, pointer_size);
    491     }
    492   } else {
    493     DCHECK(GetDataPtrSize(pointer_size) == nullptr);
    494   }
    495   const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size);
    496   const void* new_code = visitor(old_code);
    497   if (old_code != new_code) {
    498     SetEntryPointFromQuickCompiledCodePtrSize(new_code, pointer_size);
    499   }
    500 }
    501 
    502 }  // namespace art
    503 
    504 #endif  // ART_RUNTIME_ART_METHOD_INL_H_
    505