From 65f5f247a367af9d6b9ac63767b69ecf3ab079bc Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Mon, 19 Dec 2016 11:44:47 -0800 Subject: 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 --- runtime/gc/reference_processor.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'runtime/gc/reference_processor.cc') diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc index 081be968eb..c1548365c7 100644 --- a/runtime/gc/reference_processor.cc +++ b/runtime/gc/reference_processor.cc @@ -203,7 +203,9 @@ void ReferenceProcessor::DelayReferenceReferent(ObjPtr klass, DCHECK(klass != nullptr); DCHECK(klass->IsTypeOfReferenceClass()); mirror::HeapReference* 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 -- cgit v1.2.3-59-g8ed1b