summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics_arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/intrinsics_arm64.cc')
-rw-r--r--compiler/optimizing/intrinsics_arm64.cc12
1 files changed, 5 insertions, 7 deletions
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 3eaaa6cb94..75607b77e0 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -6049,21 +6049,19 @@ void IntrinsicCodeGeneratorARM64::VisitMethodHandleInvokeExact(HInvoke* invoke)
// If method is defined in the receiver's class, execute it as it is.
__ Ldr(temp, MemOperand(method, ArtMethod::DeclaringClassOffset().Int32Value()));
__ Ldr(receiver_class, HeapOperand(receiver.W(), mirror::Object::ClassOffset().Int32Value()));
+ codegen_->GetAssembler()->MaybeUnpoisonHeapReference(receiver_class.W());
+ // `receiver_class` is read w/o read barriers: false negatives go through virtual dispatch.
__ Cmp(temp, receiver_class);
__ B(eq, &execute_target_method);
// MethodIndex is uint16_t.
__ Ldrh(temp, MemOperand(method, ArtMethod::MethodIndexOffset().Int32Value()));
- // Re-using method register for receiver class.
- // /* HeapReference<Class> */ method = receiver->klass
- __ Ldr(method.W(), HeapOperand(receiver.W(), mirror::Object::ClassOffset()));
- codegen_->GetAssembler()->MaybeUnpoisonHeapReference(method.W());
-
+ // Re-using receiver class register to store vtable.
constexpr uint32_t vtable_offset =
mirror::Class::EmbeddedVTableOffset(art::PointerSize::k64).Int32Value();
- __ Add(method, method, vtable_offset);
- __ Ldr(method, MemOperand(method, temp, Extend::UXTW, 3u));
+ __ Add(receiver_class.X(), receiver_class.X(), vtable_offset);
+ __ Ldr(method, MemOperand(receiver_class.X(), temp, Extend::UXTW, 3u));
__ B(&execute_target_method);
__ Bind(&non_virtual_dispatch);