Using gcmap instead of shadow frame.

Fix misuse of TBAAJRuntime & TBAARuntimeInfo. Now, the TBAAJRuntime is
only for runtime support function.

Update DexPC before lock object and suspend.

Change-Id: I40fa37f4863fe6e127328a8413285ee3c62e8505
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index 1c04dc8..32f9b51 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -21,11 +21,10 @@
 
 %JavaObject = type opaque
 
-%ShadowFrame = type { %ShadowFrame*        ; Previous frame
+%ShadowFrame = type { i32                  ; Number of VRegs
+                    , %ShadowFrame*        ; Previous frame
                     , %JavaObject*         ; Method object pointer
                     , i32                  ; Line number for stack backtrace
-                    , i32                  ; Number of references
-                    ; [0 x %JavaObject*]   ; References
                     ; [0 x i32]            ; VRegs
                     }
 
@@ -45,7 +44,7 @@
 declare void @art_test_suspend_from_code(%JavaObject*)
 
 declare %ShadowFrame* @art_push_shadow_frame_from_code(%JavaObject*, %ShadowFrame*,
-                                                       %JavaObject*, i16, i16)
+                                                       %JavaObject*, i32)
 declare void @art_pop_shadow_frame_from_code(%ShadowFrame*)
 
 
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index a27ea6e..3524cdd 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -78,75 +78,6 @@
 
 #include <string>
 
-namespace {
-
-// TODO: We may need something to manage these passes.
-// TODO: We need high-level IR to analysis and do this at the IRBuilder level.
-class AddSuspendCheckToLoopLatchPass : public llvm::LoopPass {
- public:
-  static char ID;
-
-  AddSuspendCheckToLoopLatchPass() : llvm::LoopPass(ID), irb_(NULL) {
-    LOG(FATAL) << "Unexpected instantiation of AddSuspendCheckToLoopLatchPass";
-    // NOTE: We have to declare this constructor for llvm::RegisterPass, but
-    // this constructor won't work because we have no information on
-    // IRBuilder.  Thus, we should place a LOG(FATAL) here.
-  }
-
-  AddSuspendCheckToLoopLatchPass(art::compiler_llvm::IRBuilder* irb)
-    : llvm::LoopPass(ID), irb_(irb) {
-  }
-
-  virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const {
-    AU.addRequired<llvm::LoopInfo>();
-    AU.addRequiredID(llvm::LoopSimplifyID);
-
-    AU.addPreserved<llvm::DominatorTree>();
-    AU.addPreserved<llvm::LoopInfo>();
-    AU.addPreservedID(llvm::LoopSimplifyID);
-    AU.addPreserved<llvm::ScalarEvolution>();
-    AU.addPreservedID(llvm::BreakCriticalEdgesID);
-  }
-
-  virtual bool runOnLoop(llvm::Loop *loop, llvm::LPPassManager &lpm) {
-    llvm::LoopInfo* loop_info = &getAnalysis<llvm::LoopInfo>();
-
-    CHECK_EQ(loop->getNumBackEdges(), 1U) << "Loop must be simplified!";
-    llvm::BasicBlock* bb = loop->getLoopLatch();
-    CHECK_NE(bb, static_cast<void*>(NULL)) << "A single loop latch must exist.";
-
-    llvm::BasicBlock* tb = bb->splitBasicBlock(bb->getTerminator(), "suspend_exit");
-    // Remove unconditional branch which is added by splitBasicBlock.
-    bb->getTerminator()->eraseFromParent();
-
-    irb_->SetInsertPoint(bb);
-    irb_->Runtime().EmitTestSuspend();
-    irb_->CreateBr(tb);
-
-    loop->addBasicBlockToLoop(tb, loop_info->getBase());
-    // EmitTestSuspend() creates some basic blocks. We should add them to using
-    // addBasicBlockToLoop(...) as above.
-    for (llvm::succ_iterator succ_iter = llvm::succ_begin(bb), succ_end = llvm::succ_end(bb);
-         succ_iter != succ_end;
-         succ_iter++) {
-      loop->addBasicBlockToLoop(*succ_iter, loop_info->getBase());
-    }
-
-    return true;
-  }
-
- private:
-  art::compiler_llvm::IRBuilder* irb_;
-};
-
-char AddSuspendCheckToLoopLatchPass::ID = 0;
-
-llvm::RegisterPass<AddSuspendCheckToLoopLatchPass> reg_add_suspend_check_to_loop_latch_pass_(
-  "add-suspend-check-to-loop-latch", "Add suspend check to loop latch pass", false, false);
-
-
-} // end anonymous namespace
-
 namespace art {
 namespace compiler_llvm {
 
@@ -328,30 +259,22 @@
   if (bitcode_filename_.empty()) {
     // If we don't need write the bitcode to file, add the AddSuspendCheckToLoopLatchPass to the
     // regular FunctionPass.
-#if defined(ART_USE_DEXLANG_FRONTEND)
-    fpm.add(CreateGBCExpanderPass(dex_lang_ctx_->GetIntrinsicHelper(), *irb_.get()));
-#elif defined(ART_USE_PORTABLE_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
     fpm.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
                                   compiler_, oat_compilation_unit_));
 #endif
-    fpm.add(new ::AddSuspendCheckToLoopLatchPass(irb_.get()));
   } else {
-    // Run AddSuspendCheckToLoopLatchPass before we write the bitcode to file.
+#if defined(ART_USE_PORTABLE_COMPILER)
     llvm::FunctionPassManager fpm2(module_);
-#if defined(ART_USE_DEXLANG_FRONTEND)
-    fpm2.add(CreateGBCExpanderPass(dex_lang_ctx_->GetIntrinsicHelper(), *irb_.get()));
-#elif defined(ART_USE_PORTABLE_COMPILER)
     fpm2.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
                                    compiler_, oat_compilation_unit_));
