Title: [230977] trunk
Revision
230977
Author
[email protected]
Date
2018-04-24 16:19:25 -0700 (Tue, 24 Apr 2018)

Log Message

Keep around a pre-warmed process when doing process swap on navigation
https://bugs.webkit.org/show_bug.cgi?id=184765
<rdar://problem/39685099>

Reviewed by Ryosuke Niwa and Brady Eidson.

Source/WebKit:

This patch makes it so that WebProcessPool prewarms a process when process
swap on navigation is turned on. When we do a process swap on navigation,
we first try to grab a prewarmed process before creating a new one.

We try to be smart about when to create these processes. The initial heuristic
that this patch chooses is when we reach the DidFirstVisuallyNonEmptyLayout
layout milestone. We're going to try to improve on this heuristic in:
https://bugs.webkit.org/show_bug.cgi?id=184899

This is a 40% progression on PLT with process swap on navigation turned on.

* UIProcess/API/Cocoa/WKProcessPool.mm:
(-[WKProcessPool _prewarmedWebProcessCount]):
(-[WKProcessPool _webProcessCountIgnoringPrewarmed]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/ServiceWorkerProcessProxy.cpp:
(WebKit::ServiceWorkerProcessProxy::ServiceWorkerProcessProxy):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::notifyProcessPoolToPrewarm):
(WebKit::WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame):
* UIProcess/WebPageProxy.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::createNewWebProcess):
(WebKit::WebProcessPool::tryTakePrewarmedProcess):
(WebKit::WebProcessPool::warmInitialProcess):
(WebKit::WebProcessPool::disconnectProcess):
(WebKit::WebProcessPool::createWebPage):
(WebKit::WebProcessPool::didReachGoodTimeToPrewarm):
(WebKit::WebProcessPool::processForNavigation):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::create):
(WebKit::WebProcessProxy::WebProcessProxy):
(WebKit::m_isInPrewarmedPool):
(WebKit::m_userMediaCaptureManagerProxy): Deleted.
* UIProcess/WebProcessProxy.h:
(WebKit::WebProcessProxy::isInPrewarmedPool const):
(WebKit::WebProcessProxy::setIsInPrewarmedPool):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (230976 => 230977)


--- trunk/Source/WebKit/ChangeLog	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/ChangeLog	2018-04-24 23:19:25 UTC (rev 230977)
@@ -1,3 +1,50 @@
+2018-04-24  Saam Barati  <[email protected]>
+
+        Keep around a pre-warmed process when doing process swap on navigation
+        https://bugs.webkit.org/show_bug.cgi?id=184765
+        <rdar://problem/39685099>
+
+        Reviewed by Ryosuke Niwa and Brady Eidson.
+
+        This patch makes it so that WebProcessPool prewarms a process when process
+        swap on navigation is turned on. When we do a process swap on navigation,
+        we first try to grab a prewarmed process before creating a new one.
+        
+        We try to be smart about when to create these processes. The initial heuristic
+        that this patch chooses is when we reach the DidFirstVisuallyNonEmptyLayout
+        layout milestone. We're going to try to improve on this heuristic in:
+        https://bugs.webkit.org/show_bug.cgi?id=184899
+        
+        This is a 40% progression on PLT with process swap on navigation turned on.
+
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (-[WKProcessPool _prewarmedWebProcessCount]):
+        (-[WKProcessPool _webProcessCountIgnoringPrewarmed]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/ServiceWorkerProcessProxy.cpp:
+        (WebKit::ServiceWorkerProcessProxy::ServiceWorkerProcessProxy):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::notifyProcessPoolToPrewarm):
+        (WebKit::WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::createNewWebProcess):
+        (WebKit::WebProcessPool::tryTakePrewarmedProcess):
+        (WebKit::WebProcessPool::warmInitialProcess):
+        (WebKit::WebProcessPool::disconnectProcess):
+        (WebKit::WebProcessPool::createWebPage):
+        (WebKit::WebProcessPool::didReachGoodTimeToPrewarm):
+        (WebKit::WebProcessPool::processForNavigation):
+        * UIProcess/WebProcessPool.h:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::create):
+        (WebKit::WebProcessProxy::WebProcessProxy):
+        (WebKit::m_isInPrewarmedPool):
+        (WebKit::m_userMediaCaptureManagerProxy): Deleted.
+        * UIProcess/WebProcessProxy.h:
+        (WebKit::WebProcessProxy::isInPrewarmedPool const):
+        (WebKit::WebProcessProxy::setIsInPrewarmedPool):
+
 2018-04-24  Commit Queue  <[email protected]>
 
         Unreviewed, rolling out r230971.

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2018-04-24 23:19:25 UTC (rev 230977)
@@ -459,6 +459,21 @@
     return _processPool->processes().size();
 }
 
