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

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

Issue 1226703002: Revert of Replace reduce-memory mode in idle notification with delayed clean-up GC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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 | « test/cctest/test-api.cc ('k') | test/unittests/heap/memory-reducer-unittest.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 #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 {
11 namespace internal { 11 namespace internal {
12 12
13 namespace { 13 namespace {
14 14
15 class GCIdleTimeHandlerTest : public ::testing::Test { 15 class GCIdleTimeHandlerTest : public ::testing::Test {
16 public: 16 public:
17 GCIdleTimeHandlerTest() {} 17 GCIdleTimeHandlerTest() {}
18 virtual ~GCIdleTimeHandlerTest() {} 18 virtual ~GCIdleTimeHandlerTest() {}
19 19
20 GCIdleTimeHandler* handler() { return &handler_; } 20 GCIdleTimeHandler* handler() { return &handler_; }
21 21
22 GCIdleTimeHandler::HeapState DefaultHeapState() { 22 GCIdleTimeHandler::HeapState DefaultHeapState() {
23 GCIdleTimeHandler::HeapState result; 23 GCIdleTimeHandler::HeapState result;
24 result.contexts_disposed = 0; 24 result.contexts_disposed = 0;
25 result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate; 25 result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate;
26 result.size_of_objects = kSizeOfObjects; 26 result.size_of_objects = kSizeOfObjects;
27 result.incremental_marking_stopped = false; 27 result.incremental_marking_stopped = false;
28 result.can_start_incremental_marking = true;
28 result.sweeping_in_progress = false; 29 result.sweeping_in_progress = false;
29 result.sweeping_completed = false; 30 result.sweeping_completed = false;
30 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed; 31 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
31 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed; 32 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
32 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed; 33 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
33 result.used_new_space_size = 0; 34 result.used_new_space_size = 0;
34 result.new_space_capacity = kNewSpaceCapacity; 35 result.new_space_capacity = kNewSpaceCapacity;
35 result.new_space_allocation_throughput_in_bytes_per_ms = 36 result.new_space_allocation_throughput_in_bytes_per_ms =
36 kNewSpaceAllocationThroughput; 37 kNewSpaceAllocationThroughput;
37 return result; 38 return result;
38 } 39 }
39 40
41 void TransitionToReduceMemoryMode(
42 const GCIdleTimeHandler::HeapState& heap_state) {
43 handler()->NotifyScavenge();
44 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
45 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
46 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
47 bool incremental = !heap_state.incremental_marking_stopped ||
48 heap_state.can_start_incremental_marking;
49 for (int i = 0; i < limit; i++) {
50 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
51 if (incremental) {
52 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
53 } else {
54 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
55 }
56 }
57 handler()->Compute(idle_time_ms, heap_state);
58 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
59 }
60
61 void TransitionToDoneMode(const GCIdleTimeHandler::HeapState& heap_state,
62 double idle_time_ms,
63 GCIdleTimeActionType expected) {
64 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
65 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
66 for (int i = 0; i < limit; i++) {
67 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
68 EXPECT_EQ(expected, action.type);
69 EXPECT_TRUE(action.reduce_memory);
70 handler()->NotifyMarkCompact(true);
71 handler()->NotifyIdleMarkCompact();
72 }
73 handler()->Compute(idle_time_ms, heap_state);
74 EXPECT_EQ(GCIdleTimeHandler::kDone, handler()->mode());
75 }
76
77 void TransitionToReduceLatencyMode(
78 const GCIdleTimeHandler::HeapState& heap_state) {
79 EXPECT_EQ(GCIdleTimeHandler::kDone, handler()->mode());
80 int limit = GCIdleTimeHandler::kMarkCompactsBeforeMutatorIsActive;
81 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
82 for (int i = 0; i < limit; i++) {
83 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
84 EXPECT_EQ(DONE, action.type);
85 handler()->NotifyMarkCompact(true);
86 }
87 handler()->Compute(idle_time_ms, heap_state);
88 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
89 }
90
40 static const size_t kSizeOfObjects = 100 * MB; 91 static const size_t kSizeOfObjects = 100 * MB;
41 static const size_t kMarkCompactSpeed = 200 * KB; 92 static const size_t kMarkCompactSpeed = 200 * KB;
42 static const size_t kMarkingSpeed = 200 * KB; 93 static const size_t kMarkingSpeed = 200 * KB;
43 static const size_t kScavengeSpeed = 100 * KB; 94 static const size_t kScavengeSpeed = 100 * KB;
44 static const size_t kNewSpaceCapacity = 1 * MB; 95 static const size_t kNewSpaceCapacity = 1 * MB;
45 static const size_t kNewSpaceAllocationThroughput = 10 * KB; 96 static const size_t kNewSpaceAllocationThroughput = 10 * KB;
46 static const int kMaxNotifications = 100; 97 static const int kMaxNotifications = 1000;
47 98
48 private: 99 private:
49 GCIdleTimeHandler handler_; 100 GCIdleTimeHandler handler_;
50 }; 101 };
51 102
52 } // namespace 103 } // namespace
53 104
54 105
55 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) { 106 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
56 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0); 107 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( 256 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
206 idle_time_ms, kSizeOfObjects, kMarkingSpeed)); 257 idle_time_ms, kSizeOfObjects, kMarkingSpeed));
207 } 258 }
208 259
209 260
210 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { 261 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
211 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 262 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
212 heap_state.contexts_disposed = 1; 263 heap_state.contexts_disposed = 1;
213 heap_state.incremental_marking_stopped = true; 264 heap_state.incremental_marking_stopped = true;
214 double idle_time_ms = 0; 265 double idle_time_ms = 0;
215 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 266 for (int mode = 0; mode < 1; mode++) {
216 EXPECT_EQ(DO_NOTHING, action.type); 267 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
268 EXPECT_EQ(DO_NOTHING, action.type);
269 TransitionToReduceMemoryMode(heap_state);
270 }
217 } 271 }
218 272
219 273
220 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { 274 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
221 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 275 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
222 heap_state.contexts_disposed = 1; 276 heap_state.contexts_disposed = 1;
223 heap_state.contexts_disposal_rate = 277 heap_state.contexts_disposal_rate =
224 GCIdleTimeHandler::kHighContextDisposalRate - 1; 278 GCIdleTimeHandler::kHighContextDisposalRate - 1;
225 heap_state.incremental_marking_stopped = true; 279 heap_state.incremental_marking_stopped = true;
226 double idle_time_ms = 0; 280 double idle_time_ms = 0;
227 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 281 for (int mode = 0; mode < 1; mode++) {
228 EXPECT_EQ(DO_FULL_GC, action.type); 282 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
283 EXPECT_EQ(DO_FULL_GC, action.type);
284 heap_state.contexts_disposal_rate = 0.0;
285 TransitionToReduceMemoryMode(heap_state);
286 }
229 } 287 }
230 288
231 289
232 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { 290 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
233 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 291 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
234 heap_state.contexts_disposed = 1; 292 heap_state.contexts_disposed = 1;
235 heap_state.contexts_disposal_rate = 1.0; 293 heap_state.contexts_disposal_rate = 1.0;
236 heap_state.incremental_marking_stopped = true; 294 heap_state.incremental_marking_stopped = true;
237 double idle_time_ms = 0; 295 double idle_time_ms = 0;
238 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 296 for (int mode = 0; mode < 1; mode++) {
239 EXPECT_EQ(DO_FULL_GC, action.type); 297 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
298 EXPECT_EQ(DO_FULL_GC, action.type);
299 heap_state.contexts_disposal_rate = 0.0;
300 TransitionToReduceMemoryMode(heap_state);
301 }
240 } 302 }
241 303
242 304
243 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { 305 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
244 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 306 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
245 heap_state.contexts_disposed = 1; 307 heap_state.contexts_disposed = 1;
246 heap_state.contexts_disposal_rate = 308 heap_state.contexts_disposal_rate =
309 GCIdleTimeHandler::kHighContextDisposalRate;
310 heap_state.incremental_marking_stopped = true;
311 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
312 double idle_time_ms =
313 static_cast<double>(heap_state.size_of_objects / speed - 1);
314 for (int mode = 0; mode < 1; mode++) {
315 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
316 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
317 heap_state.contexts_disposal_rate = 0.0;
318 TransitionToReduceMemoryMode(heap_state);
319 }
320 }
321
322
323 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
324 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
325 heap_state.contexts_disposed = 1;
326 heap_state.contexts_disposal_rate =
247 GCIdleTimeHandler::kHighContextDisposalRate; 327 GCIdleTimeHandler::kHighContextDisposalRate;
248 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 328 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
249 double idle_time_ms = 329 double idle_time_ms =
250 static_cast<double>(heap_state.size_of_objects / speed - 1); 330 static_cast<double>(heap_state.size_of_objects / speed - 1);
251 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 331 for (int mode = 0; mode < 1; mode++) {
252 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 332 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
253 } 333 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
254 334 heap_state.contexts_disposal_rate = 0.0;
255 335 TransitionToReduceMemoryMode(heap_state);
256 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { 336 }
257 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 337 }
258 heap_state.contexts_disposed = 1; 338
259 heap_state.contexts_disposal_rate = 339
260 GCIdleTimeHandler::kHighContextDisposalRate; 340 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
341 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
342 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
343 double idle_time_ms = 10;
344 for (int mode = 0; mode < 1; mode++) {
345 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
346 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
347 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
348 static_cast<size_t>(action.parameter));
349 EXPECT_LT(0, action.parameter);
350 TransitionToReduceMemoryMode(heap_state);
351 }
352 }
353
354
355 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
357 heap_state.incremental_marking_stopped = true;
358 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
359 double idle_time_ms = 10;
360 for (int mode = 0; mode < 1; mode++) {
361 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
362 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
363 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
364 static_cast<size_t>(action.parameter));
365 EXPECT_LT(0, action.parameter);
366 TransitionToReduceMemoryMode(heap_state);
367 }
368 }
369
370
371 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
372 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
373 heap_state.incremental_marking_stopped = true;
374 heap_state.can_start_incremental_marking = false;
261 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 375 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
262 double idle_time_ms = 376 double idle_time_ms =
263 static_cast<double>(heap_state.size_of_objects / speed - 1); 377 static_cast<double>(heap_state.size_of_objects / speed - 1);
264 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 378 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
379 EXPECT_EQ(DO_NOTHING, action.type);
380 TransitionToReduceMemoryMode(heap_state);
381 action = handler()->Compute(idle_time_ms, heap_state);
265 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 382 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
266 } 383 }
267 384
268 385
269 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { 386 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) {
270 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 387 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
271 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 388 heap_state.incremental_marking_stopped = true;
272 double idle_time_ms = 10; 389 heap_state.can_start_incremental_marking = false;
273 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 390 for (int mode = 0; mode < 1; mode++) {
274 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 391 heap_state.sweeping_in_progress = true;
275 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 392 heap_state.sweeping_completed = true;
276 static_cast<size_t>(action.parameter)); 393 double idle_time_ms = 10.0;
277 EXPECT_LT(0, action.parameter); 394 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
278 } 395 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
279 396 heap_state.sweeping_in_progress = false;
280 397 heap_state.sweeping_completed = false;
281 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { 398 TransitionToReduceMemoryMode(heap_state);
282 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 399 }
283 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 400 }
284 double idle_time_ms = 10; 401
285 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 402
286 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 403 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) {
287 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 404 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
288 static_cast<size_t>(action.parameter)); 405 heap_state.incremental_marking_stopped = true;
289 EXPECT_LT(0, action.parameter); 406 heap_state.can_start_incremental_marking = false;
290 } 407 for (int mode = 0; mode < 1; mode++) {
291 408 heap_state.sweeping_in_progress = true;
292 409 heap_state.sweeping_completed = false;
293 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { 410 double idle_time_ms = 10.0;
294 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 411 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
295 heap_state.incremental_marking_stopped = true; 412 EXPECT_EQ(DO_NOTHING, action.type);
413 heap_state.sweeping_in_progress = false;
414 heap_state.sweeping_completed = false;
415 TransitionToReduceMemoryMode(heap_state);
416 }
417 }
418
419
420 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
421 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
422 int idle_time_ms = 10;
423 for (int mode = 0; mode < 1; mode++) {
424 heap_state.used_new_space_size =
425 heap_state.new_space_capacity -
426 (kNewSpaceAllocationThroughput * idle_time_ms);
427 GCIdleTimeAction action =
428 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
429 EXPECT_EQ(DO_SCAVENGE, action.type);
430 heap_state.used_new_space_size = 0;
431 TransitionToReduceMemoryMode(heap_state);
432 }
433 }
434
435
436 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
437 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
438 int idle_time_ms = 10;
439 heap_state.can_start_incremental_marking = false;
440 heap_state.incremental_marking_stopped = true;
441 for (int mode = 0; mode < 1; mode++) {
442 heap_state.used_new_space_size =
443 heap_state.new_space_capacity -
444 (kNewSpaceAllocationThroughput * idle_time_ms);
445 GCIdleTimeAction action =
446 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
447 EXPECT_EQ(DO_SCAVENGE, action.type);
448 heap_state.used_new_space_size = 0;
449 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
450 EXPECT_EQ(DO_NOTHING, action.type);
451 TransitionToReduceMemoryMode(heap_state);
452 }
453 }
454
455
456 TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
457 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
458 heap_state.incremental_marking_stopped = true;
459 heap_state.can_start_incremental_marking = false;
460 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
461 bool stopped = false;
462 for (int i = 0; i < kMaxNotifications && !stopped; i++) {
463 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
464 if (action.type == DO_INCREMENTAL_MARKING || action.type == DO_FULL_GC) {
465 handler()->NotifyMarkCompact(true);
466 handler()->NotifyIdleMarkCompact();
467 }
468 if (action.type == DONE) stopped = true;
469 }
470 EXPECT_TRUE(stopped);
471 }
472
473
474 TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
475 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
476 heap_state.incremental_marking_stopped = true;
477 heap_state.can_start_incremental_marking = false;
296 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 478 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
297 double idle_time_ms = 479 double idle_time_ms =
298 static_cast<double>(heap_state.size_of_objects / speed - 1); 480 static_cast<double>(heap_state.size_of_objects / speed + 1);
299 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 481 TransitionToReduceMemoryMode(heap_state);
300 EXPECT_EQ(DONE, action.type); 482 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
301 } 483 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
302 484 EXPECT_EQ(DONE, action.type);
303 485 }
304 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { 486
305 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 487
306 heap_state.incremental_marking_stopped = true; 488 TEST_F(GCIdleTimeHandlerTest, StopEventually3) {
307 heap_state.sweeping_in_progress = true; 489 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
308 heap_state.sweeping_completed = true; 490 heap_state.incremental_marking_stopped = true;
309 double idle_time_ms = 10.0; 491 heap_state.can_start_incremental_marking = false;
310 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 492 double idle_time_ms = 10;
311 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); 493 TransitionToReduceMemoryMode(heap_state);
312 } 494 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
313 495 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
314 496 EXPECT_EQ(DONE, action.type);
315 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { 497 }
316 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 498
317 heap_state.incremental_marking_stopped = true; 499
500 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
501 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
502 heap_state.incremental_marking_stopped = true;
503 heap_state.can_start_incremental_marking = false;
504 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
505 double idle_time_ms =
506 static_cast<double>(heap_state.size_of_objects / speed + 1);
507 TransitionToReduceMemoryMode(heap_state);
508 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
509 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
510 EXPECT_EQ(DONE, action.type);
511 TransitionToReduceLatencyMode(heap_state);
512 heap_state.can_start_incremental_marking = true;
513 action = handler()->Compute(idle_time_ms, heap_state);
514 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
515 EXPECT_FALSE(action.reduce_memory);
516 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
517 }
518
519
520 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
521 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
522 heap_state.incremental_marking_stopped = true;
523 heap_state.can_start_incremental_marking = false;
524 double idle_time_ms = 10;
525 TransitionToReduceMemoryMode(heap_state);
526 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
527 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
528 EXPECT_EQ(DONE, action.type);
529 TransitionToReduceLatencyMode(heap_state);
530 heap_state.can_start_incremental_marking = true;
531 action = handler()->Compute(idle_time_ms, heap_state);
532 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
533 EXPECT_FALSE(action.reduce_memory);
534 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
535 }
536
537
538 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
539 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
540 for (int i = 0; i < kMaxNotifications; i++) {
541 GCIdleTimeAction action = handler()->Compute(0, heap_state);
542 EXPECT_EQ(DO_NOTHING, action.type);
543 }
544 }
545
546
547 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
548 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
549 heap_state.incremental_marking_stopped = true;
550 heap_state.can_start_incremental_marking = false;
551 for (int i = 0; i < kMaxNotifications; i++) {
552 GCIdleTimeAction action = handler()->Compute(10, heap_state);
553 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
554 }
555 }
556
557
558 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfScavenges) {
559 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
560 heap_state.incremental_marking_stopped = true;
561 heap_state.can_start_incremental_marking = false;
562 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
563 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
564 for (int i = 0; i < kMaxNotifications; i++) {
565 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
566 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
567 if ((i + 1) % limit == 0) handler()->NotifyScavenge();
568 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
569 }
570 }
571
572
573 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfMarkCompacts) {
574 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
575 heap_state.incremental_marking_stopped = true;
576 heap_state.can_start_incremental_marking = false;
577 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
578 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
579 for (int i = 0; i < kMaxNotifications; i++) {
580 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
581 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
582 if ((i + 1) % limit == 0) handler()->NotifyMarkCompact(true);
583 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
584 }
585 }
586
587
588 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToReduceLatency) {
589 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
590 heap_state.incremental_marking_stopped = true;
591 heap_state.can_start_incremental_marking = false;
592 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
593 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
594 for (int idle_gc = 0; idle_gc < limit; idle_gc++) {
595 TransitionToReduceMemoryMode(heap_state);
596 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
597 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
598 EXPECT_TRUE(action.reduce_memory);
599 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
600 for (int i = 0; i < idle_gc; i++) {
601 action = handler()->Compute(idle_time_ms, heap_state);
602 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
603 EXPECT_TRUE(action.reduce_memory);
604 // ReduceMemory mode should tolerate one mutator GC per idle GC.
605 handler()->NotifyScavenge();
606 // Notify idle GC.
607 handler()->NotifyMarkCompact(true);
608 handler()->NotifyIdleMarkCompact();
609 }
610 // Transition to ReduceLatency mode after doing |idle_gc| idle GCs.
611 handler()->NotifyScavenge();
612 action = handler()->Compute(idle_time_ms, heap_state);
613 EXPECT_EQ(DO_NOTHING, action.type);
614 EXPECT_FALSE(action.reduce_memory);
615 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
616 }
617 }
618
619
620 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToDone) {
621 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
622 heap_state.incremental_marking_stopped = true;
623 heap_state.can_start_incremental_marking = false;
624 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
625 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
626 TransitionToReduceMemoryMode(heap_state);
627 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
628 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
629 EXPECT_TRUE(action.reduce_memory);
630 for (int i = 0; i < limit; i++) {
631 action = handler()->Compute(idle_time_ms, heap_state);
632 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
633 EXPECT_TRUE(action.reduce_memory);
634 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
635 // ReduceMemory mode should tolerate one mutator GC per idle GC.
636 handler()->NotifyScavenge();
637 // Notify idle GC.
638 handler()->NotifyMarkCompact(true);
639 handler()->NotifyIdleMarkCompact();
640 }
641 action = handler()->Compute(idle_time_ms, heap_state);
642 EXPECT_EQ(DONE, action.type);
643 }
644
645
646 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) {
647 // Regression test for crbug.com/489323.
648 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
649
650 // Simulate sweeping being in-progress but not complete.
651 heap_state.incremental_marking_stopped = true;
652 heap_state.can_start_incremental_marking = false;
318 heap_state.sweeping_in_progress = true; 653 heap_state.sweeping_in_progress = true;
319 heap_state.sweeping_completed = false; 654 heap_state.sweeping_completed = false;
320 double idle_time_ms = 10.0; 655 double idle_time_ms = 10.0;
321 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 656 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) {
322 EXPECT_EQ(DO_NOTHING, action.type); 657 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
323 } 658 EXPECT_EQ(DO_NOTHING, action.type);
324 659 }
325
326 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
327 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
328 int idle_time_ms = 10;
329 heap_state.used_new_space_size =
330 heap_state.new_space_capacity -
331 (kNewSpaceAllocationThroughput * idle_time_ms);
332 GCIdleTimeAction action =
333 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
334 EXPECT_EQ(DO_SCAVENGE, action.type);
335 heap_state.used_new_space_size = 0;
336 }
337
338
339 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
340 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
341 int idle_time_ms = 10;
342 heap_state.incremental_marking_stopped = true;
343 heap_state.used_new_space_size =
344 heap_state.new_space_capacity -
345 (kNewSpaceAllocationThroughput * idle_time_ms);
346 GCIdleTimeAction action =
347 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
348 EXPECT_EQ(DO_SCAVENGE, action.type);
349 heap_state.used_new_space_size = 0;
350 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
351 EXPECT_EQ(DONE, action.type);
352 }
353
354
355 TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
357 heap_state.incremental_marking_stopped = true;
358 double idle_time_ms = 10.0;
359 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
360 EXPECT_EQ(DONE, action.type);
361 }
362
363
364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
366 heap_state.incremental_marking_stopped = true;
367 double idle_time_ms = 10.0;
368 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
369 EXPECT_EQ(DONE, action.type);
370 heap_state.incremental_marking_stopped = false;
371 action = handler()->Compute(idle_time_ms, heap_state);
372 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
373 }
374
375
376 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
377 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
378 for (int i = 0; i < kMaxNotifications; i++) {
379 GCIdleTimeAction action = handler()->Compute(0, heap_state);
380 EXPECT_EQ(DO_NOTHING, action.type);
381 }
382 }
383
384
385 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
386 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
387 heap_state.incremental_marking_stopped = true;
388 for (int i = 0; i < kMaxNotifications; i++) {
389 GCIdleTimeAction action = handler()->Compute(10, heap_state);
390 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
391 }
392 }
393
394
395 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) {
396 // Regression test for crbug.com/489323.
397 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
398
399 // Simulate sweeping being in-progress but not complete.
400 heap_state.incremental_marking_stopped = true;
401 heap_state.sweeping_in_progress = true;
402 heap_state.sweeping_completed = false;
403 double idle_time_ms = 10.0;
404 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimes; i++) {
405 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
406 EXPECT_EQ(DO_NOTHING, action.type);
407 }
408 // We should return DONE after not making progress for some time. 660 // We should return DONE after not making progress for some time.
409 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 661 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
410 EXPECT_EQ(DONE, action.type); 662 EXPECT_EQ(DONE, action.type);
411 } 663 }
412 664
413 665
414 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { 666 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
415 // Regression test for crbug.com/489323. 667 // Regression test for crbug.com/489323.
416 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 668 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
417 669
418 // Simulate incremental marking stopped and not eligible to start. 670 // Simulate incremental marking stopped and not eligible to start.
419 heap_state.incremental_marking_stopped = true; 671 heap_state.incremental_marking_stopped = true;
672 heap_state.can_start_incremental_marking = false;
420 double idle_time_ms = 10.0; 673 double idle_time_ms = 10.0;
421 // We should return DONE if we cannot start incremental marking. 674 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) {
675 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
676 EXPECT_EQ(DO_NOTHING, action.type);
677 }
678 // We should return DONE after not making progress for some time.
422 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 679 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
423 EXPECT_EQ(DONE, action.type); 680 EXPECT_EQ(DONE, action.type);
424 } 681 }
425 682
683
684 TEST_F(GCIdleTimeHandlerTest, BackgroundReduceLatencyToReduceMemory) {
685 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
686 heap_state.incremental_marking_stopped = false;
687 heap_state.can_start_incremental_marking = true;
688 double idle_time_ms = GCIdleTimeHandler::kMinBackgroundIdleTime;
689 handler()->NotifyScavenge();
690 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
691 int limit =
692 GCIdleTimeHandler::kBackgroundIdleNotificationsBeforeMutatorIsIdle;
693 for (int i = 0; i < limit; i++) {
694 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
695 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
696 }
697 handler()->Compute(idle_time_ms, heap_state);
698 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
699 }
700
701
702 TEST_F(GCIdleTimeHandlerTest, SkipUselessGCs) {
703 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
704 heap_state.incremental_marking_stopped = false;
705 heap_state.can_start_incremental_marking = true;
706 TransitionToReduceMemoryMode(heap_state);
707 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
708 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
709 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
710 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
711 handler()->NotifyMarkCompact(false);
712 handler()->NotifyIdleMarkCompact();
713 action = handler()->Compute(idle_time_ms, heap_state);
714 EXPECT_EQ(DONE, action.type);
715 }
716
426 } // namespace internal 717 } // namespace internal
427 } // namespace v8 718 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/test-api.cc ('k') | test/unittests/heap/memory-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698