Switch JNI globals lock to reader-writer.

Also, verifier rejected classes lock. These locks show as contended during
dex2oat, however, they're commonly only read access is required.

Change-Id: If8bb834cc69cd8c26494c87fb7f7b20d4e41cdfd
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index a854971..fd82e2c 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -949,7 +949,7 @@
 
 void MarkSweep::SweepJniWeakGlobals(IsMarkedTester is_marked, void* arg) {
   JavaVMExt* vm = Runtime::Current()->GetJavaVM();
-  MutexLock mu(Thread::Current(), vm->weak_globals_lock);
+  WriterMutexLock mu(Thread::Current(), vm->weak_globals_lock);
   for (const Object** entry : vm->weak_globals) {
     if (!is_marked(*entry, arg)) {
       *entry = kClearedJniWeakGlobal;
@@ -1032,7 +1032,7 @@
   runtime->GetMonitorList()->SweepMonitorList(VerifyIsLiveCallback, this);
 
   JavaVMExt* vm = runtime->GetJavaVM();
-  MutexLock mu(Thread::Current(), vm->weak_globals_lock);
+  ReaderMutexLock mu(Thread::Current(), vm->weak_globals_lock);
   for (const Object** entry : vm->weak_globals) {
     VerifyIsLive(*entry);
   }
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index ec0c9be..a18a261 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -91,7 +91,7 @@
   }
   JavaVMExt* vm = soa.Vm();
   IndirectReferenceTable& weak_globals = vm->weak_globals;
-  MutexLock mu(soa.Self(), vm->weak_globals_lock);
+  WriterMutexLock mu(soa.Self(), vm->weak_globals_lock);
   IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, obj);
   return reinterpret_cast<jweak>(ref);
 }
@@ -823,7 +823,7 @@
     JavaVMExt* vm = soa.Vm();
     IndirectReferenceTable& globals = vm->globals;
     Object* decoded_obj = soa.Decode<Object*>(obj);
-    MutexLock mu(soa.Self(), vm->globals_lock);
+    WriterMutexLock mu(soa.Self(), vm->globals_lock);
     IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
     return reinterpret_cast<jobject>(ref);
   }
@@ -835,7 +835,7 @@
     JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
     IndirectReferenceTable& globals = vm->globals;
     Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
-    MutexLock mu(self, vm->globals_lock);
+    WriterMutexLock mu(self, vm->globals_lock);
 
     if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
       LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
@@ -855,7 +855,7 @@
     ScopedObjectAccess soa(env);
     JavaVMExt* vm = soa.Vm();
     IndirectReferenceTable& weak_globals = vm->weak_globals;
