OLD | NEW |
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; | |
27 result.incremental_marking_stopped = false; | 26 result.incremental_marking_stopped = false; |
28 result.sweeping_in_progress = false; | |
29 result.sweeping_completed = false; | |
30 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed; | 27 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed; |
31 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed; | |
32 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed; | 28 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed; |
33 result.used_new_space_size = 0; | 29 result.used_new_space_size = 0; |
34 result.new_space_capacity = kNewSpaceCapacity; | 30 result.new_space_capacity = kNewSpaceCapacity; |
35 result.new_space_allocation_throughput_in_bytes_per_ms = | 31 result.new_space_allocation_throughput_in_bytes_per_ms = |
36 kNewSpaceAllocationThroughput; | 32 kNewSpaceAllocationThroughput; |
37 return result; | 33 return result; |
38 } | 34 } |
39 | 35 |
40 static const size_t kSizeOfObjects = 100 * MB; | 36 static const size_t kSizeOfObjects = 100 * MB; |
41 static const size_t kMarkCompactSpeed = 200 * KB; | 37 static const size_t kMarkCompactSpeed = 200 * KB; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 EXPECT_EQ(DO_FULL_GC, action.type); | 248 EXPECT_EQ(DO_FULL_GC, action.type); |
253 } | 249 } |
254 | 250 |
255 | 251 |
256 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { | 252 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { |
257 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 253 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
258 heap_state.contexts_disposed = 1; | 254 heap_state.contexts_disposed = 1; |
259 heap_state.contexts_disposal_rate = | 255 heap_state.contexts_disposal_rate = |
260 GCIdleTimeHandler::kHighContextDisposalRate; | 256 GCIdleTimeHandler::kHighContextDisposalRate; |
261 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 257 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; |
262 double idle_time_ms = | 258 double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1); |
263 static_cast<double>(heap_state.size_of_objects / speed - 1); | |
264 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 259 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
265 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 260 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
266 } | 261 } |
267 | 262 |
268 | 263 |
269 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { | 264 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { |
270 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 265 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
271 heap_state.contexts_disposed = 1; | 266 heap_state.contexts_disposed = 1; |
272 heap_state.contexts_disposal_rate = | 267 heap_state.contexts_disposal_rate = |
273 GCIdleTimeHandler::kHighContextDisposalRate; | 268 GCIdleTimeHandler::kHighContextDisposalRate; |
274 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 269 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; |
275 double idle_time_ms = | 270 double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1); |
276 static_cast<double>(heap_state.size_of_objects / speed - 1); | |
277 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 271 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
278 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 272 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
279 } | 273 } |
280 | 274 |
281 | 275 |
282 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { | 276 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { |
283 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 277 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
284 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | |
285 double idle_time_ms = 10; | 278 double idle_time_ms = 10; |
286 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 279 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
287 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 280 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
288 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | |
289 static_cast<size_t>(action.parameter)); | |
290 EXPECT_LT(0, action.parameter); | |
291 } | 281 } |
292 | 282 |
293 | 283 |
294 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { | |
295 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
296 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | |
297 double idle_time_ms = 10; | |
298 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
299 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | |
300 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | |
301 static_cast<size_t>(action.parameter)); | |
302 EXPECT_LT(0, action.parameter); | |
303 } | |
304 | |
305 | |
306 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { | 284 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { |
307 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 285 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
308 heap_state.incremental_marking_stopped = true; | 286 heap_state.incremental_marking_stopped = true; |
309 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 287 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; |
310 double idle_time_ms = | 288 double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1); |
311 static_cast<double>(heap_state.size_of_objects / speed - 1); | |
312 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 289 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
313 EXPECT_EQ(DONE, action.type); | 290 EXPECT_EQ(DONE, action.type); |
314 } | 291 } |
315 | 292 |
316 | 293 |
317 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { | |
318 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
319 heap_state.incremental_marking_stopped = true; | |
320 heap_state.sweeping_in_progress = true; | |
321 heap_state.sweeping_completed = true; | |
322 double idle_time_ms = 10.0; | |
323 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
324 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); | |
325 } | |
326 | |
327 | |
328 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { | |
329 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
330 heap_state.incremental_marking_stopped = true; | |
331 heap_state.sweeping_in_progress = true; | |
332 heap_state.sweeping_completed = false; | |
333 double idle_time_ms = 10.0; | |
334 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
335 EXPECT_EQ(DO_NOTHING, action.type); | |
336 } | |
337 | |
338 | |
339 TEST_F(GCIdleTimeHandlerTest, Scavenge) { | 294 TEST_F(GCIdleTimeHandlerTest, Scavenge) { |
340 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 295 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
341 int idle_time_ms = 10; | 296 int idle_time_ms = 10; |
342 heap_state.used_new_space_size = | 297 heap_state.used_new_space_size = |
343 heap_state.new_space_capacity - | 298 heap_state.new_space_capacity - |
344 (kNewSpaceAllocationThroughput * idle_time_ms); | 299 (kNewSpaceAllocationThroughput * idle_time_ms); |
345 GCIdleTimeAction action = | 300 GCIdleTimeAction action = |
346 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); | 301 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); |
347 EXPECT_EQ(DO_SCAVENGE, action.type); | 302 EXPECT_EQ(DO_SCAVENGE, action.type); |
348 heap_state.used_new_space_size = 0; | 303 heap_state.used_new_space_size = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
375 | 330 |
376 | 331 |
377 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) { | 332 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) { |
378 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 333 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
379 heap_state.incremental_marking_stopped = true; | 334 heap_state.incremental_marking_stopped = true; |
380 double idle_time_ms = 10.0; | 335 double idle_time_ms = 10.0; |
381 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 336 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
382 EXPECT_EQ(DONE, action.type); | 337 EXPECT_EQ(DONE, action.type); |
383 heap_state.incremental_marking_stopped = false; | 338 heap_state.incremental_marking_stopped = false; |
384 action = handler()->Compute(idle_time_ms, heap_state); | 339 action = handler()->Compute(idle_time_ms, heap_state); |
385 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 340 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
386 } | 341 } |
387 | 342 |
388 | 343 |
389 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { | 344 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { |
390 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 345 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
391 for (int i = 0; i < kMaxNotifications; i++) { | 346 for (int i = 0; i < kMaxNotifications; i++) { |
392 GCIdleTimeAction action = handler()->Compute(0, heap_state); | 347 GCIdleTimeAction action = handler()->Compute(0, heap_state); |
393 EXPECT_EQ(DO_NOTHING, action.type); | 348 EXPECT_EQ(DO_NOTHING, action.type); |
394 } | 349 } |
395 } | 350 } |
396 | 351 |
397 | 352 |
398 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { | 353 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { |
399 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 354 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
400 heap_state.incremental_marking_stopped = true; | 355 heap_state.incremental_marking_stopped = true; |
401 for (int i = 0; i < kMaxNotifications; i++) { | 356 for (int i = 0; i < kMaxNotifications; i++) { |
402 GCIdleTimeAction action = handler()->Compute(10, heap_state); | 357 GCIdleTimeAction action = handler()->Compute(10, heap_state); |
403 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); | 358 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); |
404 } | 359 } |
405 } | 360 } |
406 | 361 |
407 | 362 |
408 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { | |
409 // Regression test for crbug.com/489323. | |
410 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
411 | |
412 // Simulate sweeping being in-progress but not complete. | |
413 heap_state.incremental_marking_stopped = true; | |
414 heap_state.sweeping_in_progress = true; | |
415 heap_state.sweeping_completed = false; | |
416 double idle_time_ms = 10.0; | |
417 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimes; i++) { | |
418 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
419 EXPECT_EQ(DO_NOTHING, action.type); | |
420 } | |
421 // We should return DONE after not making progress for some time. | |
422 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
423 EXPECT_EQ(DONE, action.type); | |
424 } | |
425 | |
426 | |
427 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { | 363 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { |
428 // Regression test for crbug.com/489323. | 364 // Regression test for crbug.com/489323. |
429 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
430 | 366 |
431 // Simulate incremental marking stopped and not eligible to start. | 367 // Simulate incremental marking stopped and not eligible to start. |
432 heap_state.incremental_marking_stopped = true; | 368 heap_state.incremental_marking_stopped = true; |
433 double idle_time_ms = 10.0; | 369 double idle_time_ms = 10.0; |
434 // We should return DONE if we cannot start incremental marking. | 370 // We should return DONE if we cannot start incremental marking. |
435 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 371 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
436 EXPECT_EQ(DONE, action.type); | 372 EXPECT_EQ(DONE, action.type); |
437 } | 373 } |
438 | 374 |
439 } // namespace internal | 375 } // namespace internal |
440 } // namespace v8 | 376 } // namespace v8 |
OLD | NEW |