-#endif
-    fpm2.add(new ::AddSuspendCheckToLoopLatchPass(irb_.get()));
     fpm2.doInitialization();
     for (llvm::Module::iterator F = module_->begin(), E = module_->end();
          F != E; ++F) {
       fpm2.run(*F);
     }
     fpm2.doFinalization();
-
+#endif
 
     // Write bitcode to file
     std::string errmsg;
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 3ec5e68..7843407 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -31,6 +31,7 @@
 #include "stl_util.h"
 #include "stub_compiler.h"
 #include "utils_llvm.h"
+#include "verifier/method_verifier.h"
 
 #include <llvm/LinkAllPasses.h>
 #include <llvm/LinkAllVMCore.h>
@@ -180,8 +181,10 @@
 
     cunit->Materialize();
 
-    return new CompiledMethod(cunit->GetInstructionSet(),
-                              cunit->GetCompiledCode());
+    Compiler::MethodReference mref(dex_file_, method_idx_);
+    return new CompiledMethod(cunit_->GetInstructionSet(),
+                              cunit_->GetCompiledCode(),
+                              *verifier::MethodVerifier::GetDexGcMap(mref));
   }
 #else
   UniquePtr<MethodCompiler> method_compiler(
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index 57a13d5..93d7d48 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -217,9 +217,7 @@
 
   llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty);
 
-  void Expand_AllocaShadowFrame(llvm::Value* num_entry_value, llvm::Value* num_vregs_value);
-
-  void Expand_SetShadowFrameEntry(llvm::Value* obj, llvm::Value* entry_idx);
+  void Expand_AllocaShadowFrame(llvm::Value* num_vregs_value);
 
   void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj);
 
@@ -710,7 +708,7 @@
   llvm::Value* callee_method_object_field_addr =
     EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx);
 
-  return irb_.CreateLoad(callee_method_object_field_addr, kTBAAJRuntime);
+  return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo);
 }
 
 llvm::Value* GBCExpanderPass::
@@ -765,7 +763,27 @@
 }
 
 void GBCExpanderPass::Expand_TestSuspend(llvm::CallInst& call_inst) {
+  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
+
+  llvm::Value* suspend_count =
+      irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(),
+                                              irb_.getInt16Ty(),
+                                              kTBAARuntimeInfo);
+  llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0));
+
+  llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend");
+  llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont");
+
+  irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely);
+
+  irb_.SetInsertPoint(basic_block_suspend);
+  if (dex_pc != art::DexFile::kDexNoIndex) {
+    EmitUpdateDexPC(dex_pc);
+  }
   irb_.Runtime().EmitTestSuspend();
+  irb_.CreateBr(basic_block_cont);
+
+  irb_.SetInsertPoint(basic_block_cont);
   return;
 }
 
@@ -781,7 +799,7 @@
 
   llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
 
-  return irb_.CreateLoad(string_field_addr, kTBAAJRuntime);
+  return irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
 }
 
 llvm::Value*
@@ -792,7 +810,7 @@
   llvm::Value* type_field_addr =
     EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
 
-  return irb_.CreateLoad(type_field_addr, kTBAAJRuntime);
+  return irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
 }
 
 void GBCExpanderPass::Expand_LockObject(llvm::Value* obj) {
@@ -980,7 +998,7 @@
   llvm::Value* storage_field_addr =
     EmitLoadDexCacheStaticStorageFieldAddr(type_idx);
 
-  return irb_.CreateLoad(storage_field_addr, kTBAAJRuntime);
+  return irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
 }
 
 llvm::Value*
@@ -1021,7 +1039,7 @@
     irb_.LoadFromObjectOffset(callee_method_object_addr,
                               art::AbstractMethod::GetCodeOffset().Int32Value(),
                               callee_method_type->getPointerTo(),
-                              kTBAAJRuntime);
+                              kTBAARuntimeInfo);
 
   // Invoke callee
   llvm::Value* retval = irb_.CreateCall(code_addr, args);
@@ -1093,17 +1111,14 @@
   return result;
 }
 
