summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
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
commit50a9ed014e3b4dec67246ea07727d7bec89bfb17 (patch)
tree1fcbf2173f8b7409c2feb94a372f9e8390c8bad7 /compiler/optimizing
parentcbb651fdf2c88052a4c556c96adac729176b61ea (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')
-rw-r--r--compiler/optimizing/instruction_builder.cc15
-rw-r--r--compiler/optimizing/ssa_builder.cc14
2 files changed, 18 insertions, 11 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;
}
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index f7dc112d00..03807ba1ee 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -163,18 +163,12 @@ static bool TypePhiFromInputs(HPhi* phi) {
// Replace inputs of `phi` to match its type. Return false if conflict is identified.
bool SsaBuilder::TypeInputsOfPhi(HPhi* phi, ArenaVector<HPhi*>* worklist) {
Primitive::Type common_type = phi->GetType();
- if (common_type == Primitive::kPrimVoid || Primitive::IsIntegralType(common_type)) {
- // Phi either contains only other untyped phis (common_type == kPrimVoid),
- // or `common_type` is integral and we do not need to retype ambiguous inputs
- // because they are always constructed with the integral type candidate.
+ if (Primitive::IsIntegralType(common_type)) {
+ // We do not need to retype ambiguous inputs because they are always constructed
+ // with the integral type candidate.
if (kIsDebugBuild) {
for (HInstruction* input : phi->GetInputs()) {
- if (common_type == Primitive::kPrimVoid) {
- DCHECK(input->IsPhi() && input->GetType() == Primitive::kPrimVoid);
- } else {
- DCHECK((input->IsPhi() && input->GetType() == Primitive::kPrimVoid) ||
- HPhi::ToPhiType(input->GetType()) == common_type);
- }
+ DCHECK(HPhi::ToPhiType(input->GetType()) == common_type);
}
}
// Inputs did not need to be replaced, hence no conflict. Report success.