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 |