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" |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); | 413 double avg_frac = stats_history_.Get(0).PromoCandidatesSuccessFraction(); |
414 if (stats_history_.Size() >= 2) { | 414 if (stats_history_.Size() >= 2) { |
415 // Previous scavenge is only given half as much weight. | 415 // Previous scavenge is only given half as much weight. |
416 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); | 416 avg_frac += 0.5 * stats_history_.Get(1).PromoCandidatesSuccessFraction(); |
417 avg_frac /= 1.0 + 0.5; // Normalize. | 417 avg_frac /= 1.0 + 0.5; // Normalize. |
418 } | 418 } |
419 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { | 419 if (avg_frac < (FLAG_early_tenuring_threshold / 100.0)) { |
420 // Remember the limit to which objects have been copied. | 420 // Remember the limit to which objects have been copied. |
421 survivor_end_ = top_; | 421 survivor_end_ = top_; |
422 } else { | 422 } else { |
| 423 OS::Print("early tenuring!\n"); |
423 // Move survivor end to the end of the to_ space, making all surviving | 424 // Move survivor end to the end of the to_ space, making all surviving |
424 // objects candidates for promotion next time. | 425 // objects candidates for promotion next time. |
425 survivor_end_ = end_; | 426 survivor_end_ = end_; |
426 } | 427 } |
427 #if defined(DEBUG) | 428 #if defined(DEBUG) |
428 // We can only safely verify the store buffers from old space if there is no | 429 // We can only safely verify the store buffers from old space if there is no |
429 // concurrent old space task. At the same time we prevent new tasks from | 430 // concurrent old space task. At the same time we prevent new tasks from |
430 // being spawned. | 431 // being spawned. |
431 { | 432 { |
432 PageSpace* page_space = heap_->old_space(); | 433 PageSpace* page_space = heap_->old_space(); |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 } | 836 } |
836 | 837 |
837 // Prepare for a scavenge. | 838 // Prepare for a scavenge. |
838 SpaceUsage usage_before = GetCurrentUsage(); | 839 SpaceUsage usage_before = GetCurrentUsage(); |
839 intptr_t promo_candidate_words = | 840 intptr_t promo_candidate_words = |
840 (survivor_end_ - FirstObjectStart()) / kWordSize; | 841 (survivor_end_ - FirstObjectStart()) / kWordSize; |
841 SemiSpace* from = Prologue(isolate, invoke_api_callbacks); | 842 SemiSpace* from = Prologue(isolate, invoke_api_callbacks); |
842 // The API prologue/epilogue may create/destroy zones, so we must not | 843 // The API prologue/epilogue may create/destroy zones, so we must not |
843 // depend on zone allocations surviving beyond the epilogue callback. | 844 // depend on zone allocations surviving beyond the epilogue callback. |
844 { | 845 { |
| 846 intptr_t scavenge_rate = ScavengeRateInBytesPerMicro(); |
| 847 intptr_t est_time = usage_before.used_in_words * kWordSize / scavenge_rate; |
| 848 |
845 StackZone zone(thread); | 849 StackZone zone(thread); |
846 // Setup the visitor and run the scavenge. | 850 // Setup the visitor and run the scavenge. |
847 ScavengerVisitor visitor(isolate, this, from); | 851 ScavengerVisitor visitor(isolate, this, from); |
848 page_space->AcquireDataLock(); | 852 page_space->AcquireDataLock(); |
849 IterateRoots(isolate, &visitor); | 853 IterateRoots(isolate, &visitor); |
850 int64_t start = OS::GetCurrentMonotonicMicros(); | 854 int64_t start = OS::GetCurrentMonotonicMicros(); |
851 ProcessToSpace(&visitor); | 855 ProcessToSpace(&visitor); |
852 int64_t middle = OS::GetCurrentMonotonicMicros(); | 856 int64_t middle = OS::GetCurrentMonotonicMicros(); |
853 { | 857 { |
854 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); | 858 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); |
855 ScavengerWeakVisitor weak_visitor(thread, this); | 859 ScavengerWeakVisitor weak_visitor(thread, this); |
856 IterateWeakRoots(isolate, &weak_visitor); | 860 IterateWeakRoots(isolate, &weak_visitor); |
857 } | 861 } |
858 ProcessWeakReferences(); | 862 ProcessWeakReferences(); |
859 page_space->ReleaseDataLock(); | 863 page_space->ReleaseDataLock(); |
860 | 864 |
861 // Scavenge finished. Run accounting. | 865 // Scavenge finished. Run accounting. |
862 int64_t end = OS::GetCurrentMonotonicMicros(); | 866 int64_t end = OS::GetCurrentMonotonicMicros(); |
863 heap_->RecordTime(kProcessToSpace, middle - start); | 867 heap_->RecordTime(kProcessToSpace, middle - start); |
864 heap_->RecordTime(kIterateWeaks, end - middle); | 868 heap_->RecordTime(kIterateWeaks, end - middle); |
| 869 SpaceUsage usage_after = GetCurrentUsage(); |
865 stats_history_.Add(ScavengeStats( | 870 stats_history_.Add(ScavengeStats( |
866 start, end, usage_before, GetCurrentUsage(), promo_candidate_words, | 871 start, end, usage_before, usage_after, promo_candidate_words, |
867 visitor.bytes_promoted() >> kWordSizeLog2)); | 872 visitor.bytes_promoted() >> kWordSizeLog2)); |
| 873 |
| 874 intptr_t size_before = usage_before.used_in_words * kWordSize; |
| 875 intptr_t survivor_tenured = visitor.bytes_promoted(); |
| 876 intptr_t survivor_nontenured = usage_after.used_in_words * kWordSize; |
| 877 intptr_t actual_time = end - start; |
| 878 |
| 879 OS::Print("rate=%7" Pd "B/us, " |
| 880 "size=%5" Pd "kB, " |
| 881 "survivor=%lf, " |
| 882 "tenured=%lf, " |
| 883 "nontenured=%lf, " |
| 884 "estimated=%5" Pd "ms, " |
| 885 "actual=%5" Pd "ms, " |
| 886 "headroom=%5" Pd "us\n", |
| 887 scavenge_rate, |
| 888 size_before / KB, |
| 889 (double)(survivor_tenured+survivor_nontenured)/(double)size_before
, |
| 890 (double)(survivor_tenured)/(double)size_before, |
| 891 (double)(survivor_nontenured)/(double)size_before, |
| 892 est_time / 1000, |
| 893 actual_time / 1000, |
| 894 (est_time - actual_time) |
| 895 ); |
868 } | 896 } |
869 Epilogue(isolate, from, invoke_api_callbacks); | 897 Epilogue(isolate, from, invoke_api_callbacks); |
870 | 898 |
871 // TODO(koda): Make verification more compatible with concurrent sweep. | 899 // TODO(koda): Make verification more compatible with concurrent sweep. |
872 if (FLAG_verify_after_gc && !FLAG_concurrent_sweep) { | 900 if (FLAG_verify_after_gc && !FLAG_concurrent_sweep) { |
873 OS::PrintErr("Verifying after Scavenge..."); | 901 OS::PrintErr("Verifying after Scavenge..."); |
874 heap_->Verify(kForbidMarked); | 902 heap_->Verify(kForbidMarked); |
875 OS::PrintErr(" done.\n"); | 903 OS::PrintErr(" done.\n"); |
876 } | 904 } |
877 | 905 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 return free_space >> kWordSizeLog2; | 991 return free_space >> kWordSizeLog2; |
964 } | 992 } |
965 | 993 |
966 int64_t Scavenger::UsedInWords() const { | 994 int64_t Scavenger::UsedInWords() const { |
967 int64_t free_space_in_tlab = FreeSpaceInWords(heap_->isolate()); | 995 int64_t free_space_in_tlab = FreeSpaceInWords(heap_->isolate()); |
968 int64_t max_space_used = (top_ - FirstObjectStart()) >> kWordSizeLog2; | 996 int64_t max_space_used = (top_ - FirstObjectStart()) >> kWordSizeLog2; |
969 return max_space_used - free_space_in_tlab; | 997 return max_space_used - free_space_in_tlab; |
970 } | 998 } |
971 | 999 |
972 } // namespace dart | 1000 } // namespace dart |
OLD | NEW |