-    MutexLock mu(soa.Self(), vm->weak_globals_lock);
+    WriterMutexLock mu(soa.Self(), vm->weak_globals_lock);
 
     if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) {
       LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
@@ -3019,11 +3019,11 @@
     os << "; pins=" << pin_table.Size();
   }
   {
-    MutexLock mu(self, globals_lock);
+    ReaderMutexLock mu(self, globals_lock);
     os << "; globals=" << globals.Capacity();
   }
   {
-    MutexLock mu(self, weak_globals_lock);
+    ReaderMutexLock mu(self, weak_globals_lock);
     if (weak_globals.Capacity() > 0) {
       os << " (plus " << weak_globals.Capacity() << " weak)";
     }
@@ -3039,11 +3039,11 @@
 void JavaVMExt::DumpReferenceTables(std::ostream& os) {
   Thread* self = Thread::Current();
   {
-    MutexLock mu(self, globals_lock);
+    ReaderMutexLock mu(self, globals_lock);
     globals.Dump(os);
   }
   {
-    MutexLock mu(self, weak_globals_lock);
+    ReaderMutexLock mu(self, weak_globals_lock);
     weak_globals.Dump(os);
   }
   {
@@ -3191,7 +3191,7 @@
       return NULL;
     }
   } else {
-    CHECK(c->GetStatus() >= Class::kStatusInitializing) << c->GetStatus() << " " << PrettyMethod(m);
+    CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
   }
 
   std::string detail;
@@ -3212,7 +3212,7 @@
 void JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) {
   Thread* self = Thread::Current();
   {
-    MutexLock mu(self, globals_lock);
+    ReaderMutexLock mu(self, globals_lock);
     globals.VisitRoots(visitor, arg);
   }
   {
diff --git a/runtime/jni_internal.h b/runtime/jni_internal.h
index f7caa0f..bad3841 100644
--- a/runtime/jni_internal.h
+++ b/runtime/jni_internal.h
@@ -112,11 +112,11 @@
   ReferenceTable pin_table GUARDED_BY(pins_lock);
 
   // JNI global references.
-  Mutex globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
+  ReaderWriterMutex globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
   IndirectReferenceTable globals GUARDED_BY(globals_lock);
 
   // JNI weak global references.
-  Mutex weak_globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
+  ReaderWriterMutex weak_globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
   IndirectReferenceTable weak_globals GUARDED_BY(weak_globals_lock);
 
   Mutex libraries_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 505e368..3178bf1 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1184,13 +1184,13 @@
   } else if (kind == kGlobal) {
     JavaVMExt* vm = Runtime::Current()->GetJavaVM();
     IndirectReferenceTable& globals = vm->globals;
-    MutexLock mu(const_cast<Thread*>(this), vm->globals_lock);
+    ReaderMutexLock mu(const_cast<Thread*>(this), vm->globals_lock);
     result = const_cast<mirror::Object*>(globals.Get(ref));
   } else {
     DCHECK_EQ(kind, kWeakGlobal);
     JavaVMExt* vm = Runtime::Current()->GetJavaVM();
     IndirectReferenceTable& weak_globals = vm->weak_globals;
-    MutexLock mu(const_cast<Thread*>(this), vm->weak_globals_lock);
+    ReaderMutexLock mu(const_cast<Thread*>(this), vm->weak_globals_lock);
     result = const_cast<mirror::Object*>(weak_globals.Get(ref));
     if (result == kClearedJniWeakGlobal) {
       // This is a special case where it's okay to return NULL.
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 4d2f36f..34a0f73 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -4202,7 +4202,7 @@
 ReaderWriterMutex* MethodVerifier::devirt_maps_lock_ = NULL;
 MethodVerifier::DevirtualizationMapTable* MethodVerifier::devirt_maps_ = NULL;
 
-Mutex* MethodVerifier::rejected_classes_lock_ = NULL;
+ReaderWriterMutex* MethodVerifier::rejected_classes_lock_ = NULL;
 MethodVerifier::RejectedClassesTable* MethodVerifier::rejected_classes_ = NULL;
 
 void MethodVerifier::Init() {
@@ -4227,9 +4227,9 @@
       devirt_maps_ = new MethodVerifier::DevirtualizationMapTable();
     }
 
-    rejected_classes_lock_ = new Mutex("verifier rejected classes lock");
+    rejected_classes_lock_ = new ReaderWriterMutex("verifier rejected classes lock");
     {
-      MutexLock mu(self, *rejected_classes_lock_);
+      WriterMutexLock mu(self, *rejected_classes_lock_);
       rejected_classes_ = new MethodVerifier::RejectedClassesTable;
     }
   }
@@ -4267,7 +4267,7 @@
     devirt_maps_lock_ = NULL;
 
     {
-      MutexLock mu(self, *rejected_classes_lock_);
+      WriterMutexLock mu(self, *rejected_classes_lock_);
       delete rejected_classes_;
       rejected_classes_ = NULL;
     }
@@ -4280,7 +4280,7 @@
 void MethodVerifier::AddRejectedClass(ClassReference ref) {
   DCHECK(Runtime::Current()->IsCompiler());
   {
-    MutexLock mu(Thread::Current(), *rejected_classes_lock_);
+    WriterMutexLock mu(Thread::Current(), *rejected_classes_lock_);
     rejected_classes_->insert(ref);
   }
   CHECK(IsClassRejected(ref));
@@ -4288,7 +4288,7 @@
 
 bool MethodVerifier::IsClassRejected(ClassReference ref) {
   DCHECK(Runtime::Current()->IsCompiler());
-  MutexLock mu(Thread::Current(), *rejected_classes_lock_);
+  ReaderMutexLock mu(Thread::Current(), *rejected_classes_lock_);
   return (rejected_classes_->find(ref) != rejected_classes_->end());
 }
 
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index d6bebc6..70442fb 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -661,7 +661,7 @@
                            const PcToConcreteMethodMap* pc_method_map)
         LOCKS_EXCLUDED(devirt_maps_lock_);
   typedef std::set<ClassReference> RejectedClassesTable;
-  static Mutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+  static ReaderWriterMutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   static RejectedClassesTable* rejected_classes_ GUARDED_BY(rejected_classes_lock_);
 
   static void AddRejectedClass(ClassReference ref)