| 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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 } | 423 } |
| 424 if (!raw_obj->IsOldObject()) { | 424 if (!raw_obj->IsOldObject()) { |
| 425 return false; | 425 return false; |
| 426 } | 426 } |
| 427 return !raw_obj->IsMarked(); | 427 return !raw_obj->IsMarked(); |
| 428 } | 428 } |
| 429 | 429 |
| 430 | 430 |
| 431 class MarkingWeakVisitor : public HandleVisitor { | 431 class MarkingWeakVisitor : public HandleVisitor { |
| 432 public: | 432 public: |
| 433 MarkingWeakVisitor(Thread* thread, FinalizationQueue* queue) | 433 explicit MarkingWeakVisitor(Thread* thread) : HandleVisitor(thread) {} |
| 434 : HandleVisitor(thread), queue_(queue) {} | |
| 435 | 434 |
| 436 void VisitHandle(uword addr) { | 435 void VisitHandle(uword addr) { |
| 437 FinalizablePersistentHandle* handle = | 436 FinalizablePersistentHandle* handle = |
| 438 reinterpret_cast<FinalizablePersistentHandle*>(addr); | 437 reinterpret_cast<FinalizablePersistentHandle*>(addr); |
| 439 RawObject* raw_obj = handle->raw(); | 438 RawObject* raw_obj = handle->raw(); |
| 440 if (IsUnreachable(raw_obj)) { | 439 if (IsUnreachable(raw_obj)) { |
| 441 handle->UpdateUnreachable(thread()->isolate(), queue_); | 440 handle->UpdateUnreachable(thread()->isolate()); |
| 442 } | 441 } |
| 443 } | 442 } |
| 444 | 443 |
| 445 private: | 444 private: |
| 446 FinalizationQueue* queue_; | |
| 447 | |
| 448 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); | 445 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); |
| 449 }; | 446 }; |
| 450 | 447 |
| 451 | 448 |
| 452 void GCMarker::Prologue(Isolate* isolate, bool invoke_api_callbacks) { | 449 void GCMarker::Prologue(Isolate* isolate, bool invoke_api_callbacks) { |
| 453 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { | 450 if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) { |
| 454 (isolate->gc_prologue_callback())(); | 451 (isolate->gc_prologue_callback())(); |
| 455 } | 452 } |
| 456 isolate->PrepareForGC(); | 453 isolate->PrepareForGC(); |
| 457 // The store buffers will be rebuilt as part of marking, reset them now. | 454 // The store buffers will be rebuilt as part of marking, reset them now. |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 if (num_tasks == 0) { | 701 if (num_tasks == 0) { |
| 705 // Mark everything on main thread. | 702 // Mark everything on main thread. |
| 706 SkippedCodeFunctions* skipped_code_functions = | 703 SkippedCodeFunctions* skipped_code_functions = |
| 707 collect_code ? new (zone) SkippedCodeFunctions() : NULL; | 704 collect_code ? new (zone) SkippedCodeFunctions() : NULL; |
| 708 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, | 705 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, |
| 709 skipped_code_functions); | 706 skipped_code_functions); |
| 710 IterateRoots(isolate, &mark, 0, 1); | 707 IterateRoots(isolate, &mark, 0, 1); |
| 711 mark.DrainMarkingStack(); | 708 mark.DrainMarkingStack(); |
| 712 { | 709 { |
| 713 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); | 710 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); |
| 714 if (FLAG_background_finalization) { | 711 MarkingWeakVisitor mark_weak(thread); |
| 715 FinalizationQueue* queue = new FinalizationQueue(); | 712 IterateWeakRoots(isolate, &mark_weak); |
| 716 MarkingWeakVisitor mark_weak(thread, queue); | |
| 717 IterateWeakRoots(isolate, &mark_weak); | |
| 718 if (queue->length() > 0) { | |
| 719 Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue)); | |
| 720 } else { | |
| 721 delete queue; | |
| 722 } | |
| 723 } else { | |
| 724 MarkingWeakVisitor mark_weak(thread, NULL); | |
| 725 IterateWeakRoots(isolate, &mark_weak); | |
| 726 } | |
| 727 } | 713 } |
| 728 // All marking done; detach code, etc. | 714 // All marking done; detach code, etc. |
| 729 FinalizeResultsFrom(&mark); | 715 FinalizeResultsFrom(&mark); |
| 730 } else { | 716 } else { |
| 731 ThreadBarrier barrier(num_tasks + 1, heap_->barrier(), | 717 ThreadBarrier barrier(num_tasks + 1, heap_->barrier(), |
| 732 heap_->barrier_done()); | 718 heap_->barrier_done()); |
| 733 // Used to coordinate draining among tasks; all start out as 'busy'. | 719 // Used to coordinate draining among tasks; all start out as 'busy'. |
| 734 uintptr_t num_busy = num_tasks; | 720 uintptr_t num_busy = num_tasks; |
| 735 // Phase 1: Iterate over roots and drain marking stack in tasks. | 721 // Phase 1: Iterate over roots and drain marking stack in tasks. |
| 736 for (intptr_t i = 0; i < num_tasks; ++i) { | 722 for (intptr_t i = 0; i < num_tasks; ++i) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 757 // Note: we need to have two barriers here because we want all markers | 743 // Note: we need to have two barriers here because we want all markers |
| 758 // and main thread to make decisions in lock step. | 744 // and main thread to make decisions in lock step. |
| 759 barrier.Sync(); | 745 barrier.Sync(); |
| 760 more_to_mark = AtomicOperations::LoadRelaxed(&num_busy) > 0; | 746 more_to_mark = AtomicOperations::LoadRelaxed(&num_busy) > 0; |
| 761 barrier.Sync(); | 747 barrier.Sync(); |
| 762 } while (more_to_mark); | 748 } while (more_to_mark); |
| 763 | 749 |
| 764 // Phase 2: Weak processing on main thread. | 750 // Phase 2: Weak processing on main thread. |
| 765 { | 751 { |
| 766 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); | 752 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); |
| 767 if (FLAG_background_finalization) { | 753 MarkingWeakVisitor mark_weak(thread); |
| 768 FinalizationQueue* queue = new FinalizationQueue(); | 754 IterateWeakRoots(isolate, &mark_weak); |
| 769 MarkingWeakVisitor mark_weak(thread, queue); | |
| 770 IterateWeakRoots(isolate, &mark_weak); | |
| 771 if (queue->length() > 0) { | |
| 772 Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue)); | |
| 773 } else { | |
| 774 delete queue; | |
| 775 } | |
| 776 } else { | |
| 777 MarkingWeakVisitor mark_weak(thread, NULL); | |
| 778 IterateWeakRoots(isolate, &mark_weak); | |
| 779 } | |
| 780 } | 755 } |
| 781 barrier.Sync(); | 756 barrier.Sync(); |
| 782 | 757 |
| 783 // Phase 3: Finalize results from all markers (detach code, etc.). | 758 // Phase 3: Finalize results from all markers (detach code, etc.). |
| 784 barrier.Exit(); | 759 barrier.Exit(); |
| 785 } | 760 } |
| 786 ProcessWeakTables(page_space); | 761 ProcessWeakTables(page_space); |
| 787 ProcessObjectIdTable(isolate); | 762 ProcessObjectIdTable(isolate); |
| 788 } | 763 } |
| 789 Epilogue(isolate, invoke_api_callbacks); | 764 Epilogue(isolate, invoke_api_callbacks); |
| 790 } | 765 } |
| 791 | 766 |
| 792 } // namespace dart | 767 } // namespace dart |
| OLD | NEW |