Implement most of VMStack and some of Zygote.

Change-Id: I07e18259a0452a2a9b077148f4f1ca67d3f63427
diff --git a/src/dalvik_system_VMStack.cc b/src/dalvik_system_VMStack.cc
index 2a3f18b..331a64f 100644
--- a/src/dalvik_system_VMStack.cc
+++ b/src/dalvik_system_VMStack.cc
@@ -15,7 +15,9 @@
  */
 
 #include "jni_internal.h"
+#include "class_loader.h"
 #include "object.h"
+#include "thread_list.h"
 
 #include "JniConstants.h" // Last to avoid problems with LOG redefinition.
 
@@ -23,14 +25,58 @@
 
 namespace {
 
-jint VMStack_fillStackTraceElements(JNIEnv* env, jclass, jobject targetThread, jobjectArray javaSteArray) {
-  UNIMPLEMENTED(FATAL);
-  return 0;
+class StackGetter {
+ public:
+  StackGetter(JNIEnv* env, Thread* thread) : env_(env), thread_(thread), trace_(NULL) {
+  }
+
+  static void Callback(void* arg) {
+    reinterpret_cast<StackGetter*>(arg)->Callback();
+  }
+
+  jobject GetTrace() {
+    return trace_;
+  }
+
+ private:
+  void Callback() {
+    trace_ = thread_->CreateInternalStackTrace(env_);
+  }
+
+  JNIEnv* env_;
+  Thread* thread_;
+  jobject trace_;
+};
+
+jobject GetThreadStack(JNIEnv* env, jobject javaThread) {
+  Thread* thread = Thread::FromManagedThread(env, javaThread);
+  if (thread == NULL) {
+    return NULL;
+  }
+  ThreadList* thread_list = Runtime::Current()->GetThreadList();
+  StackGetter stack_getter(env, thread);
+  thread_list->RunWhileSuspended(thread, StackGetter::Callback, &stack_getter);
+  return stack_getter.GetTrace();
+}
+
+jint VMStack_fillStackTraceElements(JNIEnv* env, jclass, jobject javaThread, jobjectArray javaSteArray) {
+  jobject trace = GetThreadStack(env, javaThread);
+  if (trace == NULL) {
+    return 0;
+  }
+  int32_t depth;
+  Thread::InternalStackTraceToStackTraceElementArray(env, trace, javaSteArray, &depth);
+  return depth;
 }
 
 jobject VMStack_getCallingClassLoader(JNIEnv* env, jclass) {
-  UNIMPLEMENTED(WARNING);
-  return NULL;
+  // Returns the defining class loader of the caller's caller.
+  Frame frame = Thread::Current()->GetTopOfStack();
+  frame.Next();
+  frame.Next();
+  Method* callerCaller = frame.GetMethod();
+  const Object* cl = callerCaller->GetDeclaringClass()->GetClassLoader();
+  return AddLocalReference<jobject>(env, cl);
 }
 
 jobjectArray VMStack_getClasses(JNIEnv* env, jclass, jint maxDepth) {
@@ -39,13 +85,22 @@
 }
 
 jclass VMStack_getStackClass2(JNIEnv* env, jclass) {
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+  // Returns the class of the caller's caller's caller.
+  Frame frame = Thread::Current()->GetTopOfStack();
+  frame.Next();
+  frame.Next();
+  frame.Next();
+  Method* callerCallerCaller = frame.GetMethod();
+  Class* c = callerCallerCaller->GetDeclaringClass();
+  return AddLocalReference<jclass>(env, c);
 }
 
-jobjectArray VMStack_getThreadStackTrace(JNIEnv* env, jclass, jobject targetThread) {
-  UNIMPLEMENTED(FATAL);
-  return NULL;
+jobjectArray VMStack_getThreadStackTrace(JNIEnv* env, jclass, jobject javaThread) {
+  jobject trace = GetThreadStack(env, javaThread);
+  if (trace == NULL) {
+    return NULL;
+  }
+  return Thread::InternalStackTraceToStackTraceElementArray(env, trace);
 }
 
 static JNINativeMethod gMethods[] = {