Fix race condition btw DelayReferenceRefernent vs Reference.clear().
Rename IsMarkedHeapReference to IsNullOrMarkedHeapReference.
Move the null check from the caller of IsMarkedHeapReference into
IsNullOrMarkedHeapReference.
Make sure that the referent is only loaded once between the null
check and the IsMarked call.
Use a CAS in ConcurrentCopying::IsNullOrMarkedHeapReference when
called from DelayReferenceRefernent.
Bug: 33389022
Test: test-art-host without and with CC.
Change-Id: I20edab4dac2a4bb02dbb72af0f09de77b55ac08e
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index 081be96..c154836 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -203,7 +203,9 @@
DCHECK(klass != nullptr);
DCHECK(klass->IsTypeOfReferenceClass());
mirror::HeapReference<mirror::Object>* referent = ref->GetReferentReferenceAddr();
- if (referent->AsMirrorPtr() != nullptr && !collector->IsMarkedHeapReference(referent)) {
+ // do_atomic_update needs to be true because this happens outside of the reference processing
+ // phase.
+ if (!collector->IsNullOrMarkedHeapReference(referent, /*do_atomic_update*/true)) {
Thread* self = Thread::Current();
// TODO: Remove these locks, and use atomic stacks for storing references?
// We need to check that the references haven't already been enqueued since we can end up