summaryrefslogtreecommitdiffstats
path: root/runtime/gc/reference_queue.cc
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-06-17 18:43:23 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-06-17 04:58:57 +0000
commitbfa45cdda3e65cefb61fdbe75e8f4c13087d4641 (patch)
treebc4adef3313d6e66396656d3d250e8ba44514aee /runtime/gc/reference_queue.cc
parent9506afda1776a7a14f8ec22588d6cadc2acbeee3 (diff)
parent308351ada0008b0cbe1a5afc31c302c975554ee4 (diff)
downloadart-bfa45cdda3e65cefb61fdbe75e8f4c13087d4641.tar.gz
art-bfa45cdda3e65cefb61fdbe75e8f4c13087d4641.tar.bz2
art-bfa45cdda3e65cefb61fdbe75e8f4c13087d4641.zip
Merge "Change reference processing to use heap references."
Diffstat (limited to 'runtime/gc/reference_queue.cc')
-rw-r--r--runtime/gc/reference_queue.cc82
1 files changed, 33 insertions, 49 deletions
diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc
index 3910c297a2..19476e62c2 100644
--- a/runtime/gc/reference_queue.cc
+++ b/runtime/gc/reference_queue.cc
@@ -26,8 +26,7 @@ namespace art {
namespace gc {
ReferenceQueue::ReferenceQueue()
- : lock_("reference queue lock"),
- list_(nullptr) {
+ : lock_("reference queue lock"), list_(nullptr) {
}
void ReferenceQueue::AtomicEnqueueIfNotEnqueued(Thread* self, mirror::Reference* ref) {
@@ -104,76 +103,61 @@ void ReferenceQueue::Dump(std::ostream& os) const {
}
}
-void ReferenceQueue::ClearWhiteReferences(ReferenceQueue& cleared_references,
- IsMarkedCallback* preserve_callback,
+void ReferenceQueue::ClearWhiteReferences(ReferenceQueue* cleared_references,
+ IsHeapReferenceMarkedCallback* preserve_callback,
void* arg) {
while (!IsEmpty()) {
mirror::Reference* ref = DequeuePendingReference();
- mirror::Object* referent = ref->GetReferent<kWithoutReadBarrier>();
- if (referent != nullptr) {
- mirror::Object* forward_address = preserve_callback(referent, arg);
- if (forward_address == nullptr) {
- // Referent is white, clear it.
- 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.
- ref->SetReferent<false>(forward_address);
+ mirror::HeapReference<mirror::Object>* referent_addr = ref->GetReferentReferenceAddr();
+ if (referent_addr->AsMirrorPtr() != nullptr && !preserve_callback(referent_addr, arg)) {
+ // Referent is white, clear it.
+ if (Runtime::Current()->IsActiveTransaction()) {
+ ref->ClearReferent<true>();
+ } else {
+ ref->ClearReferent<false>();
+ }
+ if (ref->IsEnqueuable()) {
+ cleared_references->EnqueuePendingReference(ref);
}
}
}
}
-void ReferenceQueue::EnqueueFinalizerReferences(ReferenceQueue& cleared_references,
- IsMarkedCallback* is_marked_callback,
+void ReferenceQueue::EnqueueFinalizerReferences(ReferenceQueue* cleared_references,
+ IsHeapReferenceMarkedCallback* is_marked_callback,
MarkObjectCallback* mark_object_callback,
void* arg) {
while (!IsEmpty()) {
mirror::FinalizerReference* ref = DequeuePendingReference()->AsFinalizerReference();
- mirror::Object* referent = ref->GetReferent<kWithoutReadBarrier>();
- 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 = mark_object_callback(referent, arg);
- // 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);
- ref->ClearReferent<true>();
- } else {
- ref->SetZombie<false>(forward_address);
- ref->ClearReferent<false>();
- }
- cleared_references.EnqueueReference(ref);
- } else if (referent != forward_address) {
- ref->SetReferent<false>(forward_address);
+ mirror::HeapReference<mirror::Object>* referent_addr = ref->GetReferentReferenceAddr();
+ if (referent_addr->AsMirrorPtr() != nullptr && !is_marked_callback(referent_addr, arg)) {
+ mirror::Object* forward_address = mark_object_callback(referent_addr->AsMirrorPtr(), arg);
+ // 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);
+ ref->ClearReferent<true>();
+ } else {
+ ref->SetZombie<false>(forward_address);
+ ref->ClearReferent<false>();
}
+ cleared_references->EnqueueReference(ref);
}
}
}
-void ReferenceQueue::ForwardSoftReferences(IsMarkedCallback* preserve_callback,
- void* arg) {
+void ReferenceQueue::ForwardSoftReferences(IsHeapReferenceMarkedCallback* preserve_callback,
+ void* arg) {
if (UNLIKELY(IsEmpty())) {
return;
}
mirror::Reference* const head = list_;
mirror::Reference* ref = head;
do {
- mirror::Object* referent = ref->GetReferent<kWithoutReadBarrier>();
- if (referent != nullptr) {
- mirror::Object* forward_address = preserve_callback(referent, arg);
- if (forward_address != nullptr && forward_address != referent) {
- ref->SetReferent<false>(forward_address);
- }
+ mirror::HeapReference<mirror::Object>* referent_addr = ref->GetReferentReferenceAddr();
+ if (referent_addr->AsMirrorPtr() != nullptr) {
+ UNUSED(preserve_callback(referent_addr, arg));
}
ref = ref->GetPendingNext();
} while (LIKELY(ref != head));