gc-idle-time-handler-unittest.cc 7.23 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
#include <limits>
6

7 8
#include "src/heap/gc-idle-time-handler.h"
#include "testing/gtest/include/gtest/gtest.h"
9 10 11 12

namespace v8 {
namespace internal {

13 14 15 16 17 18 19 20 21
namespace {

class GCIdleTimeHandlerTest : public ::testing::Test {
 public:
  GCIdleTimeHandlerTest() {}
  virtual ~GCIdleTimeHandlerTest() {}

  GCIdleTimeHandler* handler() { return &handler_; }

22 23
  GCIdleTimeHeapState DefaultHeapState() {
    GCIdleTimeHeapState result;
24
    result.contexts_disposed = 0;
25
    result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate;
26 27 28 29 30
    result.incremental_marking_stopped = false;
    return result;
  }

  static const size_t kSizeOfObjects = 100 * MB;
31 32
  static const size_t kMarkCompactSpeed = 200 * KB;
  static const size_t kMarkingSpeed = 200 * KB;
33
  static const int kMaxNotifications = 100;
34 35 36 37 38 39 40 41 42

 private:
  GCIdleTimeHandler handler_;
};

}  // namespace


TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
43 44 45 46 47
  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
  EXPECT_EQ(
      static_cast<size_t>(GCIdleTimeHandler::kInitialConservativeMarkingSpeed *
                          GCIdleTimeHandler::kConservativeTimeRatio),
      step_size);
48 49 50
}


51
TEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
52 53
  size_t marking_speed_in_bytes_per_millisecond = 100;
  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
54
      1, marking_speed_in_bytes_per_millisecond);
55 56
  EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
                                GCIdleTimeHandler::kConservativeTimeRatio),
57 58 59 60
            step_size);
}


61
TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
62 63 64 65
  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
      10, std::numeric_limits<size_t>::max());
  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
            step_size);
66 67 68
}


69
TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
70 71 72 73
  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
      std::numeric_limits<size_t>::max(), 10);
  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
            step_size);
74 75
}

76

77
TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
78
  size_t idle_time_ms = 16;
79
  EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
80
      idle_time_ms, 0, 0));
81 82 83 84
}


TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
85
  size_t idle_time_ms = 1;
86
  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
87
      idle_time_ms, kSizeOfObjects, kMarkingSpeed));
88 89 90
}


91
TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
92
  GCIdleTimeHeapState heap_state = DefaultHeapState();
93 94
  heap_state.contexts_disposed = 1;
  heap_state.incremental_marking_stopped = true;
95
  double idle_time_ms = 0;
96 97
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DO_NOTHING, action.type);
98 99 100 101
}


TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
102
  GCIdleTimeHeapState heap_state = DefaultHeapState();
103 104 105 106
  heap_state.contexts_disposed = 1;
  heap_state.contexts_disposal_rate =
      GCIdleTimeHandler::kHighContextDisposalRate - 1;
  heap_state.incremental_marking_stopped = true;
107
  double idle_time_ms = 0;
108 109
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DO_FULL_GC, action.type);
110 111 112
}


113
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
114
  GCIdleTimeHeapState heap_state = DefaultHeapState();
115
  heap_state.contexts_disposed = 1;
116
  heap_state.contexts_disposal_rate = 1.0;
117
  heap_state.incremental_marking_stopped = true;
118
  double idle_time_ms = 0;
119 120
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DO_FULL_GC, action.type);
121 122 123
}


124
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
125
  GCIdleTimeHeapState heap_state = DefaultHeapState();
126
  heap_state.contexts_disposed = 1;
127 128
  heap_state.contexts_disposal_rate =
      GCIdleTimeHandler::kHighContextDisposalRate;
129
  size_t speed = kMarkCompactSpeed;
130
  double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
131
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
132
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
133 134 135 136
}


TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
137
  GCIdleTimeHeapState heap_state = DefaultHeapState();
138
  heap_state.contexts_disposed = 1;
139 140
  heap_state.contexts_disposal_rate =
      GCIdleTimeHandler::kHighContextDisposalRate;
141
  size_t speed = kMarkCompactSpeed;
142
  double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
143
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
144
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
145 146 147 148
}


TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
149
  GCIdleTimeHeapState heap_state = DefaultHeapState();
150
  double idle_time_ms = 10;
151
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
152
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
153 154 155 156
}


TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
157
  GCIdleTimeHeapState heap_state = DefaultHeapState();
158
  heap_state.incremental_marking_stopped = true;
159
  size_t speed = kMarkCompactSpeed;
160
  double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
161
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
162
  EXPECT_EQ(DONE, action.type);
163 164 165
}


166
TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
167
  GCIdleTimeHeapState heap_state = DefaultHeapState();
168
  heap_state.incremental_marking_stopped = true;
169
  double idle_time_ms = 10.0;
170
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
171
  EXPECT_EQ(DONE, action.type);
172 173 174
}


175
TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
176
  GCIdleTimeHeapState heap_state = DefaultHeapState();
177
  heap_state.incremental_marking_stopped = true;
178
  double idle_time_ms = 10.0;
179 180
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DONE, action.type);
181
  heap_state.incremental_marking_stopped = false;
182
  action = handler()->Compute(idle_time_ms, heap_state);
183
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
184 185
}

186

187
TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
188
  GCIdleTimeHeapState heap_state = DefaultHeapState();
189 190 191 192
  for (int i = 0; i < kMaxNotifications; i++) {
    GCIdleTimeAction action = handler()->Compute(0, heap_state);
    EXPECT_EQ(DO_NOTHING, action.type);
  }
193 194 195
}


196
TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
197
  GCIdleTimeHeapState heap_state = DefaultHeapState();
198
  heap_state.incremental_marking_stopped = true;
199 200
  for (int i = 0; i < kMaxNotifications; i++) {
    GCIdleTimeAction action = handler()->Compute(10, heap_state);
201
    EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
202
  }
203 204 205
}


206 207
TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
  // Regression test for crbug.com/489323.
208
  GCIdleTimeHeapState heap_state = DefaultHeapState();
209 210 211 212

  // Simulate incremental marking stopped and not eligible to start.
  heap_state.incremental_marking_stopped = true;
  double idle_time_ms = 10.0;
213
  // We should return DONE if we cannot start incremental marking.
214 215 216 217
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DONE, action.type);
}

218 219
}  // namespace internal
}  // namespace v8