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/scavenger.h" | 5 #include "vm/scavenger.h" |
6 | 6 |
7 #include "vm/dart.h" | 7 #include "vm/dart.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/lockers.h" | 10 #include "vm/lockers.h" |
11 #include "vm/object.h" | 11 #include "vm/object.h" |
12 #include "vm/object_id_ring.h" | 12 #include "vm/object_id_ring.h" |
13 #include "vm/safepoint.h" | 13 #include "vm/safepoint.h" |
14 #include "vm/stack_frame.h" | 14 #include "vm/stack_frame.h" |
15 #include "vm/store_buffer.h" | 15 #include "vm/store_buffer.h" |
16 #include "vm/thread_registry.h" | 16 #include "vm/thread_registry.h" |
| 17 #include "vm/timeline.h" |
17 #include "vm/verified_memory.h" | 18 #include "vm/verified_memory.h" |
18 #include "vm/verifier.h" | 19 #include "vm/verifier.h" |
19 #include "vm/visitor.h" | 20 #include "vm/visitor.h" |
20 #include "vm/weak_table.h" | 21 #include "vm/weak_table.h" |
21 | 22 |
22 namespace dart { | 23 namespace dart { |
23 | 24 |
24 DEFINE_FLAG(int, early_tenuring_threshold, 66, | 25 DEFINE_FLAG(int, early_tenuring_threshold, 66, |
25 "When more than this percentage of promotion candidates survive, " | 26 "When more than this percentage of promotion candidates survive, " |
26 "promote all survivors of next scavenge."); | 27 "promote all survivors of next scavenge."); |
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 } | 772 } |
772 | 773 |
773 | 774 |
774 void Scavenger::Scavenge(bool invoke_api_callbacks) { | 775 void Scavenger::Scavenge(bool invoke_api_callbacks) { |
775 Isolate* isolate = heap_->isolate(); | 776 Isolate* isolate = heap_->isolate(); |
776 // Ensure that all threads for this isolate are at a safepoint (either stopped | 777 // Ensure that all threads for this isolate are at a safepoint (either stopped |
777 // or in native code). If two threads are racing at this point, the loser | 778 // or in native code). If two threads are racing at this point, the loser |
778 // will continue with its scavenge after waiting for the winner to complete. | 779 // will continue with its scavenge after waiting for the winner to complete. |
779 // TODO(koda): Consider moving SafepointThreads into allocation failure/retry | 780 // TODO(koda): Consider moving SafepointThreads into allocation failure/retry |
780 // logic to avoid needless collections. | 781 // logic to avoid needless collections. |
781 SafepointOperationScope safepoint_scope(Thread::Current()); | 782 Thread* thread = Thread::Current(); |
| 783 SafepointOperationScope safepoint_scope(thread); |
782 | 784 |
783 // Scavenging is not reentrant. Make sure that is the case. | 785 // Scavenging is not reentrant. Make sure that is the case. |
784 ASSERT(!scavenging_); | 786 ASSERT(!scavenging_); |
785 scavenging_ = true; | 787 scavenging_ = true; |
786 | 788 |
787 PageSpace* page_space = heap_->old_space(); | 789 PageSpace* page_space = heap_->old_space(); |
788 NoSafepointScope no_safepoints; | 790 NoSafepointScope no_safepoints; |
789 | 791 |
790 // TODO(koda): Make verification more compatible with concurrent sweep. | 792 // TODO(koda): Make verification more compatible with concurrent sweep. |
791 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { | 793 if (FLAG_verify_before_gc && !FLAG_concurrent_sweep) { |
792 OS::PrintErr("Verifying before Scavenge..."); | 794 OS::PrintErr("Verifying before Scavenge..."); |
793 heap_->Verify(kForbidMarked); | 795 heap_->Verify(kForbidMarked); |
794 OS::PrintErr(" done.\n"); | 796 OS::PrintErr(" done.\n"); |
795 } | 797 } |
796 | 798 |
797 // Prepare for a scavenge. | 799 // Prepare for a scavenge. |
798 SpaceUsage usage_before = GetCurrentUsage(); | 800 SpaceUsage usage_before = GetCurrentUsage(); |
799 intptr_t promo_candidate_words = | 801 intptr_t promo_candidate_words = |
800 (survivor_end_ - FirstObjectStart()) / kWordSize; | 802 (survivor_end_ - FirstObjectStart()) / kWordSize; |
801 SemiSpace* from = Prologue(isolate, invoke_api_callbacks); | 803 SemiSpace* from = Prologue(isolate, invoke_api_callbacks); |
802 // The API prologue/epilogue may create/destroy zones, so we must not | 804 // The API prologue/epilogue may create/destroy zones, so we must not |
803 // depend on zone allocations surviving beyond the epilogue callback. | 805 // depend on zone allocations surviving beyond the epilogue callback. |
804 { | 806 { |
805 StackZone zone(Thread::Current()); | 807 StackZone zone(thread); |
806 // Setup the visitor and run the scavenge. | 808 // Setup the visitor and run the scavenge. |
807 ScavengerVisitor visitor(isolate, this, from); | 809 ScavengerVisitor visitor(isolate, this, from); |
808 page_space->AcquireDataLock(); | 810 page_space->AcquireDataLock(); |
809 IterateRoots(isolate, &visitor); | 811 IterateRoots(isolate, &visitor); |
810 int64_t start = OS::GetCurrentTimeMicros(); | 812 int64_t start = OS::GetCurrentTimeMicros(); |
811 ProcessToSpace(&visitor); | 813 ProcessToSpace(&visitor); |
812 int64_t middle = OS::GetCurrentTimeMicros(); | 814 int64_t middle = OS::GetCurrentTimeMicros(); |
813 ScavengerWeakVisitor weak_visitor(this); | 815 { |
814 IterateWeakRoots(isolate, &weak_visitor); | 816 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); |
| 817 ScavengerWeakVisitor weak_visitor(this); |
| 818 IterateWeakRoots(isolate, &weak_visitor); |
| 819 } |
815 ProcessWeakReferences(); | 820 ProcessWeakReferences(); |
816 page_space->ReleaseDataLock(); | 821 page_space->ReleaseDataLock(); |
817 | 822 |
818 // Scavenge finished. Run accounting. | 823 // Scavenge finished. Run accounting. |
819 int64_t end = OS::GetCurrentTimeMicros(); | 824 int64_t end = OS::GetCurrentTimeMicros(); |
820 heap_->RecordTime(kProcessToSpace, middle - start); | 825 heap_->RecordTime(kProcessToSpace, middle - start); |
821 heap_->RecordTime(kIterateWeaks, end - middle); | 826 heap_->RecordTime(kIterateWeaks, end - middle); |
822 stats_history_.Add( | 827 stats_history_.Add( |
823 ScavengeStats(start, end, | 828 ScavengeStats(start, end, |
824 usage_before, GetCurrentUsage(), | 829 usage_before, GetCurrentUsage(), |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 } | 886 } |
882 | 887 |
883 | 888 |
884 void Scavenger::FreeExternal(intptr_t size) { | 889 void Scavenger::FreeExternal(intptr_t size) { |
885 ASSERT(size >= 0); | 890 ASSERT(size >= 0); |
886 external_size_ -= size; | 891 external_size_ -= size; |
887 ASSERT(external_size_ >= 0); | 892 ASSERT(external_size_ >= 0); |
888 } | 893 } |
889 | 894 |
890 } // namespace dart | 895 } // namespace dart |
OLD | NEW |