x86_64: Implement VarHandle.getAndSet for fields.
The implementation is based on XCHG instruction, so it cannot be reused
for other getAnd* methods.
Benchmarks improvements (using benchmarks provided by
https://android-review.googlesource.com/1420959):
benchmark before after
--------------------------------------------------
GetAndSetStaticFieldInt 2.449 0.018
GetAndSetStaticFieldString 2.818 0.014
GetAndSetFieldInt 2.728 0.012
GetAndSetFieldString 3.002 0.014
GetAndSetAcquireStaticFieldInt 2.438 0.007
GetAndSetAcquireStaticFieldString 2.811 0.010
GetAndSetAcquireFieldInt 2.726 0.007
GetAndSetAcquireFieldString 2.998 0.010
GetAndSetReleaseStaticFieldInt 2.436 0.007
GetAndSetReleaseStaticFieldString 2.813 0.010
GetAndSetReleaseFieldInt 2.730 0.007
GetAndSetReleaseFieldString 2.997 0.010
Bug: 65872996
Test: lunch aosp_cf_x86_64_phone-userdebug \
&& art/test.py --host -r -t 712-varhandle-invocations --64
Test: Repeat with ART_USE_READ_BARRIER=false.
Test: Repeat with ART_HEAP_POISONING=true.
Change-Id: I77bdf6d4b940d90b0efe499cab335e5a0fa5ca4a
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index f205979..bf324d6 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -603,9 +603,11 @@
static constexpr auto kVarHandleCAS = mirror::VarHandle::AccessModeTemplate::kCompareAndSet;
static constexpr auto kVarHandleCAX =
mirror::VarHandle::AccessModeTemplate::kCompareAndExchange;
+ static constexpr auto kVarHandleGAU = mirror::VarHandle::AccessModeTemplate::kGetAndUpdate;
DCHECK(intrinsic == Intrinsics::kUnsafeCASObject ||
mirror::VarHandle::GetAccessModeTemplateByIntrinsic(intrinsic) == kVarHandleCAS ||
- mirror::VarHandle::GetAccessModeTemplateByIntrinsic(intrinsic) == kVarHandleCAX);
+ mirror::VarHandle::GetAccessModeTemplateByIntrinsic(intrinsic) == kVarHandleCAX ||
+ mirror::VarHandle::GetAccessModeTemplateByIntrinsic(intrinsic) == kVarHandleGAU);
__ Bind(GetEntryLabel());
if (unpoison_ref_before_marking_) {