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