Class cast, fill array and interface exception support.

This change uses the deliver exception mechanism to implement support
for a number of runtime exceptions. It also tidies up code in the
compiler and allocates a singular callee save method in the image.

Also adds a fix for JNI internal test where we weren't passing
Thread::Current() and that this value is now being used in generated code.

Change-Id: I57eefd9afe40e92fa3a7e737f1a2ed7e1094b5c1
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 76d8b45..8f83cbb 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -55,19 +55,7 @@
 }
 #endif
 
-/*
- * If a helper routine might need to unwind, let it know the top
- * of the managed stack.
- */
-static ArmLIR* callUnwindableHelper(CompilationUnit* cUnit, int reg)
-{
-    // Starting point for managed traceback if we throw
-    storeWordDisp(cUnit, rSELF,
-                  art::Thread::TopOfManagedStackOffset().Int32Value(), rSP);
-    return opReg(cUnit, kOpBlx, reg);
-}
-
-static ArmLIR* callNoUnwindHelper(CompilationUnit* cUnit, int reg)
+static ArmLIR* callRuntimeHelper(CompilationUnit* cUnit, int reg)
 {
     return opReg(cUnit, kOpBlx, reg);
 }
@@ -384,7 +372,7 @@
                  OFFSETOF_MEMBER(Thread, pHandleFillArrayDataFromCode), rLR);
     // Materialize a pointer to the fill data image
     newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
 }
 
@@ -437,7 +425,7 @@
     loadWordDisp(cUnit, rSELF,
                  OFFSETOF_MEMBER(Thread, pFindInstanceFieldFromCode), rLR);
     loadConstant(cUnit, r0, fieldIdx);
-    callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
+    callRuntimeHelper(cUnit, rLR);  // resolveTypeFromCode(idx, method)
     ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
 #ifndef EXERCISE_SLOWEST_FIELD_PATH
@@ -632,7 +620,7 @@
                      OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
         genRegCopy(cUnit, r1, mReg);
         loadConstant(cUnit, r0, mir->dalvikInsn.vB);
-        callUnwindableHelper(cUnit, rLR);
+        callRuntimeHelper(cUnit, rLR);
         oatClobberCallRegs(cUnit);
         RegLocation rlResult = oatGetReturn(cUnit);
         storeValue(cUnit, rlDest, rlResult);
@@ -674,7 +662,7 @@
                  OFFSETOF_MEMBER(Thread, pAllocObjectFromCode), rLR);
     loadCurrMethodDirect(cUnit, r1);              // arg1 <= Method*
     loadConstant(cUnit, r0, mir->dalvikInsn.vB);  // arg0 <- type_id
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     RegLocation rlResult = oatGetReturn(cUnit);
     storeValue(cUnit, rlDest, rlResult);
@@ -685,7 +673,7 @@
     loadWordDisp(cUnit, rSELF,
                  OFFSETOF_MEMBER(Thread, pDeliverException), rLR);
     loadValueDirectFixed(cUnit, rlSrc, r0);  // Get exception object
-    callNoUnwindHelper(cUnit, rLR);  // art_deliver_exception(exception);
+    callRuntimeHelper(cUnit, rLR);  // art_deliver_exception(exception);
 }
 
 static void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
