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 #include "art_method.h"
     18 
     19 #include <cstddef>
     20 
     21 #include "android-base/stringprintf.h"
     22 
     23 #include "arch/context.h"
     24 #include "art_method-inl.h"
     25 #include "base/stringpiece.h"
     26 #include "class_linker-inl.h"
     27 #include "debugger.h"
     28 #include "dex_file-inl.h"
     29 #include "dex_file_annotations.h"
     30 #include "dex_instruction.h"
     31 #include "entrypoints/runtime_asm_entrypoints.h"
     32 #include "gc/accounting/card_table-inl.h"
     33 #include "interpreter/interpreter.h"
     34 #include "jit/jit.h"
     35 #include "jit/jit_code_cache.h"
     36 #include "jit/profiling_info.h"
     37 #include "jni_internal.h"
     38 #include "mirror/class-inl.h"
     39 #include "mirror/class_ext.h"
     40 #include "mirror/executable.h"
     41 #include "mirror/object_array-inl.h"
     42 #include "mirror/object-inl.h"
     43 #include "mirror/string.h"
     44 #include "oat_file-inl.h"
     45 #include "runtime_callbacks.h"
     46 #include "scoped_thread_state_change-inl.h"
     47 #include "well_known_classes.h"
     48 
     49 namespace art {
     50 
     51 using android::base::StringPrintf;
     52 
     53 extern "C" void art_quick_invoke_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
     54                                       const char*);
     55 extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
     56                                              const char*);
     57 
     58 // Enforce that we he have the right index for runtime methods.
     59 static_assert(ArtMethod::kRuntimeMethodDexMethodIndex == DexFile::kDexNoIndex,
     60               "Wrong runtime-method dex method index");
     61 
     62 ArtMethod* ArtMethod::GetNonObsoleteMethod() {
     63   DCHECK_EQ(kRuntimePointerSize, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
     64   if (LIKELY(!IsObsolete())) {
     65     return this;
     66   } else if (IsDirect()) {
     67     return &GetDeclaringClass()->GetDirectMethodsSlice(kRuntimePointerSize)[GetMethodIndex()];
     68   } else {
     69     return GetDeclaringClass()->GetVTableEntry(GetMethodIndex(), kRuntimePointerSize);
     70   }
     71 }
     72 
     73 ArtMethod* ArtMethod::GetSingleImplementation(PointerSize pointer_size) {
     74   if (!IsAbstract()) {
     75     // A non-abstract's single implementation is itself.
     76     return this;
     77   }
     78   return reinterpret_cast<ArtMethod*>(GetDataPtrSize(pointer_size));
     79 }
     80 
     81 ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
     82                                           jobject jlr_method) {
     83   ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable>(jlr_method);
     84   DCHECK(executable != nullptr);
     85   return executable->GetArtMethod();
     86 }
     87 
     88 mirror::DexCache* ArtMethod::GetObsoleteDexCache() {
     89   DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
     90   DCHECK(IsObsolete());
     91   ObjPtr<mirror::ClassExt> ext(GetDeclaringClass()->GetExtData());
     92   CHECK(!ext.IsNull());
     93   ObjPtr<mirror::PointerArray> obsolete_methods(ext->GetObsoleteMethods());
     94   CHECK(!obsolete_methods.IsNull());
     95   DCHECK(ext->GetObsoleteDexCaches() != nullptr);
     96   int32_t len = obsolete_methods->GetLength();
     97   DCHECK_EQ(len, ext->GetObsoleteDexCaches()->GetLength());
     98   // Using kRuntimePointerSize (instead of using the image's pointer size) is fine since images
     99   // should never have obsolete methods in them so they should always be the same.
    100   PointerSize pointer_size = kRuntimePointerSize;
    101   DCHECK_EQ(kRuntimePointerSize, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
    102   for (int32_t i = 0; i < len; i++) {
    103     if (this == obsolete_methods->GetElementPtrSize<ArtMethod*>(i, pointer_size)) {
    104       return ext->GetObsoleteDexCaches()->Get(i);
    105     }
    106   }
    107   LOG(FATAL) << "This method does not appear in the obsolete map of its class!";
    108   UNREACHABLE();
    109 }
    110 
    111 uint16_t ArtMethod::FindObsoleteDexClassDefIndex() {
    112   DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
    113   DCHECK(IsObsolete());
    114   const DexFile* dex_file = GetDexFile();
    115   const dex::TypeIndex declaring_class_type = dex_file->GetMethodId(GetDexMethodIndex()).class_idx_;
    116   const DexFile::ClassDef* class_def = dex_file->FindClassDef(declaring_class_type);
    117   CHECK(class_def != nullptr);
    118   return dex_file->GetIndexForClassDef(*class_def);
    119 }
    120 
    121 mirror::String* ArtMethod::GetNameAsString(Thread* self) {
    122   CHECK(!IsProxyMethod());
    123   StackHandleScope<1> hs(self);
    124   Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
    125   auto* dex_file = dex_cache->GetDexFile();
    126   uint32_t dex_method_idx = GetDexMethodIndex();
    127   const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
    128   return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
    129                                                              dex_cache);
    130 }
    131 
    132 void ArtMethod::ThrowInvocationTimeError() {
    133   DCHECK(!IsInvokable());
    134   // NOTE: IsDefaultConflicting must be first since the actual method might or might not be abstract
    135   //       due to the way we select it.
    136   if (IsDefaultConflicting()) {
    137     ThrowIncompatibleClassChangeErrorForMethodConflict(this);
    138   } else {
    139     DCHECK(IsAbstract());
    140     ThrowAbstractMethodError(this);
    141   }
    142 }
    143 
    144 InvokeType ArtMethod::GetInvokeType() {
    145   // TODO: kSuper?
    146   if (IsStatic()) {
    147     return kStatic;
    148   } else if (GetDeclaringClass()->IsInterface()) {
    149     return kInterface;
    150   } else if (IsDirect()) {
    151     return kDirect;
    152   } else {
    153     return kVirtual;
    154   }
    155 }
    156 
    157 size_t ArtMethod::NumArgRegisters(const StringPiece& shorty) {
    158   CHECK_LE(1U, shorty.length());
    159   uint32_t num_registers = 0;
    160   for (size_t i = 1; i < shorty.length(); ++i) {
    161     char ch = shorty[i];
    162     if (ch == 'D' || ch == 'J') {
    163       num_registers += 2;
    164     } else {
    165       num_registers += 1;
    166     }
    167   }
    168   return num_registers;
    169 }
    170 
    171 bool ArtMethod::HasSameNameAndSignature(ArtMethod* other) {
    172   ScopedAssertNoThreadSuspension ants("HasSameNameAndSignature");
    173   const DexFile* dex_file = GetDexFile();
    174   const DexFile::MethodId& mid = dex_file->GetMethodId(GetDexMethodIndex());
    175   if (GetDexCache() == other->GetDexCache()) {
    176     const DexFile::MethodId& mid2 = dex_file->GetMethodId(other->GetDexMethodIndex());
    177     return mid.name_idx_ == mid2.name_idx_ && mid.proto_idx_ == mid2.proto_idx_;
    178   }
    179   const DexFile* dex_file2 = other->GetDexFile();
    180   const DexFile::MethodId& mid2 = dex_file2->GetMethodId(other->GetDexMethodIndex());
    181   if (!DexFileStringEquals(dex_file, mid.name_idx_, dex_file2, mid2.name_idx_)) {
    182     return false;  // Name mismatch.
    183   }
    184   return dex_file->GetMethodSignature(mid) == dex_file2->GetMethodSignature(mid2);
    185 }
    186 
    187 ArtMethod* ArtMethod::FindOverriddenMethod(PointerSize pointer_size) {
    188   if (IsStatic()) {
    189     return nullptr;
    190   }
    191   mirror::Class* declaring_class = GetDeclaringClass();
    192   mirror::Class* super_class = declaring_class->GetSuperClass();
    193   uint16_t method_index = GetMethodIndex();
    194   ArtMethod* result = nullptr;
    195   // Did this method override a super class method? If so load the result from the super class'
    196   // vtable
    197   if (super_class->HasVTable() && method_index < super_class->GetVTableLength()) {
    198     result = super_class->GetVTableEntry(method_index, pointer_size);
    199   } else {
    200     // Method didn't override superclass method so search interfaces
    201     if (IsProxyMethod()) {
    202       result = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
    203                                                    GetDexMethodIndex(),
    204                                                    pointer_size);
    205       CHECK_EQ(result,
    206                Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
    207     } else {
    208       mirror::IfTable* iftable = GetDeclaringClass()->GetIfTable();
    209       for (size_t i = 0; i < iftable->Count() && result == nullptr; i++) {
    210         mirror::Class* interface = iftable->GetInterface(i);
    211         for (ArtMethod& interface_method : interface->GetVirtualMethods(pointer_size)) {
    212           if (HasSameNameAndSignature(interface_method.GetInterfaceMethodIfProxy(pointer_size))) {
    213             result = &interface_method;
    214             break;
    215           }
    216         }
    217       }
    218     }
    219   }
    220   DCHECK(result == nullptr ||
    221          GetInterfaceMethodIfProxy(pointer_size)->HasSameNameAndSignature(
    222              result->GetInterfaceMethodIfProxy(pointer_size)));
    223   return result;
    224 }
    225 
    226 uint32_t ArtMethod::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
    227                                                      uint32_t name_and_signature_idx) {
    228   const DexFile* dexfile = GetDexFile();
    229   const uint32_t dex_method_idx = GetDexMethodIndex();
    230   const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
    231   const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
    232   DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
    233   DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
    234   if (dexfile == &other_dexfile) {
    235     return dex_method_idx;
    236   }
    237   const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
    238   const DexFile::TypeId* other_type_id = other_dexfile.FindTypeId(mid_declaring_class_descriptor);
    239   if (other_type_id != nullptr) {
    240     const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
    241         *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
    242         other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
    243     if (other_mid != nullptr) {
    244       return other_dexfile.GetIndexForMethodId(*other_mid);
    245     }
    246   }
    247   return DexFile::kDexNoIndex;
    248 }
    249 
    250 uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type,
    251                                    uint32_t dex_pc, bool* has_no_move_exception) {
    252   const DexFile::CodeItem* code_item = GetCodeItem();
    253   // Set aside the exception while we resolve its type.
    254   Thread* self = Thread::Current();
    255   StackHandleScope<1> hs(self);
    256   Handle<mirror::Throwable> exception(hs.NewHandle(self->GetException()));
    257   self->ClearException();
    258   // Default to handler not found.
    259   uint32_t found_dex_pc = DexFile::kDexNoIndex;
    260   // Iterate over the catch handlers associated with dex_pc.
    261   for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
    262     dex::TypeIndex iter_type_idx = it.GetHandlerTypeIndex();
    263     // Catch all case
    264     if (!iter_type_idx.IsValid()) {
    265       found_dex_pc = it.GetHandlerAddress();
    266       break;
    267     }
    268     // Does this catch exception type apply?
    269     mirror::Class* iter_exception_type = GetClassFromTypeIndex(iter_type_idx, true /* resolve */);
    270     if (UNLIKELY(iter_exception_type == nullptr)) {
    271       // Now have a NoClassDefFoundError as exception. Ignore in case the exception class was
    272       // removed by a pro-guard like tool.
    273       // Note: this is not RI behavior. RI would have failed when loading the class.
    274       self->ClearException();
    275       // Delete any long jump context as this routine is called during a stack walk which will
    276       // release its in use context at the end.
    277       delete self->GetLongJumpContext();
    278       LOG(WARNING) << "Unresolved exception class when finding catch block: "
    279         << DescriptorToDot(GetTypeDescriptorFromTypeIdx(iter_type_idx));
    280     } else if (iter_exception_type->IsAssignableFrom(exception_type.Get())) {
    281       found_dex_pc = it.GetHandlerAddress();
    282       break;
    283     }
    284   }
    285   if (found_dex_pc != DexFile::kDexNoIndex) {
    286     const Instruction* first_catch_instr =
    287         Instruction::At(&code_item->insns_[found_dex_pc]);
    288     *has_no_move_exception = (first_catch_instr->Opcode() != Instruction::MOVE_EXCEPTION);
    289   }
    290   // Put the exception back.
    291   if (exception != nullptr) {
    292     self->SetException(exception.Get());
    293   }
    294   return found_dex_pc;
    295 }
    296 
    297 void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result,
    298                        const char* shorty) {
    299   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
    300     ThrowStackOverflowError(self);
    301     return;
    302   }
    303 
    304   if (kIsDebugBuild) {
    305     self->AssertThreadSuspensionIsAllowable();
    306     CHECK_EQ(kRunnable, self->GetState());
    307     CHECK_STREQ(GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(), shorty);
    308   }
    309 
    310   // Push a transition back into managed code onto the linked list in thread.
    311   ManagedStack fragment;
    312   self->PushManagedStackFragment(&fragment);
    313 
    314   Runtime* runtime = Runtime::Current();
    315   // Call the invoke stub, passing everything as arguments.
    316   // If the runtime is not yet started or it is required by the debugger, then perform the
    317   // Invocation by the interpreter, explicitly forcing interpretation over JIT to prevent
    318   // cycling around the various JIT/Interpreter methods that handle method invocation.
    319   if (UNLIKELY(!runtime->IsStarted() || Dbg::IsForcedInterpreterNeededForCalling(self, this))) {
    320     if (IsStatic()) {
    321       art::interpreter::EnterInterpreterFromInvoke(
    322           self, this, nullptr, args, result, /*stay_in_interpreter*/ true);
    323     } else {
    324       mirror::Object* receiver =
    325           reinterpret_cast<StackReference<mirror::Object>*>(&args[0])->AsMirrorPtr();
    326       art::interpreter::EnterInterpreterFromInvoke(
    327           self, this, receiver, args + 1, result, /*stay_in_interpreter*/ true);
    328     }
    329   } else {
    330     DCHECK_EQ(runtime->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
    331 
    332     constexpr bool kLogInvocationStartAndReturn = false;
    333     bool have_quick_code = GetEntryPointFromQuickCompiledCode() != nullptr;
    334     if (LIKELY(have_quick_code)) {
    335       if (kLogInvocationStartAndReturn) {
    336         LOG(INFO) << StringPrintf(
    337             "Invoking '%s' quick code=%p static=%d", PrettyMethod().c_str(),
    338             GetEntryPointFromQuickCompiledCode(), static_cast<int>(IsStatic() ? 1 : 0));
    339       }
    340 
    341       // Ensure that we won't be accidentally calling quick compiled code when -Xint.
    342       if (kIsDebugBuild && runtime->GetInstrumentation()->IsForcedInterpretOnly()) {
    343         CHECK(!runtime->UseJitCompilation());
    344         const void* oat_quick_code =
    345             (IsNative() || !IsInvokable() || IsProxyMethod() || IsObsolete())
    346             ? nullptr
    347             : GetOatMethodQuickCode(runtime->GetClassLinker()->GetImagePointerSize());
    348         CHECK(oat_quick_code == nullptr || oat_quick_code != GetEntryPointFromQuickCompiledCode())
    349             << "Don't call compiled code when -Xint " << PrettyMethod();
    350       }
    351 
    352       if (!IsStatic()) {
    353         (*art_quick_invoke_stub)(this, args, args_size, self, result, shorty);
    354       } else {
    355         (*art_quick_invoke_static_stub)(this, args, args_size, self, result, shorty);
    356       }
    357       if (UNLIKELY(self->GetException() == Thread::GetDeoptimizationException())) {
    358         // Unusual case where we were running generated code and an
    359         // exception was thrown to force the activations to be removed from the
    360         // stack. Continue execution in the interpreter.
    361         self->DeoptimizeWithDeoptimizationException(result);
    362       }
    363       if (kLogInvocationStartAndReturn) {
    364         LOG(INFO) << StringPrintf("Returned '%s' quick code=%p", PrettyMethod().c_str(),
    365                                   GetEntryPointFromQuickCompiledCode());
    366       }
    367     } else {
    368       LOG(INFO) << "Not invoking '" << PrettyMethod() << "' code=null";
    369       if (result != nullptr) {
    370         result->SetJ(0);
    371       }
    372     }
    373   }
    374 
    375   // Pop transition.
    376   self->PopManagedStackFragment(fragment);
    377 }
    378 
    379 const void* ArtMethod::RegisterNative(const void* native_method, bool is_fast) {
    380   CHECK(IsNative()) << PrettyMethod();
    381   CHECK(!IsFastNative()) << PrettyMethod();
    382   CHECK(native_method != nullptr) << PrettyMethod();
    383   if (is_fast) {
    384     AddAccessFlags(kAccFastNative);
    385   }
    386   void* new_native_method = nullptr;
    387   Runtime::Current()->GetRuntimeCallbacks()->RegisterNativeMethod(this,
    388                                                                   native_method,
    389                                                                   /*out*/&new_native_method);
    390   SetEntryPointFromJni(new_native_method);
    391   return new_native_method;
    392 }
    393 
    394 void ArtMethod::UnregisterNative() {
    395   CHECK(IsNative() && !IsFastNative()) << PrettyMethod();
    396   // restore stub to lookup native pointer via dlsym
    397   SetEntryPointFromJni(GetJniDlsymLookupStub());
    398 }
    399 
    400 bool ArtMethod::IsOverridableByDefaultMethod() {
    401   return GetDeclaringClass()->IsInterface();
    402 }
    403 
    404 bool ArtMethod::IsAnnotatedWithFastNative() {
    405   return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_FastNative,
    406                          DexFile::kDexVisibilityBuild,
    407                          /* lookup_in_resolved_boot_classes */ true);
    408 }
    409 
    410 bool ArtMethod::IsAnnotatedWithCriticalNative() {
    411   return IsAnnotatedWith(WellKnownClasses::dalvik_annotation_optimization_CriticalNative,
    412                          DexFile::kDexVisibilityBuild,
    413                          /* lookup_in_resolved_boot_classes */ true);
    414 }
    415 
    416 bool ArtMethod::IsAnnotatedWith(jclass klass,
    417                                 uint32_t visibility,
    418                                 bool lookup_in_resolved_boot_classes) {
    419   Thread* self = Thread::Current();
    420   ScopedObjectAccess soa(self);
    421   StackHandleScope<1> shs(self);
    422 
    423   ObjPtr<mirror::Class> annotation = soa.Decode<mirror::Class>(klass);
    424   DCHECK(annotation->IsAnnotation());
    425   Handle<mirror::Class> annotation_handle(shs.NewHandle(annotation));
    426 
    427   return annotations::IsMethodAnnotationPresent(
    428       this, annotation_handle, visibility, lookup_in_resolved_boot_classes);
    429 }
    430 
    431 static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
    432                                                  uint16_t class_def_idx,
    433                                                  uint32_t method_idx) {
    434   const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
    435   const uint8_t* class_data = dex_file.GetClassData(class_def);
    436   CHECK(class_data != nullptr);
    437   ClassDataItemIterator it(dex_file, class_data);
    438   // Skip fields
    439   while (it.HasNextStaticField()) {
    440     it.Next();
    441   }
    442   while (it.HasNextInstanceField()) {
    443     it.Next();
    444   }
    445   // Process methods
    446   size_t class_def_method_index = 0;
    447   while (it.HasNextDirectMethod()) {
    448     if (it.GetMemberIndex() == method_idx) {
    449       return class_def_method_index;
    450     }
    451     class_def_method_index++;
    452     it.Next();
    453   }
    454   while (it.HasNextVirtualMethod()) {
    455     if (it.GetMemberIndex() == method_idx) {
    456       return class_def_method_index;
    457     }
    458     class_def_method_index++;
    459     it.Next();
    460   }
    461   DCHECK(!it.HasNext());
    462   LOG(FATAL) << "Failed to find method index " << method_idx << " in " << dex_file.GetLocation();
    463   UNREACHABLE();
    464 }
    465 
    466 // We use the method's DexFile and declaring class name to find the OatMethod for an obsolete
    467 // method.  This is extremely slow but we need it if we want to be able to have obsolete native
    468 // methods since we need this to find the size of its stack frames.
    469 //
    470 // NB We could (potentially) do this differently and rely on the way the transformation is applied
    471 // in order to use the entrypoint to find this information. However, for debugging reasons (most
    472 // notably making sure that new invokes of obsolete methods fail) we choose to instead get the data
    473 // directly from the dex file.
    474 static const OatFile::OatMethod FindOatMethodFromDexFileFor(ArtMethod* method, bool* found)
    475     REQUIRES_SHARED(Locks::mutator_lock_) {
    476   DCHECK(method->IsObsolete() && method->IsNative());
    477   const DexFile* dex_file = method->GetDexFile();
    478 
    479   // recreate the class_def_index from the descriptor.
    480   std::string descriptor_storage;
    481   const DexFile::TypeId* declaring_class_type_id =
    482       dex_file->FindTypeId(method->GetDeclaringClass()->GetDescriptor(&descriptor_storage));
    483   CHECK(declaring_class_type_id != nullptr);
    484   dex::TypeIndex declaring_class_type_index = dex_file->GetIndexForTypeId(*declaring_class_type_id);
    485   const DexFile::ClassDef* declaring_class_type_def =
    486       dex_file->FindClassDef(declaring_class_type_index);
    487   CHECK(declaring_class_type_def != nullptr);
    488   uint16_t declaring_class_def_index = dex_file->GetIndexForClassDef(*declaring_class_type_def);
    489 
    490   size_t oat_method_index = GetOatMethodIndexFromMethodIndex(*dex_file,
    491                                                              declaring_class_def_index,
    492                                                              method->GetDexMethodIndex());
    493 
    494   OatFile::OatClass oat_class = OatFile::FindOatClass(*dex_file,
    495                                                       declaring_class_def_index,
    496                                                       found);
    497   if (!(*found)) {
    498     return OatFile::OatMethod::Invalid();
    499   }
    500   return oat_class.GetOatMethod(oat_method_index);
    501 }
    502 
    503 static const OatFile::OatMethod FindOatMethodFor(ArtMethod* method,
    504                                                  PointerSize pointer_size,
    505                                                  bool* found)
    506     REQUIRES_SHARED(Locks::mutator_lock_) {
    507   if (UNLIKELY(method->IsObsolete())) {
    508     // We shouldn't be calling this with obsolete methods except for native obsolete methods for
    509     // which we need to use the oat method to figure out how large the quick frame is.
    510     DCHECK(method->IsNative()) << "We should only be finding the OatMethod of obsolete methods in "
    511                                << "order to allow stack walking. Other obsolete methods should "
    512                                << "never need to access this information.";
    513     DCHECK_EQ(pointer_size, kRuntimePointerSize) << "Obsolete method in compiler!";
    514     return FindOatMethodFromDexFileFor(method, found);
    515   }
    516   // Although we overwrite the trampoline of non-static methods, we may get here via the resolution
    517   // method for direct methods (or virtual methods made direct).
    518   mirror::Class* declaring_class = method->GetDeclaringClass();
    519   size_t oat_method_index;
    520   if (method->IsStatic() || method->IsDirect()) {
    521     // Simple case where the oat method index was stashed at load time.
    522     oat_method_index = method->GetMethodIndex();
    523   } else {
    524     // Compute the oat_method_index by search for its position in the declared virtual methods.
    525     oat_method_index = declaring_class->NumDirectMethods();
    526     bool found_virtual = false;
    527     for (ArtMethod& art_method : declaring_class->GetVirtualMethods(pointer_size)) {
    528       // Check method index instead of identity in case of duplicate method definitions.
    529       if (method->GetDexMethodIndex() == art_method.GetDexMethodIndex()) {
    530         found_virtual = true;
    531         break;
    532       }
    533       oat_method_index++;
    534     }
    535     CHECK(found_virtual) << "Didn't find oat method index for virtual method: "
    536                          << method->PrettyMethod();
    537   }
    538   DCHECK_EQ(oat_method_index,
    539             GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
    540                                              method->GetDeclaringClass()->GetDexClassDefIndex(),
    541                                              method->GetDexMethodIndex()));
    542   OatFile::OatClass oat_class = OatFile::FindOatClass(*declaring_class->GetDexCache()->GetDexFile(),
    543                                                       declaring_class->GetDexClassDefIndex(),
    544                                                       found);
    545   if (!(*found)) {
    546     return OatFile::OatMethod::Invalid();
    547   }
    548   return oat_class.GetOatMethod(oat_method_index);
    549 }
    550 
    551 bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params) {
    552   auto* dex_cache = GetDexCache();
    553   auto* dex_file = dex_cache->GetDexFile();
    554   const auto& method_id = dex_file->GetMethodId(GetDexMethodIndex());
    555   const auto& proto_id = dex_file->GetMethodPrototype(method_id);
    556   const DexFile::TypeList* proto_params = dex_file->GetProtoParameters(proto_id);
    557   auto count = proto_params != nullptr ? proto_params->Size() : 0u;
    558   auto param_len = params != nullptr ? params->GetLength() : 0u;
    559   if (param_len != count) {
    560     return false;
    561   }
    562   auto* cl = Runtime::Current()->GetClassLinker();
    563   for (size_t i = 0; i < count; ++i) {
    564     auto type_idx = proto_params->GetTypeItem(i).type_idx_;
    565     auto* type = cl->ResolveType(type_idx, this);
    566     if (type == nullptr) {
    567       Thread::Current()->AssertPendingException();
    568       return false;
    569     }
    570     if (type != params->GetWithoutChecks(i)) {
    571       return false;
    572     }
    573   }
    574   return true;
    575 }
    576 
    577 const uint8_t* ArtMethod::GetQuickenedInfo(PointerSize pointer_size) {
    578   bool found = false;
    579   OatFile::OatMethod oat_method = FindOatMethodFor(this, pointer_size, &found);
    580   if (!found || (oat_method.GetQuickCode() != nullptr)) {
    581     return nullptr;
    582   }
    583   if (kIsVdexEnabled) {
    584     const OatQuickMethodHeader* header = oat_method.GetOatQuickMethodHeader();
    585     // OatMethod without a header: no quickening table.
    586     if (header == nullptr) {
    587       return nullptr;
    588     }
    589     // The table is in the .vdex file.
    590     const OatFile::OatDexFile* oat_dex_file = GetDexCache()->GetDexFile()->GetOatDexFile();
    591     const OatFile* oat_file = oat_dex_file->GetOatFile();
    592     if (oat_file == nullptr) {
    593       return nullptr;
    594     }
    595     return oat_file->DexBegin() + header->GetVmapTableOffset();
    596   } else {
    597     return oat_method.GetVmapTable();
    598   }
    599 }
    600 
    601 const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) {
    602   // Our callers should make sure they don't pass the instrumentation exit pc,
    603   // as this method does not look at the side instrumentation stack.
    604   DCHECK_NE(pc, reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()));
    605 
    606   if (IsRuntimeMethod()) {
    607     return nullptr;
    608   }
    609 
    610   Runtime* runtime = Runtime::Current();
    611   const void* existing_entry_point = GetEntryPointFromQuickCompiledCode();
    612   CHECK(existing_entry_point != nullptr) << PrettyMethod() << "@" << this;
    613   ClassLinker* class_linker = runtime->GetClassLinker();
    614 
    615   if (class_linker->IsQuickGenericJniStub(existing_entry_point)) {
    616     // The generic JNI does not have any method header.
    617     return nullptr;
    618   }
    619 
    620   if (existing_entry_point == GetQuickProxyInvokeHandler()) {
    621     DCHECK(IsProxyMethod() && !IsConstructor());
    622     // The proxy entry point does not have any method header.
    623     return nullptr;
    624   }
    625 
    626   // Check whether the current entry point contains this pc.
    627   if (!class_linker->IsQuickResolutionStub(existing_entry_point) &&
    628       !class_linker->IsQuickToInterpreterBridge(existing_entry_point)) {
    629     OatQuickMethodHeader* method_header =
    630         OatQuickMethodHeader::FromEntryPoint(existing_entry_point);
    631 
    632     if (method_header->Contains(pc)) {
    633       return method_header;
    634     }
    635   }
    636 
    637   // Check whether the pc is in the JIT code cache.
    638   jit::Jit* jit = runtime->GetJit();
    639   if (jit != nullptr) {
    640     jit::JitCodeCache* code_cache = jit->GetCodeCache();
    641     OatQuickMethodHeader* method_header = code_cache->LookupMethodHeader(pc, this);
    642     if (method_header != nullptr) {
    643       DCHECK(method_header->Contains(pc));
    644       return method_header;
    645     } else {
    646       DCHECK(!code_cache->ContainsPc(reinterpret_cast<const void*>(pc)))
    647           << PrettyMethod()
    648           << ", pc=" << std::hex << pc
    649           << ", entry_point=" << std::hex << reinterpret_cast<uintptr_t>(existing_entry_point)
    650           << ", copy=" << std::boolalpha << IsCopied()
    651           << ", proxy=" << std::boolalpha << IsProxyMethod();
    652     }
    653   }
    654 
    655   // The code has to be in an oat file.
    656   bool found;
    657   OatFile::OatMethod oat_method =
    658       FindOatMethodFor(this, class_linker->GetImagePointerSize(), &found);
    659   if (!found) {
    660     if (class_linker->IsQuickResolutionStub(existing_entry_point)) {
    661       // We are running the generic jni stub, but the entry point of the method has not
    662       // been updated yet.
    663       DCHECK_EQ(pc, 0u) << "Should be a downcall";
    664       DCHECK(IsNative());
    665       return nullptr;
    666     }
    667     if (existing_entry_point == GetQuickInstrumentationEntryPoint()) {
    668       // We are running the generic jni stub, but the method is being instrumented.
    669       DCHECK_EQ(pc, 0u) << "Should be a downcall";
    670       DCHECK(IsNative());
    671       return nullptr;
    672     }
    673     // Only for unit tests.
    674     // TODO(ngeoffray): Update these tests to pass the right pc?
    675     return OatQuickMethodHeader::FromEntryPoint(existing_entry_point);
    676   }
    677   const void* oat_entry_point = oat_method.GetQuickCode();
    678   if (oat_entry_point == nullptr || class_linker->IsQuickGenericJniStub(oat_entry_point)) {
    679     DCHECK(IsNative()) << PrettyMethod();
    680     return nullptr;
    681   }
    682 
    683   OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromEntryPoint(oat_entry_point);
    684   if (pc == 0) {
    685     // This is a downcall, it can only happen for a native method.
    686     DCHECK(IsNative());
    687     return method_header;
    688   }
    689 
    690   DCHECK(method_header->Contains(pc))
    691       << PrettyMethod()
    692       << " " << std::hex << pc << " " << oat_entry_point
    693       << " " << (uintptr_t)(method_header->GetCode() + method_header->GetCodeSize());
    694   return method_header;
    695 }
    696 
    697 const void* ArtMethod::GetOatMethodQuickCode(PointerSize pointer_size) {
    698   bool found;
    699   OatFile::OatMethod oat_method = FindOatMethodFor(this, pointer_size, &found);
    700   if (found) {
    701     return oat_method.GetQuickCode();
    702   }
    703   return nullptr;
    704 }
    705 
    706 bool ArtMethod::HasAnyCompiledCode() {
    707   if (IsNative() || !IsInvokable() || IsProxyMethod()) {
    708     return false;
    709   }
    710 
    711   // Check whether the JIT has compiled it.
    712   Runtime* runtime = Runtime::Current();
    713   jit::Jit* jit = runtime->GetJit();
    714   if (jit != nullptr && jit->GetCodeCache()->ContainsMethod(this)) {
    715     return true;
    716   }
    717 
    718   // Check whether we have AOT code.
    719   return GetOatMethodQuickCode(runtime->GetClassLinker()->GetImagePointerSize()) != nullptr;
    720 }
    721 
    722 void ArtMethod::CopyFrom(ArtMethod* src, PointerSize image_pointer_size) {
    723   memcpy(reinterpret_cast<void*>(this), reinterpret_cast<const void*>(src),
    724          Size(image_pointer_size));
    725   declaring_class_ = GcRoot<mirror::Class>(const_cast<ArtMethod*>(src)->GetDeclaringClass());
    726 
    727   // If the entry point of the method we are copying from is from JIT code, we just
    728   // put the entry point of the new method to interpreter. We could set the entry point
    729   // to the JIT code, but this would require taking the JIT code cache lock to notify
    730   // it, which we do not want at this level.
    731   Runtime* runtime = Runtime::Current();
    732   if (runtime->UseJitCompilation()) {
    733     if (runtime->GetJit()->GetCodeCache()->ContainsPc(GetEntryPointFromQuickCompiledCode())) {
    734       SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(), image_pointer_size);
    735     }
    736   }
    737   // Clear the profiling info for the same reasons as the JIT code.
    738   if (!src->IsNative()) {
    739     SetProfilingInfoPtrSize(nullptr, image_pointer_size);
    740   }
    741   // Clear hotness to let the JIT properly decide when to compile this method.
    742   hotness_count_ = 0;
    743 }
    744 
    745 bool ArtMethod::IsImagePointerSize(PointerSize pointer_size) {
    746   // Hijack this function to get access to PtrSizedFieldsOffset.
    747   //
    748   // Ensure that PrtSizedFieldsOffset is correct. We rely here on usually having both 32-bit and
    749   // 64-bit builds.
    750   static_assert(std::is_standard_layout<ArtMethod>::value, "ArtMethod is not standard layout.");
    751   static_assert(
    752       (sizeof(void*) != 4) ||
    753           (offsetof(ArtMethod, ptr_sized_fields_) == PtrSizedFieldsOffset(PointerSize::k32)),
    754       "Unexpected 32-bit class layout.");
    755   static_assert(
    756       (sizeof(void*) != 8) ||
    757           (offsetof(ArtMethod, ptr_sized_fields_) == PtrSizedFieldsOffset(PointerSize::k64)),
    758       "Unexpected 64-bit class layout.");
    759 
    760   Runtime* runtime = Runtime::Current();
    761   if (runtime == nullptr) {
    762     return true;
    763   }
    764   return runtime->GetClassLinker()->GetImagePointerSize() == pointer_size;
    765 }
    766 
    767 std::string ArtMethod::PrettyMethod(ArtMethod* m, bool with_signature) {
    768   if (m == nullptr) {
    769     return "null";
    770   }
    771   return m->PrettyMethod(with_signature);
    772 }
    773 
    774 std::string ArtMethod::PrettyMethod(bool with_signature) {
    775   ArtMethod* m = this;
    776   if (!m->IsRuntimeMethod()) {
    777     m = m->GetInterfaceMethodIfProxy(Runtime::Current()->GetClassLinker()->GetImagePointerSize());
    778   }
    779   std::string result(PrettyDescriptor(m->GetDeclaringClassDescriptor()));
    780   result += '.';
    781   result += m->GetName();
    782   if (UNLIKELY(m->IsFastNative())) {
    783     result += "!";
    784   }
    785   if (with_signature) {
    786     const Signature signature = m->GetSignature();
    787     std::string sig_as_string(signature.ToString());
    788     if (signature == Signature::NoSignature()) {
    789       return result + sig_as_string;
    790     }
    791     result = PrettyReturnType(sig_as_string.c_str()) + " " + result +
    792         PrettyArguments(sig_as_string.c_str());
    793   }
    794   return result;
    795 }
    796 
    797 std::string ArtMethod::JniShortName() {
    798   return GetJniShortName(GetDeclaringClassDescriptor(), GetName());
    799 }
    800 
    801 std::string ArtMethod::JniLongName() {
    802   std::string long_name;
    803   long_name += JniShortName();
    804   long_name += "__";
    805 
    806   std::string signature(GetSignature().ToString());
    807   signature.erase(0, 1);
    808   signature.erase(signature.begin() + signature.find(')'), signature.end());
    809 
    810   long_name += MangleForJni(signature);
    811 
    812   return long_name;
    813 }
    814 
    815 // AssertSharedHeld doesn't work in GetAccessFlags, so use a NO_THREAD_SAFETY_ANALYSIS helper.
    816 // TODO: Figure out why ASSERT_SHARED_CAPABILITY doesn't work.
    817 template <ReadBarrierOption kReadBarrierOption>
    818 ALWAYS_INLINE static inline void DoGetAccessFlagsHelper(ArtMethod* method)
    819     NO_THREAD_SAFETY_ANALYSIS {
    820   CHECK(method->IsRuntimeMethod() ||
    821         method->GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() ||
    822         method->GetDeclaringClass<kReadBarrierOption>()->IsErroneous());
    823 }
    824 
    825 template <ReadBarrierOption kReadBarrierOption> void ArtMethod::GetAccessFlagsDCheck() {
    826   if (kCheckDeclaringClassState) {
    827     Thread* self = Thread::Current();
    828     if (!Locks::mutator_lock_->IsSharedHeld(self)) {
    829       if (self->IsThreadSuspensionAllowable()) {
    830         ScopedObjectAccess soa(self);
    831         CHECK(IsRuntimeMethod() ||
    832               GetDeclaringClass<kReadBarrierOption>()->IsIdxLoaded() ||
    833               GetDeclaringClass<kReadBarrierOption>()->IsErroneous());
    834       }
    835     } else {
    836       // We cannot use SOA in this case. We might be holding the lock, but may not be in the
    837       // runnable state (e.g., during GC).
    838       Locks::mutator_lock_->AssertSharedHeld(self);
    839       DoGetAccessFlagsHelper<kReadBarrierOption>(this);
    840     }
    841   }
    842 }
    843 template void ArtMethod::GetAccessFlagsDCheck<ReadBarrierOption::kWithReadBarrier>();
    844 template void ArtMethod::GetAccessFlagsDCheck<ReadBarrierOption::kWithoutReadBarrier>();
    845 
    846 }  // namespace art
    847