OSDN Git Service

Fix CC DCHECK failure in 152-gc-and-run-finalization.
authorHiroshi Yamauchi <yamauchi@google.com>
Wed, 7 Dec 2016 00:46:37 +0000 (16:46 -0800)
committerHiroshi Yamauchi <yamauchi@google.com>
Wed, 7 Dec 2016 19:43:38 +0000 (11:43 -0800)
This fixes the second crash trace in 33389022#1.

Load the referent once which avoids passing nullptr to IsMarked().

It's still racey but it's okay because leaving a Reference with a
cleared referent gray is fine, if not optimal performance-wise.

Bug: 33389022
Bug: 12687968
Test: test-art-host with CC. 152 in a loop.

Change-Id: I2b389022175e38bdc40518b9553a2f5180dbc649

runtime/gc/collector/concurrent_copying.cc

index fbab73f..b889913 100644 (file)
@@ -1360,9 +1360,10 @@ inline void ConcurrentCopying::ProcessMarkStackRef(mirror::Object* to_ref) {
         << " is_marked=" << IsMarked(to_ref);
   }
 #ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
+  mirror::Object* referent = nullptr;
   if (UNLIKELY((to_ref->GetClass<kVerifyNone, kWithoutReadBarrier>()->IsTypeOfReferenceClass() &&
-                to_ref->AsReference()->GetReferent<kWithoutReadBarrier>() != nullptr &&
-                !IsInToSpace(to_ref->AsReference()->GetReferent<kWithoutReadBarrier>())))) {
+                (referent = to_ref->AsReference()->GetReferent<kWithoutReadBarrier>()) != nullptr &&
+                !IsInToSpace(referent)))) {
     // Leave this reference gray in the queue so that GetReferent() will trigger a read barrier. We
     // will change it to white later in ReferenceQueue::DequeuePendingReference().
     DCHECK(to_ref->AsReference()->GetPendingNext() != nullptr) << "Left unenqueued ref gray " << to_ref;