| 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 |