-void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_entry_value,
-                                               llvm::Value* num_vregs_value) {
+void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_vregs_value) {
   // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and
   // MethodCompiler::EmitPushShadowFrame
-  uint16_t num_shadow_frame_refs =
-    llvm::cast<llvm::ConstantInt>(num_entry_value)->getZExtValue();
   uint16_t num_vregs =
     llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue();
 
   llvm::StructType* shadow_frame_type =
-    irb_.getShadowFrameTy(num_shadow_frame_refs, num_vregs);
+    irb_.getShadowFrameTy(num_vregs);
 
   shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
 
@@ -1111,26 +1126,14 @@
   old_shadow_frame_ =
     irb_.CreateAlloca(shadow_frame_type->getElementType(0)->getPointerTo());
 
-  // Zero-initialization of the shadow frame table
-  llvm::Value* shadow_frame_table =
-    irb_.CreateConstGEP2_32(shadow_frame_, 0, 1);
-  llvm::Type* table_type = shadow_frame_type->getElementType(1);
-
-  llvm::ConstantAggregateZero* zero_initializer =
-    llvm::ConstantAggregateZero::get(table_type);
-
-  irb_.CreateStore(zero_initializer, shadow_frame_table, kTBAAShadowFrame);
-
   // Push the shadow frame
   llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
 
-  // Push the shadow frame
   llvm::Value* shadow_frame_upcast =
     irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
 
   llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast,
                                                  method_object_addr,
-                                                 num_shadow_frame_refs,
                                                  num_vregs);
 
   irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
@@ -1138,34 +1141,13 @@
   return;
 }
 
-// TODO: We will remove ShadowFrameEntry later, so I just copy/paste from ShadowFrameEntry.
-void GBCExpanderPass::Expand_SetShadowFrameEntry(llvm::Value* obj,
-                                                 llvm::Value* entry_idx) {
-  DCHECK(shadow_frame_ != NULL);
-
-  llvm::Value* gep_index[] = {
-    irb_.getInt32(0), // No pointer displacement
-    irb_.getInt32(1), // SIRT
-    entry_idx // Pointer field
-  };
-
-  llvm::Value* entry_addr = irb_.CreateGEP(shadow_frame_, gep_index);
-#if defined(ART_USE_PORTABLE_COMPILER)
-  if (obj->getType() != irb_.getJObjectTy()) {
-    obj = irb_.getJNull();
-  }
-#endif
-  irb_.CreateStore(obj, entry_addr, kTBAAShadowFrame);
-  return;
-}
-
 void GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx,
                                      llvm::Value* value) {
   DCHECK(shadow_frame_ != NULL);
 
   llvm::Value* gep_index[] = {
     irb_.getInt32(0), // No pointer displacement
-    irb_.getInt32(2), // VRegs
+    irb_.getInt32(1), // VRegs
     entry_idx // Pointer field
   };
 
@@ -1560,7 +1542,7 @@
     llvm::Value* type_field_addr =
       EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
 
-    llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAAJRuntime);
+    llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
 
     if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
       return type_object_addr;
@@ -1625,7 +1607,7 @@
   llvm::Value* storage_field_addr =
     EmitLoadDexCacheStaticStorageFieldAddr(type_idx);
 
-  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAAJRuntime);
+  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
 
   llvm::BasicBlock* block_original = irb_.GetInsertBlock();
 
@@ -1832,7 +1814,7 @@
 
   llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
 
-  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAAJRuntime);
+  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
 
   if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
     llvm::BasicBlock* block_str_exist =
@@ -1905,6 +1887,8 @@
     EmitGuard_NullPointerException(dex_pc, object_addr);
   }
 
+  EmitUpdateDexPC(dex_pc);
+
   irb_.Runtime().EmitLockObject(object_addr);
 
   return;
@@ -2177,7 +2161,7 @@
       irb_.LoadFromObjectOffset(callee_method_object_addr,
                                 art::AbstractMethod::GetCodeOffset().Int32Value(),
                                 GetFunctionType(callee_method_idx, is_static)->getPointerTo(),
-                                kTBAAJRuntime);
+                                kTBAARuntimeInfo);
   }
 
   // Invoke callee
@@ -2700,7 +2684,7 @@
       return irb_.Runtime().EmitGetCurrentThread();
     }
     case IntrinsicHelper::CheckSuspend: {
-      // We will add suspend by ourselves.
+      Expand_TestSuspend(call_inst);
       return NULL;
     }
     case IntrinsicHelper::TestSuspend: {
@@ -3478,13 +3462,7 @@
 
     //==- Shadow Frame -----------------------------------------------------==//
     case IntrinsicHelper::AllocaShadowFrame: {
-      Expand_AllocaShadowFrame(call_inst.getArgOperand(0),
-                               call_inst.getArgOperand(1));
-      return NULL;
-    }
-    case IntrinsicHelper::SetShadowFrameEntry: {
-      Expand_SetShadowFrameEntry(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1));
+      Expand_AllocaShadowFrame(call_inst.getArgOperand(0));
       return NULL;
     }
     case IntrinsicHelper::SetVReg: {
diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc
index e118646..ef8d6da 100644
--- a/src/compiler_llvm/generated/art_module.cc
+++ b/src/compiler_llvm/generated/art_module.cc
@@ -44,12 +44,12 @@
 StructTy_ShadowFrame = StructType::create(mod->getContext(), "ShadowFrame");
 }
 std::vector<Type*>StructTy_ShadowFrame_fields;
+StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
 PointerType* PointerTy_2 = PointerType::get(StructTy_ShadowFrame, 0);
 
 StructTy_ShadowFrame_fields.push_back(PointerTy_2);
 StructTy_ShadowFrame_fields.push_back(PointerTy_1);
 StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
-StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
 if (StructTy_ShadowFrame->isOpaque()) {
 StructTy_ShadowFrame->setBody(StructTy_ShadowFrame_fields, /*isPacked=*/false);
 }
@@ -93,8 +93,7 @@
 FuncTy_7_args.push_back(PointerTy_1);
 FuncTy_7_args.push_back(PointerTy_2);
 FuncTy_7_args.push_back(PointerTy_1);
-FuncTy_7_args.push_back(IntegerType::get(mod->getContext(), 16));
-FuncTy_7_args.push_back(IntegerType::get(mod->getContext(), 16));
+FuncTy_7_args.push_back(IntegerType::get(mod->getContext(), 32));
 FunctionType* FuncTy_7 = FunctionType::get(
  /*Result=*/PointerTy_2,
  /*Params=*/FuncTy_7_args,
diff --git a/src/compiler_llvm/ir_builder.cc b/src/compiler_llvm/ir_builder.cc
index b271002..e8e73e3 100644
--- a/src/compiler_llvm/ir_builder.cc
+++ b/src/compiler_llvm/ir_builder.cc
@@ -151,8 +151,8 @@
 }
 
 
-llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size, uint32_t vreg_size) {
-  std::string name(StringPrintf("ShadowFrame%u_vreg%u", sirt_size, vreg_size));
+llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t vreg_size) {
+  std::string name(StringPrintf("ShadowFrame%u", vreg_size));
 
   // Try to find the existing struct type definition
   if (llvm::Type* type = module_->getTypeByName(name)) {
@@ -163,7 +163,6 @@
   // Create new struct type definition
   llvm::Type* elem_types[] = {
     art_frame_type_,
-    llvm::ArrayType::get(jobject_type_, sirt_size),
     llvm::ArrayType::get(getInt32Ty(), vreg_size),
   };
 
diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h
index cc0bc8e..4a58515 100644
--- a/src/compiler_llvm/ir_builder.h
+++ b/src/compiler_llvm/ir_builder.h
@@ -315,7 +315,7 @@
     return getJLongTy();
   }
 
-  llvm::StructType* getShadowFrameTy(uint32_t sirt_size, uint32_t vreg_size);
+  llvm::StructType* getShadowFrameTy(uint32_t vreg_size);
 
 
   //--------------------------------------------------------------------------
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index d5a7869..2a17320 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -101,7 +101,7 @@
   }
 
   // Shadow stack
-  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size, 0);
+  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size);
   llvm::AllocaInst* shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
 
   // Store the dex pc
@@ -113,20 +113,20 @@
   // Push the shadow frame
   llvm::Value* shadow_frame_upcast = irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
   llvm::Value* old_shadow_frame =
-      irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, sirt_size, 0);
+      irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, sirt_size);
 
   // Get JNIEnv
   llvm::Value* jni_env_object_addr =
       irb_.Runtime().EmitLoadFromThreadOffset(Thread::JniEnvOffset().Int32Value(),
                                               irb_.getJObjectTy(),
-                                              kTBAAJRuntime);
+                                              kTBAARuntimeInfo);
 
   // Get callee code_addr
   llvm::Value* code_addr =
       irb_.LoadFromObjectOffset(method_object_addr,
                                 AbstractMethod::NativeMethodOffset().Int32Value(),
                                 GetFunctionType(method_idx_, is_static, true)->getPointerTo(),
-                                kTBAAJRuntime);
+                                kTBAARuntimeInfo);
 
   // Load actual parameters
   std::vector<llvm::Value*> args;
@@ -145,7 +145,8 @@
 
   // Store the "this object or class object" to SIRT
   gep_index[2] = irb_.getInt32(sirt_member_index++);
-  llvm::Value* sirt_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
+  llvm::Value* sirt_field_addr = irb_.CreateBitCast(irb_.CreateGEP(shadow_frame_, gep_index),
+                                                    irb_.getJObjectTy()->getPointerTo());
   irb_.CreateStore(this_object_or_class_object, sirt_field_addr, kTBAAShadowFrame);
   // Push the "this object or class object" to out args
   this_object_or_class_object = irb_.CreateBitCast(sirt_field_addr, irb_.getJObjectTy());
