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

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

Issue 2929113002: Enable spare RenderProcessHost to be preinitialized. (Closed)
Patch Set: remove unneeded include Created 3 years, 5 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 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 void Release(int old_route_id) { 456 void Release(int old_route_id) {
457 session_storage_namespaces_awaiting_close_->erase(old_route_id); 457 session_storage_namespaces_awaiting_close_->erase(old_route_id);
458 } 458 }
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 // This class manages spare RenderProcessHosts.
467 //
468 // There is a singleton instance of this class which manages a single spare
469 // renderer (g_spare_render_process_host_manager, below). This class
470 // encapsulates the implementation of
471 // RenderProcessHost::WarmupSpareRenderProcessHost()
472 //
473 // RenderProcessHostImpl should call
474 // SpareRenderProcessHostManager::MaybeTakeSpareRenderProcessHost when creating
475 // a new RPH. In this implementation, the spare renderer is bound to a
476 // BrowserContext and its default StoragePartition. If
477 // MaybeTakeSpareRenderProcessHost is called with a BrowserContext and
478 // StoragePartition that does not match, the spare renderer is discarded. In
479 // particular, only the default StoragePartition will be able to use a spare
480 // renderer. The spare renderer will also not be used as a guest renderer
481 // (is_for_guests_ == true).
482 //
483 // It is safe to call WarmupSpareRenderProcessHost multiple times, although if
484 // called in a context where the spare renderer is not likely to be used
485 // performance may suffer due to the unnecessary RPH creation.
486 class SpareRenderProcessHostManager : public RenderProcessHostObserver {
487 public:
488 SpareRenderProcessHostManager() {}
489
490 void WarmupSpareRenderProcessHost(BrowserContext* browser_context) {
491 StoragePartitionImpl* current_partition =
492 static_cast<StoragePartitionImpl*>(
493 BrowserContext::GetStoragePartition(browser_context, nullptr));
494
495 if (spare_render_process_host_ &&
496 matching_browser_context_ == browser_context &&
497 matching_storage_partition_ == current_partition)
498 return; // Nothing to warm up.
499
500 CleanupSpareRenderProcessHost();
501
502 // Don't create a spare renderer if we're running a single renderer or if
503 // we've got too many processes. See also ShouldTryToUseExistingProcessHost
504 // in this file.
505 if (RenderProcessHost::run_renderer_in_process() ||
506 g_all_hosts.Get().size() >=
507 RenderProcessHostImpl::GetMaxRendererProcessCount())
508 return;
509
510 matching_browser_context_ = browser_context;
511 matching_storage_partition_ = current_partition;
512
513 spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost(
514 browser_context, current_partition, false /* is_for_guests_only */);
515 spare_render_process_host_->AddObserver(this);
516 spare_render_process_host_->Init();
517 }
518
519 RenderProcessHost* MaybeTakeSpareRenderProcessHost(
520 const BrowserContext* browser_context,
521 const StoragePartition* partition,
522 bool is_for_guests_only) {
523 if (!spare_render_process_host_ ||
524 browser_context != matching_browser_context_ ||
525 partition != matching_storage_partition_ || is_for_guests_only) {
526 // As a new RenderProcessHost will almost certainly be created, we cleanup
527 // the non-matching one so as not to waste resources.
528 CleanupSpareRenderProcessHost();
529 return nullptr;
530 }
531
532 RenderProcessHost* rph = spare_render_process_host_;
533 DropSpareRenderProcessHost(spare_render_process_host_);
534 return rph;
535 }
536
537 void OnStoragePartitionShutdown(StoragePartition* partition) {
538 if (partition == matching_storage_partition_)
539 CleanupSpareRenderProcessHost();
540 }
541
542 RenderProcessHost* spare_render_process_host() {
543 return spare_render_process_host_;
544 }
545
546 private:
547 // RenderProcessHostObserver
548 void RenderProcessWillExit(RenderProcessHost* host) override {
549 DropSpareRenderProcessHost(host);
550 }
551
552 void RenderProcessExited(RenderProcessHost* host,
553 base::TerminationStatus unused_status,
554 int unused_exit_code) override {
555 DropSpareRenderProcessHost(host);
556 }
557
558 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
559 DropSpareRenderProcessHost(host);
560 }
561
562 void CleanupSpareRenderProcessHost() {
563 if (spare_render_process_host_) {
564 spare_render_process_host_->Cleanup();
565 DropSpareRenderProcessHost(spare_render_process_host_);
566 }
567 }
568
569 // Remove |host| as a possible spare renderer. Does not shut it down cleanly;
570 // the assumption is that the host was shutdown somewhere else and has
571 // notifying the SpareRenderProcessHostManager.
572 void DropSpareRenderProcessHost(RenderProcessHost* host) {
573 if (host && host == spare_render_process_host_) {
Charlie Reis 2017/06/28 22:31:35 nit: Let's make the null pointer check be on spare
mattcary 2017/06/29 12:57:09 Done.
574 spare_render_process_host_->RemoveObserver(this);
575 spare_render_process_host_ = nullptr;
576 }
577 }
578
579 // This is a bare pointer, because RenderProcessHost manages the lifetime of
580 // all its instances; see g_all_hosts, above.
581 RenderProcessHost* spare_render_process_host_;
582
583 // Used only to check if a creation request matches the spare, and not
584 // accessed.
585 const BrowserContext* matching_browser_context_ = nullptr;
586 const StoragePartition* matching_storage_partition_ = nullptr;
587
588 DISALLOW_COPY_AND_ASSIGN(SpareRenderProcessHostManager);
589 };
590
591 base::LazyInstance<SpareRenderProcessHostManager>::Leaky
592 g_spare_render_process_host_manager = LAZY_INSTANCE_INITIALIZER;
593
466 const void* const kDefaultSubframeProcessHostHolderKey = 594 const void* const kDefaultSubframeProcessHostHolderKey =
467 &kDefaultSubframeProcessHostHolderKey; 595 &kDefaultSubframeProcessHostHolderKey;
468 596
469 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, 597 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data,
470 public RenderProcessHostObserver { 598 public RenderProcessHostObserver {
471 public: 599 public:
472 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) 600 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context)
473 : browser_context_(browser_context) {} 601 : browser_context_(browser_context) {}
474 ~DefaultSubframeProcessHostHolder() override {} 602 ~DefaultSubframeProcessHostHolder() override {}
475 603
476 // Gets the correct render process to use for this SiteInstance. 604 // Gets the correct render process to use for this SiteInstance.
477 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, 605 RenderProcessHost* GetProcessHost(SiteInstance* site_instance,
478 bool is_for_guests_only) { 606 bool is_for_guests_only) {
479 StoragePartition* default_partition = 607 StoragePartition* default_partition =
480 BrowserContext::GetDefaultStoragePartition(browser_context_); 608 BrowserContext::GetDefaultStoragePartition(browser_context_);
481 StoragePartition* partition = 609 StoragePartition* partition =
482 BrowserContext::GetStoragePartition(browser_context_, site_instance); 610 BrowserContext::GetStoragePartition(browser_context_, site_instance);
483 611
484 // Is this the default storage partition? If it isn't, then just give it its 612 // Is this the default storage partition? If it isn't, then just give it its
485 // own non-shared process. 613 // own non-shared process.
486 if (partition != default_partition || is_for_guests_only) { 614 if (partition != default_partition || is_for_guests_only) {
487 RenderProcessHostImpl* host = new RenderProcessHostImpl( 615 RenderProcessHost* host = RenderProcessHostImpl::CreateRenderProcessHost(
488 browser_context_, static_cast<StoragePartitionImpl*>(partition), 616 browser_context_, static_cast<StoragePartitionImpl*>(partition),
489 is_for_guests_only); 617 is_for_guests_only);
490 host->SetIsNeverSuitableForReuse(); 618 host->SetIsNeverSuitableForReuse();
491 return host; 619 return host;
492 } 620 }
493 621
494 // If we already have a shared host for the default storage partition, use 622 // If we already have a shared host for the default storage partition, use
495 // it. 623 // it.
496 if (host_) 624 if (host_)
497 return host_; 625 return host_;
498 626
499 host_ = new RenderProcessHostImpl( 627 // Before creating a new process, try to take a spare renderer.
628 host_ =
629 g_spare_render_process_host_manager.Get()
630 .MaybeTakeSpareRenderProcessHost(browser_context_, partition,
631 false /* is for guests only */);
632
633 host_ = RenderProcessHostImpl::CreateRenderProcessHost(
500 browser_context_, static_cast<StoragePartitionImpl*>(partition), 634 browser_context_, static_cast<StoragePartitionImpl*>(partition),
501 false /* for guests only */); 635 false /* for guests only */);
502 host_->SetIsNeverSuitableForReuse(); 636 host_->SetIsNeverSuitableForReuse();
503 host_->AddObserver(this); 637 host_->AddObserver(this);
504 638
505 return host_; 639 return host_;
506 } 640 }
507 641
508 // Implementation of RenderProcessHostObserver. 642 // Implementation of RenderProcessHostObserver.
509 void RenderProcessHostDestroyed(RenderProcessHost* host) override { 643 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
510 DCHECK_EQ(host_, host); 644 DCHECK_EQ(host_, host);
511 host_->RemoveObserver(this); 645 host_->RemoveObserver(this);
512 host_ = nullptr; 646 host_ = nullptr;
513 } 647 }
514 648
515 private: 649 private:
516 BrowserContext* browser_context_; 650 BrowserContext* browser_context_;
517 651
518 // The default subframe render process used for the default storage partition 652 // The default subframe render process used for the default storage partition
519 // of this BrowserContext. 653 // of this BrowserContext.
520 RenderProcessHostImpl* host_ = nullptr; 654 RenderProcessHost* host_ = nullptr;
521 }; 655 };
522 656
523 void CreateMemoryCoordinatorHandle( 657 void CreateMemoryCoordinatorHandle(
524 int render_process_id, 658 int render_process_id,
525 const service_manager::BindSourceInfo& source_info, 659 const service_manager::BindSourceInfo& source_info,
526 mojom::MemoryCoordinatorHandleRequest request) { 660 mojom::MemoryCoordinatorHandleRequest request) {
527 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, 661 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id,
528 std::move(request)); 662 std::move(request));
529 } 663 }
530 664
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 max_count = std::min(max_count, kMaxRendererProcessCount); 1042 max_count = std::min(max_count, kMaxRendererProcessCount);
909 } 1043 }
910 return max_count; 1044 return max_count;
911 } 1045 }
912 1046
913 // static 1047 // static
914 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { 1048 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
915 g_max_renderer_count_override = count; 1049 g_max_renderer_count_override = count;
916 } 1050 }
917 1051
1052 // static
1053 RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost(
1054 BrowserContext* browser_context,
1055 StoragePartitionImpl* storage_partition_impl,
1056 bool is_for_guests_only) {
1057 if (g_render_process_host_factory_) {
1058 return g_render_process_host_factory_->CreateRenderProcessHost(
1059 browser_context);
1060 }
1061
1062 return new RenderProcessHostImpl(browser_context, storage_partition_impl,
1063 is_for_guests_only);
1064 }
1065
918 RenderProcessHostImpl::RenderProcessHostImpl( 1066 RenderProcessHostImpl::RenderProcessHostImpl(
919 BrowserContext* browser_context, 1067 BrowserContext* browser_context,
920 StoragePartitionImpl* storage_partition_impl, 1068 StoragePartitionImpl* storage_partition_impl,
921 bool is_for_guests_only) 1069 bool is_for_guests_only)
922 : fast_shutdown_started_(false), 1070 : fast_shutdown_started_(false),
923 deleting_soon_(false), 1071 deleting_soon_(false),
924 #ifndef NDEBUG 1072 #ifndef NDEBUG
925 is_self_deleted_(false), 1073 is_self_deleted_(false),
926 #endif 1074 #endif
927 pending_views_(0), 1075 pending_views_(0),
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( 2127 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1980 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); 2128 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1981 if (!tracker) { 2129 if (!tracker) {
1982 tracker = new SiteProcessCountTracker(); 2130 tracker = new SiteProcessCountTracker();
1983 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, 2131 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1984 base::WrapUnique(tracker)); 2132 base::WrapUnique(tracker));
1985 } 2133 }
1986 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); 2134 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1987 } 2135 }
1988 2136
2137 // static
2138 void RenderProcessHostImpl::OnStoragePartitionShutdown(
2139 StoragePartition* partition) {
2140 g_spare_render_process_host_manager.Get().OnStoragePartitionShutdown(
2141 partition);
2142 }
2143
2144 // static
2145 RenderProcessHost*
2146 RenderProcessHostImpl::GetSpareRenderProcessHostForTesting() {
2147 return g_spare_render_process_host_manager.Get().spare_render_process_host();
2148 }
2149
1989 bool RenderProcessHostImpl::IsForGuestsOnly() const { 2150 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1990 return is_for_guests_only_; 2151 return is_for_guests_only_;
1991 } 2152 }
1992 2153
1993 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 2154 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1994 return storage_partition_impl_; 2155 return storage_partition_impl_;
1995 } 2156 }
1996 2157
1997 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 2158 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1998 command_line->AppendSwitchASCII( 2159 command_line->AppendSwitchASCII(
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 host->GetID()) != 3079 host->GetID()) !=
2919 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( 3080 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
2920 browser_context, site_url)) { 3081 browser_context, site_url)) {
2921 return false; 3082 return false;
2922 } 3083 }
2923 3084
2924 return GetContentClient()->browser()->IsSuitableHost(host, site_url); 3085 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
2925 } 3086 }
2926 3087
2927 // static 3088 // static
3089 void RenderProcessHost::WarmupSpareRenderProcessHost(
3090 content::BrowserContext* browser_context) {
3091 g_spare_render_process_host_manager.Get().WarmupSpareRenderProcessHost(
3092 browser_context);
3093 }
3094
3095 // static
2928 bool RenderProcessHost::run_renderer_in_process() { 3096 bool RenderProcessHost::run_renderer_in_process() {
2929 return g_run_renderer_in_process_; 3097 return g_run_renderer_in_process_;
2930 } 3098 }
2931 3099
2932 // static 3100 // static
2933 void RenderProcessHost::SetRunRendererInProcess(bool value) { 3101 void RenderProcessHost::SetRunRendererInProcess(bool value) {
2934 g_run_renderer_in_process_ = value; 3102 g_run_renderer_in_process_ = value;
2935 3103
2936 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 3104 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
2937 if (value) { 3105 if (value) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 default: 3284 default:
3117 break; 3285 break;
3118 } 3286 }
3119 3287
3120 // If not (or if none found), see if we should reuse an existing process. 3288 // If not (or if none found), see if we should reuse an existing process.
3121 if (!render_process_host && 3289 if (!render_process_host &&
3122 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3290 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
3123 render_process_host = GetExistingProcessHost(browser_context, site_url); 3291 render_process_host = GetExistingProcessHost(browser_context, site_url);
3124 } 3292 }
3125 3293
3294 // Before creating a new process, try to use a spare process if one is found.
3295 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
3296 BrowserContext::GetStoragePartition(browser_context, site_instance));
3297 if (!render_process_host) {
3298 render_process_host =
3299 g_spare_render_process_host_manager.Get()
3300 .MaybeTakeSpareRenderProcessHost(browser_context, partition,
3301 is_for_guests_only);
3302 }
3303
3126 // Otherwise (or if that fails), create a new one. 3304 // Otherwise (or if that fails), create a new one.
3127 if (!render_process_host) { 3305 if (!render_process_host) {
3128 if (g_render_process_host_factory_) { 3306 render_process_host =
3129 render_process_host = 3307 CreateRenderProcessHost(browser_context, partition, is_for_guests_only);
3130 g_render_process_host_factory_->CreateRenderProcessHost(
3131 browser_context);
3132 } else {
3133 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
3134 BrowserContext::GetStoragePartition(browser_context, site_instance));
3135 render_process_host = new RenderProcessHostImpl(
3136 browser_context, partition, is_for_guests_only);
3137 }
3138 } 3308 }
3309
3310 DCHECK(render_process_host);
3139 return render_process_host; 3311 return render_process_host;
3140 } 3312 }
3141 3313
3142 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { 3314 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() {
3143 // Create a persistent memory segment for renderer histograms only if 3315 // Create a persistent memory segment for renderer histograms only if
3144 // they're active in the browser. 3316 // they're active in the browser.
3145 if (!base::GlobalHistogramAllocator::Get()) 3317 if (!base::GlobalHistogramAllocator::Get())
3146 return; 3318 return;
3147 3319
3148 // Get handle to the renderer process. Stop if there is none. 3320 // Get handle to the renderer process. Stop if there is none.
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3807 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3636 3808
3637 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3809 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3638 // Capture the error message in a crash key value. 3810 // Capture the error message in a crash key value.
3639 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3811 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3640 bad_message::ReceivedBadMessage(render_process_id, 3812 bad_message::ReceivedBadMessage(render_process_id,
3641 bad_message::RPH_MOJO_PROCESS_ERROR); 3813 bad_message::RPH_MOJO_PROCESS_ERROR);
3642 } 3814 }
3643 3815
3644 } // namespace content 3816 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698