Fix CC DCHECK failure in 152-gc-and-run-finalization.
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
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index fbab73f..b889913 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -1360,9 +1360,10 @@
<< " 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;