Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: runtime/vm/gc_marker.cc

Issue 1459173004: Remove support for object grouping during Garbage Collection (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code-review Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/gc_marker.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 492
493 void GCMarker::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { 493 void GCMarker::Epilogue(Isolate* isolate, bool invoke_api_callbacks) {
494 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { 494 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) {
495 (isolate->gc_epilogue_callback())(); 495 (isolate->gc_epilogue_callback())();
496 } 496 }
497 } 497 }
498 498
499 499
500 void GCMarker::IterateRoots(Isolate* isolate, 500 void GCMarker::IterateRoots(Isolate* isolate,
501 ObjectPointerVisitor* visitor, 501 ObjectPointerVisitor* visitor,
502 bool visit_prologue_weak_persistent_handles,
503 intptr_t slice_index, intptr_t num_slices) { 502 intptr_t slice_index, intptr_t num_slices) {
504 ASSERT(0 <= slice_index && slice_index < num_slices); 503 ASSERT(0 <= slice_index && slice_index < num_slices);
505 if ((slice_index == 0) || (num_slices <= 1)) { 504 if ((slice_index == 0) || (num_slices <= 1)) {
506 isolate->VisitObjectPointers(visitor, 505 isolate->VisitObjectPointers(visitor,
507 visit_prologue_weak_persistent_handles,
508 StackFrameIterator::kDontValidateFrames); 506 StackFrameIterator::kDontValidateFrames);
509 } 507 }
510 if ((slice_index == 1) || (num_slices <= 1)) { 508 if ((slice_index == 1) || (num_slices <= 1)) {
511 heap_->new_space()->VisitObjectPointers(visitor); 509 heap_->new_space()->VisitObjectPointers(visitor);
512 } 510 }
513 511
514 // For now, we just distinguish two parts of the root set, so any remaining 512 // For now, we just distinguish two parts of the root set, so any remaining
515 // slices are empty. 513 // slices are empty.
516 } 514 }
517 515
518 516
519 void GCMarker::IterateWeakRoots(Isolate* isolate, 517 void GCMarker::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
520 HandleVisitor* visitor,
521 bool visit_prologue_weak_persistent_handles) {
522 ApiState* state = isolate->api_state(); 518 ApiState* state = isolate->api_state();
523 ASSERT(state != NULL); 519 ASSERT(state != NULL);
524 isolate->VisitWeakPersistentHandles(visitor, 520 isolate->VisitWeakPersistentHandles(visitor);
525 visit_prologue_weak_persistent_handles);
526 } 521 }
527 522
528 523
529 template<class MarkingVisitorType>
530 void GCMarker::IterateWeakReferences(Isolate* isolate,
531 MarkingVisitorType* visitor) {
532 ApiState* state = isolate->api_state();
533 ASSERT(state != NULL);
534 while (true) {
535 WeakReferenceSet* queue = state->delayed_weak_reference_sets();
536 if (queue == NULL) {
537 // The delay queue is empty therefore no clean-up is required.
538 return;
539 }
540 state->set_delayed_weak_reference_sets(NULL);
541 while (queue != NULL) {
542 WeakReferenceSet* reference_set = WeakReferenceSet::Pop(&queue);
543 ASSERT(reference_set != NULL);
544 intptr_t num_keys = reference_set->num_keys();
545 intptr_t num_values = reference_set->num_values();
546 if ((num_keys == 1) && (num_values == 1) &&
547 reference_set->SingletonKeyEqualsValue()) {
548 // We do not have to process sets that have just one key/value pair
549 // and the key and value are identical.
550 continue;
551 }
552 bool is_unreachable = true;
553 // Test each key object for reachability. If a key object is
554 // reachable, all value objects should be marked.
555 for (intptr_t k = 0; k < num_keys; ++k) {
556 if (!IsUnreachable(*reference_set->get_key(k))) {
557 for (intptr_t v = 0; v < num_values; ++v) {
558 visitor->VisitPointer(reference_set->get_value(v));
559 }
560 is_unreachable = false;
561 // Since we have found a key object that is reachable and all
562 // value objects have been marked we can break out of iterating
563 // this set and move on to the next set.
564 break;
565 }
566 }
567 // If all key objects are unreachable put the reference on a
568 // delay queue. This reference will be revisited if another
569 // reference is marked.
570 if (is_unreachable) {
571 state->DelayWeakReferenceSet(reference_set);
572 }
573 }
574 if (!visitor->DrainMarkingStack()) {
575 // Break out of the loop if there has been no forward process.
576 // All key objects in the weak reference sets are unreachable
577 // so we reset the weak reference sets queue.
578 state->set_delayed_weak_reference_sets(NULL);
579 break;
580 }
581 }
582 ASSERT(state->delayed_weak_reference_sets() == NULL);
583 // All weak reference sets are zone allocated and unmarked references which
584 // were on the delay queue will be freed when the zone is released in the
585 // epilog callback.
586 }
587
588
589 void GCMarker::ProcessWeakTables(PageSpace* page_space) { 524 void GCMarker::ProcessWeakTables(PageSpace* page_space) {
590 for (int sel = 0; 525 for (int sel = 0;
591 sel < Heap::kNumWeakSelectors; 526 sel < Heap::kNumWeakSelectors;
592 sel++) { 527 sel++) {
593 WeakTable* table = heap_->GetWeakTable( 528 WeakTable* table = heap_->GetWeakTable(
594 Heap::kOld, static_cast<Heap::WeakSelector>(sel)); 529 Heap::kOld, static_cast<Heap::WeakSelector>(sel));
595 intptr_t size = table->size(); 530 intptr_t size = table->size();
596 for (intptr_t i = 0; i < size; i++) { 531 for (intptr_t i = 0; i < size; i++) {
597 if (table->IsValidEntryAt(i)) { 532 if (table->IsValidEntryAt(i)) {
598 RawObject* raw_obj = table->ObjectAt(i); 533 RawObject* raw_obj = table->ObjectAt(i);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 class MarkTask : public ThreadPool::Task { 571 class MarkTask : public ThreadPool::Task {
637 public: 572 public:
638 MarkTask(GCMarker* marker, 573 MarkTask(GCMarker* marker,
639 Isolate* isolate, 574 Isolate* isolate,
640 Heap* heap, 575 Heap* heap,
641 PageSpace* page_space, 576 PageSpace* page_space,
642 MarkingStack* marking_stack, 577 MarkingStack* marking_stack,
643 DelaySet* delay_set, 578 DelaySet* delay_set,
644 ThreadBarrier* barrier, 579 ThreadBarrier* barrier,
645 bool collect_code, 580 bool collect_code,
646 bool visit_prologue_weak_persistent_handles,
647 intptr_t task_index, 581 intptr_t task_index,
648 intptr_t num_tasks, 582 intptr_t num_tasks,
649 uintptr_t* num_busy) 583 uintptr_t* num_busy)
650 : marker_(marker), 584 : marker_(marker),
651 isolate_(isolate), 585 isolate_(isolate),
652 heap_(heap), 586 heap_(heap),
653 page_space_(page_space), 587 page_space_(page_space),
654 marking_stack_(marking_stack), 588 marking_stack_(marking_stack),
655 delay_set_(delay_set), 589 delay_set_(delay_set),
656 barrier_(barrier), 590 barrier_(barrier),
657 collect_code_(collect_code), 591 collect_code_(collect_code),
658 visit_prologue_weak_persistent_handles_(
659 visit_prologue_weak_persistent_handles),
660 task_index_(task_index), 592 task_index_(task_index),
661 num_tasks_(num_tasks), 593 num_tasks_(num_tasks),
662 num_busy_(num_busy) { 594 num_busy_(num_busy) {
663 } 595 }
664 596
665 virtual void Run() { 597 virtual void Run() {
666 Thread::EnterIsolateAsHelper(isolate_, true); 598 Thread::EnterIsolateAsHelper(isolate_, true);
667 { 599 {
668 StackZone stack_zone(Thread::Current()); 600 StackZone stack_zone(Thread::Current());
669 Zone* zone = stack_zone.GetZone(); 601 Zone* zone = stack_zone.GetZone();
670 SkippedCodeFunctions* skipped_code_functions = 602 SkippedCodeFunctions* skipped_code_functions =
671 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL; 603 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL;
672 SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_, 604 SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
673 delay_set_, skipped_code_functions); 605 delay_set_, skipped_code_functions);
674 // Phase 1: Iterate over roots and drain marking stack in tasks. 606 // Phase 1: Iterate over roots and drain marking stack in tasks.
675 marker_->IterateRoots(isolate_, &visitor, 607 marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_);
676 visit_prologue_weak_persistent_handles_,
677 task_index_, num_tasks_);
678 do { 608 do {
679 visitor.DrainMarkingStack(); 609 visitor.DrainMarkingStack();
680 610
681 // I can't find more work right now. If no other task is busy, 611 // I can't find more work right now. If no other task is busy,
682 // then there will never be more work (NB: 1 is *before* decrement). 612 // then there will never be more work (NB: 1 is *before* decrement).
683 if (AtomicOperations::FetchAndDecrement(num_busy_) == 1) break; 613 if (AtomicOperations::FetchAndDecrement(num_busy_) == 1) break;
684 614
685 // Wait for some work to appear. 615 // Wait for some work to appear.
686 // TODO(iposva): Replace busy-waiting with a solution using Monitor, 616 // TODO(iposva): Replace busy-waiting with a solution using Monitor,
687 // and redraw the boundaries between stack/visitor/task as needed. 617 // and redraw the boundaries between stack/visitor/task as needed.
(...skipping 28 matching lines...) Expand all
716 646
717 private: 647 private:
718 GCMarker* marker_; 648 GCMarker* marker_;
719 Isolate* isolate_; 649 Isolate* isolate_;
720 Heap* heap_; 650 Heap* heap_;
721 PageSpace* page_space_; 651 PageSpace* page_space_;
722 MarkingStack* marking_stack_; 652 MarkingStack* marking_stack_;
723 DelaySet* delay_set_; 653 DelaySet* delay_set_;
724 ThreadBarrier* barrier_; 654 ThreadBarrier* barrier_;
725 bool collect_code_; 655 bool collect_code_;
726 bool visit_prologue_weak_persistent_handles_;
727 const intptr_t task_index_; 656 const intptr_t task_index_;
728 const intptr_t num_tasks_; 657 const intptr_t num_tasks_;
729 uintptr_t* num_busy_; 658 uintptr_t* num_busy_;
730 659
731 DISALLOW_COPY_AND_ASSIGN(MarkTask); 660 DISALLOW_COPY_AND_ASSIGN(MarkTask);
732 }; 661 };
733 662
734 663
735 template<class MarkingVisitorType> 664 template<class MarkingVisitorType>
736 void GCMarker::FinalizeResultsFrom(MarkingVisitorType* visitor) { 665 void GCMarker::FinalizeResultsFrom(MarkingVisitorType* visitor) {
(...skipping 20 matching lines...) Expand all
757 bool invoke_api_callbacks, 686 bool invoke_api_callbacks,
758 bool collect_code) { 687 bool collect_code) {
759 Prologue(isolate, invoke_api_callbacks); 688 Prologue(isolate, invoke_api_callbacks);
760 // The API prologue/epilogue may create/destroy zones, so we must not 689 // The API prologue/epilogue may create/destroy zones, so we must not
761 // depend on zone allocations surviving beyond the epilogue callback. 690 // depend on zone allocations surviving beyond the epilogue callback.
762 { 691 {
763 StackZone stack_zone(Thread::Current()); 692 StackZone stack_zone(Thread::Current());
764 Zone* zone = stack_zone.GetZone(); 693 Zone* zone = stack_zone.GetZone();
765 MarkingStack marking_stack; 694 MarkingStack marking_stack;
766 DelaySet delay_set; 695 DelaySet delay_set;
767 const bool visit_prologue_weak_persistent_handles = !invoke_api_callbacks;
768 marked_bytes_ = 0; 696 marked_bytes_ = 0;
769 const int num_tasks = FLAG_marker_tasks; 697 const int num_tasks = FLAG_marker_tasks;
770 if (num_tasks == 0) { 698 if (num_tasks == 0) {
771 // Mark everything on main thread. 699 // Mark everything on main thread.
772 SkippedCodeFunctions* skipped_code_functions = 700 SkippedCodeFunctions* skipped_code_functions =
773 collect_code ? new(zone) SkippedCodeFunctions() : NULL; 701 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
774 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 702 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
775 &delay_set, skipped_code_functions); 703 &delay_set, skipped_code_functions);
776 IterateRoots(isolate, &mark, visit_prologue_weak_persistent_handles, 704 IterateRoots(isolate, &mark, 0, 1);
777 0, 1);
778 mark.DrainMarkingStack(); 705 mark.DrainMarkingStack();
779 IterateWeakReferences(isolate, &mark);
780 MarkingWeakVisitor mark_weak; 706 MarkingWeakVisitor mark_weak;
781 IterateWeakRoots(isolate, &mark_weak, 707 IterateWeakRoots(isolate, &mark_weak);
782 !visit_prologue_weak_persistent_handles);
783 // All marking done; detach code, etc. 708 // All marking done; detach code, etc.
784 FinalizeResultsFrom(&mark); 709 FinalizeResultsFrom(&mark);
785 } else { 710 } else {
786 ThreadBarrier barrier(num_tasks + 1); 711 ThreadBarrier barrier(num_tasks + 1);
787 // Used to coordinate draining among tasks; all start out as 'busy'. 712 // Used to coordinate draining among tasks; all start out as 'busy'.
788 uintptr_t num_busy = num_tasks; 713 uintptr_t num_busy = num_tasks;
789 // Phase 1: Iterate over roots and drain marking stack in tasks. 714 // Phase 1: Iterate over roots and drain marking stack in tasks.
790 for (intptr_t i = 0; i < num_tasks; ++i) { 715 for (intptr_t i = 0; i < num_tasks; ++i) {
791 MarkTask* mark_task = 716 MarkTask* mark_task =
792 new MarkTask(this, isolate, heap_, page_space, &marking_stack, 717 new MarkTask(this, isolate, heap_, page_space, &marking_stack,
793 &delay_set, &barrier, collect_code, 718 &delay_set, &barrier, collect_code,
794 visit_prologue_weak_persistent_handles,
795 i, num_tasks, &num_busy); 719 i, num_tasks, &num_busy);
796 ThreadPool* pool = Dart::thread_pool(); 720 ThreadPool* pool = Dart::thread_pool();
797 pool->Run(mark_task); 721 pool->Run(mark_task);
798 } 722 }
799 barrier.Sync(); 723 barrier.Sync();
800 724
801 // Phase 2: Weak processing and follow-up marking on main thread. 725 // Phase 2: Weak processing and follow-up marking on main thread.
802 SkippedCodeFunctions* skipped_code_functions = 726 SkippedCodeFunctions* skipped_code_functions =
803 collect_code ? new(zone) SkippedCodeFunctions() : NULL; 727 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
804 SyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 728 SyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
805 &delay_set, skipped_code_functions); 729 &delay_set, skipped_code_functions);
806 IterateWeakReferences(isolate, &mark);
807 MarkingWeakVisitor mark_weak; 730 MarkingWeakVisitor mark_weak;
808 IterateWeakRoots(isolate, &mark_weak, 731 IterateWeakRoots(isolate, &mark_weak);
809 !visit_prologue_weak_persistent_handles);
810 barrier.Sync(); 732 barrier.Sync();
811 733
812 // Phase 3: Finalize results from all markers (detach code, etc.). 734 // Phase 3: Finalize results from all markers (detach code, etc.).
813 if (FLAG_log_marker_tasks) { 735 if (FLAG_log_marker_tasks) {
814 THR_Print("Main thread marked %" Pd " bytes.\n", 736 THR_Print("Main thread marked %" Pd " bytes.\n",
815 mark.marked_bytes()); 737 mark.marked_bytes());
816 } 738 }
817 FinalizeResultsFrom(&mark); 739 FinalizeResultsFrom(&mark);
818 barrier.Exit(); 740 barrier.Exit();
819 } 741 }
820 delay_set.ClearReferences(); 742 delay_set.ClearReferences();
821 ProcessWeakTables(page_space); 743 ProcessWeakTables(page_space);
822 ProcessObjectIdTable(isolate); 744 ProcessObjectIdTable(isolate);
823 } 745 }
824 Epilogue(isolate, invoke_api_callbacks); 746 Epilogue(isolate, invoke_api_callbacks);
825 } 747 }
826 748
827 } // namespace dart 749 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/gc_marker.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698