LCOV - code coverage report
Current view: top level - test/unittests/heap - gc-idle-time-handler-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 105 111 94.6 %
Date: 2019-01-20 Functions: 40 61 65.6 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <limits>
       6             : 
       7             : #include "src/heap/gc-idle-time-handler.h"
       8             : #include "testing/gtest/include/gtest/gtest.h"
       9             : 
      10             : namespace v8 {
      11             : namespace internal {
      12             : 
      13             : namespace {
      14             : 
      15             : class GCIdleTimeHandlerTest : public ::testing::Test {
      16             :  public:
      17          15 :   GCIdleTimeHandlerTest() = default;
      18          15 :   ~GCIdleTimeHandlerTest() override = default;
      19             : 
      20             :   GCIdleTimeHandler* handler() { return &handler_; }
      21             : 
      22             :   GCIdleTimeHeapState DefaultHeapState() {
      23             :     GCIdleTimeHeapState result;
      24          13 :     result.contexts_disposed = 0;
      25          13 :     result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate;
      26          13 :     result.incremental_marking_stopped = false;
      27          13 :     result.size_of_objects = kSizeOfObjects;
      28             :     return result;
      29             :   }
      30             : 
      31             :   static const size_t kSizeOfObjects = 100 * MB;
      32             :   static const size_t kMarkCompactSpeed = 200 * KB;
      33             :   static const size_t kMarkingSpeed = 200 * KB;
      34             :   static const int kMaxNotifications = 100;
      35             : 
      36             :  private:
      37             :   GCIdleTimeHandler handler_;
      38             : };
      39             : 
      40             : }  // namespace
      41             : 
      42             : 
      43       15128 : TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
      44           1 :   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
      45           2 :   EXPECT_EQ(
      46             :       static_cast<size_t>(GCIdleTimeHandler::kInitialConservativeMarkingSpeed *
      47             :                           GCIdleTimeHandler::kConservativeTimeRatio),
      48           0 :       step_size);
      49           1 : }
      50             : 
      51             : 
      52       15128 : TEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
      53             :   size_t marking_speed_in_bytes_per_millisecond = 100;
      54             :   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
      55           1 :       1, marking_speed_in_bytes_per_millisecond);
      56           2 :   EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
      57             :                                 GCIdleTimeHandler::kConservativeTimeRatio),
      58           0 :             step_size);
      59           1 : }
      60             : 
      61             : 
      62       15128 : TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
      63             :   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
      64           1 :       10, std::numeric_limits<size_t>::max());
      65           2 :   EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
      66           0 :             step_size);
      67           1 : }
      68             : 
      69             : 
      70       15128 : TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
      71             :   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
      72           1 :       std::numeric_limits<size_t>::max(), 10);
      73           2 :   EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
      74           0 :             step_size);
      75           1 : }
      76             : 
      77             : 
      78       15129 : TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
      79             :   size_t idle_time_ms = 16;
      80           2 :   EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
      81           0 :       idle_time_ms, 0, 0));
      82           1 : }
      83             : 
      84             : 
      85       15129 : TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
      86             :   size_t idle_time_ms = 1;
      87           2 :   EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
      88           0 :       idle_time_ms, kSizeOfObjects, kMarkingSpeed));
      89           1 : }
      90             : 
      91             : 
      92       15129 : TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
      93           1 :   if (!handler()->Enabled()) return;
      94             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
      95           1 :   heap_state.contexts_disposed = 1;
      96           1 :   heap_state.incremental_marking_stopped = true;
      97             :   double idle_time_ms = 0;
      98           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
      99           2 :   EXPECT_EQ(DO_NOTHING, action.type);
     100             : }
     101             : 
     102             : 
     103       15129 : TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
     104           1 :   if (!handler()->Enabled()) return;
     105             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     106           1 :   heap_state.contexts_disposed = 1;
     107             :   heap_state.contexts_disposal_rate =
     108           1 :       GCIdleTimeHandler::kHighContextDisposalRate - 1;
     109           1 :   heap_state.incremental_marking_stopped = true;
     110             :   double idle_time_ms = 0;
     111           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     112           2 :   EXPECT_EQ(DO_FULL_GC, action.type);
     113             : }
     114             : 
     115             : 
     116       15129 : TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
     117           1 :   if (!handler()->Enabled()) return;
     118             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     119           1 :   heap_state.contexts_disposed = 1;
     120           1 :   heap_state.contexts_disposal_rate = 1.0;
     121           1 :   heap_state.incremental_marking_stopped = true;
     122             :   double idle_time_ms = 0;
     123           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     124           2 :   EXPECT_EQ(DO_FULL_GC, action.type);
     125             : }
     126             : 
     127             : 
     128       15129 : TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
     129           1 :   if (!handler()->Enabled()) return;
     130             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     131           1 :   heap_state.contexts_disposed = 1;
     132             :   heap_state.contexts_disposal_rate =
     133             :       GCIdleTimeHandler::kHighContextDisposalRate;
     134             :   size_t speed = kMarkCompactSpeed;
     135             :   double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
     136           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     137           2 :   EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
     138             : }
     139             : 
     140             : 
     141       15129 : TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
     142           1 :   if (!handler()->Enabled()) return;
     143             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     144           1 :   heap_state.contexts_disposed = 1;
     145             :   heap_state.contexts_disposal_rate =
     146             :       GCIdleTimeHandler::kHighContextDisposalRate;
     147             :   size_t speed = kMarkCompactSpeed;
     148             :   double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
     149           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     150           2 :   EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
     151             : }
     152             : 
     153       15129 : TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeHeap) {
     154           1 :   if (!handler()->Enabled()) return;
     155             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     156           1 :   heap_state.contexts_disposed = 1;
     157           1 :   heap_state.contexts_disposal_rate = 1.0;
     158           1 :   heap_state.incremental_marking_stopped = true;
     159           1 :   heap_state.size_of_objects = 101 * MB;
     160             :   double idle_time_ms = 0;
     161           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     162           2 :   EXPECT_EQ(DO_NOTHING, action.type);
     163             : }
     164             : 
     165       15129 : TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
     166           1 :   if (!handler()->Enabled()) return;
     167             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     168             :   double idle_time_ms = 10;
     169           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     170           2 :   EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
     171             : }
     172             : 
     173             : 
     174       15129 : TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
     175           1 :   if (!handler()->Enabled()) return;
     176             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     177           1 :   heap_state.incremental_marking_stopped = true;
     178             :   size_t speed = kMarkCompactSpeed;
     179             :   double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
     180           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     181           2 :   EXPECT_EQ(DONE, action.type);
     182             : }
     183             : 
     184             : 
     185       15129 : TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
     186           1 :   if (!handler()->Enabled()) return;
     187             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     188           1 :   heap_state.incremental_marking_stopped = true;
     189             :   double idle_time_ms = 10.0;
     190           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     191           2 :   EXPECT_EQ(DONE, action.type);
     192             : }
     193             : 
     194             : 
     195       15129 : TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
     196           1 :   if (!handler()->Enabled()) return;
     197             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     198           1 :   heap_state.incremental_marking_stopped = true;
     199             :   double idle_time_ms = 10.0;
     200           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     201           2 :   EXPECT_EQ(DONE, action.type);
     202           1 :   heap_state.incremental_marking_stopped = false;
     203           1 :   action = handler()->Compute(idle_time_ms, heap_state);
     204           2 :   EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
     205             : }
     206             : 
     207             : 
     208       15129 : TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
     209           1 :   if (!handler()->Enabled()) return;
     210             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     211         101 :   for (int i = 0; i < kMaxNotifications; i++) {
     212         100 :     GCIdleTimeAction action = handler()->Compute(0, heap_state);
     213         200 :     EXPECT_EQ(DO_NOTHING, action.type);
     214             :   }
     215             : }
     216             : 
     217             : 
     218       15129 : TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
     219           1 :   if (!handler()->Enabled()) return;
     220             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     221           1 :   heap_state.incremental_marking_stopped = true;
     222         101 :   for (int i = 0; i < kMaxNotifications; i++) {
     223         100 :     GCIdleTimeAction action = handler()->Compute(10, heap_state);
     224         200 :     EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
     225             :   }
     226             : }
     227             : 
     228             : 
     229       15129 : TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
     230           1 :   if (!handler()->Enabled()) return;
     231             : 
     232             :   // Regression test for crbug.com/489323.
     233             :   GCIdleTimeHeapState heap_state = DefaultHeapState();
     234             : 
     235             :   // Simulate incremental marking stopped and not eligible to start.
     236           1 :   heap_state.incremental_marking_stopped = true;
     237             :   double idle_time_ms = 10.0;
     238             :   // We should return DONE if we cannot start incremental marking.
     239           1 :   GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
     240           2 :   EXPECT_EQ(DONE, action.type);
     241             : }
     242             : 
     243             : }  // namespace internal
     244        9075 : }  // namespace v8

Generated by: LCOV version 1.10