+- (size_t)_prewarmedWebProcessCount
+{
+    size_t result = 0;
+    for (auto& process : _processPool->processes()) {
+        if (process->isInPrewarmedPool())
+            ++result;
+    }
+    return result;
+}
+
+- (size_t)_webProcessCountIgnoringPrewarmed
+{
+    return [self _webProcessCount] - [self _prewarmedWebProcessCount];
+}
+
 - (size_t)_webPageContentProcessCount
 {
     auto allWebProcesses = _processPool->processes();

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2018-04-24 23:19:25 UTC (rev 230977)
@@ -89,6 +89,8 @@
 
 // Test only.
 - (size_t)_webProcessCount WK_API_AVAILABLE(macosx(10.13), ios(11.0));
+- (size_t)_prewarmedWebProcessCount WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (size_t)_webProcessCountIgnoringPrewarmed WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (size_t)_pluginProcessCount WK_API_AVAILABLE(macosx(10.13.4), ios(11.3));
 - (size_t)_serviceWorkerProcessCount WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (void)_syncNetworkProcessCookies WK_API_AVAILABLE(macosx(10.13), ios(11.0));

Modified: trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/ServiceWorkerProcessProxy.cpp	2018-04-24 23:19:25 UTC (rev 230977)
@@ -50,7 +50,7 @@
 }
 
 ServiceWorkerProcessProxy::ServiceWorkerProcessProxy(WebProcessPool& pool, const SecurityOriginData& securityOrigin, WebsiteDataStore& store)
-    : WebProcessProxy { pool, store }
+    : WebProcessProxy { pool, store, IsInPrewarmedPool::No }
     , m_securityOrigin(securityOrigin)
     , m_serviceWorkerPageID(generatePageID())
 {

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-04-24 23:19:25 UTC (rev 230977)
@@ -506,6 +506,11 @@
     return m_isValid;
 }
 
+void WebPageProxy::notifyProcessPoolToPrewarm()
+{
+    m_process->processPool().didReachGoodTimeToPrewarm();
+}
+
 void WebPageProxy::setPreferences(WebPreferences& preferences)
 {
     if (&preferences == m_preferences.ptr())
@@ -3845,8 +3850,10 @@
 
     m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get());
 
-    if (frame->isMainFrame())
+    if (frame->isMainFrame()) {
         m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame();
+        notifyProcessPoolToPrewarm();
+    }
 }
 
 void WebPageProxy::didLayoutForCustomContentProvider()

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-04-24 23:19:25 UTC (rev 230977)
@@ -1302,6 +1302,8 @@
     WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
     void platformInitialize();
 
+    void notifyProcessPoolToPrewarm();
+
     RefPtr<API::Navigation> goToBackForwardItem(WebBackForwardListItem&, WebCore::FrameLoadType);
 
     void updateActivityState(WebCore::ActivityState::Flags flagsToUpdate = WebCore::ActivityState::AllFlags);

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-04-24 23:19:25 UTC (rev 230977)
@@ -736,12 +736,14 @@
     platformResolvePathsForSandboxExtensions();
 }
 
-WebProcessProxy& WebProcessPool::createNewWebProcess(WebsiteDataStore& websiteDataStore)
+WebProcessProxy& WebProcessPool::createNewWebProcess(WebsiteDataStore& websiteDataStore, WebProcessProxy::IsInPrewarmedPool isInPrewarmedPool)
 {
-    auto processProxy = WebProcessProxy::create(*this, websiteDataStore);
+    auto processProxy = WebProcessProxy::create(*this, websiteDataStore, isInPrewarmedPool);
     auto& process = processProxy.get();
     initializeNewWebProcess(process, websiteDataStore);
     m_processes.append(WTFMove(processProxy));
+    if (isInPrewarmedPool == WebProcessProxy::IsInPrewarmedPool::Yes)
+        ++m_prewarmedProcessCount;
 
     if (m_serviceWorkerProcessesTerminationTimer.isActive())
         m_serviceWorkerProcessesTerminationTimer.stop();
@@ -749,6 +751,26 @@
     return process;
 }
 