@@ -155,7 +156,8 @@
     if (arg_iter->getType() == irb_.getJObjectTy()) {
       // Store the reference type arguments to SIRT
       gep_index[2] = irb_.getInt32(sirt_member_index++);
-      llvm::Value* sirt_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
+      llvm::Value* sirt_field_addr = irb_.CreateBitCast(irb_.CreateGEP(shadow_frame_, gep_index),
+                                                        irb_.getJObjectTy()->getPointerTo());
       irb_.CreateStore(arg_iter, sirt_field_addr, kTBAAShadowFrame);
       // Note null is placed in the SIRT but the jobject passed to the native code must be null
       // (not a pointer into the SIRT as with regular references).
diff --git a/src/compiler_llvm/md_builder.cc b/src/compiler_llvm/md_builder.cc
index f5232aa..038e133 100644
--- a/src/compiler_llvm/md_builder.cc
+++ b/src/compiler_llvm/md_builder.cc
@@ -39,8 +39,10 @@
     case kTBAAHeapInstance: spec_ty = createTBAANode("HeapInstance", tbaa_root_); break;
     case kTBAAHeapStatic:   spec_ty = createTBAANode("HeapStatic", tbaa_root_); break;
     case kTBAAJRuntime:     spec_ty = createTBAANode("JRuntime", tbaa_root_); break;
-    case kTBAARuntimeInfo:  spec_ty = createTBAANode("RuntimeInfo", tbaa_root_); break;
-    case kTBAAShadowFrame:  spec_ty = createTBAANode("ShadowFrame", tbaa_root_); break;
+    case kTBAARuntimeInfo:  spec_ty = createTBAANode("RuntimeInfo",
+                                                     GetTBAASpecialType(kTBAAJRuntime)); break;
+    case kTBAAShadowFrame:  spec_ty = createTBAANode("ShadowFrame",
+                                                     GetTBAASpecialType(kTBAAJRuntime)); break;
     case kTBAAConstJObject: spec_ty = createTBAANode("ConstJObject", tbaa_root_, true); break;
     default:
       LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index f09553c..68121de 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -60,8 +60,6 @@
     irb_(*cunit->GetIRBuilder()),
     func_(NULL),
     regs_(code_item_->registers_size_),
-    shadow_frame_entries_(code_item_->registers_size_),
-    reg_to_shadow_frame_index_(code_item_->registers_size_, -1),
     retval_reg_(NULL),
     basic_block_alloca_(NULL), basic_block_shadow_frame_(NULL),
     basic_block_reg_arg_init_(NULL),
@@ -69,7 +67,7 @@
     basic_block_landing_pads_(code_item_->tries_size_, NULL),
     basic_block_unwind_(NULL),
     shadow_frame_(NULL), old_shadow_frame_(NULL),
-    already_pushed_shadow_frame_(NULL), num_shadow_frame_refs_(0) {
+    already_pushed_shadow_frame_(NULL) {
 }
 
 
@@ -176,9 +174,6 @@
     name = StringPrintf("%u", r);
 #endif
     regs_[r] = new DalvikReg(*this, name, GetVRegEntry(r));
-
-    // Cache shadow frame entry address
-    shadow_frame_entries_[r] = GetShadowFrameEntry(r);
   }
 
   std::string name;
@@ -256,7 +251,9 @@
     EmitStackOverflowCheck();
   }
   // Garbage collection safe-point
-  EmitGuard_GarbageCollectionSuspend();
+  if (method_info_.has_invoke) {
+    EmitGuard_GarbageCollectionSuspend(DexFile::kDexNoIndex);
+  }
   irb_.CreateBr(basic_block_shadow_frame_);
 
   irb_.SetInsertPoint(basic_block_shadow_frame_);
@@ -268,24 +265,7 @@
   irb_.SetInsertPoint(basic_block_alloca_);
 
   // Allocate the shadow frame now!
-  num_shadow_frame_refs_ = 0;
-  uint16_t arg_reg_start = code_item_->registers_size_ - code_item_->ins_size_;
-  if (method_info_.need_shadow_frame_entry) {
-    for (uint32_t i = 0, num_of_regs = code_item_->registers_size_; i < num_of_regs; ++i) {
-      if (i >= arg_reg_start && !method_info_.set_to_another_object[i]) {
-        // If we don't set argument registers to another object, we don't need the shadow frame
-        // entry for it. Because the arguments must have been in the caller's shadow frame.
-        continue;
-      }
-
-      if (IsRegCanBeObject(i)) {
-        reg_to_shadow_frame_index_[i] = num_shadow_frame_refs_++;
-      }
-    }
-  }
-
-  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(num_shadow_frame_refs_,
-                                                              code_item_->registers_size_);
+  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(code_item_->registers_size_);
   shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
 
   // Alloca a pointer to old shadow frame
@@ -293,15 +273,6 @@
 
   irb_.SetInsertPoint(basic_block_shadow_frame_);
 
-  // Zero-initialization of the shadow frame table
-  llvm::Value* shadow_frame_table = irb_.CreateConstGEP2_32(shadow_frame_, 0, 1);
-  llvm::Type* table_type = shadow_frame_type->getElementType(1);
-
-  llvm::ConstantAggregateZero* zero_initializer =
-    llvm::ConstantAggregateZero::get(table_type);
-
-  irb_.CreateStore(zero_initializer, shadow_frame_table, kTBAAShadowFrame);
-
   // Lazy pushing shadow frame
   if (method_info_.lazy_push_shadow_frame) {
     irb_.SetInsertPoint(basic_block_alloca_);
@@ -1375,7 +1346,7 @@
 
   llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
 
-  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAAJRuntime);
+  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
 
   if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
     llvm::BasicBlock* block_str_exist =
@@ -1444,7 +1415,7 @@
     llvm::Value* type_field_addr =
       EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
 
