Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: test/unittests/heap/gc-idle-time-handler-unittest.cc

Issue 1105293004: Add mode to reduce memory usage in idle notification. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add checks in tests Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/test-heap.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <limits> 5 #include <limits>
6 6
7 #include "src/heap/gc-idle-time-handler.h" 7 #include "src/heap/gc-idle-time-handler.h"
8 #include "testing/gtest/include/gtest/gtest.h" 8 #include "testing/gtest/include/gtest/gtest.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 20 matching lines...) Expand all
31 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed; 31 result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
32 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed; 32 result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
33 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed; 33 result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
34 result.used_new_space_size = 0; 34 result.used_new_space_size = 0;
35 result.new_space_capacity = kNewSpaceCapacity; 35 result.new_space_capacity = kNewSpaceCapacity;
36 result.new_space_allocation_throughput_in_bytes_per_ms = 36 result.new_space_allocation_throughput_in_bytes_per_ms =
37 kNewSpaceAllocationThroughput; 37 kNewSpaceAllocationThroughput;
38 return result; 38 return result;
39 } 39 }
40 40
41 void TransitionToReduceMemoryMode(
42 const GCIdleTimeHandler::HeapState& heap_state) {
43 handler()->NotifyScavenge();
44 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
45 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
46 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
47 bool incremental = !heap_state.incremental_marking_stopped ||
48 heap_state.can_start_incremental_marking;
49 for (int i = 0; i < limit; i++) {
50 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
51 EXPECT_EQ(incremental ? DO_INCREMENTAL_MARKING : DO_NOTHING, action.type);
52 }
53 handler()->Compute(idle_time_ms, heap_state);
54 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
55 }
56
57 void TransitionToDoneMode(const GCIdleTimeHandler::HeapState& heap_state,
58 double idle_time_ms,
59 GCIdleTimeActionType expected) {
60 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
61 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
62 for (int i = 0; i < limit; i++) {
63 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
64 EXPECT_EQ(expected, action.type);
65 EXPECT_TRUE(action.reduce_memory);
66 handler()->NotifyMarkCompact();
67 handler()->NotifyIdleMarkCompact();
68 }
69 handler()->Compute(idle_time_ms, heap_state);
70 EXPECT_EQ(GCIdleTimeHandler::kDone, handler()->mode());
71 }
72
73 void TransitionToReduceLatencyMode(
74 const GCIdleTimeHandler::HeapState& heap_state) {
75 EXPECT_EQ(GCIdleTimeHandler::kDone, handler()->mode());
76 int limit = GCIdleTimeHandler::kGCsBeforeMutatorIsActive;
77 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
78 for (int i = 0; i < limit; i++) {
79 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
80 EXPECT_EQ(DONE, action.type);
81 if (i % 2 == 0) {
82 handler()->NotifyScavenge();
83 } else {
84 handler()->NotifyMarkCompact();
85 }
86 }
87 handler()->Compute(idle_time_ms, heap_state);
88 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
89 }
90
41 static const size_t kSizeOfObjects = 100 * MB; 91 static const size_t kSizeOfObjects = 100 * MB;
42 static const size_t kMarkCompactSpeed = 200 * KB; 92 static const size_t kMarkCompactSpeed = 200 * KB;
43 static const size_t kMarkingSpeed = 200 * KB; 93 static const size_t kMarkingSpeed = 200 * KB;
44 static const size_t kScavengeSpeed = 100 * KB; 94 static const size_t kScavengeSpeed = 100 * KB;
45 static const size_t kNewSpaceCapacity = 1 * MB; 95 static const size_t kNewSpaceCapacity = 1 * MB;
46 static const size_t kNewSpaceAllocationThroughput = 10 * KB; 96 static const size_t kNewSpaceAllocationThroughput = 10 * KB;
97 static const int kMaxNotifications = 100;
47 98
48 private: 99 private:
49 GCIdleTimeHandler handler_; 100 GCIdleTimeHandler handler_;
50 }; 101 };
51 102
52 } // namespace 103 } // namespace
53 104
54 105
55 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) { 106 TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
56 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0); 107 size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) { 157 TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) {
107 size_t size = std::numeric_limits<size_t>::max(); 158 size_t size = std::numeric_limits<size_t>::max();
108 size_t speed = 1; 159 size_t speed = 1;
109 size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed); 160 size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
110 EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time); 161 EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
111 } 162 }
112 163
113 164
114 TEST_F(GCIdleTimeHandlerTest, DoScavengeEmptyNewSpace) { 165 TEST_F(GCIdleTimeHandlerTest, DoScavengeEmptyNewSpace) {
115 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 166 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
116 int idle_time_in_ms = 16; 167 int idle_time_ms = 16;
117 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( 168 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
118 idle_time_in_ms, heap_state.new_space_capacity, 169 idle_time_ms, heap_state.new_space_capacity,
119 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 170 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
120 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 171 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
121 } 172 }
122 173
123 174
124 TEST_F(GCIdleTimeHandlerTest, DoScavengeFullNewSpace) { 175 TEST_F(GCIdleTimeHandlerTest, DoScavengeFullNewSpace) {
125 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 176 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
126 heap_state.used_new_space_size = kNewSpaceCapacity; 177 heap_state.used_new_space_size = kNewSpaceCapacity;
127 int idle_time_in_ms = 16; 178 int idle_time_ms = 16;
128 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge( 179 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
129 idle_time_in_ms, heap_state.new_space_capacity, 180 idle_time_ms, heap_state.new_space_capacity,
130 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 181 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
131 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 182 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
132 } 183 }
133 184
134 185
135 TEST_F(GCIdleTimeHandlerTest, DoScavengeUnknownScavengeSpeed) { 186 TEST_F(GCIdleTimeHandlerTest, DoScavengeUnknownScavengeSpeed) {
136 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 187 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
137 heap_state.used_new_space_size = kNewSpaceCapacity; 188 heap_state.used_new_space_size = kNewSpaceCapacity;
138 heap_state.scavenge_speed_in_bytes_per_ms = 0; 189 heap_state.scavenge_speed_in_bytes_per_ms = 0;
139 int idle_time_in_ms = 8; 190 int idle_time_ms = 8;
140 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( 191 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
141 idle_time_in_ms, heap_state.new_space_capacity, 192 idle_time_ms, heap_state.new_space_capacity,
142 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 193 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
143 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 194 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
144 } 195 }
145 196
146 197
147 TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) { 198 TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) {
148 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 199 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
149 heap_state.used_new_space_size = kNewSpaceCapacity; 200 heap_state.used_new_space_size = kNewSpaceCapacity;
150 heap_state.scavenge_speed_in_bytes_per_ms = 1 * KB; 201 heap_state.scavenge_speed_in_bytes_per_ms = 1 * KB;
151 int idle_time_in_ms = 16; 202 int idle_time_ms = 16;
152 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge( 203 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
153 idle_time_in_ms, heap_state.new_space_capacity, 204 idle_time_ms, heap_state.new_space_capacity,
154 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 205 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
155 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 206 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
156 } 207 }
157 208
158 209
159 TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) { 210 TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) {
160 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 211 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
161 heap_state.used_new_space_size = kNewSpaceCapacity; 212 heap_state.used_new_space_size = kNewSpaceCapacity;
162 heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity; 213 heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
163 int idle_time_in_ms = 16; 214 int idle_time_ms = 16;
164 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge( 215 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
165 idle_time_in_ms, heap_state.new_space_capacity, 216 idle_time_ms, heap_state.new_space_capacity,
166 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, 217 heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
167 heap_state.new_space_allocation_throughput_in_bytes_per_ms)); 218 heap_state.new_space_allocation_throughput_in_bytes_per_ms));
168 } 219 }
169 220
170 221
171 TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) { 222 TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) {
172 size_t idle_time_in_ms = GCIdleTimeHandler::kMaxScheduledIdleTime; 223 size_t idle_time_ms = GCIdleTimeHandler::kMaxScheduledIdleTime;
173 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_in_ms, 0, 0)); 224 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_ms, 0, 0));
174 } 225 }
175 226
176 227
177 TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) { 228 TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) {
178 size_t idle_time_in_ms = 1; 229 size_t idle_time_ms = 1;
179 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoMarkCompact( 230 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoMarkCompact(
180 idle_time_in_ms, kSizeOfObjects, kMarkingSpeed)); 231 idle_time_ms, kSizeOfObjects, kMarkingSpeed));
181 } 232 }
182 233
183 234
184 TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) { 235 TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
185 size_t idle_time_in_ms = 16; 236 size_t idle_time_ms = 16;
186 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( 237 EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
187 idle_time_in_ms, 0, 0)); 238 idle_time_ms, 0, 0));
188 } 239 }
189 240
190 241
191 TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) { 242 TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
192 size_t idle_time_in_ms = 1; 243 size_t idle_time_ms = 1;
193 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact( 244 EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
194 idle_time_in_ms, kSizeOfObjects, kMarkingSpeed)); 245 idle_time_ms, kSizeOfObjects, kMarkingSpeed));
195 } 246 }
196 247
197 248
198 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) { 249 TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
199 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 250 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
200 heap_state.contexts_disposed = 1; 251 heap_state.contexts_disposed = 1;
201 heap_state.incremental_marking_stopped = true; 252 heap_state.incremental_marking_stopped = true;
202 double idle_time_ms = 0; 253 double idle_time_ms = 0;
203 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 254 for (int mode = 0; mode < 1; mode++) {
204 EXPECT_EQ(DO_NOTHING, action.type); 255 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
256 EXPECT_EQ(DO_NOTHING, action.type);
257 TransitionToReduceMemoryMode(heap_state);
258 }
205 } 259 }
206 260
207 261
208 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) { 262 TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
209 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 263 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
210 heap_state.contexts_disposed = 1; 264 heap_state.contexts_disposed = 1;
211 heap_state.contexts_disposal_rate = 265 heap_state.contexts_disposal_rate =
212 GCIdleTimeHandler::kHighContextDisposalRate - 1; 266 GCIdleTimeHandler::kHighContextDisposalRate - 1;
213 heap_state.incremental_marking_stopped = true; 267 heap_state.incremental_marking_stopped = true;
214 double idle_time_ms = 0; 268 double idle_time_ms = 0;
215 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 269 for (int mode = 0; mode < 1; mode++) {
216 EXPECT_EQ(DO_FULL_GC, action.type); 270 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
271 EXPECT_EQ(DO_FULL_GC, action.type);
272 TransitionToReduceMemoryMode(heap_state);
273 }
217 } 274 }
218 275
219 276
220 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
221 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
222 heap_state.contexts_disposed = 1;
223 heap_state.contexts_disposal_rate = 1.0;
224 heap_state.incremental_marking_stopped = true;
225 heap_state.can_start_incremental_marking = false;
226 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
227 double idle_time_ms =
228 static_cast<double>((heap_state.size_of_objects + speed - 1) / speed);
229 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
230 EXPECT_EQ(DO_FULL_GC, action.type);
231 }
232
233
234 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) { 277 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
235 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 278 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
236 heap_state.contexts_disposed = 1; 279 heap_state.contexts_disposed = 1;
237 heap_state.contexts_disposal_rate = 1.0; 280 heap_state.contexts_disposal_rate = 1.0;
238 heap_state.incremental_marking_stopped = true; 281 heap_state.incremental_marking_stopped = true;
239 double idle_time_ms = 0; 282 double idle_time_ms = 0;
240 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 283 for (int mode = 0; mode < 1; mode++) {
241 EXPECT_EQ(DO_FULL_GC, action.type); 284 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
285 EXPECT_EQ(DO_FULL_GC, action.type);
286 TransitionToReduceMemoryMode(heap_state);
287 }
242 } 288 }
243 289
244 290
245 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) { 291 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
246 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 292 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
247 heap_state.contexts_disposed = 1; 293 heap_state.contexts_disposed = 1;
248 heap_state.contexts_disposal_rate = 1.0; 294 heap_state.contexts_disposal_rate = 1.0;
249 heap_state.incremental_marking_stopped = true; 295 heap_state.incremental_marking_stopped = true;
250 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 296 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
251 double idle_time_ms = 297 double idle_time_ms =
252 static_cast<double>(heap_state.size_of_objects / speed - 1); 298 static_cast<double>(heap_state.size_of_objects / speed - 1);
253 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 299 for (int mode = 0; mode < 1; mode++) {
254 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 300 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
301 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
302 TransitionToReduceMemoryMode(heap_state);
303 }
255 } 304 }
256 305
257 306
258 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) { 307 TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
259 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 308 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
260 heap_state.contexts_disposed = 1; 309 heap_state.contexts_disposed = 1;
261 heap_state.contexts_disposal_rate = 1.0; 310 heap_state.contexts_disposal_rate = 1.0;
262 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 311 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
263 double idle_time_ms = 312 double idle_time_ms =
264 static_cast<double>(heap_state.size_of_objects / speed - 1); 313 static_cast<double>(heap_state.size_of_objects / speed - 1);
265 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 314 for (int mode = 0; mode < 1; mode++) {
266 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 315 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
316 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
317 TransitionToReduceMemoryMode(heap_state);
318 }
267 } 319 }
268 320
269 321
270 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) { 322 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
271 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 323 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
272 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 324 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
273 double idle_time_ms = 10; 325 double idle_time_ms = 10;
274 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 326 for (int mode = 0; mode < 1; mode++) {
275 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 327 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
276 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 328 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
277 static_cast<size_t>(action.parameter)); 329 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
278 EXPECT_LT(0, action.parameter); 330 static_cast<size_t>(action.parameter));
331 EXPECT_LT(0, action.parameter);
332 TransitionToReduceMemoryMode(heap_state);
333 }
279 } 334 }
280 335
281 336
282 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) { 337 TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
283 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 338 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
284 heap_state.incremental_marking_stopped = true; 339 heap_state.incremental_marking_stopped = true;
285 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms; 340 size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
286 double idle_time_ms = 10; 341 double idle_time_ms = 10;
287 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 342 for (int mode = 0; mode < 1; mode++) {
288 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 343 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
289 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms), 344 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
290 static_cast<size_t>(action.parameter)); 345 EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
291 EXPECT_LT(0, action.parameter); 346 static_cast<size_t>(action.parameter));
347 EXPECT_LT(0, action.parameter);
348 TransitionToReduceMemoryMode(heap_state);
349 }
292 } 350 }
293 351
294 352
295 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) { 353 TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
296 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 354 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
297 heap_state.incremental_marking_stopped = true; 355 heap_state.incremental_marking_stopped = true;
298 heap_state.can_start_incremental_marking = false; 356 heap_state.can_start_incremental_marking = false;
299 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 357 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
300 double idle_time_ms = 358 double idle_time_ms =
301 static_cast<double>(heap_state.size_of_objects / speed - 1); 359 static_cast<double>(heap_state.size_of_objects / speed - 1);
302 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 360 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
303 EXPECT_EQ(DO_NOTHING, action.type); 361 EXPECT_EQ(DO_NOTHING, action.type);
362 TransitionToReduceMemoryMode(heap_state);
363 action = handler()->Compute(idle_time_ms, heap_state);
364 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
304 } 365 }
305 366
306 367
307 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) { 368 TEST_F(GCIdleTimeHandlerTest, FinalizeSweeping) {
308 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 369 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
309 heap_state.incremental_marking_stopped = true; 370 heap_state.incremental_marking_stopped = true;
310 heap_state.can_start_incremental_marking = false; 371 heap_state.can_start_incremental_marking = false;
311 heap_state.sweeping_in_progress = true; 372 for (int mode = 0; mode < 1; mode++) {
312 heap_state.sweeping_completed = true; 373 heap_state.sweeping_in_progress = true;
313 double idle_time_ms = 10.0; 374 heap_state.sweeping_completed = true;
314 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 375 double idle_time_ms = 10.0;
315 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type); 376 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
377 EXPECT_EQ(DO_FINALIZE_SWEEPING, action.type);
378 heap_state.sweeping_in_progress = false;
379 heap_state.sweeping_completed = false;
380 TransitionToReduceMemoryMode(heap_state);
381 }
316 } 382 }
317 383
318 384
319 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) { 385 TEST_F(GCIdleTimeHandlerTest, CannotFinalizeSweeping) {
320 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 386 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
321 heap_state.incremental_marking_stopped = true; 387 heap_state.incremental_marking_stopped = true;
322 heap_state.can_start_incremental_marking = false; 388 heap_state.can_start_incremental_marking = false;
323 heap_state.sweeping_in_progress = true; 389 for (int mode = 0; mode < 1; mode++) {
324 heap_state.sweeping_completed = false; 390 heap_state.sweeping_in_progress = true;
325 double idle_time_ms = 10.0; 391 heap_state.sweeping_completed = false;
326 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 392 double idle_time_ms = 10.0;
327 EXPECT_EQ(DO_NOTHING, action.type); 393 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
394 EXPECT_EQ(DO_NOTHING, action.type);
395 heap_state.sweeping_in_progress = false;
396 heap_state.sweeping_completed = false;
397 TransitionToReduceMemoryMode(heap_state);
398 }
328 } 399 }
329 400
330 401
402 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
403 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
404 int idle_time_ms = 10;
405 for (int mode = 0; mode < 1; mode++) {
406 heap_state.used_new_space_size =
407 heap_state.new_space_capacity -
408 (kNewSpaceAllocationThroughput * idle_time_ms);
409 GCIdleTimeAction action =
410 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
411 EXPECT_EQ(DO_SCAVENGE, action.type);
412 heap_state.used_new_space_size = 0;
413 TransitionToReduceMemoryMode(heap_state);
414 }
415 }
416
417
418 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
419 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
420 int idle_time_ms = 10;
421 heap_state.can_start_incremental_marking = false;
422 heap_state.incremental_marking_stopped = true;
423 for (int mode = 0; mode < 1; mode++) {
424 heap_state.used_new_space_size =
425 heap_state.new_space_capacity -
426 (kNewSpaceAllocationThroughput * idle_time_ms);
427 GCIdleTimeAction action =
428 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
429 EXPECT_EQ(DO_SCAVENGE, action.type);
430 heap_state.used_new_space_size = 0;
431 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
432 EXPECT_EQ(DO_NOTHING, action.type);
433 TransitionToReduceMemoryMode(heap_state);
434 }
435 }
436
437
331 TEST_F(GCIdleTimeHandlerTest, StopEventually1) { 438 TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
332 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 439 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
333 heap_state.incremental_marking_stopped = true; 440 heap_state.incremental_marking_stopped = true;
334 heap_state.can_start_incremental_marking = false; 441 heap_state.can_start_incremental_marking = false;
442 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
443 bool stopped = false;
444 for (int i = 0; i < kMaxNotifications && !stopped; i++) {
445 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
446 if (action.type == DO_INCREMENTAL_MARKING || action.type == DO_FULL_GC) {
447 handler()->NotifyMarkCompact();
448 handler()->NotifyIdleMarkCompact();
449 }
450 if (action.type == DONE) stopped = true;
451 }
452 EXPECT_TRUE(stopped);
453 }
454
455
456 TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
457 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
458 heap_state.incremental_marking_stopped = true;
459 heap_state.can_start_incremental_marking = false;
335 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 460 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
336 double idle_time_ms = 461 double idle_time_ms =
337 static_cast<double>(heap_state.size_of_objects / speed + 1); 462 static_cast<double>(heap_state.size_of_objects / speed + 1);
338 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 463 TransitionToReduceMemoryMode(heap_state);
339 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 464 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
340 EXPECT_EQ(DO_FULL_GC, action.type);
341 handler()->NotifyIdleMarkCompact();
342 }
343 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 465 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
344 EXPECT_EQ(DONE, action.type); 466 EXPECT_EQ(DONE, action.type);
345 } 467 }
346 468
347 469
348 TEST_F(GCIdleTimeHandlerTest, StopEventually2) { 470 TEST_F(GCIdleTimeHandlerTest, StopEventually3) {
349 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 471 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
472 heap_state.incremental_marking_stopped = true;
473 heap_state.can_start_incremental_marking = false;
350 double idle_time_ms = 10; 474 double idle_time_ms = 10;
351 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 475 TransitionToReduceMemoryMode(heap_state);
352 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 476 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
353 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
354 // In this case we emulate incremental marking steps that finish with a
355 // full gc.
356 handler()->NotifyIdleMarkCompact();
357 }
358 heap_state.can_start_incremental_marking = false;
359 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 477 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
360 EXPECT_EQ(DONE, action.type); 478 EXPECT_EQ(DONE, action.type);
361 } 479 }
362 480
363 481
364 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) { 482 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
365 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 483 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
366 heap_state.incremental_marking_stopped = true; 484 heap_state.incremental_marking_stopped = true;
367 heap_state.can_start_incremental_marking = false; 485 heap_state.can_start_incremental_marking = false;
368 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms; 486 size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
369 double idle_time_ms = 487 double idle_time_ms =
370 static_cast<double>(heap_state.size_of_objects / speed + 1); 488 static_cast<double>(heap_state.size_of_objects / speed + 1);
371 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 489 TransitionToReduceMemoryMode(heap_state);
372 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 490 TransitionToDoneMode(heap_state, idle_time_ms, DO_FULL_GC);
373 EXPECT_EQ(DO_FULL_GC, action.type);
374 handler()->NotifyIdleMarkCompact();
375 }
376 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 491 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
377 EXPECT_EQ(DONE, action.type); 492 EXPECT_EQ(DONE, action.type);
378 // Emulate mutator work. 493 TransitionToReduceLatencyMode(heap_state);
379 for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) { 494 heap_state.can_start_incremental_marking = true;
380 handler()->NotifyScavenge();
381 }
382 action = handler()->Compute(idle_time_ms, heap_state); 495 action = handler()->Compute(idle_time_ms, heap_state);
383 EXPECT_EQ(DO_FULL_GC, action.type); 496 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
497 EXPECT_FALSE(action.reduce_memory);
498 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
384 } 499 }
385 500
386 501
387 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) { 502 TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
388 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 503 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
504 heap_state.incremental_marking_stopped = true;
505 heap_state.can_start_incremental_marking = false;
389 double idle_time_ms = 10; 506 double idle_time_ms = 10;
390 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 507 TransitionToReduceMemoryMode(heap_state);
391 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 508 TransitionToDoneMode(heap_state, idle_time_ms, DO_INCREMENTAL_MARKING);
392 if (action.type == DONE) break;
393 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
394 // In this case we try to emulate incremental marking steps the finish with
395 // a full gc.
396 handler()->NotifyIdleMarkCompact();
397 }
398 heap_state.can_start_incremental_marking = false;
399 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 509 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
400 EXPECT_EQ(DONE, action.type); 510 EXPECT_EQ(DONE, action.type);
401 // Emulate mutator work. 511 TransitionToReduceLatencyMode(heap_state);
402 for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
403 handler()->NotifyScavenge();
404 }
405 heap_state.can_start_incremental_marking = true; 512 heap_state.can_start_incremental_marking = true;
406 action = handler()->Compute(idle_time_ms, heap_state); 513 action = handler()->Compute(idle_time_ms, heap_state);
407 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 514 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
408 } 515 EXPECT_FALSE(action.reduce_memory);
409 516 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
410
411 TEST_F(GCIdleTimeHandlerTest, Scavenge) {
412 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
413 int idle_time_ms = 10;
414 heap_state.used_new_space_size =
415 heap_state.new_space_capacity -
416 (kNewSpaceAllocationThroughput * idle_time_ms);
417 GCIdleTimeAction action =
418 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
419 EXPECT_EQ(DO_SCAVENGE, action.type);
420 }
421
422
423 TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
424 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
425 int idle_time_ms = 10;
426 heap_state.can_start_incremental_marking = false;
427 heap_state.incremental_marking_stopped = true;
428 heap_state.used_new_space_size =
429 heap_state.new_space_capacity -
430 (kNewSpaceAllocationThroughput * idle_time_ms);
431 GCIdleTimeAction action =
432 handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
433 EXPECT_EQ(DO_SCAVENGE, action.type);
434 heap_state.used_new_space_size = 0;
435 action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
436 EXPECT_EQ(DO_NOTHING, action.type);
437 } 517 }
438 518
439 519
440 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) { 520 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
441 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 521 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
442 double idle_time_ms = 0; 522 for (int i = 0; i < kMaxNotifications; i++) {
443 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 523 GCIdleTimeAction action = handler()->Compute(0, heap_state);
444 EXPECT_EQ(DO_NOTHING, action.type); 524 EXPECT_EQ(DO_NOTHING, action.type);
525 }
445 } 526 }
446 527
447 528
448 TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) { 529 TEST_F(GCIdleTimeHandlerTest, SmallIdleTimeNothingToDo) {
449 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 530 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
450 double idle_time_ms = 10; 531 heap_state.incremental_marking_stopped = true;
451 for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) { 532 heap_state.can_start_incremental_marking = false;
452 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 533 for (int i = 0; i < kMaxNotifications; i++) {
453 if (action.type == DONE) break; 534 GCIdleTimeAction action = handler()->Compute(10, heap_state);
454 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type); 535 EXPECT_EQ(DO_NOTHING, action.type);
455 // In this case we try to emulate incremental marking steps the finish with
456 // a full gc.
457 handler()->NotifyIdleMarkCompact();
458 } 536 }
459 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
460 // Emulate mutator work.
461 for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
462 handler()->NotifyScavenge();
463 }
464 action = handler()->Compute(0, heap_state);
465 EXPECT_EQ(DO_NOTHING, action.type);
466 } 537 }
467 538
468 539
469 TEST_F(GCIdleTimeHandlerTest, KeepDoingDoNothingWithZeroIdleTime) { 540 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfScavenges) {
470 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 541 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
471 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerIdleRound; 542 heap_state.incremental_marking_stopped = true;
472 i++) { 543 heap_state.can_start_incremental_marking = false;
473 GCIdleTimeAction action = handler()->Compute(0, heap_state); 544 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
545 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
546 for (int i = 0; i < kMaxNotifications; i++) {
547 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
474 EXPECT_EQ(DO_NOTHING, action.type); 548 EXPECT_EQ(DO_NOTHING, action.type);
549 if ((i + 1) % limit == 0) handler()->NotifyScavenge();
550 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
475 } 551 }
476 // Should still return DO_NOTHING if we have been given 0 deadline yet.
477 GCIdleTimeAction action = handler()->Compute(0, heap_state);
478 EXPECT_EQ(DO_NOTHING, action.type);
479 } 552 }
480 553
481 554
482 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnSweeping) { 555 TEST_F(GCIdleTimeHandlerTest, StayInReduceLatencyModeBecauseOfMarkCompacts) {
483 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); 556 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
484
485 // Simulate sweeping being in-progress but not complete.
486 heap_state.incremental_marking_stopped = true; 557 heap_state.incremental_marking_stopped = true;
487 heap_state.can_start_incremental_marking = false; 558 heap_state.can_start_incremental_marking = false;
488 heap_state.sweeping_in_progress = true; 559 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
489 heap_state.sweeping_completed = false; 560 int limit = GCIdleTimeHandler::kLongIdleNotificationsBeforeMutatorIsIdle;
490 double idle_time_ms = 10.0; 561 for (int i = 0; i < kMaxNotifications; i++) {
491 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerIdleRound;
492 i++) {
493 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 562 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
494 EXPECT_EQ(DO_NOTHING, action.type); 563 EXPECT_EQ(DO_NOTHING, action.type);
564 if ((i + 1) % limit == 0) handler()->NotifyMarkCompact();
565 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
495 } 566 }
496 // We should return DONE after not making progress for some time. 567 }
568
569
570 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToReduceLatency) {
571 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
572 heap_state.incremental_marking_stopped = true;
573 heap_state.can_start_incremental_marking = false;
574 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
575 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
576 for (int idle_gc = 0; idle_gc < limit; idle_gc++) {
577 TransitionToReduceMemoryMode(heap_state);
578 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
579 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
580 EXPECT_TRUE(action.reduce_memory);
581 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
582 for (int i = 0; i < idle_gc; i++) {
583 action = handler()->Compute(idle_time_ms, heap_state);
584 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
585 EXPECT_TRUE(action.reduce_memory);
586 // ReduceMemory mode should tolerate one mutator GC per idle GC.
587 handler()->NotifyScavenge();
588 // Notify idle GC.
589 handler()->NotifyMarkCompact();
590 handler()->NotifyIdleMarkCompact();
591 }
592 // Transition to ReduceLatency mode after doing |idle_gc| idle GCs.
593 handler()->NotifyScavenge();
594 action = handler()->Compute(idle_time_ms, heap_state);
595 EXPECT_EQ(DO_NOTHING, action.type);
596 EXPECT_FALSE(action.reduce_memory);
597 EXPECT_EQ(GCIdleTimeHandler::kReduceLatency, handler()->mode());
598 }
599 }
600
601
602 TEST_F(GCIdleTimeHandlerTest, ReduceMemoryToDone) {
603 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
604 heap_state.incremental_marking_stopped = true;
605 heap_state.can_start_incremental_marking = false;
606 double idle_time_ms = GCIdleTimeHandler::kMinLongIdleTime;
607 int limit = GCIdleTimeHandler::kMaxIdleMarkCompacts;
608 TransitionToReduceMemoryMode(heap_state);
497 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state); 609 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
610 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
611 EXPECT_TRUE(action.reduce_memory);
612 for (int i = 0; i < limit; i++) {
613 action = handler()->Compute(idle_time_ms, heap_state);
614 EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
615 EXPECT_TRUE(action.reduce_memory);
616 EXPECT_EQ(GCIdleTimeHandler::kReduceMemory, handler()->mode());
617 // ReduceMemory mode should tolerate one mutator GC per idle GC.
618 handler()->NotifyScavenge();
619 // Notify idle GC.
620 handler()->NotifyMarkCompact();
621 handler()->NotifyIdleMarkCompact();
622 }
623 action = handler()->Compute(idle_time_ms, heap_state);
498 EXPECT_EQ(DONE, action.type); 624 EXPECT_EQ(DONE, action.type);
499 } 625 }
500 626
501 627
502 TEST_F(GCIdleTimeHandlerTest, DoneIfNotMakingProgressOnIncrementalMarking) {
503 GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
504
505 // Simulate incremental marking stopped and not eligible to start.
506 heap_state.incremental_marking_stopped = true;
507 heap_state.can_start_incremental_marking = false;
508 double idle_time_ms = 10.0;
509 for (int i = 0; i < GCIdleTimeHandler::kMaxNoProgressIdleTimesPerIdleRound;
510 i++) {
511 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
512 EXPECT_EQ(DO_NOTHING, action.type);
513 }
514 // We should return DONE after not making progress for some time.
515 GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
516 EXPECT_EQ(DONE, action.type);
517 }
518
519 } // namespace internal 628 } // namespace internal
520 } // namespace v8 629 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/test-heap.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698