diff options
| -rw-r--r-- | runtime/arch/arm/quick_entrypoints_arm.S | 10 | ||||
| -rw-r--r-- | runtime/arch/arm64/quick_entrypoints_arm64.S | 10 | ||||
| -rw-r--r-- | runtime/arch/mips/quick_entrypoints_mips.S | 15 | ||||
| -rw-r--r-- | runtime/arch/mips64/quick_entrypoints_mips64.S | 7 | ||||
| -rw-r--r-- | runtime/arch/x86/quick_entrypoints_x86.S | 11 | ||||
| -rw-r--r-- | runtime/arch/x86_64/quick_entrypoints_x86_64.S | 10 | ||||
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 23 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_dexcache_entrypoints.cc | 12 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 77 |
9 files changed, 80 insertions, 95 deletions
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 748857870d..3c145d77ad 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -313,8 +313,7 @@ ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFr /* * All generated callsites for interface invokes and invocation slow paths will load arguments * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain - * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the - * stack and call the appropriate C helper. + * the method_idx. This wrapper will save arg1-arg3, and call the appropriate C helper. * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1. * * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting @@ -330,13 +329,10 @@ ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFr .extern \cxx_name ENTRY \c_name SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME r2, r3 @ save callee saves in case allocation triggers GC - ldr r2, [sp, #FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE] @ pass caller Method* - mov r3, r9 @ pass Thread::Current - mov r12, sp - str r12, [sp, #-16]! @ expand the frame and pass SP + mov r2, r9 @ pass Thread::Current + mov r3, sp .cfi_adjust_cfa_offset 16 bl \cxx_name @ (method_idx, this, caller, Thread*, SP) - add sp, #16 @ strip the extra frame .cfi_adjust_cfa_offset -16 mov r12, r1 @ save Method*->code_ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index f8b0734428..6b16a2e55d 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -459,8 +459,7 @@ ONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFr /* * All generated callsites for interface invokes and invocation slow paths will load arguments * as usual - except instead of loading arg0/x0 with the target Method*, arg0/x0 will contain - * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the - * stack and call the appropriate C helper. + * the method_idx. This wrapper will save arg1-arg3, and call the appropriate C helper. * NOTE: "this" is first visible argument of the target, and so can be found in arg1/x1. * * The helper will attempt to locate the target and return a 128-bit result in x0/x1 consisting @@ -483,10 +482,9 @@ ENTRY \c_name // Helper signature is always // (method_idx, *this_object, *caller_method, *self, sp) - ldr w2, [sp, #FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE] // pass caller Method* - mov x3, xSELF // pass Thread::Current - mov x4, sp - bl \cxx_name // (method_idx, this, caller, Thread*, SP) + mov x2, xSELF // pass Thread::Current + mov x3, sp + bl \cxx_name // (method_idx, this, Thread*, SP) mov xIP0, x1 // save Method*->code_ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME cbz x0, 1f // did we find the target? if not go to exception delivery diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S index ee5c59f96f..92b180e605 100644 --- a/runtime/arch/mips/quick_entrypoints_mips.S +++ b/runtime/arch/mips/quick_entrypoints_mips.S @@ -439,8 +439,7 @@ END art_quick_throw_no_such_method /* * All generated callsites for interface invokes and invocation slow paths will load arguments * as usual - except instead of loading arg0/$a0 with the target Method*, arg0/$a0 will contain - * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the - * stack and call the appropriate C helper. + * the method_idx. This wrapper will save arg1-arg3, and call the appropriate C helper. * NOTE: "this" is first visable argument of the target, and so can be found in arg1/$a1. * * The helper will attempt to locate the target and return a 64-bit result in $v0/$v1 consisting @@ -456,15 +455,13 @@ END art_quick_throw_no_such_method .extern \cxx_name ENTRY \c_name SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME # save callee saves in case allocation triggers GC - lw $a2, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE+ARG_SLOT_SIZE($sp) # pass caller Method* - addiu $t0, $sp, ARG_SLOT_SIZE # save $sp (remove arg slots) - move $a3, rSELF # pass Thread::Current - jal \cxx_name # (method_idx, this, caller, Thread*, $sp) - sw $t0, 16($sp) # pass $sp - move $a0, $v0 # save target Method* + move $a2, rSELF # pass Thread::Current + jal \cxx_name # (method_idx, this, Thread*, $sp) + addiu $a3, $sp, ARG_SLOT_SIZE # pass $sp (remove arg slots) + move $a0, $v0 # save target Method* RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME beqz $v0, 1f - move $t9, $v1 # save $v0->code_ + move $t9, $v1 # save $v0->code_ jalr $zero, $t9 nop 1: diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S index ff79b5d77c..b7320a61ff 100644 --- a/runtime/arch/mips64/quick_entrypoints_mips64.S +++ b/runtime/arch/mips64/quick_entrypoints_mips64.S @@ -529,10 +529,9 @@ END art_quick_throw_no_such_method .extern \cxx_name ENTRY \c_name SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME # save callee saves in case allocation triggers GC - lwu $a2, FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE($sp) # pass caller Method* - move $a3, rSELF # pass Thread::Current - jal \cxx_name # (method_idx, this, caller, Thread*, $sp) - move $a4, $sp # pass $sp + move $a2, rSELF # pass Thread::Current + jal \cxx_name # (method_idx, this, Thread*, $sp) + move $a3, $sp # pass $sp move $a0, $v0 # save target Method* move $t9, $v1 # save $v0->code_ RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index 6ebeba3aaf..d62c1bcebe 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -278,8 +278,7 @@ TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromC /* * All generated callsites for interface invokes and invocation slow paths will load arguments * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain - * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the - * stack and call the appropriate C helper. + * the method_idx. This wrapper will save arg1-arg3 and call the appropriate C helper. * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1. * * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting @@ -297,19 +296,15 @@ MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name) movl %esp, %edx // remember SP // Outgoing argument set up - subl MACRO_LITERAL(12), %esp // alignment padding - CFI_ADJUST_CFA_OFFSET(12) PUSH edx // pass SP pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) - pushl 32+32(%edx) // pass caller Method* - CFI_ADJUST_CFA_OFFSET(4) PUSH ecx // pass arg2 PUSH eax // pass arg1 call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP) movl %edx, %edi // save code pointer in EDI - addl MACRO_LITERAL(36), %esp // Pop arguments skip eax - CFI_ADJUST_CFA_OFFSET(-36) + addl MACRO_LITERAL(20), %esp // Pop arguments skip eax + CFI_ADJUST_CFA_OFFSET(-20) // Restore FPRs. movsd 0(%esp), %xmm0 diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index da4d92b889..ddeb5b8e56 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -341,8 +341,7 @@ TWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromC /* * All generated callsites for interface invokes and invocation slow paths will load arguments * as usual - except instead of loading arg0/rdi with the target Method*, arg0/rdi will contain - * the method_idx. This wrapper will save arg1-arg3, load the caller's Method*, align the - * stack and call the appropriate C helper. + * the method_idx. This wrapper will save arg1-arg3, and call the appropriate C helper. * NOTE: "this" is first visible argument of the target, and so can be found in arg1/rsi. * * The helper will attempt to locate the target and return a 128-bit result in rax/rdx consisting @@ -362,11 +361,10 @@ MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name) // Helper signature is always // (method_idx, *this_object, *caller_method, *self, sp) - movl FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE(%rsp), %edx // pass caller Method* - movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread - movq %rsp, %r8 // pass SP + movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread + movq %rsp, %rcx // pass SP - call VAR(cxx_name, 1) // cxx_name(arg1, arg2, caller method*, Thread*, SP) + call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP) // save the code pointer movq %rax, %rdi movq %rdx, %rax diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 9292cff88e..625e695ce4 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -38,25 +38,34 @@ namespace art { -inline mirror::ArtMethod* GetCalleeSaveMethodCaller(Thread* self, Runtime::CalleeSaveType type) +inline mirror::ArtMethod* GetCalleeSaveMethodCaller(StackReference<mirror::ArtMethod>* sp, + Runtime::CalleeSaveType type, + bool do_caller_check = false) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - auto* refs_only_sp = self->GetManagedStack()->GetTopQuickFrame(); - DCHECK_EQ(refs_only_sp->AsMirrorPtr(), Runtime::Current()->GetCalleeSaveMethod(type)); + DCHECK_EQ(sp->AsMirrorPtr(), Runtime::Current()->GetCalleeSaveMethod(type)); const size_t callee_frame_size = GetCalleeSaveFrameSize(kRuntimeISA, type); auto* caller_sp = reinterpret_cast<StackReference<mirror::ArtMethod>*>( - reinterpret_cast<uintptr_t>(refs_only_sp) + callee_frame_size); + reinterpret_cast<uintptr_t>(sp) + callee_frame_size); auto* caller = caller_sp->AsMirrorPtr(); - if (kIsDebugBuild) { - NthCallerVisitor visitor(self, 1, true); + if (kIsDebugBuild && do_caller_check) { + // Note that do_caller_check is optional, as this method can be called by + // stubs, and tests without a proper call stack. + NthCallerVisitor visitor(Thread::Current(), 1, true); visitor.WalkStack(); - CHECK(caller == visitor.caller); + CHECK_EQ(caller, visitor.caller); } return caller; } +inline mirror::ArtMethod* GetCalleeSaveMethodCaller(Thread* self, Runtime::CalleeSaveType type) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + return GetCalleeSaveMethodCaller( + self->GetManagedStack()->GetTopQuickFrame(), type, true /* do_caller_check */); +} + template <const bool kAccessCheck> ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc index 46629f5958..91488787da 100644 --- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc @@ -25,8 +25,7 @@ namespace art { -extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, - Thread* self) +extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Called to ensure static storage base is initialized for direct static field reads and writes. // A class may be accessing another class' fields when it doesn't have access, as access has been @@ -36,8 +35,7 @@ extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx, return ResolveVerifyAndClinit(type_idx, caller, self, true, false); } -extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, - Thread* self) +extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Called when method->dex_cache_resolved_types_[] misses. ScopedQuickEntrypointChecks sqec(self); @@ -45,8 +43,7 @@ extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx, return ResolveVerifyAndClinit(type_idx, caller, self, false, false); } -extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, - Thread* self) +extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // Called when caller isn't guaranteed to have access to a type and the dex cache may be // unpopulated. @@ -55,8 +52,7 @@ extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type return ResolveVerifyAndClinit(type_idx, caller, self, false, true); } -extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, - Thread* self) +extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); auto* caller = GetCalleeSaveMethodCaller(self, Runtime::kRefsOnly); diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 2e7e2dfd74..345b0ade8b 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -294,8 +294,13 @@ class QuickArgumentVisitor { static mirror::ArtMethod* GetCallingMethod(StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { DCHECK(sp->AsMirrorPtr()->IsCalleeSaveMethod()); - uint8_t* previous_sp = reinterpret_cast<uint8_t*>(sp) + kQuickCalleeSaveFrame_RefAndArgs_FrameSize; - return reinterpret_cast<StackReference<mirror::ArtMethod>*>(previous_sp)->AsMirrorPtr(); + return GetCalleeSaveMethodCaller(sp, Runtime::kRefsAndArgs); + } + + static uint32_t GetCallingDexPc(StackReference<mirror::ArtMethod>* sp) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + DCHECK(sp->AsMirrorPtr()->IsCalleeSaveMethod()); + return GetCallingMethod(sp)->ToDexPc(QuickArgumentVisitor::GetCallingPc(sp)); } // For the given quick ref and args quick frame, return the caller's PC. @@ -827,12 +832,13 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, // Compute details about the called method (avoid GCs) ClassLinker* linker = Runtime::Current()->GetClassLinker(); - mirror::ArtMethod* caller = QuickArgumentVisitor::GetCallingMethod(sp); InvokeType invoke_type; MethodReference called_method(nullptr, 0); const bool called_method_known_on_entry = !called->IsRuntimeMethod(); + mirror::ArtMethod* caller = nullptr; if (!called_method_known_on_entry) { - uint32_t dex_pc = caller->ToDexPc(QuickArgumentVisitor::GetCallingPc(sp)); + caller = QuickArgumentVisitor::GetCallingMethod(sp); + uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); const DexFile::CodeItem* code; called_method.dex_file = caller->GetDexFile(); code = caller->GetCodeItem(); @@ -1946,16 +1952,13 @@ extern "C" uint64_t artQuickGenericJniEndTrampoline(Thread* self, jvalue result, // to hold the mutator lock (see SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) annotations). template<InvokeType type, bool access_check> -static TwoWordReturn artInvokeCommon(uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, - Thread* self, StackReference<mirror::ArtMethod>* sp); - -template<InvokeType type, bool access_check> -static TwoWordReturn artInvokeCommon(uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, - Thread* self, StackReference<mirror::ArtMethod>* sp) { +static TwoWordReturn artInvokeCommon(uint32_t method_idx, + mirror::Object* this_object, + Thread* self, + StackReference<mirror::ArtMethod>* sp) { ScopedQuickEntrypointChecks sqec(self); DCHECK_EQ(sp->AsMirrorPtr(), Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)); + mirror::ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp); mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type); if (UNLIKELY(method == nullptr)) { @@ -1994,7 +1997,6 @@ static TwoWordReturn artInvokeCommon(uint32_t method_idx, mirror::Object* this_o template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) \ TwoWordReturn artInvokeCommon<type, access_check>(uint32_t method_idx, \ mirror::Object* this_object, \ - mirror::ArtMethod* caller_method, \ Thread* self, \ StackReference<mirror::ArtMethod>* sp) \ @@ -2012,58 +2014,58 @@ EXPLICIT_INVOKE_COMMON_TEMPLATE_DECL(kSuper, true); // See comments in runtime_support_asm.S extern "C" TwoWordReturn artInvokeInterfaceTrampolineWithAccessCheck( - uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self, + uint32_t method_idx, + mirror::Object* this_object, + Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return artInvokeCommon<kInterface, true>(method_idx, this_object, - caller_method, self, sp); + return artInvokeCommon<kInterface, true>(method_idx, this_object, self, sp); } extern "C" TwoWordReturn artInvokeDirectTrampolineWithAccessCheck( - uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self, + uint32_t method_idx, + mirror::Object* this_object, + Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return artInvokeCommon<kDirect, true>(method_idx, this_object, caller_method, - self, sp); + return artInvokeCommon<kDirect, true>(method_idx, this_object, self, sp); } extern "C" TwoWordReturn artInvokeStaticTrampolineWithAccessCheck( - uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self, + uint32_t method_idx, + mirror::Object* this_object, + Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return artInvokeCommon<kStatic, true>(method_idx, this_object, caller_method, - self, sp); + return artInvokeCommon<kStatic, true>(method_idx, this_object, self, sp); } extern "C" TwoWordReturn artInvokeSuperTrampolineWithAccessCheck( - uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self, + uint32_t method_idx, + mirror::Object* this_object, + Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return artInvokeCommon<kSuper, true>(method_idx, this_object, caller_method, - self, sp); + return artInvokeCommon<kSuper, true>(method_idx, this_object, self, sp); } extern "C" TwoWordReturn artInvokeVirtualTrampolineWithAccessCheck( - uint32_t method_idx, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self, + uint32_t method_idx, + mirror::Object* this_object, + Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return artInvokeCommon<kVirtual, true>(method_idx, this_object, caller_method, - self, sp); + return artInvokeCommon<kVirtual, true>(method_idx, this_object, self, sp); } // Determine target of interface dispatch. This object is known non-null. extern "C" TwoWordReturn artInvokeInterfaceTrampoline(mirror::ArtMethod* interface_method, mirror::Object* this_object, - mirror::ArtMethod* caller_method, Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { ScopedQuickEntrypointChecks sqec(self); + mirror::ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp); mirror::ArtMethod* method; if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) { method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method); @@ -2075,12 +2077,7 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(mirror::ArtMethod* interfa } else { DCHECK(interface_method == Runtime::Current()->GetResolutionMethod()); - // Find the caller PC. - constexpr size_t pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsAndArgs); - uintptr_t caller_pc = *reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) + pc_offset); - - // Map the caller PC to a dex PC. - uint32_t dex_pc = caller_method->ToDexPc(caller_pc); + uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); const DexFile::CodeItem* code = caller_method->GetCodeItem(); CHECK_LT(dex_pc, code->insns_size_in_code_units_); const Instruction* instr = Instruction::At(&code->insns_[dex_pc]); |