Index: runtime/vm/gc_sweeper.cc |
=================================================================== |
--- runtime/vm/gc_sweeper.cc (revision 39573) |
+++ runtime/vm/gc_sweeper.cc (working copy) |
@@ -7,7 +7,9 @@ |
#include "vm/freelist.h" |
#include "vm/globals.h" |
#include "vm/heap.h" |
+#include "vm/lockers.h" |
#include "vm/pages.h" |
+#include "vm/thread_pool.h" |
namespace dart { |
@@ -77,4 +79,88 @@ |
return words_to_end; |
} |
+ |
+class SweeperTask : public ThreadPool::Task { |
+ public: |
+ SweeperTask(Isolate* isolate, |
+ PageSpace* old_space, |
+ HeapPage* first, |
+ HeapPage* last, |
+ FreeList* freelist) |
+ : task_isolate_(isolate), |
+ old_space_(old_space), |
+ first_(first), |
+ last_(last), |
+ freelist_(freelist) { |
+ ASSERT(task_isolate_ != NULL); |
+ ASSERT(first_ != NULL); |
+ ASSERT(old_space_ != NULL); |
+ ASSERT(last_ != NULL); |
+ ASSERT(freelist_ != NULL); |
+ MonitorLocker ml(old_space_->tasks_lock()); |
+ old_space_->set_tasks(old_space_->tasks() + 1); |
+ ml.Notify(); |
+ } |
+ |
+ virtual void Run() { |
+ Isolate::SetCurrent(task_isolate_); |
+ GCSweeper sweeper(NULL); |
+ |
+ HeapPage* page = first_; |
+ HeapPage* prev_page = NULL; |
+ |
+ while (page != NULL) { |
+ HeapPage* next_page = page->next(); |
+ ASSERT(page->type() == HeapPage::kData); |
+ bool page_in_use = true; |
+ { |
+ MutexLocker ml(freelist_->mutex()); |
+ page_in_use = sweeper.SweepPage(page, freelist_); |
+ } |
+ if (page_in_use) { |
+ prev_page = page; |
+ } else { |
+ old_space_->FreePage(page, prev_page); |
+ } |
+ { |
+ // Notify the mutator thread that we have added elements to the free |
+ // list or that more capacity is available. |
+ MonitorLocker ml(old_space_->tasks_lock()); |
+ ml.Notify(); |
+ } |
+ if (page == last_) break; |
+ page = next_page; |
+ } |
+ // This sweeper task is done. Notify the original isolate. |
+ { |
+ MonitorLocker ml(old_space_->tasks_lock()); |
+ old_space_->set_tasks(old_space_->tasks() - 1); |
+ ml.Notify(); |
+ } |
+ Isolate::SetCurrent(NULL); |
+ delete task_isolate_; |
+ } |
+ |
+ private: |
+ Isolate* task_isolate_; |
+ PageSpace* old_space_; |
+ HeapPage* first_; |
+ HeapPage* last_; |
+ FreeList* freelist_; |
+}; |
+ |
+ |
+void GCSweeper::SweepConcurrent(Isolate* isolate, |
+ HeapPage* first, |
+ HeapPage* last, |
+ FreeList* freelist) { |
+ SweeperTask* task = |
+ new SweeperTask(isolate->ShallowCopy(), |
+ isolate->heap()->old_space(), |
+ first, last, |
+ freelist); |
+ ThreadPool* pool = Dart::thread_pool(); |
+ pool->Run(task); |
+} |
+ |
} // namespace dart |