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/flags.h" | 7 #include "src/flags.h" |
8 #include "src/heap/memory-reducer.h" | 8 #include "src/heap/memory-reducer.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 MemoryReducer::State DoneState() { | 14 MemoryReducer::State DoneState() { |
15 return MemoryReducer::State(MemoryReducer::kDone, 0, 0.0, 1.0); | 15 return MemoryReducer::State(MemoryReducer::kDone, 0, 0.0, 1.0, 0); |
16 } | 16 } |
17 | 17 |
| 18 MemoryReducer::State DoneState(size_t committed_memory) { |
| 19 return MemoryReducer::State(MemoryReducer::kDone, 0, 0.0, 1.0, |
| 20 committed_memory); |
| 21 } |
18 | 22 |
19 MemoryReducer::State WaitState(int started_gcs, double next_gc_start_ms) { | 23 MemoryReducer::State WaitState(int started_gcs, double next_gc_start_ms) { |
20 return MemoryReducer::State(MemoryReducer::kWait, started_gcs, | 24 return MemoryReducer::State(MemoryReducer::kWait, started_gcs, |
21 next_gc_start_ms, 1.0); | 25 next_gc_start_ms, 1.0, 0); |
22 } | 26 } |
23 | 27 |
24 | 28 |
25 MemoryReducer::State RunState(int started_gcs, double next_gc_start_ms) { | 29 MemoryReducer::State RunState(int started_gcs, double next_gc_start_ms) { |
26 return MemoryReducer::State(MemoryReducer::kRun, started_gcs, | 30 return MemoryReducer::State(MemoryReducer::kRun, started_gcs, |
27 next_gc_start_ms, 1.0); | 31 next_gc_start_ms, 1.0, 0); |
28 } | 32 } |
29 | 33 |
30 | |
31 MemoryReducer::Event MarkCompactEvent(double time_ms, | 34 MemoryReducer::Event MarkCompactEvent(double time_ms, |
32 bool next_gc_likely_to_collect_more) { | 35 bool next_gc_likely_to_collect_more, |
| 36 size_t committed_memory) { |
33 MemoryReducer::Event event; | 37 MemoryReducer::Event event; |
34 event.type = MemoryReducer::kMarkCompact; | 38 event.type = MemoryReducer::kMarkCompact; |
35 event.time_ms = time_ms; | 39 event.time_ms = time_ms; |
36 event.next_gc_likely_to_collect_more = next_gc_likely_to_collect_more; | 40 event.next_gc_likely_to_collect_more = next_gc_likely_to_collect_more; |
| 41 event.committed_memory = committed_memory; |
37 return event; | 42 return event; |
38 } | 43 } |
39 | 44 |
| 45 MemoryReducer::Event MarkCompactEventGarbageLeft(double time_ms, |
| 46 size_t committed_memory) { |
| 47 return MarkCompactEvent(time_ms, true, committed_memory); |
| 48 } |
40 | 49 |
41 MemoryReducer::Event MarkCompactEventGarbageLeft(double time_ms) { | 50 MemoryReducer::Event MarkCompactEventNoGarbageLeft(double time_ms, |
42 return MarkCompactEvent(time_ms, true); | 51 size_t committed_memory) { |
| 52 return MarkCompactEvent(time_ms, false, committed_memory); |
43 } | 53 } |
44 | 54 |
45 | 55 |
46 MemoryReducer::Event MarkCompactEventNoGarbageLeft(double time_ms) { | |
47 return MarkCompactEvent(time_ms, false); | |
48 } | |
49 | |
50 | |
51 MemoryReducer::Event TimerEvent(double time_ms, | 56 MemoryReducer::Event TimerEvent(double time_ms, |
52 bool should_start_incremental_gc, | 57 bool should_start_incremental_gc, |
53 bool can_start_incremental_gc) { | 58 bool can_start_incremental_gc) { |
54 MemoryReducer::Event event; | 59 MemoryReducer::Event event; |
55 event.type = MemoryReducer::kTimer; | 60 event.type = MemoryReducer::kTimer; |
56 event.time_ms = time_ms; | 61 event.time_ms = time_ms; |
57 event.should_start_incremental_gc = should_start_incremental_gc; | 62 event.should_start_incremental_gc = should_start_incremental_gc; |
58 event.can_start_incremental_gc = can_start_incremental_gc; | 63 event.can_start_incremental_gc = can_start_incremental_gc; |
59 return event; | 64 return event; |
60 } | 65 } |
(...skipping 25 matching lines...) Expand all Loading... |
86 MemoryReducer::State state0(DoneState()), state1(DoneState()); | 91 MemoryReducer::State state0(DoneState()), state1(DoneState()); |
87 | 92 |
88 state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(0)); | 93 state1 = MemoryReducer::Step(state0, TimerEventLowAllocationRate(0)); |
89 EXPECT_EQ(MemoryReducer::kDone, state1.action); | 94 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
90 | 95 |
91 state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(0)); | 96 state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(0)); |
92 EXPECT_EQ(MemoryReducer::kDone, state1.action); | 97 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
93 | 98 |
94 state1 = MemoryReducer::Step(state0, TimerEventPendingGC(0)); | 99 state1 = MemoryReducer::Step(state0, TimerEventPendingGC(0)); |
95 EXPECT_EQ(MemoryReducer::kDone, state1.action); | 100 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
| 101 |
| 102 state1 = MemoryReducer::Step( |
| 103 state0, |
| 104 MarkCompactEventGarbageLeft(0, MemoryReducer::kCommittedMemoryDelta - 1)); |
| 105 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
| 106 |
| 107 state0 = DoneState(1000 * MB); |
| 108 state1 = MemoryReducer::Step( |
| 109 state0, MarkCompactEventGarbageLeft( |
| 110 0, static_cast<size_t>( |
| 111 1000 * MB * MemoryReducer::kCommittedMemoryFactor) - |
| 112 1)); |
| 113 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
96 } | 114 } |
97 | 115 |
98 | 116 |
99 TEST(MemoryReducer, FromDoneToWait) { | 117 TEST(MemoryReducer, FromDoneToWait) { |
100 if (!FLAG_incremental_marking) return; | 118 if (!FLAG_incremental_marking) return; |
101 | 119 |
102 MemoryReducer::State state0(DoneState()), state1(DoneState()); | 120 MemoryReducer::State state0(DoneState()), state1(DoneState()); |
103 | 121 |
104 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2)); | 122 state1 = MemoryReducer::Step( |
| 123 state0, |
| 124 MarkCompactEventGarbageLeft(2, MemoryReducer::kCommittedMemoryDelta)); |
105 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 125 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
106 EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms); | 126 EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms); |
107 EXPECT_EQ(0, state1.started_gcs); | 127 EXPECT_EQ(0, state1.started_gcs); |
108 EXPECT_EQ(2, state1.last_gc_time_ms); | 128 EXPECT_EQ(2, state1.last_gc_time_ms); |
109 | 129 |
110 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2)); | 130 state1 = MemoryReducer::Step( |
| 131 state0, |
| 132 MarkCompactEventNoGarbageLeft(2, MemoryReducer::kCommittedMemoryDelta)); |
111 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 133 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
112 EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms); | 134 EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms); |
113 EXPECT_EQ(0, state1.started_gcs); | 135 EXPECT_EQ(0, state1.started_gcs); |
114 EXPECT_EQ(2, state1.last_gc_time_ms); | 136 EXPECT_EQ(2, state1.last_gc_time_ms); |
115 | 137 |
116 state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(0)); | 138 state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(0)); |
117 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 139 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
118 EXPECT_EQ(MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); | 140 EXPECT_EQ(MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); |
119 EXPECT_EQ(0, state1.started_gcs); | 141 EXPECT_EQ(0, state1.started_gcs); |
120 EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms); | 142 EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms); |
| 143 |
| 144 state0 = DoneState(1000 * MB); |
| 145 state1 = MemoryReducer::Step( |
| 146 state0, MarkCompactEventGarbageLeft( |
| 147 2, static_cast<size_t>( |
| 148 1000 * MB * MemoryReducer::kCommittedMemoryFactor))); |
| 149 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
| 150 EXPECT_EQ(MemoryReducer::kLongDelayMs + 2, state1.next_gc_start_ms); |
| 151 EXPECT_EQ(0, state1.started_gcs); |
| 152 EXPECT_EQ(2, state1.last_gc_time_ms); |
121 } | 153 } |
122 | 154 |
123 | 155 |
124 TEST(MemoryReducer, FromWaitToWait) { | 156 TEST(MemoryReducer, FromWaitToWait) { |
125 if (!FLAG_incremental_marking) return; | 157 if (!FLAG_incremental_marking) return; |
126 | 158 |
127 MemoryReducer::State state0(WaitState(2, 1000.0)), state1(DoneState()); | 159 MemoryReducer::State state0(WaitState(2, 1000.0)), state1(DoneState()); |
128 | 160 |
129 state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(2000)); | 161 state1 = MemoryReducer::Step(state0, PossibleGarbageEvent(2000)); |
130 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 162 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
131 EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms); | 163 EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms); |
132 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 164 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
133 | 165 |
134 state1 = MemoryReducer::Step( | 166 state1 = MemoryReducer::Step( |
135 state0, TimerEventLowAllocationRate(state0.next_gc_start_ms - 1)); | 167 state0, TimerEventLowAllocationRate(state0.next_gc_start_ms - 1)); |
136 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 168 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
137 EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms); | 169 EXPECT_EQ(state0.next_gc_start_ms, state1.next_gc_start_ms); |
138 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 170 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
139 | 171 |
140 state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000)); | 172 state1 = MemoryReducer::Step(state0, TimerEventHighAllocationRate(2000)); |
141 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 173 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
142 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); | 174 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); |
143 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 175 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
144 | 176 |
145 state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000)); | 177 state1 = MemoryReducer::Step(state0, TimerEventPendingGC(2000)); |
146 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 178 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
147 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); | 179 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); |
148 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 180 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
149 | 181 |
150 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000)); | 182 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000, 0)); |
151 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 183 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
152 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); | 184 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); |
153 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 185 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
154 EXPECT_EQ(2000, state1.last_gc_time_ms); | 186 EXPECT_EQ(2000, state1.last_gc_time_ms); |
155 | 187 |
156 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000)); | 188 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000, 0)); |
157 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 189 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
158 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); | 190 EXPECT_EQ(2000 + MemoryReducer::kLongDelayMs, state1.next_gc_start_ms); |
159 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 191 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
160 EXPECT_EQ(2000, state1.last_gc_time_ms); | 192 EXPECT_EQ(2000, state1.last_gc_time_ms); |
161 | 193 |
162 state0.last_gc_time_ms = 0; | 194 state0.last_gc_time_ms = 0; |
163 state1 = MemoryReducer::Step( | 195 state1 = MemoryReducer::Step( |
164 state0, | 196 state0, |
165 TimerEventHighAllocationRate(MemoryReducer::kWatchdogDelayMs + 1)); | 197 TimerEventHighAllocationRate(MemoryReducer::kWatchdogDelayMs + 1)); |
166 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 198 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 287 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
256 EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms); | 288 EXPECT_EQ(state0.last_gc_time_ms, state1.last_gc_time_ms); |
257 } | 289 } |
258 | 290 |
259 | 291 |
260 TEST(MemoryReducer, FromRunToDone) { | 292 TEST(MemoryReducer, FromRunToDone) { |
261 if (!FLAG_incremental_marking) return; | 293 if (!FLAG_incremental_marking) return; |
262 | 294 |
263 MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState()); | 295 MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState()); |
264 | 296 |
265 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000)); | 297 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000, 0)); |
266 EXPECT_EQ(MemoryReducer::kDone, state1.action); | 298 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
267 EXPECT_EQ(0, state1.next_gc_start_ms); | 299 EXPECT_EQ(0, state1.next_gc_start_ms); |
268 EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs); | 300 EXPECT_EQ(MemoryReducer::kMaxNumberOfGCs, state1.started_gcs); |
269 EXPECT_EQ(2000, state1.last_gc_time_ms); | 301 EXPECT_EQ(2000, state1.last_gc_time_ms); |
270 | 302 |
271 state0.started_gcs = MemoryReducer::kMaxNumberOfGCs; | 303 state0.started_gcs = MemoryReducer::kMaxNumberOfGCs; |
272 | 304 |
273 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000)); | 305 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000, 0)); |
274 EXPECT_EQ(MemoryReducer::kDone, state1.action); | 306 EXPECT_EQ(MemoryReducer::kDone, state1.action); |
275 EXPECT_EQ(0, state1.next_gc_start_ms); | 307 EXPECT_EQ(0, state1.next_gc_start_ms); |
276 EXPECT_EQ(2000, state1.last_gc_time_ms); | 308 EXPECT_EQ(2000, state1.last_gc_time_ms); |
277 } | 309 } |
278 | 310 |
279 | 311 |
280 TEST(MemoryReducer, FromRunToWait) { | 312 TEST(MemoryReducer, FromRunToWait) { |
281 if (!FLAG_incremental_marking) return; | 313 if (!FLAG_incremental_marking) return; |
282 | 314 |
283 MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState()); | 315 MemoryReducer::State state0(RunState(2, 0.0)), state1(DoneState()); |
284 | 316 |
285 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000)); | 317 state1 = MemoryReducer::Step(state0, MarkCompactEventGarbageLeft(2000, 0)); |
286 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 318 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
287 EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms); | 319 EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms); |
288 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 320 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
289 EXPECT_EQ(2000, state1.last_gc_time_ms); | 321 EXPECT_EQ(2000, state1.last_gc_time_ms); |
290 | 322 |
291 state0.started_gcs = 1; | 323 state0.started_gcs = 1; |
292 | 324 |
293 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000)); | 325 state1 = MemoryReducer::Step(state0, MarkCompactEventNoGarbageLeft(2000, 0)); |
294 EXPECT_EQ(MemoryReducer::kWait, state1.action); | 326 EXPECT_EQ(MemoryReducer::kWait, state1.action); |
295 EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms); | 327 EXPECT_EQ(2000 + MemoryReducer::kShortDelayMs, state1.next_gc_start_ms); |
296 EXPECT_EQ(state0.started_gcs, state1.started_gcs); | 328 EXPECT_EQ(state0.started_gcs, state1.started_gcs); |
297 EXPECT_EQ(2000, state1.last_gc_time_ms); | 329 EXPECT_EQ(2000, state1.last_gc_time_ms); |
298 } | 330 } |
299 | 331 |
300 } // namespace internal | 332 } // namespace internal |
301 } // namespace v8 | 333 } // namespace v8 |
OLD | NEW |