Implement Throwable::nativeFillInStackTrace and nativeGetStackTrace.

Refactor stack trace into compact internal form which is then used to
compute larger and more verbose StackTraceElement[] form. Fix some
potential problems with GC.

Change-Id: I4a4308c1ec5b82fd95b649d5ec0504b9607e688f
diff --git a/src/thread.h b/src/thread.h
index 3f6228a..ed4b1e4 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -400,8 +400,13 @@
     class_loader_override_ = class_loader_override;
   }
 
-  // Allocate stack trace
-  ObjectArray<StackTraceElement>* AllocStackTrace();
+  // Create the internal representation of a stack trace, that is more time
+  // and space efficient to compute than the StackTraceElement[]
+  jobject CreateInternalStackTrace() const;
+
+  // Convert an internal stack trace representation to a StackTraceElement[]
+  static jobjectArray
+      InternalStackTraceToStackTraceElementArray(jobject internal, JNIEnv* env);
 
   void VisitRoots(Heap::RootVisitor* visitor, void* arg) const;
 
@@ -475,7 +480,7 @@
 
   static void ThreadExitCallback(void* arg);
 
-  void WalkStack(StackVisitor* visitor);
+  void WalkStack(StackVisitor* visitor) const;
 
   // Thin lock thread id. This is a small integer used by the thin lock implementation.
   // This is not to be confused with the native thread's tid, nor is it the value returned