From c4695dfdab80c280c98a89c20e027a3804191585 Mon Sep 17 00:00:00 2001 From: Richard Uhler Date: Fri, 15 Jan 2016 14:08:05 -0800 Subject: Always use pendingNext to test enqueability of references. Also clean up a misleading comment in a reference queue test. Bug: 24404957 Change-Id: Ieea4788039ecef73cba1871fb480a439bf65b499 --- runtime/mirror/reference.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'runtime/mirror/reference.h') diff --git a/runtime/mirror/reference.h b/runtime/mirror/reference.h index 5e467ab94a..3baa12e40b 100644 --- a/runtime/mirror/reference.h +++ b/runtime/mirror/reference.h @@ -75,9 +75,7 @@ class MANAGED Reference : public Object { void ClearReferent() SHARED_REQUIRES(Locks::mutator_lock_) { SetFieldObjectVolatile(ReferentOffset(), nullptr); } - // Volatile read/write is not necessary since the java pending next is only accessed from - // the java threads for cleared references. Once these cleared references have a null referent, - // we never end up reading their pending next from the GC again. + Reference* GetPendingNext() SHARED_REQUIRES(Locks::mutator_lock_) { return GetFieldObject(PendingNextOffset()); } @@ -91,14 +89,22 @@ class MANAGED Reference : public Object { } } - bool IsEnqueued() SHARED_REQUIRES(Locks::mutator_lock_) { - // Since the references are stored as cyclic lists it means that once enqueued, the pending - // next is always non-null. - return GetPendingNext() != nullptr; + // Returns true if the reference's pendingNext is null, indicating it is + // okay to process this reference. + // + // If pendingNext is not null, then one of the following cases holds: + // 1. The reference has already been enqueued to a java ReferenceQueue. In + // this case the referent should not be considered for reference processing + // ever again. + // 2. The reference is currently part of a list of references that may + // shortly be enqueued on a java ReferenceQueue. In this case the reference + // should not be processed again until and unless the reference has been + // removed from the list after having determined the reference is not ready + // to be enqueued on a java ReferenceQueue. + bool IsUnprocessed() SHARED_REQUIRES(Locks::mutator_lock_) { + return GetPendingNext() == nullptr; } - bool IsEnqueuable() SHARED_REQUIRES(Locks::mutator_lock_); - template static Class* GetJavaLangRefReference() SHARED_REQUIRES(Locks::mutator_lock_) { DCHECK(!java_lang_ref_Reference_.IsNull()); @@ -115,9 +121,9 @@ class MANAGED Reference : public Object { } // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". - HeapReference pending_next_; // Note this is Java volatile: - HeapReference queue_; // Note this is Java volatile: - HeapReference queue_next_; // Note this is Java volatile: + HeapReference pending_next_; + HeapReference queue_; + HeapReference queue_next_; HeapReference referent_; // Note this is Java volatile: static GcRoot java_lang_ref_Reference_; -- cgit v1.2.3-59-g8ed1b