diff options
author | 2021-07-21 16:20:54 +0000 | |
---|---|---|
committer | 2021-07-21 16:21:35 +0000 | |
commit | 4a889b7f1e58368f0ffd795eaa24f2f493ccab8d (patch) | |
tree | 6449e59690e4219f3b3c1beba3631ecb586a584d /compiler/optimizing/intrinsics_x86.cc | |
parent | 5d446a37192427b4d24ca9add5d8e2409f665c4d (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_x86.cc')
-rw-r--r-- | compiler/optimizing/intrinsics_x86.cc | 112 |
1 files changed, 84 insertions, 28 deletions
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index bed9ebe4b4..d11bfa27d3 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -3291,20 +3291,81 @@ void IntrinsicCodeGeneratorX86::VisitIntegerDivideUnsigned(HInvoke* invoke) { __ Bind(slow_path->GetExitLabel()); } -static bool HasVarHandleIntrinsicImplementation(HInvoke* invoke) { - VarHandleOptimizations optimizations(invoke); - if (optimizations.GetDoNotIntrinsify()) { - return false; - } - +static bool IsValidFieldVarHandleExpected(HInvoke* invoke) { 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. return false; } + 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 @@ static void GenerateSubTypeObjectCheck(Register object, __ 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 @@ static void GenerateVarHandleInstanceFieldChecks(HInvoke* invoke, __ 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 @@ static void GenerateVarHandleCommonChecks(HInvoke *invoke, 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 @@ static void CreateVarHandleGetLocations(HInvoke* invoke) { return; } - if (!HasVarHandleIntrinsicImplementation(invoke)) { + if (!IsValidFieldVarHandleExpected(invoke)) { return; } @@ -3670,7 +3726,7 @@ static void CreateVarHandleSetLocations(HInvoke* invoke) { return; } - if (!HasVarHandleIntrinsicImplementation(invoke)) { + if (!IsValidFieldVarHandleExpected(invoke)) { return; } @@ -3840,7 +3896,7 @@ static void CreateVarHandleGetAndSetLocations(HInvoke* invoke) { return; } - if (!HasVarHandleIntrinsicImplementation(invoke)) { + if (!IsValidFieldVarHandleExpected(invoke)) { return; } @@ -4011,7 +4067,7 @@ static void CreateVarHandleCompareAndSetOrExchangeLocations(HInvoke* invoke) { return; } - if (!HasVarHandleIntrinsicImplementation(invoke)) { + if (!IsValidFieldVarHandleExpected(invoke)) { return; } @@ -4194,7 +4250,7 @@ static void CreateVarHandleGetAndAddLocations(HInvoke* invoke) { return; } - if (!HasVarHandleIntrinsicImplementation(invoke)) { + if (!IsValidFieldVarHandleExpected(invoke)) { return; } @@ -4344,7 +4400,7 @@ static void CreateVarHandleGetAndBitwiseOpLocations(HInvoke* invoke) { return; } - if (!HasVarHandleIntrinsicImplementation(invoke)) { + if (!IsValidFieldVarHandleExpected(invoke)) { return; } |