arm64: Implement Unsafe.compareAndSetObject intrinsic.
Also fix a few copy-paste errors in comments for x86/x86_64.
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 3.908 0.014
UnsafeCompareAndSetFieldString 3.917 0.014
Bug: 71781600
Bug: 202868177
Test: art/test.py --target -r -t 712-varhandle-invocations --64
Change-Id: I799f47210f8b70d6944418c05b985fe678f36208
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 92776f1..77b55e4 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -1098,7 +1098,8 @@
static void CreateUnsafeCASLocations(ArenaAllocator* allocator, HInvoke* invoke) {
bool can_call = kEmitCompilerReadBarrier &&
(invoke->GetIntrinsic() == Intrinsics::kUnsafeCASObject ||
- invoke->GetIntrinsic() == Intrinsics::kJdkUnsafeCASObject);
+ invoke->GetIntrinsic() == Intrinsics::kJdkUnsafeCASObject ||
+ invoke->GetIntrinsic() == Intrinsics::kJdkUnsafeCompareAndSetObject);
LocationSummary* locations =
new (allocator) LocationSummary(invoke,
can_call
@@ -1505,14 +1506,26 @@
}
void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCASInt(HInvoke* invoke) {
- CreateUnsafeCASLocations(allocator_, invoke);
+ // `jdk.internal.misc.Unsafe.compareAndSwapInt` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetInt(invoke);
}
void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCASLong(HInvoke* invoke) {
- CreateUnsafeCASLocations(allocator_, invoke);
+ // `jdk.internal.misc.Unsafe.compareAndSwapLong` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetLong(invoke);
}
void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCASObject(HInvoke* invoke) {
- // The only read barrier implementation supporting the
- // UnsafeCASObject intrinsic is the Baker-style read barriers. b/173104084
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetObject(invoke);
+}
+
+void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCompareAndSetInt(HInvoke* invoke) {
+ CreateUnsafeCASLocations(allocator_, invoke);
+}
+void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCompareAndSetLong(HInvoke* invoke) {
+ CreateUnsafeCASLocations(allocator_, invoke);
+}
+void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCompareAndSetObject(HInvoke* invoke) {
+ // The only supported read barrier implementation is the Baker-style read barriers.
if (kEmitCompilerReadBarrier && !kUseBakerReadBarrier) {
return;
}
@@ -1536,12 +1549,6 @@
}
}
}
-void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCompareAndSetInt(HInvoke* invoke) {
- CreateUnsafeCASLocations(allocator_, invoke);
-}
-void IntrinsicLocationsBuilderARM64::VisitJdkUnsafeCompareAndSetLong(HInvoke* invoke) {
- CreateUnsafeCASLocations(allocator_, invoke);
-}
void IntrinsicCodeGeneratorARM64::VisitUnsafeCASInt(HInvoke* invoke) {
VisitJdkUnsafeCASInt(invoke);
@@ -1554,20 +1561,30 @@
}
void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeCASInt(HInvoke* invoke) {
- GenUnsafeCas(invoke, DataType::Type::kInt32, codegen_);
+ // `jdk.internal.misc.Unsafe.compareAndSwapLong` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetInt(invoke);
}
void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeCASLong(HInvoke* invoke) {
- GenUnsafeCas(invoke, DataType::Type::kInt64, codegen_);
+ // `jdk.internal.misc.Unsafe.compareAndSwapLong` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetLong(invoke);
}
void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeCASObject(HInvoke* invoke) {
- GenUnsafeCas(invoke, DataType::Type::kReference, codegen_);
+ // `jdk.internal.misc.Unsafe.compareAndSwapObject` has compare-and-set semantics (see javadoc).
+ VisitJdkUnsafeCompareAndSetObject(invoke);
}
+
void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeCompareAndSetInt(HInvoke* invoke) {
GenUnsafeCas(invoke, DataType::Type::kInt32, codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeCompareAndSetLong(HInvoke* invoke) {
GenUnsafeCas(invoke, DataType::Type::kInt64, codegen_);
}
+void IntrinsicCodeGeneratorARM64::VisitJdkUnsafeCompareAndSetObject(HInvoke* invoke) {
+ // The only supported read barrier implementation is the Baker-style read barriers.
+ DCHECK(!kEmitCompilerReadBarrier || kUseBakerReadBarrier);
+
+ GenUnsafeCas(invoke, DataType::Type::kReference, codegen_);
+}
enum class GetAndUpdateOp {
kSet,
@@ -5655,7 +5672,6 @@
UNIMPLEMENTED_INTRINSIC(ARM64, JdkUnsafeGetAndSetInt)
UNIMPLEMENTED_INTRINSIC(ARM64, JdkUnsafeGetAndSetLong)
UNIMPLEMENTED_INTRINSIC(ARM64, JdkUnsafeGetAndSetObject)
-UNIMPLEMENTED_INTRINSIC(ARM64, JdkUnsafeCompareAndSetObject)
UNREACHABLE_INTRINSICS(ARM64)