| Index: content/browser/renderer_host/render_process_host_impl.cc | 
| diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc | 
| index 247a15ffd9ea2c5f4b22a52000eda7eebb61f332..7e5dd21e2cc0f7cbd6b23b51eba820215a5bed76 100644 | 
| --- a/content/browser/renderer_host/render_process_host_impl.cc | 
| +++ b/content/browser/renderer_host/render_process_host_impl.cc | 
| @@ -466,6 +466,84 @@ class SessionStorageHolder : public base::SupportsUserData::Data { | 
| const void* const kDefaultSubframeProcessHostHolderKey = | 
| &kDefaultSubframeProcessHostHolderKey; | 
|  | 
| +// This class manages spare renderers. | 
| +class SpareRenderProcessHostManager { | 
| + public: | 
| +  SpareRenderProcessHostManager() {} | 
| + | 
| +  void WarmupSpareRenderProcessHost(BrowserContext* browser_context) { | 
| +    StoragePartitionImpl* current_partition = | 
| +        static_cast<StoragePartitionImpl*>( | 
| +            BrowserContext::GetStoragePartition(browser_context, nullptr)); | 
| + | 
| +    if (spare_render_process_host_ && | 
| +        matching_browser_context_ == browser_context && | 
| +        matching_storage_partition_ == current_partition) { | 
| +      return;  // Nothing to warm up. | 
| +    } | 
| + | 
| +    CleanupSpareRenderProcessHost(); | 
| + | 
| +    matching_browser_context_ = browser_context; | 
| +    matching_storage_partition_ = current_partition; | 
| +    spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost( | 
| +        browser_context, current_partition, false /* is_for_guests_only */); | 
| + | 
| +    spare_render_process_host_->Init(); | 
| +  } | 
| + | 
| +  RenderProcessHost* MaybeTakeSpareRenderProcessHost( | 
| +      const BrowserContext* browser_context, | 
| +      const StoragePartition* partition, | 
| +      bool is_for_guests_only) { | 
| +    if (!spare_render_process_host_ || | 
| +        browser_context != matching_browser_context_ || | 
| +        partition != matching_storage_partition_ || is_for_guests_only) { | 
| +      // As a new RenderProcessHost will almost certainly be created, we cleanup | 
| +      // the non-matching one so as not to waste resources. | 
| +      CleanupSpareRenderProcessHost(); | 
| +      return nullptr; | 
| +    } | 
| + | 
| +    if (!spare_render_process_host_->HasConnection()) { | 
| +      CleanupSpareRenderProcessHost(); | 
| +      return nullptr; | 
| +    } | 
| + | 
| +    RenderProcessHost* rph = spare_render_process_host_; | 
| +    spare_render_process_host_ = nullptr; | 
| +    return rph; | 
| +  } | 
| + | 
| +  void OnStoragePartitionShutdown(StoragePartition* partition) { | 
| +    if (partition == matching_storage_partition_) { | 
| +      CleanupSpareRenderProcessHost(); | 
| +    } | 
| +  } | 
| + | 
| + private: | 
| +  void CleanupSpareRenderProcessHost() { | 
| +    if (spare_render_process_host_) { | 
| +      spare_render_process_host_->Cleanup(); | 
| +      spare_render_process_host_ = nullptr; | 
| +    } | 
| +  } | 
| + | 
| +  // This is a bare pointer, because RenderProcessHost manages the lifetime of | 
| +  // all its instances; see g_all_hosts, above. | 
| +  RenderProcessHost* spare_render_process_host_; | 
| + | 
| +  // Used only to check if a creation request matches the | 
| +  // spare, and not accessed. | 
| +  const BrowserContext* matching_browser_context_ = nullptr; | 
| +  const StoragePartition* matching_storage_partition_ = nullptr; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(SpareRenderProcessHostManager); | 
| +}; | 
| + | 
| +base::LazyInstance<SpareRenderProcessHostManager>::Leaky | 
| +    g_spare_render_process_host_manager = LAZY_INSTANCE_INITIALIZER; | 
| + | 
| class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | 
| public RenderProcessHostObserver { | 
| public: | 
| @@ -484,7 +562,7 @@ class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | 
| // Is this the default storage partition? If it isn't, then just give it its | 
| // own non-shared process. | 
| if (partition != default_partition || is_for_guests_only) { | 
| -      RenderProcessHostImpl* host = new RenderProcessHostImpl( | 
| +      RenderProcessHost* host = RenderProcessHostImpl::CreateRenderProcessHost( | 
| browser_context_, static_cast<StoragePartitionImpl*>(partition), | 
| is_for_guests_only); | 
| host->SetIsNeverSuitableForReuse(); | 
| @@ -496,7 +574,12 @@ class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | 
| if (host_) | 
| return host_; | 
|  | 
| -    host_ = new RenderProcessHostImpl( | 
| +    host_ = | 
| +        g_spare_render_process_host_manager.Get() | 
| +            .MaybeTakeSpareRenderProcessHost(browser_context_, partition, | 
| +                                             false /* is for guests only */); | 
| + | 
| +    host_ = RenderProcessHostImpl::CreateRenderProcessHost( | 
| browser_context_, static_cast<StoragePartitionImpl*>(partition), | 
| false /* for guests only */); | 
| host_->SetIsNeverSuitableForReuse(); | 
| @@ -517,7 +600,7 @@ class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | 
|  | 
| // The default subframe render process used for the default storage partition | 
| // of this BrowserContext. | 
| -  RenderProcessHostImpl* host_ = nullptr; | 
| +  RenderProcessHost* host_ = nullptr; | 
| }; | 
|  | 
| void CreateMemoryCoordinatorHandle( | 
| @@ -908,6 +991,20 @@ void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { | 
| g_max_renderer_count_override = count; | 
| } | 
|  | 
| +// static | 
| +RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost( | 
| +    BrowserContext* browser_context, | 
| +    StoragePartitionImpl* storage_partition_impl, | 
| +    bool is_for_guests_only) { | 
| +  if (g_render_process_host_factory_) { | 
| +    return g_render_process_host_factory_->CreateRenderProcessHost( | 
| +        browser_context); | 
| +  } | 
| + | 
| +  return new RenderProcessHostImpl(browser_context, storage_partition_impl, | 
| +                                   is_for_guests_only); | 
| +} | 
| + | 
| RenderProcessHostImpl::RenderProcessHostImpl( | 
| BrowserContext* browser_context, | 
| StoragePartitionImpl* storage_partition_impl, | 
| @@ -1979,6 +2076,13 @@ void RenderProcessHostImpl::RemoveExpectedNavigationToSite( | 
| tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); | 
| } | 
|  | 
| +// static | 
| +void RenderProcessHostImpl::OnStoragePartitionShutdown( | 
| +    StoragePartition* partition) { | 
| +  g_spare_render_process_host_manager.Get().OnStoragePartitionShutdown( | 
| +      partition); | 
| +} | 
| + | 
| bool RenderProcessHostImpl::IsForGuestsOnly() const { | 
| return is_for_guests_only_; | 
| } | 
| @@ -2918,6 +3022,13 @@ bool RenderProcessHostImpl::IsSuitableHost(RenderProcessHost* host, | 
| return GetContentClient()->browser()->IsSuitableHost(host, site_url); | 
| } | 
|  | 
| +// static | 
| +void RenderProcessHost::WarmupSpareRenderProcessHost( | 
| +    content::BrowserContext* browser_context) { | 
| +  g_spare_render_process_host_manager.Get().WarmupSpareRenderProcessHost( | 
| +      browser_context); | 
| +} | 
| + | 
| // static | 
| bool RenderProcessHost::run_renderer_in_process() { | 
| return g_run_renderer_in_process_; | 
| @@ -3114,18 +3225,20 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance( | 
| render_process_host = GetExistingProcessHost(browser_context, site_url); | 
| } | 
|  | 
| +  // Try to use a spare process if one is found. | 
| +  StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( | 
| +      BrowserContext::GetStoragePartition(browser_context, site_instance)); | 
| +  if (!render_process_host) { | 
| +    render_process_host = | 
| +        g_spare_render_process_host_manager.Get() | 
| +            .MaybeTakeSpareRenderProcessHost(browser_context, partition, | 
| +                                             is_for_guests_only); | 
| +  } | 
| + | 
| // Otherwise (or if that fails), create a new one. | 
| if (!render_process_host) { | 
| -    if (g_render_process_host_factory_) { | 
| -      render_process_host = | 
| -          g_render_process_host_factory_->CreateRenderProcessHost( | 
| -              browser_context); | 
| -    } else { | 
| -      StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( | 
| -          BrowserContext::GetStoragePartition(browser_context, site_instance)); | 
| -      render_process_host = new RenderProcessHostImpl( | 
| -          browser_context, partition, is_for_guests_only); | 
| -    } | 
| +    render_process_host = | 
| +        CreateRenderProcessHost(browser_context, partition, is_for_guests_only); | 
| } | 
| return render_process_host; | 
| } | 
|  |