diff options
author | 2025-02-17 09:50:39 +0000 | |
---|---|---|
committer | 2025-02-17 03:41:16 -0800 | |
commit | e7776615ea6b005051219845a143231b5bb1e4f8 (patch) | |
tree | 29e71562cf79334022969c9adede74e0b05290a9 /compiler/optimizing | |
parent | 3075cc5e59750ba1900e8c3ec3f5a7def4594184 (diff) |
Optimizing: Do not crash on bad `filled-new-array` opcode.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: testrunner.py --host --jit --jit-on-first-use -t 412
Change-Id: I8b86c806492b9b3ff44a2e670650e5ed18749190
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 27 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.h | 6 |
2 files changed, 21 insertions, 12 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index f65586f505..1f2628c8ec 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -2542,9 +2542,9 @@ HNewArray* HInstructionBuilder::BuildNewArray(uint32_t dex_pc, return new_array; } -HNewArray* HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, - dex::TypeIndex type_index, - const InstructionOperands& operands) { +bool HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, + dex::TypeIndex type_index, + const InstructionOperands& operands) { const size_t number_of_operands = operands.GetNumberOfOperands(); HInstruction* length = graph_->GetIntConstant(number_of_operands); @@ -2552,7 +2552,13 @@ HNewArray* HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, const char* descriptor = dex_file_->GetTypeDescriptor(type_index); DCHECK_EQ(descriptor[0], '[') << descriptor; char primitive = descriptor[1]; - DCHECK(primitive == 'I' || primitive == 'L' || primitive == '[') << descriptor; + if (primitive != 'I' && primitive != 'L' && primitive != '[') { + DCHECK(primitive != 'J' && primitive != 'D'); // Rejected by the verifier. + // FIXME: Why do we JIT compile a method with `VERIFY_ERROR_FILLED_NEW_ARRAY` when + // `CanCompilerHandleVerificationFailure(VERIFY_ERROR_FILLED_NEW_ARRAY)` returns false? + MaybeRecordStat(compilation_stats_, MethodCompilationStat::kNotCompiledMalformedOpcode); + return false; + } bool is_reference_array = (primitive == 'L') || (primitive == '['); DataType::Type type = is_reference_array ? DataType::Type::kReference : DataType::Type::kInt32; @@ -2565,7 +2571,8 @@ HNewArray* HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, } latest_result_ = new_array; - return new_array; + BuildConstructorFenceForAllocation(new_array); + return true; } template <typename T> @@ -3718,16 +3725,18 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, uint32_t args[5]; uint32_t number_of_vreg_arguments = instruction.GetVarArgs(args); VarArgsInstructionOperands operands(args, number_of_vreg_arguments); - HNewArray* new_array = BuildFilledNewArray(dex_pc, type_index, operands); - BuildConstructorFenceForAllocation(new_array); + if (!BuildFilledNewArray(dex_pc, type_index, operands)) { + return false; + } break; } case Instruction::FILLED_NEW_ARRAY_RANGE: { dex::TypeIndex type_index(instruction.VRegB_3rc()); RangeInstructionOperands operands(instruction.VRegC_3rc(), instruction.VRegA_3rc()); - HNewArray* new_array = BuildFilledNewArray(dex_pc, type_index, operands); - BuildConstructorFenceForAllocation(new_array); + if (!BuildFilledNewArray(dex_pc, type_index, operands)) { + return false; + } break; } diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index b3b5deae59..90ab75ec92 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -177,9 +177,9 @@ class HInstructionBuilder : public ValueObject { HNewArray* BuildNewArray(uint32_t dex_pc, dex::TypeIndex type_index, HInstruction* length); // Builds a new array node and the instructions that fill it. - HNewArray* BuildFilledNewArray(uint32_t dex_pc, - dex::TypeIndex type_index, - const InstructionOperands& operands); + bool BuildFilledNewArray(uint32_t dex_pc, + dex::TypeIndex type_index, + const InstructionOperands& operands); void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc); |