diff options
author | 2025-03-19 11:13:51 +0000 | |
---|---|---|
committer | 2025-03-19 07:49:34 -0700 | |
commit | 5ce388aa5079c754838d4faf523eb30719073b88 (patch) | |
tree | e99c0ed615662ba285194f55496accdcdba4c204 | |
parent | 3d94fe6d114bac01f7957b248c363c9125fcf2d3 (diff) |
Do not override register storing MethodType in invokeExact.
As it might be in a callee-saved register and also known by GC
to have a reference.
arm64 and riscv are fine as they load MethodHandle's field into
a temp register and unpoison that register and not call site one.
Bug: 404465902
Test: ART_HEAP_POISONING=true art/test/testrunner/testrunner.py -b --host --optimizing --64
Test: ART_HEAP_POISONING=true art/test/testrunner/testrunner.py -b --host --optimizing --gcstress --64
Test: art/test/testrunner/testrunner.py -b --host --optimizing --64
Test: art/test/testrunner/testrunner.py -b --host --optimizing --gcstress --64
Change-Id: Ib1e80ee106a30b282f6bf2725c460f9c24d20c0e
-rw-r--r-- | compiler/optimizing/intrinsics_x86_64.cc | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 281f196f06..f891447848 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -4270,10 +4270,20 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke) CpuRegister call_site_type = locations->InAt(invoke->GetNumberOfArguments()).AsRegister<CpuRegister>(); + CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>(); + // Call site should match with MethodHandle's type. - __ MaybePoisonHeapReference(call_site_type); - __ cmpl(call_site_type, Address(method_handle, mirror::MethodHandle::MethodTypeOffset())); - __ j(kNotEqual, slow_path->GetEntryLabel()); + if (kPoisonHeapReferences) { + // call_site_type should be left intact as it 1) might be in callee-saved register 2) is known + // for GC to contain a reference. + __ movl(temp, call_site_type); + __ PoisonHeapReference(temp); + __ cmpl(temp, Address(method_handle, mirror::MethodHandle::MethodTypeOffset())); + __ j(kNotEqual, slow_path->GetEntryLabel()); + } else { + __ cmpl(call_site_type, Address(method_handle, mirror::MethodHandle::MethodTypeOffset())); + __ j(kNotEqual, slow_path->GetEntryLabel()); + } CpuRegister method = CpuRegister(kMethodRegisterArgument); __ movq(method, Address(method_handle, mirror::MethodHandle::ArtFieldOrMethodOffset())); @@ -4302,8 +4312,6 @@ void IntrinsicCodeGeneratorX86_64::VisitMethodHandleInvokeExact(HInvoke* invoke) __ testl(Address(method, ArtMethod::AccessFlagsOffset()), Immediate(kAccPrivate)); __ j(kNotZero, &execute_target_method); - CpuRegister temp = locations->GetTemp(0).AsRegister<CpuRegister>(); - __ movl(temp, Address(method, ArtMethod::DeclaringClassOffset())); __ cmpl(temp, Address(receiver, mirror::Object::ClassOffset())); // If method is defined in the receiver's class, execute it as it is. |