Changeset 230640 in webkit
- Timestamp:
- Apr 13, 2018 11:04:22 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 22 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WTF/ChangeLog
r230589 r230640 1 2018-04-13 Brady Eidson <beidson@apple.com> 2 3 Introduce SuspendedPageProxy to keep old web processes around after their WebPageProxy has been swapped to a new one. 4 https://bugs.webkit.org/show_bug.cgi?id=184559 5 6 Reviewed by Alex Christensen. 7 8 * wtf/DebugUtilities.h: 9 (WTF::debugString): Add a debug utility to easily construct a "const char*" that is released after a spin of the run loop. 10 This greatly eases uses our String classes and functions inside of "%s" style environments like printf and LOG. 11 1 12 2018-04-12 Michael Catanzaro <mcatanzaro@igalia.com> 2 13 -
trunk/Source/WTF/wtf/DebugUtilities.h
r229770 r230640 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #ifndef WTF_DebugUtilities_h 27 #define WTF_DebugUtilities_h 26 #pragma once 28 27 29 28 #include <wtf/Assertions.h> 30 29 #include <wtf/ProcessID.h> 30 #include <wtf/text/StringConcatenate.h> 31 31 32 32 #define SLEEP_THREAD_FOR_DEBUGGER() \ … … 41 41 } while (0) 42 42 43 #endif /* WTF_DebugUtilities_h */ 43 namespace WTF { 44 45 template<typename... StringTypes> 46 const char* debugString(StringTypes... strings) 47 { 48 String result = tryMakeString(strings...); 49 if (!result) 50 CRASH(); 51 52 auto cString = result.utf8(); 53 const char* cStringData = cString.data(); 54 55 callOnMainThread([cString = WTFMove(cString)] { 56 }); 57 58 return cStringData; 59 } 60 61 } // namespace WTF 62 63 using WTF::debugString; -
trunk/Source/WebCore/ChangeLog
r230639 r230640 1 2018-04-13 Brady Eidson <beidson@apple.com> 2 3 Introduce SuspendedPageProxy to keep old web processes around after their WebPageProxy has been swapped to a new one. 4 https://bugs.webkit.org/show_bug.cgi?id=184559 5 6 Reviewed by Alex Christensen. 7 8 Covered by new API test. 9 10 WebCore changes rework the meaning of a "ForSuspension" policy to simply navigate the page to about:blank. 11 12 * loader/DocumentLoader.cpp: 13 (WebCore::DocumentLoader::redirectReceived): 14 (WebCore::DocumentLoader::willSendRequest): 15 (WebCore::DocumentLoader::startLoadingMainResource): 16 * loader/DocumentLoader.h: 17 18 * loader/FrameLoader.cpp: 19 (WebCore::FrameLoader::init): 20 (WebCore::FrameLoader::continueLoadAfterNavigationPolicy): 21 1 22 2018-04-13 Chris Dumez <cdumez@apple.com> 2 23 -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r230458 r230640 520 520 #if ENABLE(SERVICE_WORKER) 521 521 bool isRedirectionFromServiceWorker = redirectResponse.source() == ResourceResponse::Source::ServiceWorker; 522 willSendRequest(WTFMove(request), redirectResponse, [isRedirectionFromServiceWorker, completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable {522 willSendRequest(WTFMove(request), redirectResponse, ShouldContinue::Yes, [isRedirectionFromServiceWorker, completionHandler = WTFMove(completionHandler), protectedThis = makeRef(*this), this] (auto&& request) mutable { 523 523 ASSERT(!m_substituteData.isValid()); 524 524 if (request.isNull() || !m_mainDocumentError.isNull() || !m_frame) { … … 553 553 }); 554 554 #else 555 willSendRequest(WTFMove(request), redirectResponse, WTFMove(completionHandler));556 #endif 557 } 558 559 void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)555 willSendRequest(WTFMove(request), redirectResponse, ShouldContinue::Yes, WTFMove(completionHandler)); 556 #endif 557 } 558 559 void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const ResourceResponse& redirectResponse, ShouldContinue shouldContinue, CompletionHandler<void(ResourceRequest&&)>&& completionHandler) 560 560 { 561 561 // Note that there are no asserts here as there are for the other callbacks. This is due to the … … 564 564 // callbacks is meant to prevent. 565 565 ASSERT(!newRequest.isNull()); 566 567 ASSERT(shouldContinue != ShouldContinue::No); 566 568 567 569 bool didReceiveRedirectResponse = !redirectResponse.isNull(); … … 631 633 setRequest(newRequest); 632 634 633 // FIXME: Ideally we'd stop the I/O until we hear back from the navigation policy delegate 634 // listener. But there's no way to do that in practice. So instead we cancel later if the 635 // listener tells us to. In practice that means the navigation policy needs to be decided 636 // synchronously for these redirect cases. 637 if (!didReceiveRedirectResponse) 635 if (!didReceiveRedirectResponse && shouldContinue != ShouldContinue::ForSuspension) 638 636 return completionHandler(WTFMove(newRequest)); 639 637 640 ASSERT(!m_waitingForNavigationPolicy); 641 m_waitingForNavigationPolicy = true; 642 frameLoader()->policyChecker().checkNavigationPolicy(ResourceRequest(newRequest), didReceiveRedirectResponse, [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, FormState*, ShouldContinue shouldContinue) mutable { 638 auto navigationPolicyCompletionHandler = [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, FormState*, ShouldContinue shouldContinue) mutable { 643 639 m_waitingForNavigationPolicy = false; 644 640 switch (shouldContinue) { 645 641 case ShouldContinue::ForSuspension: 646 FALLTHROUGH; 647 // FIXME: Setup this page for suspension (e.g. Page Cache) here. 642 // We handle suspension by navigating forward to about:blank, which leaves us setup to navigate back to resume. 643 request = { blankURL() }; 644 break; 648 645 case ShouldContinue::No: 649 646 stopLoadingForPolicyChange(); … … 654 651 655 652 completionHandler(WTFMove(request)); 656 }); 653 }; 654 655 ASSERT(!m_waitingForNavigationPolicy); 656 m_waitingForNavigationPolicy = true; 657 658 if (shouldContinue == ShouldContinue::ForSuspension) { 659 navigationPolicyCompletionHandler(WTFMove(newRequest), nullptr, shouldContinue); 660 return; 661 } 662 663 frameLoader()->policyChecker().checkNavigationPolicy(ResourceRequest(newRequest), didReceiveRedirectResponse, WTFMove(navigationPolicyCompletionHandler)); 657 664 } 658 665 … … 1656 1663 } 1657 1664 1658 void DocumentLoader::startLoadingMainResource() 1659 { 1665 void DocumentLoader::startLoadingMainResource(ShouldContinue shouldContinue) 1666 { 1667 ASSERT(shouldContinue != ShouldContinue::No); 1668 1660 1669 m_mainDocumentError = ResourceError(); 1661 1670 timing().markStartTimeAndFetchStart(); … … 1682 1691 ASSERT(timing().fetchStart()); 1683 1692 1684 willSendRequest(ResourceRequest(m_request), ResourceResponse(), [this, protectedThis = makeRef(*this)] (ResourceRequest&& request) mutable {1693 willSendRequest(ResourceRequest(m_request), ResourceResponse(), shouldContinue, [this, protectedThis = makeRef(*this)] (ResourceRequest&& request) mutable { 1685 1694 m_request = request; 1686 1695 -
trunk/Source/WebCore/loader/DocumentLoader.h
r229675 r230640 85 85 class SubstituteResource; 86 86 87 enum class ShouldContinue; 88 87 89 using ResourceLoaderMap = HashMap<unsigned long, RefPtr<ResourceLoader>>; 88 90 … … 238 240 void setMainResourceDataBufferingPolicy(DataBufferingPolicy); 239 241 240 void startLoadingMainResource( );242 void startLoadingMainResource(ShouldContinue); 241 243 WEBCORE_EXPORT void cancelMainResourceLoad(const ResourceError&); 242 244 void willContinueMainResourceLoadAfterRedirect(const ResourceRequest&); … … 352 354 #endif 353 355 354 void willSendRequest(ResourceRequest&&, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&&);356 void willSendRequest(ResourceRequest&&, const ResourceResponse&, ShouldContinue, CompletionHandler<void(ResourceRequest&&)>&&); 355 357 void finishedLoading(); 356 358 void mainReceivedError(const ResourceError&); -
trunk/Source/WebCore/loader/FrameLoader.cpp
r230458 r230640 307 307 setPolicyDocumentLoader(m_client.createDocumentLoader(ResourceRequest(URL(ParsedURLString, emptyString())), SubstituteData()).ptr()); 308 308 setProvisionalDocumentLoader(m_policyDocumentLoader.get()); 309 m_provisionalDocumentLoader->startLoadingMainResource( );309 m_provisionalDocumentLoader->startLoadingMainResource(ShouldContinue::Yes); 310 310 311 311 Ref<Frame> protect(m_frame); … … 3232 3232 } 3233 3233 3234 WTF::Function<void(void)> completionHandler = [this] {3234 CompletionHandler<void(void)> completionHandler = [this, shouldContinue] { 3235 3235 if (!m_provisionalDocumentLoader) 3236 3236 return; … … 3252 3252 3253 3253 m_loadingFromCachedPage = false; 3254 m_provisionalDocumentLoader->startLoadingMainResource(); 3254 3255 // We handle suspension by navigating forward to about:blank, which leaves us setup to navigate back to resume. 3256 if (shouldContinue == ShouldContinue::ForSuspension) 3257 m_provisionalDocumentLoader->willContinueMainResourceLoadAfterRedirect({ blankURL() }); 3258 3259 m_provisionalDocumentLoader->startLoadingMainResource(shouldContinue); 3255 3260 }; 3256 3261 -
trunk/Source/WebKit/ChangeLog
r230636 r230640 1 2018-04-13 Brady Eidson <beidson@apple.com> 2 3 Introduce SuspendedPageProxy to keep old web processes around after their WebPageProxy has been swapped to a new one. 4 https://bugs.webkit.org/show_bug.cgi?id=184559 5 6 Reviewed by Alex Christensen. 7 8 Before this patch, when a WebPageProxy navigates and is swapped to a new process, the old process almost always goes away. 9 10 This is not desirable for a few reasons: 11 1 - We can't keep the PageCache working for back/forward scenarios 12 2 - We throw away a "foo.com" web process, meaning the next time we need to host a "foo.com" web page we have to launch 13 and initialize a new web process. 14 15 This patch adds a SuspendedPageProxy object to keep around the old web process and to manage communication with it. 16 17 For now, a WebPageProxy keeps exactly one "suspended page" representing the most recently visited page and its process. 18 Additionally, that process is never reused. 19 20 So no benefit is achieved with this patch, but it enables future benefits. 21 22 * Platform/Logging.h: 23 24 * Shared/WebBackForwardListItem.cpp: 25 (WebKit::WebBackForwardListItem::setSuspendedPage): 26 * Shared/WebBackForwardListItem.h: 27 28 New object to represent the state of a WebPageProxy in an old web process that is not currently hosting the view. 29 * UIProcess/SuspendedPageProxy.cpp: Added. 30 (WebKit::SuspendedPageProxy::SuspendedPageProxy): 31 (WebKit::SuspendedPageProxy::~SuspendedPageProxy): 32 (WebKit::SuspendedPageProxy::webProcessDidClose): 33 (WebKit::SuspendedPageProxy::didFinishLoad): 34 (WebKit::SuspendedPageProxy::didReceiveMessage): 35 (WebKit::SuspendedPageProxy::loggingString const): 36 * UIProcess/SuspendedPageProxy.h: Copied from Source/WebKit/Platform/Logging.h. 37 (WebKit::SuspendedPageProxy::create): 38 (WebKit::SuspendedPageProxy::page const): 39 (WebKit::SuspendedPageProxy::process const): 40 (WebKit::SuspendedPageProxy::item const): 41 (WebKit::SuspendedPageProxy::finishedSuspending const): 42 43 * UIProcess/WebPageProxy.cpp: 44 (WebKit::WebPageProxy::reattachToWebProcess): 45 (WebKit::WebPageProxy::attachToProcessForNavigation): 46 (WebKit::WebPageProxy::maybeCreateSuspendedPage): 47 (WebKit::WebPageProxy::suspendedPageProcessClosed): 48 (WebKit::WebPageProxy::receivedPolicyDecision): 49 (WebKit::WebPageProxy::didFinishLoadForFrame): 50 * UIProcess/WebPageProxy.h: 51 52 * UIProcess/WebProcessProxy.cpp: 53 (WebKit::WebProcessProxy::suspendWebPageProxy): 54 (WebKit::WebProcessProxy::suspendedPageWasDestroyed): 55 (WebKit::WebProcessProxy::removeWebPage): 56 (WebKit::WebProcessProxy::didReceiveMessage): Optionally pass WebPageProxy messages along to SuspendedPageProxy objects. 57 (WebKit::WebProcessProxy::didClose): 58 (WebKit::WebProcessProxy::maybeShutDown): 59 (WebKit::WebProcessProxy::canTerminateChildProcess): Don't terminate child processes if they still have suspended pages. 60 * UIProcess/WebProcessProxy.h: 61 62 * WebKit.xcodeproj/project.pbxproj: 63 64 * WebProcess/WebPage/WebPage.cpp: 65 (WebKit::WebPage::setIsSuspended): 66 * WebProcess/WebPage/WebPage.h: 67 (WebKit::WebPage::isSuspended const): For now, used only by WebProcess::updateActivePages. Will have more uses soon. 68 * WebProcess/WebPage/WebPage.messages.in: 69 70 * WebProcess/WebProcess.messages.in: 71 * WebProcess/cocoa/WebProcessCocoa.mm: 72 (WebKit::WebProcess::updateActivePages): Allow the UIProcess to request an update of the web processes user visible name. 73 1 74 2018-04-13 Daniel Bates <dabates@apple.com> 2 75 -
trunk/Source/WebKit/Platform/Logging.h
r230560 r230640 63 63 M(Process) \ 64 64 M(ProcessSuspension) \ 65 M(ProcessSwapping) \ 65 66 M(RemoteLayerTree) \ 66 67 M(Resize) \ -
trunk/Source/WebKit/Shared/WebBackForwardListItem.cpp
r210042 r230640 104 104 } 105 105 106 void WebBackForwardListItem::setSuspendedPage(SuspendedPageProxy& page) 107 { 108 m_suspendedPage = &page; 109 } 110 106 111 } // namespace WebKit -
trunk/Source/WebKit/Shared/WebBackForwardListItem.h
r222824 r230640 42 42 namespace WebKit { 43 43 44 class SuspendedPageProxy; 45 44 46 class WebBackForwardListItem : public API::ObjectImpl<API::Object::Type::BackForwardListItem> { 45 47 public: … … 64 66 void setSnapshot(RefPtr<ViewSnapshot>&& snapshot) { m_itemState.snapshot = WTFMove(snapshot); } 65 67 #endif 68 void setSuspendedPage(SuspendedPageProxy&); 66 69 67 70 static uint64_t highestUsedItemID(); … … 72 75 BackForwardListItemState m_itemState; 73 76 uint64_t m_pageID; 77 SuspendedPageProxy* m_suspendedPage { nullptr }; 74 78 }; 75 79 -
trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h
r230639 r230640 1 1 /* 2 * Copyright (C) 201 0, 2013Apple Inc. All rights reserved.2 * Copyright (C) 2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 26 26 #pragma once 27 27 28 #include <pal/LogMacros.h>29 #include <wtf/Assertions.h>30 #include <wtf/ text/WTFString.h>28 #include "Connection.h" 29 #include "WebBackForwardListItem.h" 30 #include <wtf/RefCounted.h> 31 31 32 #if !LOG_DISABLED || !RELEASE_LOG_DISABLED 32 namespace WebKit { 33 33 34 #ifndef LOG_CHANNEL_PREFIX 35 #define LOG_CHANNEL_PREFIX WebKit2Log 34 class WebPageProxy; 35 class WebProcessProxy; 36 37 class SuspendedPageProxy : public RefCounted<SuspendedPageProxy> { 38 public: 39 static Ref<SuspendedPageProxy> create(WebPageProxy& page, WebProcessProxy& process, WebBackForwardListItem& item) 40 { 41 return adoptRef(*new SuspendedPageProxy(page, process, item)); 42 } 43 44 virtual ~SuspendedPageProxy(); 45 46 void didReceiveMessage(IPC::Connection&, IPC::Decoder&); 47 48 WebPageProxy& page() const { return m_page; } 49 WebProcessProxy* process() const { return m_process; } 50 WebBackForwardListItem& item() const { return m_backForwardListItem; } 51 52 bool finishedSuspending() const { return m_finishedSuspending; } 53 54 void webProcessDidClose(WebProcessProxy&); 55 56 #if !LOG_DISABLED 57 const char* loggingString() const; 36 58 #endif 37 59 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 60 private: 61 SuspendedPageProxy(WebPageProxy&, WebProcessProxy&, WebBackForwardListItem&); 41 62 42 #define WEBKIT2_LOG_CHANNELS(M) \ 43 M(CacheStorage) \ 44 M(ContextMenu) \ 45 M(DragAndDrop) \ 46 M(Fullscreen) \ 47 M(Gamepad) \ 48 M(IconDatabase) \ 49 M(IndexedDB) \ 50 M(IPC) \ 51 M(KeyHandling) \ 52 M(Layers) \ 53 M(Loading) \ 54 M(Network) \ 55 M(NetworkCache) \ 56 M(NetworkCacheSpeculativePreloading) \ 57 M(NetworkCacheStorage) \ 58 M(NetworkScheduling) \ 59 M(NetworkSession) \ 60 M(PerformanceLogging) \ 61 M(Plugins) \ 62 M(Printing) \ 63 M(Process) \ 64 M(ProcessSuspension) \ 65 M(RemoteLayerTree) \ 66 M(Resize) \ 67 M(ResourceLoadStatistics) \ 68 M(ResourceLoadStatisticsDebug) \ 69 M(Selection) \ 70 M(ServiceWorker) \ 71 M(SessionState) \ 72 M(StorageAPI) \ 73 M(TextInput) \ 74 M(ViewGestures) \ 75 M(ViewState) \ 76 M(VirtualMemory) \ 77 M(VisibleRects) \ 78 M(WebRTC) \ 79 M(WiFiAssertions) \ 63 void didFinishLoad(); 80 64 81 WEBKIT2_LOG_CHANNELS(DECLARE_LOG_CHANNEL) 65 WebPageProxy& m_page; 66 WebProcessProxy* m_process; 67 Ref<WebBackForwardListItem> m_backForwardListItem; 82 68 83 #undef DECLARE_LOG_CHANNEL 69 bool m_finishedSuspending { false }; 70 }; 84 71 85 #ifdef __cplusplus 86 } 87 #endif 88 89 #endif // !LOG_DISABLED || !RELEASE_LOG_DISABLED 90 72 } // namespace WebKit -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r230315 r230640 643 643 { 644 644 auto process = makeRef(m_process->processPool().createNewWebProcessRespectingProcessCountLimit(m_websiteDataStore.get())); 645 reattachToWebProcess(WTFMove(process) );645 reattachToWebProcess(WTFMove(process), false); 646 646 } 647 647 … … 654 654 // FIXME: this is to fix the ASSERT(isValid()) inside reattachToWebProcess, some other way to fix this is needed. 655 655 m_isValid = false; 656 reattachToWebProcess(WTFMove(process)); 657 } 658 659 void WebPageProxy::reattachToWebProcess(Ref<WebProcessProxy>&& process) 656 reattachToWebProcess(WTFMove(process), true); 657 } 658 659 SuspendedPageProxy* WebPageProxy::maybeCreateSuspendedPage(WebProcessProxy& process) 660 { 661 ASSERT(!m_suspendedPage || m_suspendedPage->process() != &process); 662 663 auto* currentItem = m_backForwardList->currentItem(); 664 if (!currentItem) { 665 LOG(ProcessSwapping, "WebPageProxy %" PRIu64 " unable to create suspended page for process pid %i - No current back/forward item", pageID(), process.processIdentifier()); 666 return nullptr; 667 } 668 669 m_suspendedPage = SuspendedPageProxy::create(*this, process, *currentItem); 670 671 LOG(ProcessSwapping, "WebPageProxy %" PRIu64 " created suspended page %s for process pid %i, back/forward item %" PRIu64, pageID(), m_suspendedPage->loggingString(), process.processIdentifier(), currentItem->itemID()); 672 673 return m_suspendedPage.get(); 674 } 675 676 void WebPageProxy::suspendedPageProcessClosed(SuspendedPageProxy& page) 677 { 678 ASSERT_UNUSED(page, &page == m_suspendedPage.get()); 679 m_suspendedPage = nullptr; 680 } 681 682 void WebPageProxy::reattachToWebProcess(Ref<WebProcessProxy>&& process, bool suspendInOldProcess) 660 683 { 661 684 ASSERT(!m_isClosed); … … 663 686 664 687 m_isValid = true; 665 m_process->removeWebPage(*this, m_pageID); 666 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); 688 689 if (!suspendInOldProcess) { 690 m_process->removeWebPage(*this, m_pageID); 691 m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); 692 } else 693 m_process->suspendWebPageProxy(*this); 667 694 668 695 m_process = WTFMove(process); … … 2355 2382 2356 2383 if (proposedProcess.ptr() != &process()) { 2357 LOG( Loading, "Switching from process %i to new process for navigation %" PRIu64 " '%s'", processIdentifier(), navigation->navigationID(), navigation->loggingString().utf8().data());2384 LOG(ProcessSwapping, "Switching from process %i to new process for navigation %" PRIu64 " '%s'", processIdentifier(), navigation->navigationID(), navigation->loggingString().utf8().data()); 2358 2385 2359 2386 RunLoop::main().dispatch([this, protectedThis = makeRef(*this), navigation = makeRef(*navigation), proposedProcess = WTFMove(proposedProcess)]() mutable { … … 3572 3599 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData) 3573 3600 { 3601 LOG(Loading, "WebPageProxy::didFinishLoadForFrame - WebPageProxy %p with navigationID %llu didFinishLoad", this, navigationID); 3602 3574 3603 PageClientProtector protector(m_pageClient); 3575 3604 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r230591 r230640 45 45 #include "SandboxExtension.h" 46 46 #include "ShareableBitmap.h" 47 #include "SuspendedPageProxy.h" 47 48 #include "SystemPreviewController.h" 48 49 #include "UserMediaPermissionRequestManagerProxy.h" … … 1287 1288 WebPreferencesStore preferencesStore() const; 1288 1289 1290 SuspendedPageProxy* maybeCreateSuspendedPage(WebProcessProxy&); 1291 void suspendedPageProcessClosed(SuspendedPageProxy&); 1292 1289 1293 private: 1290 1294 WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&); … … 1437 1441 void reattachToWebProcess(); 1438 1442 void attachToProcessForNavigation(Ref<WebProcessProxy>&&); 1439 void reattachToWebProcess(Ref<WebProcessProxy>&& );1443 void reattachToWebProcess(Ref<WebProcessProxy>&&, bool suspendInOldProcess); 1440 1444 1441 1445 RefPtr<API::Navigation> reattachToWebProcessForReload(); … … 2130 2134 2131 2135 std::optional<MonotonicTime> m_pageLoadStart; 2136 2137 // FIXME: Support more than one suspended page per WebPageProxy, 2138 // and have a global collection of them per process pool 2139 // (e.g. for that process pool's page cache) 2140 RefPtr<SuspendedPageProxy> m_suspendedPage; 2132 2141 }; 2133 2142 -
trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp
r230293 r230640 35 35 #include "PluginInfoStore.h" 36 36 #include "PluginProcessManager.h" 37 #include "SuspendedPageProxy.h" 37 38 #include "TextChecker.h" 38 39 #include "TextCheckerState.h" … … 396 397 } 397 398 399 void WebProcessProxy::suspendWebPageProxy(WebPageProxy& webPage) 400 { 401 if (auto* suspendedPage = webPage.maybeCreateSuspendedPage(*this)) { 402 LOG(ProcessSwapping, "WebProcessProxy pid %i added suspended page %s", processIdentifier(), suspendedPage->loggingString()); 403 m_suspendedPageMap.set(webPage.pageID(), suspendedPage); 404 } 405 406 removeWebPage(webPage, webPage.pageID()); 407 removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), webPage.pageID()); 408 } 409 410 void WebProcessProxy::suspendedPageWasDestroyed(SuspendedPageProxy& suspendedPage) 411 { 412 LOG(ProcessSwapping, "WebProcessProxy pid %i suspended page %s was destroyed", processIdentifier(), suspendedPage.loggingString()); 413 414 ASSERT(m_suspendedPageMap.contains(suspendedPage.page().pageID())); 415 m_suspendedPageMap.remove(suspendedPage.page().pageID()); 416 417 maybeShutDown(); 418 } 419 398 420 void WebProcessProxy::removeWebPage(WebPageProxy& webPage, uint64_t pageID) 399 421 { … … 415 437 m_backForwardListItemMap.remove(itemID); 416 438 417 // If this was the last WebPage open in that web process, and we have no other reason to keep it alive, let it go. 418 // We only allow this when using a network process, as otherwise the WebProcess needs to preserve its session state. 419 if (state() == State::Terminated || !canTerminateChildProcess()) 420 return; 421 422 shutDown(); 439 maybeShutDown(); 423 440 } 424 441 … … 638 655 } 639 656 657 // WebPageProxy messages are normally handled by the normal "dispatchMessage" up above. 658 // If they were not handled there, then they may potentially be handled by SuspendedPageProxy objects. 659 if (decoder.messageReceiverName() == Messages::WebPageProxy::messageReceiverName()) { 660 if (auto* suspendedPage = m_suspendedPageMap.get(decoder.destinationID())) { 661 suspendedPage->didReceiveMessage(connection, decoder); 662 return; 663 } 664 } 665 640 666 // FIXME: Add unhandled message logging. 641 667 } … … 681 707 page->processDidTerminate(ProcessTerminationReason::Crash); 682 708 709 for (auto* suspendedPage : copyToVectorOf<SuspendedPageProxy*>(m_suspendedPageMap.values())) 710 suspendedPage->webProcessDidClose(*this); 711 712 m_suspendedPageMap.clear(); 683 713 } 684 714 … … 828 858 } 829 859 860 void WebProcessProxy::maybeShutDown() 861 { 862 if (state() == State::Terminated || !canTerminateChildProcess()) 863 return; 864 865 shutDown(); 866 } 867 830 868 bool WebProcessProxy::canTerminateChildProcess() 831 869 { 832 if (!m_pageMap.isEmpty() )870 if (!m_pageMap.isEmpty() || !m_suspendedPageMap.isEmpty()) 833 871 return false; 834 872 -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r230293 r230640 67 67 class ObjCObjectGraph; 68 68 class PageClient; 69 class SuspendedPageProxy; 69 70 class UserMediaCaptureManagerProxy; 70 71 class VisitedLinkStore; … … 209 210 bool hasCommittedAnyProvisionalLoads() const { return m_hasCommittedAnyProvisionalLoads; } 210 211 212 void suspendWebPageProxy(WebPageProxy&); 213 void suspendedPageWasDestroyed(SuspendedPageProxy&); 214 211 215 protected: 212 216 static uint64_t generatePageID(); … … 222 226 // Will potentially cause the WebProcessProxy object to be freed. 223 227 void shutDown(); 228 void maybeShutDown(); 224 229 225 230 // IPC message handlers. … … 299 304 300 305 WebPageProxyMap m_pageMap; 306 HashMap<uint64_t, SuspendedPageProxy*> m_suspendedPageMap; 301 307 WebFrameProxyMap m_frameMap; 302 308 WebBackForwardListItemMap m_backForwardListItemMap; -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r230560 r230640 1071 1071 515BE1B51D5917FF00DD7C68 /* UIGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 515BE1AD1D555C5100DD7C68 /* UIGamepad.h */; }; 1072 1072 515BE1B71D5A94FD00DD7C68 /* UIGamepadProviderMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 515BE1B61D5A94F900DD7C68 /* UIGamepadProviderMac.mm */; }; 1073 515C415C207D7CAE00726E02 /* SuspendedPageProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 515C415A207D74E000726E02 /* SuspendedPageProxy.cpp */; }; 1073 1074 515E7727183DD6F60007203F /* AsyncRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 515E7725183DD6F60007203F /* AsyncRequest.cpp */; }; 1074 1075 515E7728183DD6F60007203F /* AsyncRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 515E7726183DD6F60007203F /* AsyncRequest.h */; }; … … 3487 3488 515BE1B11D5902B600DD7C68 /* GamepadData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GamepadData.cpp; sourceTree = "<group>"; }; 3488 3489 515BE1B61D5A94F900DD7C68 /* UIGamepadProviderMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = UIGamepadProviderMac.mm; path = UIProcess/Gamepad/mac/UIGamepadProviderMac.mm; sourceTree = SOURCE_ROOT; }; 3490 515C415A207D74E000726E02 /* SuspendedPageProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SuspendedPageProxy.cpp; sourceTree = "<group>"; }; 3491 515C415B207D74E100726E02 /* SuspendedPageProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuspendedPageProxy.h; sourceTree = "<group>"; }; 3489 3492 515E7725183DD6F60007203F /* AsyncRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncRequest.cpp; sourceTree = "<group>"; }; 3490 3493 515E7726183DD6F60007203F /* AsyncRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncRequest.h; sourceTree = "<group>"; }; … … 7270 7273 51A4D5A816CAC4FF000E615E /* StatisticsRequest.cpp */, 7271 7274 514BDED216C98EDD00E4E25E /* StatisticsRequest.h */, 7275 515C415A207D74E000726E02 /* SuspendedPageProxy.cpp */, 7276 515C415B207D74E100726E02 /* SuspendedPageProxy.h */, 7272 7277 318A1F04204F4764003480BC /* SystemPreviewController.cpp */, 7273 7278 3157135D2040A9B20084F9CF /* SystemPreviewController.h */, … … 10894 10899 1AE00D6B18327C1200087DD7 /* StringReference.cpp in Sources */, 10895 10900 296BD85E15019BC30071F424 /* StringUtilities.mm in Sources */, 10901 515C415C207D7CAE00726E02 /* SuspendedPageProxy.cpp in Sources */, 10896 10902 318A1F05204F4764003480BC /* SystemPreviewController.cpp in Sources */, 10897 10903 3157135E2040A9B20084F9CF /* SystemPreviewControllerCocoa.mm in Sources */, -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp
r230506 r230640 5867 5867 } 5868 5868 5869 void WebPage::setIsSuspended(bool suspended) 5870 { 5871 m_isSuspended = suspended; 5872 } 5873 5869 5874 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) 5870 5875 static uint64_t nextRequestStorageAccessContextId() -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r230591 r230640 1073 1073 UserContentControllerIdentifier userContentControllerIdentifier() const { return m_userContentController->identifier(); } 1074 1074 1075 bool isSuspended() const { return m_isSuspended; } 1076 1075 1077 private: 1076 1078 WebPage(uint64_t pageID, WebPageCreationParameters&&); … … 1389 1391 void urlSchemeTaskDidComplete(uint64_t handlerIdentifier, uint64_t taskIdentifier, const WebCore::ResourceError&); 1390 1392 1393 void setIsSuspended(bool); 1394 1391 1395 RefPtr<WebImage> snapshotAtSize(const WebCore::IntRect&, const WebCore::IntSize& bitmapSize, SnapshotOptions); 1392 1396 RefPtr<WebImage> snapshotNode(WebCore::Node&, SnapshotOptions, unsigned maximumPixelCount = std::numeric_limits<unsigned>::max()); … … 1706 1710 #endif 1707 1711 1712 bool m_isSuspended { false }; 1708 1713 }; 1709 1714 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in
r230591 r230640 492 492 URLSchemeTaskDidComplete(uint64_t handlerIdentifier, uint64_t taskIdentifier, WebCore::ResourceError error) 493 493 494 SetIsSuspended(bool suspended) 495 494 496 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) 495 497 StorageAccessResponse(bool wasGranted, uint64_t contextId) -
trunk/Source/WebKit/WebProcess/WebProcess.messages.in
r230454 r230640 129 129 MessagesAvailableForPort(struct WebCore::MessagePortIdentifier port) 130 130 131 UpdateActivePages() 132 131 133 #if PLATFORM(MAC) 132 134 SetScreenProperties(uint32_t primaryScreenID, HashMap<uint32_t, WebCore::ScreenProperties> screenProperties) -
trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm
r230225 r230640 388 388 389 389 for (auto& page : m_pageMap.values()) { 390 if (page->usesEphemeralSession() )390 if (page->usesEphemeralSession() || page->isSuspended()) 391 391 continue; 392 392 -
trunk/Tools/ChangeLog
r230639 r230640 1 2018-04-13 Brady Eidson <beidson@apple.com> 2 3 Introduce SuspendedPageProxy to keep old web processes around after their WebPageProxy has been swapped to a new one. 4 https://bugs.webkit.org/show_bug.cgi?id=184559 5 6 Reviewed by Alex Christensen. 7 8 * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm: 9 1 10 2018-04-13 Chris Dumez <cdumez@apple.com> 2 11 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm
r230315 r230640 752 752 } 753 753 754 TEST(ProcessSwap, OnePreviousProcessRemains) 755 { 756 auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]); 757 [processPoolConfiguration setProcessSwapsOnNavigation:YES]; 758 auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]); 759 760 auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]); 761 [webViewConfiguration setProcessPool:processPool.get()]; 762 auto handler = adoptNS([[PSONScheme alloc] init]); 763 [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"]; 764 765 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]); 766 auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]); 767 [webView setNavigationDelegate:delegate.get()]; 768 769 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host1/main.html"]]; 770 [webView loadRequest:request]; 771 772 TestWebKitAPI::Util::run(&done); 773 done = false; 774 775 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host2/main.html"]]; 776 [webView loadRequest:request]; 777 778 TestWebKitAPI::Util::run(&done); 779 done = false; 780 781 request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host3/main.html"]]; 782 [webView loadRequest:request]; 783 784 TestWebKitAPI::Util::run(&done); 785 done = false; 786 787 // Navigations to 3 different domains, we expect to have seen 3 different PIDs 788 EXPECT_EQ(3u, seenPIDs.size()); 789 790 // But only 2 of those processes should still be alive 791 EXPECT_EQ(2u, [processPool _webProcessCount]); 792 } 793 754 794 #endif // WK_API_ENABLED
Note: See TracChangeset
for help on using the changeset viewer.