Support for return PC offset and frame size in JNI compiler.

For stack crawls we need the return PC and the size of frames, store
this information in the Method.

Change-Id: Ic616b4f78ca571c837e5c8473607285a7e8b58f0
diff --git a/src/calling_convention.h b/src/calling_convention.h
index 7bfc28e..0aeb260 100644
--- a/src/calling_convention.h
+++ b/src/calling_convention.h
@@ -105,6 +105,8 @@
   // always at the bottom of a frame, but this doesn't work for outgoing
   // native args). Includes alignment.
   size_t FrameSize();
+  // Offset within the frame of the return pc
+  size_t ReturnPcOffset();
   // Size of outgoing arguments, including alignment
   size_t OutArgSize();
   // Number of handles in stack handle block
diff --git a/src/calling_convention_arm.cc b/src/calling_convention_arm.cc
index 743445d..143d83b 100644
--- a/src/calling_convention_arm.cc
+++ b/src/calling_convention_arm.cc
@@ -78,6 +78,12 @@
   return RoundUp(frame_data_size + handle_area_size + SizeOfReturnValue(), 16);
 }
 
+size_t JniCallingConvention::ReturnPcOffset() {
+  // Link register is always the last value spilled, skip forward one word for
+  // the Method* then skip back one word to get the link register (ie +0)
+  return SpillAreaSize();
+}
+
 size_t JniCallingConvention::SpillAreaSize() {
   // Space for link register. For synchronized methods we need enough space to
   // save R1, R2 and R3 (R0 is the method register and always preserved)
diff --git a/src/calling_convention_x86.cc b/src/calling_convention_x86.cc
index ed95eb0..1d2c4f8 100644
--- a/src/calling_convention_x86.cc
+++ b/src/calling_convention_x86.cc
@@ -59,6 +59,12 @@
   return RoundUp(frame_data_size + handle_area_size + SizeOfReturnValue(), 16);
 }
 
+size_t JniCallingConvention::ReturnPcOffset() {
+  // Return PC is pushed at the top of the frame by the call into the method
+  return FrameSize() - kPointerSize;
+}
+
+
 size_t JniCallingConvention::SpillAreaSize() {
   // No spills, return address was pushed at the top of the frame
   return 0;
diff --git a/src/jni_compiler.cc b/src/jni_compiler.cc
index 626de8c..eccd8f9 100644
--- a/src/jni_compiler.cc
+++ b/src/jni_compiler.cc
@@ -294,6 +294,8 @@
   jni_asm->FinalizeInstructions(code);
   native_method->SetCode(reinterpret_cast<byte*>(code.pointer()), cs,
       jni_asm->GetInstructionSet());
+  native_method->SetFrameSize(frame_size);
+  native_method->SetReturnPcOffset(jni_conv.ReturnPcOffset());
 }
 
 // Copy a single parameter from the managed to the JNI calling convention
diff --git a/src/object.h b/src/object.h
index 0b1c072..f86142a 100644
--- a/src/object.h
+++ b/src/object.h
@@ -605,20 +605,20 @@
     code_ =  reinterpret_cast<void*>(address);
   }
 
-  void SetFrameSize(uint32_t frame_size) {
+  void SetFrameSize(size_t frame_size) {
     frame_size_ = frame_size;
   }
 
-  void SetPcOffset(uint32_t pc_offset) {
-    pc_offset_ = pc_offset;
+  void SetReturnPcOffset(size_t return_pc_offset) {
+    return_pc_offset_ = return_pc_offset;
   }
 
   size_t GetFrameSize() const {
     return frame_size_;
   }
 
-  size_t GetPcOffset() const {
-    return pc_offset_;
+  size_t GetReturnPcOffset() const {
+    return return_pc_offset_;
   }
 
   void SetCoreSpillMask(uint32_t core_spill_mask) {
@@ -675,7 +675,7 @@
   uint16_t num_ins_;
 
   // Total size in bytes of the frame
-  uint32_t frame_size_;
+  size_t frame_size_;
 
   // Architecture-dependent register spill masks
   uint32_t core_spill_mask_;
@@ -702,7 +702,8 @@
   // The short-form method descriptor string.
   StringPiece shorty_;
 
-  // short cuts to declaring_class_->dex_cache_ members for fast compiled code access
+  // short cuts to declaring_class_->dex_cache_ members for fast compiled code
+  // access
   ObjectArray<String>* dex_cache_strings_;
   ObjectArray<Class>* dex_cache_classes_;
   ObjectArray<Method>* dex_cache_methods_;
@@ -718,8 +719,8 @@
   // Size in bytes of compiled code associated with this method
   const uint32_t code_size_;
 
-  // Offset of PC within compiled code (in bytes)
-  uint32_t pc_offset_;
+  // Offset of return PC within frame for compiled code (in bytes)
+  size_t return_pc_offset_;
 
   // Any native method registered with this method
   const void* native_method_;
diff --git a/src/thread.cc b/src/thread.cc
index 30012b9..8d11541 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -57,7 +57,7 @@
 
 void* Frame::GetPC() const {
   byte* pc_addr = reinterpret_cast<byte*>(sp_) +
-      GetMethod()->GetPcOffset();
+      GetMethod()->GetReturnPcOffset();
   return reinterpret_cast<void*>(pc_addr);
 }