OSDN Git Service

Don't need to block in AddWeakGlobalRef and MonitorList::Add under CC.
authorHiroshi Yamauchi <yamauchi@google.com>
Fri, 6 Jan 2017 20:23:47 +0000 (12:23 -0800)
committerHiroshi Yamauchi <yamauchi@google.com>
Fri, 6 Jan 2017 20:48:15 +0000 (12:48 -0800)
CMS needs this to block because an object allocated during the GC
won't be marked and concurrent reference processing would incorrectly
clear the JNI weak ref or the monitor list weak.

But CC doesn't because of the to-space invariant, that is, when a
mutator tries to create a JNI weak ref or a monitor for an object, it
must be already marked and the concurrent reference processing
wouldn't incorrectly clear it.

Bug: 34128900
Bug: 12687968
Test: test-art-host with CC.
Change-Id: Ia87bf8ed9e604900df5ecb450c89b0ac222bef32

runtime/java_vm_ext.cc
runtime/monitor.cc

index f80c43d..e0f28ad 100644 (file)
@@ -566,7 +566,10 @@ jweak JavaVMExt::AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) {
     return nullptr;
   }
   MutexLock mu(self, *Locks::jni_weak_globals_lock_);
-  while (UNLIKELY(!MayAccessWeakGlobals(self))) {
+  // CMS needs this to block for concurrent reference processing because an object allocated during
+  // the GC won't be marked and concurrent reference processing would incorrectly clear the JNI weak
+  // ref. But CC (kUseReadBarrier == true) doesn't because of the to-space invariant.
+  while (!kUseReadBarrier && UNLIKELY(!MayAccessWeakGlobals(self))) {
     // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
     // presence of threads blocking for weak ref access.
     self->CheckEmptyCheckpoint();
index 893abd5..9c09275 100644 (file)
@@ -1361,8 +1361,10 @@ void MonitorList::BroadcastForNewMonitors() {
 void MonitorList::Add(Monitor* m) {
   Thread* self = Thread::Current();
   MutexLock mu(self, monitor_list_lock_);
-  while (UNLIKELY((!kUseReadBarrier && !allow_new_monitors_) ||
-                  (kUseReadBarrier && !self->GetWeakRefAccessEnabled()))) {
+  // CMS needs this to block for concurrent reference processing because an object allocated during
+  // the GC won't be marked and concurrent reference processing would incorrectly clear the JNI weak
+  // ref. But CC (kUseReadBarrier == true) doesn't because of the to-space invariant.
+  while (!kUseReadBarrier && UNLIKELY(!allow_new_monitors_)) {
     // Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
     // presence of threads blocking for weak ref access.
     self->CheckEmptyCheckpoint();