| 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/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/pages.h" | 10 #include "vm/pages.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 class MarkingVisitor : public ObjectPointerVisitor { | 117 class MarkingVisitor : public ObjectPointerVisitor { |
| 118 public: | 118 public: |
| 119 MarkingVisitor(Isolate* isolate, | 119 MarkingVisitor(Isolate* isolate, |
| 120 Heap* heap, | 120 Heap* heap, |
| 121 PageSpace* page_space, | 121 PageSpace* page_space, |
| 122 MarkingStack* marking_stack) | 122 MarkingStack* marking_stack) |
| 123 : ObjectPointerVisitor(isolate), | 123 : ObjectPointerVisitor(isolate), |
| 124 heap_(heap), | 124 heap_(heap), |
| 125 vm_heap_(Dart::vm_isolate()->heap()), | 125 vm_heap_(Dart::vm_isolate()->heap()), |
| 126 page_space_(page_space), | 126 page_space_(page_space), |
| 127 marking_stack_(marking_stack) { | 127 marking_stack_(marking_stack), |
| 128 update_store_buffers_(false) { |
| 128 ASSERT(heap_ != vm_heap_); | 129 ASSERT(heap_ != vm_heap_); |
| 129 } | 130 } |
| 130 | 131 |
| 131 MarkingStack* marking_stack() const { return marking_stack_; } | 132 MarkingStack* marking_stack() const { return marking_stack_; } |
| 132 | 133 |
| 133 void VisitPointers(RawObject** first, RawObject** last) { | 134 void VisitPointers(RawObject** first, RawObject** last) { |
| 134 for (RawObject** current = first; current <= last; current++) { | 135 for (RawObject** current = first; current <= last; current++) { |
| 135 MarkObject(*current); | 136 MarkObject(*current, current); |
| 136 } | 137 } |
| 137 } | 138 } |
| 138 | 139 |
| 140 void set_update_store_buffers(bool val) { update_store_buffers_ = val; } |
| 141 |
| 139 private: | 142 private: |
| 140 void MarkAndPush(RawObject* raw_obj) { | 143 void MarkAndPush(RawObject* raw_obj) { |
| 141 ASSERT(raw_obj->IsHeapObject()); | 144 ASSERT(raw_obj->IsHeapObject()); |
| 142 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); | 145 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
| 143 | 146 |
| 144 // Mark the object and push it on the marking stack. | 147 // Mark the object and push it on the marking stack. |
| 145 ASSERT(!raw_obj->IsMarked()); | 148 ASSERT(!raw_obj->IsMarked()); |
| 146 RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); | 149 RawClass* raw_class = isolate()->class_table()->At(raw_obj->GetClassId()); |
| 147 raw_obj->SetMarkBit(); | 150 raw_obj->SetMarkBit(); |
| 148 marking_stack_->Push(raw_obj); | 151 marking_stack_->Push(raw_obj); |
| 149 | 152 |
| 150 // Update the number of used bytes on this page for fast accounting. | 153 // Update the number of used bytes on this page for fast accounting. |
| 151 HeapPage* page = PageSpace::PageFor(raw_obj); | 154 HeapPage* page = PageSpace::PageFor(raw_obj); |
| 152 page->AddUsed(raw_obj->Size()); | 155 page->AddUsed(raw_obj->Size()); |
| 153 | 156 |
| 154 // TODO(iposva): Should we mark the classes early? | 157 // TODO(iposva): Should we mark the classes early? |
| 155 MarkObject(raw_class); | 158 MarkObject(raw_class, NULL); |
| 156 } | 159 } |
| 157 | 160 |
| 158 void MarkObject(RawObject* raw_obj) { | 161 void MarkObject(RawObject* raw_obj, RawObject** p) { |
| 159 // Fast exit if the raw object is a Smi. | 162 // Fast exit if the raw object is a Smi. |
| 160 if (!raw_obj->IsHeapObject()) return; | 163 if (!raw_obj->IsHeapObject()) return; |
| 161 | 164 |
| 162 // Fast exit if the raw object is marked. | 165 // Fast exit if the raw object is marked. |
| 163 if (raw_obj->IsMarked()) return; | 166 if (raw_obj->IsMarked()) return; |
| 164 | 167 |
| 165 // Skip over new objects, but verify consistency of heap while at it. | 168 // Skip over new objects, but verify consistency of heap while at it. |
| 166 if (raw_obj->IsNewObject()) { | 169 if (raw_obj->IsNewObject()) { |
| 167 // TODO(iposva): Add consistency check. | 170 // TODO(iposva): Add consistency check. |
| 171 if (update_store_buffers_) { |
| 172 ASSERT(p != NULL); |
| 173 isolate()->store_buffer()->AddPointer(reinterpret_cast<uword>(p)); |
| 174 } |
| 168 return; | 175 return; |
| 169 } | 176 } |
| 170 | 177 |
| 171 // TODO(iposva): merge old and code spaces. | 178 // TODO(iposva): merge old and code spaces. |
| 172 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); | 179 ASSERT(page_space_->Contains(RawObject::ToAddr(raw_obj))); |
| 173 MarkAndPush(raw_obj); | 180 MarkAndPush(raw_obj); |
| 174 } | 181 } |
| 175 | 182 |
| 176 Heap* heap_; | 183 Heap* heap_; |
| 177 Heap* vm_heap_; | 184 Heap* vm_heap_; |
| 178 PageSpace* page_space_; | 185 PageSpace* page_space_; |
| 179 MarkingStack* marking_stack_; | 186 MarkingStack* marking_stack_; |
| 187 bool update_store_buffers_; |
| 180 | 188 |
| 181 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); | 189 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
| 182 }; | 190 }; |
| 183 | 191 |
| 184 | 192 |
| 185 bool IsUnreachable(const RawObject* raw_obj) { | 193 bool IsUnreachable(const RawObject* raw_obj) { |
| 186 if (!raw_obj->IsHeapObject()) { | 194 if (!raw_obj->IsHeapObject()) { |
| 187 return false; | 195 return false; |
| 188 } | 196 } |
| 189 if (raw_obj == Object::null()) { | 197 if (raw_obj == Object::null()) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 212 | 220 |
| 213 private: | 221 private: |
| 214 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); | 222 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); |
| 215 }; | 223 }; |
| 216 | 224 |
| 217 | 225 |
| 218 void GCMarker::Prologue(Isolate* isolate, bool invoke_api_callbacks) { | 226 void GCMarker::Prologue(Isolate* isolate, bool invoke_api_callbacks) { |
| 219 if (invoke_api_callbacks) { | 227 if (invoke_api_callbacks) { |
| 220 isolate->gc_prologue_callbacks().Invoke(); | 228 isolate->gc_prologue_callbacks().Invoke(); |
| 221 } | 229 } |
| 230 // The store buffers will be rebuilt as part of marking, reset them now. |
| 231 isolate->store_buffer()->Reset(); |
| 232 isolate->store_buffer_block()->Reset(); |
| 222 } | 233 } |
| 223 | 234 |
| 224 | 235 |
| 225 void GCMarker::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { | 236 void GCMarker::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { |
| 226 if (invoke_api_callbacks) { | 237 if (invoke_api_callbacks) { |
| 227 isolate->gc_epilogue_callbacks().Invoke(); | 238 isolate->gc_epilogue_callbacks().Invoke(); |
| 228 } | 239 } |
| 229 } | 240 } |
| 230 | 241 |
| 231 | 242 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 state->set_delayed_weak_references(NULL); | 308 state->set_delayed_weak_references(NULL); |
| 298 while (queue != NULL) { | 309 while (queue != NULL) { |
| 299 delete WeakReference::Pop(&queue); | 310 delete WeakReference::Pop(&queue); |
| 300 } | 311 } |
| 301 } | 312 } |
| 302 } | 313 } |
| 303 | 314 |
| 304 | 315 |
| 305 void GCMarker::DrainMarkingStack(Isolate* isolate, | 316 void GCMarker::DrainMarkingStack(Isolate* isolate, |
| 306 MarkingVisitor* visitor) { | 317 MarkingVisitor* visitor) { |
| 318 visitor->set_update_store_buffers(true); |
| 307 while (!visitor->marking_stack()->IsEmpty()) { | 319 while (!visitor->marking_stack()->IsEmpty()) { |
| 308 RawObject* raw_obj = visitor->marking_stack()->Pop(); | 320 RawObject* raw_obj = visitor->marking_stack()->Pop(); |
| 309 raw_obj->VisitPointers(visitor); | 321 raw_obj->VisitPointers(visitor); |
| 310 } | 322 } |
| 323 visitor->set_update_store_buffers(false); |
| 311 } | 324 } |
| 312 | 325 |
| 313 | 326 |
| 314 void GCMarker::MarkObjects(Isolate* isolate, | 327 void GCMarker::MarkObjects(Isolate* isolate, |
| 315 PageSpace* page_space, | 328 PageSpace* page_space, |
| 316 bool invoke_api_callbacks) { | 329 bool invoke_api_callbacks) { |
| 317 MarkingStack marking_stack; | 330 MarkingStack marking_stack; |
| 318 Prologue(isolate, invoke_api_callbacks); | 331 Prologue(isolate, invoke_api_callbacks); |
| 319 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); | 332 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack); |
| 320 IterateRoots(isolate, &mark, !invoke_api_callbacks); | 333 IterateRoots(isolate, &mark, !invoke_api_callbacks); |
| 321 DrainMarkingStack(isolate, &mark); | 334 DrainMarkingStack(isolate, &mark); |
| 322 IterateWeakReferences(isolate, &mark); | 335 IterateWeakReferences(isolate, &mark); |
| 323 MarkingWeakVisitor mark_weak; | 336 MarkingWeakVisitor mark_weak; |
| 324 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); | 337 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); |
| 325 Epilogue(isolate, invoke_api_callbacks); | 338 Epilogue(isolate, invoke_api_callbacks); |
| 326 } | 339 } |
| 327 | 340 |
| 328 } // namespace dart | 341 } // namespace dart |
| OLD | NEW |