diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2016-09-23 15:40:41 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2016-09-26 11:49:24 +0100 |
commit | 50a9ed014e3b4dec67246ea07727d7bec89bfb17 (patch) | |
tree | 1fcbf2173f8b7409c2feb94a372f9e8390c8bad7 /compiler/optimizing/instruction_builder.cc | |
parent | cbb651fdf2c88052a4c556c96adac729176b61ea (diff) |
Compensate in compiler for verifier shortcomings.
The verifier does not differentiate zero and null, so a move-object
of zero can be used as a non-object later on.
Change the compiler to ignore the object conversion when the input
is zero or a phi (which might just hold zeros). The type propagation
will then do proper inferencing of the types.
Also remove some stalled comments in ssa_builder.cc.
bug:31313170
test: dex2oat b31313170.apk
test: run-test 800
test: m test-art-host-run-test
Change-Id: I579d667415a7decf8ff2c2238dae4c13eec5d0e0
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 5a6a212cc9..f7dc2377be 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1815,7 +1815,20 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::MOVE_OBJECT: case Instruction::MOVE_OBJECT_16: case Instruction::MOVE_OBJECT_FROM16: { - HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot); + // The verifier has no notion of a null type, so a move-object of constant 0 + // will lead to the same constant 0 in the destination register. To mimic + // this behavior, we just pretend we haven't seen a type change (int to reference) + // for the 0 constant and phis. We rely on our type propagation to eventually get the + // types correct. + uint32_t reg_number = instruction.VRegB(); + HInstruction* value = (*current_locals_)[reg_number]; + if (value->IsIntConstant()) { + DCHECK_EQ(value->AsIntConstant()->GetValue(), 0); + } else if (value->IsPhi()) { + DCHECK(value->GetType() == Primitive::kPrimInt || value->GetType() == Primitive::kPrimNot); + } else { + value = LoadLocal(reg_number, Primitive::kPrimNot); + } UpdateLocal(instruction.VRegA(), value); break; } |