X86: Implement VarHandle.getAndSet, getAndSetAcquire, getAndSetRelease
This commit implements VarHandle getAndSet variants. This implied adding
xchgb and xchgw instructions and tests for them.
Also, all the varType checks were moved to GenerateVarHandleCommonChecks.
Test: ART_HEAP_POISONING=true art/test.py --host -r -t 712-varhandle-invocation --32
Test: ART_HEAP_POISONING=false art/test.py --host -r -t 712-varhandle-invocation --32
Test: ART_USE_READ_BARRIER=true art/test.py --host -r -t 712-varhandle-invocation --32
Test: ART_USE_READ_BARRIER=false art/test.py --host -r -t 712-varhandle-invocation --32
Test: m test-art-host-gtest
Bug: 65872996
Change-Id: I675f47e1dbb51a5ece42f20ad8ce552cfef63ffe
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc
index da53138..adc7bcc 100644
--- a/compiler/utils/x86/assembler_x86.cc
+++ b/compiler/utils/x86/assembler_x86.cc
@@ -2887,6 +2887,27 @@
}
+void X86Assembler::xchgb(Register reg, const Address& address) {
+ // For testing purpose
+ xchgb(static_cast<ByteRegister>(reg), address);
+}
+
+
+void X86Assembler::xchgb(ByteRegister reg, const Address& address) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitUint8(0x86);
+ EmitOperand(reg, address);
+}
+
+
+void X86Assembler::xchgw(Register reg, const Address& address) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOperandSizeOverride();
+ EmitUint8(0x87);
+ EmitOperand(reg, address);
+}
+
+
void X86Assembler::xchgl(Register dst, Register src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x87);
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h
index 3dfeecb..a9050e6 100644
--- a/compiler/utils/x86/assembler_x86.h
+++ b/compiler/utils/x86/assembler_x86.h
@@ -695,6 +695,10 @@
void fptan();
void fprem();
+ void xchgb(ByteRegister reg, const Address& address);
+ void xchgb(Register reg, const Address& address);
+ void xchgw(Register reg, const Address& address);
+
void xchgl(Register dst, Register src);
void xchgl(Register reg, const Address& address);
diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc
index ee0f8a1..32d138f 100644
--- a/compiler/utils/x86/assembler_x86_test.cc
+++ b/compiler/utils/x86/assembler_x86_test.cc
@@ -331,6 +331,21 @@
DriverStr(expected, "LoadLongConstant");
}
+TEST_F(AssemblerX86Test, Xchgb) {
+ DriverStr(RepeatwA(&x86::X86Assembler::xchgb,
+ "xchgb {mem}, %{reg}"), "xchgb");
+}
+
+TEST_F(AssemblerX86Test, Xchgw) {
+ DriverStr(RepeatrA(&x86::X86Assembler::xchgw,
+ "xchgw {mem}, %{reg}"), "xchgw");
+}
+
+TEST_F(AssemblerX86Test, Xchgl) {
+ DriverStr(RepeatRA(&x86::X86Assembler::xchgl,
+ "xchgl {mem}, %{reg}"), "xchgl");
+}
+
TEST_F(AssemblerX86Test, LockCmpxchgb) {
DriverStr(RepeatAw(&x86::X86Assembler::LockCmpxchgb,
"lock cmpxchgb %{reg}, {mem}"), "lock_cmpxchgb");