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

Side by Side Diff: test/unittests/heap/gc-idle-time-handler-unittest.cc

Issue 1105293004: Add mode to reduce memory usage in idle notification. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments 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
« src/heap/gc-idle-time-handler.cc ('K') | « test/cctest/test-heap.cc ('k') | no next file » | 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 #include <limits> 5 #include <limits>
6 6
7 #include "src/heap/gc-idle-time-handler.h" 7 #include "src/heap/gc-idle-time-handler.h"
8 #include "testing/gtest/include/gtest/gtest.h" 8 #include "testing/gtest/include/gtest/gtest.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 20 matching lines...) Expand all
31 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed; 31 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
32 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed; 32 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
33 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed; 33 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
34 result.used_new_space_size = 0; 34 result.used_new_space_size = 0;
35 result.new_space_capacity = kNewSpaceCapacity; 35 result.new_space_capacity = kNewSpaceCapacity;
36 result.new_space_allocation_throughput_in_bytes_per_ms = 36 result.new_space_allocation_throughput_in_bytes_per_ms =
37 kNewSpaceAllocationThroughput; 37 kNewSpaceAllocationThroughput;
38 return result; 38 return result;
39 } 39 }
40 40
41 void TransitionToReduceMemoryMode(
42 const GCIdleTimeHandler::HeapState& heap_state) {
43 handler()->NotifyScavenge();
44 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
45 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
46 bool incremental = !heap_state.incremental_marking_stopped ||
47 heap_state.can_start_incremental_marking;
48 for (int i = 0; i < limit; i++) {
49 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
50 EXPECT_EQ(incremental ? DO_INCREMENTAL_MARKING : DO_NOTHING, action.type);
51 }
52 }
53
54 void TransitionToDoneMode(const GCIdleTimeHandler::HeapState& heap_state,
55 double idle_time_ms,
56 GCIdleTimeActionType expected) {
57 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
58 for (int i = 0; i < limit; i++) {
59 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
60 EXPECT_EQ(expected, action.type);
61 EXPECT_EQ(true, action.reduce_memory);
Erik Corry 2015/05/05 21:38:52 EXPECT_TRUE(action.reduce_memory)
ulan 2015/05/06 09:47:19 Done.
62 handler()->NotifyMarkCompact();
63 handler()->NotifyIdleMarkCompact();
64 }
65 }
66
67 void TransitionToReduceLatencyMode() {
68 int limit = GCIdleTimeHandler::kGCsBeforeMutatorIsActive;
69 for (int i = 0; i < limit; i++) {
70 if (i % 2 == 0) {
71 handler()->NotifyScavenge();
Erik Corry 2015/05/05 21:38:52 In this test there are 7 GCs in a row without any
ulan 2015/05/06 09:47:19 Added call to Compute.
72 } else {
73 handler()->NotifyMarkCompact();
74 }
75 }
76 }
77
41 static const size_t kSizeOfObjects = 100 * MB; 78 static const size_t kSizeOfObjects = 100 * MB;
42 static const size_t kMarkCompactSpeed = 200 * KB; 79 static const size_t kMarkCompactSpeed = 200 * KB;
43 static const size_t kMarkingSpeed = 200 * KB; 80 static const size_t kMarkingSpeed = 200 * KB;
44 static const size_t kScavengeSpeed = 100 * KB; 81 static const size_t kScavengeSpeed = 100 * KB;
45 static const size_t kNewSpaceCapacity = 1 * MB; 82 static const size_t kNewSpaceCapacity = 1 * MB;
46 static const size_t kNewSpaceAllocationThroughput = 10 * KB; 83 static const size_t kNewSpaceAllocationThroughput = 10 * KB;
84 static const int kMaxNotifications = 100;
47 85
48 private: 86 private:
49 GCIdleTimeHandler handler_; 87 GCIdleTimeHandler handler_;
50 }; 88 };
51 89
52 } // namespace 90 } // namespace
53 91
54 92
55 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) { 93 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
56 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0); 94 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) { 144 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) {
107 size_t size = std::numeric_limits<size_t>::max(); 145 size_t size = std::numeric_limits<size_t>::max();
108 size_t speed = 1; 146 size_t speed = 1;
109 size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed); 147 size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
110 EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time); 148 EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
111 } 149 }
112 150
113 151
114 TEST_F(GCIdleTimeHandlerTest, DoScavengeEmptyNewSpace) { 152 TEST_F(GCIdleTimeHandlerTest, DoScavengeEmptyNewSpace) {
115 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 153 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
116 int idle_time_in_ms = 16; 154 int idle_time_ms = 16;
117 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( 155 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
118 idle_time_in_ms, heap_state.new_space_capacity, 156 idle_time_ms, heap_state.new_space_capacity,
119 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 157 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
120 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 158 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
121 } 159 }
122 160
123 161
124 TEST_F(GCIdleTimeHandlerTest, DoScavengeFullNewSpace) { 162 TEST_F(GCIdleTimeHandlerTest, DoScavengeFullNewSpace) {
125 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 163 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
126 heap_state.used_new_space_size = kNewSpaceCapacity; 164 heap_state.used_new_space_size = kNewSpaceCapacity;
127 int idle_time_in_ms = 16; 165 int idle_time_ms = 16;
128 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge( 166 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
129 idle_time_in_ms, heap_state.new_space_capacity, 167 idle_time_ms, heap_state.new_space_capacity,
130 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 168 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
131 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 169 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
132 } 170 }
133 171
134 172
135 TEST_F(GCIdleTimeHandlerTest, DoScavengeUnknownScavengeSpeed) { 173 TEST_F(GCIdleTimeHandlerTest, DoScavengeUnknownScavengeSpeed) {
136 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 174 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
137 heap_state.used_new_space_size = kNewSpaceCapacity; 175 heap_state.used_new_space_size = kNewSpaceCapacity;
138 heap_state.scavenge_speed_in_bytes_per_ms = 0; 176 heap_state.scavenge_speed_in_bytes_per_ms = 0;
139 int idle_time_in_ms = 8; 177 int idle_time_ms = 8;
140 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( 178 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
141 idle_time_in_ms, heap_state.new_space_capacity, 179 idle_time_ms, heap_state.new_space_capacity,
142 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 180 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
143 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 181 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
144 } 182 }
145 183
146 184
147 TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) { 185 TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) {
148 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 186 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
149 heap_state.used_new_space_size = kNewSpaceCapacity; 187 heap_state.used_new_space_size = kNewSpaceCapacity;
150 heap_state.scavenge_speed_in_bytes_per_ms = 1 * KB; 188 heap_state.scavenge_speed_in_bytes_per_ms = 1 * KB;
151 int idle_time_in_ms = 16; 189 int idle_time_ms = 16;
152 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( 190 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
153 idle_time_in_ms, heap_state.new_space_capacity, 191 idle_time_ms, heap_state.new_space_capacity,
154 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 192 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
155 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 193 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
156 } 194 }
157 195
158 196
159 TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) { 197 TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) {
160 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 198 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
161 heap_state.used_new_space_size = kNewSpaceCapacity; 199 heap_state.used_new_space_size = kNewSpaceCapacity;
162 heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity; 200 heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
163 int idle_time_in_ms = 16; 201 int idle_time_ms = 16;
164 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge( 202 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
165 idle_time_in_ms, heap_state.new_space_capacity, 203 idle_time_ms, heap_state.new_space_capacity,
166 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 204 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
167 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 205 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
168 } 206 }
169 207
170 208
171 TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) { 209 TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) {
172 size_t idle_time_in_ms = GCIdleTimeHandler::kMaxScheduledIdleTime; 210 size_t idle_time_ms = GCIdleTimeHandler::kMaxScheduledIdleTime;
173 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_in_ms, 0, 0)); 211 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_ms, 0, 0));
174 } 212 }
175 213
176 214
177 TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) { 215 TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) {
178 size_t idle_time_in_ms = 1; 216 size_t idle_time_ms = 1;
179 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoMarkCompact( 217 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoMarkCompact(
180 idle_time_in_ms, kSizeOfObjects, kMarkingSpeed)); 218 idle_time_ms, kSizeOfObjects, kMarkingSpeed));
181 } 219 }
182 220
183 221
184 TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) { 222 TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
185 size_t idle_time_in_ms = 16; 223 size_t idle_time_ms = 16;
186 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( 224 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
187 idle_time_in_ms, 0, 0)); 225 idle_time_ms, 0, 0));
188 } 226 }
189 227
190 228
191 TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) { 229 TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
192 size_t idle_time_in_ms = 1; 230 size_t idle_time_ms = 1;
193 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( 231 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
194 idle_time_in_ms, kSizeOfObjects, kMarkingSpeed)); 232 idle_time_ms, kSizeOfObjects, kMarkingSpeed));
195 } 233 }
196 234
197 235
198 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { 236 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
199 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 237 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
200 heap_state.contexts_disposed = 1; 238 heap_state.contexts_disposed = 1;
201 heap_state.incremental_marking_stopped = true; 239 heap_state.incremental_marking_stopped = true;
202 double idle_time_ms = 0; 240 double idle_time_ms = 0;
203 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 241 for (int mode = 0; mode < 1; mode++) {
204 EXPECT_EQ(DO_NOTHING, action.type); 242 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
243 EXPECT_EQ(DO_NOTHING, action.type);
244 TransitionToReduceMemoryMode(heap_state);
245 }
205 } 246 }
206 247
207 248
208 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { 249 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
209 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 250 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
210 heap_state.contexts_disposed = 1; 251 heap_state.contexts_disposed = 1;
211 heap_state.contexts_disposal_rate = 252 heap_state.contexts_disposal_rate =
212 GCIdleTimeHandler::kHighContextDisposalRate - 1; 253 GCIdleTimeHandler::kHighContextDisposalRate - 1;
213 heap_state.incremental_marking_stopped = true; 254 heap_state.incremental_marking_stopped = true;
214 double idle_time_ms = 0; 255 double idle_time_ms = 0;
215 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 256 for (int mode = 0; mode < 1; mode++) {
216 EXPECT_EQ(DO_FULL_GC, action.type); 257 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
258 EXPECT_EQ(DO_FULL_GC, action.type);
259 TransitionToReduceMemoryMode(heap_state);
260 }
217 } 261 }
218 262
219 263
220 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
221 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
222 heap_state.contexts_disposed = 1;
223 heap_state.contexts_disposal_rate = 1.0;
224 heap_state.incremental_marking_stopped = true;
225 heap_state.can_start_incremental_marking = false;
226 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
227 double idle_time_ms =
228 static_cast<double>((heap_state.size_of_objects + speed - 1) / speed);
229 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
230 EXPECT_EQ(DO_FULL_GC, action.type);
231 }
232
233
234 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { 264 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
235 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 265 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
236 heap_state.contexts_disposed = 1; 266 heap_state.contexts_disposed = 1;
237 heap_state.contexts_disposal_rate = 1.0; 267 heap_state.contexts_disposal_rate = 1.0;
238 heap_state.incremental_marking_stopped = true; 268 heap_state.incremental_marking_stopped = true;
239 double idle_time_ms = 0; 269 double idle_time_ms = 0;
240 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 270 for (int mode = 0; mode < 1; mode++) {
241 EXPECT_EQ(DO_FULL_GC, action.type); 271 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
272 EXPECT_EQ(DO_FULL_GC, action.type);
273 TransitionToReduceMemoryMode(heap_state);
274 }
242 } 275 }
243 276
244 277
245 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { 278 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
246 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 279 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
247 heap_state.contexts_disposed = 1; 280 heap_state.contexts_disposed = 1;
248 heap_state.contexts_disposal_rate = 1.0; 281 heap_state.contexts_disposal_rate = 1.0;
249 heap_state.incremental_marking_stopped = true; 282 heap_state.incremental_marking_stopped = true;
250 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 283 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
251 double idle_time_ms = 284 double idle_time_ms =
252 static_cast<double>(heap_state.size_of_objects / speed - 1); 285 static_cast<double>(heap_state.size_of_objects / speed - 1);
253 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 286 for (int mode = 0; mode < 1; mode++) {
254 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 287 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
288 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
289 TransitionToReduceMemoryMode(heap_state);
290 }
255 } 291 }
256 292
257 293
258 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { 294 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
259 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 295 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
260 heap_state.contexts_disposed = 1; 296 heap_state.contexts_disposed = 1;
261 heap_state.contexts_disposal_rate = 1.0; 297 heap_state.contexts_disposal_rate = 1.0;
262 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 298 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
263 double idle_time_ms = 299 double idle_time_ms =
264 static_cast<double>(heap_state.size_of_objects / speed - 1); 300 static_cast<double>(heap_state.size_of_objects / speed - 1);
265 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 301 for (int mode = 0; mode < 1; mode++) {
266 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 302 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
303 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
304 TransitionToReduceMemoryMode(heap_state);
305 }
267 } 306 }
268 307
269 308
270 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { 309 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
271 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 310 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
272 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 311 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
273 double idle_time_ms = 10; 312 double idle_time_ms = 10;
274 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 313 for (int mode = 0; mode < 1; mode++) {
275 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 314 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
276 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 315 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
277 static_cast<size_t>(action.parameter)); 316 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
278 EXPECT_LT(0, action.parameter); 317 static_cast<size_t>(action.parameter));
318 EXPECT_LT(0, action.parameter);
319 TransitionToReduceMemoryMode(heap_state);
320 }
279 } 321 }
280 322
281 323
282 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { 324 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
283 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 325 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
284 heap_state.incremental_marking_stopped = true; 326 heap_state.incremental_marking_stopped = true;
285 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 327 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
286 double idle_time_ms = 10; 328 double idle_time_ms = 10;
287 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 329 for (int mode = 0; mode < 1; mode++) {
288 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 330 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
289 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 331 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
290 static_cast<size_t>(action.parameter)); 332 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
291 EXPECT_LT(0, action.parameter); 333 static_cast<size_t>(action.parameter));
334 EXPECT_LT(0, action.parameter);
335 TransitionToReduceMemoryMode(heap_state);
336 }
292 } 337 }
293 338
294 339
295 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { 340 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
296 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 341 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
297 heap_state.incremental_marking_stopped = true; 342 heap_state.incremental_marking_stopped = true;
298 heap_state.can_start_incremental_marking = false; 343 heap_state.can_start_incremental_marking = false;
299 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 344 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
300 double idle_time_ms = 345 double idle_time_ms =
301 static_cast<double>(heap_state.size_of_objects / speed - 1); 346 static_cast<double>(heap_state.size_of_objects / speed - 1);
302 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 347 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
303 EXPECT_EQ(DO_NOTHING, action.type); 348 EXPECT_EQ(DO_NOTHING, action.type);
349 TransitionToReduceMemoryMode(heap_state);
350 action = handler()->Compute(idle_time_ms, heap_state);
351 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
304 } 352 }
305 353
306 354
307 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { 355 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) {
308 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
309 heap_state.incremental_marking_stopped = true; 357 heap_state.incremental_marking_stopped = true;
310 heap_state.can_start_incremental_marking = false; 358 heap_state.can_start_incremental_marking = false;
311 heap_state.sweeping_in_progress = true; 359 for (int mode = 0; mode < 1; mode++) {
312 heap_state.sweeping_completed = true; 360 heap_state.sweeping_in_progress = true;
313 double idle_time_ms = 10.0; 361 heap_state.sweeping_completed = true;
314 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 362 double idle_time_ms = 10.0;
315 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); 363 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
364 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
365 heap_state.sweeping_in_progress = false;
366 heap_state.sweeping_completed = false;
367 TransitionToReduceMemoryMode(heap_state);
368 }
316 } 369 }
317 370
318 371
319 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { 372 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) {
320 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 373 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
321 heap_state.incremental_marking_stopped = true; 374 heap_state.incremental_marking_stopped = true;
322 heap_state.can_start_incremental_marking = false; 375 heap_state.can_start_incremental_marking = false;
323 heap_state.sweeping_in_progress = true; 376 for (int mode = 0; mode < 1; mode++) {
324 heap_state.sweeping_completed = false; 377 heap_state.sweeping_in_progress = true;
325 double idle_time_ms = 10.0; 378 heap_state.sweeping_completed = false;
326 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 379 double idle_time_ms = 10.0;
327 EXPECT_EQ(DO_NOTHING, action.type); 380 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
381 EXPECT_EQ(DO_NOTHING, action.type);
382 heap_state.sweeping_in_progress = false;
383 heap_state.sweeping_completed = false;
384 TransitionToReduceMemoryMode(heap_state);
385 }
328 } 386 }
329 387
330 388
389 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
390 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
391 int idle_time_ms = 10;
392 for (int mode = 0; mode < 1; mode++) {
393 heap_state.used_new_space_size =
394 heap_state.new_space_capacity -
395 (kNewSpaceAllocationThroughput * idle_time_ms);
396 GCIdleTimeAction action =
397 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
398 EXPECT_EQ(DO_SCAVENGE, action.type);
399 heap_state.used_new_space_size = 0;
400 TransitionToReduceMemoryMode(heap_state);
401 }
402 }
403
404
405 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
406 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
407 int idle_time_ms = 10;
408 heap_state.can_start_incremental_marking = false;
409 heap_state.incremental_marking_stopped = true;
410 for (int mode = 0; mode < 1; mode++) {
411 heap_state.used_new_space_size =
412 heap_state.new_space_capacity -
413 (kNewSpaceAllocationThroughput * idle_time_ms);
414 GCIdleTimeAction action =
415 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
416 EXPECT_EQ(DO_SCAVENGE, action.type);
417 heap_state.used_new_space_size = 0;
418 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
419 EXPECT_EQ(DO_NOTHING, action.type);
420 TransitionToReduceMemoryMode(heap_state);
421 }
422 }
423
424
331 TEST_F(GCIdleTimeHandlerTest, StopEventually1) { 425 TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
332 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 426 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
333 heap_state.incremental_marking_stopped = true; 427 heap_state.incremental_marking_stopped = true;
334 heap_state.can_start_incremental_marking = false; 428 heap_state.can_start_incremental_marking = false;
429 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
430 bool stopped = false;
431 for (int i = 0; i < kMaxNotifications && !stopped; i++) {
432 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
433 if (action.type == DO_INCREMENTAL_MARKING || action.type == DO_FULL_GC) {
434 handler()->NotifyMarkCompact();
435 handler()->NotifyIdleMarkCompact();
436 }
437 if (action.type == DONE) stopped = true;
438 }
439 EXPECT_TRUE(stopped);
440 }
441
442
443 TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
444 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
445 heap_state.incremental_marking_stopped = true;
446 heap_state.can_start_incremental_marking = false;
335 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 447 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
336 double idle_time_ms = 448 double idle_time_ms =
337 static_cast<double>(heap_state.size_of_objects / speed + 1); 449 static_cast<double>(heap_state.size_of_objects / speed + 1);
338 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 450 TransitionToReduceMemoryMode(heap_state);
339 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 451 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
340 EXPECT_EQ(DO_FULL_GC, action.type);
341 handler()->NotifyIdleMarkCompact();
342 }
343 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 452 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
344 EXPECT_EQ(DONE, action.type); 453 EXPECT_EQ(DONE, action.type);
345 } 454 }
346 455
347 456
348 TEST_F(GCIdleTimeHandlerTest, StopEventually2) { 457 TEST_F(GCIdleTimeHandlerTest, StopEventually3) {
349 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 458 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
459 heap_state.incremental_marking_stopped = true;
460 heap_state.can_start_incremental_marking = false;
350 double idle_time_ms = 10; 461 double idle_time_ms = 10;
351 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 462 TransitionToReduceMemoryMode(heap_state);
352 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 463 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
353 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
354 // In this case we emulate incremental marking steps that finish with a
355 // full gc.
356 handler()->NotifyIdleMarkCompact();
357 }
358 heap_state.can_start_incremental_marking = false;
359 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 464 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
360 EXPECT_EQ(DONE, action.type); 465 EXPECT_EQ(DONE, action.type);
361 } 466 }
362 467
363 468
364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) { 469 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 470 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
366 heap_state.incremental_marking_stopped = true; 471 heap_state.incremental_marking_stopped = true;
367 heap_state.can_start_incremental_marking = false; 472 heap_state.can_start_incremental_marking = false;
368 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 473 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
369 double idle_time_ms = 474 double idle_time_ms =
370 static_cast<double>(heap_state.size_of_objects / speed + 1); 475 static_cast<double>(heap_state.size_of_objects / speed + 1);
371 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 476 TransitionToReduceMemoryMode(heap_state);
372 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 477 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
373 EXPECT_EQ(DO_FULL_GC, action.type);
374 handler()->NotifyIdleMarkCompact();
375 }
376 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 478 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
377 EXPECT_EQ(DONE, action.type); 479 EXPECT_EQ(DONE, action.type);
378 // Emulate mutator work. 480 TransitionToReduceLatencyMode();
379 for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) { 481 heap_state.can_start_incremental_marking = true;
380 handler()->NotifyScavenge();
381 }
382 action = handler()->Compute(idle_time_ms, heap_state); 482 action = handler()->Compute(idle_time_ms, heap_state);
383 EXPECT_EQ(DO_FULL_GC, action.type); 483 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
484 EXPECT_FALSE(action.reduce_memory);
384 } 485 }
385 486
386 487
387 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) { 488 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
388 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 489 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
490 heap_state.incremental_marking_stopped = true;
491 heap_state.can_start_incremental_marking = false;
389 double idle_time_ms = 10; 492 double idle_time_ms = 10;
390 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 493 TransitionToReduceMemoryMode(heap_state);
391 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 494 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
392 if (action.type == DONE) break;
393 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
394 // In this case we try to emulate incremental marking steps the finish with
395 // a full gc.
396 handler()->NotifyIdleMarkCompact();
397 }
398 heap_state.can_start_incremental_marking = false;
399 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 495 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
400 EXPECT_EQ(DONE, action.type); 496 EXPECT_EQ(DONE, action.type);
401 // Emulate mutator work. 497 TransitionToReduceLatencyMode();
402 for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
403 handler()->NotifyScavenge();
404 }
405 heap_state.can_start_incremental_marking = true; 498 heap_state.can_start_incremental_marking = true;
406 action = handler()->Compute(idle_time_ms, heap_state); 499 action = handler()->Compute(idle_time_ms, heap_state);
407 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 500 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
408 } 501 EXPECT_FALSE(action.reduce_memory);
409
410
411 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
412 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
413 int idle_time_ms = 10;
414 heap_state.used_new_space_size =
415 heap_state.new_space_capacity -
416 (kNewSpaceAllocationThroughput * idle_time_ms);
417 GCIdleTimeAction action =
418 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
419 EXPECT_EQ(DO_SCAVENGE, action.type);
420 }
421
422
423 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
424 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
425 int idle_time_ms = 10;
426 heap_state.can_start_incremental_marking = false;
427 heap_state.incremental_marking_stopped = true;
428 heap_state.used_new_space_size =
429 heap_state.new_space_capacity -
430 (kNewSpaceAllocationThroughput * idle_time_ms);
431 GCIdleTimeAction action =
432 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
433 EXPECT_EQ(DO_SCAVENGE, action.type);
434 heap_state.used_new_space_size = 0;
435 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
436 EXPECT_EQ(DO_NOTHING, action.type);
437 } 502 }
438 503
439 504
440 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { 505 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
441 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 506 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
442 double idle_time_ms = 0; 507 for (int i = 0; i < kMaxNotifications; i++) {
443 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 508 GCIdleTimeAction action = handler()->Compute(0, heap_state);
444 EXPECT_EQ(DO_NOTHING, action.type); 509 EXPECT_EQ(DO_NOTHING, action.type);
510 }
445 } 511 }
446 512
447 513
448 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) { 514 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
449 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 515 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
450 double idle_time_ms = 10; 516 heap_state.incremental_marking_stopped = true;
451 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 517 heap_state.can_start_incremental_marking = false;
452 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 518 for (int i = 0; i < kMaxNotifications; i++) {
453 if (action.type == DONE) break; 519 GCIdleTimeAction action = handler()->Compute(10, heap_state);
454 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 520 EXPECT_EQ(DO_NOTHING, action.type);
455 // In this case we try to emulate incremental marking steps the finish with
456 // a full gc.
457 handler()->NotifyIdleMarkCompact();
458 } 521 }
459 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
460 // Emulate mutator work.
461 for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
462 handler()->NotifyScavenge();
463 }
464 action = handler()->Compute(0, heap_state);
465 EXPECT_EQ(DO_NOTHING, action.type);
466 } 522 }
467 523
468 524
469 TEST_F(GCIdleTimeHandlerTest, KeepDoingDoNothingWithZeroIdleTime) { 525 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfScavenges) {
470 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 526 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
471 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerIdleRound; 527 heap_state.incremental_marking_stopped = true;
472 i++) { 528 heap_state.can_start_incremental_marking = false;
473 GCIdleTimeAction action = handler()->Compute(0, heap_state); 529 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
530 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
531 for (int i = 0; i < kMaxNotifications; i++) {
532 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
474 EXPECT_EQ(DO_NOTHING, action.type); 533 EXPECT_EQ(DO_NOTHING, action.type);
534 if ((i + 1) % limit == 0) handler()->NotifyScavenge();
475 } 535 }
476 // Should still return DO_NOTHING if we have been given 0 deadline yet.
477 GCIdleTimeAction action = handler()->Compute(0, heap_state);
478 EXPECT_EQ(DO_NOTHING, action.type);
479 } 536 }
480 537
481 538
482 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { 539 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfMarkCompacts) {
483 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 540 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
484
485 // Simulate sweeping being in-progress but not complete.
486 heap_state.incremental_marking_stopped = true; 541 heap_state.incremental_marking_stopped = true;
487 heap_state.can_start_incremental_marking = false; 542 heap_state.can_start_incremental_marking = false;
488 heap_state.sweeping_in_progress = true; 543 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
489 heap_state.sweeping_completed = false; 544 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
490 double idle_time_ms = 10.0; 545 for (int i = 0; i < kMaxNotifications; i++) {
491 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerIdleRound;
492 i++) {
493 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 546 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
494 EXPECT_EQ(DO_NOTHING, action.type); 547 EXPECT_EQ(DO_NOTHING, action.type);
548 if ((i + 1) % limit == 0) handler()->NotifyMarkCompact();
495 } 549 }
496 // We should return DONE after not making progress for some time. 550 }
551
552
553 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToReduceLatency) {
554 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
555 heap_state.incremental_marking_stopped = true;
556 heap_state.can_start_incremental_marking = false;
557 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
558 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
559 for (int idle_gc = 0; idle_gc < limit; idle_gc++) {
560 TransitionToReduceMemoryMode(heap_state);
561 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
562 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
563 EXPECT_TRUE(action.reduce_memory);
564 for (int i = 0; i < idle_gc; i++) {
565 action = handler()->Compute(idle_time_ms, heap_state);
566 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
567 EXPECT_TRUE(action.reduce_memory);
568 // ReduceMemory mode should tolerate one mutator GC per idle GC.
569 handler()->NotifyScavenge();
570 // Notify idle GC.
571 handler()->NotifyMarkCompact();
572 handler()->NotifyIdleMarkCompact();
573 }
574 // Transition to ReduceLatency mode after doing |idle_gc| idle GCs.
575 handler()->NotifyScavenge();
576 action = handler()->Compute(idle_time_ms, heap_state);
577 EXPECT_EQ(DO_NOTHING, action.type);
578 EXPECT_FALSE(action.reduce_memory);
579 }
580 }
581
582
583 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToDone) {
584 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
585 heap_state.incremental_marking_stopped = true;
586 heap_state.can_start_incremental_marking = false;
587 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
588 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
589 TransitionToReduceMemoryMode(heap_state);
497 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 590 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
591 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
592 EXPECT_TRUE(action.reduce_memory);
593 for (int i = 0; i < limit; i++) {
594 action = handler()->Compute(idle_time_ms, heap_state);
595 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
596 EXPECT_TRUE(action.reduce_memory);
597 // ReduceMemory mode should tolerate one mutator GC per idle GC.
598 handler()->NotifyScavenge();
599 // Notify idle GC.
600 handler()->NotifyMarkCompact();
601 handler()->NotifyIdleMarkCompact();
602 }
603 action = handler()->Compute(idle_time_ms, heap_state);
498 EXPECT_EQ(DONE, action.type); 604 EXPECT_EQ(DONE, action.type);
499 } 605 }
500 606
501 607
502 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
503 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
504
505 // Simulate incremental marking stopped and not eligible to start.
506 heap_state.incremental_marking_stopped = true;
507 heap_state.can_start_incremental_marking = false;
508 double idle_time_ms = 10.0;
509 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerIdleRound;
510 i++) {
511 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
512 EXPECT_EQ(DO_NOTHING, action.type);
513 }
514 // We should return DONE after not making progress for some time.
515 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
516 EXPECT_EQ(DONE, action.type);
517 }
518
519 } // namespace internal 608 } // namespace internal
520 } // namespace v8 609 } // namespace v8
OLDNEW
« src/heap/gc-idle-time-handler.cc ('K') | « test/cctest/test-heap.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698