-    llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAAJRuntime);
+    llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
 
     if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
       return type_object_addr;
@@ -1523,6 +1494,8 @@
     EmitGuard_NullPointerException(dex_pc, object_addr);
   }
 
+  EmitUpdateDexPC(dex_pc);
+
   irb_.Runtime().EmitLockObject(object_addr);
 
   irb_.CreateBr(GetNextBasicBlock(dex_pc));
@@ -1914,6 +1887,11 @@
 
   int32_t branch_offset = dec_insn.vA;
 
+  if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
+    // Garbage collection safe-point on backward branch
+    EmitGuard_GarbageCollectionSuspend(dex_pc);
+  }
+
   irb_.CreateBr(GetBasicBlock(dex_pc + branch_offset));
 }
 
@@ -2044,6 +2022,11 @@
 
   int32_t branch_offset = dec_insn.vC;
 
+  if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
+    // Garbage collection safe-point on backward branch
+    EmitGuard_GarbageCollectionSuspend(dex_pc);
+  }
+
   llvm::Value* src1_value;
   llvm::Value* src2_value;
 
@@ -2105,6 +2088,11 @@
 
   int32_t branch_offset = dec_insn.vB;
 
+  if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
+    // Garbage collection safe-point on backward branch
+    EmitGuard_GarbageCollectionSuspend(dex_pc);
+  }
+
   llvm::Value* src1_value;
   llvm::Value* src2_value;
 
@@ -2145,12 +2133,6 @@
   return map->GetRegCategory(dex_pc, reg_idx);
 }
 
-bool MethodCompiler::IsRegCanBeObject(uint16_t reg_idx) {
-  const greenland::InferredRegCategoryMap* map = GetInferredRegCategoryMap();
-
-  return map->IsRegCanBeObject(reg_idx);
-}
-
 
 llvm::Value* MethodCompiler::EmitConditionResult(llvm::Value* lhs,
                                                  llvm::Value* rhs,
@@ -2442,7 +2424,7 @@
   llvm::Value* storage_field_addr =
     EmitLoadDexCacheStaticStorageFieldAddr(type_idx);
 
-  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAAJRuntime);
+  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
 
   llvm::BasicBlock* block_original = irb_.GetInsertBlock();
 
@@ -2809,7 +2791,7 @@
       irb_.LoadFromObjectOffset(callee_method_object_addr,
                                 AbstractMethod::GetCodeOffset().Int32Value(),
                                 GetFunctionType(callee_method_idx, is_static)->getPointerTo(),
-                                kTBAAJRuntime);
+                                kTBAARuntimeInfo);
   }
 
   // Invoke callee
@@ -2835,7 +2817,7 @@
   llvm::Value* callee_method_object_field_addr =
     EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx);
 
-  return irb_.CreateLoad(callee_method_object_field_addr, kTBAAJRuntime);
+  return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo);
 }
 
 
@@ -3529,8 +3511,10 @@
 
   cunit_->Materialize();
 
+  Compiler::MethodReference mref(dex_file_, method_idx_);
   return new CompiledMethod(cunit_->GetInstructionSet(),
-                            cunit_->GetCompiledCode());
+                            cunit_->GetCompiledCode(),
+                            *verifier::MethodVerifier::GetDexGcMap(mref));
 }
 
 
@@ -3570,13 +3554,26 @@
 }
 
 
-void MethodCompiler::EmitGuard_GarbageCollectionSuspend() {
-  // Loop suspend will be added by our llvm pass.
-  if (!method_info_.has_invoke) {
-    return;
-  }
+void MethodCompiler::EmitGuard_GarbageCollectionSuspend(uint32_t dex_pc) {
+  llvm::Value* suspend_count =
+      irb_.Runtime().EmitLoadFromThreadOffset(Thread::ThreadFlagsOffset().Int32Value(),
+                                              irb_.getInt16Ty(),
+                                              kTBAARuntimeInfo);
+  llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0));
 
+  llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend");
+  llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont");
+
+  irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely);
+
+  irb_.SetInsertPoint(basic_block_suspend);
+  if (dex_pc != DexFile::kDexNoIndex) {
+    EmitUpdateDexPC(dex_pc);
+  }
   irb_.Runtime().EmitTestSuspend();
+  irb_.CreateBr(basic_block_cont);
+
+  irb_.SetInsertPoint(basic_block_cont);
 }
 
 
@@ -3766,49 +3763,7 @@
 }
 
 