@@ -709,7 +697,7 @@
         loadWordDisp(cUnit, rSELF,
                      OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
         loadConstant(cUnit, r0, mir->dalvikInsn.vC);
-        callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
+        callRuntimeHelper(cUnit, rLR);  // resolveTypeFromCode(idx, method)
         genRegCopy(cUnit, r2, r0); // Align usage with fast path
         // Rejoin code paths
         ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -731,7 +719,7 @@
     ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq);
     genRegCopy(cUnit, r0, r3);
     genRegCopy(cUnit, r1, r2);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     /* branch target here */
     ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -762,7 +750,7 @@
         loadWordDisp(cUnit, rSELF,
                      OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
         loadConstant(cUnit, r0, mir->dalvikInsn.vB);
-        callUnwindableHelper(cUnit, rLR); // resolveTypeFromCode(idx, method)
+        callRuntimeHelper(cUnit, rLR);  // resolveTypeFromCode(idx, method)
         genRegCopy(cUnit, r2, r0); // Align usage with fast path
         // Rejoin code paths
         ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -783,7 +771,7 @@
     ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); /* If equal, trivial yes */
     genRegCopy(cUnit, r0, r1);
     genRegCopy(cUnit, r1, r2);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     /* branch target here */
     ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -948,7 +936,7 @@
     loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pLockObjectFromCode),
                  rLR);
     genRegCopy(cUnit, r0, rSELF);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
 
     // Resume here
     target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -996,7 +984,7 @@
     loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode),
                  rLR);
     genRegCopy(cUnit, r0, rSELF);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
 
     // Resume here
     target = newLIR0(cUnit, kArmPseudoTargetLabel);
@@ -1084,7 +1072,7 @@
         rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
         loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
     }
-    callNoUnwindHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     if (tgtSize == 1) {
         RegLocation rlResult;
@@ -1139,7 +1127,7 @@
     loadWordDisp(cUnit, rSELF, funcOffset, rLR);
     loadValueDirectFixed(cUnit, rlSrc1, r0);
     loadValueDirectFixed(cUnit, rlSrc2, r1);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     rlResult = oatGetReturn(cUnit);
     storeValue(cUnit, rlDest, rlResult);
@@ -1185,7 +1173,7 @@
     loadWordDisp(cUnit, rSELF, funcOffset, rLR);
     loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
     loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     rlResult = oatGetReturnWide(cUnit);
     storeValueWide(cUnit, rlDest, rlResult);
@@ -1265,7 +1253,7 @@
                  OFFSETOF_MEMBER(Thread, pCanPutArrayElementFromCode), rLR);
     /* Get the array's clazz */
     loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), r1);
-    callUnwindableHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
 
     // Now, redo loadValues in case they didn't survive the call
@@ -1455,7 +1443,7 @@
     loadWordDisp(cUnit, rSELF, funcOffset, rLR);
     loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
     loadValueDirect(cUnit, rlShift, r2);
-    callNoUnwindHelper(cUnit, rLR);
+    callRuntimeHelper(cUnit, rLR);
     oatClobberCallRegs(cUnit);
     RegLocation rlResult = oatGetReturnWide(cUnit);
     storeValueWide(cUnit, rlDest, rlResult);
@@ -1550,7 +1538,7 @@
         loadWordDisp(cUnit, rSELF, funcOffset, rLR);
         loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
         loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-        callUnwindableHelper(cUnit, rLR);
+        callRuntimeHelper(cUnit, rLR);
         oatClobberCallRegs(cUnit);
         if (retReg == r0)
             rlResult = oatGetReturnWide(cUnit);
@@ -1672,7 +1660,7 @@
         if (checkZero) {
             genImmedCheck(cUnit, kArmCondEq, r1, 0, mir, kArmThrowDivZero);
         }
-        callUnwindableHelper(cUnit, rLR);
+        callRuntimeHelper(cUnit, rLR);
         oatClobberCallRegs(cUnit);
         if (retReg == r0)
             rlResult = oatGetReturn(cUnit);
@@ -1732,7 +1720,7 @@
     callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self)
 #else
     ArmLIR* branch = opCondBranch(cUnit, kArmCondEq);
-    callUnwindableHelper(cUnit, rLR); // CheckSuspendFromCode(self)
+    callRuntimeHelper(cUnit, rLR); // CheckSuspendFromCode(self)
     ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
     branch->generic.target = (LIR*)target;
@@ -1960,7 +1948,7 @@
             }
             loadWordDisp(cUnit, rSELF, funcOffset, rLR);
             loadConstant(cUnit, r1, lit);
-            callUnwindableHelper(cUnit, rLR);
+            callRuntimeHelper(cUnit, rLR);
             oatClobberCallRegs(cUnit);
             if (isDiv)
                 rlResult = oatGetReturn(cUnit);