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 "arch/context.h"
     20 #include "art_field-inl.h"
     21 #include "art_method-inl.h"
     22 #include "base/stringpiece.h"
     23 #include "class_linker-inl.h"
     24 #include "debugger.h"
     25 #include "dex_file-inl.h"
     26 #include "dex_instruction.h"
     27 #include "entrypoints/runtime_asm_entrypoints.h"
     28 #include "gc/accounting/card_table-inl.h"
     29 #include "interpreter/interpreter.h"
     30 #include "jit/jit.h"
     31 #include "jit/jit_code_cache.h"
     32 #include "jit/profiling_info.h"
     33 #include "jni_internal.h"
     34 #include "mirror/abstract_method.h"
     35 #include "mirror/class-inl.h"
     36 #include "mirror/object_array-inl.h"
     37 #include "mirror/object-inl.h"
     38 #include "mirror/string.h"
     39 #include "oat_file-inl.h"
     40 #include "scoped_thread_state_change.h"
     41 #include "well_known_classes.h"
     42 
     43 namespace art {
     44 
     45 extern "C" void art_quick_invoke_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
     46                                       const char*);
     47 extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
     48                                              const char*);
     49 
     50 ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
     51                                           jobject jlr_method) {
     52   auto* abstract_method = soa.Decode<mirror::AbstractMethod*>(jlr_method);
     53   DCHECK(abstract_method != nullptr);
     54   return abstract_method->GetArtMethod();
     55 }
     56 
     57 mirror::String* ArtMethod::GetNameAsString(Thread* self) {
     58   CHECK(!IsProxyMethod());
     59   StackHandleScope<1> hs(self);
     60   Handle<mirror::DexCache> dex_cache(hs.NewHandle(GetDexCache()));
     61   auto* dex_file = dex_cache->GetDexFile();
     62   uint32_t dex_method_idx = GetDexMethodIndex();
     63   const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
     64   return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
     65                                                              dex_cache);
     66 }
     67 
     68 void ArtMethod::ThrowInvocationTimeError() {
     69   DCHECK(!IsInvokable());
     70   // NOTE: IsDefaultConflicting must be first since the actual method might or might not be abstract
     71   //       due to the way we select it.
     72   if (IsDefaultConflicting()) {
     73     ThrowIncompatibleClassChangeErrorForMethodConflict(this);
     74   } else {
     75     DCHECK(IsAbstract());
     76     ThrowAbstractMethodError(this);
     77   }
     78 }
     79 
     80 InvokeType ArtMethod::GetInvokeType() {
     81   // TODO: kSuper?
     82   if (IsStatic()) {
     83     return kStatic;
     84   } else if (GetDeclaringClass()->IsInterface()) {
     85     return kInterface;
     86   } else if (IsDirect()) {
     87     return kDirect;
     88   } else {
     89     return kVirtual;
     90   }
     91 }
     92 
     93 size_t ArtMethod::NumArgRegisters(const StringPiece& shorty) {
     94   CHECK_LE(1U, shorty.length());
     95   uint32_t num_registers = 0;
     96   for (size_t i = 1; i < shorty.length(); ++i) {
     97     char ch = shorty[i];
     98     if (ch == 'D' || ch == 'J') {
     99       num_registers += 2;
    100     } else {
    101       num_registers += 1;
    102     }
    103   }
    104   return num_registers;
    105 }
    106 
    107 bool ArtMethod::HasSameNameAndSignature(ArtMethod* other) {
    108   ScopedAssertNoThreadSuspension ants(Thread::Current(), "HasSameNameAndSignature");
    109   const DexFile* dex_file = GetDexFile();
    110   const DexFile::MethodId& mid = dex_file->GetMethodId(GetDexMethodIndex());
    111   if (GetDexCache() == other->GetDexCache()) {
    112     const DexFile::MethodId& mid2 = dex_file->GetMethodId(other->GetDexMethodIndex());
    113     return mid.name_idx_ == mid2.name_idx_ && mid.proto_idx_ == mid2.proto_idx_;
    114   }
    115   const DexFile* dex_file2 = other->GetDexFile();
    116   const DexFile::MethodId& mid2 = dex_file2->GetMethodId(other->GetDexMethodIndex());
    117   if (!DexFileStringEquals(dex_file, mid.name_idx_, dex_file2, mid2.name_idx_)) {
    118     return false;  // Name mismatch.
    119   }
    120   return dex_file->GetMethodSignature(mid) == dex_file2->GetMethodSignature(mid2);
    121 }
    122 
    123 ArtMethod* ArtMethod::FindOverriddenMethod(size_t pointer_size) {
    124   if (IsStatic()) {
    125     return nullptr;
    126   }
    127   mirror::Class* declaring_class = GetDeclaringClass();
    128   mirror::Class* super_class = declaring_class->GetSuperClass();
    129   uint16_t method_index = GetMethodIndex();
    130   ArtMethod* result = nullptr;
    131   // Did this method override a super class method? If so load the result from the super class'
    132   // vtable
    133   if (super_class->HasVTable() && method_index < super_class->GetVTableLength()) {
    134     result = super_class->GetVTableEntry(method_index, pointer_size);
    135   } else {
    136     // Method didn't override superclass method so search interfaces
    137     if (IsProxyMethod()) {
    138       result = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
    139                                                    GetDexMethodIndex(),
    140                                                    pointer_size);
    141       CHECK_EQ(result,
    142                Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
    143     } else {
    144       mirror::IfTable* iftable = GetDeclaringClass()->GetIfTable();
    145       for (size_t i = 0; i < iftable->Count() && result == nullptr; i++) {
    146         mirror::Class* interface = iftable->GetInterface(i);
    147         for (ArtMethod& interface_method : interface->GetVirtualMethods(pointer_size)) {
    148           if (HasSameNameAndSignature(interface_method.GetInterfaceMethodIfProxy(pointer_size))) {
    149             result = &interface_method;
    150             break;
    151           }
    152         }
    153       }
    154     }
    155   }
    156   DCHECK(result == nullptr ||
    157          GetInterfaceMethodIfProxy(pointer_size)->HasSameNameAndSignature(
    158              result->GetInterfaceMethodIfProxy(pointer_size)));
    159   return result;
    160 }
    161 
    162 uint32_t ArtMethod::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
    163                                                      uint32_t name_and_signature_idx) {
    164   const DexFile* dexfile = GetDexFile();
    165   const uint32_t dex_method_idx = GetDexMethodIndex();
    166   const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
    167   const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
    168   DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
    169   DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
    170   if (dexfile == &other_dexfile) {
    171     return dex_method_idx;
    172   }
    173   const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
    174   const DexFile::TypeId* other_type_id = other_dexfile.FindTypeId(mid_declaring_class_descriptor);
    175   if (other_type_id != nullptr) {
    176     const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
    177         *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
    178         other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
    179     if (other_mid != nullptr) {
    180       return other_dexfile.GetIndexForMethodId(*other_mid);
    181     }
    182   }
    183   return DexFile::kDexNoIndex;
    184 }
    185 
    186 uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type,
    187                                    uint32_t dex_pc, bool* has_no_move_exception) {
    188   const DexFile::CodeItem* code_item = GetCodeItem();
    189   // Set aside the exception while we resolve its type.
    190   Thread* self = Thread::Current();
    191   StackHandleScope<1> hs(self);
    192   Handle<mirror::Throwable> exception(hs.NewHandle(self->GetException()));
    193   self->ClearException();
    194   // Default to handler not found.
    195   uint32_t found_dex_pc = DexFile::kDexNoIndex;
    196   // Iterate over the catch handlers associated with dex_pc.
    197   size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
    198   for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
    199     uint16_t iter_type_idx = it.GetHandlerTypeIndex();
    200     // Catch all case
    201     if (iter_type_idx == DexFile::kDexNoIndex16) {
    202       found_dex_pc = it.GetHandlerAddress();
    203       break;
    204     }
    205     // Does this catch exception type apply?
    206     mirror::Class* iter_exception_type = GetClassFromTypeIndex(iter_type_idx,
    207                                                                true /* resolve */,
    208                                                                pointer_size);
    209     if (UNLIKELY(iter_exception_type == nullptr)) {
    210       // Now have a NoClassDefFoundError as exception. Ignore in case the exception class was
    211       // removed by a pro-guard like tool.
    212       // Note: this is not RI behavior. RI would have failed when loading the class.
    213       self->ClearException();
    214       // Delete any long jump context as this routine is called during a stack walk which will
    215       // release its in use context at the end.
    216       delete self->GetLongJumpContext();
    217       LOG(WARNING) << "Unresolved exception class when finding catch block: "
    218         << DescriptorToDot(GetTypeDescriptorFromTypeIdx(iter_type_idx));
    219     } else if (iter_exception_type->IsAssignableFrom(exception_type.Get())) {
    220       found_dex_pc = it.GetHandlerAddress();
    221       break;
    222     }
    223   }
    224   if (found_dex_pc != DexFile::kDexNoIndex) {
    225     const Instruction* first_catch_instr =
    226         Instruction::At(&code_item->insns_[found_dex_pc]);
    227     *has_no_move_exception = (first_catch_instr->Opcode() != Instruction::MOVE_EXCEPTION);
    228   }
    229   // Put the exception back.
    230   if (exception.Get() != nullptr) {
    231     self->SetException(exception.Get());
    232   }
    233   return found_dex_pc;
    234 }
    235 
    236 void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result,
    237                        const char* shorty) {
    238   if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
    239     ThrowStackOverflowError(self);
    240     return;
    241   }
    242 
    243   if (kIsDebugBuild) {
    244     self->AssertThreadSuspensionIsAllowable();
    245     CHECK_EQ(kRunnable, self->GetState());
    246     CHECK_STREQ(GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(), shorty);
    247   }
    248 
    249   // Push a transition back into managed code onto the linked list in thread.
    250   ManagedStack fragment;
    251   self->PushManagedStackFragment(&fragment);
    252 
    253   Runtime* runtime = Runtime::Current();
    254   // Call the invoke stub, passing everything as arguments.
    255   // If the runtime is not yet started or it is required by the debugger, then perform the
    256   // Invocation by the interpreter, explicitly forcing interpretation over JIT to prevent
    257   // cycling around the various JIT/Interpreter methods that handle method invocation.
    258   if (UNLIKELY(!runtime->IsStarted() || Dbg::IsForcedInterpreterNeededForCalling(self, this))) {
    259     if (IsStatic()) {
    260       art::interpreter::EnterInterpreterFromInvoke(
    261           self, this, nullptr, args, result, /*stay_in_interpreter*/ true);
    262     } else {
    263       mirror::Object* receiver =
    264           reinterpret_cast<StackReference<mirror::Object>*>(&args[0])->AsMirrorPtr();
    265       art::interpreter::EnterInterpreterFromInvoke(
    266           self, this, receiver, args + 1, result, /*stay_in_interpreter*/ true);
    267     }
    268   } else {
    269     DCHECK_EQ(runtime->GetClassLinker()->GetImagePointerSize(), sizeof(void*));
    270 
    271     constexpr bool kLogInvocationStartAndReturn = false;
    272     bool have_quick_code = GetEntryPointFromQuickCompiledCode() != nullptr;
    273     if (LIKELY(have_quick_code)) {
    274       if (kLogInvocationStartAndReturn) {
    275         LOG(INFO) << StringPrintf(
    276             "Invoking '%s' quick code=%p static=%d", PrettyMethod(this).c_str(),
    277             GetEntryPointFromQuickCompiledCode(), static_cast<int>(IsStatic() ? 1 : 0));
    278       }
    279 
    280       // Ensure that we won't be accidentally calling quick compiled code when -Xint.
    281       if (kIsDebugBuild && runtime->GetInstrumentation()->IsForcedInterpretOnly()) {
    282         CHECK(!runtime->UseJitCompilation());
    283         const void* oat_quick_code = runtime->GetClassLinker()->GetOatMethodQuickCodeFor(this);
    284         CHECK(oat_quick_code == nullptr || oat_quick_code != GetEntryPointFromQuickCompiledCode())
    285             << "Don't call compiled code when -Xint " << PrettyMethod(this);
    286       }
    287 
    288       if (!IsStatic()) {
    289         (*art_quick_invoke_stub)(this, args, args_size, self, result, shorty);
    290       } else {
    291         (*art_quick_invoke_static_stub)(this, args, args_size, self, result, shorty);
    292       }
    293       if (UNLIKELY(self->GetException() == Thread::GetDeoptimizationException())) {
    294         // Unusual case where we were running generated code and an
    295         // exception was thrown to force the activations to be removed from the
    296         // stack. Continue execution in the interpreter.
    297         self->DeoptimizeWithDeoptimizationException(result);
    298       }
    299       if (kLogInvocationStartAndReturn) {
    300         LOG(INFO) << StringPrintf("Returned '%s' quick code=%p", PrettyMethod(this).c_str(),
    301                                   GetEntryPointFromQuickCompiledCode());
    302       }
    303     } else {
    304       LOG(INFO) << "Not invoking '" << PrettyMethod(this) << "' code=null";
    305       if (result != nullptr) {
    306         result->SetJ(0);
    307       }
    308     }
    309   }
    310 
    311   // Pop transition.
    312   self->PopManagedStackFragment(fragment);
    313 }
    314 
    315 void ArtMethod::RegisterNative(const void* native_method, bool is_fast) {
    316   CHECK(IsNative()) << PrettyMethod(this);
    317   CHECK(!IsFastNative()) << PrettyMethod(this);
    318   CHECK(native_method != nullptr) << PrettyMethod(this);
    319   if (is_fast) {
    320     SetAccessFlags(GetAccessFlags() | kAccFastNative);
    321   }
    322   SetEntryPointFromJni(native_method);
    323 }
    324 
    325 void ArtMethod::UnregisterNative() {
    326   CHECK(IsNative() && !IsFastNative()) << PrettyMethod(this);
    327   // restore stub to lookup native pointer via dlsym
    328   RegisterNative(GetJniDlsymLookupStub(), false);
    329 }
    330 
    331 bool ArtMethod::IsOverridableByDefaultMethod() {
    332   return GetDeclaringClass()->IsInterface();
    333 }
    334 
    335 bool ArtMethod::EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params) {
    336   auto* dex_cache = GetDexCache();
    337   auto* dex_file = dex_cache->GetDexFile();
    338   const auto& method_id = dex_file->GetMethodId(GetDexMethodIndex());
    339   const auto& proto_id = dex_file->GetMethodPrototype(method_id);
    340   const DexFile::TypeList* proto_params = dex_file->GetProtoParameters(proto_id);
    341   auto count = proto_params != nullptr ? proto_params->Size() : 0u;
    342   auto param_len = params.Get() != nullptr ? params->GetLength() : 0u;
    343   if (param_len != count) {
    344     return false;
    345   }
    346   auto* cl = Runtime::Current()->GetClassLinker();
    347   for (size_t i = 0; i < count; ++i) {
    348     auto type_idx = proto_params->GetTypeItem(i).type_idx_;
    349     auto* type = cl->ResolveType(type_idx, this);
    350     if (type == nullptr) {
    351       Thread::Current()->AssertPendingException();
    352       return false;
    353     }
    354     if (type != params->GetWithoutChecks(i)) {
    355       return false;
    356     }
    357   }
    358   return true;
    359 }
    360 
    361 const uint8_t* ArtMethod::GetQuickenedInfo() {
    362   bool found = false;
    363   OatFile::OatMethod oat_method =
    364       Runtime::Current()->GetClassLinker()->FindOatMethodFor(this, &found);
    365   if (!found || (oat_method.GetQuickCode() != nullptr)) {
    366     return nullptr;
    367   }
    368   return oat_method.GetVmapTable();
    369 }
    370 
    371 const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) {
    372   // Our callers should make sure they don't pass the instrumentation exit pc,
    373   // as this method does not look at the side instrumentation stack.
    374   DCHECK_NE(pc, reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()));
    375 
    376   if (IsRuntimeMethod()) {
    377     return nullptr;
    378   }
    379 
    380   Runtime* runtime = Runtime::Current();
    381   const void* existing_entry_point = GetEntryPointFromQuickCompiledCode();
    382   CHECK(existing_entry_point != nullptr) << PrettyMethod(this) << "@" << this;
    383   ClassLinker* class_linker = runtime->GetClassLinker();
    384 
    385   if (class_linker->IsQuickGenericJniStub(existing_entry_point)) {
    386     // The generic JNI does not have any method header.
    387     return nullptr;
    388   }
    389 
    390   if (existing_entry_point == GetQuickProxyInvokeHandler()) {
    391     DCHECK(IsProxyMethod() && !IsConstructor());
    392     // The proxy entry point does not have any method header.
    393     return nullptr;
    394   }
    395 
    396   // Check whether the current entry point contains this pc.
    397   if (!class_linker->IsQuickResolutionStub(existing_entry_point) &&
    398       !class_linker->IsQuickToInterpreterBridge(existing_entry_point)) {
    399     OatQuickMethodHeader* method_header =
    400         OatQuickMethodHeader::FromEntryPoint(existing_entry_point);
    401 
    402     if (method_header->Contains(pc)) {
    403       return method_header;
    404     }
    405   }
    406 
    407   // Check whether the pc is in the JIT code cache.
    408   jit::Jit* jit = Runtime::Current()->GetJit();
    409   if (jit != nullptr) {
    410     jit::JitCodeCache* code_cache = jit->GetCodeCache();
    411     OatQuickMethodHeader* method_header = code_cache->LookupMethodHeader(pc, this);
    412     if (method_header != nullptr) {
    413       DCHECK(method_header->Contains(pc));
    414       return method_header;
    415     } else {
    416       DCHECK(!code_cache->ContainsPc(reinterpret_cast<const void*>(pc)))
    417           << PrettyMethod(this)
    418           << ", pc=" << std::hex << pc
    419           << ", entry_point=" << std::hex << reinterpret_cast<uintptr_t>(existing_entry_point)
    420           << ", copy=" << std::boolalpha << IsCopied()
    421           << ", proxy=" << std::boolalpha << IsProxyMethod();
    422     }
    423   }
    424 
    425   // The code has to be in an oat file.
    426   bool found;
    427   OatFile::OatMethod oat_method = class_linker->FindOatMethodFor(this, &found);
    428   if (!found) {
    429     if (class_linker->IsQuickResolutionStub(existing_entry_point)) {
    430       // We are running the generic jni stub, but the entry point of the method has not
    431       // been updated yet.
    432       DCHECK_EQ(pc, 0u) << "Should be a downcall";
    433       DCHECK(IsNative());
    434       return nullptr;
    435     }
    436     if (existing_entry_point == GetQuickInstrumentationEntryPoint()) {
    437       // We are running the generic jni stub, but the method is being instrumented.
    438       DCHECK_EQ(pc, 0u) << "Should be a downcall";
    439       DCHECK(IsNative());
    440       return nullptr;
    441     }
    442     // Only for unit tests.
    443     // TODO(ngeoffray): Update these tests to pass the right pc?
    444     return OatQuickMethodHeader::FromEntryPoint(existing_entry_point);
    445   }
    446   const void* oat_entry_point = oat_method.GetQuickCode();
    447   if (oat_entry_point == nullptr || class_linker->IsQuickGenericJniStub(oat_entry_point)) {
    448     DCHECK(IsNative()) << PrettyMethod(this);
    449     return nullptr;
    450   }
    451 
    452   OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromEntryPoint(oat_entry_point);
    453   if (pc == 0) {
    454     // This is a downcall, it can only happen for a native method.
    455     DCHECK(IsNative());
    456     return method_header;
    457   }
    458 
    459   DCHECK(method_header->Contains(pc))
    460       << PrettyMethod(this)
    461       << std::hex << pc << " " << oat_entry_point
    462       << " " << (uintptr_t)(method_header->code_ + method_header->code_size_);
    463   return method_header;
    464 }
    465 
    466 bool ArtMethod::HasAnyCompiledCode() {
    467   // Check whether the JIT has compiled it.
    468   jit::Jit* jit = Runtime::Current()->GetJit();
    469   if (jit != nullptr && jit->GetCodeCache()->ContainsMethod(this)) {
    470     return true;
    471   }
    472 
    473   // Check whether we have AOT code.
    474   return Runtime::Current()->GetClassLinker()->GetOatMethodQuickCodeFor(this) != nullptr;
    475 }
    476 
    477 void ArtMethod::CopyFrom(ArtMethod* src, size_t image_pointer_size) {
    478   memcpy(reinterpret_cast<void*>(this), reinterpret_cast<const void*>(src),
    479          Size(image_pointer_size));
    480   declaring_class_ = GcRoot<mirror::Class>(const_cast<ArtMethod*>(src)->GetDeclaringClass());
    481 
    482   // If the entry point of the method we are copying from is from JIT code, we just
    483   // put the entry point of the new method to interpreter. We could set the entry point
    484   // to the JIT code, but this would require taking the JIT code cache lock to notify
    485   // it, which we do not want at this level.
    486   Runtime* runtime = Runtime::Current();
    487   if (runtime->UseJitCompilation()) {
    488     if (runtime->GetJit()->GetCodeCache()->ContainsPc(GetEntryPointFromQuickCompiledCode())) {
    489       SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(), image_pointer_size);
    490     }
    491   }
    492   // Clear the profiling info for the same reasons as the JIT code.
    493   if (!src->IsNative()) {
    494     SetProfilingInfoPtrSize(nullptr, image_pointer_size);
    495   }
    496   // Clear hotness to let the JIT properly decide when to compile this method.
    497   hotness_count_ = 0;
    498 }
    499 
    500 }  // namespace art
    501