Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / v8 / src / heap / gc-idle-time-handler-unittest.cc
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   GCIdleTimeHandlerTest() {}
18   virtual ~GCIdleTimeHandlerTest() {}
19
20   GCIdleTimeHandler* handler() { return &handler_; }
21
22   GCIdleTimeHandler::HeapState DefaultHeapState() {
23     GCIdleTimeHandler::HeapState result;
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;
34     result.new_space_allocation_throughput_in_bytes_per_ms =
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:
47   GCIdleTimeHandler handler_;
48 };
49
50 }  // namespace
51
52
53 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
54   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
55   EXPECT_EQ(
56       static_cast<size_t>(GCIdleTimeHandler::kInitialConservativeMarkingSpeed *
57                           GCIdleTimeHandler::kConservativeTimeRatio),
58       step_size);
59 }
60
61
62 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
63   size_t marking_speed_in_bytes_per_millisecond = 100;
64   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
65       1, marking_speed_in_bytes_per_millisecond);
66   EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
67                                 GCIdleTimeHandler::kConservativeTimeRatio),
68             step_size);
69 }
70
71
72 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
73   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
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) {
81   size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
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;
90   size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, 0);
91   EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeMarkCompactSpeed,
92             time);
93 }
94
95
96 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeNonZero) {
97   size_t size = 100 * MB;
98   size_t speed = 1 * MB;
99   size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
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);
108   EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
109 }
110
111
112 TEST(GCIdleTimeHandler, EstimateScavengeTimeInitial) {
113   size_t size = 1 * MB;
114   size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, 0);
115   EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeScavengeSpeed, time);
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;
129   EXPECT_FALSE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, 0));
130 }
131
132
133 TEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroFalse) {
134   size_t available = (GCIdleTimeHandler::kMaxFrameRenderingIdleTime + 1) * KB;
135   size_t speed = 1 * KB;
136   EXPECT_FALSE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, speed));
137 }
138
139
140 TEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroTrue) {
141   size_t available = GCIdleTimeHandler::kMaxFrameRenderingIdleTime * KB;
142   size_t speed = 1 * KB;
143   EXPECT_TRUE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, speed));
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);
222   for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
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;
235   for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
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);
254   for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
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;
273   for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
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;
330   for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
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