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/lockers.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 uword start = page->object_start(); | 21 uword start = page->object_start(); |
22 uword end = page->object_end(); | 22 uword end = page->object_end(); |
23 uword current = start; | 23 uword current = start; |
24 | 24 |
25 while (current < end) { | 25 while (current < end) { |
26 intptr_t obj_size; | 26 intptr_t obj_size; |
27 RawObject* raw_obj = RawObject::FromAddr(current); | 27 RawObject* raw_obj = RawObject::FromAddr(current); |
28 if (raw_obj->IsMarked()) { | 28 if (raw_obj->IsMarked()) { |
29 // Found marked object. Clear the mark bit and update swept bytes. | 29 // Found marked object. Clear the mark bit and update swept bytes. |
30 raw_obj->ClearMarkBit(); | 30 raw_obj->ClearMarkBit(); |
31 obj_size = raw_obj->Size(); | 31 obj_size = raw_obj->Size(class_table_); |
32 in_use = true; | 32 in_use = true; |
33 } else { | 33 } else { |
34 uword free_end = current + raw_obj->Size(); | 34 uword free_end = current + raw_obj->Size(class_table_); |
35 while (free_end < end) { | 35 while (free_end < end) { |
36 RawObject* next_obj = RawObject::FromAddr(free_end); | 36 RawObject* next_obj = RawObject::FromAddr(free_end); |
37 if (next_obj->IsMarked()) { | 37 if (next_obj->IsMarked()) { |
38 // Reached the end of the free block. | 38 // Reached the end of the free block. |
39 break; | 39 break; |
40 } | 40 } |
41 // Expand the free block by the size of this object. | 41 // Expand the free block by the size of this object. |
42 free_end += next_obj->Size(); | 42 free_end += next_obj->Size(class_table_); |
43 } | 43 } |
44 obj_size = free_end - current; | 44 obj_size = free_end - current; |
45 if (is_executable) { | 45 if (is_executable) { |
46 memset(reinterpret_cast<void*>(current), 0xcc, obj_size); | 46 memset(reinterpret_cast<void*>(current), 0xcc, obj_size); |
47 } else { | 47 } else { |
48 #if defined(DEBUG) | 48 #if defined(DEBUG) |
49 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size); | 49 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size); |
50 #endif // DEBUG | 50 #endif // DEBUG |
51 } | 51 } |
52 if ((current != start) || (free_end != end)) { | 52 if ((current != start) || (free_end != end)) { |
(...skipping 11 matching lines...) Expand all Loading... |
64 | 64 |
65 return in_use; | 65 return in_use; |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 intptr_t GCSweeper::SweepLargePage(HeapPage* page) { | 69 intptr_t GCSweeper::SweepLargePage(HeapPage* page) { |
70 intptr_t words_to_end = 0; | 70 intptr_t words_to_end = 0; |
71 RawObject* raw_obj = RawObject::FromAddr(page->object_start()); | 71 RawObject* raw_obj = RawObject::FromAddr(page->object_start()); |
72 if (raw_obj->IsMarked()) { | 72 if (raw_obj->IsMarked()) { |
73 raw_obj->ClearMarkBit(); | 73 raw_obj->ClearMarkBit(); |
74 words_to_end = (raw_obj->Size() >> kWordSizeLog2); | 74 words_to_end = (raw_obj->Size(class_table_) >> kWordSizeLog2); |
75 } | 75 } |
76 #ifdef DEBUG | 76 #ifdef DEBUG |
77 // String::MakeExternal and Array::MakeArray create trailing filler objects, | 77 // String::MakeExternal and Array::MakeArray create trailing filler objects, |
78 // but they are always unreachable. Verify that they are not marked. | 78 // but they are always unreachable. Verify that they are not marked. |
79 uword current = RawObject::ToAddr(raw_obj) + raw_obj->Size(); | 79 uword current = RawObject::ToAddr(raw_obj) + raw_obj->Size(class_table_); |
80 uword end = page->object_end(); | 80 uword end = page->object_end(); |
81 while (current < end) { | 81 while (current < end) { |
82 RawObject* cur_obj = RawObject::FromAddr(current); | 82 RawObject* cur_obj = RawObject::FromAddr(current); |
83 ASSERT(!cur_obj->IsMarked()); | 83 ASSERT(!cur_obj->IsMarked()); |
84 intptr_t obj_size = cur_obj->Size(); | 84 intptr_t obj_size = cur_obj->Size(class_table_); |
85 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size); | 85 memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size); |
86 current += obj_size; | 86 current += obj_size; |
87 } | 87 } |
88 #endif // DEBUG | 88 #endif // DEBUG |
89 return words_to_end; | 89 return words_to_end; |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 class SweeperTask : public ThreadPool::Task { | 93 class SweeperTask : public ThreadPool::Task { |
94 public: | 94 public: |
95 SweeperTask(Isolate* isolate, | 95 SweeperTask(ClassTable* class_table, |
96 PageSpace* old_space, | 96 PageSpace* old_space, |
97 HeapPage* first, | 97 HeapPage* first, |
98 HeapPage* last, | 98 HeapPage* last, |
99 FreeList* freelist) | 99 FreeList* freelist) |
100 : task_isolate_(isolate), | 100 : class_table_(class_table), |
101 old_space_(old_space), | 101 old_space_(old_space), |
102 first_(first), | 102 first_(first), |
103 last_(last), | 103 last_(last), |
104 freelist_(freelist) { | 104 freelist_(freelist) { |
105 ASSERT(task_isolate_ != NULL); | 105 ASSERT(class_table_ != NULL); |
106 ASSERT(first_ != NULL); | 106 ASSERT(first_ != NULL); |
107 ASSERT(old_space_ != NULL); | 107 ASSERT(old_space_ != NULL); |
108 ASSERT(last_ != NULL); | 108 ASSERT(last_ != NULL); |
109 ASSERT(freelist_ != NULL); | 109 ASSERT(freelist_ != NULL); |
110 MonitorLocker ml(old_space_->tasks_lock()); | 110 MonitorLocker ml(old_space_->tasks_lock()); |
111 old_space_->set_tasks(old_space_->tasks() + 1); | 111 old_space_->set_tasks(old_space_->tasks() + 1); |
112 ml.Notify(); | 112 ml.Notify(); |
113 } | 113 } |
114 | 114 |
115 virtual void Run() { | 115 virtual void Run() { |
116 Isolate::SetCurrent(task_isolate_); | 116 GCSweeper sweeper(class_table_); |
117 GCSweeper sweeper; | |
118 | 117 |
119 HeapPage* page = first_; | 118 HeapPage* page = first_; |
120 HeapPage* prev_page = NULL; | 119 HeapPage* prev_page = NULL; |
121 | 120 |
122 while (page != NULL) { | 121 while (page != NULL) { |
123 HeapPage* next_page = page->next(); | 122 HeapPage* next_page = page->next(); |
124 ASSERT(page->type() == HeapPage::kData); | 123 ASSERT(page->type() == HeapPage::kData); |
125 bool page_in_use = sweeper.SweepPage(page, freelist_, false); | 124 bool page_in_use = sweeper.SweepPage(page, freelist_, false); |
126 if (page_in_use) { | 125 if (page_in_use) { |
127 prev_page = page; | 126 prev_page = page; |
128 } else { | 127 } else { |
129 old_space_->FreePage(page, prev_page); | 128 old_space_->FreePage(page, prev_page); |
130 } | 129 } |
131 { | 130 { |
132 // Notify the mutator thread that we have added elements to the free | 131 // Notify the mutator thread that we have added elements to the free |
133 // list or that more capacity is available. | 132 // list or that more capacity is available. |
134 MonitorLocker ml(old_space_->tasks_lock()); | 133 MonitorLocker ml(old_space_->tasks_lock()); |
135 ml.Notify(); | 134 ml.Notify(); |
136 } | 135 } |
137 if (page == last_) break; | 136 if (page == last_) break; |
138 page = next_page; | 137 page = next_page; |
139 } | 138 } |
140 // This sweeper task is done. Notify the original isolate. | 139 // This sweeper task is done. Notify the original isolate. |
141 { | 140 { |
142 MonitorLocker ml(old_space_->tasks_lock()); | 141 MonitorLocker ml(old_space_->tasks_lock()); |
143 old_space_->set_tasks(old_space_->tasks() - 1); | 142 old_space_->set_tasks(old_space_->tasks() - 1); |
144 ml.Notify(); | 143 ml.Notify(); |
145 } | 144 } |
146 Isolate::SetCurrent(NULL); | |
147 delete task_isolate_; | |
148 } | 145 } |
149 | 146 |
150 private: | 147 private: |
151 Isolate* task_isolate_; | 148 ClassTable* class_table_; |
152 PageSpace* old_space_; | 149 PageSpace* old_space_; |
153 HeapPage* first_; | 150 HeapPage* first_; |
154 HeapPage* last_; | 151 HeapPage* last_; |
155 FreeList* freelist_; | 152 FreeList* freelist_; |
156 }; | 153 }; |
157 | 154 |
158 | 155 |
159 void GCSweeper::SweepConcurrent(Isolate* isolate, | 156 void GCSweeper::SweepConcurrent(Isolate* isolate, |
160 HeapPage* first, | 157 HeapPage* first, |
161 HeapPage* last, | 158 HeapPage* last, |
162 FreeList* freelist) { | 159 FreeList* freelist) { |
163 SweeperTask* task = | 160 SweeperTask* task = |
164 new SweeperTask(isolate->ShallowCopy(), | 161 new SweeperTask(isolate->class_table(), |
165 isolate->heap()->old_space(), | 162 isolate->heap()->old_space(), |
166 first, last, | 163 first, last, |
167 freelist); | 164 freelist); |
168 ThreadPool* pool = Dart::thread_pool(); | 165 ThreadPool* pool = Dart::thread_pool(); |
169 pool->Run(task); | 166 pool->Run(task); |
170 } | 167 } |
171 | 168 |
172 } // namespace dart | 169 } // namespace dart |
OLD | NEW |