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