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