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

Side by Side Diff: src/heap/memory-reducer.cc

Issue 1262363002: Ensure the memory reduces makes progress. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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 | « src/heap/memory-reducer.h ('k') | test/unittests/heap/memory-reducer-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 "src/heap/memory-reducer.h" 5 #include "src/heap/memory-reducer.h"
6 6
7 #include "src/flags.h" 7 #include "src/flags.h"
8 #include "src/heap/heap.h" 8 #include "src/heap/heap.h"
9 #include "src/utils.h" 9 #include "src/utils.h"
10 #include "src/v8.h" 10 #include "src/v8.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 const int MemoryReducer::kLongDelayMs = 5000; 15 const int MemoryReducer::kLongDelayMs = 5000;
16 const int MemoryReducer::kShortDelayMs = 500; 16 const int MemoryReducer::kShortDelayMs = 500;
17 const int MemoryReducer::kWatchdogDelayMs = 100000;
17 const int MemoryReducer::kMaxNumberOfGCs = 3; 18 const int MemoryReducer::kMaxNumberOfGCs = 3;
18 19
19 MemoryReducer::TimerTask::TimerTask(MemoryReducer* memory_reducer) 20 MemoryReducer::TimerTask::TimerTask(MemoryReducer* memory_reducer)
20 : CancelableTask(memory_reducer->heap()->isolate()), 21 : CancelableTask(memory_reducer->heap()->isolate()),
21 memory_reducer_(memory_reducer) {} 22 memory_reducer_(memory_reducer) {}
22 23
23 24
24 void MemoryReducer::TimerTask::RunInternal() { 25 void MemoryReducer::TimerTask::RunInternal() {
25 Heap* heap = memory_reducer_->heap(); 26 Heap* heap = memory_reducer_->heap();
26 Event event; 27 Event event;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 if (FLAG_trace_gc_verbose) { 100 if (FLAG_trace_gc_verbose) {
100 PrintIsolate(heap()->isolate(), 101 PrintIsolate(heap()->isolate(),
101 "Memory reducer: started GC #%d" 102 "Memory reducer: started GC #%d"
102 " (background idle)\n", 103 " (background idle)\n",
103 state_.started_gcs); 104 state_.started_gcs);
104 } 105 }
105 } 106 }
106 } 107 }
107 108
108 109
110 bool MemoryReducer::WatchdogGC(const State& state, const Event& event) {
111 return state.last_gc_time_ms != 0 &&
112 event.time_ms > state.last_gc_time_ms + kWatchdogDelayMs;
113 }
114
115
109 // For specification of this function see the comment for MemoryReducer class. 116 // For specification of this function see the comment for MemoryReducer class.
110 MemoryReducer::State MemoryReducer::Step(const State& state, 117 MemoryReducer::State MemoryReducer::Step(const State& state,
111 const Event& event) { 118 const Event& event) {
112 if (!FLAG_incremental_marking) { 119 if (!FLAG_incremental_marking) {
113 return State(kDone, 0, 0); 120 return State(kDone, 0, 0, state.last_gc_time_ms);
114 } 121 }
115 switch (state.action) { 122 switch (state.action) {
116 case kDone: 123 case kDone:
117 if (event.type == kTimer || event.type == kBackgroundIdleNotification) { 124 if (event.type == kTimer || event.type == kBackgroundIdleNotification) {
118 return state; 125 return state;
119 } else { 126 } else {
120 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact); 127 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact);
121 return State(kWait, 0, event.time_ms + kLongDelayMs); 128 return State(
129 kWait, 0, event.time_ms + kLongDelayMs,
130 event.type == kMarkCompact ? event.time_ms : state.last_gc_time_ms);
122 } 131 }
123 case kWait: 132 case kWait:
124 switch (event.type) { 133 switch (event.type) {
125 case kContextDisposed: 134 case kContextDisposed:
126 return state; 135 return state;
127 case kTimer: 136 case kTimer:
128 if (state.started_gcs >= kMaxNumberOfGCs) { 137 if (state.started_gcs >= kMaxNumberOfGCs) {
129 return State(kDone, 0, 0.0); 138 return State(kDone, 0, 0.0, state.last_gc_time_ms);
130 } else if (event.can_start_incremental_gc && 139 } else if (event.can_start_incremental_gc &&
131 event.low_allocation_rate) { 140 (event.low_allocation_rate || WatchdogGC(state, event))) {
132 if (state.next_gc_start_ms <= event.time_ms) { 141 if (state.next_gc_start_ms <= event.time_ms) {
133 return State(kRun, state.started_gcs + 1, 0.0); 142 return State(kRun, state.started_gcs + 1, 0.0,
143 state.last_gc_time_ms);
134 } else { 144 } else {
135 return state; 145 return state;
136 } 146 }
137 } else { 147 } else {
138 return State(kWait, state.started_gcs, 148 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs,
139 event.time_ms + kLongDelayMs); 149 state.last_gc_time_ms);
140 } 150 }
141 case kBackgroundIdleNotification: 151 case kBackgroundIdleNotification:
142 if (event.can_start_incremental_gc && 152 if (event.can_start_incremental_gc &&
143 state.started_gcs < kMaxNumberOfGCs) { 153 state.started_gcs < kMaxNumberOfGCs) {
144 return State(kWait, state.started_gcs + 1, 154 return State(kWait, state.started_gcs + 1,
145 event.time_ms + kLongDelayMs); 155 event.time_ms + kLongDelayMs, state.last_gc_time_ms);
146 } else { 156 } else {
147 return state; 157 return state;
148 } 158 }
149 case kMarkCompact: 159 case kMarkCompact:
150 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs); 160 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs,
161 event.time_ms);
151 } 162 }
152 case kRun: 163 case kRun:
153 if (event.type != kMarkCompact) { 164 if (event.type != kMarkCompact) {
154 return state; 165 return state;
155 } else { 166 } else {
156 if (state.started_gcs < kMaxNumberOfGCs && 167 if (state.started_gcs < kMaxNumberOfGCs &&
157 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) { 168 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) {
158 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs); 169 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs,
170 event.time_ms);
159 } else { 171 } else {
160 return State(kDone, 0, 0.0); 172 return State(kDone, 0, 0.0, event.time_ms);
161 } 173 }
162 } 174 }
163 } 175 }
164 UNREACHABLE(); 176 UNREACHABLE();
165 return State(kDone, 0, 0); // Make the compiler happy. 177 return State(kDone, 0, 0, 0.0); // Make the compiler happy.
166 } 178 }
167 179
168 180
169 void MemoryReducer::ScheduleTimer(double delay_ms) { 181 void MemoryReducer::ScheduleTimer(double delay_ms) {
170 DCHECK(delay_ms > 0); 182 DCHECK(delay_ms > 0);
171 // Leave some room for precision error in task scheduler. 183 // Leave some room for precision error in task scheduler.
172 const double kSlackMs = 100; 184 const double kSlackMs = 100;
173 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate()); 185 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate());
174 auto timer_task = new MemoryReducer::TimerTask(this); 186 auto timer_task = new MemoryReducer::TimerTask(this);
175 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread( 187 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread(
176 isolate, timer_task, (delay_ms + kSlackMs) / 1000.0); 188 isolate, timer_task, (delay_ms + kSlackMs) / 1000.0);
177 } 189 }
178 190
179 191
180 void MemoryReducer::TearDown() { 192 void MemoryReducer::TearDown() { state_ = State(kDone, 0, 0, 0.0); }
181 state_ = State(kDone, 0, 0);
182 }
183 193
184 } // internal 194 } // internal
185 } // v8 195 } // v8
OLDNEW
« no previous file with comments | « src/heap/memory-reducer.h ('k') | test/unittests/heap/memory-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698