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

Side by Side Diff: content/browser/renderer_host/render_process_host_impl.cc

Issue 2929113002: Enable spare RenderProcessHost to be preinitialized. (Closed)
Patch Set: Add WarmupManager hook Created 3 years, 6 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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 // Represents the browser side of the browser <--> renderer communication 5 // Represents the browser side of the browser <--> renderer communication
6 // channel. There will be one RenderProcessHost per renderer process. 6 // channel. There will be one RenderProcessHost per renderer process.
7 7
8 #include "content/browser/renderer_host/render_process_host_impl.h" 8 #include "content/browser/renderer_host/render_process_host_impl.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 459
460 private: 460 private:
461 std::unique_ptr<std::map<int, SessionStorageNamespaceMap>> 461 std::unique_ptr<std::map<int, SessionStorageNamespaceMap>>
462 session_storage_namespaces_awaiting_close_; 462 session_storage_namespaces_awaiting_close_;
463 DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder); 463 DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder);
464 }; 464 };
465 465
466 const void* const kDefaultSubframeProcessHostHolderKey = 466 const void* const kDefaultSubframeProcessHostHolderKey =
467 &kDefaultSubframeProcessHostHolderKey; 467 &kDefaultSubframeProcessHostHolderKey;
468 468
469 // This class manages spare renderers.
470 class SpareRenderProcessHostManager {
471 public:
472 SpareRenderProcessHostManager() {}
473
474 void WarmupSpareRenderProcessHost(BrowserContext* browser_context) {
475 StoragePartitionImpl* current_partition =
476 static_cast<StoragePartitionImpl*>(
477 BrowserContext::GetStoragePartition(browser_context, nullptr));
478
479 if (spare_render_process_host_ &&
480 matching_browser_context_ == browser_context &&
481 matching_storage_partition_ == current_partition) {
482 return; // Nothing to warm up.
483 }
484
485 CleanupSpareRenderProcessHost();
486
487 matching_browser_context_ = browser_context;
488 matching_storage_partition_ = current_partition;
489 spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost(
490 browser_context, current_partition, false /* is_for_guests_only */);
491
492 spare_render_process_host_->Init();
493 }
494
495 RenderProcessHost* MaybeTakeSpareRenderProcessHost(
496 const BrowserContext* browser_context,
497 const StoragePartition* partition,
498 bool is_for_guests_only) {
499 if (!spare_render_process_host_ ||
500 browser_context != matching_browser_context_ ||
501 partition != matching_storage_partition_ || is_for_guests_only) {
502 // As a new RenderProcessHost will almost certainly be created, we cleanup
503 // the non-matching one so as not to waste resources.
504 CleanupSpareRenderProcessHost();
505 return nullptr;
506 }
507
508 if (!spare_render_process_host_->HasConnection()) {
509 CleanupSpareRenderProcessHost();
510 return nullptr;
511 }
512
513 RenderProcessHost* rph = spare_render_process_host_;
514 spare_render_process_host_ = nullptr;
515 return rph;
516 }
517
518 void OnStoragePartitionShutdown(StoragePartition* partition) {
519 if (partition == matching_storage_partition_) {
520 CleanupSpareRenderProcessHost();
521 }
522 }
523
524 private:
525 void CleanupSpareRenderProcessHost() {
526 if (spare_render_process_host_) {
527 spare_render_process_host_->Cleanup();
528 spare_render_process_host_ = nullptr;
529 }
530 }
531
532 // This is a bare pointer, because RenderProcessHost manages the lifetime of
533 // all its instances; see g_all_hosts, above.
534 RenderProcessHost* spare_render_process_host_;
535
536 // Used only to check if a creation request matches the
537 // spare, and not accessed.
538 const BrowserContext* matching_browser_context_ = nullptr;
539 const StoragePartition* matching_storage_partition_ = nullptr;
540
541 DISALLOW_COPY_AND_ASSIGN(SpareRenderProcessHostManager);
542 };
543
544 base::LazyInstance<SpareRenderProcessHostManager>::Leaky
545 g_spare_render_process_host_manager = LAZY_INSTANCE_INITIALIZER;
546
469 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, 547 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data,
470 public RenderProcessHostObserver { 548 public RenderProcessHostObserver {
471 public: 549 public:
472 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) 550 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context)
473 : browser_context_(browser_context) {} 551 : browser_context_(browser_context) {}
474 ~DefaultSubframeProcessHostHolder() override {} 552 ~DefaultSubframeProcessHostHolder() override {}
475 553
476 // Gets the correct render process to use for this SiteInstance. 554 // Gets the correct render process to use for this SiteInstance.
477 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, 555 RenderProcessHost* GetProcessHost(SiteInstance* site_instance,
478 bool is_for_guests_only) { 556 bool is_for_guests_only) {
479 StoragePartition* default_partition = 557 StoragePartition* default_partition =
480 BrowserContext::GetDefaultStoragePartition(browser_context_); 558 BrowserContext::GetDefaultStoragePartition(browser_context_);
481 StoragePartition* partition = 559 StoragePartition* partition =
482 BrowserContext::GetStoragePartition(browser_context_, site_instance); 560 BrowserContext::GetStoragePartition(browser_context_, site_instance);
483 561
484 // Is this the default storage partition? If it isn't, then just give it its 562 // Is this the default storage partition? If it isn't, then just give it its
485 // own non-shared process. 563 // own non-shared process.
486 if (partition != default_partition || is_for_guests_only) { 564 if (partition != default_partition || is_for_guests_only) {
487 RenderProcessHostImpl* host = new RenderProcessHostImpl( 565 RenderProcessHost* host = RenderProcessHostImpl::CreateRenderProcessHost(
488 browser_context_, static_cast<StoragePartitionImpl*>(partition), 566 browser_context_, static_cast<StoragePartitionImpl*>(partition),
489 is_for_guests_only); 567 is_for_guests_only);
490 host->SetIsNeverSuitableForReuse(); 568 host->SetIsNeverSuitableForReuse();
491 return host; 569 return host;
492 } 570 }
493 571
494 // If we already have a shared host for the default storage partition, use 572 // If we already have a shared host for the default storage partition, use
495 // it. 573 // it.
496 if (host_) 574 if (host_)
497 return host_; 575 return host_;
498 576
499 host_ = new RenderProcessHostImpl( 577 host_ =
578 g_spare_render_process_host_manager.Get()
579 .MaybeTakeSpareRenderProcessHost(browser_context_, partition,
580 false /* is for guests only */);
581
582 host_ = RenderProcessHostImpl::CreateRenderProcessHost(
500 browser_context_, static_cast<StoragePartitionImpl*>(partition), 583 browser_context_, static_cast<StoragePartitionImpl*>(partition),
501 false /* for guests only */); 584 false /* for guests only */);
502 host_->SetIsNeverSuitableForReuse(); 585 host_->SetIsNeverSuitableForReuse();
503 host_->AddObserver(this); 586 host_->AddObserver(this);
504 587
505 return host_; 588 return host_;
506 } 589 }
507 590
508 // Implementation of RenderProcessHostObserver. 591 // Implementation of RenderProcessHostObserver.
509 void RenderProcessHostDestroyed(RenderProcessHost* host) override { 592 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
510 DCHECK_EQ(host_, host); 593 DCHECK_EQ(host_, host);
511 host_->RemoveObserver(this); 594 host_->RemoveObserver(this);
512 host_ = nullptr; 595 host_ = nullptr;
513 } 596 }
514 597
515 private: 598 private:
516 BrowserContext* browser_context_; 599 BrowserContext* browser_context_;
517 600
518 // The default subframe render process used for the default storage partition 601 // The default subframe render process used for the default storage partition
519 // of this BrowserContext. 602 // of this BrowserContext.
520 RenderProcessHostImpl* host_ = nullptr; 603 RenderProcessHost* host_ = nullptr;
521 }; 604 };
522 605
523 void CreateMemoryCoordinatorHandle( 606 void CreateMemoryCoordinatorHandle(
524 int render_process_id, 607 int render_process_id,
525 const service_manager::BindSourceInfo& source_info, 608 const service_manager::BindSourceInfo& source_info,
526 mojom::MemoryCoordinatorHandleRequest request) { 609 mojom::MemoryCoordinatorHandleRequest request) {
527 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, 610 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id,
528 std::move(request)); 611 std::move(request));
529 } 612 }
530 613
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 max_count = std::min(max_count, kMaxRendererProcessCount); 984 max_count = std::min(max_count, kMaxRendererProcessCount);
902 } 985 }
903 return max_count; 986 return max_count;
904 } 987 }
905 988
906 // static 989 // static
907 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { 990 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
908 g_max_renderer_count_override = count; 991 g_max_renderer_count_override = count;
909 } 992 }
910 993
994 // static
995 RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost(
996 BrowserContext* browser_context,
997 StoragePartitionImpl* storage_partition_impl,
998 bool is_for_guests_only) {
999 if (g_render_process_host_factory_) {
1000 return g_render_process_host_factory_->CreateRenderProcessHost(
1001 browser_context);
1002 }
1003
1004 return new RenderProcessHostImpl(browser_context, storage_partition_impl,
1005 is_for_guests_only);
1006 }
1007
911 RenderProcessHostImpl::RenderProcessHostImpl( 1008 RenderProcessHostImpl::RenderProcessHostImpl(
912 BrowserContext* browser_context, 1009 BrowserContext* browser_context,
913 StoragePartitionImpl* storage_partition_impl, 1010 StoragePartitionImpl* storage_partition_impl,
914 bool is_for_guests_only) 1011 bool is_for_guests_only)
915 : fast_shutdown_started_(false), 1012 : fast_shutdown_started_(false),
916 deleting_soon_(false), 1013 deleting_soon_(false),
917 #ifndef NDEBUG 1014 #ifndef NDEBUG
918 is_self_deleted_(false), 1015 is_self_deleted_(false),
919 #endif 1016 #endif
920 pending_views_(0), 1017 pending_views_(0),
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( 2069 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1973 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); 2070 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1974 if (!tracker) { 2071 if (!tracker) {
1975 tracker = new SiteProcessCountTracker(); 2072 tracker = new SiteProcessCountTracker();
1976 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, 2073 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1977 base::WrapUnique(tracker)); 2074 base::WrapUnique(tracker));
1978 } 2075 }
1979 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); 2076 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1980 } 2077 }
1981 2078
2079 // static
2080 void RenderProcessHostImpl::OnStoragePartitionShutdown(
2081 StoragePartition* partition) {
2082 g_spare_render_process_host_manager.Get().OnStoragePartitionShutdown(
2083 partition);
2084 }
2085
1982 bool RenderProcessHostImpl::IsForGuestsOnly() const { 2086 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1983 return is_for_guests_only_; 2087 return is_for_guests_only_;
1984 } 2088 }
1985 2089
1986 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 2090 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1987 return storage_partition_impl_; 2091 return storage_partition_impl_;
1988 } 2092 }
1989 2093
1990 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 2094 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1991 command_line->AppendSwitchASCII( 2095 command_line->AppendSwitchASCII(
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
2912 host->GetID()) != 3016 host->GetID()) !=
2913 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( 3017 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
2914 browser_context, site_url)) { 3018 browser_context, site_url)) {
2915 return false; 3019 return false;
2916 } 3020 }
2917 3021
2918 return GetContentClient()->browser()->IsSuitableHost(host, site_url); 3022 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
2919 } 3023 }
2920 3024
2921 // static 3025 // static
3026 void RenderProcessHost::WarmupSpareRenderProcessHost(
3027 content::BrowserContext* browser_context) {
3028 g_spare_render_process_host_manager.Get().WarmupSpareRenderProcessHost(
3029 browser_context);
3030 }
3031
3032 // static
2922 bool RenderProcessHost::run_renderer_in_process() { 3033 bool RenderProcessHost::run_renderer_in_process() {
2923 return g_run_renderer_in_process_; 3034 return g_run_renderer_in_process_;
2924 } 3035 }
2925 3036
2926 // static 3037 // static
2927 void RenderProcessHost::SetRunRendererInProcess(bool value) { 3038 void RenderProcessHost::SetRunRendererInProcess(bool value) {
2928 g_run_renderer_in_process_ = value; 3039 g_run_renderer_in_process_ = value;
2929 3040
2930 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 3041 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
2931 if (value) { 3042 if (value) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3107 default: 3218 default:
3108 break; 3219 break;
3109 } 3220 }
3110 3221
3111 // If not (or if none found), see if we should reuse an existing process. 3222 // If not (or if none found), see if we should reuse an existing process.
3112 if (!render_process_host && 3223 if (!render_process_host &&
3113 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3224 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
3114 render_process_host = GetExistingProcessHost(browser_context, site_url); 3225 render_process_host = GetExistingProcessHost(browser_context, site_url);
3115 } 3226 }
3116 3227
3228 // Try to use a spare process if one is found.
3229 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
3230 BrowserContext::GetStoragePartition(browser_context, site_instance));
3231 if (!render_process_host) {
3232 render_process_host =
3233 g_spare_render_process_host_manager.Get()
3234 .MaybeTakeSpareRenderProcessHost(browser_context, partition,
3235 is_for_guests_only);
3236 }
3237
3117 // Otherwise (or if that fails), create a new one. 3238 // Otherwise (or if that fails), create a new one.
3118 if (!render_process_host) { 3239 if (!render_process_host) {
3119 if (g_render_process_host_factory_) { 3240 render_process_host =
3120 render_process_host = 3241 CreateRenderProcessHost(browser_context, partition, is_for_guests_only);
3121 g_render_process_host_factory_->CreateRenderProcessHost(
3122 browser_context);
3123 } else {
3124 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
3125 BrowserContext::GetStoragePartition(browser_context, site_instance));
3126 render_process_host = new RenderProcessHostImpl(
3127 browser_context, partition, is_for_guests_only);
3128 }
3129 } 3242 }
3130 return render_process_host; 3243 return render_process_host;
3131 } 3244 }
3132 3245
3133 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { 3246 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() {
3134 // Create a persistent memory segment for renderer histograms only if 3247 // Create a persistent memory segment for renderer histograms only if
3135 // they're active in the browser. 3248 // they're active in the browser.
3136 if (!base::GlobalHistogramAllocator::Get()) 3249 if (!base::GlobalHistogramAllocator::Get())
3137 return; 3250 return;
3138 3251
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3626 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3739 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3627 3740
3628 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3741 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3629 // Capture the error message in a crash key value. 3742 // Capture the error message in a crash key value.
3630 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3743 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3631 bad_message::ReceivedBadMessage(render_process_id, 3744 bad_message::ReceivedBadMessage(render_process_id,
3632 bad_message::RPH_MOJO_PROCESS_ERROR); 3745 bad_message::RPH_MOJO_PROCESS_ERROR);
3633 } 3746 }
3634 3747
3635 } // namespace content 3748 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698