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

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

Issue 1337943004: Add ThreadBarrier; use in GCMarker and unit test (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix git again. Created 5 years, 3 months 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_test.cc » ('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
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_pool.h" 20 #include "vm/thread_pool.h"
20 #include "vm/visitor.h" 21 #include "vm/visitor.h"
21 #include "vm/object_id_ring.h" 22 #include "vm/object_id_ring.h"
22 23
23 namespace dart { 24 namespace dart {
24 25
25 DEFINE_FLAG(int, marker_tasks, 1, 26 DEFINE_FLAG(int, marker_tasks, 1,
26 "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 "
27 "perform all marking on main thread)."); 28 "perform all marking on main thread).");
28 29
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 547
547 548
548 class MarkTask : public ThreadPool::Task { 549 class MarkTask : public ThreadPool::Task {
549 public: 550 public:
550 MarkTask(GCMarker* marker, 551 MarkTask(GCMarker* marker,
551 Isolate* isolate, 552 Isolate* isolate,
552 Heap* heap, 553 Heap* heap,
553 PageSpace* page_space, 554 PageSpace* page_space,
554 MarkingStack* marking_stack, 555 MarkingStack* marking_stack,
555 DelaySet* delay_set, 556 DelaySet* delay_set,
557 ThreadBarrier* barrier,
556 bool collect_code, 558 bool collect_code,
557 bool visit_prologue_weak_persistent_handles) 559 bool visit_prologue_weak_persistent_handles)
558 : marker_(marker), 560 : marker_(marker),
559 isolate_(isolate), 561 isolate_(isolate),
560 heap_(heap), 562 heap_(heap),
561 page_space_(page_space), 563 page_space_(page_space),
562 marking_stack_(marking_stack), 564 marking_stack_(marking_stack),
563 delay_set_(delay_set), 565 delay_set_(delay_set),
566 barrier_(barrier),
564 collect_code_(collect_code), 567 collect_code_(collect_code),
565 visit_prologue_weak_persistent_handles_( 568 visit_prologue_weak_persistent_handles_(
566 visit_prologue_weak_persistent_handles) { 569 visit_prologue_weak_persistent_handles) {
567 } 570 }
568 571
569 virtual void Run() { 572 virtual void Run() {
570 Thread::EnterIsolateAsHelper(isolate_, true); 573 Thread::EnterIsolateAsHelper(isolate_, true);
571 { 574 {
572 StackZone stack_zone(Thread::Current()); 575 StackZone stack_zone(Thread::Current());
573 Zone* zone = stack_zone.GetZone(); 576 Zone* zone = stack_zone.GetZone();
574 SkippedCodeFunctions* skipped_code_functions = 577 SkippedCodeFunctions* skipped_code_functions =
575 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL; 578 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL;
576 MarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_, 579 MarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
577 delay_set_, skipped_code_functions); 580 delay_set_, skipped_code_functions);
578 // Phase 1: Populate and drain marking stack in task. 581 // Phase 1: Populate and drain marking stack in task.
579 // TODO(koda): Split root iteration work among multiple tasks. 582 // TODO(koda): Split root iteration work among multiple tasks.
580 marker_->IterateRoots(isolate_, &visitor, 583 marker_->IterateRoots(isolate_, &visitor,
581 visit_prologue_weak_persistent_handles_); 584 visit_prologue_weak_persistent_handles_);
582 visitor.DrainMarkingStack(); 585 visitor.DrainMarkingStack();
583 marker_->TaskSync(); 586 barrier_->Sync();
584 // Phase 2: Weak processing and follow-up marking on main thread. 587 // Phase 2: Weak processing and follow-up marking on main thread.
585 marker_->TaskSync(); 588 barrier_->Sync();
586 // Phase 3: Finalize results from all markers (detach code, etc.). 589 // Phase 3: Finalize results from all markers (detach code, etc.).
587 marker_->FinalizeResultsFrom(&visitor); 590 marker_->FinalizeResultsFrom(&visitor);
588 } 591 }
589 Thread::ExitIsolateAsHelper(true); 592 Thread::ExitIsolateAsHelper(true);
590 // This task is done. Notify the original thread. 593 // This task is done. Notify the original thread.
591 marker_->TaskNotifyDone(); 594 barrier_->Exit();
592 } 595 }
593 596
594 private: 597 private:
595 GCMarker* marker_; 598 GCMarker* marker_;
596 Isolate* isolate_; 599 Isolate* isolate_;
597 Heap* heap_; 600 Heap* heap_;
598 PageSpace* page_space_; 601 PageSpace* page_space_;
599 MarkingStack* marking_stack_; 602 MarkingStack* marking_stack_;
600 DelaySet* delay_set_; 603 DelaySet* delay_set_;
604 ThreadBarrier* barrier_;
601 bool collect_code_; 605 bool collect_code_;
602 bool visit_prologue_weak_persistent_handles_; 606 bool visit_prologue_weak_persistent_handles_;
603 607
604 DISALLOW_COPY_AND_ASSIGN(MarkTask); 608 DISALLOW_COPY_AND_ASSIGN(MarkTask);
605 }; 609 };
606 610
607 611
608 void GCMarker::MainSync(intptr_t num_tasks) {
609 MonitorLocker ml(&monitor_);
610 while (done_count_ < num_tasks) {
611 ml.Wait();
612 }
613 done_count_ = 0; // Tasks may now resume.
614 // TODO(koda): Add barrier utility with two condition variables to allow for
615 // Notify rather than NotifyAll. Also use it for safepoints.
616 ml.NotifyAll();
617 }
618
619
620 void GCMarker::TaskNotifyDone() {
621 MonitorLocker ml(&monitor_);
622 ++done_count_;
623 // TODO(koda): Add barrier utility with two condition variables to allow for
624 // Notify rather than NotifyAll. Also use it for safepoints.
625 ml.NotifyAll();
626 }
627
628
629 void GCMarker::TaskSync() {
630 MonitorLocker ml(&monitor_);
631 ++done_count_;
632 ml.NotifyAll(); // Notify controller that this thread reached end of phase.
633 ASSERT(done_count_ > 0);
634 while (done_count_ > 0) {
635 // Wait for the controller to release into next phase.
636 ml.Wait();
637 }
638 }
639
640
641 void GCMarker::FinalizeResultsFrom(MarkingVisitor* visitor) { 612 void GCMarker::FinalizeResultsFrom(MarkingVisitor* visitor) {
642 { 613 {
643 MonitorLocker ml(&monitor_); 614 MonitorLocker ml(&monitor_);
644 marked_bytes_ += visitor->marked_bytes(); 615 marked_bytes_ += visitor->marked_bytes();
645 } 616 }
646 visitor->Finalize(); 617 visitor->Finalize();
647 } 618 }
648 619
649 620
650 void GCMarker::MarkObjects(Isolate* isolate, 621 void GCMarker::MarkObjects(Isolate* isolate,
(...skipping 25 matching lines...) Expand all
676 !visit_prologue_weak_persistent_handles); 647 !visit_prologue_weak_persistent_handles);
677 // All marking done; detach code, etc. 648 // All marking done; detach code, etc.
678 FinalizeResultsFrom(&mark); 649 FinalizeResultsFrom(&mark);
679 } else { 650 } else {
680 if (num_tasks > 1) { 651 if (num_tasks > 1) {
681 // TODO(koda): Support multiple: 652 // TODO(koda): Support multiple:
682 // 1. non-concurrent tasks, after splitting root iteration work, then 653 // 1. non-concurrent tasks, after splitting root iteration work, then
683 // 2. concurrent tasks, after synchronizing headers. 654 // 2. concurrent tasks, after synchronizing headers.
684 FATAL("Multiple marking tasks not yet supported"); 655 FATAL("Multiple marking tasks not yet supported");
685 } 656 }
657 ThreadBarrier barrier(num_tasks + 1); // +1 for the main thread.
686 // Phase 1: Populate and drain marking stack in task. 658 // Phase 1: Populate and drain marking stack in task.
687 MarkTask* mark_task = 659 MarkTask* mark_task =
688 new MarkTask(this, isolate, heap_, page_space, &marking_stack, 660 new MarkTask(this, isolate, heap_, page_space, &marking_stack,
689 &delay_set, collect_code, 661 &delay_set, &barrier, collect_code,
690 visit_prologue_weak_persistent_handles); 662 visit_prologue_weak_persistent_handles);
691 ThreadPool* pool = Dart::thread_pool(); 663 ThreadPool* pool = Dart::thread_pool();
692 pool->Run(mark_task); 664 pool->Run(mark_task);
693 MainSync(num_tasks); 665 barrier.Sync();
694 // Phase 2: Weak processing and follow-up marking on main thread. 666 // Phase 2: Weak processing and follow-up marking on main thread.
695 SkippedCodeFunctions* skipped_code_functions = 667 SkippedCodeFunctions* skipped_code_functions =
696 collect_code ? new(zone) SkippedCodeFunctions() : NULL; 668 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
697 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 669 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
698 &delay_set, skipped_code_functions); 670 &delay_set, skipped_code_functions);
699 IterateWeakReferences(isolate, &mark); 671 IterateWeakReferences(isolate, &mark);
700 MarkingWeakVisitor mark_weak; 672 MarkingWeakVisitor mark_weak;
701 IterateWeakRoots(isolate, &mark_weak, 673 IterateWeakRoots(isolate, &mark_weak,
702 !visit_prologue_weak_persistent_handles); 674 !visit_prologue_weak_persistent_handles);
703 MainSync(num_tasks); 675 barrier.Sync();
704 // Phase 3: Finalize results from all markers (detach code, etc.). 676 // Phase 3: Finalize results from all markers (detach code, etc.).
705 FinalizeResultsFrom(&mark); 677 FinalizeResultsFrom(&mark);
706 MainSync(num_tasks); 678 barrier.Exit();
707 // Finalization complete and all tasks exited.
708 } 679 }
709 delay_set.ClearReferences(); 680 delay_set.ClearReferences();
710 ProcessWeakTables(page_space); 681 ProcessWeakTables(page_space);
711 ProcessObjectIdTable(isolate); 682 ProcessObjectIdTable(isolate);
712 } 683 }
713 Epilogue(isolate, invoke_api_callbacks); 684 Epilogue(isolate, invoke_api_callbacks);
714 } 685 }
715 686
716 } // namespace dart 687 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/gc_marker.h ('k') | runtime/vm/isolate_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698