diff options
| author | 2017-03-09 02:26:44 +0000 | |
|---|---|---|
| committer | 2017-03-09 02:26:45 +0000 | |
| commit | b3ab3f8c352a278486ff7bb90e5f4860b79272c9 (patch) | |
| tree | 230814b2467f760a54e75e87c7e3f0a8fcf8db30 | |
| parent | fb005aa868f17077700fd92e6d97723062260b0f (diff) | |
| parent | 5667f56867383fc4113aa4a6551efdf9f48ee5e7 (diff) | |
Merge "Modify invoke interface trampoline to pass interface method."
| -rw-r--r-- | runtime/arch/arm/quick_entrypoints_arm.S | 1 | ||||
| -rw-r--r-- | runtime/arch/arm64/quick_entrypoints_arm64.S | 1 | ||||
| -rw-r--r-- | runtime/arch/mips/quick_entrypoints_mips.S | 1 | ||||
| -rw-r--r-- | runtime/arch/mips64/quick_entrypoints_mips64.S | 1 | ||||
| -rw-r--r-- | runtime/arch/x86/quick_entrypoints_x86.S | 1 | ||||
| -rw-r--r-- | runtime/arch/x86_64/quick_entrypoints_x86_64.S | 1 | ||||
| -rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 55 |
7 files changed, 31 insertions, 30 deletions
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 85310911be..72aa785973 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -1487,6 +1487,7 @@ ENTRY art_quick_imt_conflict_trampoline .Lconflict_trampoline: // Call the runtime stub to populate the ImtConflictTable and jump to the // resolved method. + mov r0, r12 // Load interface method INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline END art_quick_imt_conflict_trampoline diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index 7cb50b7118..5b5d2ef0dc 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -1966,6 +1966,7 @@ ENTRY art_quick_imt_conflict_trampoline .Lconflict_trampoline: // Call the runtime stub to populate the ImtConflictTable and jump to the // resolved method. + mov x0, xIP0 // Load interface method INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline END art_quick_imt_conflict_trampoline diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S index 4f7b4957b6..5d6153949a 100644 --- a/runtime/arch/mips/quick_entrypoints_mips.S +++ b/runtime/arch/mips/quick_entrypoints_mips.S @@ -1763,6 +1763,7 @@ ENTRY art_quick_imt_conflict_trampoline .Lconflict_trampoline: # Call the runtime stub to populate the ImtConflictTable and jump to the resolved method. + move $a0, $t7 # Load interface method. INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline END art_quick_imt_conflict_trampoline diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S index 28d7c77938..3ee9c4a9c8 100644 --- a/runtime/arch/mips64/quick_entrypoints_mips64.S +++ b/runtime/arch/mips64/quick_entrypoints_mips64.S @@ -1715,6 +1715,7 @@ ENTRY art_quick_imt_conflict_trampoline .Lconflict_trampoline: # Call the runtime stub to populate the ImtConflictTable and jump to the resolved method. + move $a0, $t0 # Load interface method. INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline END art_quick_imt_conflict_trampoline diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index 8c907e0790..ff7ba92f93 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -1806,6 +1806,7 @@ DEFINE_FUNCTION art_quick_imt_conflict_trampoline .Lconflict_trampoline: // Call the runtime stub to populate the ImtConflictTable and jump to the // resolved method. + movl %edi, %eax // Load interface method POP EDI INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline END_FUNCTION art_quick_imt_conflict_trampoline diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index f1be52eeb6..8a663d15c5 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -1662,6 +1662,7 @@ DEFINE_FUNCTION art_quick_imt_conflict_trampoline .Lconflict_trampoline: // Call the runtime stub to populate the ImtConflictTable and jump to the // resolved method. + movq %r10, %rdi // Load interface method INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline #endif // __APPLE__ END_FUNCTION art_quick_imt_conflict_trampoline diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 4c3990aad6..3fd20a66c2 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -2323,48 +2323,26 @@ extern "C" TwoWordReturn artInvokeVirtualTrampolineWithAccessCheck( return artInvokeCommon<kVirtual, true>(method_idx, this_object, self, sp); } -// Determine target of interface dispatch. This object is known non-null. First argument -// is there for consistency but should not be used, as some architectures overwrite it -// in the assembly trampoline. -extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t deadbeef ATTRIBUTE_UNUSED, +// Determine target of interface dispatch. The interface method and this object are known non-null. +// The interface method is the method returned by the dex cache in the conflict trampoline. +extern "C" TwoWordReturn artInvokeInterfaceTrampoline(ArtMethod* interface_method, mirror::Object* raw_this_object, Thread* self, ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) { + CHECK(interface_method != nullptr); ObjPtr<mirror::Object> this_object(raw_this_object); ScopedQuickEntrypointChecks sqec(self); StackHandleScope<1> hs(self); Handle<mirror::Class> cls(hs.NewHandle(this_object->GetClass())); ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp); - - // Fetch the dex_method_idx of the target interface method from the caller. - uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); - - const DexFile::CodeItem* code_item = caller_method->GetCodeItem(); - CHECK_LT(dex_pc, code_item->insns_size_in_code_units_); - const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]); - Instruction::Code instr_code = instr->Opcode(); - CHECK(instr_code == Instruction::INVOKE_INTERFACE || - instr_code == Instruction::INVOKE_INTERFACE_RANGE) - << "Unexpected call into interface trampoline: " << instr->DumpString(nullptr); - uint32_t dex_method_idx; - if (instr_code == Instruction::INVOKE_INTERFACE) { - dex_method_idx = instr->VRegB_35c(); - } else { - CHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE); - dex_method_idx = instr->VRegB_3rc(); - } - - ArtMethod* interface_method = caller_method->GetDexCacheResolvedMethod( - dex_method_idx, kRuntimePointerSize); - DCHECK(interface_method != nullptr) << dex_method_idx << " " << caller_method->PrettyMethod(); ArtMethod* method = nullptr; ImTable* imt = cls->GetImt(kRuntimePointerSize); if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) { - // If the dex cache already resolved the interface method, look whether we have - // a match in the ImtConflictTable. + // If the interface method is already resolved, look whether we have a match in the + // ImtConflictTable. ArtMethod* conflict_method = imt->Get(ImTable::GetImtIndex(interface_method), kRuntimePointerSize); if (LIKELY(conflict_method->IsRuntimeMethod())) { @@ -2389,9 +2367,26 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t deadbeef ATTRIBUT return GetTwoWordFailureValue(); // Failure. } } else { - // The dex cache did not resolve the method, look it up in the dex file - // of the caller, + // The interface method is unresolved, so look it up in the dex file of the caller. DCHECK_EQ(interface_method, Runtime::Current()->GetResolutionMethod()); + + // Fetch the dex_method_idx of the target interface method from the caller. + uint32_t dex_method_idx; + uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); + const DexFile::CodeItem* code_item = caller_method->GetCodeItem(); + DCHECK_LT(dex_pc, code_item->insns_size_in_code_units_); + const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]); + Instruction::Code instr_code = instr->Opcode(); + DCHECK(instr_code == Instruction::INVOKE_INTERFACE || + instr_code == Instruction::INVOKE_INTERFACE_RANGE) + << "Unexpected call into interface trampoline: " << instr->DumpString(nullptr); + if (instr_code == Instruction::INVOKE_INTERFACE) { + dex_method_idx = instr->VRegB_35c(); + } else { + DCHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE); + dex_method_idx = instr->VRegB_3rc(); + } + const DexFile* dex_file = caller_method->GetDeclaringClass()->GetDexCache() ->GetDexFile(); uint32_t shorty_len; |