X86: Add VarHandle.getAndAddAcquire and getAndAddRelease
Test: art/test.py --host -r -t 712-varhandle-invocation --32
Test: art/test/run-test --dex2oat-jobs 4 --host --prebuild --compact-dex-level fast --jit --no-relocate --runtime-option -Xcheck:jni 954-invoke-polymorphic-verifier
Bug: 65872996
Change-Id: I685831b0dc57c0a2781f512515480db7fc830750
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index a6f8384..661680d 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -3150,6 +3150,17 @@
}
}
+static bool IsVarHandleGetAndAdd(HInvoke* invoke) {
+ switch (invoke->GetIntrinsic()) {
+ case Intrinsics::kVarHandleGetAndAdd:
+ case Intrinsics::kVarHandleGetAndAddAcquire:
+ case Intrinsics::kVarHandleGetAndAddRelease:
+ return true;
+ default:
+ return false;
+ }
+}
+
static bool IsValidFieldVarHandleExpected(HInvoke* invoke) {
size_t expected_coordinates_count = GetExpectedVarHandleCoordinatesCount(invoke);
if (expected_coordinates_count > 1u) {
@@ -3189,7 +3200,7 @@
}
case mirror::VarHandle::AccessModeTemplate::kGetAndUpdate: {
DataType::Type value_type = GetDataTypeFromShorty(invoke, number_of_arguments - 1);
- if (invoke->GetIntrinsic() == Intrinsics::kVarHandleGetAndAdd &&
+ if (IsVarHandleGetAndAdd(invoke) &&
(value_type == DataType::Type::kReference || value_type == DataType::Type::kBool)) {
// We should only add numerical types
return false;
@@ -3860,7 +3871,7 @@
GenerateVarHandleCompareAndSet(invoke, codegen_);
}
-void IntrinsicLocationsBuilderX86::VisitVarHandleGetAndAdd(HInvoke* invoke) {
+static void CreateVarHandleGetAndAddLocations(HInvoke* invoke) {
// The only read barrier implementation supporting the
// VarHandleGet intrinsic is the Baker-style read barriers.
if (kEmitCompilerReadBarrier && !kUseBakerReadBarrier) {
@@ -3909,12 +3920,11 @@
}
}
-void IntrinsicCodeGeneratorX86::VisitVarHandleGetAndAdd(HInvoke* invoke) {
+static void GenerateVarHandleGetAndAdd(HInvoke* invoke, CodeGeneratorX86* codegen) {
// The only read barrier implementation supporting the
// VarHandleGet intrinsic is the Baker-style read barriers.
DCHECK(!kEmitCompilerReadBarrier || kUseBakerReadBarrier);
- CodeGeneratorX86* codegen = down_cast<CodeGeneratorX86*>(codegen_);
X86Assembler* assembler = codegen->GetAssembler();
LocationSummary* locations = invoke->GetLocations();
uint32_t number_of_arguments = invoke->GetNumberOfArguments();
@@ -3990,6 +4000,30 @@
__ Bind(slow_path->GetExitLabel());
}
+void IntrinsicLocationsBuilderX86::VisitVarHandleGetAndAdd(HInvoke* invoke) {
+ CreateVarHandleGetAndAddLocations(invoke);
+}
+
+void IntrinsicCodeGeneratorX86::VisitVarHandleGetAndAdd(HInvoke* invoke) {
+ GenerateVarHandleGetAndAdd(invoke, codegen_);
+}
+
+void IntrinsicLocationsBuilderX86::VisitVarHandleGetAndAddAcquire(HInvoke* invoke) {
+ CreateVarHandleGetAndAddLocations(invoke);
+}
+
+void IntrinsicCodeGeneratorX86::VisitVarHandleGetAndAddAcquire(HInvoke* invoke) {
+ GenerateVarHandleGetAndAdd(invoke, codegen_);
+}
+
+void IntrinsicLocationsBuilderX86::VisitVarHandleGetAndAddRelease(HInvoke* invoke) {
+ CreateVarHandleGetAndAddLocations(invoke);
+}
+
+void IntrinsicCodeGeneratorX86::VisitVarHandleGetAndAddRelease(HInvoke* invoke) {
+ GenerateVarHandleGetAndAdd(invoke, codegen_);
+}
+
static void CreateVarHandleGetAndBitwiseOpLocations(HInvoke* invoke) {
// The only read barrier implementation supporting the
// VarHandleGet intrinsic is the Baker-style read barriers.
@@ -4250,8 +4284,6 @@
UNIMPLEMENTED_INTRINSIC(X86, VarHandleCompareAndExchange)
UNIMPLEMENTED_INTRINSIC(X86, VarHandleCompareAndExchangeAcquire)
UNIMPLEMENTED_INTRINSIC(X86, VarHandleCompareAndExchangeRelease)
-UNIMPLEMENTED_INTRINSIC(X86, VarHandleGetAndAddAcquire)
-UNIMPLEMENTED_INTRINSIC(X86, VarHandleGetAndAddRelease)
UNIMPLEMENTED_INTRINSIC(X86, VarHandleGetAndSet)
UNIMPLEMENTED_INTRINSIC(X86, VarHandleGetAndSetAcquire)
UNIMPLEMENTED_INTRINSIC(X86, VarHandleGetAndSetRelease)