| Index: runtime/vm/gc_marker.cc
|
| diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
|
| index 1d151d03c4e6298710b59c8366f223a2a5bee4fc..aa3d8d62696b3255698f04a926dc2b2d3bc1fb7f 100644
|
| --- a/runtime/vm/gc_marker.cc
|
| +++ b/runtime/vm/gc_marker.cc
|
| @@ -16,6 +16,7 @@
|
| #include "vm/raw_object.h"
|
| #include "vm/stack_frame.h"
|
| #include "vm/store_buffer.h"
|
| +#include "vm/thread_barrier.h"
|
| #include "vm/thread_pool.h"
|
| #include "vm/visitor.h"
|
| #include "vm/object_id_ring.h"
|
| @@ -553,6 +554,7 @@ class MarkTask : public ThreadPool::Task {
|
| PageSpace* page_space,
|
| MarkingStack* marking_stack,
|
| DelaySet* delay_set,
|
| + ThreadBarrier* barrier,
|
| bool collect_code,
|
| bool visit_prologue_weak_persistent_handles)
|
| : marker_(marker),
|
| @@ -561,6 +563,7 @@ class MarkTask : public ThreadPool::Task {
|
| page_space_(page_space),
|
| marking_stack_(marking_stack),
|
| delay_set_(delay_set),
|
| + barrier_(barrier),
|
| collect_code_(collect_code),
|
| visit_prologue_weak_persistent_handles_(
|
| visit_prologue_weak_persistent_handles) {
|
| @@ -580,15 +583,15 @@ class MarkTask : public ThreadPool::Task {
|
| marker_->IterateRoots(isolate_, &visitor,
|
| visit_prologue_weak_persistent_handles_);
|
| visitor.DrainMarkingStack();
|
| - marker_->TaskSync();
|
| + barrier_->Sync();
|
| // Phase 2: Weak processing and follow-up marking on main thread.
|
| - marker_->TaskSync();
|
| + barrier_->Sync();
|
| // Phase 3: Finalize results from all markers (detach code, etc.).
|
| marker_->FinalizeResultsFrom(&visitor);
|
| }
|
| Thread::ExitIsolateAsHelper(true);
|
| // This task is done. Notify the original thread.
|
| - marker_->TaskNotifyDone();
|
| + barrier_->Exit();
|
| }
|
|
|
| private:
|
| @@ -598,6 +601,7 @@ class MarkTask : public ThreadPool::Task {
|
| PageSpace* page_space_;
|
| MarkingStack* marking_stack_;
|
| DelaySet* delay_set_;
|
| + ThreadBarrier* barrier_;
|
| bool collect_code_;
|
| bool visit_prologue_weak_persistent_handles_;
|
|
|
| @@ -605,39 +609,6 @@ class MarkTask : public ThreadPool::Task {
|
| };
|
|
|
|
|
| -void GCMarker::MainSync(intptr_t num_tasks) {
|
| - MonitorLocker ml(&monitor_);
|
| - while (done_count_ < num_tasks) {
|
| - ml.Wait();
|
| - }
|
| - done_count_ = 0; // Tasks may now resume.
|
| - // TODO(koda): Add barrier utility with two condition variables to allow for
|
| - // Notify rather than NotifyAll. Also use it for safepoints.
|
| - ml.NotifyAll();
|
| -}
|
| -
|
| -
|
| -void GCMarker::TaskNotifyDone() {
|
| - MonitorLocker ml(&monitor_);
|
| - ++done_count_;
|
| - // TODO(koda): Add barrier utility with two condition variables to allow for
|
| - // Notify rather than NotifyAll. Also use it for safepoints.
|
| - ml.NotifyAll();
|
| -}
|
| -
|
| -
|
| -void GCMarker::TaskSync() {
|
| - MonitorLocker ml(&monitor_);
|
| - ++done_count_;
|
| - ml.NotifyAll(); // Notify controller that this thread reached end of phase.
|
| - ASSERT(done_count_ > 0);
|
| - while (done_count_ > 0) {
|
| - // Wait for the controller to release into next phase.
|
| - ml.Wait();
|
| - }
|
| -}
|
| -
|
| -
|
| void GCMarker::FinalizeResultsFrom(MarkingVisitor* visitor) {
|
| {
|
| MonitorLocker ml(&monitor_);
|
| @@ -683,14 +654,15 @@ void GCMarker::MarkObjects(Isolate* isolate,
|
| // 2. concurrent tasks, after synchronizing headers.
|
| FATAL("Multiple marking tasks not yet supported");
|
| }
|
| + ThreadBarrier barrier(num_tasks + 1); // +1 for the main thread.
|
| // Phase 1: Populate and drain marking stack in task.
|
| MarkTask* mark_task =
|
| new MarkTask(this, isolate, heap_, page_space, &marking_stack,
|
| - &delay_set, collect_code,
|
| + &delay_set, &barrier, collect_code,
|
| visit_prologue_weak_persistent_handles);
|
| ThreadPool* pool = Dart::thread_pool();
|
| pool->Run(mark_task);
|
| - MainSync(num_tasks);
|
| + barrier.Sync();
|
| // Phase 2: Weak processing and follow-up marking on main thread.
|
| SkippedCodeFunctions* skipped_code_functions =
|
| collect_code ? new(zone) SkippedCodeFunctions() : NULL;
|
| @@ -700,11 +672,10 @@ void GCMarker::MarkObjects(Isolate* isolate,
|
| MarkingWeakVisitor mark_weak;
|
| IterateWeakRoots(isolate, &mark_weak,
|
| !visit_prologue_weak_persistent_handles);
|
| - MainSync(num_tasks);
|
| + barrier.Sync();
|
| // Phase 3: Finalize results from all markers (detach code, etc.).
|
| FinalizeResultsFrom(&mark);
|
| - MainSync(num_tasks);
|
| - // Finalization complete and all tasks exited.
|
| + barrier.Exit();
|
| }
|
| delay_set.ClearReferences();
|
| ProcessWeakTables(page_space);
|
|
|