summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2024-10-22 16:15:54 +0100
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-10-23 11:10:38 +0000
commit0cdb0fedbf1eae14d56178eda1e800d133a76bea (patch)
treeae21c13edecc1b9cd3f4f8245a598816bfde2daf
parent398bedca50a44d26edc84e24a1c1b587cefaf8de (diff)
x86-64: handle invoke-direct in invokeExact intrinsic.
Also fix NPE not being thrown in the interpreter when receiver is null in invoke-direct MethodHandle. Bug: 297147201 Test: ./art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: I30d369316b56713dc7428d264fcff98954c63d37
-rw-r--r--compiler/optimizing/intrinsics_x86_64.cc11
-rw-r--r--runtime/method_handles.cc5
-rw-r--r--test/956-methodhandles/src/Main.java6
3 files changed, 19 insertions, 3 deletions
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index c7ee518acb..38954c8fa1 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -4262,14 +4262,19 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke)
Address method_handle_kind = Address(method_handle, mirror::MethodHandle::HandleKindOffset());
if (invoke->AsInvokePolymorphic()->CanTargetInstanceMethod()) {
- // Handle invoke-virtual case.
- __ cmpl(method_handle_kind, Immediate(mirror::MethodHandle::Kind::kInvokeVirtual));
- __ j(kNotEqual, &static_dispatch);
CpuRegister receiver = locations->InAt(1).AsRegister<CpuRegister>();
+ // Receiver shouldn't be null for all the following cases.
__ testl(receiver, receiver);
__ j(kEqual, slow_path->GetEntryLabel());
+ __ cmpl(method_handle_kind, Immediate(mirror::MethodHandle::Kind::kInvokeDirect));
+ // No dispatch is needed for invoke-direct.
+ __ j(kEqual, &execute_target_method);
+
+ // Handle invoke-virtual case.
+ __ cmpl(method_handle_kind, Immediate(mirror::MethodHandle::Kind::kInvokeVirtual));
+ __ j(kNotEqual, &static_dispatch);
// Skip virtual dispatch if `method` is private.
__ testl(Address(method, ArtMethod::AccessFlagsOffset()), Immediate(kAccPrivate));
__ j(kNotZero, &execute_target_method);
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index a91348ae63..741ec0d84d 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -466,6 +466,11 @@ ArtMethod* RefineTargetMethod(Thread* self,
// String constructors are replaced with static StringFactory methods when a MethodHandle
// object is created.
DCHECK(!target_method->IsStringConstructor());
+ ObjPtr<mirror::Object> receiver(shadow_frame.GetVRegReference(receiver_reg));
+ if (receiver == nullptr) {
+ ThrowNullPointerException("null receiver");
+ return nullptr;
+ }
} else if (handle_kind == mirror::MethodHandle::Kind::kInvokeSuper) {
// Note that we're not dynamically dispatching on the type of the receiver
// here. We use the static type of the "receiver" object that we've
diff --git a/test/956-methodhandles/src/Main.java b/test/956-methodhandles/src/Main.java
index 168862c040..51f7a17779 100644
--- a/test/956-methodhandles/src/Main.java
+++ b/test/956-methodhandles/src/Main.java
@@ -185,6 +185,12 @@ public class Main {
MethodType.methodType(void.class), D.class /* specialCaller */);
mh3.invoke(dInstance);
+ try {
+ mh3.invokeExact((D) null);
+ fail("Expected NPE to be thrown");
+ } catch (NullPointerException expected) {
+ }
+
// The private method shouldn't be accessible from any special caller except
// itself...
try {