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)