OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/heap/incremental-marking.h" | 7 #include "src/heap/incremental-marking.h" |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 if (IsStopped() && WorthActivating() && heap_->NextGCIsLikelyToBeFull()) { | 814 if (IsStopped() && WorthActivating() && heap_->NextGCIsLikelyToBeFull()) { |
815 // TODO(hpayer): Let's play safe for now, but compaction should be | 815 // TODO(hpayer): Let's play safe for now, but compaction should be |
816 // in principle possible. | 816 // in principle possible. |
817 Start(PREVENT_COMPACTION); | 817 Start(PREVENT_COMPACTION); |
818 } else { | 818 } else { |
819 Step(allocated * kFastMarking / kInitialMarkingSpeed, GC_VIA_STACK_GUARD); | 819 Step(allocated * kFastMarking / kInitialMarkingSpeed, GC_VIA_STACK_GUARD); |
820 } | 820 } |
821 } | 821 } |
822 | 822 |
823 | 823 |
| 824 void IncrementalMarking::SpeedUp() { |
| 825 bool speed_up = false; |
| 826 |
| 827 if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) { |
| 828 if (FLAG_trace_gc) { |
| 829 PrintPID("Speed up marking after %d steps\n", |
| 830 static_cast<int>(kMarkingSpeedAccellerationInterval)); |
| 831 } |
| 832 speed_up = true; |
| 833 } |
| 834 |
| 835 bool space_left_is_very_small = |
| 836 (old_generation_space_available_at_start_of_incremental_ < 10 * MB); |
| 837 |
| 838 bool only_1_nth_of_space_that_was_available_still_left = |
| 839 (SpaceLeftInOldSpace() * (marking_speed_ + 1) < |
| 840 old_generation_space_available_at_start_of_incremental_); |
| 841 |
| 842 if (space_left_is_very_small || |
| 843 only_1_nth_of_space_that_was_available_still_left) { |
| 844 if (FLAG_trace_gc) PrintPID("Speed up marking because of low space left\n"); |
| 845 speed_up = true; |
| 846 } |
| 847 |
| 848 bool size_of_old_space_multiplied_by_n_during_marking = |
| 849 (heap_->PromotedTotalSize() > |
| 850 (marking_speed_ + 1) * |
| 851 old_generation_space_used_at_start_of_incremental_); |
| 852 if (size_of_old_space_multiplied_by_n_during_marking) { |
| 853 speed_up = true; |
| 854 if (FLAG_trace_gc) { |
| 855 PrintPID("Speed up marking because of heap size increase\n"); |
| 856 } |
| 857 } |
| 858 |
| 859 int64_t promoted_during_marking = |
| 860 heap_->PromotedTotalSize() - |
| 861 old_generation_space_used_at_start_of_incremental_; |
| 862 intptr_t delay = marking_speed_ * MB; |
| 863 intptr_t scavenge_slack = heap_->MaxSemiSpaceSize(); |
| 864 |
| 865 // We try to scan at at least twice the speed that we are allocating. |
| 866 if (promoted_during_marking > bytes_scanned_ / 2 + scavenge_slack + delay) { |
| 867 if (FLAG_trace_gc) { |
| 868 PrintPID("Speed up marking because marker was not keeping up\n"); |
| 869 } |
| 870 speed_up = true; |
| 871 } |
| 872 |
| 873 if (speed_up) { |
| 874 if (state_ != MARKING) { |
| 875 if (FLAG_trace_gc) { |
| 876 PrintPID("Postponing speeding up marking until marking starts\n"); |
| 877 } |
| 878 } else { |
| 879 marking_speed_ += kMarkingSpeedAccelleration; |
| 880 marking_speed_ = static_cast<int>( |
| 881 Min(kMaxMarkingSpeed, static_cast<intptr_t>(marking_speed_ * 1.3))); |
| 882 if (FLAG_trace_gc) { |
| 883 PrintPID("Marking speed increased to %d\n", marking_speed_); |
| 884 } |
| 885 } |
| 886 } |
| 887 } |
| 888 |
| 889 |
824 void IncrementalMarking::Step(intptr_t allocated_bytes, CompletionAction action, | 890 void IncrementalMarking::Step(intptr_t allocated_bytes, CompletionAction action, |
825 bool force_marking) { | 891 bool force_marking) { |
826 if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking || | 892 if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking || |
827 !FLAG_incremental_marking_steps || | 893 !FLAG_incremental_marking_steps || |
828 (state_ != SWEEPING && state_ != MARKING)) { | 894 (state_ != SWEEPING && state_ != MARKING)) { |
829 return; | 895 return; |
830 } | 896 } |
831 | 897 |
832 allocated_ += allocated_bytes; | 898 allocated_ += allocated_bytes; |
833 | 899 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 bytes_scanned_ = 0; | 936 bytes_scanned_ = 0; |
871 StartMarking(PREVENT_COMPACTION); | 937 StartMarking(PREVENT_COMPACTION); |
872 } | 938 } |
873 } else if (state_ == MARKING) { | 939 } else if (state_ == MARKING) { |
874 bytes_processed = ProcessMarkingDeque(bytes_to_process); | 940 bytes_processed = ProcessMarkingDeque(bytes_to_process); |
875 if (marking_deque_.IsEmpty()) MarkingComplete(action); | 941 if (marking_deque_.IsEmpty()) MarkingComplete(action); |
876 } | 942 } |
877 | 943 |
878 steps_count_++; | 944 steps_count_++; |
879 | 945 |
880 bool speed_up = false; | 946 // Speed up marking if we are marking too slow or if we are almost done |
881 | 947 // with marking. |
882 if ((steps_count_ % kMarkingSpeedAccellerationInterval) == 0) { | 948 SpeedUp(); |
883 if (FLAG_trace_gc) { | |
884 PrintPID("Speed up marking after %d steps\n", | |
885 static_cast<int>(kMarkingSpeedAccellerationInterval)); | |
886 } | |
887 speed_up = true; | |
888 } | |
889 | |
890 bool space_left_is_very_small = | |
891 (old_generation_space_available_at_start_of_incremental_ < 10 * MB); | |
892 | |
893 bool only_1_nth_of_space_that_was_available_still_left = | |
894 (SpaceLeftInOldSpace() * (marking_speed_ + 1) < | |
895 old_generation_space_available_at_start_of_incremental_); | |
896 | |
897 if (space_left_is_very_small || | |
898 only_1_nth_of_space_that_was_available_still_left) { | |
899 if (FLAG_trace_gc) | |
900 PrintPID("Speed up marking because of low space left\n"); | |
901 speed_up = true; | |
902 } | |
903 | |
904 bool size_of_old_space_multiplied_by_n_during_marking = | |
905 (heap_->PromotedTotalSize() > | |
906 (marking_speed_ + 1) * | |
907 old_generation_space_used_at_start_of_incremental_); | |
908 if (size_of_old_space_multiplied_by_n_during_marking) { | |
909 speed_up = true; | |
910 if (FLAG_trace_gc) { | |
911 PrintPID("Speed up marking because of heap size increase\n"); | |
912 } | |
913 } | |
914 | |
915 int64_t promoted_during_marking = | |
916 heap_->PromotedTotalSize() - | |
917 old_generation_space_used_at_start_of_incremental_; | |
918 intptr_t delay = marking_speed_ * MB; | |
919 intptr_t scavenge_slack = heap_->MaxSemiSpaceSize(); | |
920 | |
921 // We try to scan at at least twice the speed that we are allocating. | |
922 if (promoted_during_marking > bytes_scanned_ / 2 + scavenge_slack + delay) { | |
923 if (FLAG_trace_gc) { | |
924 PrintPID("Speed up marking because marker was not keeping up\n"); | |
925 } | |
926 speed_up = true; | |
927 } | |
928 | |
929 if (speed_up) { | |
930 if (state_ != MARKING) { | |
931 if (FLAG_trace_gc) { | |
932 PrintPID("Postponing speeding up marking until marking starts\n"); | |
933 } | |
934 } else { | |
935 marking_speed_ += kMarkingSpeedAccelleration; | |
936 marking_speed_ = static_cast<int>( | |
937 Min(kMaxMarkingSpeed, static_cast<intptr_t>(marking_speed_ * 1.3))); | |
938 if (FLAG_trace_gc) { | |
939 PrintPID("Marking speed increased to %d\n", marking_speed_); | |
940 } | |
941 } | |
942 } | |
943 | 949 |
944 double end = base::OS::TimeCurrentMillis(); | 950 double end = base::OS::TimeCurrentMillis(); |
945 double duration = (end - start); | 951 double duration = (end - start); |
946 // Note that we report zero bytes here when sweeping was in progress or | 952 // Note that we report zero bytes here when sweeping was in progress or |
947 // when we just started incremental marking. In these cases we did not | 953 // when we just started incremental marking. In these cases we did not |
948 // process the marking deque. | 954 // process the marking deque. |
949 heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed); | 955 heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed); |
950 } | 956 } |
951 } | 957 } |
952 | 958 |
953 | 959 |
954 void IncrementalMarking::ResetStepCounters() { | 960 void IncrementalMarking::ResetStepCounters() { |
955 steps_count_ = 0; | 961 steps_count_ = 0; |
956 old_generation_space_available_at_start_of_incremental_ = | 962 old_generation_space_available_at_start_of_incremental_ = |
957 SpaceLeftInOldSpace(); | 963 SpaceLeftInOldSpace(); |
958 old_generation_space_used_at_start_of_incremental_ = | 964 old_generation_space_used_at_start_of_incremental_ = |
959 heap_->PromotedTotalSize(); | 965 heap_->PromotedTotalSize(); |
960 bytes_rescanned_ = 0; | 966 bytes_rescanned_ = 0; |
961 marking_speed_ = kInitialMarkingSpeed; | 967 marking_speed_ = kInitialMarkingSpeed; |
962 bytes_scanned_ = 0; | 968 bytes_scanned_ = 0; |
963 write_barriers_invoked_since_last_step_ = 0; | 969 write_barriers_invoked_since_last_step_ = 0; |
964 } | 970 } |
965 | 971 |
966 | 972 |
967 int64_t IncrementalMarking::SpaceLeftInOldSpace() { | 973 int64_t IncrementalMarking::SpaceLeftInOldSpace() { |
968 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects(); | 974 return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects(); |
969 } | 975 } |
970 } | 976 } |
971 } // namespace v8::internal | 977 } // namespace v8::internal |
OLD | NEW |