Fix VMStack_getClosestUserClassLoader

Fixes failure in libcore.java.io.OldAndroidSerializationTest#testSerialization

Change-Id: I13187f081ea87402be88d59a48ec3890505342ae
diff --git a/src/dalvik_system_VMStack.cc b/src/dalvik_system_VMStack.cc
index 37ee8b2..bcfe29b 100644
--- a/src/dalvik_system_VMStack.cc
+++ b/src/dalvik_system_VMStack.cc
@@ -50,23 +50,37 @@
   frame.Next();
   frame.Next();
   Method* callerCaller = frame.GetMethod();
+  DCHECK(callerCaller != NULL);
   const Object* cl = callerCaller->GetDeclaringClass()->GetClassLoader();
   return AddLocalReference<jobject>(env, cl);
 }
 
 jobject VMStack_getClosestUserClassLoader(JNIEnv* env, jclass, jobject javaBootstrap, jobject javaSystem) {
-  Thread* self = Thread::Current();
+  struct ClosestUserClassLoaderVisitor : public Thread::StackVisitor {
+    ClosestUserClassLoaderVisitor(Object* bootstrap, Object* system)
+      : bootstrap(bootstrap), system(system), class_loader(NULL) {}
+    virtual void VisitFrame(const Frame& f, uintptr_t) {
+      if (class_loader != NULL) {
+        // If we already found a result, nothing to do.
+        // TODO: need SmartFrame (Thread::WalkStack-like iterator).
+        // (or change VisitFrame to let us return bool to stop visiting)
+        return;
+      }
+      Class* c = f.GetMethod()->GetDeclaringClass();
+      Object* cl = c->GetClassLoader();
+      if (cl != NULL && cl != bootstrap && cl != system) {
+        class_loader = cl;
+      }
+    }
+    Object* bootstrap;
+    Object* system;
+    Object* class_loader;
+  };
   Object* bootstrap = Decode<Object*>(env, javaBootstrap);
   Object* system = Decode<Object*>(env, javaSystem);
-  // TODO: need SmartFrame (Thread::WalkStack-like iterator).
-  for (Frame frame = self->GetTopOfStack(); frame.HasNext(); frame.Next()) {
-    Class* c = frame.GetMethod()->GetDeclaringClass();
-    Object* cl = c->GetClassLoader();
-    if (cl != NULL && cl != bootstrap && cl != system) {
-      return AddLocalReference<jobject>(env, cl);
-    }
-  }
-  return NULL;
+  ClosestUserClassLoaderVisitor visitor(bootstrap, system);
+  Thread::Current()->WalkStack(&visitor);
+  return AddLocalReference<jobject>(env, visitor.class_loader);
 }
 
 jclass VMStack_getStackClass2(JNIEnv* env, jclass) {
@@ -77,6 +91,7 @@
   frame.Next();
   frame.Next();
   Method* callerCallerCaller = frame.GetMethod();
+  DCHECK(callerCallerCaller != NULL);
   Class* c = callerCallerCaller->GetDeclaringClass();
   return AddLocalReference<jclass>(env, c);
 }