Try/Catch analysis; various workarounds

Fixed a couple of codegen bugs.  Added a temporary workaround until
SSA renaming problem is fixed.  By enabling the "CompileDexLibCore"
test in compiler_test.cc and disabling the jni_compiler, we appear to
be successfully compiling 17,641 methods of libcore (note: of those,
4 exhibit the SSA problem).

Also turned off most of the compiler logging, and disabled the fast
path for invoke virtual (which seems to be broken).

Change-Id: I0ecf460cba209f885209efbee62e9f80bffbf666
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index b5ce6ea..13e5497 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define FORCE_SLOW 1
+
 static const RegLocation badLoc = {kLocDalvikFrame, 0, 0, INVALID_REG,
                                    INVALID_REG, INVALID_SREG, 0,
                                    kLocDalvikFrame, INVALID_REG, INVALID_REG,
@@ -200,7 +202,7 @@
 {
     int fieldIdx = mir->dalvikInsn.vB;
     Field* field = cUnit->method->GetDexCacheResolvedFields()->Get(fieldIdx);
-    if (field == NULL) {
+    if (FORCE_SLOW || field == NULL) {
         oatFlushAllRegs(cUnit);
         loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pSet64Static), rLR);
         loadConstant(cUnit, r0, mir->dalvikInsn.vB);
@@ -256,7 +258,7 @@
 {
     int fieldIdx = mir->dalvikInsn.vB;
     Field* field = cUnit->method->GetDexCacheResolvedFields()->Get(fieldIdx);
-    if (field == NULL) {
+    if (FORCE_SLOW || field == NULL) {
         oatFlushAllRegs(cUnit);
         loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pGet64Static), rLR);
         loadConstant(cUnit, r0, mir->dalvikInsn.vB);
@@ -314,7 +316,7 @@
     Field* field = cUnit->method->GetDexCacheResolvedFields()->Get(fieldIdx);
     bool isObject = ((mir->dalvikInsn.opcode == OP_SGET_OBJECT) ||
                      (mir->dalvikInsn.opcode == OP_SGET_OBJECT_VOLATILE));
-    if (field == NULL) {
+    if (FORCE_SLOW || field == NULL) {
         // Slow path
         int funcOffset = isObject ? OFFSETOF_MEMBER(Thread, pGetObjStatic)
                                   : OFFSETOF_MEMBER(Thread, pGet32Static);
@@ -527,8 +529,8 @@
 {
     for (int i = 0; i < 3; i++) {
         if (args[i] != INVALID_REG) {
-            RegLocation rlArg = oatGetSrc(cUnit, mir, i);
             // Arguments are treated as a series of untyped 32-bit values.
+            RegLocation rlArg = oatGetRawSrc(cUnit, mir, i);
             rlArg.wide = false;
             loadValueDirectFixed(cUnit, rlArg, r1 + i);
             callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
@@ -709,6 +711,8 @@
     RegLocation rlArg;
     int registerArgs[3];
 
+skipThis = false;
+
     /* If no arguments, just return */
     if (dInsn->vA == 0)
         return callState;
@@ -722,8 +726,7 @@
      */
     for (unsigned int i=3; i < dInsn->vA; i++) {
         int reg;
-        int arg = (isRange) ? dInsn->vC + i : i;
-        rlArg = oatUpdateLoc(cUnit, oatGetSrc(cUnit, mir, arg));
+        rlArg = oatUpdateLoc(cUnit, oatGetSrc(cUnit, mir, i));
         if (rlArg.location == kLocPhysReg) {
             reg = rlArg.lowReg;
         } else {
@@ -736,12 +739,15 @@
     }
 
     /* Load register arguments r1..r3 */
-    for (unsigned int i = skipThis ? 1 : 0; i < 3; i++) {
+    for (unsigned int i = 0; i < 3; i++) {
         if (i < dInsn->vA)
             registerArgs[i] = (isRange) ? dInsn->vC + i : i;
         else
             registerArgs[i] = INVALID_REG;
     }
+    if (skipThis) {
+        registerArgs[0] = INVALID_REG;
+    }
     callState = loadArgRegs(cUnit, mir, dInsn, callState, registerArgs,
                             nextCallInsn, rollback);
 
@@ -775,6 +781,9 @@
 {
     int firstArg = dInsn->vC;
     int numArgs = dInsn->vA;
+    int registerArgs[3];
+
+skipThis = false;
 
     // If we can treat it as non-range (Jumbo ops will use range form)
     if (numArgs <= 5)
@@ -798,7 +807,7 @@
      */
     // Scan the rest of the args - if in physReg flush to memory
     for (int i = 4; i < numArgs; i++) {
-        RegLocation loc = oatGetSrc(cUnit, mir, i);
+        RegLocation loc = oatGetRawSrc(cUnit, mir, i);
         if (loc.wide) {
             loc = oatUpdateLocWide(cUnit, loc);
             if (loc.location == kLocPhysReg) {  // TUNING: if dirty?
@@ -840,11 +849,17 @@
     }
 
     // Handle the 1st 3 in r1, r2 & r3
-    for (unsigned int i = skipThis? 1 : 0; i < dInsn->vA && i < 3; i++) {
-        RegLocation loc = oatGetSrc(cUnit, mir, firstArg + i);
-        loadValueDirectFixed(cUnit, loc, r1 + i);
-        callState = nextCallInsn(cUnit, mir, dInsn, callState, rollback);
+    for (unsigned int i = 0; i < 3; i++) {
+       if (i < dInsn->vA)
+            registerArgs[i] = dInsn->vC + i;
+        else
+            registerArgs[i] = INVALID_REG;
     }
+    if (skipThis) {
+        registerArgs[0] = INVALID_REG;
+    }
+    callState = loadArgRegs(cUnit, mir, dInsn, callState, registerArgs,
+                            nextCallInsn, rollback);
 
     // Finally, deal with the register arguments
     // We'll be using fixed registers here
@@ -958,9 +973,7 @@
         Get(dInsn->vB);
     NextCallInsn nextCallInsn;
 
-    method = NULL; // TODO
-    UNIMPLEMENTED(WARNING) << "the genInvokeVirtual fast path generates bad code (r0/r9 mixup?)";
-    if (method == NULL) {
+    if (FORCE_SLOW || method == NULL) {
         // Slow path
         nextCallInsn = nextVCallInsnSP;
         // If we need a slow-path callout, we'll restart here