Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(594)

Side by Side Diff: src/heap/gc-idle-time-handler.h

Issue 1105293004: Add mode to reduce memory usage in idle notification. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add checks in tests Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/heap/gc-idle-time-handler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 #ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_ 5 #ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_
6 #define V8_HEAP_GC_IDLE_TIME_HANDLER_H_ 6 #define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
7 7
8 #include "src/globals.h" 8 #include "src/globals.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13 enum GCIdleTimeActionType { 13 enum GCIdleTimeActionType {
14 DONE, 14 DONE,
15 DO_NOTHING, 15 DO_NOTHING,
16 DO_INCREMENTAL_MARKING, 16 DO_INCREMENTAL_MARKING,
17 DO_SCAVENGE, 17 DO_SCAVENGE,
18 DO_FULL_GC, 18 DO_FULL_GC,
19 DO_FINALIZE_SWEEPING 19 DO_FINALIZE_SWEEPING
20 }; 20 };
21 21
22 22
23 class GCIdleTimeAction { 23 class GCIdleTimeAction {
24 public: 24 public:
25 static GCIdleTimeAction Done() { 25 static GCIdleTimeAction Done() {
26 GCIdleTimeAction result; 26 GCIdleTimeAction result;
27 result.type = DONE; 27 result.type = DONE;
28 result.parameter = 0; 28 result.parameter = 0;
29 result.additional_work = false; 29 result.additional_work = false;
30 result.reduce_memory = false;
30 return result; 31 return result;
31 } 32 }
32 33
33 static GCIdleTimeAction Nothing() { 34 static GCIdleTimeAction Nothing() {
34 GCIdleTimeAction result; 35 GCIdleTimeAction result;
35 result.type = DO_NOTHING; 36 result.type = DO_NOTHING;
36 result.parameter = 0; 37 result.parameter = 0;
37 result.additional_work = false; 38 result.additional_work = false;
39 result.reduce_memory = false;
38 return result; 40 return result;
39 } 41 }
40 42
41 static GCIdleTimeAction IncrementalMarking(intptr_t step_size) { 43 static GCIdleTimeAction IncrementalMarking(intptr_t step_size,
44 bool reduce_memory) {
42 GCIdleTimeAction result; 45 GCIdleTimeAction result;
43 result.type = DO_INCREMENTAL_MARKING; 46 result.type = DO_INCREMENTAL_MARKING;
44 result.parameter = step_size; 47 result.parameter = step_size;
45 result.additional_work = false; 48 result.additional_work = false;
49 result.reduce_memory = reduce_memory;
46 return result; 50 return result;
47 } 51 }
48 52
49 static GCIdleTimeAction Scavenge() { 53 static GCIdleTimeAction Scavenge() {
50 GCIdleTimeAction result; 54 GCIdleTimeAction result;
51 result.type = DO_SCAVENGE; 55 result.type = DO_SCAVENGE;
52 result.parameter = 0; 56 result.parameter = 0;
53 result.additional_work = false; 57 result.additional_work = false;
58 // TODO(ulan): add reduce_memory argument and shrink new space size if
59 // reduce_memory = true.
60 result.reduce_memory = false;
54 return result; 61 return result;
55 } 62 }
56 63
57 static GCIdleTimeAction FullGC() { 64 static GCIdleTimeAction FullGC(bool reduce_memory) {
58 GCIdleTimeAction result; 65 GCIdleTimeAction result;
59 result.type = DO_FULL_GC; 66 result.type = DO_FULL_GC;
60 result.parameter = 0; 67 result.parameter = 0;
61 result.additional_work = false; 68 result.additional_work = false;
69 result.reduce_memory = reduce_memory;
62 return result; 70 return result;
63 } 71 }
64 72
65 static GCIdleTimeAction FinalizeSweeping() { 73 static GCIdleTimeAction FinalizeSweeping() {
66 GCIdleTimeAction result; 74 GCIdleTimeAction result;
67 result.type = DO_FINALIZE_SWEEPING; 75 result.type = DO_FINALIZE_SWEEPING;
68 result.parameter = 0; 76 result.parameter = 0;
69 result.additional_work = false; 77 result.additional_work = false;
78 result.reduce_memory = false;
70 return result; 79 return result;
71 } 80 }
72 81
73 void Print(); 82 void Print();
74 83
75 GCIdleTimeActionType type; 84 GCIdleTimeActionType type;
76 intptr_t parameter; 85 intptr_t parameter;
77 bool additional_work; 86 bool additional_work;
87 bool reduce_memory;
78 }; 88 };
79 89
80 90
81 class GCTracer; 91 class GCTracer;
82 92
83 // The idle time handler makes decisions about which garbage collection 93 // The idle time handler makes decisions about which garbage collection
84 // operations are executing during IdleNotification. 94 // operations are executing during IdleNotification.
85 class GCIdleTimeHandler { 95 class GCIdleTimeHandler {
86 public: 96 public:
87 // If we haven't recorded any incremental marking events yet, we carefully 97 // If we haven't recorded any incremental marking events yet, we carefully
(...skipping 16 matching lines...) Expand all
104 static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed = 114 static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
105 2 * MB; 115 2 * MB;
106 116
107 // Maximum mark-compact time returned by EstimateMarkCompactTime. 117 // Maximum mark-compact time returned by EstimateMarkCompactTime.
108 static const size_t kMaxMarkCompactTimeInMs; 118 static const size_t kMaxMarkCompactTimeInMs;
109 119
110 // Maximum final incremental mark-compact time returned by 120 // Maximum final incremental mark-compact time returned by
111 // EstimateFinalIncrementalMarkCompactTime. 121 // EstimateFinalIncrementalMarkCompactTime.
112 static const size_t kMaxFinalIncrementalMarkCompactTimeInMs; 122 static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
113 123
114 // Number of idle mark-compact events, after which idle handler will finish
115 // idle round.
116 static const int kMaxMarkCompactsInIdleRound;
117
118 // Number of scavenges that will trigger start of new idle round.
119 static const int kIdleScavengeThreshold;
120
121 // This is the maximum scheduled idle time. Note that it can be more than 124 // This is the maximum scheduled idle time. Note that it can be more than
122 // 16.66 ms when there is currently no rendering going on. 125 // 16.66 ms when there is currently no rendering going on.
123 static const size_t kMaxScheduledIdleTime = 50; 126 static const size_t kMaxScheduledIdleTime = 50;
124 127
125 // The maximum idle time when frames are rendered is 16.66ms. 128 // The maximum idle time when frames are rendered is 16.66ms.
126 static const size_t kMaxFrameRenderingIdleTime = 17; 129 static const size_t kMaxFrameRenderingIdleTime = 17;
127 130
128 // We conservatively assume that in the next kTimeUntilNextIdleEvent ms 131 // We conservatively assume that in the next kTimeUntilNextIdleEvent ms
129 // no idle notification happens. 132 // no idle notification happens.
130 static const size_t kTimeUntilNextIdleEvent = 100; 133 static const size_t kTimeUntilNextIdleEvent = 100;
131 134
132 // If we haven't recorded any scavenger events yet, we use a conservative 135 // If we haven't recorded any scavenger events yet, we use a conservative
133 // lower bound for the scavenger speed. 136 // lower bound for the scavenger speed.
134 static const size_t kInitialConservativeScavengeSpeed = 100 * KB; 137 static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
135 138
136 // If contexts are disposed at a higher rate a full gc is triggered. 139 // If contexts are disposed at a higher rate a full gc is triggered.
137 static const double kHighContextDisposalRate; 140 static const double kHighContextDisposalRate;
138 141
139 // Incremental marking step time. 142 // Incremental marking step time.
140 static const size_t kIncrementalMarkingStepTimeInMs = 1; 143 static const size_t kIncrementalMarkingStepTimeInMs = 1;
141 144
142 static const size_t kMinTimeForOverApproximatingWeakClosureInMs; 145 static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
143 146
144 // Number of times we will return a Nothing action per Idle round despite 147 // The number of idle MarkCompact GCs to perform before transitioning to
145 // having idle time available before we returning a Done action to ensure we 148 // the kDone mode.
146 // don't keep scheduling idle tasks and making no progress. 149 static const int kMaxIdleMarkCompacts = 3;
147 static const int kMaxNoProgressIdleTimesPerIdleRound = 10; 150
151 // The number of mutator GCs before transitioning to the kReduceLatency mode.
152 static const int kGCsBeforeMutatorIsActive = 7;
153
154 // Mutator is considered idle if
155 // 1) there is an idle notification with time >= kLargeLongIdleTime,
156 // 2) or there are kLongIdleNotificationsBeforeMutatorIsIdle idle
157 // notifications
158 // with time >= kMinLongIdleTime and without any mutator GC in between.
159 static const int kMinLongIdleTime = kMaxFrameRenderingIdleTime + 1;
160 static const int kLargeLongIdleTime = 900;
161 static const int kLongIdleNotificationsBeforeMutatorIsIdle = 20;
162
148 163
149 class HeapState { 164 class HeapState {
150 public: 165 public:
151 void Print(); 166 void Print();
152 167
153 int contexts_disposed; 168 int contexts_disposed;
154 double contexts_disposal_rate; 169 double contexts_disposal_rate;
155 size_t size_of_objects; 170 size_t size_of_objects;
156 bool incremental_marking_stopped; 171 bool incremental_marking_stopped;
157 bool can_start_incremental_marking; 172 bool can_start_incremental_marking;
158 bool sweeping_in_progress; 173 bool sweeping_in_progress;
159 bool sweeping_completed; 174 bool sweeping_completed;
160 size_t mark_compact_speed_in_bytes_per_ms; 175 size_t mark_compact_speed_in_bytes_per_ms;
161 size_t incremental_marking_speed_in_bytes_per_ms; 176 size_t incremental_marking_speed_in_bytes_per_ms;
162 size_t final_incremental_mark_compact_speed_in_bytes_per_ms; 177 size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
163 size_t scavenge_speed_in_bytes_per_ms; 178 size_t scavenge_speed_in_bytes_per_ms;
164 size_t used_new_space_size; 179 size_t used_new_space_size;
165 size_t new_space_capacity; 180 size_t new_space_capacity;
166 size_t new_space_allocation_throughput_in_bytes_per_ms; 181 size_t new_space_allocation_throughput_in_bytes_per_ms;
167 }; 182 };
168 183
169 GCIdleTimeHandler() 184 GCIdleTimeHandler()
170 : mark_compacts_since_idle_round_started_(0), 185 : idle_mark_compacts_(0),
171 scavenges_since_last_idle_round_(0), 186 mark_compacts_(0),
172 idle_times_which_made_no_progress_since_last_idle_round_(0) {} 187 scavenges_(0),
188 long_idle_notifications_(0),
189 mode_(kReduceLatency) {}
173 190
174 GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state); 191 GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
175 192
176 void NotifyIdleMarkCompact() { 193 void NotifyIdleMarkCompact() { ++idle_mark_compacts_; }
177 if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
178 ++mark_compacts_since_idle_round_started_;
179 if (mark_compacts_since_idle_round_started_ ==
180 kMaxMarkCompactsInIdleRound) {
181 scavenges_since_last_idle_round_ = 0;
182 }
183 }
184 }
185 194
186 void NotifyScavenge() { ++scavenges_since_last_idle_round_; } 195 void NotifyMarkCompact() { ++mark_compacts_; }
196
197 void NotifyScavenge() { ++scavenges_; }
187 198
188 static size_t EstimateMarkingStepSize(size_t idle_time_in_ms, 199 static size_t EstimateMarkingStepSize(size_t idle_time_in_ms,
189 size_t marking_speed_in_bytes_per_ms); 200 size_t marking_speed_in_bytes_per_ms);
190 201
191 static size_t EstimateMarkCompactTime( 202 static size_t EstimateMarkCompactTime(
192 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms); 203 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
193 204
194 static size_t EstimateFinalIncrementalMarkCompactTime( 205 static size_t EstimateFinalIncrementalMarkCompactTime(
195 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms); 206 size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
196 207
197 static bool ShouldDoMarkCompact(size_t idle_time_in_ms, 208 static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
198 size_t size_of_objects, 209 size_t size_of_objects,
199 size_t mark_compact_speed_in_bytes_per_ms); 210 size_t mark_compact_speed_in_bytes_per_ms);
200 211
201 static bool ShouldDoContextDisposalMarkCompact(int context_disposed, 212 static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
202 double contexts_disposal_rate); 213 double contexts_disposal_rate);
203 214
204 static bool ShouldDoFinalIncrementalMarkCompact( 215 static bool ShouldDoFinalIncrementalMarkCompact(
205 size_t idle_time_in_ms, size_t size_of_objects, 216 size_t idle_time_in_ms, size_t size_of_objects,
206 size_t final_incremental_mark_compact_speed_in_bytes_per_ms); 217 size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
207 218
208 static bool ShouldDoOverApproximateWeakClosure(size_t idle_time_in_ms); 219 static bool ShouldDoOverApproximateWeakClosure(size_t idle_time_in_ms);
209 220
210 static bool ShouldDoScavenge( 221 static bool ShouldDoScavenge(
211 size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size, 222 size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
212 size_t scavenger_speed_in_bytes_per_ms, 223 size_t scavenger_speed_in_bytes_per_ms,
213 size_t new_space_allocation_throughput_in_bytes_per_ms); 224 size_t new_space_allocation_throughput_in_bytes_per_ms);
214 225
226 enum Mode { kReduceLatency, kReduceMemory, kDone };
227
228 Mode mode() { return mode_; }
229
215 private: 230 private:
216 GCIdleTimeAction NothingOrDone(); 231 bool IsMutatorActive(int contexts_disposed, int gcs);
232 bool IsMutatorIdle(int long_idle_notifications, int gcs);
233 void UpdateCounters(double idle_time_in_ms);
234 void ResetCounters();
235 Mode NextMode(const HeapState& heap_state);
236 GCIdleTimeAction Action(double idle_time_in_ms, const HeapState& heap_state,
237 bool reduce_memory);
217 238
218 void StartIdleRound() { 239 int idle_mark_compacts_;
219 mark_compacts_since_idle_round_started_ = 0; 240 int mark_compacts_;
220 idle_times_which_made_no_progress_since_last_idle_round_ = 0; 241 int scavenges_;
221 } 242 // The number of long idle notifications with no mutator GC happening
222 bool IsMarkCompactIdleRoundFinished() { 243 // between the notifications.
223 return mark_compacts_since_idle_round_started_ == 244 int long_idle_notifications_;
224 kMaxMarkCompactsInIdleRound;
225 }
226 bool EnoughGarbageSinceLastIdleRound() {
227 return scavenges_since_last_idle_round_ >= kIdleScavengeThreshold;
228 }
229 245
230 int mark_compacts_since_idle_round_started_; 246 Mode mode_;
231 int scavenges_since_last_idle_round_;
232 int idle_times_which_made_no_progress_since_last_idle_round_;
233 247
234 DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler); 248 DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
235 }; 249 };
236 250
237 } // namespace internal 251 } // namespace internal
238 } // namespace v8 252 } // namespace v8
239 253
240 #endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_ 254 #endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
OLDNEW
« no previous file with comments | « no previous file | src/heap/gc-idle-time-handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698