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