Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/gc_sweeper.h" | 5 #include "vm/gc_sweeper.h" |
| 6 | 6 |
| 7 #include "vm/freelist.h" | 7 #include "vm/freelist.h" |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/lockers.h" | |
| 10 #include "vm/pages.h" | 11 #include "vm/pages.h" |
| 12 #include "vm/thread_pool.h" | |
| 11 | 13 |
| 12 namespace dart { | 14 namespace dart { |
| 13 | 15 |
| 14 bool GCSweeper::SweepPage(HeapPage* page, FreeList* freelist) { | 16 bool GCSweeper::SweepPage(HeapPage* page, FreeList* freelist) { |
| 15 // Keep track whether this page is still in use. | 17 // Keep track whether this page is still in use. |
| 16 bool in_use = false; | 18 bool in_use = false; |
| 17 | 19 |
| 18 bool is_executable = (page->type() == HeapPage::kExecutable); | 20 bool is_executable = (page->type() == HeapPage::kExecutable); |
| 19 uword start = page->object_start(); | 21 uword start = page->object_start(); |
| 20 uword end = page->object_end(); | 22 uword end = page->object_end(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 uword end = page->object_end(); | 72 uword end = page->object_end(); |
| 71 while (current < end) { | 73 while (current < end) { |
| 72 RawObject* cur_obj = RawObject::FromAddr(current); | 74 RawObject* cur_obj = RawObject::FromAddr(current); |
| 73 ASSERT(!cur_obj->IsMarked()); | 75 ASSERT(!cur_obj->IsMarked()); |
| 74 current += cur_obj->Size(); | 76 current += cur_obj->Size(); |
| 75 } | 77 } |
| 76 #endif // DEBUG | 78 #endif // DEBUG |
| 77 return words_to_end; | 79 return words_to_end; |
| 78 } | 80 } |
| 79 | 81 |
| 82 | |
| 83 class SweeperTask : public ThreadPool::Task { | |
| 84 public: | |
| 85 SweeperTask(Isolate* isolate, | |
| 86 PageSpace* old_space, | |
| 87 HeapPage* first, | |
| 88 HeapPage* last, | |
| 89 FreeList* freelist) | |
| 90 : task_isolate_(isolate->ShallowCopy()), | |
| 91 old_space_(old_space), | |
| 92 first_(first), | |
| 93 last_(last), | |
| 94 freelist_(freelist) { | |
| 95 ASSERT(task_isolate_ != NULL); | |
| 96 ASSERT(first_ != NULL); | |
| 97 ASSERT(old_space_ != NULL); | |
| 98 ASSERT(last_ != NULL); | |
| 99 ASSERT(freelist_ != NULL); | |
| 100 MonitorLocker ml(old_space_->tasks_lock()); | |
| 101 old_space_->set_tasks(old_space_->tasks() + 1); | |
| 102 ml.Notify(); | |
| 103 } | |
| 104 | |
| 105 virtual void Run() { | |
| 106 Isolate::SetCurrent(task_isolate_); | |
| 107 GCSweeper sweeper(NULL); | |
| 108 | |
| 109 HeapPage* page = first_; | |
| 110 HeapPage* prev_page = NULL; | |
| 111 | |
| 112 while (page != NULL) { | |
| 113 HeapPage* next_page = page->next(); | |
| 114 if (page->type() == HeapPage::kData) { | |
| 115 bool page_in_use = true; | |
| 116 { | |
| 117 MutexLocker ml(freelist_->mutex()); | |
| 118 page_in_use = sweeper.SweepPage(page, freelist_); | |
| 119 } | |
| 120 if (page_in_use) { | |
| 121 // Notify the mutator thread that we have potentially added elements | |
| 122 // to the free list. | |
| 123 MonitorLocker ml(old_space_->tasks_lock()); | |
| 124 ml.Notify(); | |
| 125 prev_page = page; | |
| 126 } else { | |
| 127 old_space_->FreePage(page, prev_page); | |
| 128 } | |
| 129 } else { | |
| 130 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
| |
| 131 } | |
| 132 if (page == last_) break; | |
| 133 page = next_page; | |
| 134 } | |
| 135 { | |
| 136 MonitorLocker ml(old_space_->tasks_lock()); | |
| 137 old_space_->set_tasks(old_space_->tasks() - 1); | |
| 138 ml.Notify(); | |
| 139 } | |
| 140 Isolate::SetCurrent(NULL); | |
| 141 delete task_isolate_; | |
| 142 } | |
| 143 | |
| 144 private: | |
| 145 Isolate* task_isolate_; | |
| 146 PageSpace* old_space_; | |
| 147 HeapPage* first_; | |
| 148 HeapPage* last_; | |
| 149 FreeList* freelist_; | |
| 150 }; | |
| 151 | |
| 152 | |
| 153 void GCSweeper::SweepConcurrent(Isolate* isolate, | |
| 154 PageSpace* old_space, | |
| 155 HeapPage* first, | |
| 156 HeapPage* last, | |
| 157 FreeList* freelist) { | |
| 158 SweeperTask* task = | |
| 159 new SweeperTask(isolate, old_space, first, last, freelist); | |
| 160 ThreadPool* pool = Dart::thread_pool(); | |
| 161 pool->Run(task); | |
| 162 } | |
| 163 | |
| 80 } // namespace dart | 164 } // namespace dart |
| OLD | NEW |