Chromium Code Reviews| 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 239 EXPECT_EQ(DO_FULL_GC, action.type); | 235 EXPECT_EQ(DO_FULL_GC, action.type); |
| 240 } | 236 } |
| 241 | 237 |
| 242 | 238 |
| 243 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { | 239 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { |
| 244 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 240 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 245 heap_state.contexts_disposed = 1; | 241 heap_state.contexts_disposed = 1; |
| 246 heap_state.contexts_disposal_rate = | 242 heap_state.contexts_disposal_rate = |
| 247 GCIdleTimeHandler::kHighContextDisposalRate; | 243 GCIdleTimeHandler::kHighContextDisposalRate; |
| 248 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 244 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; |
| 249 double idle_time_ms = | 245 double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1); |
| 250 static_cast<double>(heap_state.size_of_objects / speed - 1); | |
| 251 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 246 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
| 252 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 247 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
| 253 } | 248 } |
| 254 | 249 |
| 255 | 250 |
| 256 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { | 251 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { |
| 257 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 252 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 258 heap_state.contexts_disposed = 1; | 253 heap_state.contexts_disposed = 1; |
| 259 heap_state.contexts_disposal_rate = | 254 heap_state.contexts_disposal_rate = |
| 260 GCIdleTimeHandler::kHighContextDisposalRate; | 255 GCIdleTimeHandler::kHighContextDisposalRate; |
| 261 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 256 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; |
| 262 double idle_time_ms = | 257 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); | 258 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
| 265 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 259 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
| 266 } | 260 } |
| 267 | 261 |
| 268 | 262 |
| 269 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { | 263 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { |
| 270 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 264 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 271 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | |
| 272 double idle_time_ms = 10; | 265 double idle_time_ms = 10; |
| 273 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 266 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
| 274 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 267 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
| 275 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | |
| 276 static_cast<size_t>(action.parameter)); | |
| 277 EXPECT_LT(0, action.parameter); | |
| 278 } | 268 } |
| 279 | 269 |
| 280 | 270 |
| 281 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { | |
|
ulan
2015/08/05 11:11:59
This test and two tests below are redundant now.
| |
| 282 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
| 283 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | |
| 284 double idle_time_ms = 10; | |
| 285 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
| 286 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | |
| 287 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | |
| 288 static_cast<size_t>(action.parameter)); | |
| 289 EXPECT_LT(0, action.parameter); | |
| 290 } | |
| 291 | |
| 292 | |
| 293 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { | 271 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { |
| 294 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 272 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 295 heap_state.incremental_marking_stopped = true; | 273 heap_state.incremental_marking_stopped = true; |
| 296 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 274 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; |
| 297 double idle_time_ms = | 275 double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1); |
| 298 static_cast<double>(heap_state.size_of_objects / speed - 1); | |
| 299 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 276 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
| 300 EXPECT_EQ(DONE, action.type); | 277 EXPECT_EQ(DONE, action.type); |
| 301 } | 278 } |
| 302 | 279 |
| 303 | 280 |
| 304 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { | |
| 305 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
| 306 heap_state.incremental_marking_stopped = true; | |
| 307 heap_state.sweeping_in_progress = true; | |
| 308 heap_state.sweeping_completed = true; | |
| 309 double idle_time_ms = 10.0; | |
| 310 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
| 311 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); | |
| 312 } | |
| 313 | |
| 314 | |
| 315 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { | |
| 316 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | |
| 317 heap_state.incremental_marking_stopped = true; | |
| 318 heap_state.sweeping_in_progress = true; | |
| 319 heap_state.sweeping_completed = false; | |
| 320 double idle_time_ms = 10.0; | |
| 321 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
| 322 EXPECT_EQ(DO_NOTHING, action.type); | |
| 323 } | |
| 324 | |
| 325 | |
| 326 TEST_F(GCIdleTimeHandlerTest, Scavenge) { | 281 TEST_F(GCIdleTimeHandlerTest, Scavenge) { |
| 327 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 282 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 328 int idle_time_ms = 10; | 283 int idle_time_ms = 10; |
| 329 heap_state.used_new_space_size = | 284 heap_state.used_new_space_size = |
| 330 heap_state.new_space_capacity - | 285 heap_state.new_space_capacity - |
| 331 (kNewSpaceAllocationThroughput * idle_time_ms); | 286 (kNewSpaceAllocationThroughput * idle_time_ms); |
| 332 GCIdleTimeAction action = | 287 GCIdleTimeAction action = |
| 333 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); | 288 handler()->Compute(static_cast<double>(idle_time_ms), heap_state); |
| 334 EXPECT_EQ(DO_SCAVENGE, action.type); | 289 EXPECT_EQ(DO_SCAVENGE, action.type); |
| 335 heap_state.used_new_space_size = 0; | 290 heap_state.used_new_space_size = 0; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 362 | 317 |
| 363 | 318 |
| 364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) { | 319 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) { |
| 365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 320 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 366 heap_state.incremental_marking_stopped = true; | 321 heap_state.incremental_marking_stopped = true; |
| 367 double idle_time_ms = 10.0; | 322 double idle_time_ms = 10.0; |
| 368 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 323 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
| 369 EXPECT_EQ(DONE, action.type); | 324 EXPECT_EQ(DONE, action.type); |
| 370 heap_state.incremental_marking_stopped = false; | 325 heap_state.incremental_marking_stopped = false; |
| 371 action = handler()->Compute(idle_time_ms, heap_state); | 326 action = handler()->Compute(idle_time_ms, heap_state); |
| 372 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 327 EXPECT_EQ(DO_INCREMENTAL_STEP, action.type); |
| 373 } | 328 } |
| 374 | 329 |
| 375 | 330 |
| 376 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { | 331 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { |
| 377 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 332 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 378 for (int i = 0; i < kMaxNotifications; i++) { | 333 for (int i = 0; i < kMaxNotifications; i++) { |
| 379 GCIdleTimeAction action = handler()->Compute(0, heap_state); | 334 GCIdleTimeAction action = handler()->Compute(0, heap_state); |
| 380 EXPECT_EQ(DO_NOTHING, action.type); | 335 EXPECT_EQ(DO_NOTHING, action.type); |
| 381 } | 336 } |
| 382 } | 337 } |
| 383 | 338 |
| 384 | 339 |
| 385 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { | 340 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { |
| 386 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 341 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 387 heap_state.incremental_marking_stopped = true; | 342 heap_state.incremental_marking_stopped = true; |
| 388 for (int i = 0; i < kMaxNotifications; i++) { | 343 for (int i = 0; i < kMaxNotifications; i++) { |
| 389 GCIdleTimeAction action = handler()->Compute(10, heap_state); | 344 GCIdleTimeAction action = handler()->Compute(10, heap_state); |
| 390 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); | 345 EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); |
| 391 } | 346 } |
| 392 } | 347 } |
| 393 | 348 |
| 394 | 349 |
| 395 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { | |
|
ulan
2015/08/05 11:11:59
This is a real change. We will keep reposting idle
| |
| 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. | |
| 409 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | |
| 410 EXPECT_EQ(DONE, action.type); | |
| 411 } | |
| 412 | |
| 413 | |
| 414 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { | 350 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { |
| 415 // Regression test for crbug.com/489323. | 351 // Regression test for crbug.com/489323. |
| 416 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 352 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |
| 417 | 353 |
| 418 // Simulate incremental marking stopped and not eligible to start. | 354 // Simulate incremental marking stopped and not eligible to start. |
| 419 heap_state.incremental_marking_stopped = true; | 355 heap_state.incremental_marking_stopped = true; |
| 420 double idle_time_ms = 10.0; | 356 double idle_time_ms = 10.0; |
| 421 // We should return DONE if we cannot start incremental marking. | 357 // We should return DONE if we cannot start incremental marking. |
| 422 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 358 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |
| 423 EXPECT_EQ(DONE, action.type); | 359 EXPECT_EQ(DONE, action.type); |
| 424 } | 360 } |
| 425 | 361 |
| 426 } // namespace internal | 362 } // namespace internal |
| 427 } // namespace v8 | 363 } // namespace v8 |
| OLD | NEW |