-llvm::Value* MethodCompiler::GetShadowFrameEntry(uint32_t reg_idx) {
-  if (reg_to_shadow_frame_index_[reg_idx] == -1) {
-    // This register dosen't need ShadowFrame entry
-    return NULL;
-  }
-
-  if (!method_info_.need_shadow_frame_entry) {
-    return NULL;
-  }
-
-  std::string reg_name;
-
-#if !defined(NDEBUG)
-  StringAppendF(&reg_name, "s%u", reg_idx);
-#endif
-
-  // Save current IR builder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-
-  irb_.SetInsertPoint(basic_block_shadow_frame_);
-
-  llvm::Value* gep_index[] = {
-    irb_.getInt32(0), // No pointer displacement
-    irb_.getInt32(1), // SIRT
-    irb_.getInt32(reg_to_shadow_frame_index_[reg_idx]) // Pointer field
-  };
-
-  llvm::Value* reg_addr = irb_.CreateGEP(shadow_frame_, gep_index, reg_name);
-
-  // Restore IRBuilder insert point
-  irb_.restoreIP(irb_ip_original);
-
-  DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
-  return reg_addr;
-}
-
-
-// TODO: We will remove ShadowFrameEntry later, so I just copy/paste from ShadowFrameEntry.
 llvm::Value* MethodCompiler::GetVRegEntry(uint32_t reg_idx) {
-  if (!compiler_->IsDebuggingSupported()) {
-    return NULL;
-  }
-
   if (!method_info_.need_shadow_frame_entry) {
     return NULL;
   }
@@ -3826,7 +3781,7 @@
 
   llvm::Value* gep_index[] = {
     irb_.getInt32(0), // No pointer displacement
-    irb_.getInt32(2), // VRegs
+    irb_.getInt32(1), // VRegs
     irb_.getInt32(reg_idx) // Pointer field
   };
 
@@ -3857,12 +3812,9 @@
   llvm::Value* result;
   if (is_inline) {
     result = irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr,
-                                                num_shadow_frame_refs_,
                                                 code_item_->registers_size_);
   } else {
-    DCHECK(num_shadow_frame_refs_ == 0);
     result = irb_.Runtime().EmitPushShadowFrameNoInline(shadow_frame_upcast, method_object_addr,
-                                                        num_shadow_frame_refs_,
                                                         code_item_->registers_size_);
   }
   irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
@@ -3932,9 +3884,6 @@
 void MethodCompiler::EmitStoreDalvikReg(uint32_t reg_idx, JType jty,
                                         JTypeSpace space, llvm::Value* new_value) {
   regs_[reg_idx]->SetValue(jty, space, new_value);
-  if (jty == kObject && shadow_frame_entries_[reg_idx] != NULL) {
-    irb_.CreateStore(new_value, shadow_frame_entries_[reg_idx], kTBAAShadowFrame);
-  }
 }
 
 void MethodCompiler::EmitStoreDalvikReg(uint32_t reg_idx, char shorty,
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index 02c3d6a..f67866a 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -289,7 +289,7 @@
 
   void EmitBranchExceptionLandingPad(uint32_t dex_pc);
 
-  void EmitGuard_GarbageCollectionSuspend();
+  void EmitGuard_GarbageCollectionSuspend(uint32_t dex_pc);
 
   llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq,
                                           llvm::Value* cmp_lt);
@@ -461,9 +461,7 @@
   llvm::Function* func_;
 
   std::vector<DalvikReg*> regs_;
-  std::vector<llvm::Value*> shadow_frame_entries_;
   std::vector<llvm::Value*> vregs_;
-  std::vector<int32_t> reg_to_shadow_frame_index_;
   UniquePtr<DalvikReg> retval_reg_;
 
   llvm::BasicBlock* basic_block_alloca_;
diff --git a/src/compiler_llvm/runtime_support_builder.cc b/src/compiler_llvm/runtime_support_builder.cc
index dbcbe89..169f8e8 100644
--- a/src/compiler_llvm/runtime_support_builder.cc
+++ b/src/compiler_llvm/runtime_support_builder.cc
@@ -86,8 +86,8 @@
 /* ShadowFrame */
 
 llvm::Value* RuntimeSupportBuilder::EmitPushShadowFrame(llvm::Value* new_shadow_frame,
-                                                        llvm::Value* method, uint16_t num_refs,
-                                                        uint16_t num_vregs) {
+                                                        llvm::Value* method,
+                                                        uint32_t num_vregs) {
   Value* old_shadow_frame = EmitLoadFromThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
                                                      irb_.getArtFrameTy()->getPointerTo(),
                                                      kTBAARuntimeInfo);
@@ -101,16 +101,10 @@
                            method,
                            kTBAAShadowFrame);
 
-  // Store the number of the reference slots
-  irb_.StoreToObjectOffset(new_shadow_frame,
-                           ShadowFrame::NumberOfReferencesOffset(),
-                           irb_.getInt16(num_refs),
-                           kTBAAShadowFrame);
-
   // Store the number of vregs
   irb_.StoreToObjectOffset(new_shadow_frame,
                            ShadowFrame::NumberOfVRegsOffset(),
-                           irb_.getInt16(num_vregs),
+                           irb_.getInt32(num_vregs),
                            kTBAAShadowFrame);
 
   // Store the link to previous shadow frame
@@ -124,16 +118,15 @@
 
 llvm::Value*
 RuntimeSupportBuilder::EmitPushShadowFrameNoInline(llvm::Value* new_shadow_frame,
-                                                   llvm::Value* method, uint16_t num_refs,
-                                                   uint16_t num_vregs) {
+                                                   llvm::Value* method,
+                                                   uint32_t num_vregs) {
   Function* func = GetRuntimeSupportFunction(runtime_support::PushShadowFrame);
   llvm::CallInst* call_inst =
-      irb_.CreateCall5(func,
+      irb_.CreateCall4(func,
                        EmitGetCurrentThread(),
                        new_shadow_frame,
                        method,
-                       irb_.getInt16(num_refs),
-                       irb_.getInt16(num_vregs));
+                       irb_.getInt32(num_vregs));
   irb_.SetTBAA(call_inst, kTBAARuntimeInfo);
   return call_inst;
 }
