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

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

Issue 1214813004: Version 4.5.95.1 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.5.95
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 =
247 GCIdleTimeHandler::kHighContextDisposalRate; 309 GCIdleTimeHandler::kHighContextDisposalRate;
310 heap_state.incremental_marking_stopped = true;
248 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 311 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
249 double idle_time_ms = 312 double idle_time_ms =
250 static_cast<double>(heap_state.size_of_objects / speed - 1); 313 static_cast<double>(heap_state.size_of_objects / speed - 1);
251 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 314 for (int mode = 0; mode < 1; mode++) {
252 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 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 }
253 } 320 }
254 321
255 322
256 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { 323 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
257 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 324 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
258 heap_state.contexts_disposed = 1; 325 heap_state.contexts_disposed = 1;
259 heap_state.contexts_disposal_rate = 326 heap_state.contexts_disposal_rate =
260 GCIdleTimeHandler::kHighContextDisposalRate; 327 GCIdleTimeHandler::kHighContextDisposalRate;
261 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;
262 double idle_time_ms = 329 double idle_time_ms =
263 static_cast<double>(heap_state.size_of_objects / speed - 1); 330 static_cast<double>(heap_state.size_of_objects / speed - 1);
264 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 331 for (int mode = 0; mode < 1; mode++) {
265 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 332 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
333 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
334 heap_state.contexts_disposal_rate = 0.0;
335 TransitionToReduceMemoryMode(heap_state);
336 }
266 } 337 }
267 338
268 339
269 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { 340 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
270 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 341 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
271 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 342 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
272 double idle_time_ms = 10; 343 double idle_time_ms = 10;
273 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 344 for (int mode = 0; mode < 1; mode++) {
274 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 345 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
275 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 346 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
276 static_cast<size_t>(action.parameter)); 347 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
277 EXPECT_LT(0, action.parameter); 348 static_cast<size_t>(action.parameter));
349 EXPECT_LT(0, action.parameter);
350 TransitionToReduceMemoryMode(heap_state);
351 }
278 } 352 }
279 353
280 354
281 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { 355 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
282 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
357 heap_state.incremental_marking_stopped = true;
283 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 358 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
284 double idle_time_ms = 10; 359 double idle_time_ms = 10;
285 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 360 for (int mode = 0; mode < 1; mode++) {
286 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 361 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
287 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 362 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
288 static_cast<size_t>(action.parameter)); 363 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
289 EXPECT_LT(0, action.parameter); 364 static_cast<size_t>(action.parameter));
365 EXPECT_LT(0, action.parameter);
366 TransitionToReduceMemoryMode(heap_state);
367 }
290 } 368 }
291 369
292 370
293 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { 371 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
294 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 372 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
295 heap_state.incremental_marking_stopped = true; 373 heap_state.incremental_marking_stopped = true;
374 heap_state.can_start_incremental_marking = false;
296 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;
297 double idle_time_ms = 376 double idle_time_ms =
298 static_cast<double>(heap_state.size_of_objects / speed - 1); 377 static_cast<double>(heap_state.size_of_objects / speed - 1);
299 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 378 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
300 EXPECT_EQ(DONE, action.type); 379 EXPECT_EQ(DO_NOTHING, action.type);
380 TransitionToReduceMemoryMode(heap_state);
381 action = handler()->Compute(idle_time_ms, heap_state);
382 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
301 } 383 }
302 384
303 385
304 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { 386 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) {
305 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 387 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
306 heap_state.incremental_marking_stopped = true; 388 heap_state.incremental_marking_stopped = true;
307 heap_state.sweeping_in_progress = true; 389 heap_state.can_start_incremental_marking = false;
308 heap_state.sweeping_completed = true; 390 for (int mode = 0; mode < 1; mode++) {
309 double idle_time_ms = 10.0; 391 heap_state.sweeping_in_progress = true;
310 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 392 heap_state.sweeping_completed = true;
311 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); 393 double idle_time_ms = 10.0;
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 }
312 } 400 }
313 401
314 402
315 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { 403 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) {
316 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 404 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
317 heap_state.incremental_marking_stopped = true; 405 heap_state.incremental_marking_stopped = true;
318 heap_state.sweeping_in_progress = true; 406 heap_state.can_start_incremental_marking = false;
319 heap_state.sweeping_completed = false; 407 for (int mode = 0; mode < 1; mode++) {
320 double idle_time_ms = 10.0; 408 heap_state.sweeping_in_progress = true;
321 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 409 heap_state.sweeping_completed = false;
322 EXPECT_EQ(DO_NOTHING, action.type); 410 double idle_time_ms = 10.0;
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 }
323 } 417 }
324 418
325 419
326 TEST_F(GCIdleTimeHandlerTest, Scavenge) { 420 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
327 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 421 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
328 int idle_time_ms = 10; 422 int idle_time_ms = 10;
329 heap_state.used_new_space_size = 423 for (int mode = 0; mode < 1; mode++) {
330 heap_state.new_space_capacity - 424 heap_state.used_new_space_size =
331 (kNewSpaceAllocationThroughput * idle_time_ms); 425 heap_state.new_space_capacity -
332 GCIdleTimeAction action = 426 (kNewSpaceAllocationThroughput * idle_time_ms);
333 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); 427 GCIdleTimeAction action =
334 EXPECT_EQ(DO_SCAVENGE, action.type); 428 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
335 heap_state.used_new_space_size = 0; 429 EXPECT_EQ(DO_SCAVENGE, action.type);
430 heap_state.used_new_space_size = 0;
431 TransitionToReduceMemoryMode(heap_state);
432 }
336 } 433 }
337 434
338 435
339 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) { 436 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
340 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 437 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
341 int idle_time_ms = 10; 438 int idle_time_ms = 10;
439 heap_state.can_start_incremental_marking = false;
342 heap_state.incremental_marking_stopped = true; 440 heap_state.incremental_marking_stopped = true;
343 heap_state.used_new_space_size = 441 for (int mode = 0; mode < 1; mode++) {
344 heap_state.new_space_capacity - 442 heap_state.used_new_space_size =
345 (kNewSpaceAllocationThroughput * idle_time_ms); 443 heap_state.new_space_capacity -
346 GCIdleTimeAction action = 444 (kNewSpaceAllocationThroughput * idle_time_ms);
347 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); 445 GCIdleTimeAction action =
348 EXPECT_EQ(DO_SCAVENGE, action.type); 446 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
349 heap_state.used_new_space_size = 0; 447 EXPECT_EQ(DO_SCAVENGE, action.type);
350 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state); 448 heap_state.used_new_space_size = 0;
351 EXPECT_EQ(DONE, action.type); 449 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
450 EXPECT_EQ(DO_NOTHING, action.type);
451 TransitionToReduceMemoryMode(heap_state);
452 }
352 } 453 }
353 454
354 455
355 TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) { 456 TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
356 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 457 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
357 heap_state.incremental_marking_stopped = true; 458 heap_state.incremental_marking_stopped = true;
358 double idle_time_ms = 10.0; 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;
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);
359 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 483 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
360 EXPECT_EQ(DONE, action.type); 484 EXPECT_EQ(DONE, action.type);
361 } 485 }
362 486
363 487
364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) { 488 TEST_F(GCIdleTimeHandlerTest, StopEventually3) {
365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 489 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
366 heap_state.incremental_marking_stopped = true; 490 heap_state.incremental_marking_stopped = true;
367 double idle_time_ms = 10.0; 491 heap_state.can_start_incremental_marking = false;
492 double idle_time_ms = 10;
493 TransitionToReduceMemoryMode(heap_state);
494 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
368 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 495 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
369 EXPECT_EQ(DONE, action.type); 496 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 } 497 }
374 498
375 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
376 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { 538 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
377 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 539 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
378 for (int i = 0; i < kMaxNotifications; i++) { 540 for (int i = 0; i < kMaxNotifications; i++) {
379 GCIdleTimeAction action = handler()->Compute(0, heap_state); 541 GCIdleTimeAction action = handler()->Compute(0, heap_state);
380 EXPECT_EQ(DO_NOTHING, action.type); 542 EXPECT_EQ(DO_NOTHING, action.type);
381 } 543 }
382 } 544 }
383 545
384 546
385 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { 547 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
386 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 548 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
387 heap_state.incremental_marking_stopped = true; 549 heap_state.incremental_marking_stopped = true;
550 heap_state.can_start_incremental_marking = false;
388 for (int i = 0; i < kMaxNotifications; i++) { 551 for (int i = 0; i < kMaxNotifications; i++) {
389 GCIdleTimeAction action = handler()->Compute(10, heap_state); 552 GCIdleTimeAction action = handler()->Compute(10, heap_state);
390 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); 553 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
391 } 554 }
392 } 555 }
393 556
394 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
395 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { 646 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) {
396 // Regression test for crbug.com/489323. 647 // Regression test for crbug.com/489323.
397 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 648 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
398 649
399 // Simulate sweeping being in-progress but not complete. 650 // Simulate sweeping being in-progress but not complete.
400 heap_state.incremental_marking_stopped = true; 651 heap_state.incremental_marking_stopped = true;
652 heap_state.can_start_incremental_marking = false;
401 heap_state.sweeping_in_progress = true; 653 heap_state.sweeping_in_progress = true;
402 heap_state.sweeping_completed = false; 654 heap_state.sweeping_completed = false;
403 double idle_time_ms = 10.0; 655 double idle_time_ms = 10.0;
404 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimes; i++) { 656 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) {
405 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 657 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
406 EXPECT_EQ(DO_NOTHING, action.type); 658 EXPECT_EQ(DO_NOTHING, action.type);
407 } 659 }
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