summaryrefslogtreecommitdiff
path: root/src/compiler/codegen/arm/MethodCodegenDriver.cc
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2011-10-25 12:39:20 -0700
committer buzbee <buzbee@google.com> 2011-10-25 12:39:20 -0700
commit8febc5828219a933d2b702f002030ac11e48480b (patch)
tree22fb15eda62a5a5a4c40bf9e2e52c4c2911a33f9 /src/compiler/codegen/arm/MethodCodegenDriver.cc
parent6b4ef025af12b158d117fc80fc79acf620f411a0 (diff)
Fixes for GoogleEarth & Streek.apk failed DCHECKS
A old version of dx had an unfortunate bug that caused it to reuse incoming argument storage of static methods, possibly with different types and sizes. The compiler needs precise type and size knowledge, and was asserting that this case could not happen. It can. Fixed for legacy support. Change-Id: I889983bb7f26a37ca64d4bae63d686c8ec0cfc62
Diffstat (limited to 'src/compiler/codegen/arm/MethodCodegenDriver.cc')
-rw-r--r--src/compiler/codegen/arm/MethodCodegenDriver.cc24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index f57094fd07..366a6d321d 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -1807,27 +1807,37 @@ STATIC void flushIns(CompilationUnit* cUnit)
int lastArgReg = r3;
int startVReg = cUnit->method->NumRegisters() -
cUnit->method->NumIns();
+ /*
+ * Arguments passed in registers should be flushed
+ * to their backing locations in the frame for now.
+ * Also, we need to do initial assignment for promoted
+ * arguments. NOTE: an older version of dx had an issue
+ * in which it would reuse static method argument registers.
+ * This could result in the same Dalvik virtual register
+ * being promoted to both core and fp regs. In those
+ * cases, copy argument to both. This will be uncommon
+ * enough that it isn't worth attempting to optimize.
+ */
for (int i = 0; i < cUnit->method->NumIns(); i++) {
PromotionMap vMap = cUnit->promotionMap[startVReg + i];
- // For arguments only, should have at most one promotion kind
- DCHECK(!((vMap.coreLocation == kLocPhysReg) &&
- (vMap.fpLocation == kLocPhysReg)));
if (i <= (lastArgReg - firstArgReg)) {
- // If arriving in register, copy or flush
+ // If arriving in register
if (vMap.coreLocation == kLocPhysReg) {
genRegCopy(cUnit, vMap.coreReg, firstArgReg + i);
- } else if (vMap.fpLocation == kLocPhysReg) {
+ }
+ if (vMap.fpLocation == kLocPhysReg) {
genRegCopy(cUnit, vMap.fpReg, firstArgReg + i);
}
// Also put a copy in memory in case we're partially promoted
storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
firstArgReg + i, kWord);
} else {
- // If arriving in frame, initialize promoted target regs
+ // If arriving in frame & promoted
if (vMap.coreLocation == kLocPhysReg) {
loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
vMap.coreReg);
- } else if (vMap.fpLocation == kLocPhysReg) {
+ }
+ if (vMap.fpLocation == kLocPhysReg) {
loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
vMap.fpReg);
}