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

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

Issue 2929113002: Enable spare RenderProcessHost to be preinitialized. (Closed)
Patch Set: browsertests 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 RenderProcessHosts.
470 class SpareRenderProcessHostManager : public RenderProcessHostObserver {
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
490 spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost(
491 browser_context, current_partition, false /* is_for_guests_only */);
492 spare_render_process_host_->AddObserver(this);
493 spare_render_process_host_->Init();
494 }
495
496 RenderProcessHost* MaybeTakeSpareRenderProcessHost(
497 const BrowserContext* browser_context,
498 const StoragePartition* partition,
499 bool is_for_guests_only) {
500 if (!spare_render_process_host_ ||
501 browser_context != matching_browser_context_ ||
502 partition != matching_storage_partition_ || is_for_guests_only) {
503 // As a new RenderProcessHost will almost certainly be created, we cleanup
504 // the non-matching one so as not to waste resources.
505 CleanupSpareRenderProcessHost();
506 return nullptr;
507 }
508
509 RenderProcessHost* rph = spare_render_process_host_;
510 spare_render_process_host_ = nullptr;
511 return rph;
Benoit L 2017/06/19 11:30:35 Shouldn't we stop observing the RenderProcessHost
mattcary 2017/06/19 12:55:10 Good point, thanks.
512 }
513
514 void OnStoragePartitionShutdown(StoragePartition* partition) {
515 if (partition == matching_storage_partition_) {
516 CleanupSpareRenderProcessHost();
517 }
518 }
519
520 RenderProcessHost* spare_render_process_host() {
521 return spare_render_process_host_;
522 }
523
524 private:
525 // RenderProcessHostObserver
526 void RenderProcessWillExit(RenderProcessHost* host) override {
527 DropSpareRenderProcessHost(host);
528 }
529
530 void RenderProcessExited(RenderProcessHost* host,
531 base::TerminationStatus unused_status,
532 int unused_exit_code) override {
533 DropSpareRenderProcessHost(host);
534 }
535
536 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
537 DropSpareRenderProcessHost(host);
538 }
539
540 void CleanupSpareRenderProcessHost() {
541 if (spare_render_process_host_) {
542 spare_render_process_host_->Cleanup();
543 DropSpareRenderProcessHost(spare_render_process_host_);
544 }
545 }
546
547 // Remove |host| as a possible spare renderer. Does not shut it down cleanly,
548 // the assumption is that the host has been shutdown somewhere else and has
549 // notifying the SpareRenderProcessHostManager.
550 void DropSpareRenderProcessHost(RenderProcessHost* host) {
551 if (host && host == spare_render_process_host_) {
552 spare_render_process_host_->RemoveObserver(this);
553 spare_render_process_host_ = nullptr;
554 }
555 }
556
557 // This is a bare pointer, because RenderProcessHost manages the lifetime of
558 // all its instances; see g_all_hosts, above.
559 RenderProcessHost* spare_render_process_host_;
560
561 // Used only to check if a creation request matches the
562 // spare, and not accessed.
563 const BrowserContext* matching_browser_context_ = nullptr;
564 const StoragePartition* matching_storage_partition_ = nullptr;
565
566 DISALLOW_COPY_AND_ASSIGN(SpareRenderProcessHostManager);
567 };
568
569 base::LazyInstance<SpareRenderProcessHostManager>::Leaky
570 g_spare_render_process_host_manager = LAZY_INSTANCE_INITIALIZER;
571
469 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, 572 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data,
470 public RenderProcessHostObserver { 573 public RenderProcessHostObserver {
471 public: 574 public:
472 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) 575 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context)
473 : browser_context_(browser_context) {} 576 : browser_context_(browser_context) {}
474 ~DefaultSubframeProcessHostHolder() override {} 577 ~DefaultSubframeProcessHostHolder() override {}
475 578
476 // Gets the correct render process to use for this SiteInstance. 579 // Gets the correct render process to use for this SiteInstance.
477 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, 580 RenderProcessHost* GetProcessHost(SiteInstance* site_instance,
478 bool is_for_guests_only) { 581 bool is_for_guests_only) {
479 StoragePartition* default_partition = 582 StoragePartition* default_partition =
480 BrowserContext::GetDefaultStoragePartition(browser_context_); 583 BrowserContext::GetDefaultStoragePartition(browser_context_);
481 StoragePartition* partition = 584 StoragePartition* partition =
482 BrowserContext::GetStoragePartition(browser_context_, site_instance); 585 BrowserContext::GetStoragePartition(browser_context_, site_instance);
483 586
484 // Is this the default storage partition? If it isn't, then just give it its 587 // Is this the default storage partition? If it isn't, then just give it its
485 // own non-shared process. 588 // own non-shared process.
486 if (partition != default_partition || is_for_guests_only) { 589 if (partition != default_partition || is_for_guests_only) {
487 RenderProcessHostImpl* host = new RenderProcessHostImpl( 590 RenderProcessHost* host = RenderProcessHostImpl::CreateRenderProcessHost(
488 browser_context_, static_cast<StoragePartitionImpl*>(partition), 591 browser_context_, static_cast<StoragePartitionImpl*>(partition),
489 is_for_guests_only); 592 is_for_guests_only);
490 host->SetIsNeverSuitableForReuse(); 593 host->SetIsNeverSuitableForReuse();
491 return host; 594 return host;
492 } 595 }
493 596
494 // If we already have a shared host for the default storage partition, use 597 // If we already have a shared host for the default storage partition, use
495 // it. 598 // it.
496 if (host_) 599 if (host_)
497 return host_; 600 return host_;
498 601
499 host_ = new RenderProcessHostImpl( 602 host_ =
603 g_spare_render_process_host_manager.Get()
604 .MaybeTakeSpareRenderProcessHost(browser_context_, partition,
605 false /* is for guests only */);
606
607 host_ = RenderProcessHostImpl::CreateRenderProcessHost(
500 browser_context_, static_cast<StoragePartitionImpl*>(partition), 608 browser_context_, static_cast<StoragePartitionImpl*>(partition),
501 false /* for guests only */); 609 false /* for guests only */);
502 host_->SetIsNeverSuitableForReuse(); 610 host_->SetIsNeverSuitableForReuse();
503 host_->AddObserver(this); 611 host_->AddObserver(this);
504 612
505 return host_; 613 return host_;
506 } 614 }
507 615
508 // Implementation of RenderProcessHostObserver. 616 // Implementation of RenderProcessHostObserver.
509 void RenderProcessHostDestroyed(RenderProcessHost* host) override { 617 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
510 DCHECK_EQ(host_, host); 618 DCHECK_EQ(host_, host);
511 host_->RemoveObserver(this); 619 host_->RemoveObserver(this);
512 host_ = nullptr; 620 host_ = nullptr;
513 } 621 }
514 622
515 private: 623 private:
516 BrowserContext* browser_context_; 624 BrowserContext* browser_context_;
517 625
518 // The default subframe render process used for the default storage partition 626 // The default subframe render process used for the default storage partition
519 // of this BrowserContext. 627 // of this BrowserContext.
520 RenderProcessHostImpl* host_ = nullptr; 628 RenderProcessHost* host_ = nullptr;
521 }; 629 };
522 630
523 void CreateMemoryCoordinatorHandle( 631 void CreateMemoryCoordinatorHandle(
524 int render_process_id, 632 int render_process_id,
525 const service_manager::BindSourceInfo& source_info, 633 const service_manager::BindSourceInfo& source_info,
526 mojom::MemoryCoordinatorHandleRequest request) { 634 mojom::MemoryCoordinatorHandleRequest request) {
527 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, 635 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id,
528 std::move(request)); 636 std::move(request));
529 } 637 }
530 638
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 max_count = std::min(max_count, kMaxRendererProcessCount); 1009 max_count = std::min(max_count, kMaxRendererProcessCount);
902 } 1010 }
903 return max_count; 1011 return max_count;
904 } 1012 }
905 1013
906 // static 1014 // static
907 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { 1015 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
908 g_max_renderer_count_override = count; 1016 g_max_renderer_count_override = count;
909 } 1017 }
910 1018
1019 // static
1020 RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost(
1021 BrowserContext* browser_context,
1022 StoragePartitionImpl* storage_partition_impl,
1023 bool is_for_guests_only) {
1024 if (g_render_process_host_factory_) {
1025 return g_render_process_host_factory_->CreateRenderProcessHost(
1026 browser_context);
1027 }
1028
1029 return new RenderProcessHostImpl(browser_context, storage_partition_impl,
1030 is_for_guests_only);
1031 }
1032
911 RenderProcessHostImpl::RenderProcessHostImpl( 1033 RenderProcessHostImpl::RenderProcessHostImpl(
912 BrowserContext* browser_context, 1034 BrowserContext* browser_context,
913 StoragePartitionImpl* storage_partition_impl, 1035 StoragePartitionImpl* storage_partition_impl,
914 bool is_for_guests_only) 1036 bool is_for_guests_only)
915 : fast_shutdown_started_(false), 1037 : fast_shutdown_started_(false),
916 deleting_soon_(false), 1038 deleting_soon_(false),
917 #ifndef NDEBUG 1039 #ifndef NDEBUG
918 is_self_deleted_(false), 1040 is_self_deleted_(false),
919 #endif 1041 #endif
920 pending_views_(0), 1042 pending_views_(0),
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( 2094 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1973 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); 2095 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1974 if (!tracker) { 2096 if (!tracker) {
1975 tracker = new SiteProcessCountTracker(); 2097 tracker = new SiteProcessCountTracker();
1976 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, 2098 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1977 base::WrapUnique(tracker)); 2099 base::WrapUnique(tracker));
1978 } 2100 }
1979 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); 2101 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1980 } 2102 }
1981 2103
2104 // static
2105 void RenderProcessHostImpl::OnStoragePartitionShutdown(
2106 StoragePartition* partition) {
2107 g_spare_render_process_host_manager.Get().OnStoragePartitionShutdown(
2108 partition);
2109 }
2110
2111 // static
2112 RenderProcessHost*
2113 RenderProcessHostImpl::GetSpareRenderProcessHostForTesting() {
2114 return g_spare_render_process_host_manager.Get().spare_render_process_host();
2115 }
2116
1982 bool RenderProcessHostImpl::IsForGuestsOnly() const { 2117 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1983 return is_for_guests_only_; 2118 return is_for_guests_only_;
1984 } 2119 }
1985 2120
1986 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 2121 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1987 return storage_partition_impl_; 2122 return storage_partition_impl_;
1988 } 2123 }
1989 2124
1990 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 2125 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1991 command_line->AppendSwitchASCII( 2126 command_line->AppendSwitchASCII(
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
2912 host->GetID()) != 3047 host->GetID()) !=
2913 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( 3048 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
2914 browser_context, site_url)) { 3049 browser_context, site_url)) {
2915 return false; 3050 return false;
2916 } 3051 }
2917 3052
2918 return GetContentClient()->browser()->IsSuitableHost(host, site_url); 3053 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
2919 } 3054 }
2920 3055
2921 // static 3056 // static
3057 void RenderProcessHost::WarmupSpareRenderProcessHost(
3058 content::BrowserContext* browser_context) {
3059 g_spare_render_process_host_manager.Get().WarmupSpareRenderProcessHost(
3060 browser_context);
3061 }
3062
3063 // static
2922 bool RenderProcessHost::run_renderer_in_process() { 3064 bool RenderProcessHost::run_renderer_in_process() {
2923 return g_run_renderer_in_process_; 3065 return g_run_renderer_in_process_;
2924 } 3066 }
2925 3067
2926 // static 3068 // static
2927 void RenderProcessHost::SetRunRendererInProcess(bool value) { 3069 void RenderProcessHost::SetRunRendererInProcess(bool value) {
2928 g_run_renderer_in_process_ = value; 3070 g_run_renderer_in_process_ = value;
2929 3071
2930 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 3072 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
2931 if (value) { 3073 if (value) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3107 default: 3249 default:
3108 break; 3250 break;
3109 } 3251 }
3110 3252
3111 // If not (or if none found), see if we should reuse an existing process. 3253 // If not (or if none found), see if we should reuse an existing process.
3112 if (!render_process_host && 3254 if (!render_process_host &&
3113 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3255 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
3114 render_process_host = GetExistingProcessHost(browser_context, site_url); 3256 render_process_host = GetExistingProcessHost(browser_context, site_url);
3115 } 3257 }
3116 3258
3259 // Try to use a spare process if one is found.
3260 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
3261 BrowserContext::GetStoragePartition(browser_context, site_instance));
3262 if (!render_process_host) {
3263 render_process_host =
3264 g_spare_render_process_host_manager.Get()
3265 .MaybeTakeSpareRenderProcessHost(browser_context, partition,
3266 is_for_guests_only);
3267 }
3268
3117 // Otherwise (or if that fails), create a new one. 3269 // Otherwise (or if that fails), create a new one.
3118 if (!render_process_host) { 3270 if (!render_process_host) {
3119 if (g_render_process_host_factory_) { 3271 render_process_host =
3120 render_process_host = 3272 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 } 3273 }
3130 return render_process_host; 3274 return render_process_host;
3131 } 3275 }
3132 3276
3133 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { 3277 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() {
3134 // Create a persistent memory segment for renderer histograms only if 3278 // Create a persistent memory segment for renderer histograms only if
3135 // they're active in the browser. 3279 // they're active in the browser.
3136 if (!base::GlobalHistogramAllocator::Get()) 3280 if (!base::GlobalHistogramAllocator::Get())
3137 return; 3281 return;
3138 3282
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3626 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3770 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3627 3771
3628 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3772 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3629 // Capture the error message in a crash key value. 3773 // Capture the error message in a crash key value.
3630 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3774 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3631 bad_message::ReceivedBadMessage(render_process_id, 3775 bad_message::ReceivedBadMessage(render_process_id,
3632 bad_message::RPH_MOJO_PROCESS_ERROR); 3776 bad_message::RPH_MOJO_PROCESS_ERROR);
3633 } 3777 }
3634 3778
3635 } // namespace content 3779 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698