Chromium Code Reviews| 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 |