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

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

Issue 1208993009: Reland "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;
29 result.sweeping_in_progress = false; 28 result.sweeping_in_progress = false;
30 result.sweeping_completed = false; 29 result.sweeping_completed = false;
31 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed; 30 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
32 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed; 31 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
33 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed; 32 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
34 result.used_new_space_size = 0; 33 result.used_new_space_size = 0;
35 result.new_space_capacity = kNewSpaceCapacity; 34 result.new_space_capacity = kNewSpaceCapacity;
36 result.new_space_allocation_throughput_in_bytes_per_ms = 35 result.new_space_allocation_throughput_in_bytes_per_ms =
37 kNewSpaceAllocationThroughput; 36 kNewSpaceAllocationThroughput;
38 return result; 37 return result;
39 } 38 }
40 39
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
91 static const size_t kSizeOfObjects = 100 * MB; 40 static const size_t kSizeOfObjects = 100 * MB;
92 static const size_t kMarkCompactSpeed = 200 * KB; 41 static const size_t kMarkCompactSpeed = 200 * KB;
93 static const size_t kMarkingSpeed = 200 * KB; 42 static const size_t kMarkingSpeed = 200 * KB;
94 static const size_t kScavengeSpeed = 100 * KB; 43 static const size_t kScavengeSpeed = 100 * KB;
95 static const size_t kNewSpaceCapacity = 1 * MB; 44 static const size_t kNewSpaceCapacity = 1 * MB;
96 static const size_t kNewSpaceAllocationThroughput = 10 * KB; 45 static const size_t kNewSpaceAllocationThroughput = 10 * KB;
97 static const int kMaxNotifications = 1000; 46 static const int kMaxNotifications = 100;
98 47
99 private: 48 private:
100 GCIdleTimeHandler handler_; 49 GCIdleTimeHandler handler_;
101 }; 50 };
102 51
103 } // namespace 52 } // namespace
104 53
105 54
106 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) { 55 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
107 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0); 56 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( 205 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
257 idle_time_ms, kSizeOfObjects, kMarkingSpeed)); 206 idle_time_ms, kSizeOfObjects, kMarkingSpeed));
258 } 207 }
259 208
260 209
261 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { 210 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
262 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 211 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
263 heap_state.contexts_disposed = 1; 212 heap_state.contexts_disposed = 1;
264 heap_state.incremental_marking_stopped = true; 213 heap_state.incremental_marking_stopped = true;
265 double idle_time_ms = 0; 214 double idle_time_ms = 0;
266 for (int mode = 0; mode < 1; mode++) { 215 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
267 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 216 EXPECT_EQ(DO_NOTHING, action.type);
268 EXPECT_EQ(DO_NOTHING, action.type);
269 TransitionToReduceMemoryMode(heap_state);
270 }
271 } 217 }
272 218
273 219
274 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { 220 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
275 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 221 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
276 heap_state.contexts_disposed = 1; 222 heap_state.contexts_disposed = 1;
277 heap_state.contexts_disposal_rate = 223 heap_state.contexts_disposal_rate =
278 GCIdleTimeHandler::kHighContextDisposalRate - 1; 224 GCIdleTimeHandler::kHighContextDisposalRate - 1;
279 heap_state.incremental_marking_stopped = true; 225 heap_state.incremental_marking_stopped = true;
280 double idle_time_ms = 0; 226 double idle_time_ms = 0;
281 for (int mode = 0; mode < 1; mode++) { 227 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
282 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 228 EXPECT_EQ(DO_FULL_GC, action.type);
283 EXPECT_EQ(DO_FULL_GC, action.type);
284 heap_state.contexts_disposal_rate = 0.0;
285 TransitionToReduceMemoryMode(heap_state);
286 }
287 } 229 }
288 230
289 231
290 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { 232 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
291 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 233 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
292 heap_state.contexts_disposed = 1; 234 heap_state.contexts_disposed = 1;
293 heap_state.contexts_disposal_rate = 1.0; 235 heap_state.contexts_disposal_rate = 1.0;
294 heap_state.incremental_marking_stopped = true; 236 heap_state.incremental_marking_stopped = true;
295 double idle_time_ms = 0; 237 double idle_time_ms = 0;
296 for (int mode = 0; mode < 1; mode++) { 238 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
297 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 239 EXPECT_EQ(DO_FULL_GC, action.type);
298 EXPECT_EQ(DO_FULL_GC, action.type);
299 heap_state.contexts_disposal_rate = 0.0;
300 TransitionToReduceMemoryMode(heap_state);
301 }
302 } 240 }
303 241
304 242
305 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { 243 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
306 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 244 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
307 heap_state.contexts_disposed = 1; 245 heap_state.contexts_disposed = 1;
308 heap_state.contexts_disposal_rate = 246 heap_state.contexts_disposal_rate =
309 GCIdleTimeHandler::kHighContextDisposalRate; 247 GCIdleTimeHandler::kHighContextDisposalRate;
310 heap_state.incremental_marking_stopped = true;
311 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 248 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
312 double idle_time_ms = 249 double idle_time_ms =
313 static_cast<double>(heap_state.size_of_objects / speed - 1); 250 static_cast<double>(heap_state.size_of_objects / speed - 1);
314 for (int mode = 0; mode < 1; mode++) { 251 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
315 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 252 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
316 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
317 heap_state.contexts_disposal_rate = 0.0;
318 TransitionToReduceMemoryMode(heap_state);
319 }
320 } 253 }
321 254
322 255
323 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { 256 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
324 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 257 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
325 heap_state.contexts_disposed = 1; 258 heap_state.contexts_disposed = 1;
326 heap_state.contexts_disposal_rate = 259 heap_state.contexts_disposal_rate =
327 GCIdleTimeHandler::kHighContextDisposalRate; 260 GCIdleTimeHandler::kHighContextDisposalRate;
328 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 261 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
329 double idle_time_ms = 262 double idle_time_ms =
330 static_cast<double>(heap_state.size_of_objects / speed - 1); 263 static_cast<double>(heap_state.size_of_objects / speed - 1);
331 for (int mode = 0; mode < 1; mode++) { 264 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
332 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 265 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
333 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
334 heap_state.contexts_disposal_rate = 0.0;
335 TransitionToReduceMemoryMode(heap_state);
336 }
337 } 266 }
338 267
339 268
340 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { 269 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
341 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 270 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
342 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 271 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
343 double idle_time_ms = 10; 272 double idle_time_ms = 10;
344 for (int mode = 0; mode < 1; mode++) { 273 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
345 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 274 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
346 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 275 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
347 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 276 static_cast<size_t>(action.parameter));
348 static_cast<size_t>(action.parameter)); 277 EXPECT_LT(0, action.parameter);
349 EXPECT_LT(0, action.parameter);
350 TransitionToReduceMemoryMode(heap_state);
351 }
352 } 278 }
353 279
354 280
355 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { 281 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 282 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; 283 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
359 double idle_time_ms = 10; 284 double idle_time_ms = 10;
360 for (int mode = 0; mode < 1; mode++) { 285 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
361 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 286 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
362 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 287 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
363 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 288 static_cast<size_t>(action.parameter));
364 static_cast<size_t>(action.parameter)); 289 EXPECT_LT(0, action.parameter);
365 EXPECT_LT(0, action.parameter);
366 TransitionToReduceMemoryMode(heap_state);
367 }
368 } 290 }
369 291
370 292
371 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { 293 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
372 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 294 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
373 heap_state.incremental_marking_stopped = true; 295 heap_state.incremental_marking_stopped = true;
374 heap_state.can_start_incremental_marking = false;
375 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 296 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
376 double idle_time_ms = 297 double idle_time_ms =
377 static_cast<double>(heap_state.size_of_objects / speed - 1); 298 static_cast<double>(heap_state.size_of_objects / speed - 1);
378 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 299 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
379 EXPECT_EQ(DO_NOTHING, action.type); 300 EXPECT_EQ(DONE, action.type);
380 TransitionToReduceMemoryMode(heap_state);
381 action = handler()->Compute(idle_time_ms, heap_state);
382 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
383 } 301 }
384 302
385 303
386 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { 304 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) {
387 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 305 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
388 heap_state.incremental_marking_stopped = true; 306 heap_state.incremental_marking_stopped = true;
389 heap_state.can_start_incremental_marking = false; 307 heap_state.sweeping_in_progress = true;
390 for (int mode = 0; mode < 1; mode++) { 308 heap_state.sweeping_completed = true;
391 heap_state.sweeping_in_progress = true; 309 double idle_time_ms = 10.0;
392 heap_state.sweeping_completed = true; 310 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
393 double idle_time_ms = 10.0; 311 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
394 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
395 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
396 heap_state.sweeping_in_progress = false;
397 heap_state.sweeping_completed = false;
398 TransitionToReduceMemoryMode(heap_state);
399 }
400 } 312 }
401 313
402 314
403 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { 315 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) {
404 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 316 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
405 heap_state.incremental_marking_stopped = true; 317 heap_state.incremental_marking_stopped = true;
406 heap_state.can_start_incremental_marking = false; 318 heap_state.sweeping_in_progress = true;
407 for (int mode = 0; mode < 1; mode++) { 319 heap_state.sweeping_completed = false;
408 heap_state.sweeping_in_progress = true; 320 double idle_time_ms = 10.0;
409 heap_state.sweeping_completed = false; 321 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
410 double idle_time_ms = 10.0; 322 EXPECT_EQ(DO_NOTHING, action.type);
411 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
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 } 323 }
418 324
419 325
420 TEST_F(GCIdleTimeHandlerTest, Scavenge) { 326 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
421 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 327 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
422 int idle_time_ms = 10; 328 int idle_time_ms = 10;
423 for (int mode = 0; mode < 1; mode++) { 329 heap_state.used_new_space_size =
424 heap_state.used_new_space_size = 330 heap_state.new_space_capacity -
425 heap_state.new_space_capacity - 331 (kNewSpaceAllocationThroughput * idle_time_ms);
426 (kNewSpaceAllocationThroughput * idle_time_ms); 332 GCIdleTimeAction action =
427 GCIdleTimeAction action = 333 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
428 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); 334 EXPECT_EQ(DO_SCAVENGE, action.type);
429 EXPECT_EQ(DO_SCAVENGE, action.type); 335 heap_state.used_new_space_size = 0;
430 heap_state.used_new_space_size = 0;
431 TransitionToReduceMemoryMode(heap_state);
432 }
433 } 336 }
434 337
435 338
436 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) { 339 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
437 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 340 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
438 int idle_time_ms = 10; 341 int idle_time_ms = 10;
439 heap_state.can_start_incremental_marking = false;
440 heap_state.incremental_marking_stopped = true; 342 heap_state.incremental_marking_stopped = true;
441 for (int mode = 0; mode < 1; mode++) { 343 heap_state.used_new_space_size =
442 heap_state.used_new_space_size = 344 heap_state.new_space_capacity -
443 heap_state.new_space_capacity - 345 (kNewSpaceAllocationThroughput * idle_time_ms);
444 (kNewSpaceAllocationThroughput * idle_time_ms); 346 GCIdleTimeAction action =
445 GCIdleTimeAction action = 347 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
446 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); 348 EXPECT_EQ(DO_SCAVENGE, action.type);
447 EXPECT_EQ(DO_SCAVENGE, action.type); 349 heap_state.used_new_space_size = 0;
448 heap_state.used_new_space_size = 0; 350 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
449 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state); 351 EXPECT_EQ(DONE, action.type);
450 EXPECT_EQ(DO_NOTHING, action.type);
451 TransitionToReduceMemoryMode(heap_state);
452 }
453 } 352 }
454 353
455 354
456 TEST_F(GCIdleTimeHandlerTest, StopEventually1) { 355 TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
457 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
458 heap_state.incremental_marking_stopped = true; 357 heap_state.incremental_marking_stopped = true;
459 heap_state.can_start_incremental_marking = false; 358 double idle_time_ms = 10.0;
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;
478 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
479 double idle_time_ms =
480 static_cast<double>(heap_state.size_of_objects / speed + 1);
481 TransitionToReduceMemoryMode(heap_state);
482 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
483 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 359 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
484 EXPECT_EQ(DONE, action.type); 360 EXPECT_EQ(DONE, action.type);
485 } 361 }
486 362
487 363
488 TEST_F(GCIdleTimeHandlerTest, StopEventually3) { 364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
489 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
490 heap_state.incremental_marking_stopped = true; 366 heap_state.incremental_marking_stopped = true;
491 heap_state.can_start_incremental_marking = false; 367 double idle_time_ms = 10.0;
492 double idle_time_ms = 10;
493 TransitionToReduceMemoryMode(heap_state);
494 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
495 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 368 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
496 EXPECT_EQ(DONE, action.type); 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);
497 } 373 }
498 374
499 375
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) { 376 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
539 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 377 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
540 for (int i = 0; i < kMaxNotifications; i++) { 378 for (int i = 0; i < kMaxNotifications; i++) {
541 GCIdleTimeAction action = handler()->Compute(0, heap_state); 379 GCIdleTimeAction action = handler()->Compute(0, heap_state);
542 EXPECT_EQ(DO_NOTHING, action.type); 380 EXPECT_EQ(DO_NOTHING, action.type);
543 } 381 }
544 } 382 }
545 383
546 384
547 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { 385 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
548 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 386 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
549 heap_state.incremental_marking_stopped = true; 387 heap_state.incremental_marking_stopped = true;
550 heap_state.can_start_incremental_marking = false;
551 for (int i = 0; i < kMaxNotifications; i++) { 388 for (int i = 0; i < kMaxNotifications; i++) {
552 GCIdleTimeAction action = handler()->Compute(10, heap_state); 389 GCIdleTimeAction action = handler()->Compute(10, heap_state);
553 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); 390 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
554 } 391 }
555 } 392 }
556 393
557 394
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) { 395 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) {
647 // Regression test for crbug.com/489323. 396 // Regression test for crbug.com/489323.
648 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 397 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
649 398
650 // Simulate sweeping being in-progress but not complete. 399 // Simulate sweeping being in-progress but not complete.
651 heap_state.incremental_marking_stopped = true; 400 heap_state.incremental_marking_stopped = true;
652 heap_state.can_start_incremental_marking = false;
653 heap_state.sweeping_in_progress = true; 401 heap_state.sweeping_in_progress = true;
654 heap_state.sweeping_completed = false; 402 heap_state.sweeping_completed = false;
655 double idle_time_ms = 10.0; 403 double idle_time_ms = 10.0;
656 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) { 404 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimes; i++) {
657 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 405 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
658 EXPECT_EQ(DO_NOTHING, action.type); 406 EXPECT_EQ(DO_NOTHING, action.type);
659 } 407 }
660 // We should return DONE after not making progress for some time. 408 // We should return DONE after not making progress for some time.
661 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 409 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
662 EXPECT_EQ(DONE, action.type); 410 EXPECT_EQ(DONE, action.type);
663 } 411 }
664 412
665 413
666 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { 414 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
667 // Regression test for crbug.com/489323. 415 // Regression test for crbug.com/489323.
668 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 416 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
669 417
670 // Simulate incremental marking stopped and not eligible to start. 418 // Simulate incremental marking stopped and not eligible to start.
671 heap_state.incremental_marking_stopped = true; 419 heap_state.incremental_marking_stopped = true;
672 heap_state.can_start_incremental_marking = false;
673 double idle_time_ms = 10.0; 420 double idle_time_ms = 10.0;
674 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) { 421 // We should return DONE if we cannot start incremental marking.
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.
679 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 422 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
680 EXPECT_EQ(DONE, action.type); 423 EXPECT_EQ(DONE, action.type);
681 } 424 }
682 425
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
717 } // namespace internal 426 } // namespace internal
718 } // namespace v8 427 } // 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