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

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

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

Powered by Google App Engine
This is Rietveld 408576698