summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2024-11-13 16:18:03 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-11-27 15:40:50 +0000
commitb82da21e55c185dbe031dcfb260578dab576e4bc (patch)
treebfe0988b7f339fdd0bfede515206dd55bebba8cb /compiler/optimizing
parentb16c991a56873f7baddec375ca63691f43a1afd6 (diff)
x86-64: handle invoke-interface in invokeExact intrinsic.
Bug: 297147201 Test: ./art/test/testrunner/testrunner.py -b --host --64 Test: ./art/test/testrunner/testrunner.py -b --jvm Change-Id: I2c07ae919921363e8e419ec7296cd24696e7f3b5
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/intrinsics_x86_64.cc50
1 files changed, 47 insertions, 3 deletions
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index b9d1a9f2c7..cf1bc93129 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -4236,6 +4236,8 @@ void IntrinsicLocationsBuilderX86_64::VisitMethodHandleInvokeExact(HInvoke* invo
locations->SetInAt(number_of_args, Location::RequiresRegister());
locations->AddTemp(Location::RequiresRegister());
+ // Hidden arg for invoke-interface.
+ locations->AddTemp(Location::RegisterLocation(RAX));
}
void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke) {
@@ -4273,14 +4275,15 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke)
// No dispatch is needed for invoke-direct.
__ j(kEqual, &execute_target_method);
+ Label non_virtual_dispatch;
// Handle invoke-virtual case.
__ cmpl(method_handle_kind, Immediate(mirror::MethodHandle::Kind::kInvokeVirtual));
- __ j(kNotEqual, &static_dispatch);
+ __ j(kNotEqual, &non_virtual_dispatch);
+
// Skip virtual dispatch if `method` is private.
__ testl(Address(method, ArtMethod::AccessFlagsOffset()), Immediate(kAccPrivate));
__ j(kNotZero, &execute_target_method);
- Label do_virtual_dispatch;
CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>();
__ movl(temp, Address(method, ArtMethod::DeclaringClassOffset()));
@@ -4288,7 +4291,6 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke)
// If method is defined in the receiver's class, execute it as it is.
__ j(kEqual, &execute_target_method);
- __ Bind(&do_virtual_dispatch);
// MethodIndex is uint16_t.
__ movzxw(temp, Address(method, ArtMethod::MethodIndexOffset()));
@@ -4300,6 +4302,48 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke)
mirror::Class::EmbeddedVTableOffset(art::PointerSize::k64).Int32Value();
__ movq(method, Address(method, temp, TIMES_8, vtable_offset));
__ Jump(&execute_target_method);
+
+ __ Bind(&non_virtual_dispatch);
+ __ cmpl(method_handle_kind, Immediate(mirror::MethodHandle::Kind::kInvokeInterface));
+ __ j(kNotEqual, &static_dispatch);
+
+ __ movl(temp, Address(method, ArtMethod::AccessFlagsOffset()));
+
+ __ testl(temp, Immediate(kAccPrivate));
+ __ j(kNotZero, &execute_target_method);
+
+ CpuRegister hidden_arg = locations->GetTemp(1).AsRegister<CpuRegister>();
+ // Set the hidden argument.
+ DCHECK_EQ(RAX, hidden_arg.AsRegister());
+ __ movq(hidden_arg, method);
+
+ Label get_imt_index_from_method_index;
+ Label do_imt_dispatch;
+
+ // Get IMT index.
+ // Not doing default conflict check as IMT index is set for all method which have
+ // kAccAbstract bit.
+ __ testl(temp, Immediate(kAccAbstract));
+ __ j(kZero, &get_imt_index_from_method_index);
+
+ // imt_index_ is uint16_t
+ __ movzxw(temp, Address(method, ArtMethod::ImtIndexOffset()));
+ __ Jump(&do_imt_dispatch);
+
+ // Default method, do method->GetMethodIndex() & (ImTable::kSizeTruncToPowerOfTwo - 1);
+ __ Bind(&get_imt_index_from_method_index);
+ __ movl(temp, Address(method, ArtMethod::MethodIndexOffset()));
+ __ andl(temp, Immediate(ImTable::kSizeTruncToPowerOfTwo - 1));
+
+ __ Bind(&do_imt_dispatch);
+ // Re-using `method` to store receiver class and ImTableEntry.
+ __ movl(method, Address(receiver, mirror::Object::ClassOffset()));
+
+ __ movq(method, Address(method, mirror::Class::ImtPtrOffset(kX86_64PointerSize).Uint32Value()));
+ // method = receiver->GetClass()->embedded_imtable_->Get(method_offset);
+ __ movq(method, Address(method, temp, TIMES_8, /* disp= */ 0));
+
+ __ Jump(&execute_target_method);
}
__ Bind(&static_dispatch);
__ cmpl(method_handle_kind, Immediate(mirror::MethodHandle::Kind::kInvokeStatic));