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