diff options
author | 2015-07-13 14:35:43 -0700 | |
---|---|---|
committer | 2015-07-14 16:45:27 -0700 | |
commit | 97509954404d031594b2ecbda607314d169d512e (patch) | |
tree | bb5371ba90d52e2f561b1dc6959584857cb84683 /runtime/gc/reference_processor.cc | |
parent | c6f3439b67962584cfb764133e192c3317f0e1fc (diff) |
Clean up GC callbacks to be virtual methods
Change-Id: Ia08034a4e5931c4fcb329c3bd3c4b1f301135735
Diffstat (limited to 'runtime/gc/reference_processor.cc')
-rw-r--r-- | runtime/gc/reference_processor.cc | 68 |
1 files changed, 24 insertions, 44 deletions
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc index c08ed0e349..256cdd2b7a 100644 --- a/runtime/gc/reference_processor.cc +++ b/runtime/gc/reference_processor.cc @@ -17,6 +17,7 @@ #include "reference_processor.h" #include "base/time_utils.h" +#include "collector/garbage_collector.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/reference-inl.h" @@ -34,7 +35,7 @@ namespace gc { static constexpr bool kAsyncReferenceQueueAdd = false; ReferenceProcessor::ReferenceProcessor() - : process_references_args_(nullptr, nullptr, nullptr), + : collector_(nullptr), preserving_references_(false), condition_("reference processor condition", *Locks::reference_processor_lock_) , soft_reference_queue_(Locks::reference_queue_soft_references_lock_), @@ -83,16 +84,14 @@ mirror::Object* ReferenceProcessor::GetReferent(Thread* self, mirror::Reference* } // Try to see if the referent is already marked by using the is_marked_callback. We can return // it to the mutator as long as the GC is not preserving references. - IsHeapReferenceMarkedCallback* const is_marked_callback = - process_references_args_.is_marked_callback_; - if (LIKELY(is_marked_callback != nullptr)) { + if (LIKELY(collector_ != nullptr)) { // If it's null it means not marked, but it could become marked if the referent is reachable // by finalizer referents. So we can not return in this case and must block. Otherwise, we // can return it to the mutator as long as the GC is not preserving references, in which // case only black nodes can be safely returned. If the GC is preserving references, the // mutator could take a white field from a grey or white node and move it somewhere else // in the heap causing corruption since this field would get swept. - if (is_marked_callback(referent_addr, process_references_args_.arg_)) { + if (collector_->IsMarkedHeapReference(referent_addr)) { if (!preserving_references_ || (LIKELY(!reference->IsFinalizerReferenceInstance()) && !reference->IsEnqueued())) { return referent_addr->AsMirrorPtr(); @@ -104,16 +103,6 @@ mirror::Object* ReferenceProcessor::GetReferent(Thread* self, mirror::Reference* return reference->GetReferent(); } -bool ReferenceProcessor::PreserveSoftReferenceCallback(mirror::HeapReference<mirror::Object>* obj, - void* arg) { - auto* const args = reinterpret_cast<ProcessReferencesArgs*>(arg); - // TODO: Add smarter logic for preserving soft references. - mirror::Object* new_obj = args->mark_callback_(obj->AsMirrorPtr(), args->arg_); - DCHECK(new_obj != nullptr); - obj->Assign(new_obj); - return true; -} - void ReferenceProcessor::StartPreservingReferences(Thread* self) { MutexLock mu(self, *Locks::reference_processor_lock_); preserving_references_ = true; @@ -129,17 +118,12 @@ void ReferenceProcessor::StopPreservingReferences(Thread* self) { // Process reference class instances and schedule finalizations. void ReferenceProcessor::ProcessReferences(bool concurrent, TimingLogger* timings, bool clear_soft_references, - IsHeapReferenceMarkedCallback* is_marked_callback, - MarkObjectCallback* mark_object_callback, - ProcessMarkStackCallback* process_mark_stack_callback, - void* arg) { + collector::GarbageCollector* collector) { TimingLogger::ScopedTiming t(concurrent ? __FUNCTION__ : "(Paused)ProcessReferences", timings); Thread* self = Thread::Current(); { MutexLock mu(self, *Locks::reference_processor_lock_); - process_references_args_.is_marked_callback_ = is_marked_callback; - process_references_args_.mark_callback_ = mark_object_callback; - process_references_args_.arg_ = arg; + collector_ = collector; if (!kUseReadBarrier) { CHECK_EQ(SlowPathEnabled(), concurrent) << "Slow path must be enabled iff concurrent"; } else { @@ -154,16 +138,16 @@ void ReferenceProcessor::ProcessReferences(bool concurrent, TimingLogger* timing if (concurrent) { StartPreservingReferences(self); } - soft_reference_queue_.ForwardSoftReferences(&PreserveSoftReferenceCallback, - &process_references_args_); - process_mark_stack_callback(arg); + // TODO: Add smarter logic for preserving soft references. + soft_reference_queue_.ForwardSoftReferences(collector); + collector->ProcessMarkStack(); if (concurrent) { StopPreservingReferences(self); } } // Clear all remaining soft and weak references with white referents. - soft_reference_queue_.ClearWhiteReferences(&cleared_references_, is_marked_callback, arg); - weak_reference_queue_.ClearWhiteReferences(&cleared_references_, is_marked_callback, arg); + soft_reference_queue_.ClearWhiteReferences(&cleared_references_, collector); + weak_reference_queue_.ClearWhiteReferences(&cleared_references_, collector); { TimingLogger::ScopedTiming t2(concurrent ? "EnqueueFinalizerReferences" : "(Paused)EnqueueFinalizerReferences", timings); @@ -171,18 +155,17 @@ void ReferenceProcessor::ProcessReferences(bool concurrent, TimingLogger* timing StartPreservingReferences(self); } // Preserve all white objects with finalize methods and schedule them for finalization. - finalizer_reference_queue_.EnqueueFinalizerReferences(&cleared_references_, is_marked_callback, - mark_object_callback, arg); - process_mark_stack_callback(arg); + finalizer_reference_queue_.EnqueueFinalizerReferences(&cleared_references_, collector); + collector->ProcessMarkStack(); if (concurrent) { StopPreservingReferences(self); } } // Clear all finalizer referent reachable soft and weak references with white referents. - soft_reference_queue_.ClearWhiteReferences(&cleared_references_, is_marked_callback, arg); - weak_reference_queue_.ClearWhiteReferences(&cleared_references_, is_marked_callback, arg); + soft_reference_queue_.ClearWhiteReferences(&cleared_references_, collector); + weak_reference_queue_.ClearWhiteReferences(&cleared_references_, collector); // Clear all phantom references with white referents. - phantom_reference_queue_.ClearWhiteReferences(&cleared_references_, is_marked_callback, arg); + phantom_reference_queue_.ClearWhiteReferences(&cleared_references_, collector); // At this point all reference queues other than the cleared references should be empty. DCHECK(soft_reference_queue_.IsEmpty()); DCHECK(weak_reference_queue_.IsEmpty()); @@ -194,12 +177,10 @@ void ReferenceProcessor::ProcessReferences(bool concurrent, TimingLogger* timing // could result in a stale is_marked_callback_ being called before the reference processing // starts since there is a small window of time where slow_path_enabled_ is enabled but the // callback isn't yet set. - process_references_args_.is_marked_callback_ = nullptr; - if (!kUseReadBarrier) { - if (concurrent) { - // Done processing, disable the slow path and broadcast to the waiters. - DisableSlowPath(self); - } + collector_ = nullptr; + if (!kUseReadBarrier && concurrent) { + // Done processing, disable the slow path and broadcast to the waiters. + DisableSlowPath(self); } } } @@ -207,13 +188,12 @@ void ReferenceProcessor::ProcessReferences(bool concurrent, TimingLogger* timing // Process the "referent" field in a java.lang.ref.Reference. If the referent has not yet been // marked, put it on the appropriate list in the heap for later processing. void ReferenceProcessor::DelayReferenceReferent(mirror::Class* klass, mirror::Reference* ref, - IsHeapReferenceMarkedCallback* is_marked_callback, - void* arg) { + collector::GarbageCollector* collector) { // klass can be the class of the old object if the visitor already updated the class of ref. DCHECK(klass != nullptr); DCHECK(klass->IsTypeOfReferenceClass()); mirror::HeapReference<mirror::Object>* referent = ref->GetReferentReferenceAddr(); - if (referent->AsMirrorPtr() != nullptr && !is_marked_callback(referent, arg)) { + if (referent->AsMirrorPtr() != nullptr && !collector->IsMarkedHeapReference(referent)) { Thread* self = Thread::Current(); // TODO: Remove these locks, and use atomic stacks for storing references? // We need to check that the references haven't already been enqueued since we can end up @@ -233,8 +213,8 @@ void ReferenceProcessor::DelayReferenceReferent(mirror::Class* klass, mirror::Re } } -void ReferenceProcessor::UpdateRoots(IsMarkedCallback* callback, void* arg) { - cleared_references_.UpdateRoots(callback, arg); +void ReferenceProcessor::UpdateRoots(IsMarkedVisitor* visitor) { + cleared_references_.UpdateRoots(visitor); } class ClearedReferenceTask : public HeapTask { |