Actually track the JNI MonitorEnter/MonitorExit calls.

Also log if we do end up having to clean up behind a detaching thread.

Also add a few missing "static"s.

Change-Id: I4ba1734b04b9a6dde112f3693a6dd171b42cd69c
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 00667ad..dba933a 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -2224,14 +2224,24 @@
 
   static jint MonitorEnter(JNIEnv* env, jobject java_object) {
     ScopedJniThreadState ts(env);
-    Decode<Object*>(ts, java_object)->MonitorEnter(ts.Self());
-    return ts.Self()->IsExceptionPending() ? JNI_ERR : JNI_OK;
+    Object* o = Decode<Object*>(ts, java_object);
+    o->MonitorEnter(ts.Self());
+    if (ts.Self()->IsExceptionPending()) {
+      return JNI_ERR;
+    }
+    ts.Env()->monitors.Add(o);
+    return JNI_OK;
   }
 
   static jint MonitorExit(JNIEnv* env, jobject java_object) {
     ScopedJniThreadState ts(env);
-    Decode<Object*>(ts, java_object)->MonitorExit(ts.Self());
-    return ts.Self()->IsExceptionPending() ? JNI_ERR : JNI_OK;
+    Object* o = Decode<Object*>(ts, java_object);
+    o->MonitorExit(ts.Self());
+    if (ts.Self()->IsExceptionPending()) {
+      return JNI_ERR;
+    }
+    ts.Env()->monitors.Remove(o);
+    return JNI_OK;
   }
 
   static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
diff --git a/src/thread.cc b/src/thread.cc
index 1f1952d..dea554f 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -314,7 +314,7 @@
   return NULL;
 }
 
-void SetVmData(Object* managed_thread, Thread* native_thread) {
+static void SetVmData(Object* managed_thread, Thread* native_thread) {
   gThread_vmData->SetInt(managed_thread, reinterpret_cast<uintptr_t>(native_thread));
 }
 
@@ -326,7 +326,7 @@
   return FromManagedThread(Decode<Object*>(env, java_thread));
 }
 
-size_t FixStackSize(size_t stack_size) {
+static size_t FixStackSize(size_t stack_size) {
   // A stack size of zero means "use the default".
   if (stack_size == 0) {
     stack_size = Runtime::Current()->GetDefaultStackSize();
@@ -846,35 +846,28 @@
 }
 
 // TODO: make more accessible?
-Class* FindPrimitiveClassOrDie(ClassLinker* class_linker, char descriptor) {
-  Class* c = class_linker->FindPrimitiveClass(descriptor);
-  CHECK(c != NULL) << descriptor;
-  return c;
-}
-
-// TODO: make more accessible?
-Class* FindClassOrDie(ClassLinker* class_linker, const char* descriptor) {
+static Class* FindClassOrDie(ClassLinker* class_linker, const char* descriptor) {
   Class* c = class_linker->FindSystemClass(descriptor);
   CHECK(c != NULL) << descriptor;
   return c;
 }
 
 // TODO: make more accessible?
-Field* FindFieldOrDie(Class* c, const char* name, const char* descriptor) {
+static Field* FindFieldOrDie(Class* c, const char* name, const char* descriptor) {
   Field* f = c->FindDeclaredInstanceField(name, descriptor);
   CHECK(f != NULL) << PrettyClass(c) << " " << name << " " << descriptor;
   return f;
 }
 
 // TODO: make more accessible?
-Method* FindMethodOrDie(Class* c, const char* name, const char* signature) {
+static Method* FindMethodOrDie(Class* c, const char* name, const char* signature) {
   Method* m = c->FindVirtualMethod(name, signature);
   CHECK(m != NULL) << PrettyClass(c) << " " << name << " " << signature;
   return m;
 }
 
 // TODO: make more accessible?
-Field* FindStaticFieldOrDie(Class* c, const char* name, const char* descriptor) {
+static Field* FindStaticFieldOrDie(Class* c, const char* name, const char* descriptor) {
   Field* f = c->FindDeclaredStaticField(name, descriptor);
   CHECK(f != NULL) << PrettyClass(c) << " " << name << " " << descriptor;
   return f;
@@ -974,8 +967,10 @@
   memset(&held_mutexes_[0], 0, sizeof(held_mutexes_));
 }
 
-void MonitorExitVisitor(const Object* object, void*) {
+static void MonitorExitVisitor(const Object* object, void*) {
   Object* entered_monitor = const_cast<Object*>(object);
+  LOG(WARNING) << "Calling MonitorExit on object " << object << " (" << PrettyTypeOf(object) << ")"
+               << " left locked by native thread " << *Thread::Current() << " which is detaching";
   entered_monitor->MonitorExit(Thread::Current());
 }
 
@@ -1290,7 +1285,7 @@
 };
 
 // TODO: remove this.
-uintptr_t ManglePc(uintptr_t pc) {
+static uintptr_t ManglePc(uintptr_t pc) {
   // Move the PC back 2 bytes as a call will frequently terminate the
   // decoding of a particular instruction and we want to make sure we
   // get the Dex PC of the instruction with the call and not the
@@ -1300,7 +1295,7 @@
 }
 
 // TODO: remove this.
-uintptr_t DemanglePc(uintptr_t pc) {
+static uintptr_t DemanglePc(uintptr_t pc) {
   // Revert mangling for the case where we need the PC to return to the upcall
   if (pc > 0) { pc +=  2; }
   return pc;
@@ -1873,7 +1868,7 @@
 }
 
 #if VERIFY_OBJECT_ENABLED
-void VerifyObject(const Object* obj, void*) {
+static void VerifyObject(const Object* obj, void*) {
   Runtime::Current()->GetHeap()->VerifyObject(obj);
 }