| 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 "vm/allocation.h" | 7 #include "vm/allocation.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/pages.h" | 9 #include "vm/pages.h" |
| 10 #include "vm/raw_object.h" | 10 #include "vm/raw_object.h" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 DISALLOW_COPY_AND_ASSIGN(MarkingStack); | 112 DISALLOW_COPY_AND_ASSIGN(MarkingStack); |
| 113 }; | 113 }; |
| 114 | 114 |
| 115 | 115 |
| 116 class MarkingVisitor : public ObjectPointerVisitor { | 116 class MarkingVisitor : public ObjectPointerVisitor { |
| 117 public: | 117 public: |
| 118 MarkingVisitor(Heap* heap, PageSpace* page_space, MarkingStack* marking_stack) | 118 MarkingVisitor(Heap* heap, PageSpace* page_space, MarkingStack* marking_stack) |
| 119 : heap_(heap), | 119 : heap_(heap), |
| 120 vm_heap_(Dart::vm_isolate()->heap()), | 120 vm_heap_(Dart::vm_isolate()->heap()), |
| 121 page_space_(page_space), | 121 page_space_(page_space), |
| 122 marking_stack_(marking_stack) {} | 122 marking_stack_(marking_stack) { |
| 123 ASSERT(heap_ != vm_heap_); |
| 124 } |
| 123 | 125 |
| 124 MarkingStack* marking_stack() const { return marking_stack_; } | 126 MarkingStack* marking_stack() const { return marking_stack_; } |
| 125 | 127 |
| 126 void VisitPointers(RawObject** first, RawObject** last) { | 128 void VisitPointers(RawObject** first, RawObject** last) { |
| 127 for (RawObject** current = first; current <= last; current++) { | 129 for (RawObject** current = first; current <= last; current++) { |
| 128 MarkObject(*current); | 130 MarkObject(*current); |
| 129 } | 131 } |
| 130 } | 132 } |
| 131 | 133 |
| 132 private: | 134 private: |
| 133 void MarkAndPush(RawObject* raw_obj) { | 135 void MarkAndPush(RawObject* raw_obj) { |
| 134 ASSERT(raw_obj->IsHeapObject()); | 136 ASSERT(raw_obj->IsHeapObject()); |
| 137 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
| 135 | 138 |
| 136 // Mark the object and push it on the marking stack. | 139 // Mark the object and push it on the marking stack. |
| 137 ASSERT(!raw_obj->IsMarked()); | 140 ASSERT(!raw_obj->IsMarked()); |
| 138 RawClass* raw_class = raw_obj->ptr()->class_; | 141 RawClass* raw_class = raw_obj->ptr()->class_; |
| 139 raw_obj->SetMarkBit(); | 142 raw_obj->SetMarkBit(); |
| 140 marking_stack_->Push(raw_obj); | 143 marking_stack_->Push(raw_obj); |
| 141 | 144 |
| 145 // Update the number of used bytes on this page for fast accounting. |
| 146 HeapPage* page = PageSpace::PageFor(raw_obj); |
| 147 page->AddUsed(raw_obj->Size()); |
| 148 |
| 142 // TODO(iposva): Should we mark the classes early? | 149 // TODO(iposva): Should we mark the classes early? |
| 143 MarkObject(raw_class); | 150 MarkObject(raw_class); |
| 144 } | 151 } |
| 145 | 152 |
| 146 void MarkObject(RawObject* raw_obj) { | 153 void MarkObject(RawObject* raw_obj) { |
| 147 // Fast exit if the raw object is a Smi. | 154 // Fast exit if the raw object is a Smi. |
| 148 if (!raw_obj->IsHeapObject()) return; | 155 if (!raw_obj->IsHeapObject()) return; |
| 149 | 156 |
| 150 // Fast exit if the raw object is marked. | 157 // Fast exit if the raw object is marked. |
| 151 if (raw_obj->IsMarked()) return; | 158 if (raw_obj->IsMarked()) return; |
| 152 | 159 |
| 153 // Skip over new objects, but verify consistency of heap while at it. | 160 // Skip over new objects, but verify consistency of heap while at it. |
| 154 if (raw_obj->IsNewObject()) { | 161 if (raw_obj->IsNewObject()) { |
| 155 // TODO(iposva): Add consistency check. | 162 // TODO(iposva): Add consistency check. |
| 156 return; | 163 return; |
| 157 } | 164 } |
| 158 | 165 |
| 159 uword raw_addr = RawObject::ToAddr(raw_obj); | 166 uword raw_addr = RawObject::ToAddr(raw_obj); |
| 160 // TODO(iposva): Premark vm_isolate objects, to avoid this extra check here. | 167 // TODO(iposva): Premark vm_isolate objects, to avoid this extra check here. |
| 161 if (vm_heap_->Contains(raw_addr)) { | 168 if (vm_heap_->Contains(raw_addr)) { |
| 162 return; | 169 return; |
| 163 } | 170 } |
| 164 // TODO(iposva): merge old and code spaces. | 171 // TODO(iposva): merge old and code spaces. |
| 165 // ASSERT(page_space_->Contains(raw_addr)); | 172 ASSERT(heap_->Contains(raw_addr)); |
| 173 if (!page_space_->Contains(raw_addr)) { |
| 174 // TODO(iposva): Skip code space if marking data space and vice-versa. |
| 175 return; |
| 176 } |
| 166 | 177 |
| 167 MarkAndPush(raw_obj); | 178 MarkAndPush(raw_obj); |
| 168 } | 179 } |
| 169 | 180 |
| 170 Heap* heap_; | 181 Heap* heap_; |
| 171 Heap* vm_heap_; | 182 Heap* vm_heap_; |
| 172 PageSpace* page_space_; | 183 PageSpace* page_space_; |
| 173 MarkingStack* marking_stack_; | 184 MarkingStack* marking_stack_; |
| 174 | 185 |
| 175 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); | 186 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
| 176 }; | 187 }; |
| 177 | 188 |
| 178 | 189 |
| 179 void GCMarker::Prologue(Isolate* isolate) { | 190 void GCMarker::Prologue(Isolate* isolate) { |
| 180 // Nothing to do at the moment. | 191 // Nothing to do at the moment. |
| 181 } | 192 } |
| 182 | 193 |
| 183 | 194 |
| 184 void GCMarker::IterateRoots(Isolate* isolate, MarkingVisitor* visitor) { | 195 void GCMarker::IterateRoots(Isolate* isolate, MarkingVisitor* visitor) { |
| 185 isolate->VisitObjectPointers(visitor, | 196 isolate->VisitObjectPointers(visitor, |
| 186 StackFrameIterator::kDontValidateFrames); | 197 StackFrameIterator::kDontValidateFrames); |
| 187 heap_->IterateNewPointers(visitor); | 198 heap_->IterateNewPointers(visitor); |
| 199 heap_->IterateCodePointers(visitor); |
| 188 } | 200 } |
| 189 | 201 |
| 190 | 202 |
| 191 void GCMarker::DrainMarkingStack(Isolate* isolate, MarkingVisitor* visitor) { | 203 void GCMarker::DrainMarkingStack(Isolate* isolate, MarkingVisitor* visitor) { |
| 192 while (!visitor->marking_stack()->IsEmpty()) { | 204 while (!visitor->marking_stack()->IsEmpty()) { |
| 193 RawObject* raw_obj = visitor->marking_stack()->Pop(); | 205 RawObject* raw_obj = visitor->marking_stack()->Pop(); |
| 194 raw_obj->VisitPointers(visitor); | 206 raw_obj->VisitPointers(visitor); |
| 195 } | 207 } |
| 196 } | 208 } |
| 197 | 209 |
| 198 | 210 |
| 199 void GCMarker::MarkObjects(Isolate* isolate, PageSpace* page_space) { | 211 void GCMarker::MarkObjects(Isolate* isolate, PageSpace* page_space) { |
| 200 MarkingStack marking_stack; | 212 MarkingStack marking_stack; |
| 201 Prologue(isolate); | 213 Prologue(isolate); |
| 202 MarkingVisitor mark(heap_, page_space, &marking_stack); | 214 MarkingVisitor mark(heap_, page_space, &marking_stack); |
| 203 IterateRoots(isolate, &mark); | 215 IterateRoots(isolate, &mark); |
| 204 DrainMarkingStack(isolate, &mark); | 216 DrainMarkingStack(isolate, &mark); |
| 205 } | 217 } |
| 206 | 218 |
| 207 } // namespace dart | 219 } // namespace dart |
| OLD | NEW |