diff options
author | 2023-10-19 19:44:46 +0000 | |
---|---|---|
committer | 2023-10-23 18:36:14 +0000 | |
commit | ea6525ab31ca14d5a919a244824cc8e63ba8c767 (patch) | |
tree | 59f7572f2152a0f643ed19c66e21261c3f94fd3b /runtime/gc/reference_queue.cc | |
parent | 23bdf0606a4d97050de96dfb5a87c32587721579 (diff) |
Use release memory-order when going from gray to non-gray state
At certain places we were using `relaxed` order which allows
reordering the preceding stores of to-space references in the object
after the state change.
Bug: 302845084
Test: art/test/testrunner/testrunner.py
Change-Id: Ibbf27c8fa9eda2bf9635c69668b3750139178a30
Diffstat (limited to 'runtime/gc/reference_queue.cc')
-rw-r--r-- | runtime/gc/reference_queue.cc | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc index 6bdacaf18c..53eef9c027 100644 --- a/runtime/gc/reference_queue.cc +++ b/runtime/gc/reference_queue.cc @@ -73,7 +73,8 @@ ObjPtr<mirror::Reference> ReferenceQueue::DequeuePendingReference() { } // This must be called whenever DequeuePendingReference is called. -void ReferenceQueue::DisableReadBarrierForReference(ObjPtr<mirror::Reference> ref) { +void ReferenceQueue::DisableReadBarrierForReference(ObjPtr<mirror::Reference> ref, + std::memory_order order) { Heap* heap = Runtime::Current()->GetHeap(); if (kUseBakerReadBarrier && heap->CurrentCollectorType() == kCollectorTypeCC && heap->ConcurrentCopyingCollector()->IsActive()) { @@ -84,7 +85,7 @@ void ReferenceQueue::DisableReadBarrierForReference(ObjPtr<mirror::Reference> re collector::ConcurrentCopying* concurrent_copying = heap->ConcurrentCopyingCollector(); uint32_t rb_state = ref->GetReadBarrierState(); if (rb_state == ReadBarrier::GrayState()) { - ref->AtomicSetReadBarrierState(ReadBarrier::GrayState(), ReadBarrier::NonGrayState()); + ref->AtomicSetReadBarrierState(ReadBarrier::GrayState(), ReadBarrier::NonGrayState(), order); CHECK_EQ(ref->GetReadBarrierState(), ReadBarrier::NonGrayState()); } else { // In ConcurrentCopying::ProcessMarkStackRef() we may leave a non-gray reference in the queue @@ -158,7 +159,7 @@ void ReferenceQueue::ClearWhiteReferences(ReferenceQueue* cleared_references, } // Delay disabling the read barrier until here so that the ClearReferent call above in // transaction mode will trigger the read barrier. - DisableReadBarrierForReference(ref); + DisableReadBarrierForReference(ref, std::memory_order_relaxed); } } @@ -186,7 +187,7 @@ FinalizerStats ReferenceQueue::EnqueueFinalizerReferences(ReferenceQueue* cleare } // Delay disabling the read barrier until here so that the ClearReferent call above in // transaction mode will trigger the read barrier. - DisableReadBarrierForReference(ref->AsReference()); + DisableReadBarrierForReference(ref->AsReference(), std::memory_order_relaxed); } return FinalizerStats(num_refs, num_enqueued); } @@ -216,7 +217,7 @@ uint32_t ReferenceQueue::ForwardSoftReferences(MarkObjectVisitor* visitor) { visitor->MarkHeapReference(referent_addr, /*do_atomic_update=*/ true); ++num_refs; } - DisableReadBarrierForReference(buf[i]->AsReference()); + DisableReadBarrierForReference(buf[i]->AsReference(), std::memory_order_release); } } while (!empty); return num_refs; |