<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[237008] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/237008">237008</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2018-10-10 11:21:11 -0700 (Wed, 10 Oct 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>Regression(PSON): Assertion hit under WebPageProxy::didNavigateWithNavigationData()
https://bugs.webkit.org/show_bug.cgi?id=190418
<rdar://problem/45059769>

Reviewed by Geoffrey Garen.

Source/WebKit:

When process swapping and "suspending" the previous WebProcess in a SuspendedPageProxy,
we need to keep around the main frame's ID that still exists on in this process. This
is needed so that we can re-create a UI-side WebFrameProxy for the WebFrame that exists
in the WebProcess, if we ever swap back to this suspended process (see login in
WebPageProxy::swapToWebProcess()).

The bug was that the main frame ID was stored on the WebPageProxy via m_mainFrameID instead of the
SuspendedPageProxy. This means that m_mainFrameID would get overriden when navigating in the new
WebProcess with the value 1 (because WebFrame identifiers start at 1 and are per-WebProcess).
This would lead to us constructing a WebFrameProxy with the wrong frame identifier in
WebPageProxy::swapToWebProcess(), which would override an existing unrelated WebFrame in the
WebProcessProxy's HashMap of frames. This would lead to crashes later on as the WebFrame
would not be associated to the WebPageProxy we expect.

