| 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> | 7 #include <map> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "vm/allocation.h" | 11 #include "vm/allocation.h" |
| 12 #include "vm/dart_api_state.h" | 12 #include "vm/dart_api_state.h" |
| 13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
| 14 #include "vm/log.h" | 14 #include "vm/log.h" |
| 15 #include "vm/pages.h" | 15 #include "vm/pages.h" |
| 16 #include "vm/raw_object.h" | 16 #include "vm/raw_object.h" |
| 17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
| 18 #include "vm/store_buffer.h" | 18 #include "vm/store_buffer.h" |
| 19 #include "vm/thread_barrier.h" | 19 #include "vm/thread_barrier.h" |
| 20 #include "vm/thread_pool.h" | 20 #include "vm/thread_pool.h" |
| 21 #include "vm/visitor.h" | 21 #include "vm/visitor.h" |
| 22 #include "vm/object_id_ring.h" | 22 #include "vm/object_id_ring.h" |
| 23 | 23 |
| 24 namespace dart { | 24 namespace dart { |
| 25 | 25 |
| 26 DEFINE_FLAG(int, marker_tasks, 1, | 26 DEFINE_FLAG(int, marker_tasks, 1, |
| 27 "The number of tasks to spawn during old gen GC marking (0 means " | 27 "The number of tasks to spawn during old gen GC marking (0 means " |
| 28 "perform all marking on main thread)."); | 28 "perform all marking on main thread)."); |
| 29 | 29 |
| 30 typedef StoreBufferBlock PointerBlock; // TODO(koda): Rename to PointerBlock. | |
| 31 typedef StoreBuffer MarkingStack; // TODO(koda): Create shared base class. | |
| 32 | |
| 33 class DelaySet { | 30 class DelaySet { |
| 34 private: | 31 private: |
| 35 typedef std::multimap<RawObject*, RawWeakProperty*> Map; | 32 typedef std::multimap<RawObject*, RawWeakProperty*> Map; |
| 36 typedef std::pair<RawObject*, RawWeakProperty*> MapEntry; | 33 typedef std::pair<RawObject*, RawWeakProperty*> MapEntry; |
| 37 | 34 |
| 38 public: | 35 public: |
| 39 DelaySet() : mutex_(new Mutex()) {} | 36 DelaySet() : mutex_(new Mutex()) {} |
| 40 ~DelaySet() { delete mutex_; } | 37 ~DelaySet() { delete mutex_; } |
| 41 | 38 |
| 42 // Returns 'true' if this inserted a new key (not just added a value). | 39 // Returns 'true' if this inserted a new key (not just added a value). |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 ASSERT(work_ == NULL); | 278 ASSERT(work_ == NULL); |
| 282 ASSERT(marking_stack_ == NULL); | 279 ASSERT(marking_stack_ == NULL); |
| 283 } | 280 } |
| 284 | 281 |
| 285 // Returns NULL if no more work was found. | 282 // Returns NULL if no more work was found. |
| 286 RawObject* Pop() { | 283 RawObject* Pop() { |
| 287 ASSERT(work_ != NULL); | 284 ASSERT(work_ != NULL); |
| 288 if (work_->IsEmpty()) { | 285 if (work_->IsEmpty()) { |
| 289 // TODO(koda): Track over/underflow events and use in heuristics to | 286 // TODO(koda): Track over/underflow events and use in heuristics to |
| 290 // distribute work and prevent degenerate flip-flopping. | 287 // distribute work and prevent degenerate flip-flopping. |
| 291 PointerBlock* new_work = marking_stack_->PopNonEmptyBlock(); | 288 MarkingStack::Block* new_work = marking_stack_->PopNonEmptyBlock(); |
| 292 if (new_work == NULL) { | 289 if (new_work == NULL) { |
| 293 return NULL; | 290 return NULL; |
| 294 } | 291 } |
| 295 marking_stack_->PushBlock(work_, false); | 292 marking_stack_->PushBlock(work_); |
| 296 work_ = new_work; | 293 work_ = new_work; |
| 297 } | 294 } |
| 298 return work_->Pop(); | 295 return work_->Pop(); |
| 299 } | 296 } |
| 300 | 297 |
| 301 void Push(RawObject* raw_obj) { | 298 void Push(RawObject* raw_obj) { |
| 302 if (work_->IsFull()) { | 299 if (work_->IsFull()) { |
| 303 // TODO(koda): Track over/underflow events and use in heuristics to | 300 // TODO(koda): Track over/underflow events and use in heuristics to |
| 304 // distribute work and prevent degenerate flip-flopping. | 301 // distribute work and prevent degenerate flip-flopping. |
| 305 marking_stack_->PushBlock(work_, false); | 302 marking_stack_->PushBlock(work_); |
| 306 work_ = marking_stack_->PopEmptyBlock(); | 303 work_ = marking_stack_->PopEmptyBlock(); |
| 307 } | 304 } |
| 308 work_->Push(raw_obj); | 305 work_->Push(raw_obj); |
| 309 } | 306 } |
| 310 | 307 |
| 311 void Finalize() { | 308 void Finalize() { |
| 312 ASSERT(work_->IsEmpty()); | 309 ASSERT(work_->IsEmpty()); |
| 313 marking_stack_->PushBlock(work_, false); | 310 marking_stack_->PushBlock(work_); |
| 314 work_ = NULL; | 311 work_ = NULL; |
| 315 // Fail fast on attempts to mark after finalizing. | 312 // Fail fast on attempts to mark after finalizing. |
| 316 marking_stack_ = NULL; | 313 marking_stack_ = NULL; |
| 317 } | 314 } |
| 318 | 315 |
| 319 private: | 316 private: |
| 320 PointerBlock* work_; | 317 MarkingStack::Block* work_; |
| 321 MarkingStack* marking_stack_; | 318 MarkingStack* marking_stack_; |
| 322 }; | 319 }; |
| 323 | 320 |
| 324 void MarkAndPush(RawObject* raw_obj) { | 321 void MarkAndPush(RawObject* raw_obj) { |
| 325 ASSERT(raw_obj->IsHeapObject()); | 322 ASSERT(raw_obj->IsHeapObject()); |
| 326 ASSERT((FLAG_verify_before_gc || FLAG_verify_before_gc) ? | 323 ASSERT((FLAG_verify_before_gc || FLAG_verify_before_gc) ? |
| 327 page_space_->Contains(RawObject::ToAddr(raw_obj)) : | 324 page_space_->Contains(RawObject::ToAddr(raw_obj)) : |
| 328 true); | 325 true); |
| 329 | 326 |
| 330 // Mark the object and push it on the marking stack. | 327 // Mark the object and push it on the marking stack. |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 barrier.Exit(); | 708 barrier.Exit(); |
| 712 } | 709 } |
| 713 delay_set.ClearReferences(); | 710 delay_set.ClearReferences(); |
| 714 ProcessWeakTables(page_space); | 711 ProcessWeakTables(page_space); |
| 715 ProcessObjectIdTable(isolate); | 712 ProcessObjectIdTable(isolate); |
| 716 } | 713 } |
| 717 Epilogue(isolate, invoke_api_callbacks); | 714 Epilogue(isolate, invoke_api_callbacks); |
| 718 } | 715 } |
| 719 | 716 |
| 720 } // namespace dart | 717 } // namespace dart |
| OLD | NEW |