@@ -156,7 +149,7 @@
 llvm::Value* RuntimeSupportBuilder::EmitIsExceptionPending() {
   Value* exception = EmitLoadFromThreadOffset(Thread::ExceptionOffset().Int32Value(),
                                               irb_.getJObjectTy(),
-                                              kTBAAJRuntime);
+                                              kTBAARuntimeInfo);
   // If exception not null
   return irb_.CreateIsNotNull(exception);
 }
@@ -166,22 +159,8 @@
 
 void RuntimeSupportBuilder::EmitTestSuspend() {
   Function* slow_func = GetRuntimeSupportFunction(runtime_support::TestSuspend);
-  Value* suspend_count = EmitLoadFromThreadOffset(Thread::ThreadFlagsOffset().Int32Value(),
-                                                  irb_.getInt16Ty(),
-                                                  kTBAARuntimeInfo);
-  Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0));
-
-  Function* parent_func = irb_.GetInsertBlock()->getParent();
-  BasicBlock* basic_block_suspend = BasicBlock::Create(context_, "suspend", parent_func);
-  BasicBlock* basic_block_cont = BasicBlock::Create(context_, "suspend_cont", parent_func);
-  irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely);
-
-  irb_.SetInsertPoint(basic_block_suspend);
   CallInst* call_inst = irb_.CreateCall(slow_func, EmitGetCurrentThread());
-  irb_.SetTBAA(call_inst, kTBAARuntimeInfo);
-  irb_.CreateBr(basic_block_cont);
-
-  irb_.SetInsertPoint(basic_block_cont);
+  irb_.SetTBAA(call_inst, kTBAAJRuntime);
 }
 
 
diff --git a/src/compiler_llvm/runtime_support_builder.h b/src/compiler_llvm/runtime_support_builder.h
index ba512af..58f01f6 100644
--- a/src/compiler_llvm/runtime_support_builder.h
+++ b/src/compiler_llvm/runtime_support_builder.h
@@ -51,9 +51,9 @@
 
   /* ShadowFrame */
   virtual llvm::Value* EmitPushShadowFrame(llvm::Value* new_shadow_frame,
-                                       llvm::Value* method, uint16_t num_refs, uint16_t num_vregs);
+                                           llvm::Value* method, uint32_t num_vregs);
   virtual llvm::Value* EmitPushShadowFrameNoInline(llvm::Value* new_shadow_frame,
-                                       llvm::Value* method, uint16_t num_refs, uint16_t num_vregs);
+                                                   llvm::Value* method, uint32_t num_vregs);
   virtual void EmitPopShadowFrame(llvm::Value* old_shadow_frame);
 
   /* Exception */
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index 3cdd532..7d73249 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -90,11 +90,9 @@
 }
 
 ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
-                                             AbstractMethod* method, uint16_t num_refs,
-                                             uint16_t num_vregs) {
+                                             AbstractMethod* method, uint32_t num_vregs) {
   ShadowFrame* old_frame = thread->PushShadowFrame(new_shadow_frame);
   new_shadow_frame->SetMethod(method);
-  new_shadow_frame->SetNumberOfReferences(num_refs);
   new_shadow_frame->SetNumberOfVRegs(num_vregs);
   return old_frame;
 }
diff --git a/src/compiler_llvm/runtime_support_llvm.h b/src/compiler_llvm/runtime_support_llvm.h
index c52b7f9..6c133c9 100644
--- a/src/compiler_llvm/runtime_support_llvm.h
+++ b/src/compiler_llvm/runtime_support_llvm.h
@@ -26,8 +26,7 @@
 //----------------------------------------------------------------------------
 
 ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
-                                             AbstractMethod* method, uint16_t num_refs,
-                                             uint16_t num_vregs);
+                                             AbstractMethod* method, uint32_t num_vregs);
 
 void art_pop_shadow_frame_from_code(void*);
 
diff --git a/src/compiler_llvm/stub_compiler.cc b/src/compiler_llvm/stub_compiler.cc
index 4854c9f..4571f58 100644
--- a/src/compiler_llvm/stub_compiler.cc
+++ b/src/compiler_llvm/stub_compiler.cc
@@ -148,7 +148,7 @@
     irb_.CreatePtrDisp(method_object_addr, code_field_offset_value,
                        accurate_func_type->getPointerTo()->getPointerTo());
 
-  llvm::Value* code_addr = irb_.CreateLoad(code_field_addr, kTBAAJRuntime);
+  llvm::Value* code_addr = irb_.CreateLoad(code_field_addr, kTBAARuntimeInfo);
 
   llvm::CallInst* retval = irb_.CreateCall(code_addr, args);
 #if defined(ART_USE_PORTABLE_COMPILER)