x86: Implement Unsafe.compareAndSetObject intrinsic.
The implementation is the same as Unsafe.compareAndSwapObject, as the
latter operation has compare-and-set semantics.
Benchmarks improvements (using benchmarks provided by
https://android-review.googlesource.com/1420959):
benchmark before after
-----------------------------------------------------
UnsafeCompareAndSetStaticFieldString 1.442 0.011
UnsafeCompareAndSetFieldString 1.446 0.009
Bug: 71781600
Test: ART_HEAP_POISONING=true m build-art-host-tests \
&& art/test.py --host -r -t 712-varhandle-invocations --32
Change-Id: I325e1f09d3b4d016d43657604be9a2d5b910e68a
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index 6015a6d..c9c8a5a 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -2070,7 +2070,8 @@
bool can_call = kEmitCompilerReadBarrier &&
kUseBakerReadBarrier &&
(invoke->GetIntrinsic() == Intrinsics::kUnsafeCASObject ||
- invoke->GetIntrinsic() == Intrinsics::kJdkUnsafeCASObject);
+ invoke->GetIntrinsic() == Intrinsics::kJdkUnsafeCASObject ||
+ invoke->GetIntrinsic() == Intrinsics::kJdkUnsafeCompareAndSetObject);
LocationSummary* locations =
new (allocator) LocationSummary(invoke,
can_call
@@ -2116,21 +2117,18 @@
}
void IntrinsicLocationsBuilderX86::VisitJdkUnsafeCASInt(HInvoke* invoke) {
- CreateIntIntIntIntIntToInt(allocator_, DataType::Type::kInt32, invoke);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetInt(invoke);
}
void IntrinsicLocationsBuilderX86::VisitJdkUnsafeCASLong(HInvoke* invoke) {
- CreateIntIntIntIntIntToInt(allocator_, DataType::Type::kInt64, invoke);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetLong(invoke);
}
void IntrinsicLocationsBuilderX86::VisitJdkUnsafeCASObject(HInvoke* invoke) {
- // The only read barrier implementation supporting the
- // JdkUnsafeCASObject intrinsic is the Baker-style read barriers.
- if (kEmitCompilerReadBarrier && !kUseBakerReadBarrier) {
- return;
- }
-
- CreateIntIntIntIntIntToInt(allocator_, DataType::Type::kReference, invoke);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetObject(invoke);
}
void IntrinsicLocationsBuilderX86::VisitJdkUnsafeCompareAndSetInt(HInvoke* invoke) {
@@ -2141,6 +2139,15 @@
CreateIntIntIntIntIntToInt(allocator_, DataType::Type::kInt64, invoke);
}
+void IntrinsicLocationsBuilderX86::VisitJdkUnsafeCompareAndSetObject(HInvoke* invoke) {
+ // The only supported read barrier implementation is the Baker-style read barriers.
+ if (kEmitCompilerReadBarrier && !kUseBakerReadBarrier) {
+ return;
+ }
+
+ CreateIntIntIntIntIntToInt(allocator_, DataType::Type::kReference, invoke);
+}
+
static void GenPrimitiveLockedCmpxchg(DataType::Type type,
CodeGeneratorX86* codegen,
Location expected_value,
@@ -2378,19 +2385,18 @@
}
void IntrinsicCodeGeneratorX86::VisitJdkUnsafeCASInt(HInvoke* invoke) {
- GenCAS(DataType::Type::kInt32, invoke, codegen_);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetInt(invoke);
}
void IntrinsicCodeGeneratorX86::VisitJdkUnsafeCASLong(HInvoke* invoke) {
- GenCAS(DataType::Type::kInt64, invoke, codegen_);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetLong(invoke);
}
void IntrinsicCodeGeneratorX86::VisitJdkUnsafeCASObject(HInvoke* invoke) {
- // The only read barrier implementation supporting the
- // JdkUnsafeCASObject intrinsic is the Baker-style read barriers.
- DCHECK(!kEmitCompilerReadBarrier || kUseBakerReadBarrier);
-
- GenCAS(DataType::Type::kReference, invoke, codegen_);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetObject(invoke);
}
void IntrinsicCodeGeneratorX86::VisitJdkUnsafeCompareAndSetInt(HInvoke* invoke) {
@@ -2401,6 +2407,12 @@
GenCAS(DataType::Type::kInt64, invoke, codegen_);
}
+void IntrinsicCodeGeneratorX86::VisitJdkUnsafeCompareAndSetObject(HInvoke* invoke) {
+ // The only supported read barrier implementation is the Baker-style read barriers.
+ DCHECK(!kEmitCompilerReadBarrier || kUseBakerReadBarrier);
+
+ GenCAS(DataType::Type::kReference, invoke, codegen_);
+}
void IntrinsicLocationsBuilderX86::VisitIntegerReverse(HInvoke* invoke) {
LocationSummary* locations =
@@ -4840,7 +4852,6 @@
UNIMPLEMENTED_INTRINSIC(X86, JdkUnsafeGetAndSetInt)
UNIMPLEMENTED_INTRINSIC(X86, JdkUnsafeGetAndSetLong)
UNIMPLEMENTED_INTRINSIC(X86, JdkUnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(X86, JdkUnsafeCompareAndSetObject)
UNREACHABLE_INTRINSICS(X86)