Revert "Compile time null checks for VarHandle intrinsics."
This reverts commit b3a7a6a72d7b91ee5507bd7314a3aae3948e6f29.
Reason for revert: Breaks ART baseline compiler.
Bug: 191765508
Change-Id: Ida63660e0149c4847f015950f95282e61add7204
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index bed9ebe..d11bfa2 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -3291,20 +3291,81 @@
__ Bind(slow_path->GetExitLabel());
}
-static bool HasVarHandleIntrinsicImplementation(HInvoke* invoke) {
- VarHandleOptimizations optimizations(invoke);
- if (optimizations.GetDoNotIntrinsify()) {
+static bool IsValidFieldVarHandleExpected(HInvoke* invoke) {
+ size_t expected_coordinates_count = GetExpectedVarHandleCoordinatesCount(invoke);
+ if (expected_coordinates_count > 1u) {
+ // Only static and instance fields VarHandle are supported now.
return false;
}
- size_t expected_coordinates_count = GetExpectedVarHandleCoordinatesCount(invoke);
- DCHECK_LE(expected_coordinates_count, 2u); // Filtered by the `DoNotIntrinsify` flag above.
- if (expected_coordinates_count > 1u) {
- // Only static and instance fields VarHandle are supported now.
- // TODO: add support for arrays and views.
+ if (expected_coordinates_count == 1u &&
+ invoke->InputAt(1)->GetType() != DataType::Type::kReference) {
+ // For instance fields, the source object must be a reference
return false;
}
+ uint32_t number_of_arguments = invoke->GetNumberOfArguments();
+ DataType::Type return_type = invoke->GetType();
+ mirror::VarHandle::AccessModeTemplate access_mode_template =
+ mirror::VarHandle::GetAccessModeTemplateByIntrinsic(invoke->GetIntrinsic());
+ switch (access_mode_template) {
+ case mirror::VarHandle::AccessModeTemplate::kGet:
+ // The return type should be the same as varType, so it shouldn't be void.
+ if (return_type == DataType::Type::kVoid) {
+ return false;
+ }
+ break;
+ case mirror::VarHandle::AccessModeTemplate::kSet:
+ if (return_type != DataType::Type::kVoid) {
+ return false;
+ }
+ break;
+ case mirror::VarHandle::AccessModeTemplate::kCompareAndSet: {
+ if (return_type != DataType::Type::kBool) {
+ return false;
+ }
+ uint32_t expected_value_index = number_of_arguments - 2;
+ uint32_t new_value_index = number_of_arguments - 1;
+ DataType::Type expected_value_type = GetDataTypeFromShorty(invoke, expected_value_index);
+ DataType::Type new_value_type = GetDataTypeFromShorty(invoke, new_value_index);
+
+ if (expected_value_type != new_value_type) {
+ return false;
+ }
+ break;
+ }
+ case mirror::VarHandle::AccessModeTemplate::kGetAndUpdate: {
+ DataType::Type value_type = GetDataTypeFromShorty(invoke, number_of_arguments - 1);
+ if (IsVarHandleGetAndAdd(invoke) &&
+ (value_type == DataType::Type::kReference || value_type == DataType::Type::kBool)) {
+ // We should only add numerical types.
+ return false;
+ } else if (IsVarHandleGetAndBitwiseOp(invoke) && !DataType::IsIntegralType(value_type)) {
+ // We can only apply operators to bitwise integral types.
+ // Note that bitwise VarHandle operations accept a non-integral boolean type and
+ // perform the appropriate logical operation. However, the result is the same as
+ // using the bitwise operation on our boolean representation and this fits well
+ // with DataType::IsIntegralType() treating the compiler type kBool as integral.
+ return false;
+ }
+ if (value_type != return_type) {
+ return false;
+ }
+ break;
+ }
+ case mirror::VarHandle::AccessModeTemplate::kCompareAndExchange: {
+ uint32_t expected_value_index = number_of_arguments - 2;
+ uint32_t new_value_index = number_of_arguments - 1;
+ DataType::Type expected_value_type = GetDataTypeFromShorty(invoke, expected_value_index);
+ DataType::Type new_value_type = GetDataTypeFromShorty(invoke, new_value_index);
+
+ if (expected_value_type != new_value_type || return_type != expected_value_type) {
+ return false;
+ }
+ break;
+ }
+ }
+
return true;
}
@@ -3365,15 +3426,11 @@
__ Bind(&type_matched);
}
-static void GenerateVarHandleInstanceFieldChecks(HInvoke* invoke,
- Register temp,
- SlowPathCode* slow_path,
- X86Assembler* assembler) {
- VarHandleOptimizations optimizations(invoke);
- LocationSummary* locations = invoke->GetLocations();
- Register varhandle_object = locations->InAt(0).AsRegister<Register>();
- Register object = locations->InAt(1).AsRegister<Register>();
-
+static void GenerateVarHandleInstanceFieldObjectCheck(Register varhandle_object,
+ Register object,
+ Register temp,
+ SlowPathCode* slow_path,
+ X86Assembler* assembler) {
const uint32_t coordtype0_offset = mirror::VarHandle::CoordinateType0Offset().Uint32Value();
const uint32_t coordtype1_offset = mirror::VarHandle::CoordinateType1Offset().Uint32Value();
@@ -3384,10 +3441,8 @@
__ j(kNotEqual, slow_path->GetEntryLabel());
// Check if the object is null
- if (!optimizations.GetSkipObjectNullCheck()) {
- __ testl(object, object);
- __ j(kZero, slow_path->GetEntryLabel());
- }
+ __ testl(object, object);
+ __ j(kZero, slow_path->GetEntryLabel());
// Check the object's class against coordinateType0.
GenerateSubTypeObjectCheck(object,
@@ -3435,7 +3490,8 @@
GenerateVarHandleStaticFieldCheck(vh_object, slow_path, assembler);
break;
case 1u: {
- GenerateVarHandleInstanceFieldChecks(invoke, temp, slow_path, assembler);
+ Register object = locations->InAt(1).AsRegister<Register>();
+ GenerateVarHandleInstanceFieldObjectCheck(vh_object, object, temp, slow_path, assembler);
break;
}
default:
@@ -3547,7 +3603,7 @@
return;
}
- if (!HasVarHandleIntrinsicImplementation(invoke)) {
+ if (!IsValidFieldVarHandleExpected(invoke)) {
return;
}
@@ -3670,7 +3726,7 @@
return;
}
- if (!HasVarHandleIntrinsicImplementation(invoke)) {
+ if (!IsValidFieldVarHandleExpected(invoke)) {
return;
}
@@ -3840,7 +3896,7 @@
return;
}
- if (!HasVarHandleIntrinsicImplementation(invoke)) {
+ if (!IsValidFieldVarHandleExpected(invoke)) {
return;
}
@@ -4011,7 +4067,7 @@
return;
}
- if (!HasVarHandleIntrinsicImplementation(invoke)) {
+ if (!IsValidFieldVarHandleExpected(invoke)) {
return;
}
@@ -4194,7 +4250,7 @@
return;
}
- if (!HasVarHandleIntrinsicImplementation(invoke)) {
+ if (!IsValidFieldVarHandleExpected(invoke)) {
return;
}
@@ -4344,7 +4400,7 @@
return;
}
- if (!HasVarHandleIntrinsicImplementation(invoke)) {
+ if (!IsValidFieldVarHandleExpected(invoke)) {
return;
}