Explicitly pass Thread::Current to MutexLock and Alloc.

Change-Id: I8b75bc0617915465f102815b32306aa7760dcae4
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 75ab1f0..22438a0 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -195,7 +195,7 @@
   }
   JavaVMExt* vm = soa.Vm();
   IndirectReferenceTable& weak_globals = vm->weak_globals;
-  MutexLock mu(vm->weak_globals_lock);
+  MutexLock mu(soa.Self(), vm->weak_globals_lock);
   IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, obj);
   return reinterpret_cast<jweak>(ref);
 }
@@ -203,15 +203,27 @@
 static void CheckMethodArguments(AbstractMethod* m, JValue* args)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   MethodHelper mh(m);
-  ObjectArray<Class>* parameter_types = mh.GetParameterTypes();
-  CHECK(parameter_types != NULL);
+  const DexFile::TypeList* params = mh.GetParameterTypeList();
+  if (params == NULL) {
+    return;  // No arguments so nothing to check.
+  }
+  uint32_t num_params = params->Size();
   size_t error_count = 0;
-  for (int i = 0; i < parameter_types->GetLength(); ++i) {
-    Class* parameter_type = parameter_types->Get(i);
-    // TODO: check primitives are in range.
-    if (!parameter_type->IsPrimitive()) {
+  for (uint32_t i = 0; i < num_params; i++) {
+    uint16_t type_idx = params->GetTypeItem(i).type_idx_;
+    Class* param_type = mh.GetClassFromTypeIdx(type_idx);
+    if (param_type == NULL) {
+      Thread* self = Thread::Current();
+      CHECK(self->IsExceptionPending());
+      LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: "
+          << mh.GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
+          << self->GetException()->Dump();
+      self->ClearException();
+      ++error_count;
+    } else if (!param_type->IsPrimitive()) {
+      // TODO: check primitives are in range.
       Object* argument = args[i].GetL();
-      if (argument != NULL && !argument->InstanceOf(parameter_type)) {
+      if (argument != NULL && !argument->InstanceOf(param_type)) {
         LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
                    << PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m);
         ++error_count;
@@ -382,14 +394,14 @@
 static void PinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   JavaVMExt* vm = soa.Vm();
-  MutexLock mu(vm->pins_lock);
+  MutexLock mu(soa.Self(), vm->pins_lock);
   vm->pin_table.Add(array);
 }
 
 static void UnpinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   JavaVMExt* vm = soa.Vm();
-  MutexLock mu(vm->pins_lock);
+  MutexLock mu(soa.Self(), vm->pins_lock);
   vm->pin_table.Remove(array);
 }
 
@@ -521,7 +533,7 @@
     self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
     bool okay;
     {
-      MutexLock mu(jni_on_load_lock_);
+      MutexLock mu(self, jni_on_load_lock_);
 
       if (jni_on_load_thread_id_ == self->GetThinLockId()) {
         // Check this so we don't end up waiting for ourselves.  We need to return "true" so the
@@ -544,7 +556,7 @@
   }
 
   void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
-    MutexLock mu(jni_on_load_lock_);
+    MutexLock mu(Thread::Current(), jni_on_load_lock_);
 
     jni_on_load_result_ = result ? kOkay : kFailed;
     jni_on_load_thread_id_ = 0;
@@ -836,7 +848,7 @@
     JavaVMExt* vm = soa.Vm();
     IndirectReferenceTable& globals = vm->globals;
     Object* decoded_obj = soa.Decode<Object*>(obj);
-    MutexLock mu(vm->globals_lock);
+    MutexLock mu(soa.Self(), vm->globals_lock);
     IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
     return reinterpret_cast<jobject>(ref);
   }
@@ -848,7 +860,7 @@
     ScopedObjectAccess soa(env);
     JavaVMExt* vm = soa.Vm();
     IndirectReferenceTable& globals = vm->globals;
-    MutexLock mu(vm->globals_lock);
+    MutexLock mu(soa.Self(), vm->globals_lock);
 
     if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
       LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
@@ -868,7 +880,7 @@
     ScopedObjectAccess soa(env);
     JavaVMExt* vm = soa.Vm();
     IndirectReferenceTable& weak_globals = vm->weak_globals;
-    MutexLock mu(vm->weak_globals_lock);
+    MutexLock mu(soa.Self(), vm->weak_globals_lock);
 
     if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) {
       LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
@@ -918,7 +930,7 @@
     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
       return NULL;
     }
-    return soa.AddLocalReference<jobject>(c->AllocObject());
+    return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
   }
 
   static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) {
@@ -935,7 +947,7 @@
     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
       return NULL;
     }
-    Object* result = c->AllocObject();
+    Object* result = c->AllocObject(soa.Self());
     if (result == NULL) {
       return NULL;
     }
@@ -954,7 +966,7 @@
     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
       return NULL;
     }
-    Object* result = c->AllocObject();
+    Object* result = c->AllocObject(soa.Self());
     if (result == NULL) {
       return NULL;
     }
