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_marker.h" | 5 #include "vm/gc_marker.h" |
6 | 6 |
7 #include <map> | |
turnidge
2012/08/09 18:34:34
Do we get to use stl now? That's helpful.
| |
8 | |
7 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
8 #include "vm/dart_api_state.h" | 10 #include "vm/dart_api_state.h" |
9 #include "vm/isolate.h" | 11 #include "vm/isolate.h" |
10 #include "vm/pages.h" | 12 #include "vm/pages.h" |
11 #include "vm/raw_object.h" | 13 #include "vm/raw_object.h" |
12 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" |
13 #include "vm/visitor.h" | 15 #include "vm/visitor.h" |
14 | 16 |
15 namespace dart { | 17 namespace dart { |
16 | 18 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 } | 132 } |
131 | 133 |
132 MarkingStack* marking_stack() const { return marking_stack_; } | 134 MarkingStack* marking_stack() const { return marking_stack_; } |
133 | 135 |
134 void VisitPointers(RawObject** first, RawObject** last) { | 136 void VisitPointers(RawObject** first, RawObject** last) { |
135 for (RawObject** current = first; current <= last; current++) { | 137 for (RawObject** current = first; current <= last; current++) { |
136 MarkObject(*current, current); | 138 MarkObject(*current, current); |
137 } | 139 } |
138 } | 140 } |
139 | 141 |
142 void DelayWeakProperty(RawWeakProperty* raw_weak) { | |
143 RawObject* raw_key = raw_weak->ptr()->key_; | |
144 DelaySet::iterator it = delay_set_.find(raw_key); | |
145 if (it != delay_set_.end()) { | |
146 ASSERT(raw_key->IsWatched()); | |
147 WeakProperty::Push(raw_weak, &it->second); | |
148 } else { | |
149 ASSERT(!raw_key->IsWatched()); | |
150 raw_key->SetWatchedBit(); | |
151 delay_set_[raw_key] = raw_weak; | |
152 } | |
turnidge
2012/08/09 18:34:34
So what we are implementing here is a map from Key
cshapiro
2012/08/14 04:58:18
I am now using a multimap instead of a map. As su
| |
153 } | |
154 | |
155 void Finalize() { | |
156 DelaySet::iterator it = delay_set_.begin(); | |
157 for (; it != delay_set_.end(); ++it) { | |
158 while (it->second != Object::null()) { | |
159 RawWeakProperty* head = WeakProperty::Pop(&it->second); | |
160 WeakProperty::Clear(head); | |
161 } | |
162 } | |
163 } | |
164 | |
140 void set_update_store_buffers(bool val) { update_store_buffers_ = val; } | 165 void set_update_store_buffers(bool val) { update_store_buffers_ = val; } |
141 | 166 |
142 private: | 167 private: |
143 void MarkAndPush(RawObject* raw_obj) { | 168 void MarkAndPush(RawObject* raw_obj) { |
144 ASSERT(raw_obj->IsHeapObject()); | 169 ASSERT(raw_obj->IsHeapObject()); |
145 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); | 170 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
146 | 171 |
147 // Mark the object and push it on the marking stack. | 172 // Mark the object and push it on the marking stack. |
148 ASSERT(!raw_obj->IsMarked()); | 173 ASSERT(!raw_obj->IsMarked()); |
149 RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); | 174 RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); |
150 raw_obj->SetMarkBit(); | 175 raw_obj->SetMarkBit(); |
176 if (raw_obj->IsWatched()) { | |
177 DelaySet::iterator it = delay_set_.find(raw_obj); | |
178 ASSERT(it != delay_set_.end()); | |
179 RawWeakProperty* raw_weak = it->second; | |
180 while (raw_weak != WeakProperty::null()) { | |
turnidge
2012/08/09 18:34:34
Is there are reason that you use WeakProperty::Pop
cshapiro
2012/08/14 04:58:18
That was an oversight. This has been superseded b
| |
181 raw_weak->VisitPointers(this); | |
182 RawWeakProperty* next = raw_weak->ptr()->next_; | |
183 raw_weak->ptr()->next_ = WeakProperty::null(); | |
184 raw_weak = next; | |
185 } | |
186 delay_set_.erase(it); | |
187 raw_obj->ClearWatchedBit(); | |
188 } | |
151 marking_stack_->Push(raw_obj); | 189 marking_stack_->Push(raw_obj); |
152 | 190 |
153 // Update the number of used bytes on this page for fast accounting. | 191 // Update the number of used bytes on this page for fast accounting. |
154 HeapPage* page = PageSpace::PageFor(raw_obj); | 192 HeapPage* page = PageSpace::PageFor(raw_obj); |
155 page->AddUsed(raw_obj->Size()); | 193 page->AddUsed(raw_obj->Size()); |
156 | 194 |
157 // TODO(iposva): Should we mark the classes early? | 195 // TODO(iposva): Should we mark the classes early? |
158 MarkObject(raw_class, NULL); | 196 MarkObject(raw_class, NULL); |
159 } | 197 } |
160 | 198 |
(...skipping 16 matching lines...) Expand all Loading... | |
177 | 215 |
178 // TODO(iposva): merge old and code spaces. | 216 // TODO(iposva): merge old and code spaces. |
179 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); | 217 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
180 MarkAndPush(raw_obj); | 218 MarkAndPush(raw_obj); |
181 } | 219 } |
182 | 220 |
183 Heap* heap_; | 221 Heap* heap_; |
184 Heap* vm_heap_; | 222 Heap* vm_heap_; |
185 PageSpace* page_space_; | 223 PageSpace* page_space_; |
186 MarkingStack* marking_stack_; | 224 MarkingStack* marking_stack_; |
225 typedef std::map<RawObject*, RawWeakProperty*> DelaySet; | |
226 DelaySet delay_set_; | |
187 bool update_store_buffers_; | 227 bool update_store_buffers_; |
188 | 228 |
189 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); | 229 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
190 }; | 230 }; |
191 | 231 |
192 | 232 |
193 bool IsUnreachable(const RawObject* raw_obj) { | 233 bool IsUnreachable(const RawObject* raw_obj) { |
194 if (!raw_obj->IsHeapObject()) { | 234 if (!raw_obj->IsHeapObject()) { |
195 return false; | 235 return false; |
196 } | 236 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 } | 351 } |
312 } | 352 } |
313 } | 353 } |
314 | 354 |
315 | 355 |
316 void GCMarker::DrainMarkingStack(Isolate* isolate, | 356 void GCMarker::DrainMarkingStack(Isolate* isolate, |
317 MarkingVisitor* visitor) { | 357 MarkingVisitor* visitor) { |
318 visitor->set_update_store_buffers(true); | 358 visitor->set_update_store_buffers(true); |
319 while (!visitor->marking_stack()->IsEmpty()) { | 359 while (!visitor->marking_stack()->IsEmpty()) { |
320 RawObject* raw_obj = visitor->marking_stack()->Pop(); | 360 RawObject* raw_obj = visitor->marking_stack()->Pop(); |
321 raw_obj->VisitPointers(visitor); | 361 if (raw_obj->GetClassId() != kWeakProperty) { |
362 raw_obj->VisitPointers(visitor); | |
363 } else { | |
364 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); | |
365 ProcessWeakProperty(raw_weak, visitor); | |
366 } | |
322 } | 367 } |
323 visitor->set_update_store_buffers(false); | 368 visitor->set_update_store_buffers(false); |
324 } | 369 } |
325 | 370 |
326 | 371 |
372 void GCMarker::ProcessWeakProperty(RawWeakProperty* raw_weak, | |
373 MarkingVisitor* visitor) { | |
374 // The fate of the weak property is determined by its key. | |
375 RawObject* raw_key = raw_weak->ptr()->key_; | |
376 if (!raw_key->IsMarked()) { | |
377 // Key is white. Delay the weak property. | |
378 visitor->DelayWeakProperty(raw_weak); | |
379 } else { | |
380 // Key is gray or black. Make the weak property black. | |
381 raw_weak->VisitPointers(visitor); | |
382 } | |
383 } | |
384 | |
385 | |
327 void GCMarker::MarkObjects(Isolate* isolate, | 386 void GCMarker::MarkObjects(Isolate* isolate, |
328 PageSpace* page_space, | 387 PageSpace* page_space, |
329 bool invoke_api_callbacks) { | 388 bool invoke_api_callbacks) { |
330 MarkingStack marking_stack; | 389 MarkingStack marking_stack; |
331 Prologue(isolate, invoke_api_callbacks); | 390 Prologue(isolate, invoke_api_callbacks); |
332 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); | 391 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); |
333 IterateRoots(isolate, &mark, !invoke_api_callbacks); | 392 IterateRoots(isolate, &mark, !invoke_api_callbacks); |
334 DrainMarkingStack(isolate, &mark); | 393 DrainMarkingStack(isolate, &mark); |
335 IterateWeakReferences(isolate, &mark); | 394 IterateWeakReferences(isolate, &mark); |
336 MarkingWeakVisitor mark_weak; | 395 MarkingWeakVisitor mark_weak; |
337 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); | 396 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); |
397 mark.Finalize(); | |
338 Epilogue(isolate, invoke_api_callbacks); | 398 Epilogue(isolate, invoke_api_callbacks); |
339 } | 399 } |
340 | 400 |
341 } // namespace dart | 401 } // namespace dart |
OLD | NEW |