+RefPtr<WebProcessProxy> WebProcessPool::tryTakePrewarmedProcess(WebsiteDataStore& websiteDataStore)
+{
+    if (!m_prewarmedProcessCount)
+        return nullptr;
+
+    for (const auto& process : m_processes) {
+        if (process->isInPrewarmedPool()) {
+            --m_prewarmedProcessCount;
+            process->setIsInPrewarmedPool(false);
+            if (&process->websiteDataStore() != &websiteDataStore)
+                process->send(Messages::WebProcess::AddWebsiteDataStore(websiteDataStore.parameters()), 0);
+            return process.get();
+        }
+    }
+
+    ASSERT_NOT_REACHED();
+    m_prewarmedProcessCount = 0;
+    return nullptr;
+}
+
 #if PLATFORM(MAC)
 static void displayReconfigurationCallBack(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *userInfo)
 {
@@ -926,7 +948,7 @@
 
 void WebProcessPool::warmInitialProcess()
 {
-    if (m_haveInitialEmptyProcess) {
+    if (m_prewarmedProcessCount) {
         ASSERT(!m_processes.isEmpty());
         return;
     }
@@ -936,9 +958,7 @@
 
     if (!m_websiteDataStore)
         m_websiteDataStore = API::WebsiteDataStore::defaultDataStore().ptr();
-    createNewWebProcess(m_websiteDataStore->websiteDataStore());
-
-    m_haveInitialEmptyProcess = true;
+    createNewWebProcess(m_websiteDataStore->websiteDataStore(), WebProcessProxy::IsInPrewarmedPool::Yes);
 }
 
 void WebProcessPool::enableProcessTermination()
@@ -994,8 +1014,8 @@
 {
     ASSERT(m_processes.contains(process));
 
-    if (m_haveInitialEmptyProcess && process == m_processes.last())
-        m_haveInitialEmptyProcess = false;
+    if (process->isInPrewarmedPool())
+        --m_prewarmedProcessCount;
 
     // FIXME (Multi-WebProcess): <rdar://problem/12239765> Some of the invalidation calls of the other supplements are still necessary in multi-process mode, but they should only affect data structures pertaining to the process being disconnected.
     // Clearing everything causes assertion failures, so it's less trouble to skip that for now.
@@ -1082,14 +1102,14 @@
     }
 
     RefPtr<WebProcessProxy> process;
-    if (m_haveInitialEmptyProcess) {
-        process = m_processes.last();
-        m_haveInitialEmptyProcess = false;
-    } else if (pageConfiguration->relatedPage()) {
+    if (pageConfiguration->relatedPage()) {
         // Sharing processes, e.g. when creating the page via window.open().
         process = &pageConfiguration->relatedPage()->process();
-    } else
-        process = &createNewWebProcessRespectingProcessCountLimit(pageConfiguration->websiteDataStore()->websiteDataStore());
+    } else {
+        process = tryTakePrewarmedProcess(pageConfiguration->websiteDataStore()->websiteDataStore());
+        if (!process)
+            process = &createNewWebProcessRespectingProcessCountLimit(pageConfiguration->websiteDataStore()->websiteDataStore());
+    }
 
 #if ENABLE(SERVICE_WORKER)
     ASSERT(!is<ServiceWorkerProcessProxy>(*process));
@@ -1228,6 +1248,17 @@
     }
 }
 
+void WebProcessPool::didReachGoodTimeToPrewarm()
+{
+    if (!m_configuration->processSwapsOnNavigation())
+        return;
+    if (!m_websiteDataStore)
+        m_websiteDataStore = API::WebsiteDataStore::defaultDataStore().ptr();
+    static constexpr size_t maxPrewarmCount = 1;
+    while (m_prewarmedProcessCount < maxPrewarmCount)
+        createNewWebProcess(m_websiteDataStore->websiteDataStore(), WebProcessProxy::IsInPrewarmedPool::Yes);
+}
+
 void WebProcessPool::populateVisitedLinks()
 {
     m_historyClient->populateVisitedLinks(*this);
@@ -2019,6 +2050,8 @@
         return page.process();
 
     action = ""
+    if (RefPtr<WebProcessProxy> process = tryTakePrewarmedProcess(page.websiteDataStore()))
+        return process.releaseNonNull();
     return createNewWebProcess(page.websiteDataStore());
 }
 

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.h	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h	2018-04-24 23:19:25 UTC (rev 230977)
@@ -106,8 +106,7 @@
 int webProcessThroughputQOS();
 #endif
 
