Add AllocStackTrace(). Move InternalStackTrace to managed heap.

Replaces trace.method and trace.pc with IntArray and ObjectArray<Method>.
Exception_tests pass.

Change-Id: I54431bbf8031b186fdd360ec27a31b11c8eff052
diff --git a/src/class_linker.h b/src/class_linker.h
index c85fb4e..b62433c 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -126,6 +126,11 @@
   const DexFile& FindDexFile(const DexCache* dex_cache) const;
   DexCache* FindDexCache(const DexFile& dex_file) const;
 
+  template <class T>
+  ObjectArray<T>* AllocObjectArray(size_t length) {
+    return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
+  }
+
   ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length);
 
  private:
@@ -153,10 +158,6 @@
   DexCache* AllocDexCache(const DexFile& dex_file);
   Field* AllocField();
   Method* AllocMethod();
-  template <class T>
-  ObjectArray<T>* AllocObjectArray(size_t length) {
-    return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
-  }
   CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
 
   Class* CreatePrimitiveClass(const char* descriptor);
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 4337d7a..a1a101d 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -148,18 +148,18 @@
   Thread* thread = Thread::Current();
   thread->SetTopOfStack(fake_stack);
 
-  Thread::InternalStackTrace* traces = thread->GetStackTrace(2);
-  ObjectArray<StackTraceElement>* trace_array = thread->GetStackTraceElement(2, traces);
-  delete[] traces;
+  ObjectArray<StackTraceElement>* trace_array = thread->AllocStackTrace(2);
 
   ASSERT_TRUE(trace_array->Get(0) != NULL);
-  EXPECT_STREQ("java.lang.MyClass", trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
+  EXPECT_STREQ("java.lang.MyClass",
+               trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
   EXPECT_STREQ("MyClass.java", trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
   EXPECT_STREQ("g", trace_array->Get(0)->GetMethodName()->ToModifiedUtf8().c_str());
   EXPECT_EQ(22u, trace_array->Get(0)->GetLineNumber());
 
   ASSERT_TRUE(trace_array->Get(1) != NULL);
-  EXPECT_STREQ("java.lang.MyClass", trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
+  EXPECT_STREQ("java.lang.MyClass",
+               trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
   EXPECT_STREQ("MyClass.java", trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
   EXPECT_STREQ("f", trace_array->Get(1)->GetMethodName()->ToModifiedUtf8().c_str());
   EXPECT_EQ(7u, trace_array->Get(1)->GetLineNumber());
diff --git a/src/thread.cc b/src/thread.cc
index 717c6f7..2e7b6a9 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -316,33 +316,44 @@
   return result;
 }
 
-// TODO: Replaces trace.method and trace.pc with IntArray nad
-// ObjectArray<Method>.
-Thread::InternalStackTrace* Thread::GetStackTrace(uint16_t length) {
+// TODO: Compute length
+bool Thread::WalkStack(uint16_t length,
+                       ObjectArray<Method>* method_trace,
+                       IntArray* pc_trace) {
   Frame frame = Thread::Current()->GetTopOfStack();
-  InternalStackTrace *traces = new InternalStackTrace[length];
+
   for (uint16_t i = 0; i < length && frame.HasNext(); ++i, frame.Next()) {
-    traces[i].method = frame.GetMethod();
-    traces[i].pc = frame.GetPC();
+    method_trace->Set(i, (Method*) frame.GetMethod());
+    pc_trace->Set(i, frame.GetPC());
   }
-  return traces;
+  return true;
 }
 
-ObjectArray<StackTraceElement>* Thread::GetStackTraceElement(uint16_t length, InternalStackTrace *raw_trace) {
+ObjectArray<StackTraceElement>* Thread::AllocStackTrace(uint16_t length) {
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+
+  ObjectArray<Method>* method_trace = class_linker->AllocObjectArray<Method>(length);
+  IntArray* pc_trace = IntArray::Alloc(length);
+
+  WalkStack(length, method_trace, pc_trace);
+
   ObjectArray<StackTraceElement>* java_traces = class_linker->AllocStackTraceElementArray(length);
 
   for (uint16_t i = 0; i < length; ++i) {
     // Prepare parameter for StackTraceElement(String cls, String method, String file, int line)
-    const Method* method = raw_trace[i].method;
+    const Method* method = method_trace->Get(i);
     const Class* klass = method->GetDeclaringClass();
     const DexFile& dex_file = class_linker->FindDexFile(klass->GetDexCache());
-    String* readable_descriptor = String::AllocFromModifiedUtf8(PrettyDescriptor(klass->GetDescriptor()).c_str());
+    String* readable_descriptor = String::AllocFromModifiedUtf8(
+        PrettyDescriptor(klass->GetDescriptor()).c_str()
+        );
 
     StackTraceElement* obj =
         StackTraceElement::Alloc(readable_descriptor,
-                                 method->GetName(), String::AllocFromModifiedUtf8(klass->source_file_),
-                                 dex_file.GetLineNumFromPC(method, method->ToDexPC(raw_trace[i].pc)));
+                                 method->GetName(),
+                                 String::AllocFromModifiedUtf8(klass->source_file_),
+                                 dex_file.GetLineNumFromPC(method,
+                                                           method->ToDexPC(pc_trace->Get(i))));
     java_traces->Set(i, obj);
   }
   return java_traces;
diff --git a/src/thread.h b/src/thread.h
index 8b64249..85abf2f 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -29,6 +29,8 @@
 class Throwable;
 class StackTraceElement;
 template<class T> class ObjectArray;
+template<class T> class PrimitiveArray;
+typedef PrimitiveArray<int32_t> IntArray;
 
 class Mutex {
  public:
@@ -398,15 +400,8 @@
     class_loader_override_ = class_loader_override;
   }
 
-  struct InternalStackTrace {
-    const Method* method;
-    uintptr_t pc;
-  };
-
-  // Get the top length frames information
-  InternalStackTrace* GetStackTrace(uint16_t length);
-
-  ObjectArray<StackTraceElement>* GetStackTraceElement(uint16_t length, InternalStackTrace *raw_trace);
+  // Allocate stack trace
+  ObjectArray<StackTraceElement>* AllocStackTrace(uint16_t length);
 
  private:
   Thread()
@@ -427,6 +422,8 @@
   void InitCpu();
   void InitFunctionPointers();
 
+  bool WalkStack(uint16_t length, ObjectArray<Method>* method_trace, IntArray* pc_trace);
+
   // Managed thread id.
   uint32_t id_;