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

Side by Side Diff: content/browser/memory/memory_coordinator_impl.cc

Issue 2586873002: Change type of MemoryCoordinatorImpl::ChildInfo::memory_state (Closed)
Patch Set: rebase Created 4 years 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium 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 "content/browser/memory/memory_coordinator_impl.h" 5 #include "content/browser/memory/memory_coordinator_impl.h"
6 6
7 #include "base/memory/memory_coordinator_client_registry.h" 7 #include "base/memory/memory_coordinator_client_registry.h"
8 #include "base/metrics/histogram_macros.h" 8 #include "base/metrics/histogram_macros.h"
9 #include "base/process/process_handle.h" 9 #include "base/process/process_handle.h"
10 #include "base/process/process_metrics.h" 10 #include "base/process/process_metrics.h"
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 std::unique_ptr<MemoryCoordinatorHandleImpl> handle( 188 std::unique_ptr<MemoryCoordinatorHandleImpl> handle(
189 new MemoryCoordinatorHandleImpl(std::move(request), this, 189 new MemoryCoordinatorHandleImpl(std::move(request), this,
190 render_process_id)); 190 render_process_id));
191 handle->binding().set_connection_error_handler( 191 handle->binding().set_connection_error_handler(
192 base::Bind(&MemoryCoordinatorImpl::OnConnectionError, 192 base::Bind(&MemoryCoordinatorImpl::OnConnectionError,
193 base::Unretained(this), render_process_id)); 193 base::Unretained(this), render_process_id));
194 CreateChildInfoMapEntry(render_process_id, std::move(handle)); 194 CreateChildInfoMapEntry(render_process_id, std::move(handle));
195 } 195 }
196 196
197 bool MemoryCoordinatorImpl::SetChildMemoryState(int render_process_id, 197 bool MemoryCoordinatorImpl::SetChildMemoryState(int render_process_id,
198 mojom::MemoryState memory_state) { 198 MemoryState memory_state) {
199 // Can't set an invalid memory state. 199 // Can't set an invalid memory state.
200 if (memory_state == mojom::MemoryState::UNKNOWN) 200 if (memory_state == MemoryState::UNKNOWN)
201 return false; 201 return false;
202 202
203 // Can't send a message to a child that doesn't exist. 203 // Can't send a message to a child that doesn't exist.
204 auto iter = children_.find(render_process_id); 204 auto iter = children_.find(render_process_id);
205 if (iter == children_.end()) 205 if (iter == children_.end())
206 return false; 206 return false;
207 207
208 // Can't send a message to a child that isn't bound. 208 // Can't send a message to a child that isn't bound.
209 if (!iter->second.handle->child().is_bound()) 209 if (!iter->second.handle->child().is_bound())
210 return false; 210 return false;
211 211
212 memory_state = OverrideGlobalState(memory_state, iter->second); 212 memory_state = OverrideGlobalState(memory_state, iter->second);
213 213
214 // A nop doesn't need to be sent, but is considered successful. 214 // A nop doesn't need to be sent, but is considered successful.
215 if (iter->second.memory_state == memory_state) 215 if (iter->second.memory_state == memory_state)
216 return true; 216 return true;
217 217
218 // Can't suspend the given renderer. 218 // Can't suspend the given renderer.
219 if (memory_state == mojom::MemoryState::SUSPENDED && 219 if (memory_state == MemoryState::SUSPENDED &&
220 !CanSuspendRenderer(render_process_id)) 220 !CanSuspendRenderer(render_process_id))
221 return false; 221 return false;
222 222
223 // Update the internal state and send the message. 223 // Update the internal state and send the message.
224 iter->second.memory_state = memory_state; 224 iter->second.memory_state = memory_state;
225 iter->second.handle->child()->OnStateChange(memory_state); 225 iter->second.handle->child()->OnStateChange(ToMojomMemoryState(memory_state));
226 return true; 226 return true;
227 } 227 }
228 228
229 mojom::MemoryState MemoryCoordinatorImpl::GetChildMemoryState( 229 base::MemoryState MemoryCoordinatorImpl::GetChildMemoryState(
230 int render_process_id) const { 230 int render_process_id) const {
231 auto iter = children_.find(render_process_id); 231 auto iter = children_.find(render_process_id);
232 if (iter == children_.end()) 232 if (iter == children_.end())
233 return mojom::MemoryState::UNKNOWN; 233 return base::MemoryState::UNKNOWN;
234 return iter->second.memory_state; 234 return iter->second.memory_state;
235 } 235 }
236 236
237 void MemoryCoordinatorImpl::RecordMemoryPressure( 237 void MemoryCoordinatorImpl::RecordMemoryPressure(
238 base::MemoryPressureMonitor::MemoryPressureLevel level) { 238 base::MemoryPressureMonitor::MemoryPressureLevel level) {
239 DCHECK(GetGlobalMemoryState() != base::MemoryState::UNKNOWN); 239 DCHECK(GetGlobalMemoryState() != base::MemoryState::UNKNOWN);
240 int state = static_cast<int>(GetGlobalMemoryState()); 240 int state = static_cast<int>(GetGlobalMemoryState());
241 switch (level) { 241 switch (level) {
242 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: 242 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
243 UMA_HISTOGRAM_ENUMERATION( 243 UMA_HISTOGRAM_ENUMERATION(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 const NotificationDetails& details) { 285 const NotificationDetails& details) {
286 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED); 286 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED);
287 RenderWidgetHost* render_widget_host = Source<RenderWidgetHost>(source).ptr(); 287 RenderWidgetHost* render_widget_host = Source<RenderWidgetHost>(source).ptr();
288 RenderProcessHost* process = render_widget_host->GetProcess(); 288 RenderProcessHost* process = render_widget_host->GetProcess();
289 if (!process) 289 if (!process)
290 return; 290 return;
291 auto iter = children().find(process->GetID()); 291 auto iter = children().find(process->GetID());
292 if (iter == children().end()) 292 if (iter == children().end())
293 return; 293 return;
294 iter->second.is_visible = *Details<bool>(details).ptr(); 294 iter->second.is_visible = *Details<bool>(details).ptr();
295 auto new_state = ToMojomMemoryState(GetGlobalMemoryState()); 295 auto new_state = GetGlobalMemoryState();
296 SetChildMemoryState(iter->first, new_state); 296 SetChildMemoryState(iter->first, new_state);
297 } 297 }
298 298
299 bool MemoryCoordinatorImpl::ChangeStateIfNeeded(base::MemoryState prev_state, 299 bool MemoryCoordinatorImpl::ChangeStateIfNeeded(base::MemoryState prev_state,
300 base::MemoryState next_state) { 300 base::MemoryState next_state) {
301 DCHECK(CalledOnValidThread()); 301 DCHECK(CalledOnValidThread());
302 if (prev_state == next_state) 302 if (prev_state == next_state)
303 return false; 303 return false;
304 304
305 base::TimeTicks prev_last_state_change = last_state_change_; 305 base::TimeTicks prev_last_state_change = last_state_change_;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 auto* render_process_host = RenderProcessHost::FromID(render_process_id); 338 auto* render_process_host = RenderProcessHost::FromID(render_process_id);
339 if (!render_process_host || !render_process_host->IsProcessBackgrounded()) 339 if (!render_process_host || !render_process_host->IsProcessBackgrounded())
340 return false; 340 return false;
341 if (render_process_host->GetWorkerRefCount() > 0) 341 if (render_process_host->GetWorkerRefCount() > 0)
342 return false; 342 return false;
343 return delegate_->CanSuspendBackgroundedRenderer(render_process_id); 343 return delegate_->CanSuspendBackgroundedRenderer(render_process_id);
344 } 344 }
345 345
346 void MemoryCoordinatorImpl::OnChildAdded(int render_process_id) { 346 void MemoryCoordinatorImpl::OnChildAdded(int render_process_id) {
347 // Populate the global state as an initial state of a newly created process. 347 // Populate the global state as an initial state of a newly created process.
348 auto new_state = ToMojomMemoryState(GetGlobalMemoryState()); 348 auto new_state = GetGlobalMemoryState();
349 SetChildMemoryState(render_process_id, new_state); 349 SetChildMemoryState(render_process_id, new_state);
350 } 350 }
351 351
352 mojom::MemoryState MemoryCoordinatorImpl::OverrideGlobalState( 352 base::MemoryState MemoryCoordinatorImpl::OverrideGlobalState(
353 mojom::MemoryState memory_state, 353 MemoryState memory_state,
354 const ChildInfo& child) { 354 const ChildInfo& child) {
355 // We don't suspend foreground renderers. Throttle them instead. 355 // We don't suspend foreground renderers. Throttle them instead.
356 if (child.is_visible && memory_state == mojom::MemoryState::SUSPENDED) 356 if (child.is_visible && memory_state == MemoryState::SUSPENDED)
357 return mojom::MemoryState::THROTTLED; 357 return MemoryState::THROTTLED;
358 #if defined(OS_ANDROID) 358 #if defined(OS_ANDROID)
359 // On Android, we throttle background renderers immediately. 359 // On Android, we throttle background renderers immediately.
360 // TODO(bashi): Create a specialized class of MemoryCoordinator for Android 360 // TODO(bashi): Create a specialized class of MemoryCoordinator for Android
361 // and move this ifdef to the class. 361 // and move this ifdef to the class.
362 if (!child.is_visible && memory_state == mojom::MemoryState::NORMAL) 362 if (!child.is_visible && memory_state == MemoryState::NORMAL)
363 return mojom::MemoryState::THROTTLED; 363 return MemoryState::THROTTLED;
364 // TODO(bashi): Suspend background renderers after a certain period of time. 364 // TODO(bashi): Suspend background renderers after a certain period of time.
365 #endif // defined(OS_ANDROID) 365 #endif // defined(OS_ANDROID)
366 return memory_state; 366 return memory_state;
367 } 367 }
368 368
369 void MemoryCoordinatorImpl::SetDelegateForTesting( 369 void MemoryCoordinatorImpl::SetDelegateForTesting(
370 std::unique_ptr<MemoryCoordinatorDelegate> delegate) { 370 std::unique_ptr<MemoryCoordinatorDelegate> delegate) {
371 CHECK(!delegate_); 371 CHECK(!delegate_);
372 delegate_ = std::move(delegate); 372 delegate_ = std::move(delegate);
373 } 373 }
374 374
375 void MemoryCoordinatorImpl::CreateChildInfoMapEntry( 375 void MemoryCoordinatorImpl::CreateChildInfoMapEntry(
376 int render_process_id, 376 int render_process_id,
377 std::unique_ptr<MemoryCoordinatorHandleImpl> handle) { 377 std::unique_ptr<MemoryCoordinatorHandleImpl> handle) {
378 auto& child_info = children_[render_process_id]; 378 auto& child_info = children_[render_process_id];
379 // Process always start with normal memory state. 379 // Process always start with normal memory state.
380 // We'll set renderer's memory state to the current global state when the 380 // We'll set renderer's memory state to the current global state when the
381 // corresponding renderer process is ready to communicate. Renderer processes 381 // corresponding renderer process is ready to communicate. Renderer processes
382 // call AddChild() when they are ready. 382 // call AddChild() when they are ready.
383 child_info.memory_state = mojom::MemoryState::NORMAL; 383 child_info.memory_state = MemoryState::NORMAL;
384 child_info.is_visible = true; 384 child_info.is_visible = true;
385 child_info.handle = std::move(handle); 385 child_info.handle = std::move(handle);
386 } 386 }
387 387
388 void MemoryCoordinatorImpl::NotifyStateToClients() { 388 void MemoryCoordinatorImpl::NotifyStateToClients() {
389 auto state = GetCurrentMemoryState(); 389 auto state = GetCurrentMemoryState();
390 base::MemoryCoordinatorClientRegistry::GetInstance()->Notify(state); 390 base::MemoryCoordinatorClientRegistry::GetInstance()->Notify(state);
391 } 391 }
392 392
393 void MemoryCoordinatorImpl::NotifyStateToChildren() { 393 void MemoryCoordinatorImpl::NotifyStateToChildren() {
394 auto mojo_state = ToMojomMemoryState(current_state_);
395 // It's OK to call SetChildMemoryState() unconditionally because it checks 394 // It's OK to call SetChildMemoryState() unconditionally because it checks
396 // whether this state transition is valid. 395 // whether this state transition is valid.
397 for (auto& iter : children()) 396 for (auto& iter : children())
398 SetChildMemoryState(iter.first, mojo_state); 397 SetChildMemoryState(iter.first, current_state_);
399 } 398 }
400 399
401 void MemoryCoordinatorImpl::RecordStateChange(MemoryState prev_state, 400 void MemoryCoordinatorImpl::RecordStateChange(MemoryState prev_state,
402 MemoryState next_state, 401 MemoryState next_state,
403 base::TimeDelta duration) { 402 base::TimeDelta duration) {
404 size_t total_private_kb = 0; 403 size_t total_private_kb = 0;
405 404
406 // TODO(bashi): On MacOS we can't get process metrics for child processes and 405 // TODO(bashi): On MacOS we can't get process metrics for child processes and
407 // therefore can't calculate the total private memory. 406 // therefore can't calculate the total private memory.
408 #if !defined(OS_MACOSX) 407 #if !defined(OS_MACOSX)
(...skipping 20 matching lines...) Expand all
429 428
430 MemoryCoordinatorImpl::ChildInfo::ChildInfo() {} 429 MemoryCoordinatorImpl::ChildInfo::ChildInfo() {}
431 430
432 MemoryCoordinatorImpl::ChildInfo::ChildInfo(const ChildInfo& rhs) { 431 MemoryCoordinatorImpl::ChildInfo::ChildInfo(const ChildInfo& rhs) {
433 // This is a nop, but exists for compatibility with STL containers. 432 // This is a nop, but exists for compatibility with STL containers.
434 } 433 }
435 434
436 MemoryCoordinatorImpl::ChildInfo::~ChildInfo() {} 435 MemoryCoordinatorImpl::ChildInfo::~ChildInfo() {}
437 436
438 } // namespace content 437 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/memory/memory_coordinator_impl.h ('k') | content/browser/memory/memory_coordinator_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698