| 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;
|
| }
|
|
|