Refactor reference code into mirror namespace.
Added two new files: mirror/reference.h and mirror/reference-inl.h.
Change-Id: Ibe3ff6379aef7096ff130594535b7f7c0b7dabce
diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc
index 203701f..aee7891 100644
--- a/runtime/gc/reference_queue.cc
+++ b/runtime/gc/reference_queue.cc
@@ -20,91 +20,84 @@
#include "heap.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
+#include "mirror/reference-inl.h"
namespace art {
namespace gc {
-ReferenceQueue::ReferenceQueue(Heap* heap)
+ReferenceQueue::ReferenceQueue()
: lock_("reference queue lock"),
- heap_(heap),
list_(nullptr) {
}
-void ReferenceQueue::AtomicEnqueueIfNotEnqueued(Thread* self, mirror::Object* ref) {
+void ReferenceQueue::AtomicEnqueueIfNotEnqueued(Thread* self, mirror::Reference* ref) {
DCHECK(ref != NULL);
MutexLock mu(self, lock_);
- if (!heap_->IsEnqueued(ref)) {
+ if (!ref->IsEnqueued()) {
EnqueuePendingReference(ref);
}
}
-void ReferenceQueue::EnqueueReference(mirror::Object* ref) {
- CHECK(heap_->IsEnqueuable(ref));
+void ReferenceQueue::EnqueueReference(mirror::Reference* ref) {
+ CHECK(ref->IsEnqueuable());
EnqueuePendingReference(ref);
}
-void ReferenceQueue::EnqueuePendingReference(mirror::Object* ref) {
+void ReferenceQueue::EnqueuePendingReference(mirror::Reference* ref) {
DCHECK(ref != NULL);
- MemberOffset pending_next_offset = heap_->GetReferencePendingNextOffset();
- DCHECK_NE(pending_next_offset.Uint32Value(), 0U);
if (IsEmpty()) {
// 1 element cyclic queue, ie: Reference ref = ..; ref.pendingNext = ref;
- if (Runtime::Current()->IsActiveTransaction()) {
- ref->SetFieldObject<true>(pending_next_offset, ref, false);
- } else {
- ref->SetFieldObject<false>(pending_next_offset, ref, false);
- }
list_ = ref;
} else {
- mirror::Object* head = list_->GetFieldObject<mirror::Object>(pending_next_offset, false);
+ mirror::Reference* head = list_->GetPendingNext();
if (Runtime::Current()->IsActiveTransaction()) {
- ref->SetFieldObject<true>(pending_next_offset, head, false);
- list_->SetFieldObject<true>(pending_next_offset, ref, false);
+ ref->SetPendingNext<true>(head);
} else {
- ref->SetFieldObject<false>(pending_next_offset, head, false);
- list_->SetFieldObject<false>(pending_next_offset, ref, false);
+ ref->SetPendingNext<false>(head);
}
}
+ if (Runtime::Current()->IsActiveTransaction()) {
+ list_->SetPendingNext<true>(ref);
+ } else {
+ list_->SetPendingNext<false>(ref);
+ }
}
-mirror::Object* ReferenceQueue::DequeuePendingReference() {
+mirror::Reference* ReferenceQueue::DequeuePendingReference() {
DCHECK(!IsEmpty());
- MemberOffset pending_next_offset = heap_->GetReferencePendingNextOffset();
- mirror::Object* head = list_->GetFieldObject<mirror::Object>(pending_next_offset, false);
+ mirror::Reference* head = list_->GetPendingNext();
DCHECK(head != nullptr);
- mirror::Object* ref;
+ mirror::Reference* ref;
// Note: the following code is thread-safe because it is only called from ProcessReferences which
// is single threaded.
if (list_ == head) {
ref = list_;
list_ = nullptr;
} else {
- mirror::Object* next = head->GetFieldObject<mirror::Object>(pending_next_offset, false);
+ mirror::Reference* next = head->GetPendingNext();
if (Runtime::Current()->IsActiveTransaction()) {
- list_->SetFieldObject<true>(pending_next_offset, next, false);
+ list_->SetPendingNext<true>(next);
} else {
- list_->SetFieldObject<false>(pending_next_offset, next, false);
+ list_->SetPendingNext<false>(next);
}
ref = head;
}
if (Runtime::Current()->IsActiveTransaction()) {
- ref->SetFieldObject<true>(pending_next_offset, nullptr, false);
+ ref->SetPendingNext<true>(nullptr);
} else {
- ref->SetFieldObject<false>(pending_next_offset, nullptr, false);
+ ref->SetPendingNext<false>(nullptr);
}
return ref;
}
void ReferenceQueue::Dump(std::ostream& os) const {
- mirror::Object* cur = list_;
+ mirror::Reference* cur = list_;
os << "Reference starting at list_=" << list_ << "\n";
while (cur != nullptr) {
- mirror::Object* pending_next =
- cur->GetFieldObject<mirror::Object>(heap_->GetReferencePendingNextOffset(), false);
+ mirror::Reference* pending_next = cur->GetPendingNext();
os << "PendingNext=" << pending_next;
- if (cur->GetClass()->IsFinalizerReferenceClass()) {
- os << " Zombie=" <<
- cur->GetFieldObject<mirror::Object>(heap_->GetFinalizerReferenceZombieOffset(), false);
+ if (cur->IsFinalizerReferenceInstance()) {
+ os << " Zombie=" << cur->AsFinalizerReference()->GetZombie();
}
os << "\n";
cur = pending_next;
@@ -115,19 +108,23 @@
IsMarkedCallback* preserve_callback,
void* arg) {
while (!IsEmpty()) {
- mirror::Object* ref = DequeuePendingReference();
- mirror::Object* referent = heap_->GetReferenceReferent(ref);
+ mirror::Reference* ref = DequeuePendingReference();
+ mirror::Object* referent = ref->GetReferent();
if (referent != nullptr) {
mirror::Object* forward_address = preserve_callback(referent, arg);
if (forward_address == nullptr) {
// Referent is white, clear it.
- heap_->ClearReferenceReferent(ref);
- if (heap_->IsEnqueuable(ref)) {
+ if (Runtime::Current()->IsActiveTransaction()) {
+ ref->ClearReferent<true>();
+ } else {
+ ref->ClearReferent<false>();
+ }
+ if (ref->IsEnqueuable()) {
cleared_references.EnqueuePendingReference(ref);
}
} else if (referent != forward_address) {
// Object moved, need to updated the referent.
- heap_->SetReferenceReferent(ref, forward_address);
+ ref->SetReferent<false>(forward_address);
}
}
}
@@ -138,42 +135,43 @@
MarkObjectCallback recursive_mark_callback,
void* arg) {
while (!IsEmpty()) {
- mirror::Object* ref = DequeuePendingReference();
- mirror::Object* referent = heap_->GetReferenceReferent(ref);
+ mirror::FinalizerReference* ref = DequeuePendingReference()->AsFinalizerReference();
+ mirror::Object* referent = ref->GetReferent();
if (referent != nullptr) {
mirror::Object* forward_address = is_marked_callback(referent, arg);
// If the referent isn't marked, mark it and update the
if (forward_address == nullptr) {
forward_address = recursive_mark_callback(referent, arg);
// If the referent is non-null the reference must queuable.
- DCHECK(heap_->IsEnqueuable(ref));
+ DCHECK(ref->IsEnqueuable());
// Move the updated referent to the zombie field.
if (Runtime::Current()->IsActiveTransaction()) {
- ref->SetFieldObject<true>(heap_->GetFinalizerReferenceZombieOffset(), forward_address, false);
+ ref->SetZombie<true>(forward_address);
+ ref->ClearReferent<true>();
} else {
- ref->SetFieldObject<false>(heap_->GetFinalizerReferenceZombieOffset(), forward_address, false);
+ ref->SetZombie<false>(forward_address);
+ ref->ClearReferent<false>();
}
- heap_->ClearReferenceReferent(ref);
cleared_references.EnqueueReference(ref);
} else if (referent != forward_address) {
- heap_->SetReferenceReferent(ref, forward_address);
+ ref->SetReferent<false>(forward_address);
}
}
}
}
void ReferenceQueue::PreserveSomeSoftReferences(IsMarkedCallback preserve_callback, void* arg) {
- ReferenceQueue cleared(heap_);
+ ReferenceQueue cleared;
while (!IsEmpty()) {
- mirror::Object* ref = DequeuePendingReference();
- mirror::Object* referent = heap_->GetReferenceReferent(ref);
+ mirror::Reference* ref = DequeuePendingReference();
+ mirror::Object* referent = ref->GetReferent();
if (referent != nullptr) {
mirror::Object* forward_address = preserve_callback(referent, arg);
if (forward_address == nullptr) {
// Either the reference isn't marked or we don't wish to preserve it.
cleared.EnqueuePendingReference(ref);
} else if (forward_address != referent) {
- heap_->SetReferenceReferent(ref, forward_address);
+ ref->SetReferent<false>(forward_address);
}
}
}