| 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/log.h" | 10 #include "vm/log.h" |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 } | 415 } |
| 416 if (!raw_obj->IsOldObject()) { | 416 if (!raw_obj->IsOldObject()) { |
| 417 return false; | 417 return false; |
| 418 } | 418 } |
| 419 return !raw_obj->IsMarked(); | 419 return !raw_obj->IsMarked(); |
| 420 } | 420 } |
| 421 | 421 |
| 422 | 422 |
| 423 class MarkingWeakVisitor : public HandleVisitor { | 423 class MarkingWeakVisitor : public HandleVisitor { |
| 424 public: | 424 public: |
| 425 MarkingWeakVisitor() : HandleVisitor(Thread::Current()) { | 425 MarkingWeakVisitor(Thread* thread, FinalizationQueue* queue) : |
| 426 } | 426 HandleVisitor(thread), queue_(queue) { } |
| 427 | 427 |
| 428 void VisitHandle(uword addr) { | 428 void VisitHandle(uword addr) { |
| 429 FinalizablePersistentHandle* handle = | 429 FinalizablePersistentHandle* handle = |
| 430 reinterpret_cast<FinalizablePersistentHandle*>(addr); | 430 reinterpret_cast<FinalizablePersistentHandle*>(addr); |
| 431 RawObject* raw_obj = handle->raw(); | 431 RawObject* raw_obj = handle->raw(); |
| 432 if (IsUnreachable(raw_obj)) { | 432 if (IsUnreachable(raw_obj)) { |
| 433 handle->UpdateUnreachable(thread()->isolate()); | 433 handle->UpdateUnreachable(thread()->isolate(), queue_); |
| 434 } | 434 } |
| 435 } | 435 } |
| 436 | 436 |
| 437 private: | 437 private: |
| 438 FinalizationQueue* queue_; |
| 439 |
| 438 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); | 440 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); |
| 439 }; | 441 }; |
| 440 | 442 |
| 441 | 443 |
| 442 void GCMarker::Prologue(Isolate* isolate, bool invoke_api_callbacks) { | 444 void GCMarker::Prologue(Isolate* isolate, bool invoke_api_callbacks) { |
| 443 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { | 445 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { |
| 444 (isolate->gc_prologue_callback())(); | 446 (isolate->gc_prologue_callback())(); |
| 445 } | 447 } |
| 446 isolate->PrepareForGC(); | 448 isolate->PrepareForGC(); |
| 447 // The store buffers will be rebuilt as part of marking, reset them now. | 449 // The store buffers will be rebuilt as part of marking, reset them now. |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 if (num_tasks == 0) { | 663 if (num_tasks == 0) { |
| 662 // Mark everything on main thread. | 664 // Mark everything on main thread. |
| 663 SkippedCodeFunctions* skipped_code_functions = | 665 SkippedCodeFunctions* skipped_code_functions = |
| 664 collect_code ? new(zone) SkippedCodeFunctions() : NULL; | 666 collect_code ? new(zone) SkippedCodeFunctions() : NULL; |
| 665 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, | 667 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, |
| 666 skipped_code_functions); | 668 skipped_code_functions); |
| 667 IterateRoots(isolate, &mark, 0, 1); | 669 IterateRoots(isolate, &mark, 0, 1); |
| 668 mark.DrainMarkingStack(); | 670 mark.DrainMarkingStack(); |
| 669 { | 671 { |
| 670 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); | 672 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); |
| 671 MarkingWeakVisitor mark_weak; | 673 FinalizationQueue* queue = new FinalizationQueue(); |
| 674 MarkingWeakVisitor mark_weak(thread, queue); |
| 672 IterateWeakRoots(isolate, &mark_weak); | 675 IterateWeakRoots(isolate, &mark_weak); |
| 676 if (queue->length() > 0) { |
| 677 Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue)); |
| 678 } else { |
| 679 delete queue; |
| 680 } |
| 673 } | 681 } |
| 674 // All marking done; detach code, etc. | 682 // All marking done; detach code, etc. |
| 675 FinalizeResultsFrom(&mark); | 683 FinalizeResultsFrom(&mark); |
| 676 } else { | 684 } else { |
| 677 ThreadBarrier barrier(num_tasks + 1, | 685 ThreadBarrier barrier(num_tasks + 1, |
| 678 heap_->barrier(), | 686 heap_->barrier(), |
| 679 heap_->barrier_done()); | 687 heap_->barrier_done()); |
| 680 // Used to coordinate draining among tasks; all start out as 'busy'. | 688 // Used to coordinate draining among tasks; all start out as 'busy'. |
| 681 uintptr_t num_busy = num_tasks; | 689 uintptr_t num_busy = num_tasks; |
| 682 // Phase 1: Iterate over roots and drain marking stack in tasks. | 690 // Phase 1: Iterate over roots and drain marking stack in tasks. |
| 683 for (intptr_t i = 0; i < num_tasks; ++i) { | 691 for (intptr_t i = 0; i < num_tasks; ++i) { |
| 684 MarkTask* mark_task = | 692 MarkTask* mark_task = |
| 685 new MarkTask(this, isolate, heap_, page_space, &marking_stack, | 693 new MarkTask(this, isolate, heap_, page_space, &marking_stack, |
| 686 &barrier, collect_code, | 694 &barrier, collect_code, |
| 687 i, num_tasks, &num_busy); | 695 i, num_tasks, &num_busy); |
| 688 ThreadPool* pool = Dart::thread_pool(); | 696 ThreadPool* pool = Dart::thread_pool(); |
| 689 pool->Run(mark_task); | 697 pool->Run(mark_task); |
| 690 } | 698 } |
| 691 barrier.Sync(); | 699 barrier.Sync(); |
| 692 | 700 |
| 693 // Phase 2: Weak processing on main thread. | 701 // Phase 2: Weak processing on main thread. |
| 694 { | 702 { |
| 695 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); | 703 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); |
| 696 MarkingWeakVisitor mark_weak; | 704 FinalizationQueue* queue = new FinalizationQueue(); |
| 705 MarkingWeakVisitor mark_weak(thread, queue); |
| 697 IterateWeakRoots(isolate, &mark_weak); | 706 IterateWeakRoots(isolate, &mark_weak); |
| 707 if (queue->length() > 0) { |
| 708 Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue)); |
| 709 } else { |
| 710 delete queue; |
| 711 } |
| 698 } | 712 } |
| 699 barrier.Sync(); | 713 barrier.Sync(); |
| 700 | 714 |
| 701 // Phase 3: Finalize results from all markers (detach code, etc.). | 715 // Phase 3: Finalize results from all markers (detach code, etc.). |
| 702 barrier.Exit(); | 716 barrier.Exit(); |
| 703 } | 717 } |
| 704 ProcessWeakTables(page_space); | 718 ProcessWeakTables(page_space); |
| 705 ProcessObjectIdTable(isolate); | 719 ProcessObjectIdTable(isolate); |
| 706 } | 720 } |
| 707 Epilogue(isolate, invoke_api_callbacks); | 721 Epilogue(isolate, invoke_api_callbacks); |
| 708 } | 722 } |
| 709 | 723 |
| 710 } // namespace dart | 724 } // namespace dart |
| OLD | NEW |