summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics_arm64.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2021-07-21 16:20:54 +0000
committer Vladimir Marko <vmarko@google.com> 2021-07-21 16:21:35 +0000
commit4a889b7f1e58368f0ffd795eaa24f2f493ccab8d (patch)
tree6449e59690e4219f3b3c1beba3631ecb586a584d /compiler/optimizing/intrinsics_arm64.cc
parent5d446a37192427b4d24ca9add5d8e2409f665c4d (diff)
Revert "Compile time null checks for VarHandle intrinsics."
This reverts commit b3a7a6a72d7b91ee5507bd7314a3aae3948e6f29. Reason for revert: Breaks ART baseline compiler. Bug: 191765508 Change-Id: Ida63660e0149c4847f015950f95282e61add7204
Diffstat (limited to 'compiler/optimizing/intrinsics_arm64.cc')
-rw-r--r--compiler/optimizing/intrinsics_arm64.cc107
1 files changed, 91 insertions, 16 deletions
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 800e5bdd52..d0c64c2230 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -4045,7 +4045,6 @@ static void GenerateVarHandleStaticFieldCheck(HInvoke* invoke,
static void GenerateVarHandleInstanceFieldChecks(HInvoke* invoke,
CodeGeneratorARM64* codegen,
SlowPathCodeARM64* slow_path) {
- VarHandleOptimizations optimizations(invoke);
MacroAssembler* masm = codegen->GetVIXLAssembler();
Register varhandle = InputRegisterAt(invoke, 0);
Register object = InputRegisterAt(invoke, 1);
@@ -4054,9 +4053,7 @@ static void GenerateVarHandleInstanceFieldChecks(HInvoke* invoke,
const MemberOffset coordinate_type1_offset = mirror::VarHandle::CoordinateType1Offset();
// Null-check the object.
- if (!optimizations.GetSkipObjectNullCheck()) {
- __ Cbz(object, slow_path->GetEntryLabel());
- }
+ __ Cbz(object, slow_path->GetEntryLabel());
UseScratchRegisterScope temps(masm);
Register temp = temps.AcquireW();
@@ -4093,7 +4090,6 @@ static DataType::Type GetVarHandleExpectedValueType(HInvoke* invoke,
static void GenerateVarHandleArrayChecks(HInvoke* invoke,
CodeGeneratorARM64* codegen,
VarHandleSlowPathARM64* slow_path) {
- VarHandleOptimizations optimizations(invoke);
MacroAssembler* masm = codegen->GetVIXLAssembler();
Register varhandle = InputRegisterAt(invoke, 0);
Register object = InputRegisterAt(invoke, 1);
@@ -4110,9 +4106,7 @@ static void GenerateVarHandleArrayChecks(HInvoke* invoke,
const MemberOffset array_length_offset = mirror::Array::LengthOffset();
// Null-check the object.
- if (!optimizations.GetSkipObjectNullCheck()) {
- __ Cbz(object, slow_path->GetEntryLabel());
- }
+ __ Cbz(object, slow_path->GetEntryLabel());
UseScratchRegisterScope temps(masm);
Register temp = temps.AcquireW();
@@ -4268,6 +4262,91 @@ static void GenerateVarHandleTarget(HInvoke* invoke,
}
}
+static bool HasVarHandleIntrinsicImplementation(HInvoke* invoke) {
+ size_t expected_coordinates_count = GetExpectedVarHandleCoordinatesCount(invoke);
+ if (expected_coordinates_count > 2u) {
+ // Invalid coordinate count. This invoke shall throw at runtime.
+ return false;
+ }
+ if (expected_coordinates_count != 0u &&
+ invoke->InputAt(1)->GetType() != DataType::Type::kReference) {
+ // Except for static fields (no coordinates), the first coordinate must be a reference.
+ return false;
+ }
+ if (expected_coordinates_count == 2u) {
+ // For arrays and views, the second coordinate must be convertible to `int`.
+ // In this context, `boolean` is not convertible but we have to look at the shorty
+ // as compiler transformations can give the invoke a valid boolean input.
+ DataType::Type index_type = GetDataTypeFromShorty(invoke, 2);
+ if (index_type == DataType::Type::kBool ||
+ DataType::Kind(index_type) != DataType::Type::kInt32) {
+ 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::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;
+ }
+ 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;
+ }
+ }
+
+ return true;
+}
+
static LocationSummary* CreateVarHandleCommonLocations(HInvoke* invoke) {
size_t expected_coordinates_count = GetExpectedVarHandleCoordinatesCount(invoke);
DataType::Type return_type = invoke->GetType();
@@ -4320,8 +4399,7 @@ static LocationSummary* CreateVarHandleCommonLocations(HInvoke* invoke) {
}
static void CreateVarHandleGetLocations(HInvoke* invoke) {
- VarHandleOptimizations optimizations(invoke);
- if (optimizations.GetDoNotIntrinsify()) {
+ if (!HasVarHandleIntrinsicImplementation(invoke)) {
return;
}
@@ -4447,8 +4525,7 @@ void IntrinsicCodeGeneratorARM64::VisitVarHandleGetVolatile(HInvoke* invoke) {
}
static void CreateVarHandleSetLocations(HInvoke* invoke) {
- VarHandleOptimizations optimizations(invoke);
- if (optimizations.GetDoNotIntrinsify()) {
+ if (!HasVarHandleIntrinsicImplementation(invoke)) {
return;
}
@@ -4553,8 +4630,7 @@ void IntrinsicCodeGeneratorARM64::VisitVarHandleSetVolatile(HInvoke* invoke) {
}
static void CreateVarHandleCompareAndSetOrExchangeLocations(HInvoke* invoke, bool return_success) {
- VarHandleOptimizations optimizations(invoke);
- if (optimizations.GetDoNotIntrinsify()) {
+ if (!HasVarHandleIntrinsicImplementation(invoke)) {
return;
}
@@ -4901,8 +4977,7 @@ void IntrinsicCodeGeneratorARM64::VisitVarHandleWeakCompareAndSetRelease(HInvoke
static void CreateVarHandleGetAndUpdateLocations(HInvoke* invoke,
GetAndUpdateOp get_and_update_op) {
- VarHandleOptimizations optimizations(invoke);
- if (optimizations.GetDoNotIntrinsify()) {
+ if (!HasVarHandleIntrinsicImplementation(invoke)) {
return;
}