| Index: content/browser/renderer_host/renderer_frame_manager.cc | 
| diff --git a/content/browser/renderer_host/renderer_frame_manager.cc b/content/browser/renderer_host/renderer_frame_manager.cc | 
| index 1eff47d67da952fffeb99c36110470cc732fd921..a05a92c3f59c595f9cec9808ebb7946e4001f4d5 100644 | 
| --- a/content/browser/renderer_host/renderer_frame_manager.cc | 
| +++ b/content/browser/renderer_host/renderer_frame_manager.cc | 
| @@ -8,12 +8,15 @@ | 
|  | 
| #include "base/bind.h" | 
| #include "base/logging.h" | 
| +#include "base/memory/memory_coordinator_client_registry.h" | 
| +#include "base/memory/memory_coordinator_proxy.h" | 
| #include "base/memory/memory_pressure_listener.h" | 
| #include "base/memory/memory_pressure_monitor.h" | 
| #include "base/memory/shared_memory.h" | 
| #include "base/sys_info.h" | 
| #include "build/build_config.h" | 
| #include "content/common/host_shared_bitmap_manager.h" | 
| +#include "content/public/common/content_features.h" | 
|  | 
| namespace content { | 
| namespace { | 
| @@ -72,35 +75,50 @@ void RendererFrameManager::UnlockFrame(RendererFrameManagerClient* frame) { | 
| } | 
|  | 
| size_t RendererFrameManager::GetMaxNumberOfSavedFrames() const { | 
| -  base::MemoryPressureMonitor* monitor = base::MemoryPressureMonitor::Get(); | 
| - | 
| -  if (!monitor) | 
| -    return max_number_of_saved_frames_; | 
| - | 
| -  // Until we have a global OnMemoryPressureChanged event we need to query the | 
| -  // value from our specific pressure monitor. | 
| int percentage = 100; | 
| -  switch (monitor->GetCurrentPressureLevel()) { | 
| -    case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: | 
| -      percentage = 100; | 
| -      break; | 
| -    case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: | 
| -      percentage = kModeratePressurePercentage; | 
| -      break; | 
| -    case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: | 
| -      percentage = kCriticalPressurePercentage; | 
| -      break; | 
| +  if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) { | 
| +    switch (base::MemoryCoordinatorProxy::GetInstance()-> | 
| +            GetCurrentMemoryState()) { | 
| +      case base::MemoryState::NORMAL: | 
| +        percentage = 100; | 
| +        break; | 
| +      case base::MemoryState::THROTTLED: | 
| +        percentage = kCriticalPressurePercentage; | 
| +        break; | 
| +      case base::MemoryState::SUSPENDED: | 
| +      case base::MemoryState::UNKNOWN: | 
| +        NOTREACHED(); | 
| +        break; | 
| +    } | 
| +  } else { | 
| +    base::MemoryPressureMonitor* monitor = base::MemoryPressureMonitor::Get(); | 
| + | 
| +    if (!monitor) | 
| +      return max_number_of_saved_frames_; | 
| + | 
| +    // Until we have a global OnMemoryPressureChanged event we need to query the | 
| +    // value from our specific pressure monitor. | 
| +    switch (monitor->GetCurrentPressureLevel()) { | 
| +      case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: | 
| +        percentage = 100; | 
| +        break; | 
| +      case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: | 
| +        percentage = kModeratePressurePercentage; | 
| +        break; | 
| +      case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: | 
| +        percentage = kCriticalPressurePercentage; | 
| +        break; | 
| +    } | 
| } | 
| size_t frames = (max_number_of_saved_frames_ * percentage) / 100; | 
| return std::max(static_cast<size_t>(1), frames); | 
| } | 
|  | 
| RendererFrameManager::RendererFrameManager() | 
| -    : memory_pressure_listener_( | 
| +  : memory_pressure_listener_(new base::MemoryPressureListener( | 
| base::Bind(&RendererFrameManager::OnMemoryPressure, | 
| -                   base::Unretained(this))) { | 
| -  // Note: With the destruction of this class the |memory_pressure_listener_| | 
| -  // gets destroyed and the observer will remove itself. | 
| +                   base::Unretained(this)))) { | 
| +  base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | 
| max_number_of_saved_frames_ = | 
| #if defined(OS_ANDROID) | 
| // If the amount of memory on the device is >= 3.5 GB, save up to 5 | 
| @@ -136,21 +154,40 @@ void RendererFrameManager::CullUnlockedFrames(size_t saved_frame_limit) { | 
|  | 
| void RendererFrameManager::OnMemoryPressure( | 
| base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { | 
| -  int saved_frame_limit = max_number_of_saved_frames_; | 
| -  if (saved_frame_limit <= 1) | 
| -    return; | 
| -  int percentage = 100; | 
| switch (memory_pressure_level) { | 
| case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: | 
| -      percentage = kModeratePressurePercentage; | 
| +      PurgeMemory(kModeratePressurePercentage); | 
| break; | 
| case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: | 
| -      percentage = kCriticalPressurePercentage; | 
| +      PurgeMemory(kCriticalPressurePercentage); | 
| break; | 
| case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: | 
| // No need to change anything when there is no pressure. | 
| return; | 
| } | 
| +} | 
| + | 
| +void RendererFrameManager::OnMemoryStateChange(base::MemoryState state) { | 
| +  switch (state) { | 
| +    case base::MemoryState::NORMAL: | 
| +      // It is not necessary to purge here. | 
| +      break; | 
| +    case base::MemoryState::THROTTLED: | 
| +      PurgeMemory(kCriticalPressurePercentage); | 
| +      break; | 
| +    case base::MemoryState::SUSPENDED: | 
| +      // Note that SUSPENDED never occurs in the main browser process so far. | 
| +      // Fall through. | 
| +    case base::MemoryState::UNKNOWN: | 
| +      NOTREACHED(); | 
| +      break; | 
| +  } | 
| +} | 
| + | 
| +void RendererFrameManager::PurgeMemory(int percentage) { | 
| +  int saved_frame_limit = max_number_of_saved_frames_; | 
| +  if (saved_frame_limit <= 1) | 
| +    return; | 
| CullUnlockedFrames(std::max(1, (saved_frame_limit * percentage) / 100)); | 
| } | 
|  | 
|  |