Merge "Quick compiler:interpret on type mismatch"
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 84e1a94..89b1a75 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -957,6 +957,10 @@
CompiledMethod* result = NULL;
+ if (cu.mir_graph->PuntToInterpreter()) {
+ return NULL;
+ }
+
cu.cg->Materialize();
cu.NewTimingSplit("Dedupe"); /* deduping takes up the vast majority of time in GetCompiledMethod(). */
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index 2ec17de..1350665 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -1011,7 +1011,7 @@
}
// Contains a pattern we don't want to compile?
- if (punt_to_interpreter_) {
+ if (PuntToInterpreter()) {
return true;
}
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 27b8ca4..15c0aa4 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -958,6 +958,14 @@
bool SetHigh(int index, bool is_high);
bool SetHigh(int index);
+ bool PuntToInterpreter() {
+ return punt_to_interpreter_;
+ }
+
+ void SetPuntToInterpreter(bool val) {
+ punt_to_interpreter_ = val;
+ }
+
char* GetDalvikDisassembly(const MIR* mir);
void ReplaceSpecialChars(std::string& str);
std::string GetSSAName(int ssa_reg);
diff --git a/compiler/dex/vreg_analysis.cc b/compiler/dex/vreg_analysis.cc
index c4af9cb..db383c4 100644
--- a/compiler/dex/vreg_analysis.cc
+++ b/compiler/dex/vreg_analysis.cc
@@ -123,6 +123,16 @@
*/
bool MIRGraph::InferTypeAndSize(BasicBlock* bb, MIR* mir, bool changed) {
SSARepresentation *ssa_rep = mir->ssa_rep;
+
+ /*
+ * The dex bytecode definition does not explicitly outlaw the definition of the same
+ * virtual register to be used in both a 32-bit and 64-bit pair context. However, dx
+ * does not generate this pattern (at least recently). Further, in the next revision of
+ * dex, we will forbid this. To support the few cases in the wild, detect this pattern
+ * and punt to the interpreter.
+ */
+ bool type_mismatch = false;
+
if (ssa_rep) {
uint64_t attrs = GetDataFlowAttributes(mir);
const int* uses = ssa_rep->uses;
@@ -145,6 +155,7 @@
}
}
+
// Handles uses
int next = 0;
if (attrs & DF_UA) {
@@ -162,6 +173,7 @@
SRegToVReg(uses[next + 1]));
next += 2;
} else {
+ type_mismatch |= reg_location_[uses[next]].wide;
next++;
}
}
@@ -180,6 +192,7 @@
SRegToVReg(uses[next + 1]));
next += 2;
} else {
+ type_mismatch |= reg_location_[uses[next]].wide;
next++;
}
}
@@ -196,6 +209,8 @@
reg_location_[uses[next + 1]].high_word = true;
DCHECK_EQ(SRegToVReg(uses[next])+1,
SRegToVReg(uses[next + 1]));
+ } else {
+ type_mismatch |= reg_location_[uses[next]].wide;
}
}
@@ -205,6 +220,7 @@
(mir->dalvikInsn.opcode == Instruction::RETURN_OBJECT)) {
switch (cu_->shorty[0]) {
case 'I':
+ type_mismatch |= reg_location_[uses[0]].wide;
changed |= SetCore(uses[0]);
break;
case 'J':
@@ -215,6 +231,7 @@
reg_location_[uses[1]].high_word = true;
break;
case 'F':
+ type_mismatch |= reg_location_[uses[0]].wide;
changed |= SetFp(uses[0]);
break;
case 'D':
@@ -225,6 +242,7 @@
reg_location_[uses[1]].high_word = true;
break;
case 'L':
+ type_mismatch |= reg_location_[uses[0]].wide;
changed |= SetRef(uses[0]);
break;
default: break;
@@ -261,6 +279,7 @@
(mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC_RANGE))) {
reg_location_[uses[next]].defined = true;
reg_location_[uses[next]].ref = true;
+ type_mismatch |= reg_location_[uses[next]].wide;
next++;
}
uint32_t cpos = 1;
@@ -286,12 +305,15 @@
i++;
break;
case 'F':
+ type_mismatch |= reg_location_[uses[i]].wide;
ssa_rep->fp_use[i] = true;
break;
case 'L':
+ type_mismatch |= reg_location_[uses[i]].wide;
changed |= SetRef(uses[i]);
break;
default:
+ type_mismatch |= reg_location_[uses[i]].wide;
changed |= SetCore(uses[i]);
break;
}
@@ -367,6 +389,12 @@
}
}
}
+ if (type_mismatch) {
+ LOG(WARNING) << "Deprecated dex type mismatch, interpreting "
+ << PrettyMethod(cu_->method_idx, *cu_->dex_file);
+ LOG(INFO) << "@ 0x" << std::hex << mir->offset;
+ SetPuntToInterpreter(true);
+ }
return changed;
}