Index: runtime/vm/gc_sweeper.cc |
=================================================================== |
--- runtime/vm/gc_sweeper.cc (revision 39568) |
+++ 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,86 @@ |
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->ShallowCopy()), |
+ 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(); |
+ if (page->type() == HeapPage::kData) { |
+ bool page_in_use = true; |
+ { |
+ MutexLocker ml(freelist_->mutex()); |
+ page_in_use = sweeper.SweepPage(page, freelist_); |
+ } |
+ if (page_in_use) { |
+ // Notify the mutator thread that we have potentially added elements |
+ // to the free list. |
+ MonitorLocker ml(old_space_->tasks_lock()); |
+ ml.Notify(); |
+ prev_page = page; |
+ } else { |
+ old_space_->FreePage(page, prev_page); |
+ } |
+ } else { |
+ prev_page = page; |
koda
2014/08/26 23:34:48
You are silently skipping non-kData pages. This sh
Ivan Posva
2014/08/27 01:00:21
Changed to an assertion that only data pages are p
|
+ } |
+ if (page == last_) break; |
+ page = next_page; |
+ } |
+ { |
+ 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, |
+ PageSpace* old_space, |
+ HeapPage* first, |
+ HeapPage* last, |
+ FreeList* freelist) { |
+ SweeperTask* task = |
+ new SweeperTask(isolate, old_space, first, last, freelist); |
+ ThreadPool* pool = Dart::thread_pool(); |
+ pool->Run(task); |
+} |
+ |
} // namespace dart |