-class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPool>, private IPC::MessageReceiver
-    {
+class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPool>, private IPC::MessageReceiver {
 public:
     static Ref<WebProcessPool> create(API::ProcessPoolConfiguration&);
 
@@ -449,6 +448,7 @@
     Ref<WebProcessProxy> processForNavigation(WebPageProxy&, const API::Navigation&, WebCore::PolicyAction&);
     void registerSuspendedPageProxy(SuspendedPageProxy&);
     void unregisterSuspendedPageProxy(SuspendedPageProxy&);
+    void didReachGoodTimeToPrewarm();
 
 private:
     void platformInitialize();
@@ -456,7 +456,9 @@
     void platformInitializeWebProcess(WebProcessCreationParameters&);
     void platformInvalidateContext();
 
-    WebProcessProxy& createNewWebProcess(WebsiteDataStore&);
+    RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&);
+
+    WebProcessProxy& createNewWebProcess(WebsiteDataStore&, WebProcessProxy::IsInPrewarmedPool = WebProcessProxy::IsInPrewarmedPool::No);
     void initializeNewWebProcess(WebProcessProxy&, WebsiteDataStore&);
 
     void requestWebContentStatistics(StatisticsRequest*);
@@ -516,7 +518,7 @@
     IPC::MessageReceiverMap m_messageReceiverMap;
 
     Vector<RefPtr<WebProcessProxy>> m_processes;
-    bool m_haveInitialEmptyProcess { false };
+    unsigned m_prewarmedProcessCount { 0 };
 
     WebProcessProxy* m_processWithPageCache { nullptr };
 #if ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2018-04-24 23:19:25 UTC (rev 230977)
@@ -105,14 +105,14 @@
     return pageMap;
 }
 
-Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool, WebsiteDataStore& websiteDataStore)
+Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool, WebsiteDataStore& websiteDataStore, IsInPrewarmedPool isInPrewarmedPool)
 {
-    auto proxy = adoptRef(*new WebProcessProxy(processPool, websiteDataStore));
+    auto proxy = adoptRef(*new WebProcessProxy(processPool, websiteDataStore, isInPrewarmedPool));
     proxy->connect();
     return proxy;
 }
 
-WebProcessProxy::WebProcessProxy(WebProcessPool& processPool, WebsiteDataStore& websiteDataStore)
+WebProcessProxy::WebProcessProxy(WebProcessPool& processPool, WebsiteDataStore& websiteDataStore, IsInPrewarmedPool isInPrewarmedPool)
     : ChildProcessProxy(processPool.alwaysRunsAtBackgroundPriority())
     , m_responsivenessTimer(*this)
     , m_backgroundResponsivenessTimer(*this)
@@ -126,6 +126,7 @@
 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
     , m_userMediaCaptureManagerProxy(std::make_unique<UserMediaCaptureManagerProxy>(*this))
 #endif
+    , m_isInPrewarmedPool(isInPrewarmedPool == IsInPrewarmedPool::Yes)
 {
     auto result = allProcesses().add(coreProcessIdentifier(), this);
     ASSERT_UNUSED(result, result.isNewEntry);

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (230976 => 230977)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2018-04-24 23:19:25 UTC (rev 230977)
@@ -97,7 +97,12 @@
     typedef HashMap<uint64_t, WebPageProxy*> WebPageProxyMap;
     typedef HashMap<uint64_t, RefPtr<API::UserInitiatedAction>> UserInitiatedActionMap;
 
-    static Ref<WebProcessProxy> create(WebProcessPool&, WebsiteDataStore&);
+    enum class IsInPrewarmedPool {
+        No,
+        Yes
+    };
+
+    static Ref<WebProcessProxy> create(WebProcessPool&, WebsiteDataStore&, IsInPrewarmedPool);
     ~WebProcessProxy();
 
     WebConnection* webConnection() const { return m_webConnection.get(); }
@@ -213,9 +218,12 @@
     void releaseBackgroundActivityTokenForFullscreenInput();
 #endif
 
+    bool isInPrewarmedPool() const { return m_isInPrewarmedPool; }
+    void setIsInPrewarmedPool(bool isInPrewarmedPool) { m_isInPrewarmedPool = isInPrewarmedPool; }
+
 protected:
     static uint64_t generatePageID();
-    WebProcessProxy(WebProcessPool&, WebsiteDataStore&);
+    WebProcessProxy(WebProcessPool&, WebsiteDataStore&, IsInPrewarmedPool);
 
     // ChildProcessProxy
     void getLaunchOptions(ProcessLauncher::LaunchOptions&) override;
@@ -340,6 +348,7 @@
     HashMap<uint64_t, CompletionHandler<void(WebCore::MessagePortChannelProvider::HasActivity)>> m_localPortActivityCompletionHandlers;
 
     bool m_hasCommittedAnyProvisionalLoads { false };
+    bool m_isInPrewarmedPool;
 
 #if ENABLE(EXTRA_ZOOM_MODE)
     ProcessThrottler::BackgroundActivityToken m_backgroundActivityTokenForFullscreenFormControls;

Modified: trunk/Tools/ChangeLog (230976 => 230977)


--- trunk/Tools/ChangeLog	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Tools/ChangeLog	2018-04-24 23:19:25 UTC (rev 230977)
@@ -1,3 +1,13 @@
+2018-04-24  Saam Barati  <[email protected]>
+
+        Keep around a pre-warmed process when doing process swap on navigation
+        https://bugs.webkit.org/show_bug.cgi?id=184765
+        <rdar://problem/39685099>
+
+        Reviewed by Ryosuke Niwa and Brady Eidson.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
 2018-04-24  Aakash Jain  <[email protected]>
 
         [build.webkit.org] unit-tests fail when passwords.json is missing

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (230976 => 230977)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2018-04-24 23:06:26 UTC (rev 230976)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2018-04-24 23:19:25 UTC (rev 230977)
@@ -785,7 +785,7 @@
     EXPECT_EQ(3u, seenPIDs.size());
 
     // But only 2 of those processes should still be alive
-    EXPECT_EQ(2u, [processPool _webProcessCount]);
+    EXPECT_EQ(2u, [processPool _webProcessCountIgnoringPrewarmed]);
 }
 
 static const char* pageCache1Bytes = R"PSONRESOURCE(
