Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |