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> |
| 8 #include <utility> |
| 9 |
7 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
8 #include "vm/dart_api_state.h" | 11 #include "vm/dart_api_state.h" |
9 #include "vm/isolate.h" | 12 #include "vm/isolate.h" |
10 #include "vm/pages.h" | 13 #include "vm/pages.h" |
11 #include "vm/raw_object.h" | 14 #include "vm/raw_object.h" |
12 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
13 #include "vm/visitor.h" | 16 #include "vm/visitor.h" |
14 | 17 |
15 namespace dart { | 18 namespace dart { |
16 | 19 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } | 133 } |
131 | 134 |
132 MarkingStack* marking_stack() const { return marking_stack_; } | 135 MarkingStack* marking_stack() const { return marking_stack_; } |
133 | 136 |
134 void VisitPointers(RawObject** first, RawObject** last) { | 137 void VisitPointers(RawObject** first, RawObject** last) { |
135 for (RawObject** current = first; current <= last; current++) { | 138 for (RawObject** current = first; current <= last; current++) { |
136 MarkObject(*current, current); | 139 MarkObject(*current, current); |
137 } | 140 } |
138 } | 141 } |
139 | 142 |
| 143 void DelayWeakProperty(RawWeakProperty* raw_weak) { |
| 144 RawObject* raw_key = raw_weak->ptr()->key_; |
| 145 DelaySet::iterator it = delay_set_.find(raw_key); |
| 146 if (it != delay_set_.end()) { |
| 147 ASSERT(raw_key->IsWatched()); |
| 148 } else { |
| 149 ASSERT(!raw_key->IsWatched()); |
| 150 raw_key->SetWatchedBit(); |
| 151 } |
| 152 delay_set_.insert(std::make_pair(raw_key, raw_weak)); |
| 153 } |
| 154 |
| 155 void Finalize() { |
| 156 DelaySet::iterator it = delay_set_.begin(); |
| 157 for (; it != delay_set_.end(); ++it) { |
| 158 WeakProperty::Clear(it->second); |
| 159 } |
| 160 } |
| 161 |
140 void set_update_store_buffers(bool val) { update_store_buffers_ = val; } | 162 void set_update_store_buffers(bool val) { update_store_buffers_ = val; } |
141 | 163 |
142 private: | 164 private: |
143 void MarkAndPush(RawObject* raw_obj) { | 165 void MarkAndPush(RawObject* raw_obj) { |
144 ASSERT(raw_obj->IsHeapObject()); | 166 ASSERT(raw_obj->IsHeapObject()); |
145 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); | 167 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
146 | 168 |
147 // Mark the object and push it on the marking stack. | 169 // Mark the object and push it on the marking stack. |
148 ASSERT(!raw_obj->IsMarked()); | 170 ASSERT(!raw_obj->IsMarked()); |
149 RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); | 171 RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); |
150 raw_obj->SetMarkBit(); | 172 raw_obj->SetMarkBit(); |
| 173 if (raw_obj->IsWatched()) { |
| 174 std::pair<DelaySet::iterator, DelaySet::iterator> ret; |
| 175 // Visit all elements with a key equal to raw_obj. |
| 176 ret = delay_set_.equal_range(raw_obj); |
| 177 for (DelaySet::iterator it = ret.first; it != ret.second; ++it) { |
| 178 it->second->VisitPointers(this); |
| 179 } |
| 180 delay_set_.erase(ret.first, ret.second); |
| 181 raw_obj->ClearWatchedBit(); |
| 182 } |
151 marking_stack_->Push(raw_obj); | 183 marking_stack_->Push(raw_obj); |
152 | 184 |
153 // Update the number of used bytes on this page for fast accounting. | 185 // Update the number of used bytes on this page for fast accounting. |
154 HeapPage* page = PageSpace::PageFor(raw_obj); | 186 HeapPage* page = PageSpace::PageFor(raw_obj); |
155 page->AddUsed(raw_obj->Size()); | 187 page->AddUsed(raw_obj->Size()); |
156 | 188 |
157 // TODO(iposva): Should we mark the classes early? | 189 // TODO(iposva): Should we mark the classes early? |
158 MarkObject(raw_class, NULL); | 190 MarkObject(raw_class, NULL); |
159 } | 191 } |
160 | 192 |
(...skipping 16 matching lines...) Expand all Loading... |
177 | 209 |
178 // TODO(iposva): merge old and code spaces. | 210 // TODO(iposva): merge old and code spaces. |
179 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); | 211 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
180 MarkAndPush(raw_obj); | 212 MarkAndPush(raw_obj); |
181 } | 213 } |
182 | 214 |
183 Heap* heap_; | 215 Heap* heap_; |
184 Heap* vm_heap_; | 216 Heap* vm_heap_; |
185 PageSpace* page_space_; | 217 PageSpace* page_space_; |
186 MarkingStack* marking_stack_; | 218 MarkingStack* marking_stack_; |
| 219 typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet; |
| 220 DelaySet delay_set_; |
187 bool update_store_buffers_; | 221 bool update_store_buffers_; |
188 | 222 |
189 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); | 223 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
190 }; | 224 }; |
191 | 225 |
192 | 226 |
193 bool IsUnreachable(const RawObject* raw_obj) { | 227 bool IsUnreachable(const RawObject* raw_obj) { |
194 if (!raw_obj->IsHeapObject()) { | 228 if (!raw_obj->IsHeapObject()) { |
195 return false; | 229 return false; |
196 } | 230 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 } | 345 } |
312 } | 346 } |
313 } | 347 } |
314 | 348 |
315 | 349 |
316 void GCMarker::DrainMarkingStack(Isolate* isolate, | 350 void GCMarker::DrainMarkingStack(Isolate* isolate, |
317 MarkingVisitor* visitor) { | 351 MarkingVisitor* visitor) { |
318 visitor->set_update_store_buffers(true); | 352 visitor->set_update_store_buffers(true); |
319 while (!visitor->marking_stack()->IsEmpty()) { | 353 while (!visitor->marking_stack()->IsEmpty()) { |
320 RawObject* raw_obj = visitor->marking_stack()->Pop(); | 354 RawObject* raw_obj = visitor->marking_stack()->Pop(); |
321 raw_obj->VisitPointers(visitor); | 355 if (raw_obj->GetClassId() != kWeakPropertyCid) { |
| 356 raw_obj->VisitPointers(visitor); |
| 357 } else { |
| 358 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); |
| 359 ProcessWeakProperty(raw_weak, visitor); |
| 360 } |
322 } | 361 } |
323 visitor->set_update_store_buffers(false); | 362 visitor->set_update_store_buffers(false); |
324 } | 363 } |
325 | 364 |
326 | 365 |
| 366 void GCMarker::ProcessWeakProperty(RawWeakProperty* raw_weak, |
| 367 MarkingVisitor* visitor) { |
| 368 // The fate of the weak property is determined by its key. |
| 369 RawObject* raw_key = raw_weak->ptr()->key_; |
| 370 if (!raw_key->IsMarked()) { |
| 371 // Key is white. Delay the weak property. |
| 372 visitor->DelayWeakProperty(raw_weak); |
| 373 } else { |
| 374 // Key is gray or black. Make the weak property black. |
| 375 raw_weak->VisitPointers(visitor); |
| 376 } |
| 377 } |
| 378 |
| 379 |
327 void GCMarker::MarkObjects(Isolate* isolate, | 380 void GCMarker::MarkObjects(Isolate* isolate, |
328 PageSpace* page_space, | 381 PageSpace* page_space, |
329 bool invoke_api_callbacks) { | 382 bool invoke_api_callbacks) { |
330 MarkingStack marking_stack; | 383 MarkingStack marking_stack; |
331 Prologue(isolate, invoke_api_callbacks); | 384 Prologue(isolate, invoke_api_callbacks); |
332 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); | 385 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); |
333 IterateRoots(isolate, &mark, !invoke_api_callbacks); | 386 IterateRoots(isolate, &mark, !invoke_api_callbacks); |
334 DrainMarkingStack(isolate, &mark); | 387 DrainMarkingStack(isolate, &mark); |
335 IterateWeakReferences(isolate, &mark); | 388 IterateWeakReferences(isolate, &mark); |
336 MarkingWeakVisitor mark_weak; | 389 MarkingWeakVisitor mark_weak; |
337 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); | 390 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); |
| 391 mark.Finalize(); |
338 Epilogue(isolate, invoke_api_callbacks); | 392 Epilogue(isolate, invoke_api_callbacks); |
339 } | 393 } |
340 | 394 |
341 } // namespace dart | 395 } // namespace dart |
OLD | NEW |