Add suspend check & stub

Change-Id: I017653026ca95166cbc4b6b94b5da1fef2597804
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h
index c702204..67ed6ee 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/Ralloc.h
@@ -171,6 +171,8 @@
 /* To be used when explicitly managing register use */
 extern void oatLockCallTemps(CompilationUnit* cUnit);
 
+extern void oatFreeCallTemps(CompilationUnit* cUnit);
+
 extern void oatFlushAllRegs(CompilationUnit* cUnit);
 
 extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit);
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index 5951ad4..1fe680f 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -712,6 +712,16 @@
     oatLockTemp(cUnit, r3);
 }
 
+/* To be used when explicitly managing register use */
+extern void oatFreeCallTemps(CompilationUnit* cUnit)
+{
+    //TODO: Arm specific - move to target dependent code
+    oatFreeTemp(cUnit, r0);
+    oatFreeTemp(cUnit, r1);
+    oatFreeTemp(cUnit, r2);
+    oatFreeTemp(cUnit, r3);
+}
+
 // Make sure nothing is live and dirty
 static void flushAllRegsBody(CompilationUnit* cUnit, RegisterInfo* info,
                              int numRegs)
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 4ae254b..ce1c9a7 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -377,9 +377,8 @@
  */
 static void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
 {
-#if 1
-  UNIMPLEMENTED(WARNING);
-#else
+#if 0
+    // TODO: re-enable when concurrent collector is active
     int regCardBase = oatAllocTemp(cUnit);
     int regCardNo = oatAllocTemp(cUnit);
     ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondEq, valReg, 0);
@@ -1708,22 +1707,22 @@
     return false;
 }
 
-/*
- * Fetch *self->info.breakFlags. If the breakFlags are non-zero,
- * punt to the interpreter.
- */
+/* Check for pending suspend request.  */
 static void genSuspendPoll(CompilationUnit* cUnit, MIR* mir)
 {
-    UNIMPLEMENTED(WARNING);
-#if 0
-    int rTemp = oatAllocTemp(cUnit);
+    oatLockCallTemps(cUnit);   // Explicit register usage
+    int rSuspendCount = r1;
     ArmLIR* ld;
-    ld = loadBaseDisp(cUnit, NULL, rSELF,
-                      offsetof(Thread, interpBreak.ctl.breakFlags),
-                      rTemp, kUnsignedByte, INVALID_SREG);
+    ld = loadWordDisp(cUnit, rSELF,
+        art::Thread::SuspendCountOffset().Int32Value(), rSuspendCount);
     setMemRefType(ld, true /* isLoad */, kMustNotAlias);
-    genRegImmCheck(cUnit, kArmCondNe, rTemp, 0, mir->offset, NULL);
-#endif
+    loadWordDisp(cUnit, rSELF,
+                 OFFSETOF_MEMBER(Thread, pCheckSuspendFromCode), rLR);
+    genRegCopy(cUnit, r0, rSELF);
+    opRegImm(cUnit, kOpCmp, rSuspendCount, 0);
+    genIT(cUnit, kArmCondNe, "");
+    opReg(cUnit, kOpBlx, rLR); // CheckSuspendFromCode(self)
+    oatFreeCallTemps(cUnit);
 }
 
 /*
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc
index b3d21a3..307a804 100644
--- a/src/mark_sweep.cc
+++ b/src/mark_sweep.cc
@@ -31,6 +31,8 @@
 
   // TODO: if concurrent, clear the card table.
 
+  // TODO: if concurrent, enable card marking in compiler
+
   // TODO: check that the mark bitmap is entirely clear.
 
   return true;
diff --git a/src/thread.cc b/src/thread.cc
index 98f7f78..6109825 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -127,6 +127,15 @@
     obj->MonitorEnter(thread);
 }
 
+// TODO: placeholder
+static void CheckSuspendFromCode(Thread* thread) {
+    /*
+     * Code is at a safe point, suspend if needed.
+     * Also, this is where a pending safepoint callback
+     * would be fired.
+     */
+}
+
 void Thread::InitFunctionPointers() {
 #if defined(__arm__)
   pShlLong = art_shl_long;
@@ -178,6 +187,7 @@
   pLockObjectFromCode = LockObjectFromCode;
   pUnlockObjectFromCode = UnlockObjectFromCode;
   pFindFieldFromCode = Field::FindFieldFromCode;
+  pCheckSuspendFromCode = CheckSuspendFromCode;
   pDebugMe = DebugMe;
 }
 
diff --git a/src/thread.h b/src/thread.h
index a5a6911..ba5d6ef 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -230,6 +230,7 @@
   void (*pInvokeInterfaceTrampoline)(void*, void*, void*, void*);
   StaticStorageBase* (*pInitializeStaticStorage)(uint32_t, const Method*);
   Field* (*pFindFieldFromCode)(uint32_t, const Method*);
+  void (*pCheckSuspendFromCode)(Thread*);
 
   class StackVisitor {
    public: