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

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

Issue 1284673002: Version 4.5.103.21 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.5
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 20
20 void MemoryReducer::TimerTask::Run() { 21 void MemoryReducer::TimerTask::Run() {
21 if (heap_is_torn_down_) return; 22 if (heap_is_torn_down_) return;
22 Heap* heap = memory_reducer_->heap(); 23 Heap* heap = memory_reducer_->heap();
23 Event event; 24 Event event;
25 double time_ms = heap->MonotonicallyIncreasingTimeInMs();
26 heap->tracer()->SampleAllocation(time_ms, heap->NewSpaceAllocationCounter(),
27 heap->OldGenerationAllocationCounter());
24 event.type = kTimer; 28 event.type = kTimer;
25 event.time_ms = heap->MonotonicallyIncreasingTimeInMs(); 29 event.time_ms = time_ms;
26 event.low_allocation_rate = heap->HasLowAllocationRate(); 30 event.low_allocation_rate = heap->HasLowAllocationRate();
27 event.can_start_incremental_gc = 31 event.can_start_incremental_gc =
28 heap->incremental_marking()->IsStopped() && 32 heap->incremental_marking()->IsStopped() &&
29 heap->incremental_marking()->CanBeActivated(); 33 heap->incremental_marking()->CanBeActivated();
30 memory_reducer_->NotifyTimer(event); 34 memory_reducer_->NotifyTimer(event);
31 } 35 }
32 36
33 37
34 void MemoryReducer::NotifyTimer(const Event& event) { 38 void MemoryReducer::NotifyTimer(const Event& event) {
35 DCHECK(nullptr != pending_task_); 39 DCHECK(nullptr != pending_task_);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 90
87 91
88 void MemoryReducer::NotifyBackgroundIdleNotification(const Event& event) { 92 void MemoryReducer::NotifyBackgroundIdleNotification(const Event& event) {
89 DCHECK_EQ(kBackgroundIdleNotification, event.type); 93 DCHECK_EQ(kBackgroundIdleNotification, event.type);
90 Action old_action = state_.action; 94 Action old_action = state_.action;
91 int old_started_gcs = state_.started_gcs; 95 int old_started_gcs = state_.started_gcs;
92 state_ = Step(state_, event); 96 state_ = Step(state_, event);
93 if (old_action == kWait && state_.action == kWait && 97 if (old_action == kWait && state_.action == kWait &&
94 old_started_gcs + 1 == state_.started_gcs) { 98 old_started_gcs + 1 == state_.started_gcs) {
95 DCHECK(heap()->incremental_marking()->IsStopped()); 99 DCHECK(heap()->incremental_marking()->IsStopped());
96 DCHECK(FLAG_incremental_marking); 100 // TODO(ulan): Replace it with incremental marking GC once
97 heap()->StartIdleIncrementalMarking(); 101 // chromium:490559 is fixed.
98 if (FLAG_trace_gc_verbose) { 102 if (event.time_ms > state_.last_gc_time_ms + kLongDelayMs) {
99 PrintIsolate(heap()->isolate(), 103 heap()->CollectAllGarbage(Heap::kReduceMemoryFootprintMask,
100 "Memory reducer: started GC #%d" 104 "memory reducer background GC");
101 " (background idle)\n", 105 } else {
102 state_.started_gcs); 106 DCHECK(FLAG_incremental_marking);
107 heap()->StartIdleIncrementalMarking();
108 if (FLAG_trace_gc_verbose) {
109 PrintIsolate(heap()->isolate(),
110 "Memory reducer: started GC #%d"
111 " (background idle)\n",
112 state_.started_gcs);
113 }
103 } 114 }
104 } 115 }
105 } 116 }
106 117
107 118
119 bool MemoryReducer::WatchdogGC(const State& state, const Event& event) {
120 return state.last_gc_time_ms != 0 &&
121 event.time_ms > state.last_gc_time_ms + kWatchdogDelayMs;
122 }
123
124
108 // For specification of this function see the comment for MemoryReducer class. 125 // For specification of this function see the comment for MemoryReducer class.
109 MemoryReducer::State MemoryReducer::Step(const State& state, 126 MemoryReducer::State MemoryReducer::Step(const State& state,
110 const Event& event) { 127 const Event& event) {
111 if (!FLAG_incremental_marking) { 128 if (!FLAG_incremental_marking) {
112 return State(kDone, 0, 0); 129 return State(kDone, 0, 0, state.last_gc_time_ms);
113 } 130 }
114 switch (state.action) { 131 switch (state.action) {
115 case kDone: 132 case kDone:
116 if (event.type == kTimer || event.type == kBackgroundIdleNotification) { 133 if (event.type == kTimer || event.type == kBackgroundIdleNotification) {
117 return state; 134 return state;
118 } else { 135 } else {
119 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact); 136 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact);
120 return State(kWait, 0, event.time_ms + kLongDelayMs); 137 return State(
138 kWait, 0, event.time_ms + kLongDelayMs,
139 event.type == kMarkCompact ? event.time_ms : state.last_gc_time_ms);
121 } 140 }
122 case kWait: 141 case kWait:
123 switch (event.type) { 142 switch (event.type) {
124 case kContextDisposed: 143 case kContextDisposed:
125 return state; 144 return state;
126 case kTimer: 145 case kTimer:
127 if (state.started_gcs >= kMaxNumberOfGCs) { 146 if (state.started_gcs >= kMaxNumberOfGCs) {
128 return State(kDone, 0, 0.0); 147 return State(kDone, kMaxNumberOfGCs, 0.0, state.last_gc_time_ms);
129 } else if (event.can_start_incremental_gc && 148 } else if (event.can_start_incremental_gc &&
130 event.low_allocation_rate) { 149 (event.low_allocation_rate || WatchdogGC(state, event))) {
131 if (state.next_gc_start_ms <= event.time_ms) { 150 if (state.next_gc_start_ms <= event.time_ms) {
132 return State(kRun, state.started_gcs + 1, 0.0); 151 return State(kRun, state.started_gcs + 1, 0.0,
152 state.last_gc_time_ms);
133 } else { 153 } else {
134 return state; 154 return state;
135 } 155 }
136 } else { 156 } else {
137 return State(kWait, state.started_gcs, 157 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs,
138 event.time_ms + kLongDelayMs); 158 state.last_gc_time_ms);
139 } 159 }
140 case kBackgroundIdleNotification: 160 case kBackgroundIdleNotification:
141 if (event.can_start_incremental_gc && 161 if (event.can_start_incremental_gc &&
142 state.started_gcs < kMaxNumberOfGCs) { 162 state.started_gcs < kMaxNumberOfGCs) {
143 return State(kWait, state.started_gcs + 1, 163 return State(kWait, state.started_gcs + 1,
144 event.time_ms + kLongDelayMs); 164 event.time_ms + kLongDelayMs, state.last_gc_time_ms);
145 } else { 165 } else {
146 return state; 166 return state;
147 } 167 }
148 case kMarkCompact: 168 case kMarkCompact:
149 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs); 169 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs,
170 event.time_ms);
150 } 171 }
151 case kRun: 172 case kRun:
152 if (event.type != kMarkCompact) { 173 if (event.type != kMarkCompact) {
153 return state; 174 return state;
154 } else { 175 } else {
155 if (state.started_gcs < kMaxNumberOfGCs && 176 if (state.started_gcs < kMaxNumberOfGCs &&
156 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) { 177 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) {
157 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs); 178 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs,
179 event.time_ms);
158 } else { 180 } else {
159 return State(kDone, 0, 0.0); 181 return State(kDone, kMaxNumberOfGCs, 0.0, event.time_ms);
160 } 182 }
161 } 183 }
162 } 184 }
163 UNREACHABLE(); 185 UNREACHABLE();
164 return State(kDone, 0, 0); // Make the compiler happy. 186 return State(kDone, 0, 0, 0.0); // Make the compiler happy.
165 } 187 }
166 188
167 189
168 void MemoryReducer::ScheduleTimer(double delay_ms) { 190 void MemoryReducer::ScheduleTimer(double delay_ms) {
169 DCHECK(delay_ms > 0); 191 DCHECK(delay_ms > 0);
170 // Leave some room for precision error in task scheduler. 192 // Leave some room for precision error in task scheduler.
171 const double kSlackMs = 100; 193 const double kSlackMs = 100;
172 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate()); 194 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate());
173 DCHECK(nullptr == pending_task_); 195 DCHECK(nullptr == pending_task_);
174 pending_task_ = new MemoryReducer::TimerTask(this); 196 pending_task_ = new MemoryReducer::TimerTask(this);
175 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread( 197 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread(
176 isolate, pending_task_, (delay_ms + kSlackMs) / 1000.0); 198 isolate, pending_task_, (delay_ms + kSlackMs) / 1000.0);
177 } 199 }
178 200
179 201
180 void MemoryReducer::ClearTask(v8::Task* task) { 202 void MemoryReducer::ClearTask(v8::Task* task) {
181 if (pending_task_ == task) { 203 if (pending_task_ == task) {
182 pending_task_ = nullptr; 204 pending_task_ = nullptr;
183 } 205 }
184 } 206 }
185 207
186 208
187 void MemoryReducer::TearDown() { 209 void MemoryReducer::TearDown() {
188 if (pending_task_ != nullptr) { 210 if (pending_task_ != nullptr) {
189 pending_task_->NotifyHeapTearDown(); 211 pending_task_->NotifyHeapTearDown();
190 pending_task_ = nullptr; 212 pending_task_ = nullptr;
191 } 213 }
192 state_ = State(kDone, 0, 0); 214 state_ = State(kDone, 0, 0, 0.0);
193 } 215 }
194 216
195 } // internal 217 } // internal
196 } // v8 218 } // 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