| 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; | 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  Loading... | 
| 205   EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( | 256   EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( | 
| 206       idle_time_ms, kSizeOfObjects, kMarkingSpeed)); | 257       idle_time_ms, kSizeOfObjects, kMarkingSpeed)); | 
| 207 } | 258 } | 
| 208 | 259 | 
| 209 | 260 | 
| 210 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { | 261 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { | 
| 211   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 262   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 212   heap_state.contexts_disposed = 1; | 263   heap_state.contexts_disposed = 1; | 
| 213   heap_state.incremental_marking_stopped = true; | 264   heap_state.incremental_marking_stopped = true; | 
| 214   double idle_time_ms = 0; | 265   double idle_time_ms = 0; | 
| 215   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 266   for (int mode = 0; mode < 1; mode++) { | 
| 216   EXPECT_EQ(DO_NOTHING, action.type); | 267     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 268     EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 269     TransitionToReduceMemoryMode(heap_state); | 
|  | 270   } | 
| 217 } | 271 } | 
| 218 | 272 | 
| 219 | 273 | 
| 220 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { | 274 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { | 
| 221   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 275   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 222   heap_state.contexts_disposed = 1; | 276   heap_state.contexts_disposed = 1; | 
| 223   heap_state.contexts_disposal_rate = | 277   heap_state.contexts_disposal_rate = | 
| 224       GCIdleTimeHandler::kHighContextDisposalRate - 1; | 278       GCIdleTimeHandler::kHighContextDisposalRate - 1; | 
| 225   heap_state.incremental_marking_stopped = true; | 279   heap_state.incremental_marking_stopped = true; | 
| 226   double idle_time_ms = 0; | 280   double idle_time_ms = 0; | 
| 227   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 281   for (int mode = 0; mode < 1; mode++) { | 
| 228   EXPECT_EQ(DO_FULL_GC, action.type); | 282     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 283     EXPECT_EQ(DO_FULL_GC, action.type); | 
|  | 284     heap_state.contexts_disposal_rate = 0.0; | 
|  | 285     TransitionToReduceMemoryMode(heap_state); | 
|  | 286   } | 
| 229 } | 287 } | 
| 230 | 288 | 
| 231 | 289 | 
| 232 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { | 290 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { | 
| 233   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 291   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 234   heap_state.contexts_disposed = 1; | 292   heap_state.contexts_disposed = 1; | 
| 235   heap_state.contexts_disposal_rate = 1.0; | 293   heap_state.contexts_disposal_rate = 1.0; | 
| 236   heap_state.incremental_marking_stopped = true; | 294   heap_state.incremental_marking_stopped = true; | 
| 237   double idle_time_ms = 0; | 295   double idle_time_ms = 0; | 
| 238   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 296   for (int mode = 0; mode < 1; mode++) { | 
| 239   EXPECT_EQ(DO_FULL_GC, action.type); | 297     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 298     EXPECT_EQ(DO_FULL_GC, action.type); | 
|  | 299     heap_state.contexts_disposal_rate = 0.0; | 
|  | 300     TransitionToReduceMemoryMode(heap_state); | 
|  | 301   } | 
| 240 } | 302 } | 
| 241 | 303 | 
| 242 | 304 | 
| 243 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { | 305 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { | 
| 244   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 306   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 245   heap_state.contexts_disposed = 1; | 307   heap_state.contexts_disposed = 1; | 
| 246   heap_state.contexts_disposal_rate = | 308   heap_state.contexts_disposal_rate = | 
|  | 309       GCIdleTimeHandler::kHighContextDisposalRate; | 
|  | 310   heap_state.incremental_marking_stopped = true; | 
|  | 311   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 
|  | 312   double idle_time_ms = | 
|  | 313       static_cast<double>(heap_state.size_of_objects / speed - 1); | 
|  | 314   for (int mode = 0; mode < 1; mode++) { | 
|  | 315     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 316     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 317     heap_state.contexts_disposal_rate = 0.0; | 
|  | 318     TransitionToReduceMemoryMode(heap_state); | 
|  | 319   } | 
|  | 320 } | 
|  | 321 | 
|  | 322 | 
|  | 323 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { | 
|  | 324   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 325   heap_state.contexts_disposed = 1; | 
|  | 326   heap_state.contexts_disposal_rate = | 
| 247       GCIdleTimeHandler::kHighContextDisposalRate; | 327       GCIdleTimeHandler::kHighContextDisposalRate; | 
| 248   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 328   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 
| 249   double idle_time_ms = | 329   double idle_time_ms = | 
| 250       static_cast<double>(heap_state.size_of_objects / speed - 1); | 330       static_cast<double>(heap_state.size_of_objects / speed - 1); | 
| 251   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 331   for (int mode = 0; mode < 1; mode++) { | 
| 252   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 332     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 253 } | 333     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
| 254 | 334     heap_state.contexts_disposal_rate = 0.0; | 
| 255 | 335     TransitionToReduceMemoryMode(heap_state); | 
| 256 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { | 336   } | 
| 257   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 337 } | 
| 258   heap_state.contexts_disposed = 1; | 338 | 
| 259   heap_state.contexts_disposal_rate = | 339 | 
| 260       GCIdleTimeHandler::kHighContextDisposalRate; | 340 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { | 
|  | 341   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 342   size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | 
|  | 343   double idle_time_ms = 10; | 
|  | 344   for (int mode = 0; mode < 1; mode++) { | 
|  | 345     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 346     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 347     EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | 
|  | 348               static_cast<size_t>(action.parameter)); | 
|  | 349     EXPECT_LT(0, action.parameter); | 
|  | 350     TransitionToReduceMemoryMode(heap_state); | 
|  | 351   } | 
|  | 352 } | 
|  | 353 | 
|  | 354 | 
|  | 355 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { | 
|  | 356   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 357   heap_state.incremental_marking_stopped = true; | 
|  | 358   size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | 
|  | 359   double idle_time_ms = 10; | 
|  | 360   for (int mode = 0; mode < 1; mode++) { | 
|  | 361     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 362     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 363     EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | 
|  | 364               static_cast<size_t>(action.parameter)); | 
|  | 365     EXPECT_LT(0, action.parameter); | 
|  | 366     TransitionToReduceMemoryMode(heap_state); | 
|  | 367   } | 
|  | 368 } | 
|  | 369 | 
|  | 370 | 
|  | 371 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { | 
|  | 372   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 373   heap_state.incremental_marking_stopped = true; | 
|  | 374   heap_state.can_start_incremental_marking = false; | 
| 261   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 375   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 
| 262   double idle_time_ms = | 376   double idle_time_ms = | 
| 263       static_cast<double>(heap_state.size_of_objects / speed - 1); | 377       static_cast<double>(heap_state.size_of_objects / speed - 1); | 
| 264   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 378   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 379   EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 380   TransitionToReduceMemoryMode(heap_state); | 
|  | 381   action = handler()->Compute(idle_time_ms, heap_state); | 
| 265   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 382   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
| 266 } | 383 } | 
| 267 | 384 | 
| 268 | 385 | 
| 269 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { | 386 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { | 
| 270   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 387   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 271   size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | 388   heap_state.incremental_marking_stopped = true; | 
| 272   double idle_time_ms = 10; | 389   heap_state.can_start_incremental_marking = false; | 
| 273   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 390   for (int mode = 0; mode < 1; mode++) { | 
| 274   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 391     heap_state.sweeping_in_progress = true; | 
| 275   EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | 392     heap_state.sweeping_completed = true; | 
| 276             static_cast<size_t>(action.parameter)); | 393     double idle_time_ms = 10.0; | 
| 277   EXPECT_LT(0, action.parameter); | 394     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 278 } | 395     EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); | 
| 279 | 396     heap_state.sweeping_in_progress = false; | 
| 280 | 397     heap_state.sweeping_completed = false; | 
| 281 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { | 398     TransitionToReduceMemoryMode(heap_state); | 
| 282   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 399   } | 
| 283   size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; | 400 } | 
| 284   double idle_time_ms = 10; | 401 | 
| 285   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 402 | 
| 286   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 403 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { | 
| 287   EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), | 404   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 288             static_cast<size_t>(action.parameter)); | 405   heap_state.incremental_marking_stopped = true; | 
| 289   EXPECT_LT(0, action.parameter); | 406   heap_state.can_start_incremental_marking = false; | 
| 290 } | 407   for (int mode = 0; mode < 1; mode++) { | 
| 291 | 408     heap_state.sweeping_in_progress = true; | 
| 292 | 409     heap_state.sweeping_completed = false; | 
| 293 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { | 410     double idle_time_ms = 10.0; | 
| 294   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 411     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 295   heap_state.incremental_marking_stopped = true; | 412     EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 413     heap_state.sweeping_in_progress = false; | 
|  | 414     heap_state.sweeping_completed = false; | 
|  | 415     TransitionToReduceMemoryMode(heap_state); | 
|  | 416   } | 
|  | 417 } | 
|  | 418 | 
|  | 419 | 
|  | 420 TEST_F(GCIdleTimeHandlerTest, Scavenge) { | 
|  | 421   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 422   int idle_time_ms = 10; | 
|  | 423   for (int mode = 0; mode < 1; mode++) { | 
|  | 424     heap_state.used_new_space_size = | 
|  | 425         heap_state.new_space_capacity - | 
|  | 426         (kNewSpaceAllocationThroughput * idle_time_ms); | 
|  | 427     GCIdleTimeAction action = | 
|  | 428         handler()->Compute(static_cast<double>(idle_time_ms), heap_state); | 
|  | 429     EXPECT_EQ(DO_SCAVENGE, action.type); | 
|  | 430     heap_state.used_new_space_size = 0; | 
|  | 431     TransitionToReduceMemoryMode(heap_state); | 
|  | 432   } | 
|  | 433 } | 
|  | 434 | 
|  | 435 | 
|  | 436 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) { | 
|  | 437   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 438   int idle_time_ms = 10; | 
|  | 439   heap_state.can_start_incremental_marking = false; | 
|  | 440   heap_state.incremental_marking_stopped = true; | 
|  | 441   for (int mode = 0; mode < 1; mode++) { | 
|  | 442     heap_state.used_new_space_size = | 
|  | 443         heap_state.new_space_capacity - | 
|  | 444         (kNewSpaceAllocationThroughput * idle_time_ms); | 
|  | 445     GCIdleTimeAction action = | 
|  | 446         handler()->Compute(static_cast<double>(idle_time_ms), heap_state); | 
|  | 447     EXPECT_EQ(DO_SCAVENGE, action.type); | 
|  | 448     heap_state.used_new_space_size = 0; | 
|  | 449     action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state); | 
|  | 450     EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 451     TransitionToReduceMemoryMode(heap_state); | 
|  | 452   } | 
|  | 453 } | 
|  | 454 | 
|  | 455 | 
|  | 456 TEST_F(GCIdleTimeHandlerTest, StopEventually1) { | 
|  | 457   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 458   heap_state.incremental_marking_stopped = true; | 
|  | 459   heap_state.can_start_incremental_marking = false; | 
|  | 460   double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime; | 
|  | 461   bool stopped = false; | 
|  | 462   for (int i = 0; i < kMaxNotifications && !stopped; i++) { | 
|  | 463     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 464     if (action.type == DO_INCREMENTAL_MARKING || action.type == DO_FULL_GC) { | 
|  | 465       handler()->NotifyMarkCompact(true); | 
|  | 466       handler()->NotifyIdleMarkCompact(); | 
|  | 467     } | 
|  | 468     if (action.type == DONE) stopped = true; | 
|  | 469   } | 
|  | 470   EXPECT_TRUE(stopped); | 
|  | 471 } | 
|  | 472 | 
|  | 473 | 
|  | 474 TEST_F(GCIdleTimeHandlerTest, StopEventually2) { | 
|  | 475   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 476   heap_state.incremental_marking_stopped = true; | 
|  | 477   heap_state.can_start_incremental_marking = false; | 
| 296   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 478   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 
| 297   double idle_time_ms = | 479   double idle_time_ms = | 
| 298       static_cast<double>(heap_state.size_of_objects / speed - 1); | 480       static_cast<double>(heap_state.size_of_objects / speed + 1); | 
| 299   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 481   TransitionToReduceMemoryMode(heap_state); | 
| 300   EXPECT_EQ(DONE, action.type); | 482   TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC); | 
| 301 } | 483   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 302 | 484   EXPECT_EQ(DONE, action.type); | 
| 303 | 485 } | 
| 304 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { | 486 | 
| 305   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 487 | 
| 306   heap_state.incremental_marking_stopped = true; | 488 TEST_F(GCIdleTimeHandlerTest, StopEventually3) { | 
| 307   heap_state.sweeping_in_progress = true; | 489   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 308   heap_state.sweeping_completed = true; | 490   heap_state.incremental_marking_stopped = true; | 
| 309   double idle_time_ms = 10.0; | 491   heap_state.can_start_incremental_marking = false; | 
| 310   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 492   double idle_time_ms = 10; | 
| 311   EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); | 493   TransitionToReduceMemoryMode(heap_state); | 
| 312 } | 494   TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING); | 
| 313 | 495   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 314 | 496   EXPECT_EQ(DONE, action.type); | 
| 315 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { | 497 } | 
| 316   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 498 | 
| 317   heap_state.incremental_marking_stopped = true; | 499 | 
|  | 500 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) { | 
|  | 501   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 502   heap_state.incremental_marking_stopped = true; | 
|  | 503   heap_state.can_start_incremental_marking = false; | 
|  | 504   size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; | 
|  | 505   double idle_time_ms = | 
|  | 506       static_cast<double>(heap_state.size_of_objects / speed + 1); | 
|  | 507   TransitionToReduceMemoryMode(heap_state); | 
|  | 508   TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC); | 
|  | 509   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 510   EXPECT_EQ(DONE, action.type); | 
|  | 511   TransitionToReduceLatencyMode(heap_state); | 
|  | 512   heap_state.can_start_incremental_marking = true; | 
|  | 513   action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 514   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 515   EXPECT_FALSE(action.reduce_memory); | 
|  | 516   EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode()); | 
|  | 517 } | 
|  | 518 | 
|  | 519 | 
|  | 520 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) { | 
|  | 521   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 522   heap_state.incremental_marking_stopped = true; | 
|  | 523   heap_state.can_start_incremental_marking = false; | 
|  | 524   double idle_time_ms = 10; | 
|  | 525   TransitionToReduceMemoryMode(heap_state); | 
|  | 526   TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING); | 
|  | 527   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 528   EXPECT_EQ(DONE, action.type); | 
|  | 529   TransitionToReduceLatencyMode(heap_state); | 
|  | 530   heap_state.can_start_incremental_marking = true; | 
|  | 531   action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 532   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 533   EXPECT_FALSE(action.reduce_memory); | 
|  | 534   EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode()); | 
|  | 535 } | 
|  | 536 | 
|  | 537 | 
|  | 538 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { | 
|  | 539   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 540   for (int i = 0; i < kMaxNotifications; i++) { | 
|  | 541     GCIdleTimeAction action = handler()->Compute(0, heap_state); | 
|  | 542     EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 543   } | 
|  | 544 } | 
|  | 545 | 
|  | 546 | 
|  | 547 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { | 
|  | 548   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 549   heap_state.incremental_marking_stopped = true; | 
|  | 550   heap_state.can_start_incremental_marking = false; | 
|  | 551   for (int i = 0; i < kMaxNotifications; i++) { | 
|  | 552     GCIdleTimeAction action = handler()->Compute(10, heap_state); | 
|  | 553     EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); | 
|  | 554   } | 
|  | 555 } | 
|  | 556 | 
|  | 557 | 
|  | 558 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfScavenges) { | 
|  | 559   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 560   heap_state.incremental_marking_stopped = true; | 
|  | 561   heap_state.can_start_incremental_marking = false; | 
|  | 562   double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime; | 
|  | 563   int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle; | 
|  | 564   for (int i = 0; i < kMaxNotifications; i++) { | 
|  | 565     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 566     EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); | 
|  | 567     if ((i + 1) % limit == 0) handler()->NotifyScavenge(); | 
|  | 568     EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode()); | 
|  | 569   } | 
|  | 570 } | 
|  | 571 | 
|  | 572 | 
|  | 573 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfMarkCompacts) { | 
|  | 574   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 575   heap_state.incremental_marking_stopped = true; | 
|  | 576   heap_state.can_start_incremental_marking = false; | 
|  | 577   double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime; | 
|  | 578   int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle; | 
|  | 579   for (int i = 0; i < kMaxNotifications; i++) { | 
|  | 580     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 581     EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); | 
|  | 582     if ((i + 1) % limit == 0) handler()->NotifyMarkCompact(true); | 
|  | 583     EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode()); | 
|  | 584   } | 
|  | 585 } | 
|  | 586 | 
|  | 587 | 
|  | 588 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToReduceLatency) { | 
|  | 589   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 590   heap_state.incremental_marking_stopped = true; | 
|  | 591   heap_state.can_start_incremental_marking = false; | 
|  | 592   double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime; | 
|  | 593   int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts; | 
|  | 594   for (int idle_gc = 0; idle_gc < limit; idle_gc++) { | 
|  | 595     TransitionToReduceMemoryMode(heap_state); | 
|  | 596     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 597     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 598     EXPECT_TRUE(action.reduce_memory); | 
|  | 599     EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode()); | 
|  | 600     for (int i = 0; i < idle_gc; i++) { | 
|  | 601       action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 602       EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 603       EXPECT_TRUE(action.reduce_memory); | 
|  | 604       // ReduceMemory mode should tolerate one mutator GC per idle GC. | 
|  | 605       handler()->NotifyScavenge(); | 
|  | 606       // Notify idle GC. | 
|  | 607       handler()->NotifyMarkCompact(true); | 
|  | 608       handler()->NotifyIdleMarkCompact(); | 
|  | 609     } | 
|  | 610     // Transition to ReduceLatency mode after doing |idle_gc| idle GCs. | 
|  | 611     handler()->NotifyScavenge(); | 
|  | 612     action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 613     EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 614     EXPECT_FALSE(action.reduce_memory); | 
|  | 615     EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode()); | 
|  | 616   } | 
|  | 617 } | 
|  | 618 | 
|  | 619 | 
|  | 620 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToDone) { | 
|  | 621   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 622   heap_state.incremental_marking_stopped = true; | 
|  | 623   heap_state.can_start_incremental_marking = false; | 
|  | 624   double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime; | 
|  | 625   int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts; | 
|  | 626   TransitionToReduceMemoryMode(heap_state); | 
|  | 627   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 628   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 629   EXPECT_TRUE(action.reduce_memory); | 
|  | 630   for (int i = 0; i < limit; i++) { | 
|  | 631     action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 632     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 633     EXPECT_TRUE(action.reduce_memory); | 
|  | 634     EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode()); | 
|  | 635     // ReduceMemory mode should tolerate one mutator GC per idle GC. | 
|  | 636     handler()->NotifyScavenge(); | 
|  | 637     // Notify idle GC. | 
|  | 638     handler()->NotifyMarkCompact(true); | 
|  | 639     handler()->NotifyIdleMarkCompact(); | 
|  | 640   } | 
|  | 641   action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 642   EXPECT_EQ(DONE, action.type); | 
|  | 643 } | 
|  | 644 | 
|  | 645 | 
|  | 646 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { | 
|  | 647   // Regression test for crbug.com/489323. | 
|  | 648   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 649 | 
|  | 650   // Simulate sweeping being in-progress but not complete. | 
|  | 651   heap_state.incremental_marking_stopped = true; | 
|  | 652   heap_state.can_start_incremental_marking = false; | 
| 318   heap_state.sweeping_in_progress = true; | 653   heap_state.sweeping_in_progress = true; | 
| 319   heap_state.sweeping_completed = false; | 654   heap_state.sweeping_completed = false; | 
| 320   double idle_time_ms = 10.0; | 655   double idle_time_ms = 10.0; | 
| 321   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 656   for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) { | 
| 322   EXPECT_EQ(DO_NOTHING, action.type); | 657     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 323 } | 658     EXPECT_EQ(DO_NOTHING, action.type); | 
| 324 | 659   } | 
| 325 |  | 
| 326 TEST_F(GCIdleTimeHandlerTest, Scavenge) { |  | 
| 327   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 328   int idle_time_ms = 10; |  | 
| 329   heap_state.used_new_space_size = |  | 
| 330       heap_state.new_space_capacity - |  | 
| 331       (kNewSpaceAllocationThroughput * idle_time_ms); |  | 
| 332   GCIdleTimeAction action = |  | 
| 333       handler()->Compute(static_cast<double>(idle_time_ms), heap_state); |  | 
| 334   EXPECT_EQ(DO_SCAVENGE, action.type); |  | 
| 335   heap_state.used_new_space_size = 0; |  | 
| 336 } |  | 
| 337 |  | 
| 338 |  | 
| 339 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) { |  | 
| 340   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 341   int idle_time_ms = 10; |  | 
| 342   heap_state.incremental_marking_stopped = true; |  | 
| 343   heap_state.used_new_space_size = |  | 
| 344       heap_state.new_space_capacity - |  | 
| 345       (kNewSpaceAllocationThroughput * idle_time_ms); |  | 
| 346   GCIdleTimeAction action = |  | 
| 347       handler()->Compute(static_cast<double>(idle_time_ms), heap_state); |  | 
| 348   EXPECT_EQ(DO_SCAVENGE, action.type); |  | 
| 349   heap_state.used_new_space_size = 0; |  | 
| 350   action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state); |  | 
| 351   EXPECT_EQ(DONE, action.type); |  | 
| 352 } |  | 
| 353 |  | 
| 354 |  | 
| 355 TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) { |  | 
| 356   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 357   heap_state.incremental_marking_stopped = true; |  | 
| 358   double idle_time_ms = 10.0; |  | 
| 359   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |  | 
| 360   EXPECT_EQ(DONE, action.type); |  | 
| 361 } |  | 
| 362 |  | 
| 363 |  | 
| 364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) { |  | 
| 365   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 366   heap_state.incremental_marking_stopped = true; |  | 
| 367   double idle_time_ms = 10.0; |  | 
| 368   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |  | 
| 369   EXPECT_EQ(DONE, action.type); |  | 
| 370   heap_state.incremental_marking_stopped = false; |  | 
| 371   action = handler()->Compute(idle_time_ms, heap_state); |  | 
| 372   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); |  | 
| 373 } |  | 
| 374 |  | 
| 375 |  | 
| 376 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { |  | 
| 377   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 378   for (int i = 0; i < kMaxNotifications; i++) { |  | 
| 379     GCIdleTimeAction action = handler()->Compute(0, heap_state); |  | 
| 380     EXPECT_EQ(DO_NOTHING, action.type); |  | 
| 381   } |  | 
| 382 } |  | 
| 383 |  | 
| 384 |  | 
| 385 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) { |  | 
| 386   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 387   heap_state.incremental_marking_stopped = true; |  | 
| 388   for (int i = 0; i < kMaxNotifications; i++) { |  | 
| 389     GCIdleTimeAction action = handler()->Compute(10, heap_state); |  | 
| 390     EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type); |  | 
| 391   } |  | 
| 392 } |  | 
| 393 |  | 
| 394 |  | 
| 395 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { |  | 
| 396   // Regression test for crbug.com/489323. |  | 
| 397   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); |  | 
| 398 |  | 
| 399   // Simulate sweeping being in-progress but not complete. |  | 
| 400   heap_state.incremental_marking_stopped = true; |  | 
| 401   heap_state.sweeping_in_progress = true; |  | 
| 402   heap_state.sweeping_completed = false; |  | 
| 403   double idle_time_ms = 10.0; |  | 
| 404   for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimes; i++) { |  | 
| 405     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); |  | 
| 406     EXPECT_EQ(DO_NOTHING, action.type); |  | 
| 407   } |  | 
| 408   // We should return DONE after not making progress for some time. | 660   // We should return DONE after not making progress for some time. | 
| 409   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 661   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 410   EXPECT_EQ(DONE, action.type); | 662   EXPECT_EQ(DONE, action.type); | 
| 411 } | 663 } | 
| 412 | 664 | 
| 413 | 665 | 
| 414 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { | 666 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) { | 
| 415   // Regression test for crbug.com/489323. | 667   // Regression test for crbug.com/489323. | 
| 416   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 668   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
| 417 | 669 | 
| 418   // Simulate incremental marking stopped and not eligible to start. | 670   // Simulate incremental marking stopped and not eligible to start. | 
| 419   heap_state.incremental_marking_stopped = true; | 671   heap_state.incremental_marking_stopped = true; | 
|  | 672   heap_state.can_start_incremental_marking = false; | 
| 420   double idle_time_ms = 10.0; | 673   double idle_time_ms = 10.0; | 
| 421   // We should return DONE if we cannot start incremental marking. | 674   for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerMode; i++) { | 
|  | 675     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 676     EXPECT_EQ(DO_NOTHING, action.type); | 
|  | 677   } | 
|  | 678   // We should return DONE after not making progress for some time. | 
| 422   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 679   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
| 423   EXPECT_EQ(DONE, action.type); | 680   EXPECT_EQ(DONE, action.type); | 
| 424 } | 681 } | 
| 425 | 682 | 
|  | 683 | 
|  | 684 TEST_F(GCIdleTimeHandlerTest, BackgroundReduceLatencyToReduceMemory) { | 
|  | 685   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 686   heap_state.incremental_marking_stopped = false; | 
|  | 687   heap_state.can_start_incremental_marking = true; | 
|  | 688   double idle_time_ms = GCIdleTimeHandler::kMinBackgroundIdleTime; | 
|  | 689   handler()->NotifyScavenge(); | 
|  | 690   EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode()); | 
|  | 691   int limit = | 
|  | 692       GCIdleTimeHandler::kBackgroundIdleNotificationsBeforeMutatorIsIdle; | 
|  | 693   for (int i = 0; i < limit; i++) { | 
|  | 694     GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 695     EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 696   } | 
|  | 697   handler()->Compute(idle_time_ms, heap_state); | 
|  | 698   EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode()); | 
|  | 699 } | 
|  | 700 | 
|  | 701 | 
|  | 702 TEST_F(GCIdleTimeHandlerTest, SkipUselessGCs) { | 
|  | 703   GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); | 
|  | 704   heap_state.incremental_marking_stopped = false; | 
|  | 705   heap_state.can_start_incremental_marking = true; | 
|  | 706   TransitionToReduceMemoryMode(heap_state); | 
|  | 707   EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode()); | 
|  | 708   double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime; | 
|  | 709   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 710   EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); | 
|  | 711   handler()->NotifyMarkCompact(false); | 
|  | 712   handler()->NotifyIdleMarkCompact(); | 
|  | 713   action = handler()->Compute(idle_time_ms, heap_state); | 
|  | 714   EXPECT_EQ(DONE, action.type); | 
|  | 715 } | 
|  | 716 | 
| 426 }  // namespace internal | 717 }  // namespace internal | 
| 427 }  // namespace v8 | 718 }  // namespace v8 | 
| OLD | NEW | 
|---|