diff options
author | 2016-01-15 14:08:05 -0800 | |
---|---|---|
committer | 2016-01-28 15:34:19 -0800 | |
commit | c4695dfdab80c280c98a89c20e027a3804191585 (patch) | |
tree | b78f388ac75edd9f02abfcae68aad7d445af75d1 /runtime/gc/reference_queue.cc | |
parent | 97f4bc04b61d5cf78b0820dbf18e999b20d7a108 (diff) |
Always use pendingNext to test enqueability of references.
Also clean up a misleading comment in a reference queue test.
Bug: 24404957
Change-Id: Ieea4788039ecef73cba1871fb480a439bf65b499
Diffstat (limited to 'runtime/gc/reference_queue.cc')
-rw-r--r-- | runtime/gc/reference_queue.cc | 29 |
1 files changed, 10 insertions, 19 deletions
diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc index 67dcc2d1a8..03ab9a1a73 100644 --- a/runtime/gc/reference_queue.cc +++ b/runtime/gc/reference_queue.cc @@ -32,42 +32,37 @@ ReferenceQueue::ReferenceQueue(Mutex* lock) : lock_(lock), list_(nullptr) { void ReferenceQueue::AtomicEnqueueIfNotEnqueued(Thread* self, mirror::Reference* ref) { DCHECK(ref != nullptr); MutexLock mu(self, *lock_); - if (!ref->IsEnqueued()) { - EnqueuePendingReference(ref); + if (ref->IsUnprocessed()) { + EnqueueReference(ref); } } void ReferenceQueue::EnqueueReference(mirror::Reference* ref) { - CHECK(ref->IsEnqueuable()); - EnqueuePendingReference(ref); -} - -void ReferenceQueue::EnqueuePendingReference(mirror::Reference* ref) { DCHECK(ref != nullptr); + CHECK(ref->IsUnprocessed()); if (IsEmpty()) { // 1 element cyclic queue, ie: Reference ref = ..; ref.pendingNext = ref; list_ = ref; } else { mirror::Reference* head = list_->GetPendingNext(); + DCHECK(head != nullptr); ref->SetPendingNext(head); } + // Add the reference in the middle to preserve the cycle. list_->SetPendingNext(ref); } mirror::Reference* ReferenceQueue::DequeuePendingReference() { DCHECK(!IsEmpty()); - mirror::Reference* head = list_->GetPendingNext(); - DCHECK(head != nullptr); - mirror::Reference* ref; + mirror::Reference* ref = list_->GetPendingNext(); + DCHECK(ref != nullptr); // Note: the following code is thread-safe because it is only called from ProcessReferences which // is single threaded. - if (list_ == head) { - ref = list_; + if (list_ == ref) { list_ = nullptr; } else { - mirror::Reference* next = head->GetPendingNext(); + mirror::Reference* next = ref->GetPendingNext(); list_->SetPendingNext(next); - ref = head; } ref->SetPendingNext(nullptr); Heap* heap = Runtime::Current()->GetHeap(); @@ -152,9 +147,7 @@ void ReferenceQueue::ClearWhiteReferences(ReferenceQueue* cleared_references, } else { ref->ClearReferent<false>(); } - if (ref->IsEnqueuable()) { - cleared_references->EnqueuePendingReference(ref); - } + cleared_references->EnqueueReference(ref); } } } @@ -167,8 +160,6 @@ void ReferenceQueue::EnqueueFinalizerReferences(ReferenceQueue* cleared_referenc if (referent_addr->AsMirrorPtr() != nullptr && !collector->IsMarkedHeapReference(referent_addr)) { mirror::Object* forward_address = collector->MarkObject(referent_addr->AsMirrorPtr()); - // If the referent is non-null the reference must queuable. - DCHECK(ref->IsEnqueuable()); // Move the updated referent to the zombie field. if (Runtime::Current()->IsActiveTransaction()) { ref->SetZombie<true>(forward_address); |