V8 Project
gc-idle-time-handler-unittest.cc
Go to the documentation of this file.
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 
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:
19 
20  GCIdleTimeHandler* handler() { return &handler_; }
21 
24  result.contexts_disposed = 0;
25  result.size_of_objects = kSizeOfObjects;
26  result.incremental_marking_stopped = false;
27  result.can_start_incremental_marking = true;
28  result.sweeping_in_progress = false;
29  result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
30  result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
31  result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
32  result.available_new_space_memory = kNewSpaceCapacity;
33  result.new_space_capacity = kNewSpaceCapacity;
35  kNewSpaceAllocationThroughput;
36  return result;
37  }
38 
39  static const size_t kSizeOfObjects = 100 * MB;
40  static const size_t kMarkCompactSpeed = 200 * KB;
41  static const size_t kMarkingSpeed = 200 * KB;
42  static const size_t kScavengeSpeed = 100 * KB;
43  static const size_t kNewSpaceCapacity = 1 * MB;
44  static const size_t kNewSpaceAllocationThroughput = 10 * KB;
45 
46  private:
48 };
49 
50 } // namespace
51 
52 
53 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
54  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
55  EXPECT_EQ(
58  step_size);
59 }
60 
61 
62 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
63  size_t marking_speed_in_bytes_per_millisecond = 100;
65  1, marking_speed_in_bytes_per_millisecond);
66  EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
68  step_size);
69 }
70 
71 
72 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
74  10, std::numeric_limits<size_t>::max());
75  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
76  step_size);
77 }
78 
79 
80 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
82  std::numeric_limits<size_t>::max(), 10);
83  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
84  step_size);
85 }
86 
87 
88 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeInitial) {
89  size_t size = 100 * MB;
92  time);
93 }
94 
95 
96 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeNonZero) {
97  size_t size = 100 * MB;
98  size_t speed = 1 * MB;
100  EXPECT_EQ(size / speed, time);
101 }
102 
103 
104 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) {
105  size_t size = std::numeric_limits<size_t>::max();
106  size_t speed = 1;
107  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
109 }
110 
111 
112 TEST(GCIdleTimeHandler, EstimateScavengeTimeInitial) {
113  size_t size = 1 * MB;
116 }
117 
118 
119 TEST(GCIdleTimeHandler, EstimateScavengeTimeNonZero) {
120  size_t size = 1 * MB;
121  size_t speed = 1 * MB;
122  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, speed);
123  EXPECT_EQ(size / speed, time);
124 }
125 
126 
127 TEST(GCIdleTimeHandler, ScavangeMayHappenSoonInitial) {
128  size_t available = 100 * KB;
130 }
131 
132 
133 TEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroFalse) {
135  size_t speed = 1 * KB;
137 }
138 
139 
140 TEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroTrue) {
142  size_t speed = 1 * KB;
144 }
145 
146 
147 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
148  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
149  heap_state.contexts_disposed = 1;
150  heap_state.incremental_marking_stopped = true;
151  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
152  int idle_time_ms =
153  static_cast<int>((heap_state.size_of_objects + speed - 1) / speed);
154  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
155  EXPECT_EQ(DO_FULL_GC, action.type);
156 }
157 
158 
159 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
160  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
161  heap_state.contexts_disposed = 1;
162  heap_state.incremental_marking_stopped = true;
163  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
164  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
165  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
166  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
167 }
168 
169 
170 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
171  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
172  heap_state.contexts_disposed = 1;
173  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
174  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
175  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
176  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
177 }
178 
179 
180 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
181  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
182  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
183  int idle_time_ms = 10;
184  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
185  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
186  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
187  static_cast<size_t>(action.parameter));
188  EXPECT_LT(0, action.parameter);
189 }
190 
191 
192 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
193  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
194  heap_state.incremental_marking_stopped = true;
195  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
196  int idle_time_ms = 10;
197  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
198  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
199  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
200  static_cast<size_t>(action.parameter));
201  EXPECT_LT(0, action.parameter);
202 }
203 
204 
205 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
206  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
207  heap_state.incremental_marking_stopped = true;
208  heap_state.can_start_incremental_marking = false;
209  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
210  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
211  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
212  EXPECT_EQ(DO_NOTHING, action.type);
213 }
214 
215 
216 TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
217  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
218  heap_state.incremental_marking_stopped = true;
219  heap_state.can_start_incremental_marking = false;
220  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
221  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1);
223  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
224  EXPECT_EQ(DO_FULL_GC, action.type);
225  handler()->NotifyIdleMarkCompact();
226  }
227  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
228  EXPECT_EQ(DONE, action.type);
229 }
230 
231 
232 TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
233  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
234  int idle_time_ms = 10;
236  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
237  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
238  // In this case we emulate incremental marking steps that finish with a
239  // full gc.
240  handler()->NotifyIdleMarkCompact();
241  }
242  heap_state.can_start_incremental_marking = false;
243  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
244  EXPECT_EQ(DONE, action.type);
245 }
246 
247 
248 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
249  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
250  heap_state.incremental_marking_stopped = true;
251  heap_state.can_start_incremental_marking = false;
252  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
253  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1);
255  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
256  EXPECT_EQ(DO_FULL_GC, action.type);
257  handler()->NotifyIdleMarkCompact();
258  }
259  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
260  EXPECT_EQ(DONE, action.type);
261  // Emulate mutator work.
262  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
263  handler()->NotifyScavenge();
264  }
265  action = handler()->Compute(idle_time_ms, heap_state);
266  EXPECT_EQ(DO_FULL_GC, action.type);
267 }
268 
269 
270 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
271  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
272  int idle_time_ms = 10;
274  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
275  if (action.type == DONE) break;
276  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
277  // In this case we try to emulate incremental marking steps the finish with
278  // a full gc.
279  handler()->NotifyIdleMarkCompact();
280  }
281  heap_state.can_start_incremental_marking = false;
282  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
283  EXPECT_EQ(DONE, action.type);
284  // Emulate mutator work.
285  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
286  handler()->NotifyScavenge();
287  }
288  heap_state.can_start_incremental_marking = true;
289  action = handler()->Compute(idle_time_ms, heap_state);
290  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
291 }
292 
293 
294 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
295  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
296  int idle_time_ms = 10;
297  heap_state.available_new_space_memory =
298  kNewSpaceAllocationThroughput * idle_time_ms;
299  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
300  EXPECT_EQ(DO_SCAVENGE, action.type);
301 }
302 
303 
304 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
305  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
306  int idle_time_ms = 10;
307  heap_state.can_start_incremental_marking = false;
308  heap_state.incremental_marking_stopped = true;
309  heap_state.available_new_space_memory =
310  kNewSpaceAllocationThroughput * idle_time_ms;
311  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
312  EXPECT_EQ(DO_SCAVENGE, action.type);
313  heap_state.available_new_space_memory = kNewSpaceCapacity;
314  action = handler()->Compute(idle_time_ms, heap_state);
315  EXPECT_EQ(DO_NOTHING, action.type);
316 }
317 
318 
319 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
320  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
321  int idle_time_ms = 0;
322  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
323  EXPECT_EQ(DO_NOTHING, action.type);
324 }
325 
326 
327 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) {
328  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
329  int idle_time_ms = 10;
331  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
332  if (action.type == DONE) break;
333  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
334  // In this case we try to emulate incremental marking steps the finish with
335  // a full gc.
336  handler()->NotifyIdleMarkCompact();
337  }
338  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
339  // Emulate mutator work.
340  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
341  handler()->NotifyScavenge();
342  }
343  action = handler()->Compute(0, heap_state);
344  EXPECT_EQ(DO_NOTHING, action.type);
345 }
346 
347 } // namespace internal
348 } // namespace v8
static size_t EstimateScavengeTime(size_t new_space_size, size_t scavenger_speed_in_bytes_per_ms)
static const double kConservativeTimeRatio
static const size_t kInitialConservativeMarkingSpeed
static const size_t kInitialConservativeMarkCompactSpeed
static const size_t kMaxFrameRenderingIdleTime
static const size_t kMaxMarkCompactTimeInMs
static const size_t kInitialConservativeScavengeSpeed
static size_t EstimateMarkCompactTime(size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms)
static const size_t kMaximumMarkingStepSize
static bool ScavangeMayHappenSoon(size_t available_new_space_memory, size_t new_space_allocation_throughput_in_bytes_per_ms)
static size_t EstimateMarkingStepSize(size_t idle_time_in_ms, size_t marking_speed_in_bytes_per_ms)
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if available(X64 only)") DEFINE_BOOL(enable_vfp3
const int KB
Definition: globals.h:106
TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime)
const int MB
Definition: globals.h:107
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20