* UIProcess/SuspendedPageProxy.cpp:
(WebKit::SuspendedPageProxy::SuspendedPageProxy):
* UIProcess/SuspendedPageProxy.h:
(WebKit::SuspendedPageProxy::mainFrameID const):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::maybeCreateSuspendedPage):
(WebKit::WebPageProxy::swapToWebProcess):
(WebKit::WebPageProxy::continueNavigationInNewProcess):
(WebKit::WebPageProxy::didCreateMainFrame):
* UIProcess/WebPageProxy.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::suspendWebPageProxy):
* UIProcess/WebProcessProxy.h:

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessSuspendedPageProxycpp">trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessSuspendedPageProxyh">trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxycpp">trunk/Source/WebKit/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebPageProxyh">trunk/Source/WebKit/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebProcessProxycpp">trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebProcessProxyh">trunk/Source/WebKit/UIProcess/WebProcessProxy.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaProcessSwapOnNavigationmm">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/ChangeLog       2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -1,3 +1,39 @@
</span><ins>+2018-10-10  Chris Dumez  <cdumez@apple.com>
+
+        Regression(PSON): Assertion hit under WebPageProxy::didNavigateWithNavigationData()
+        https://bugs.webkit.org/show_bug.cgi?id=190418
+        <rdar://problem/45059769>
+
+        Reviewed by Geoffrey Garen.
+
+        When process swapping and "suspending" the previous WebProcess in a SuspendedPageProxy,
+        we need to keep around the main frame's ID that still exists on in this process. This
+        is needed so that we can re-create a UI-side WebFrameProxy for the WebFrame that exists
+        in the WebProcess, if we ever swap back to this suspended process (see login in
+        WebPageProxy::swapToWebProcess()).
+
+        The bug was that the main frame ID was stored on the WebPageProxy via m_mainFrameID instead of the
+        SuspendedPageProxy. This means that m_mainFrameID would get overriden when navigating in the new
+        WebProcess with the value 1 (because WebFrame identifiers start at 1 and are per-WebProcess).
+        This would lead to us constructing a WebFrameProxy with the wrong frame identifier in
+        WebPageProxy::swapToWebProcess(), which would override an existing unrelated WebFrame in the
+        WebProcessProxy's HashMap of frames. This would lead to crashes later on as the WebFrame
+        would not be associated to the WebPageProxy we expect.
+
+        * UIProcess/SuspendedPageProxy.cpp:
+        (WebKit::SuspendedPageProxy::SuspendedPageProxy):
+        * UIProcess/SuspendedPageProxy.h:
+        (WebKit::SuspendedPageProxy::mainFrameID const):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::maybeCreateSuspendedPage):
+        (WebKit::WebPageProxy::swapToWebProcess):
+        (WebKit::WebPageProxy::continueNavigationInNewProcess):
+        (WebKit::WebPageProxy::didCreateMainFrame):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::suspendWebPageProxy):
+        * UIProcess/WebProcessProxy.h:
+
</ins><span class="cx"> 2018-10-10  Antti Koivisto  <antti@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Do domain prewarming for processes for new tabs
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessSuspendedPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp     2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp        2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -74,9 +74,10 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-SuspendedPageProxy::SuspendedPageProxy(WebPageProxy& page, Ref<WebProcessProxy>&& process, WebBackForwardListItem& item)
</del><ins>+SuspendedPageProxy::SuspendedPageProxy(WebPageProxy& page, Ref<WebProcessProxy>&& process, WebBackForwardListItem& item, uint64_t mainFrameID)
</ins><span class="cx">     : m_page(page)
</span><span class="cx">     , m_process(WTFMove(process))
</span><ins>+    , m_mainFrameID(mainFrameID)
</ins><span class="cx">     , m_origin(SecurityOriginData::fromURL({ { }, item.url() }))
</span><span class="cx"> {
</span><span class="cx">     item.setSuspendedPage(*this);
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessSuspendedPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h       2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h  2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> class SuspendedPageProxy : public CanMakeWeakPtr<SuspendedPageProxy> {
</span><span class="cx"> public:
</span><del>-    SuspendedPageProxy(WebPageProxy&, Ref<WebProcessProxy>&&, WebBackForwardListItem&);
</del><ins>+    SuspendedPageProxy(WebPageProxy&, Ref<WebProcessProxy>&&, WebBackForwardListItem&, uint64_t mainFrameID);
</ins><span class="cx">     ~SuspendedPageProxy();
</span><span class="cx"> 
</span><span class="cx">     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> 
</span><span class="cx">     WebPageProxy& page() const { return m_page; }
</span><span class="cx">     WebProcessProxy* process() const { return m_process.get(); }
</span><ins>+    uint64_t mainFrameID() const { return m_mainFrameID; }
</ins><span class="cx">     const WebCore::SecurityOriginData& origin() const { return m_origin; }
</span><span class="cx"> 
</span><span class="cx">     void webProcessDidClose(WebProcessProxy&);
</span><span class="lines">@@ -60,6 +61,7 @@
</span><span class="cx"> 
</span><span class="cx">     WebPageProxy& m_page;
</span><span class="cx">     RefPtr<WebProcessProxy> m_process;
</span><ins>+    uint64_t m_mainFrameID;
</ins><span class="cx">     WebCore::SecurityOriginData m_origin;
</span><span class="cx"> 
</span><span class="cx"> #if !LOG_DISABLED
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp   2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp      2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -710,7 +710,7 @@
</span><span class="cx">     finishAttachingToWebProcess();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SuspendedPageProxy* WebPageProxy::maybeCreateSuspendedPage(WebProcessProxy& process, API::Navigation& navigation)
</del><ins>+SuspendedPageProxy* WebPageProxy::maybeCreateSuspendedPage(WebProcessProxy& process, API::Navigation& navigation, uint64_t mainFrameID)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_suspendedPage || m_suspendedPage->process() != &process);
</span><span class="cx"> 
</span><span class="lines">@@ -720,7 +720,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_suspendedPage = std::make_unique<SuspendedPageProxy>(*this, process, *currentItem);
</del><ins>+    m_suspendedPage = std::make_unique<SuspendedPageProxy>(*this, process, *currentItem, mainFrameID);
</ins><span class="cx"> 
</span><span class="cx">     LOG(ProcessSwapping, "WebPageProxy %" PRIu64 " created suspended page %s for process pid %i, back/forward item %s" PRIu64, pageID(), m_suspendedPage->loggingString(), process.processIdentifier(), currentItem->itemID().logString());
</span><span class="cx"> 
</span><span class="lines">@@ -733,7 +733,7 @@
</span><span class="cx">     m_suspendedPage = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPageProxy::swapToWebProcess(Ref<WebProcessProxy>&& process, API::Navigation& navigation)
</del><ins>+void WebPageProxy::swapToWebProcess(Ref<WebProcessProxy>&& process, API::Navigation& navigation, std::optional<uint64_t> mainFrameIDInPreviousProcess)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_isClosed);
</span><span class="cx">     RELEASE_LOG_IF_ALLOWED(Process, "%p WebPageProxy::swapToWebProcess\n", this);
</span><span class="lines">@@ -741,7 +741,8 @@
</span><span class="cx">     // If the process we're attaching to is kept alive solely by our current suspended page,
</span><span class="cx">     // we need to maintain that by temporarily keeping the suspended page alive.
</span><span class="cx">     auto currentSuspendedPage = WTFMove(m_suspendedPage);
</span><del>-    m_process->suspendWebPageProxy(*this, navigation);
</del><ins>+    if (mainFrameIDInPreviousProcess)
+        m_process->suspendWebPageProxy(*this, navigation, *mainFrameIDInPreviousProcess);
</ins><span class="cx"> 
</span><span class="cx">     m_process = WTFMove(process);
</span><span class="cx">     m_isValid = true;
</span><span class="lines">@@ -752,9 +753,8 @@
</span><span class="cx">     // already exists and already has a main frame.
</span><span class="cx">     if (currentSuspendedPage && currentSuspendedPage->process() == m_process.ptr()) {
</span><span class="cx">         ASSERT(!m_mainFrame);
</span><del>-        ASSERT(m_mainFrameID);
-        m_mainFrame = WebFrameProxy::create(this, *m_mainFrameID);
-        m_process->frameCreated(*m_mainFrameID, *m_mainFrame);
</del><ins>+        m_mainFrame = WebFrameProxy::create(this, currentSuspendedPage->mainFrameID());
+        m_process->frameCreated(currentSuspendedPage->mainFrameID(), *m_mainFrame);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     finishAttachingToWebProcess();
</span><span class="lines">@@ -2537,15 +2537,13 @@
</span><span class="cx">     LOG(Loading, "Continuing navigation %" PRIu64 " '%s' in a new web process", navigation.navigationID(), navigation.loggingString());
</span><span class="cx"> 
</span><span class="cx">     Ref<WebProcessProxy> previousProcess = m_process.copyRef();
</span><del>-    std::optional<uint64_t> navigatedFrameIdentifierInPreviousProcess;
-    if (m_mainFrame)
-        navigatedFrameIdentifierInPreviousProcess = m_mainFrame->frameID();
</del><ins>+    std::optional<uint64_t> mainFrameIDInPreviousProcess = m_mainFrame ? std::make_optional(m_mainFrame->frameID()) : std::nullopt;
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(m_process.ptr() != process.ptr());
</span><span class="cx"> 
</span><span class="cx">     processDidTerminate(ProcessTerminationReason::NavigationSwap);
</span><span class="cx"> 
</span><del>-    swapToWebProcess(WTFMove(process), navigation);
</del><ins>+    swapToWebProcess(WTFMove(process), navigation, mainFrameIDInPreviousProcess);
</ins><span class="cx"> 
</span><span class="cx">     if (auto* item = navigation.targetItem()) {
</span><span class="cx">         LOG(Loading, "WebPageProxy %p continueNavigationInNewProcess to back item URL %s", this, item->url().utf8().data());
</span><span class="lines">@@ -2584,13 +2582,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool isInitialNavigationInNewWindow = openedByDOM() && !hasCommittedAnyProvisionalLoads();
</span><del>-    if (!isInitialNavigationInNewWindow || !navigatedFrameIdentifierInPreviousProcess)
</del><ins>+    if (!isInitialNavigationInNewWindow || !mainFrameIDInPreviousProcess)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_mainFrameWindowCreationHandler = [this, previousProcess = WTFMove(previousProcess), navigatedFrameIdentifierInPreviousProcess = *navigatedFrameIdentifierInPreviousProcess](const GlobalWindowIdentifier& windowIdentifier) {
</del><ins>+    m_mainFrameWindowCreationHandler = [this, previousProcess = WTFMove(previousProcess), mainFrameIDInPreviousProcess = *mainFrameIDInPreviousProcess](const GlobalWindowIdentifier& windowIdentifier) {
</ins><span class="cx">         ASSERT(m_mainFrame);
</span><span class="cx">         GlobalFrameIdentifier navigatedFrameIdentifierInNewProcess { pageID(), m_mainFrame->frameID() };
</span><del>-        previousProcess->send(Messages::WebPage::FrameBecameRemote(navigatedFrameIdentifierInPreviousProcess, navigatedFrameIdentifierInNewProcess, windowIdentifier), pageID());
</del><ins>+        previousProcess->send(Messages::WebPage::FrameBecameRemote(mainFrameIDInPreviousProcess, navigatedFrameIdentifierInNewProcess, windowIdentifier), pageID());
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3415,7 +3413,6 @@
</span><span class="cx">     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
</span><span class="cx"> 
</span><span class="cx">     m_mainFrame = WebFrameProxy::create(this, frameID);
</span><del>-    m_mainFrameID = frameID;
</del><span class="cx"> 
</span><span class="cx">     // Add the frame to the process wide map.
</span><span class="cx">     m_process->frameCreated(frameID, *m_mainFrame);
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebPageProxy.h     2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h        2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -1354,7 +1354,7 @@
</span><span class="cx"> 
</span><span class="cx">     WebPreferencesStore preferencesStore() const;
</span><span class="cx"> 
</span><del>-    SuspendedPageProxy* maybeCreateSuspendedPage(WebProcessProxy&, API::Navigation&);
</del><ins>+    SuspendedPageProxy* maybeCreateSuspendedPage(WebProcessProxy&, API::Navigation&, uint64_t mainFrameID);
</ins><span class="cx">     SuspendedPageProxy* suspendedPage() const { return m_suspendedPage.get(); }
</span><span class="cx">     void suspendedPageClosed(SuspendedPageProxy&);
</span><span class="cx"> 
</span><span class="lines">@@ -1525,7 +1525,7 @@
</span><span class="cx">     void setCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents) { m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; }
</span><span class="cx"> 
</span><span class="cx">     void reattachToWebProcess();
</span><del>-    void swapToWebProcess(Ref<WebProcessProxy>&&, API::Navigation&);
</del><ins>+    void swapToWebProcess(Ref<WebProcessProxy>&&, API::Navigation&, std::optional<uint64_t> mainFrameIDInPreviousProcess);
</ins><span class="cx">     void finishAttachingToWebProcess();
</span><span class="cx"> 
</span><span class="cx">     RefPtr<API::Navigation> reattachToWebProcessForReload();
</span><span class="lines">@@ -1894,7 +1894,6 @@
</span><span class="cx">     Ref<WebsiteDataStore> m_websiteDataStore;
</span><span class="cx"> 
</span><span class="cx">     RefPtr<WebFrameProxy> m_mainFrame;
</span><del>-    std::optional<uint64_t> m_mainFrameID;
</del><span class="cx">     Function<void()> m_mainFrameCreationHandler;
</span><span class="cx">     Function<void(const WebCore::GlobalWindowIdentifier&)> m_mainFrameWindowCreationHandler;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebProcessProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp        2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp   2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -438,9 +438,9 @@
</span><span class="cx">     updateBackgroundResponsivenessTimer();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebProcessProxy::suspendWebPageProxy(WebPageProxy& webPage, API::Navigation& navigation)
</del><ins>+void WebProcessProxy::suspendWebPageProxy(WebPageProxy& webPage, API::Navigation& navigation, uint64_t mainFrameID)
</ins><span class="cx"> {
</span><del>-    if (auto* suspendedPage = webPage.maybeCreateSuspendedPage(*this, navigation)) {
</del><ins>+    if (auto* suspendedPage = webPage.maybeCreateSuspendedPage(*this, navigation, mainFrameID)) {
</ins><span class="cx">         LOG(ProcessSwapping, "WebProcessProxy pid %i added suspended page %s", processIdentifier(), suspendedPage->loggingString());
</span><span class="cx">         m_suspendedPageMap.set(webPage.pageID(), suspendedPage);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebProcessProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h  2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h     2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -208,7 +208,7 @@
</span><span class="cx">     void didCommitProvisionalLoad() { m_hasCommittedAnyProvisionalLoads = true; }
</span><span class="cx">     bool hasCommittedAnyProvisionalLoads() const { return m_hasCommittedAnyProvisionalLoads; }
</span><span class="cx"> 
</span><del>-    void suspendWebPageProxy(WebPageProxy&, API::Navigation&);
</del><ins>+    void suspendWebPageProxy(WebPageProxy&, API::Navigation&, uint64_t mainFrameID);
</ins><span class="cx">     void suspendedPageWasDestroyed(SuspendedPageProxy&);
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(WATCHOS)
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Tools/ChangeLog       2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2018-10-10  Chris Dumez  <cdumez@apple.com>
+
+        Regression(PSON): Assertion hit under WebPageProxy::didNavigateWithNavigationData()
+        https://bugs.webkit.org/show_bug.cgi?id=190418
+        <rdar://problem/45059769>
+
+        Reviewed by Geoffrey Garen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
</ins><span class="cx"> 2018-10-10  Guillaume Emont  <guijemont@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [JSCOnly Add an armv7 JSCOnly EWS that runs tests
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaProcessSwapOnNavigationmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (237007 => 237008)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm   2018-10-10 18:20:08 UTC (rev 237007)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm      2018-10-10 18:21:11 UTC (rev 237008)
</span><span class="lines">@@ -307,6 +307,16 @@
</span><span class="cx"> </script>
</span><span class="cx"> )PSONRESOURCE";
</span><span class="cx"> 
</span><ins>+static const char* linkToAppleTestBytes = R"PSONRESOURCE(
+<script>
+window.addEventListener('pageshow', function(event) {
+    if (event.persisted)
+        window.webkit.messageHandlers.pson.postMessage("Was persisted");
+});
+</script>
+<a id="testLink" href="pson://www.apple.com/main.html">Navigate</a>
+)PSONRESOURCE";
+
</ins><span class="cx"> #endif // PLATFORM(MAC)
</span><span class="cx"> 
</span><span class="cx"> TEST(ProcessSwap, Basic)
</span><span class="lines">@@ -1927,4 +1937,80 @@
</span><span class="cx">     EXPECT_NE(pid3, pid4);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
+
+TEST(ProcessSwap, GoBackToSuspendedPageWithMainFrameIDThatIsNotOne)
+{
+    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]);
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main1.html" toData:targetBlankSameSiteNoOpenerTestBytes];
+    [handler addMappingFromURLString:@"pson://www.webkit.org/main2.html" toData:linkToAppleTestBytes];
+    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+    auto messageHandler = adoptNS([[PSONMessageHandler alloc] init]);
+    [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"pson"];
+
+    auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView1 setNavigationDelegate:navigationDelegate.get()];
+    auto uiDelegate = adoptNS([[PSONUIDelegate alloc] initWithNavigationDelegate:navigationDelegate.get()]);
+    [webView1 setUIDelegate:uiDelegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main1.html"]];
+
+    [webView1 loadRequest:request];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_WK_STREQ(@"pson://www.webkit.org/main1.html", [[webView1 URL] absoluteString]);
+    auto pid1 = [webView1 _webProcessIdentifier];
+
+    TestWebKitAPI::Util::run(&didCreateWebView);
+    didCreateWebView = false;
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    // New WKWebView has now navigated to webkit.org.
+    EXPECT_WK_STREQ(@"pson://www.webkit.org/main2.html", [[createdWebView URL] absoluteString]);
+    auto pid2 = [createdWebView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid2);
+
+    // Click link in new WKWebView so that it navigates cross-site to apple.com.
+    [createdWebView evaluateJavaScript:@"testLink.click()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    // New WKWebView has now navigated to apple.com.
+    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[createdWebView URL] absoluteString]);
+    auto pid3 = [createdWebView _webProcessIdentifier];
+    EXPECT_NE(pid1, pid3); // Should have process-swapped.
+
+    // Navigate back to the suspended page (should use the page cache).
+    [createdWebView goBack];
+    TestWebKitAPI::Util::run(&receivedMessage);
+    receivedMessage = false;
+
+    EXPECT_WK_STREQ(@"pson://www.webkit.org/main2.html", [[createdWebView URL] absoluteString]);
+    auto pid4 = [createdWebView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid4); // Should have process-swapped to the original "suspended" process.
+
+    // Do a fragment navigation in the original WKWebView and make sure this does not crash.
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main1.html#testLink"]];
+    [webView1 loadRequest:request];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    EXPECT_WK_STREQ(@"pson://www.webkit.org/main1.html#testLink", [[webView1 URL] absoluteString]);
+    auto pid5 = [createdWebView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid5);
+}
+
+#endif // PLATFORM(MAC)
+
</ins><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre>
</div>
</div>

</body>
</html>