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_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 |