gc-idle-time-handler-unittest.cc 7.66 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
  if (!handler()->Enabled()) return;
93
  GCIdleTimeHeapState heap_state = DefaultHeapState();
94 95
  heap_state.contexts_disposed = 1;
  heap_state.incremental_marking_stopped = true;
96
  double idle_time_ms = 0;
97 98
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DO_NOTHING, action.type);
99 100 101 102
}


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


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


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


TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
141
  if (!handler()->Enabled()) return;
142
  GCIdleTimeHeapState heap_state = DefaultHeapState();
143
  heap_state.contexts_disposed = 1;
144 145
  heap_state.contexts_disposal_rate =
      GCIdleTimeHandler::kHighContextDisposalRate;
146
  size_t speed = kMarkCompactSpeed;
147
  double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
148
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
149
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
150 151 152 153
}


TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
154
  if (!handler()->Enabled()) return;
155
  GCIdleTimeHeapState heap_state = DefaultHeapState();
156
  double idle_time_ms = 10;
157
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
158
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
159 160 161 162
}


TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
163
  if (!handler()->Enabled()) return;
164
  GCIdleTimeHeapState heap_state = DefaultHeapState();
165
  heap_state.incremental_marking_stopped = true;
166
  size_t speed = kMarkCompactSpeed;
167
  double idle_time_ms = static_cast<double>(kSizeOfObjects / speed - 1);
168
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
169
  EXPECT_EQ(DONE, action.type);
170 171 172
}


173
TEST_F(GCIdleTimeHandlerTest, DoNotStartIncrementalMarking) {
174
  if (!handler()->Enabled()) return;
175
  GCIdleTimeHeapState heap_state = DefaultHeapState();
176
  heap_state.incremental_marking_stopped = true;
177
  double idle_time_ms = 10.0;
178
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
179
  EXPECT_EQ(DONE, action.type);
180 181 182
}


183
TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop) {
184
  if (!handler()->Enabled()) return;
185
  GCIdleTimeHeapState heap_state = DefaultHeapState();
186
  heap_state.incremental_marking_stopped = true;
187
  double idle_time_ms = 10.0;
188 189
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DONE, action.type);
190
  heap_state.incremental_marking_stopped = false;
191
  action = handler()->Compute(idle_time_ms, heap_state);
192
  EXPECT_EQ(DO_INCREMENTAL_STEP, action.type);
193 194
}

195

196
TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
197
  if (!handler()->Enabled()) return;
198
  GCIdleTimeHeapState heap_state = DefaultHeapState();
199 200 201 202
  for (int i = 0; i < kMaxNotifications; i++) {
    GCIdleTimeAction action = handler()->Compute(0, heap_state);
    EXPECT_EQ(DO_NOTHING, action.type);
  }
203 204 205
}


206
TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
207
  if (!handler()->Enabled()) return;
208
  GCIdleTimeHeapState heap_state = DefaultHeapState();
209
  heap_state.incremental_marking_stopped = true;
210 211
  for (int i = 0; i < kMaxNotifications; i++) {
    GCIdleTimeAction action = handler()->Compute(10, heap_state);
212
    EXPECT_TRUE(DO_NOTHING == action.type || DONE == action.type);
213
  }
214 215 216
}


217
TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
218 219
  if (!handler()->Enabled()) return;

220
  // Regression test for crbug.com/489323.
221
  GCIdleTimeHeapState heap_state = DefaultHeapState();
222 223 224 225

  // Simulate incremental marking stopped and not eligible to start.
  heap_state.incremental_marking_stopped = true;
  double idle_time_ms = 10.0;
226
  // We should return DONE if we cannot start incremental marking.
227 228 229 230
  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
  EXPECT_EQ(DONE, action.type);
}

231 232
}  // namespace internal
}  // namespace v8