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

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

Issue 1309033007: Old-gen marking on separate thread (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Revert static method change. 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/thread.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
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_pool.h" 19 #include "vm/thread_pool.h"
20 #include "vm/visitor.h" 20 #include "vm/visitor.h"
21 #include "vm/object_id_ring.h" 21 #include "vm/object_id_ring.h"
22 22
23 namespace dart { 23 namespace dart {
24 24
25 DEFINE_FLAG(int, marker_tasks, 1,
26 "The number of tasks to spawn during old gen GC marking (0 means "
27 "perform all marking on main thread).");
28
25 typedef StoreBufferBlock PointerBlock; // TODO(koda): Rename to PointerBlock. 29 typedef StoreBufferBlock PointerBlock; // TODO(koda): Rename to PointerBlock.
26 typedef StoreBuffer MarkingStack; // TODO(koda): Create shared base class. 30 typedef StoreBuffer MarkingStack; // TODO(koda): Create shared base class.
27 31
28 class DelaySet { 32 class DelaySet {
29 private: 33 private:
30 typedef std::multimap<RawObject*, RawWeakProperty*> Map; 34 typedef std::multimap<RawObject*, RawWeakProperty*> Map;
31 typedef std::pair<RawObject*, RawWeakProperty*> MapEntry; 35 typedef std::pair<RawObject*, RawWeakProperty*> MapEntry;
32 36
33 public: 37 public:
34 DelaySet() : mutex_(new Mutex()) {} 38 DelaySet() : mutex_(new Mutex()) {}
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 538
535 539
536 void GCMarker::ProcessObjectIdTable(Isolate* isolate) { 540 void GCMarker::ProcessObjectIdTable(Isolate* isolate) {
537 ObjectIdRingClearPointerVisitor visitor(isolate); 541 ObjectIdRingClearPointerVisitor visitor(isolate);
538 ObjectIdRing* ring = isolate->object_id_ring(); 542 ObjectIdRing* ring = isolate->object_id_ring();
539 ASSERT(ring != NULL); 543 ASSERT(ring != NULL);
540 ring->VisitPointers(&visitor); 544 ring->VisitPointers(&visitor);
541 } 545 }
542 546
543 547
548 class MarkTask : public ThreadPool::Task {
549 public:
550 MarkTask(GCMarker* marker,
551 Isolate* isolate,
552 Heap* heap,
553 PageSpace* page_space,
554 MarkingStack* marking_stack,
555 DelaySet* delay_set,
556 bool collect_code,
557 bool visit_prologue_weak_persistent_handles)
558 : marker_(marker),
559 isolate_(isolate),
560 heap_(heap),
561 page_space_(page_space),
562 marking_stack_(marking_stack),
563 delay_set_(delay_set),
564 collect_code_(collect_code),
565 visit_prologue_weak_persistent_handles_(
566 visit_prologue_weak_persistent_handles) {
567 }
568
569 virtual void Run() {
570 Thread::EnterIsolateAsHelper(isolate_, true);
571 {
572 StackZone stack_zone(Thread::Current());
573 Zone* zone = stack_zone.GetZone();
574 SkippedCodeFunctions* skipped_code_functions =
575 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL;
576 MarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
577 delay_set_, skipped_code_functions);
578 // Phase 1: Populate and drain marking stack in task.
579 // TODO(koda): Split root iteration work among multiple tasks.
580 marker_->IterateRoots(isolate_, &visitor,
581 visit_prologue_weak_persistent_handles_);
582 visitor.DrainMarkingStack();
583 marker_->TaskSync();
584 // Phase 2: Weak processing and follow-up marking on main thread.
585 marker_->TaskSync();
586 // Phase 3: Finalize results from all markers (detach code, etc.).
587 marker_->FinalizeResultsFrom(&visitor);
588 }
589 Thread::ExitIsolateAsHelper(true);
590 // This task is done. Notify the original thread.
591 marker_->TaskNotifyDone();
592 }
593
594 private:
595 GCMarker* marker_;
596 Isolate* isolate_;
597 Heap* heap_;
598 PageSpace* page_space_;
599 MarkingStack* marking_stack_;
600 DelaySet* delay_set_;
601 bool collect_code_;
602 bool visit_prologue_weak_persistent_handles_;
603
604 DISALLOW_COPY_AND_ASSIGN(MarkTask);
605 };
606
607
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) {
642 {
643 MonitorLocker ml(&monitor_);
644 marked_bytes_ += visitor->marked_bytes();
645 }
646 visitor->Finalize();
647 }
648
649
544 void GCMarker::MarkObjects(Isolate* isolate, 650 void GCMarker::MarkObjects(Isolate* isolate,
545 PageSpace* page_space, 651 PageSpace* page_space,
546 bool invoke_api_callbacks, 652 bool invoke_api_callbacks,
547 bool collect_code) { 653 bool collect_code) {
548 Prologue(isolate, invoke_api_callbacks); 654 Prologue(isolate, invoke_api_callbacks);
549 // The API prologue/epilogue may create/destroy zones, so we must not 655 // The API prologue/epilogue may create/destroy zones, so we must not
550 // depend on zone allocations surviving beyond the epilogue callback. 656 // depend on zone allocations surviving beyond the epilogue callback.
551 { 657 {
552 StackZone stack_zone(Thread::Current()); 658 StackZone stack_zone(Thread::Current());
553 Zone* zone = stack_zone.GetZone(); 659 Zone* zone = stack_zone.GetZone();
554 MarkingStack marking_stack; 660 MarkingStack marking_stack;
555 DelaySet delay_set; 661 DelaySet delay_set;
556 SkippedCodeFunctions* skipped_code_functions = 662 const bool visit_prologue_weak_persistent_handles = !invoke_api_callbacks;
557 collect_code ? new(zone) SkippedCodeFunctions() : NULL; 663 marked_bytes_ = 0;
558 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 664 const int num_tasks = FLAG_marker_tasks;
559 &delay_set, skipped_code_functions); 665 if (num_tasks == 0) {
560 IterateRoots(isolate, &mark, !invoke_api_callbacks); 666 // Mark everything on main thread.
561 mark.DrainMarkingStack(); 667 SkippedCodeFunctions* skipped_code_functions =
562 IterateWeakReferences(isolate, &mark); 668 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
563 MarkingWeakVisitor mark_weak; 669 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
564 IterateWeakRoots(isolate, &mark_weak, invoke_api_callbacks); 670 &delay_set, skipped_code_functions);
565 // TODO(koda): Add hand-over callback. 671 IterateRoots(isolate, &mark, visit_prologue_weak_persistent_handles);
566 marked_bytes_ = mark.marked_bytes(); 672 mark.DrainMarkingStack();
567 mark.Finalize(); 673 IterateWeakReferences(isolate, &mark);
674 MarkingWeakVisitor mark_weak;
675 IterateWeakRoots(isolate, &mark_weak,
676 !visit_prologue_weak_persistent_handles);
677 // All marking done; detach code, etc.
678 FinalizeResultsFrom(&mark);
679 } else {
680 if (num_tasks > 1) {
681 // TODO(koda): Support multiple:
682 // 1. non-concurrent tasks, after splitting root iteration work, then
683 // 2. concurrent tasks, after synchronizing headers.
684 FATAL("Multiple marking tasks not yet supported");
685 }
686 // Phase 1: Populate and drain marking stack in task.
687 MarkTask* mark_task =
688 new MarkTask(this, isolate, heap_, page_space, &marking_stack,
689 &delay_set, collect_code,
690 visit_prologue_weak_persistent_handles);
691 ThreadPool* pool = Dart::thread_pool();
692 pool->Run(mark_task);
693 MainSync(num_tasks);
694 // Phase 2: Weak processing and follow-up marking on main thread.
695 SkippedCodeFunctions* skipped_code_functions =
696 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
697 MarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
698 &delay_set, skipped_code_functions);
699 IterateWeakReferences(isolate, &mark);
700 MarkingWeakVisitor mark_weak;
701 IterateWeakRoots(isolate, &mark_weak,
702 !visit_prologue_weak_persistent_handles);
703 // TODO(koda): Move this into Phase 3 after making ISL_Print thread-safe
704 // (used in SkippedCodeFunctions::DetachCode).
705 FinalizeResultsFrom(&mark);
706 MainSync(num_tasks);
707 // Phase 3: Finalize results from all markers (detach code, etc.).
708 MainSync(num_tasks);
709 // Finalization complete and all tasks exited.
710 }
568 delay_set.ClearReferences(); 711 delay_set.ClearReferences();
569 ProcessWeakTables(page_space); 712 ProcessWeakTables(page_space);
570 ProcessObjectIdTable(isolate); 713 ProcessObjectIdTable(isolate);
571 } 714 }
572 Epilogue(isolate, invoke_api_callbacks); 715 Epilogue(isolate, invoke_api_callbacks);
573 } 716 }
574 717
575 } // namespace dart 718 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/gc_marker.h ('k') | runtime/vm/thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698