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