@@ -1754,7 +1766,7 @@
 
   static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
     ScopedObjectAccess soa(env);
-    String* result = String::AllocFromUtf16(char_count, chars);
+    String* result = String::AllocFromUtf16(soa.Self(), char_count, chars);
     return soa.AddLocalReference<jstring>(result);
   }
 
@@ -1763,7 +1775,7 @@
       return NULL;
     }
     ScopedObjectAccess soa(env);
-    String* result = String::AllocFromModifiedUtf8(utf);
+    String* result = String::AllocFromModifiedUtf8(soa.Self(), utf);
     return soa.AddLocalReference<jstring>(result);
   }
 
@@ -1923,7 +1935,7 @@
 
     // Allocate and initialize if necessary.
     Class* array_class = soa.Decode<Class*>(java_array_class.get());
-    ObjectArray<Object>* result = ObjectArray<Object>::Alloc(array_class, length);
+    ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length);
     if (initial_element != NULL) {
       Object* initial_object = soa.Decode<Object*>(initial_element);
       for (jsize i = 0; i < length; ++i) {
@@ -2297,7 +2309,7 @@
   static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     CHECK_GE(length, 0); // TODO: ReportJniError
-    ArtT* result = ArtT::Alloc(length);
+    ArtT* result = ArtT::Alloc(soa.Self(), length);
     return soa.AddLocalReference<JniT>(result);
   }
 
@@ -2762,16 +2774,17 @@
     os << " (with forcecopy)";
   }
   os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off");
+  Thread* self = Thread::Current();
   {
-    MutexLock mu(pins_lock);
+    MutexLock mu(self, pins_lock);
     os << "; pins=" << pin_table.Size();
   }
   {
-    MutexLock mu(globals_lock);
+    MutexLock mu(self, globals_lock);
     os << "; globals=" << globals.Capacity();
   }
   {
-    MutexLock mu(weak_globals_lock);
+    MutexLock mu(self, weak_globals_lock);
     if (weak_globals.Capacity() > 0) {
       os << " (plus " << weak_globals.Capacity() << " weak)";
     }
@@ -2779,22 +2792,23 @@
   os << '\n';
 
   {
-    MutexLock mu(libraries_lock);
+    MutexLock mu(self, libraries_lock);
     os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
   }
 }
 
 void JavaVMExt::DumpReferenceTables(std::ostream& os) {
+  Thread* self = Thread::Current();
   {
-    MutexLock mu(globals_lock);
+    MutexLock mu(self, globals_lock);
     globals.Dump(os);
   }
   {
-    MutexLock mu(weak_globals_lock);
+    MutexLock mu(self, weak_globals_lock);
     weak_globals.Dump(os);
   }
   {
-    MutexLock mu(pins_lock);
+    MutexLock mu(self, pins_lock);
     pin_table.Dump(os);
   }
 }
@@ -2808,9 +2822,10 @@
   // TODO: for better results we should canonicalize the pathname (or even compare
   // inodes). This implementation is fine if everybody is using System.loadLibrary.
   SharedLibrary* library;
+  Thread* self = Thread::Current();
   {
     // TODO: move the locking (and more of this logic) into Libraries.
-    MutexLock mu(libraries_lock);
+    MutexLock mu(self, libraries_lock);
     library = libraries->Get(path);
   }
   if (library != NULL) {
@@ -2847,7 +2862,6 @@
 
   // This can execute slowly for a large library on a busy system, so we
   // want to switch from kRunnable while it executes.  This allows the GC to ignore us.
-  Thread* self = Thread::Current();
   self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
   void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY);
   self->TransitionFromSuspendedToRunnable();
@@ -2864,7 +2878,7 @@
   // TODO: move the locking (and more of this logic) into Libraries.
   bool created_library = false;
   {
-    MutexLock mu(libraries_lock);
+    MutexLock mu(self, libraries_lock);
     library = libraries->Get(path);
     if (library == NULL) {  // We won race to get libraries_lock
       library = new SharedLibrary(path, handle, class_loader);
@@ -2942,24 +2956,26 @@
 
   std::string detail;
   void* native_method;
+  Thread* self = Thread::Current();
   {
-    MutexLock mu(libraries_lock);
+    MutexLock mu(self, libraries_lock);
     native_method = libraries->FindNativeMethod(m, detail);
   }
   // throwing can cause libraries_lock to be reacquired
   if (native_method == NULL) {
-    Thread::Current()->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
+    self->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
   }
   return native_method;
 }
 
 void JavaVMExt::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+  Thread* self = Thread::Current();
   {
-    MutexLock mu(globals_lock);
+    MutexLock mu(self, globals_lock);
     globals.VisitRoots(visitor, arg);
   }
   {
-    MutexLock mu(pins_lock);
+    MutexLock mu(self, pins_lock);
     pin_table.VisitRoots(visitor, arg);
   }
   // The weak_globals table is visited by the GC itself (because it mutates the table).