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

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

Issue 2929113002: Enable spare RenderProcessHost to be preinitialized. (Closed)
Patch Set: Omnibox 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 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 const void* const kDefaultSubframeProcessHostHolderKey = 466 const void* const kDefaultSubframeProcessHostHolderKey =
467 &kDefaultSubframeProcessHostHolderKey; 467 &kDefaultSubframeProcessHostHolderKey;
Charlie Reis 2017/06/25 23:48:27 nit: Please keep this and the DefaultSubframeProce
mattcary 2017/06/26 14:45:06 Whoops, I assumed it was for the preceeding class.
468 468
469 // This class manages spare RenderProcessHosts.
Charlie Reis 2017/06/25 23:48:27 Please elaborate. :) Is this one per BrowserCont
mattcary 2017/06/26 14:45:06 Done.
470 class SpareRenderProcessHostManager : public RenderProcessHostObserver {
471 public:
472 SpareRenderProcessHostManager() {}
473
474 void WarmupSpareRenderProcessHost(BrowserContext* browser_context) {
Charlie Reis 2017/06/25 23:48:28 This should return early if we're over the process
mattcary 2017/06/26 14:45:06 Yes. See also your comment about low-end devices.
475 StoragePartitionImpl* current_partition =
476 static_cast<StoragePartitionImpl*>(
477 BrowserContext::GetStoragePartition(browser_context, nullptr));
Charlie Reis 2017/06/25 23:48:28 Do we only allow spare processes in the default St
mattcary 2017/06/26 14:45:07 Done, in the implementation notes above.
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 */);
Charlie Reis 2017/06/25 23:48:27 If we can't use spare processes for is_for_guests_
mattcary 2017/06/26 14:45:06 Done.
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 DropSpareRenderProcessHost(spare_render_process_host_);
511 return rph;
512 }
513
514 void OnStoragePartitionShutdown(StoragePartition* partition) {
515 if (partition == matching_storage_partition_) {
Charlie Reis 2017/06/25 23:48:27 nit: No braces needed.
mattcary 2017/06/26 14:45:06 Done.
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();
Charlie Reis 2017/06/25 23:48:27 Is this the right method to be calling? It looks
mattcary 2017/06/26 14:45:07 It's possible that Shutdown is better. My reasonin
Charlie Reis 2017/06/28 22:31:35 Sorry, I missed this in the last round. Looking c
mattcary 2017/06/29 12:57:09 Good find! I don't think that's correct, GetExisti
Charlie Reis 2017/06/29 21:09:16 Thanks! I added a few suggestions to improve thes
543 DropSpareRenderProcessHost(spare_render_process_host_);
544 }
545 }
546
547 // Remove |host| as a possible spare renderer. Does not shut it down cleanly,
Charlie Reis 2017/06/25 23:48:28 nit: semicolon rather than comma
mattcary 2017/06/26 14:45:06 Done.
548 // the assumption is that the host has been shutdown somewhere else and has
Charlie Reis 2017/06/25 23:48:28 nit: s/has/is/
mattcary 2017/06/26 14:45:06 Done (well, s/has been/was/, which maybe was your
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.
Charlie Reis 2017/06/25 23:48:28 nit: Rewrap
mattcary 2017/06/26 14:45:06 Done.
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,
Charlie Reis 2017/06/25 23:48:28 Is there a reason not to do this within CreateRend
mattcary 2017/06/26 14:45:06 Yes, CreateRenderProcessHost is used in WarmupSpar
Charlie Reis 2017/06/26 21:22:49 I see. The trouble right now is that we're duplic
mattcary 2017/06/28 13:14:38 Note that your suggestion could change the behavio
Charlie Reis 2017/06/28 22:31:35 FWIW, the default StoragePartition can't change, b
mattcary 2017/06/29 12:57:09 :P point taken...
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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 max_count = std::min(max_count, kMaxRendererProcessCount); 1016 max_count = std::min(max_count, kMaxRendererProcessCount);
909 } 1017 }
910 return max_count; 1018 return max_count;
911 } 1019 }
912 1020
913 // static 1021 // static
914 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { 1022 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
915 g_max_renderer_count_override = count; 1023 g_max_renderer_count_override = count;
916 } 1024 }
917 1025
1026 // static
1027 RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost(
1028 BrowserContext* browser_context,
1029 StoragePartitionImpl* storage_partition_impl,
1030 bool is_for_guests_only) {
1031 if (g_render_process_host_factory_) {
1032 return g_render_process_host_factory_->CreateRenderProcessHost(
1033 browser_context);
1034 }
1035
1036 return new RenderProcessHostImpl(browser_context, storage_partition_impl,
1037 is_for_guests_only);
1038 }
1039
918 RenderProcessHostImpl::RenderProcessHostImpl( 1040 RenderProcessHostImpl::RenderProcessHostImpl(
919 BrowserContext* browser_context, 1041 BrowserContext* browser_context,
920 StoragePartitionImpl* storage_partition_impl, 1042 StoragePartitionImpl* storage_partition_impl,
921 bool is_for_guests_only) 1043 bool is_for_guests_only)
922 : fast_shutdown_started_(false), 1044 : fast_shutdown_started_(false),
923 deleting_soon_(false), 1045 deleting_soon_(false),
924 #ifndef NDEBUG 1046 #ifndef NDEBUG
925 is_self_deleted_(false), 1047 is_self_deleted_(false),
926 #endif 1048 #endif
927 pending_views_(0), 1049 pending_views_(0),
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( 2101 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1980 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); 2102 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1981 if (!tracker) { 2103 if (!tracker) {
1982 tracker = new SiteProcessCountTracker(); 2104 tracker = new SiteProcessCountTracker();
1983 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, 2105 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1984 base::WrapUnique(tracker)); 2106 base::WrapUnique(tracker));
1985 } 2107 }
1986 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); 2108 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1987 } 2109 }
1988 2110
2111 // static
2112 void RenderProcessHostImpl::OnStoragePartitionShutdown(
2113 StoragePartition* partition) {
2114 g_spare_render_process_host_manager.Get().OnStoragePartitionShutdown(
2115 partition);
2116 }
2117
2118 // static
2119 RenderProcessHost*
2120 RenderProcessHostImpl::GetSpareRenderProcessHostForTesting() {
2121 return g_spare_render_process_host_manager.Get().spare_render_process_host();
2122 }
2123
1989 bool RenderProcessHostImpl::IsForGuestsOnly() const { 2124 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1990 return is_for_guests_only_; 2125 return is_for_guests_only_;
1991 } 2126 }
1992 2127
1993 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 2128 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1994 return storage_partition_impl_; 2129 return storage_partition_impl_;
1995 } 2130 }
1996 2131
1997 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 2132 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1998 command_line->AppendSwitchASCII( 2133 command_line->AppendSwitchASCII(
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 host->GetID()) != 3053 host->GetID()) !=
2919 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( 3054 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
2920 browser_context, site_url)) { 3055 browser_context, site_url)) {
2921 return false; 3056 return false;
2922 } 3057 }
2923 3058
2924 return GetContentClient()->browser()->IsSuitableHost(host, site_url); 3059 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
2925 } 3060 }
2926 3061
2927 // static 3062 // static
3063 void RenderProcessHost::WarmupSpareRenderProcessHost(
3064 content::BrowserContext* browser_context) {
3065 g_spare_render_process_host_manager.Get().WarmupSpareRenderProcessHost(
3066 browser_context);
3067 }
3068
3069 // static
2928 bool RenderProcessHost::run_renderer_in_process() { 3070 bool RenderProcessHost::run_renderer_in_process() {
2929 return g_run_renderer_in_process_; 3071 return g_run_renderer_in_process_;
2930 } 3072 }
2931 3073
2932 // static 3074 // static
2933 void RenderProcessHost::SetRunRendererInProcess(bool value) { 3075 void RenderProcessHost::SetRunRendererInProcess(bool value) {
2934 g_run_renderer_in_process_ = value; 3076 g_run_renderer_in_process_ = value;
2935 3077
2936 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 3078 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
2937 if (value) { 3079 if (value) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 default: 3258 default:
3117 break; 3259 break;
3118 } 3260 }
3119 3261
3120 // If not (or if none found), see if we should reuse an existing process. 3262 // If not (or if none found), see if we should reuse an existing process.
3121 if (!render_process_host && 3263 if (!render_process_host &&
3122 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3264 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
3123 render_process_host = GetExistingProcessHost(browser_context, site_url); 3265 render_process_host = GetExistingProcessHost(browser_context, site_url);
3124 } 3266 }
3125 3267
3268 // Try to use a spare process if one is found.
Charlie Reis 2017/06/25 23:48:27 nit: Start with "Before creating a new process,"
mattcary 2017/06/26 14:45:06 Done.
3269 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
3270 BrowserContext::GetStoragePartition(browser_context, site_instance));
3271 if (!render_process_host) {
3272 render_process_host =
3273 g_spare_render_process_host_manager.Get()
3274 .MaybeTakeSpareRenderProcessHost(browser_context, partition,
3275 is_for_guests_only);
3276 }
3277
3126 // Otherwise (or if that fails), create a new one. 3278 // Otherwise (or if that fails), create a new one.
3127 if (!render_process_host) { 3279 if (!render_process_host) {
3128 if (g_render_process_host_factory_) { 3280 render_process_host =
3129 render_process_host = 3281 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 } 3282 }
3139 return render_process_host; 3283 return render_process_host;
Charlie Reis 2017/06/25 23:48:27 nit: Unrelated, but can you put a DCHECK(render_pr
mattcary 2017/06/26 14:45:06 Done.
3140 } 3284 }
3141 3285
3142 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { 3286 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() {
3143 // Create a persistent memory segment for renderer histograms only if 3287 // Create a persistent memory segment for renderer histograms only if
3144 // they're active in the browser. 3288 // they're active in the browser.
3145 if (!base::GlobalHistogramAllocator::Get()) 3289 if (!base::GlobalHistogramAllocator::Get())
3146 return; 3290 return;
3147 3291
3148 // Get handle to the renderer process. Stop if there is none. 3292 // Get handle to the renderer process. Stop if there is none.
3149 base::ProcessHandle destination = GetHandle(); 3293 base::ProcessHandle destination = GetHandle();
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3779 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3636 3780
3637 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3781 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3638 // Capture the error message in a crash key value. 3782 // Capture the error message in a crash key value.
3639 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3783 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3640 bad_message::ReceivedBadMessage(render_process_id, 3784 bad_message::ReceivedBadMessage(render_process_id,
3641 bad_message::RPH_MOJO_PROCESS_ERROR); 3785 bad_message::RPH_MOJO_PROCESS_ERROR);
3642 } 3786 }
3643 3787
3644 } // namespace content 3788 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698