Record thread data when making reentrant transitions.

Calls from managed to native code record the top of the managed stack
for stack crawls. Up calls from native to managed (already in the
runnable managed thread state) need to preserve this data as the managed
code may call back into native code. This change introduces a linked
list of records from native to managed code, that allows the regions of
managed code to have their stack crawled.

Change-Id: I71bf680cf1fc2e95d261063050dd6effb72b1786
diff --git a/src/thread.h b/src/thread.h
index 054a4cd..66b5e28 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -99,6 +99,11 @@
   DISALLOW_COPY_AND_ASSIGN(StackHandleBlock);
 };
 
+struct NativeToManagedRecord {
+  NativeToManagedRecord* link;
+  void* last_top_of_managed_stack;
+};
+
 class Thread {
  public:
   enum State {
@@ -241,9 +246,23 @@
   void IncrementSuspendCount() { suspend_count_++; }
   void DecrementSuspendCount() { suspend_count_--; }
 
+  // Linked list recording transitions from native to managed code
+  void PushNativeToManagedRecord(NativeToManagedRecord* record) {
+    record->last_top_of_managed_stack = top_of_managed_stack_;
+    record->link = native_to_managed_record_;
+    native_to_managed_record_ = record;
+    top_of_managed_stack_ = NULL;
+  }
+  void PopNativeToManagedRecord(const NativeToManagedRecord& record) {
+    native_to_managed_record_ = record.link;
+    top_of_managed_stack_ = record.last_top_of_managed_stack;
+  }
+
  private:
   Thread()
       : id_(1234),
+        top_of_managed_stack_(NULL),
+        native_to_managed_record_(NULL),
         top_shb_(NULL),
         jni_env_(NULL),
         exception_(NULL),
@@ -264,6 +283,10 @@
   // a managed stack when a thread is in native code.
   void* top_of_managed_stack_;
 
+  // A linked list (of stack allocated records) recording transitions from
+  // native to managed code.
+  NativeToManagedRecord* native_to_managed_record_;
+
   // Top of linked list of stack handle blocks or NULL for none
   StackHandleBlock* top_shb_;