Chromium Code Reviews| Index: runtime/vm/gc_marker.cc |
| diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc |
| index 55199b460c2b87da057836677eb93cdf68f6f4a2..12fe96ec2ffe79e22d4a58c53a32c13792e8e71a 100644 |
| --- a/runtime/vm/gc_marker.cc |
| +++ b/runtime/vm/gc_marker.cc |
| @@ -4,6 +4,8 @@ |
| #include "vm/gc_marker.h" |
| +#include <map> |
|
turnidge
2012/08/09 18:34:34
Do we get to use stl now? That's helpful.
|
| + |
| #include "vm/allocation.h" |
| #include "vm/dart_api_state.h" |
| #include "vm/isolate.h" |
| @@ -137,6 +139,29 @@ class MarkingVisitor : public ObjectPointerVisitor { |
| } |
| } |
| + void DelayWeakProperty(RawWeakProperty* raw_weak) { |
| + RawObject* raw_key = raw_weak->ptr()->key_; |
| + DelaySet::iterator it = delay_set_.find(raw_key); |
| + if (it != delay_set_.end()) { |
| + ASSERT(raw_key->IsWatched()); |
| + WeakProperty::Push(raw_weak, &it->second); |
| + } else { |
| + ASSERT(!raw_key->IsWatched()); |
| + raw_key->SetWatchedBit(); |
| + delay_set_[raw_key] = raw_weak; |
| + } |
|
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
|
| + } |
| + |
| + void Finalize() { |
| + DelaySet::iterator it = delay_set_.begin(); |
| + for (; it != delay_set_.end(); ++it) { |
| + while (it->second != Object::null()) { |
| + RawWeakProperty* head = WeakProperty::Pop(&it->second); |
| + WeakProperty::Clear(head); |
| + } |
| + } |
| + } |
| + |
| void set_update_store_buffers(bool val) { update_store_buffers_ = val; } |
| private: |
| @@ -148,6 +173,19 @@ class MarkingVisitor : public ObjectPointerVisitor { |
| ASSERT(!raw_obj->IsMarked()); |
| RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); |
| raw_obj->SetMarkBit(); |
| + if (raw_obj->IsWatched()) { |
| + DelaySet::iterator it = delay_set_.find(raw_obj); |
| + ASSERT(it != delay_set_.end()); |
| + RawWeakProperty* raw_weak = it->second; |
| + 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
|
| + raw_weak->VisitPointers(this); |
| + RawWeakProperty* next = raw_weak->ptr()->next_; |
| + raw_weak->ptr()->next_ = WeakProperty::null(); |
| + raw_weak = next; |
| + } |
| + delay_set_.erase(it); |
| + raw_obj->ClearWatchedBit(); |
| + } |
| marking_stack_->Push(raw_obj); |
| // Update the number of used bytes on this page for fast accounting. |
| @@ -184,6 +222,8 @@ class MarkingVisitor : public ObjectPointerVisitor { |
| Heap* vm_heap_; |
| PageSpace* page_space_; |
| MarkingStack* marking_stack_; |
| + typedef std::map<RawObject*, RawWeakProperty*> DelaySet; |
| + DelaySet delay_set_; |
| bool update_store_buffers_; |
| DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
| @@ -318,12 +358,31 @@ void GCMarker::DrainMarkingStack(Isolate* isolate, |
| visitor->set_update_store_buffers(true); |
| while (!visitor->marking_stack()->IsEmpty()) { |
| RawObject* raw_obj = visitor->marking_stack()->Pop(); |
| - raw_obj->VisitPointers(visitor); |
| + if (raw_obj->GetClassId() != kWeakProperty) { |
| + raw_obj->VisitPointers(visitor); |
| + } else { |
| + RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); |
| + ProcessWeakProperty(raw_weak, visitor); |
| + } |
| } |
| visitor->set_update_store_buffers(false); |
| } |
| +void GCMarker::ProcessWeakProperty(RawWeakProperty* raw_weak, |
| + MarkingVisitor* visitor) { |
| + // The fate of the weak property is determined by its key. |
| + RawObject* raw_key = raw_weak->ptr()->key_; |
| + if (!raw_key->IsMarked()) { |
| + // Key is white. Delay the weak property. |
| + visitor->DelayWeakProperty(raw_weak); |
| + } else { |
| + // Key is gray or black. Make the weak property black. |
| + raw_weak->VisitPointers(visitor); |
| + } |
| +} |
| + |
| + |
| void GCMarker::MarkObjects(Isolate* isolate, |
| PageSpace* page_space, |
| bool invoke_api_callbacks) { |
| @@ -335,6 +394,7 @@ void GCMarker::MarkObjects(Isolate* isolate, |
| IterateWeakReferences(isolate, &mark); |
| MarkingWeakVisitor mark_weak; |
| IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); |
| + mark.Finalize(); |
| Epilogue(isolate, invoke_api_callbacks); |
| } |