Workaround for Issue 7250540
There's a problem (originating with Dalvik's failure to properly type constants) with
Dalvik vregs that are used in both reference and floating point situations. In
particular, if a constant zero is used in a floating point context, the verifier in
some cases will treat it as a null pointer for the purposes generating the GC map.
If that vreg ends up promoted to a floating point value, the run-time value of that
vreg will not be found during garbage collection. As a quick workaround, this
CL causes the compiler to detect this special case of an immediate zero being loaded
into a promoted floating point register and also store a zero in the core/ref identity
of that vreg.
Note, the CL also excludes references from store elimination.
Change-Id: I72f0a96744823ff9c5a2bd961a5e39ac4bbc707b
diff --git a/src/compiler/codegen/codegen.h b/src/compiler/codegen/codegen.h
index 9dfa609..0698156 100644
--- a/src/compiler/codegen/codegen.h
+++ b/src/compiler/codegen/codegen.h
@@ -381,6 +381,9 @@
virtual void OpRegCopyWide(CompilationUnit* cu, int dest_lo, int dest_hi, int src_lo,
int src_hi) = 0;
virtual void OpTlsCmp(CompilationUnit* cu, int offset, int val) = 0;
+
+ // Temp workaround
+ void Workaround7250540(CompilationUnit* cu, RegLocation rl_dest, int value);
}; // Class Codegen
} // namespace art
diff --git a/src/compiler/codegen/gen_loadstore.cc b/src/compiler/codegen/gen_loadstore.cc
index 7d28e1b..11b4a62 100644
--- a/src/compiler/codegen/gen_loadstore.cc
+++ b/src/compiler/codegen/gen_loadstore.cc
@@ -35,6 +35,29 @@
return LoadConstantNoClobber(cu, r_dest, value);
}
+/*
+ * Temporary workaround for Issue 7250540. If we're loading a constant zero into a
+ * promoted floating point register, also copy a zero into the int/ref identity of
+ * that sreg.
+ */
+void Codegen::Workaround7250540(CompilationUnit* cu, RegLocation rl_dest, int value)
+{
+ if (rl_dest.fp && (value == 0)) {
+ int pmap_index = SRegToPMap(cu, rl_dest.s_reg_low);
+ if (cu->promotion_map[pmap_index].fp_location == kLocPhysReg) {
+ if (cu->promotion_map[pmap_index].core_location == kLocPhysReg) {
+ // Promoted - just copy in a zero
+ LoadConstant(cu, cu->promotion_map[pmap_index].core_reg, 0);
+ } else {
+ // Lives in the frame, need to store.
+ int temp_reg = AllocTemp(cu);
+ LoadConstant(cu, temp_reg, 0);
+ StoreBaseDisp(cu, TargetReg(kSp), SRegOffset(cu, rl_dest.s_reg_low), temp_reg, kWord);
+ }
+ }
+ }
+}
+
/* Load a word at base + displacement. Displacement must be word multiple */
LIR* Codegen::LoadWordDisp(CompilationUnit* cu, int rBase, int displacement, int r_dest)
{
@@ -172,7 +195,10 @@
rl_dest.low_reg, kWord);
MarkClean(cu, rl_dest);
def_end = cu->last_lir_insn;
- MarkDef(cu, rl_dest, def_start, def_end);
+ if (!rl_dest.ref) {
+ // Exclude references from store elimination
+ MarkDef(cu, rl_dest, def_start, def_end);
+ }
}
}
diff --git a/src/compiler/codegen/mir_to_gbc.cc b/src/compiler/codegen/mir_to_gbc.cc
index b5ad024..19b069c 100644
--- a/src/compiler/codegen/mir_to_gbc.cc
+++ b/src/compiler/codegen/mir_to_gbc.cc
@@ -2576,6 +2576,7 @@
} else {
cg->LoadConstantNoClobber(cu, rl_result.low_reg, immval & 0xffffffff);
cg->StoreValue(cu, rl_dest, rl_result);
+ cg->Workaround7250540(cu, rl_dest, immval & 0xffffffff);
}
}
diff --git a/src/compiler/codegen/mir_to_lir.cc b/src/compiler/codegen/mir_to_lir.cc
index 5a6a5fc..3dc6d59 100644
--- a/src/compiler/codegen/mir_to_lir.cc
+++ b/src/compiler/codegen/mir_to_lir.cc
@@ -141,12 +141,14 @@
rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB);
cg->StoreValue(cu, rl_dest, rl_result);
+ cg->Workaround7250540(cu, rl_dest, vB);
break;
case Instruction::CONST_HIGH16:
rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB << 16);
cg->StoreValue(cu, rl_dest, rl_result);
+ cg->Workaround7250540(cu, rl_dest, vB);
break;
case Instruction::CONST_WIDE_16:
diff --git a/src/compiler/codegen/ralloc_util.cc b/src/compiler/codegen/ralloc_util.cc
index 7cc3fad..999c652 100644
--- a/src/compiler/codegen/ralloc_util.cc
+++ b/src/compiler/codegen/ralloc_util.cc
@@ -146,7 +146,7 @@
* ssa name (above the last original Dalvik register). This function
* maps SSA names to positions in the promotion_map array.
*/
-static int SRegToPMap(CompilationUnit* cu, int s_reg)
+int SRegToPMap(CompilationUnit* cu, int s_reg)
{
DCHECK_LT(s_reg, cu->num_ssa_regs);
DCHECK_GE(s_reg, 0);
diff --git a/src/compiler/codegen/ralloc_util.h b/src/compiler/codegen/ralloc_util.h
index 78a623b..3526f4c 100644
--- a/src/compiler/codegen/ralloc_util.h
+++ b/src/compiler/codegen/ralloc_util.h
@@ -156,6 +156,7 @@
void RecordCorePromotion(CompilationUnit* cu, int reg, int s_reg);
void RecordFpPromotion(CompilationUnit* cu, int reg, int s_reg);
int ComputeFrameSize(CompilationUnit* cu);
+int SRegToPMap(CompilationUnit* cu, int s_reg);
} // namespace art
diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc
index b8c9b8e..cd07dde 100644
--- a/src/compiler/frontend.cc
+++ b/src/compiler/frontend.cc
@@ -835,28 +835,6 @@
}
#endif
-#if 1
-// *** Temporary ****
-// For use in debugging issue 7250540. Disable optimization in problem method
-// to see if monkey results change. Should be removed after monkey runs
-// complete.
-if (PrettyMethod(method_idx, dex_file).find("void com.android.inputmethod.keyboard.Key.<init>(android.content.res.Resources, com.android.inputmethod.keyboard.Keyboard$Params, com.android.inputmethod.keyboard.Keyboard$Builder$Row, org.xmlpull.v1.XmlPullParser)") != std::string::npos) {
- cu->disable_opt |= (
- (1 << kLoadStoreElimination) |
- (1 << kLoadHoisting) |
- (1 << kSuppressLoads) |
- //(1 << kNullCheckElimination) |
- //(1 << kPromoteRegs) |
- (1 << kTrackLiveTemps) |
- //(1 << kSkipLargeMethodOptimization) |
- //(1 << kSafeOptimizations) |
- (1 << kBBOpt) |
- (1 << kMatch) |
- //(1 << kPromoteCompilerTemps) |
- 0);
-}
-#endif
-
if (cu->instruction_set == kMips) {
// Disable some optimizations for mips for now
cu->disable_opt |= (