@@ -826,7 +826,7 @@
 
     auto pidAfterLoad1 = [webView _webProcessIdentifier];
 
-    EXPECT_EQ(1u, [processPool _webProcessCount]);
+    EXPECT_EQ(1u, [processPool _webProcessCountIgnoringPrewarmed]);
 
     request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson2://host/main.html"]];
 
@@ -836,7 +836,7 @@
 
     auto pidAfterLoad2 = [webView _webProcessIdentifier];
 
-    EXPECT_EQ(2u, [processPool _webProcessCount]);
+    EXPECT_EQ(2u, [processPool _webProcessCountIgnoringPrewarmed]);
     EXPECT_NE(pidAfterLoad1, pidAfterLoad2);
 
     [webView goBack];
@@ -847,7 +847,7 @@
 
     auto pidAfterLoad3 = [webView _webProcessIdentifier];
 
-    EXPECT_EQ(2u, [processPool _webProcessCount]);
+    EXPECT_EQ(2u, [processPool _webProcessCountIgnoringPrewarmed]);
     EXPECT_EQ(pidAfterLoad1, pidAfterLoad3);
     EXPECT_EQ(1u, [receivedMessages count]);
     EXPECT_TRUE([receivedMessages.get()[0] isEqualToString:@"Was persisted" ]);
@@ -861,7 +861,7 @@
 
     auto pidAfterLoad4 = [webView _webProcessIdentifier];
 
-    EXPECT_EQ(2u, [processPool _webProcessCount]);
+    EXPECT_EQ(2u, [processPool _webProcessCountIgnoringPrewarmed]);
     EXPECT_EQ(pidAfterLoad2, pidAfterLoad4);
     EXPECT_EQ(2u, [receivedMessages count]);
     EXPECT_TRUE([receivedMessages.get()[1] isEqualToString:@"Was persisted" ]);
@@ -868,6 +868,40 @@
     EXPECT_EQ(2u, seenPIDs.size());
 }
 
+TEST(ProcessSwap, NumberOfPrewarmedProcesses)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    [processPoolConfiguration setProcessSwapsOnNavigation:YES];
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler = adoptNS([[PSONScheme alloc] init]);
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host1/main.html"]];
+    [webView loadRequest:request];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_EQ(2u, [processPool _webProcessCount]);
+    EXPECT_EQ(1u, [processPool _webProcessCountIgnoringPrewarmed]);
+    EXPECT_EQ(1u, [processPool _prewarmedWebProcessCount]);
+
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host3/main.html"]];
+    [webView loadRequest:request];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_EQ(3u, [processPool _webProcessCount]);
+    EXPECT_EQ(2u, [processPool _webProcessCountIgnoringPrewarmed]);
+    EXPECT_EQ(1u, [processPool _prewarmedWebProcessCount]);
+}
+
 static const char* visibilityBytes = R"PSONRESOURCE(
 <script>
 window.addEventListener('pageshow', function(event) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to