Improved ClassLoader support for JNI FindClass, FieldFieldID, JNI_OnLoad

Also fix AttachCurrentThread to use the peer's thread name,
not the possibly null name from the arguments.

Change-Id: I12e612619d828734d8353a0dca44fb4f11ee0c66
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 0982f83..5052773 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -310,6 +310,15 @@
   return EncodeMethod(method);
 }
 
+const ClassLoader* GetClassLoader(Thread* self) {
+  Frame frame = self->GetTopOfStack();
+  Method* method = frame.GetMethod();
+  if (method == NULL || PrettyMethod(method, false) == "java.lang.Runtime.nativeLoad") {
+    return self->GetClassLoaderOverride();
+  }
+  return method->GetDeclaringClass()->GetClassLoader();
+}
+
 jfieldID FindFieldID(ScopedJniThreadState& ts, jclass jni_class, const char* name, const char* sig, bool is_static) {
   Class* c = Decode<Class*>(ts, jni_class);
   if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true)) {
@@ -320,8 +329,7 @@
   Class* field_type;
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   if (sig[1] != '\0') {
-    // TODO: need to get the appropriate ClassLoader.
-    const ClassLoader* cl = ts.Self()->GetClassLoaderOverride();
+    const ClassLoader* cl = GetClassLoader(ts.Self());
     field_type = class_linker->FindClass(sig, cl);
   } else {
     field_type = class_linker->FindPrimitiveClass(*sig);
@@ -641,8 +649,7 @@
     std::string descriptor(NormalizeJniClassDescriptor(name));
     Class* c = NULL;
     if (runtime->IsStarted()) {
-      // TODO: need to get the appropriate ClassLoader.
-      const ClassLoader* cl = ts.Self()->GetClassLoaderOverride();
+      const ClassLoader* cl = GetClassLoader(ts.Self());
       c = class_linker->FindClass(descriptor, cl);
     } else {
       c = class_linker->FindSystemClass(descriptor);