Add vregs to ShadowFrame.

Change-Id: I870ab3c19c0e727f0e67b570eb55d45c3497d2ad
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index af2fcc4..3c3c90b 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -44,7 +44,7 @@
 declare void @art_test_suspend_from_code(%JavaObject*)
 
 declare %ShadowFrame* @art_push_shadow_frame_from_code(%JavaObject*, %ShadowFrame*,
-                                                       %JavaObject*, i32)
+                                                       %JavaObject*, i16, i16)
 declare void @art_pop_shadow_frame_from_code(%ShadowFrame*)
 
 
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index 5bc3bfc..7001ec3 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -113,7 +113,7 @@
   // 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);
+      irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, sirt_size, 0);
 
   // Get JNIEnv
   llvm::Value* jni_env_object_addr =
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index ca9cbdf..1737b70 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -69,7 +69,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), shadow_frame_size_(0) {
+    already_pushed_shadow_frame_(NULL), num_shadow_frame_refs_(0) {
 }
 
 
@@ -268,7 +268,7 @@
   irb_.SetInsertPoint(basic_block_alloca_);
 
   // Allocate the shadow frame now!
-  shadow_frame_size_ = 0;
+  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) {
@@ -279,12 +279,12 @@
       }
 
       if (IsRegCanBeObject(i)) {
-        reg_to_shadow_frame_index_[i] = shadow_frame_size_++;
+        reg_to_shadow_frame_index_[i] = num_shadow_frame_refs_++;
       }
     }
   }
 
-  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(shadow_frame_size_);
+  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(num_shadow_frame_refs_);
   shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
 
   // Alloca a pointer to old shadow frame
@@ -3819,11 +3819,11 @@
   llvm::Value* result;
   if (is_inline) {
     result = irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr,
-                                                shadow_frame_size_);
+                                                num_shadow_frame_refs_, 0);
   } else {
-    DCHECK(shadow_frame_size_ == 0);
+    DCHECK(num_shadow_frame_refs_ == 0);
     result = irb_.Runtime().EmitPushShadowFrameNoInline(shadow_frame_upcast, method_object_addr,
-                                                        shadow_frame_size_);
+                                                        num_shadow_frame_refs_);
   }
   irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
 }
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index 15b8558..0b6fcfd 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -475,7 +475,7 @@
   llvm::Value* old_shadow_frame_;
 
   llvm::Value* already_pushed_shadow_frame_;
-  uint32_t shadow_frame_size_;
+  uint16_t num_shadow_frame_refs_;
 
   uint16_t elf_func_idx_;
 };
diff --git a/src/compiler_llvm/runtime_support_builder.cc b/src/compiler_llvm/runtime_support_builder.cc
index b51a822..2effddd 100644
--- a/src/compiler_llvm/runtime_support_builder.cc
+++ b/src/compiler_llvm/runtime_support_builder.cc
@@ -86,7 +86,8 @@
 /* ShadowFrame */
 
 llvm::Value* RuntimeSupportBuilder::EmitPushShadowFrame(llvm::Value* new_shadow_frame,
-                                                        llvm::Value* method, uint32_t size) {
+                                                        llvm::Value* method, uint16_t num_refs,
+                                                        uint16_t num_vregs) {
   Value* old_shadow_frame = EmitLoadFromThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
                                                      irb_.getArtFrameTy()->getPointerTo(),
                                                      kTBAARuntimeInfo);
@@ -100,10 +101,16 @@
                            method,
                            kTBAAShadowFrame);
 
-  // Store the number of the pointer slots
+  // Store the number of the reference slots
   irb_.StoreToObjectOffset(new_shadow_frame,
                            ShadowFrame::NumberOfReferencesOffset(),
-                           irb_.getInt32(size),
+                           irb_.getInt16(num_refs),
+                           kTBAAShadowFrame);
+
+  // Store the number of vregs
+  irb_.StoreToObjectOffset(new_shadow_frame,
+                           ShadowFrame::NumberOfVRegsOffset(),
+                           irb_.getInt16(num_vregs),
                            kTBAAShadowFrame);
 
   // Store the link to previous shadow frame
diff --git a/src/compiler_llvm/runtime_support_builder.h b/src/compiler_llvm/runtime_support_builder.h
index ab076bb..b8123a5 100644
--- a/src/compiler_llvm/runtime_support_builder.h
+++ b/src/compiler_llvm/runtime_support_builder.h
@@ -51,7 +51,7 @@
 
   /* ShadowFrame */
   virtual llvm::Value* EmitPushShadowFrame(llvm::Value* new_shadow_frame,
-                                       llvm::Value* method, uint32_t size);
+                                       llvm::Value* method, uint16_t num_refs, uint16_t num_vregs);
   virtual llvm::Value* EmitPushShadowFrameNoInline(llvm::Value* new_shadow_frame,
                                                llvm::Value* method, uint32_t size);
   virtual void EmitPopShadowFrame(llvm::Value* old_shadow_frame);
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index d7e146a..668712f 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -90,10 +90,12 @@
 }
 
 ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
-                                             AbstractMethod* method, uint32_t size) {
+                                             AbstractMethod* method, uint16_t num_refs,
+                                             uint16_t num_vregs) {
   ShadowFrame* old_frame = thread->PushShadowFrame(new_shadow_frame);
   new_shadow_frame->SetMethod(method);
-  new_shadow_frame->SetNumberOfReferences(size);
+  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 626fe4f..c52b7f9 100644
--- a/src/compiler_llvm/runtime_support_llvm.h
+++ b/src/compiler_llvm/runtime_support_llvm.h
@@ -26,7 +26,8 @@
 //----------------------------------------------------------------------------
 
 ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
-                                             AbstractMethod* method, uint32_t size);
+                                             AbstractMethod* method, uint16_t num_refs,
+                                             uint16_t num_vregs);
 
 void art_pop_shadow_frame_from_code(void*);
 
diff --git a/src/stack.h b/src/stack.h
index bceadc3..845b840 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -37,16 +37,18 @@
 
 class ShadowFrame {
  public:
-  // Number of references contained within this shadow frame
   uint32_t NumberOfReferences() const {
     return number_of_references_;
   }
 
-  void SetNumberOfReferences(uint32_t number_of_references) {
+  void SetNumberOfReferences(uint16_t number_of_references) {
     number_of_references_ = number_of_references;
   }
 
-  // Caller dex pc
+  void SetNumberOfVRegs(uint16_t number_of_vregs) {
+    number_of_vregs_ = number_of_vregs;
+  }
+
   uint32_t GetDexPC() const {
     return dex_pc_;
   }
@@ -55,7 +57,6 @@
     dex_pc_ = dex_pc;
   }
 
-  // Link to previous shadow frame or NULL
   ShadowFrame* GetLink() const {
     return link_;
   }
@@ -101,37 +102,42 @@
     }
   }
 
-  // Offset of link within shadow frame
   static size_t LinkOffset() {
     return OFFSETOF_MEMBER(ShadowFrame, link_);
   }
 
-  // Offset of method within shadow frame
   static size_t MethodOffset() {
     return OFFSETOF_MEMBER(ShadowFrame, method_);
   }
 
-  // Offset of dex pc within shadow frame
   static size_t DexPCOffset() {
     return OFFSETOF_MEMBER(ShadowFrame, dex_pc_);
   }
 
-  // Offset of length within shadow frame
   static size_t NumberOfReferencesOffset() {
     return OFFSETOF_MEMBER(ShadowFrame, number_of_references_);
   }
 
-  // Offset of references within shadow frame
+  static size_t NumberOfVRegsOffset() {
+    return OFFSETOF_MEMBER(ShadowFrame, number_of_vregs_);
+  }
+
   static size_t ReferencesOffset() {
     return OFFSETOF_MEMBER(ShadowFrame, references_);
   }
 
+  size_t VRegsOffset() {
+    return ReferencesOffset() + (sizeof(Object*) * NumberOfReferences());
+  }
+
  private:
   // ShadowFrame should be allocated by the generated code directly.
   // We should not create new shadow stack in the runtime support function.
   ~ShadowFrame() {}
 
-  uint32_t number_of_references_;
+  uint16_t number_of_references_;
+  uint16_t number_of_vregs_;
+  // Link to previous shadow frame or NULL.
   ShadowFrame* link_;
   AbstractMethod* method_;
   uint32_t dex_pc_;