summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2025-02-17 09:50:39 +0000
committer VladimĂ­r Marko <vmarko@google.com> 2025-02-17 03:41:16 -0800
commite7776615ea6b005051219845a143231b5bb1e4f8 (patch)
tree29e71562cf79334022969c9adede74e0b05290a9 /compiler/optimizing
parent3075cc5e59750ba1900e8c3ec3f5a7def4594184 (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.cc27
-rw-r--r--compiler/optimizing/instruction_builder.h6
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);