Shadow frame support for MIR->LLVM-IR conversion

Added basic shadow stack support.  Minimally tested.
[Removed some stray debugging LOGs]

Change-Id: Ia27f8383548a5ca8a6fe0aa6543310575c2523ac
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 2e43b01..e9a2656 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -405,6 +405,9 @@
       placeholderBB(NULL),
       entryBB(NULL),
       tempName(0),
+      requireShadowFrame(false),
+      numShadowFrameEntries(0),
+      shadowMap(NULL),
 #endif
 #ifndef NDEBUG
       liveSReg(0),
@@ -575,6 +578,9 @@
   SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
   SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
   SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
+  bool requireShadowFrame;
+  int numShadowFrameEntries;
+  int* shadowMap;
 #endif
 #ifndef NDEBUG
   /*
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index 27e7d26..4ada78c 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -32,6 +32,7 @@
 
 namespace art {
 extern const RegLocation badLoc;
+RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val);
 
 llvm::BasicBlock* getLLVMBlock(CompilationUnit* cUnit, int id)
 {
@@ -122,6 +123,16 @@
   llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
   return cUnit->irb->CreateCall(intr, src);
 }
+
+void emitPopShadowFrame(CompilationUnit* cUnit)
+{
+  llvm::Function* intr = cUnit->intrinsic_helper->GetIntrinsicFunction(
+      greenland::IntrinsicHelper::PopShadowFrame);
+  cUnit->irb->CreateCall(intr);
+}
+
+
+
 llvm::Value* emitCopy(CompilationUnit* cUnit, llvm::ArrayRef<llvm::Value*> src,
                       RegLocation loc)
 {
@@ -274,6 +285,26 @@
   defineValue(cUnit, res, rlDest.origSReg);
 }
 
+void setShadowFrameEntry(CompilationUnit* cUnit, llvm::Value* newVal)
+{
+  int index = -1;
+  DCHECK(newVal != NULL);
+  int vReg = SRegToVReg(cUnit, getLoc(cUnit, newVal).origSReg);
+  for (int i = 0; i < cUnit->numShadowFrameEntries; i++) {
+    if (cUnit->shadowMap[i] == vReg) {
+      index = i;
+      break;
+    }
+  }
+  DCHECK(index != -1) << "Corrupt shadowMap";
+  greenland::IntrinsicHelper::IntrinsicId id =
+      greenland::IntrinsicHelper::SetShadowFrameEntry;
+  llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+  llvm::Value* tableSlot = cUnit->irb->getInt32(index);
+  llvm::Value* args[] = { newVal, tableSlot };
+  cUnit->irb->CreateCall(func, args);
+}
+
 void convertArithOpLit(CompilationUnit* cUnit, OpKind op, RegLocation rlDest,
                        RegLocation rlSrc1, int32_t imm)
 {
@@ -296,6 +327,7 @@
   RegLocation rlDest = badLoc;
   RegLocation rlResult = badLoc;
   Instruction::Code opcode = mir->dalvikInsn.opcode;
+  bool objectDefinition = false;
 
   /* Prep Src and Dest locations */
   int nextSreg = 0;
@@ -332,6 +364,9 @@
       rlDest = oatGetDestWide(cUnit, mir, 0, 1);
     } else {
       rlDest = oatGetDest(cUnit, mir, 0);
+      if (rlDest.ref) {
+        objectDefinition = true;
+      }
     }
   }
 
@@ -403,6 +438,7 @@
         if (!cUnit->attrs & METHOD_IS_LEAF) {
           emitSuspendCheck(cUnit);
         }
+        emitPopShadowFrame(cUnit);
         cUnit->irb->CreateRet(getLLVMValue(cUnit, rlSrc[0].origSReg));
         bb->hasReturn = true;
       }
@@ -412,6 +448,7 @@
         if (!cUnit->attrs & METHOD_IS_LEAF) {
           emitSuspendCheck(cUnit);
         }
+        emitPopShadowFrame(cUnit);
         cUnit->irb->CreateRetVoid();
         bb->hasReturn = true;
       }
@@ -934,6 +971,10 @@
     default:
       res = true;
   }
+  if (objectDefinition) {
+    setShadowFrameEntry(cUnit, (llvm::Value*)
+                        cUnit->llvmValues.elemList[rlDest.origSReg]);
+  }
   return res;
 }
 
@@ -1040,7 +1081,32 @@
 
   if (bb->blockType == kEntryBlock) {
     setMethodInfo(cUnit);
-    //genEntrySequence(cUnit, bb);
+    bool *canBeRef = (bool*)  oatNew(cUnit, sizeof(bool) *
+                                     cUnit->numDalvikRegisters, true,
+                                     kAllocMisc);
+    for (int i = 0; i < cUnit->numSSARegs; i++) {
+      canBeRef[SRegToVReg(cUnit, i)] |= cUnit->regLocation[i].ref;
+    }
+    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
+      if (canBeRef[i]) {
+        cUnit->numShadowFrameEntries++;
+      }
+    }
+    if (cUnit->numShadowFrameEntries > 0) {
+      cUnit->shadowMap = (int*) oatNew(cUnit, sizeof(int) *
+                                       cUnit->numShadowFrameEntries, true,
+                                       kAllocMisc);
+      for (int i = 0, j = 0; i < cUnit->numDalvikRegisters; i++) {
+        if (canBeRef[i]) {
+          cUnit->shadowMap[j++] = i;
+        }
+      }
+      greenland::IntrinsicHelper::IntrinsicId id =
+              greenland::IntrinsicHelper::AllocaShadowFrame;
+      llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
+      llvm::Value* entries = cUnit->irb->getInt32(cUnit->numShadowFrameEntries);
+      cUnit->irb->CreateCall(func, entries);
+    }
   } else if (bb->blockType == kExitBlock) {
     /*
      * Because of the differences between how MIR/LIR and llvm handle exit
@@ -1244,6 +1310,7 @@
 
 RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
   RegLocation res;
+  DCHECK(val != NULL);
   SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
   if (it == cUnit->locMap.end()) {
     const char* valName = val->getName().str().c_str();
@@ -1528,6 +1595,10 @@
           greenland::IntrinsicHelper::IntrinsicId id =
               cUnit->intrinsic_helper->GetIntrinsicId(callee);
           switch (id) {
+            case greenland::IntrinsicHelper::AllocaShadowFrame:
+            case greenland::IntrinsicHelper::SetShadowFrameEntry:
+              // Ignore shadow frame stuff for quick compiler
+              break;
             case greenland::IntrinsicHelper::CopyInt:
             case greenland::IntrinsicHelper::CopyObj:
             case greenland::IntrinsicHelper::CopyFloat: