<!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>[247594] branches/safari-608-branch/Source</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/247594">247594</a></dd>
<dt>Author</dt> <dd>kocsen_chung@apple.com</dd>
<dt>Date</dt> <dd>2019-07-18 13:23:58 -0700 (Thu, 18 Jul 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Cherry-pick <a href="http://trac.webkit.org/projects/webkit/changeset/247486">r247486</a>. rdar://problem/53229738

    Speed up StorageManager::getValues()
    https://bugs.webkit.org/show_bug.cgi?id=199812

    Reviewed by Alex Christensen.

    Source/WebCore:

    * storage/StorageMap.cpp:
    (WebCore::StorageMap::importItems):
    * storage/StorageMap.h:

    Source/WebKit:

    Made the following performance improvements:
    - Made StorageManager a WorkQueueMessageReceiver again (like it was before it
      got moved from the UIProcess to the Network process). This avoids a lot of
      thread hopping (IPC thread -> Main thread -> StorageManagerThread -> Main Thread)
      and a lot of isolatedCopying of the strings.
    - Move values around when possible to avoid copying.
    - Add fast path to StorageMap::importItems() for when the StorageMap is
      empty when importing (15ms -> 2.5ms).

    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
    (WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
    (WebKit::NetworkConnectionToWebProcess::didReceiveSyncMessage):
    * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
    (WebKit::LocalStorageDatabase::importItems):
    * NetworkProcess/WebStorage/StorageManager.cpp:
    (WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection):
    (WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection):
    (WebKit::StorageManager::processDidCloseConnection):
    (WebKit::StorageManager::createLocalStorageMap):
    (WebKit::StorageManager::createTransientLocalStorageMap):
    (WebKit::StorageManager::createSessionStorageMap):
    (WebKit::StorageManager::destroyStorageMap):
    (WebKit::StorageManager::getValues):
    (WebKit::StorageManager::setItem):
    (WebKit::StorageManager::setItems):
    (WebKit::StorageManager::removeItem):
    (WebKit::StorageManager::clear):
    * NetworkProcess/WebStorage/StorageManager.h:

    * Platform/IPC/Connection.cpp:
    (IPC::Connection::addWorkQueueMessageReceiver):
    (IPC::Connection::removeWorkQueueMessageReceiver):
    (IPC::Connection::processIncomingMessage):
    (IPC::Connection::dispatchMessage):
    (IPC::Connection::dispatchMessageToWorkQueueReceiver):
    * Platform/IPC/Connection.h:
    * WebProcess/WebStorage/StorageAreaMap.cpp:
    (WebKit::StorageAreaMap::loadValuesIfNeeded):
    Messages to WorkQueueMessageReceivers are normally dispatched from the IPC WorkQueue. However, there is a race if
    a client (here StorageManager) adds itself as a WorkQueueMessageReceiver as a result of receiving an IPC message
    on the main thread (here NetworkConnectionToWebProcess::WebPageWasAdded).
    The message might have already been dispatched from the IPC WorkQueue to the main thread by the time the
    client registers itself as a WorkQueueMessageReceiver. To address this, we check again for messages receivers
    once the message arrives on the main thread.

    Source/WebKitLegacy:

    * Storage/StorageAreaImpl.cpp:
    (WebKit::StorageAreaImpl::importItems):
    * Storage/StorageAreaImpl.h:
    * Storage/StorageAreaSync.cpp:
    (WebKit::StorageAreaSync::performImport):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247486 268f45cc-cd09-0410-ab3c-d52691b4dbfc</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari608branchSourceWebCoreChangeLog">branches/safari-608-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari608branchSourceWebCorestorageStorageMapcpp">branches/safari-608-branch/Source/WebCore/storage/StorageMap.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebCorestorageStorageMaph">branches/safari-608-branch/Source/WebCore/storage/StorageMap.h</a></li>
<li><a href="#branchessafari608branchSourceWebKitChangeLog">branches/safari-608-branch/Source/WebKit/ChangeLog</a></li>
<li><a href="#branchessafari608branchSourceWebKitNetworkProcessNetworkConnectionToWebProcesscpp">branches/safari-608-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebKitNetworkProcessWebStorageLocalStorageDatabasecpp">branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebKitNetworkProcessWebStorageStorageManagercpp">branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebKitNetworkProcessWebStorageStorageManagerh">branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h</a></li>
<li><a href="#branchessafari608branchSourceWebKitPlatformIPCConnectioncpp">branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebKitPlatformIPCConnectionh">branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.h</a></li>
<li><a href="#branchessafari608branchSourceWebKitWebProcessWebStorageStorageAreaMapcpp">branches/safari-608-branch/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebKitLegacyChangeLog">branches/safari-608-branch/Source/WebKitLegacy/ChangeLog</a></li>
<li><a href="#branchessafari608branchSourceWebKitLegacyStorageStorageAreaImplcpp">branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp</a></li>
<li><a href="#branchessafari608branchSourceWebKitLegacyStorageStorageAreaImplh">branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.h</a></li>
<li><a href="#branchessafari608branchSourceWebKitLegacyStorageStorageAreaSynccpp">branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaSync.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari608branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebCore/ChangeLog (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebCore/ChangeLog      2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebCore/ChangeLog 2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -1,5 +1,89 @@
</span><span class="cx"> 2019-07-17  Kocsen Chung  <kocsen_chung@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r247486. rdar://problem/53229738
+
+    Speed up StorageManager::getValues()
+    https://bugs.webkit.org/show_bug.cgi?id=199812
+    
+    Reviewed by Alex Christensen.
+    
+    Source/WebCore:
+    
+    * storage/StorageMap.cpp:
+    (WebCore::StorageMap::importItems):
+    * storage/StorageMap.h:
+    
+    Source/WebKit:
+    
+    Made the following performance improvements:
+    - Made StorageManager a WorkQueueMessageReceiver again (like it was before it
+      got moved from the UIProcess to the Network process). This avoids a lot of
+      thread hopping (IPC thread -> Main thread -> StorageManagerThread -> Main Thread)
+      and a lot of isolatedCopying of the strings.
+    - Move values around when possible to avoid copying.
+    - Add fast path to StorageMap::importItems() for when the StorageMap is
+      empty when importing (15ms -> 2.5ms).
+    
+    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+    (WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
+    (WebKit::NetworkConnectionToWebProcess::didReceiveSyncMessage):
+    * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
+    (WebKit::LocalStorageDatabase::importItems):
+    * NetworkProcess/WebStorage/StorageManager.cpp:
+    (WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection):
+    (WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection):
+    (WebKit::StorageManager::processDidCloseConnection):
+    (WebKit::StorageManager::createLocalStorageMap):
+    (WebKit::StorageManager::createTransientLocalStorageMap):
+    (WebKit::StorageManager::createSessionStorageMap):
+    (WebKit::StorageManager::destroyStorageMap):
+    (WebKit::StorageManager::getValues):
+    (WebKit::StorageManager::setItem):
+    (WebKit::StorageManager::setItems):
+    (WebKit::StorageManager::removeItem):
+    (WebKit::StorageManager::clear):
+    * NetworkProcess/WebStorage/StorageManager.h:
+    
+    * Platform/IPC/Connection.cpp:
+    (IPC::Connection::addWorkQueueMessageReceiver):
+    (IPC::Connection::removeWorkQueueMessageReceiver):
+    (IPC::Connection::processIncomingMessage):
+    (IPC::Connection::dispatchMessage):
+    (IPC::Connection::dispatchMessageToWorkQueueReceiver):
+    * Platform/IPC/Connection.h:
+    * WebProcess/WebStorage/StorageAreaMap.cpp:
+    (WebKit::StorageAreaMap::loadValuesIfNeeded):
+    Messages to WorkQueueMessageReceivers are normally dispatched from the IPC WorkQueue. However, there is a race if
+    a client (here StorageManager) adds itself as a WorkQueueMessageReceiver as a result of receiving an IPC message
+    on the main thread (here NetworkConnectionToWebProcess::WebPageWasAdded).
+    The message might have already been dispatched from the IPC WorkQueue to the main thread by the time the
+    client registers itself as a WorkQueueMessageReceiver. To address this, we check again for messages receivers
+    once the message arrives on the main thread.
+    
+    Source/WebKitLegacy:
+    
+    * Storage/StorageAreaImpl.cpp:
+    (WebKit::StorageAreaImpl::importItems):
+    * Storage/StorageAreaImpl.h:
+    * Storage/StorageAreaSync.cpp:
+    (WebKit::StorageAreaSync::performImport):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247486 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-07-16  Chris Dumez  <cdumez@apple.com>
+
+            Speed up StorageManager::getValues()
+            https://bugs.webkit.org/show_bug.cgi?id=199812
+
+            Reviewed by Alex Christensen.
+
+            * storage/StorageMap.cpp:
+            (WebCore::StorageMap::importItems):
+            * storage/StorageMap.h:
+
+2019-07-17  Kocsen Chung  <kocsen_chung@apple.com>
+
</ins><span class="cx">         Cherry-pick r247484. rdar://problem/53229757
</span><span class="cx"> 
</span><span class="cx">     [Text autosizing] [iPadOS] Paragraph text on the front page of LinkedIn.com is not boosted
</span></span></pre></div>
<a id="branchessafari608branchSourceWebCorestorageStorageMapcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebCore/storage/StorageMap.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebCore/storage/StorageMap.cpp 2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebCore/storage/StorageMap.cpp    2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -182,19 +182,27 @@
</span><span class="cx">     return m_map.contains(key);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StorageMap::importItems(const HashMap<String, String>& items)
</del><ins>+void StorageMap::importItems(HashMap<String, String>&& items)
</ins><span class="cx"> {
</span><ins>+    if (m_map.isEmpty()) {
+        // Fast path.
+        m_map = WTFMove(items);
+        for (auto& pair : m_map) {
+            ASSERT(m_currentLength + pair.key.length() + pair.value.length() >= m_currentLength);
+            m_currentLength += (pair.key.length() + pair.value.length());
+        }
+        return;
+    }
+
</ins><span class="cx">     for (auto& item : items) {
</span><del>-        const String& key = item.key;
-        const String& value = item.value;
</del><ins>+        auto& key = item.key;
+        auto& value = item.value;
</ins><span class="cx"> 
</span><del>-        HashMap<String, String>::AddResult result = m_map.add(key, value);
</del><ins>+        ASSERT(m_currentLength + key.length() + value.length() >= m_currentLength);
+        m_currentLength += (key.length() + value.length());
+        
+        auto result = m_map.add(WTFMove(key), WTFMove(value));
</ins><span class="cx">         ASSERT_UNUSED(result, result.isNewEntry); // True if the key didn't exist previously.
</span><del>-
-        ASSERT(m_currentLength + key.length() >= m_currentLength);
-        m_currentLength += key.length();
-        ASSERT(m_currentLength + value.length() >= m_currentLength);
-        m_currentLength += value.length();
</del><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari608branchSourceWebCorestorageStorageMaph"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebCore/storage/StorageMap.h (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebCore/storage/StorageMap.h   2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebCore/storage/StorageMap.h      2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT bool contains(const String& key) const;
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT void importItems(const HashMap<String, String>&);
</del><ins>+    WEBCORE_EXPORT void importItems(HashMap<String, String>&&);
</ins><span class="cx">     const HashMap<String, String>& items() const { return m_map; }
</span><span class="cx"> 
</span><span class="cx">     unsigned quota() const { return m_quotaSize; }
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/ChangeLog (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/ChangeLog       2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/ChangeLog  2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -1,5 +1,130 @@
</span><span class="cx"> 2019-07-17  Kocsen Chung  <kocsen_chung@apple.com>
</span><span class="cx"> 
</span><ins>+        Cherry-pick r247486. rdar://problem/53229738
+
+    Speed up StorageManager::getValues()
+    https://bugs.webkit.org/show_bug.cgi?id=199812
+    
+    Reviewed by Alex Christensen.
+    
+    Source/WebCore:
+    
+    * storage/StorageMap.cpp:
+    (WebCore::StorageMap::importItems):
+    * storage/StorageMap.h:
+    
+    Source/WebKit:
+    
+    Made the following performance improvements:
+    - Made StorageManager a WorkQueueMessageReceiver again (like it was before it
+      got moved from the UIProcess to the Network process). This avoids a lot of
+      thread hopping (IPC thread -> Main thread -> StorageManagerThread -> Main Thread)
+      and a lot of isolatedCopying of the strings.
+    - Move values around when possible to avoid copying.
+    - Add fast path to StorageMap::importItems() for when the StorageMap is
+      empty when importing (15ms -> 2.5ms).
+    
+    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+    (WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
+    (WebKit::NetworkConnectionToWebProcess::didReceiveSyncMessage):
+    * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
+    (WebKit::LocalStorageDatabase::importItems):
+    * NetworkProcess/WebStorage/StorageManager.cpp:
+    (WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection):
+    (WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection):
+    (WebKit::StorageManager::processDidCloseConnection):
+    (WebKit::StorageManager::createLocalStorageMap):
+    (WebKit::StorageManager::createTransientLocalStorageMap):
+    (WebKit::StorageManager::createSessionStorageMap):
+    (WebKit::StorageManager::destroyStorageMap):
+    (WebKit::StorageManager::getValues):
+    (WebKit::StorageManager::setItem):
+    (WebKit::StorageManager::setItems):
+    (WebKit::StorageManager::removeItem):
+    (WebKit::StorageManager::clear):
+    * NetworkProcess/WebStorage/StorageManager.h:
+    
+    * Platform/IPC/Connection.cpp:
+    (IPC::Connection::addWorkQueueMessageReceiver):
+    (IPC::Connection::removeWorkQueueMessageReceiver):
+    (IPC::Connection::processIncomingMessage):
+    (IPC::Connection::dispatchMessage):
+    (IPC::Connection::dispatchMessageToWorkQueueReceiver):
+    * Platform/IPC/Connection.h:
+    * WebProcess/WebStorage/StorageAreaMap.cpp:
+    (WebKit::StorageAreaMap::loadValuesIfNeeded):
+    Messages to WorkQueueMessageReceivers are normally dispatched from the IPC WorkQueue. However, there is a race if
+    a client (here StorageManager) adds itself as a WorkQueueMessageReceiver as a result of receiving an IPC message
+    on the main thread (here NetworkConnectionToWebProcess::WebPageWasAdded).
+    The message might have already been dispatched from the IPC WorkQueue to the main thread by the time the
+    client registers itself as a WorkQueueMessageReceiver. To address this, we check again for messages receivers
+    once the message arrives on the main thread.
+    
+    Source/WebKitLegacy:
+    
+    * Storage/StorageAreaImpl.cpp:
+    (WebKit::StorageAreaImpl::importItems):
+    * Storage/StorageAreaImpl.h:
+    * Storage/StorageAreaSync.cpp:
+    (WebKit::StorageAreaSync::performImport):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247486 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-07-16  Chris Dumez  <cdumez@apple.com>
+
+            Speed up StorageManager::getValues()
+            https://bugs.webkit.org/show_bug.cgi?id=199812
+
+            Reviewed by Alex Christensen.
+
+            Made the following performance improvements:
+            - Made StorageManager a WorkQueueMessageReceiver again (like it was before it
+              got moved from the UIProcess to the Network process). This avoids a lot of
+              thread hopping (IPC thread -> Main thread -> StorageManagerThread -> Main Thread)
+              and a lot of isolatedCopying of the strings.
+            - Move values around when possible to avoid copying.
+            - Add fast path to StorageMap::importItems() for when the StorageMap is
+              empty when importing (15ms -> 2.5ms).
+
+            * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+            (WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
+            (WebKit::NetworkConnectionToWebProcess::didReceiveSyncMessage):
+            * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
+            (WebKit::LocalStorageDatabase::importItems):
+            * NetworkProcess/WebStorage/StorageManager.cpp:
+            (WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection):
+            (WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection):
+            (WebKit::StorageManager::processDidCloseConnection):
+            (WebKit::StorageManager::createLocalStorageMap):
+            (WebKit::StorageManager::createTransientLocalStorageMap):
+            (WebKit::StorageManager::createSessionStorageMap):
+            (WebKit::StorageManager::destroyStorageMap):
+            (WebKit::StorageManager::getValues):
+            (WebKit::StorageManager::setItem):
+            (WebKit::StorageManager::setItems):
+            (WebKit::StorageManager::removeItem):
+            (WebKit::StorageManager::clear):
+            * NetworkProcess/WebStorage/StorageManager.h:
+
+            * Platform/IPC/Connection.cpp:
+            (IPC::Connection::addWorkQueueMessageReceiver):
+            (IPC::Connection::removeWorkQueueMessageReceiver):
+            (IPC::Connection::processIncomingMessage):
+            (IPC::Connection::dispatchMessage):
+            (IPC::Connection::dispatchMessageToWorkQueueReceiver):
+            * Platform/IPC/Connection.h:
+            * WebProcess/WebStorage/StorageAreaMap.cpp:
+            (WebKit::StorageAreaMap::loadValuesIfNeeded):
+            Messages to WorkQueueMessageReceivers are normally dispatched from the IPC WorkQueue. However, there is a race if
+            a client (here StorageManager) adds itself as a WorkQueueMessageReceiver as a result of receiving an IPC message
+            on the main thread (here NetworkConnectionToWebProcess::WebPageWasAdded).
+            The message might have already been dispatched from the IPC WorkQueue to the main thread by the time the
+            client registers itself as a WorkQueueMessageReceiver. To address this, we check again for messages receivers
+            once the message arrives on the main thread.
+
+2019-07-17  Kocsen Chung  <kocsen_chung@apple.com>
+
</ins><span class="cx">         Cherry-pick r247483. rdar://problem/53229618
</span><span class="cx"> 
</span><span class="cx">     [ContentChangeObserver] Cancel ongoing content observation when tap is failed/cancelled
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitNetworkProcessNetworkConnectionToWebProcesscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp        2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp   2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -49,7 +49,6 @@
</span><span class="cx"> #include "PreconnectTask.h"
</span><span class="cx"> #include "ServiceWorkerFetchTaskMessages.h"
</span><span class="cx"> #include "StorageManager.h"
</span><del>-#include "StorageManagerMessages.h"
</del><span class="cx"> #include "WebCoreArgumentCoders.h"
</span><span class="cx"> #include "WebErrors.h"
</span><span class="cx"> #include "WebIDBConnectionToClient.h"
</span><span class="lines">@@ -232,13 +231,6 @@
</span><span class="cx">         return paymentCoordinator().didReceiveMessage(connection, decoder);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    if (decoder.messageReceiverName() == Messages::StorageManager::messageReceiverName()) {
-        if (auto* session = m_networkProcess->networkSessionByConnection(connection)) {
-            session->storageManager().didReceiveMessage(connection, decoder);
-            return;
-        }
-    }
-
</del><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -278,13 +270,6 @@
</span><span class="cx">         return paymentCoordinator().didReceiveSyncMessage(connection, decoder, reply);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    if (decoder.messageReceiverName() == Messages::StorageManager::messageReceiverName()) {
-        if (auto* session = m_networkProcess->networkSessionByConnection(connection)) {
-            session->storageManager().didReceiveSyncMessage(connection, decoder, reply);
-            return;
-        }
-    }
-
</del><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitNetworkProcessWebStorageLocalStorageDatabasecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp      2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/LocalStorageDatabase.cpp 2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -171,7 +171,7 @@
</span><span class="cx">     if (!m_database.isOpen())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    SQLiteStatement query(m_database, "SELECT key, value FROM ItemTable");
</del><ins>+    SQLiteStatement query(m_database, "SELECT key, value FROM ItemTable"_str);
</ins><span class="cx">     if (query.prepare() != SQLITE_OK) {
</span><span class="cx">         LOG_ERROR("Unable to select items from ItemTable for local storage");
</span><span class="cx">         return;
</span><span class="lines">@@ -184,7 +184,7 @@
</span><span class="cx">         String key = query.getColumnText(0);
</span><span class="cx">         String value = query.getColumnBlobAsString(1);
</span><span class="cx">         if (!key.isNull() && !value.isNull())
</span><del>-            items.set(key, value);
</del><ins>+            items.add(WTFMove(key), WTFMove(value));
</ins><span class="cx">         result = query.step();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -193,7 +193,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    storageMap.importItems(items);
</del><ins>+    storageMap.importItems(WTFMove(items));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void LocalStorageDatabase::setItem(const String& key, const String& value)
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitNetworkProcessWebStorageStorageManagercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp    2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.cpp       2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -523,6 +523,10 @@
</span><span class="cx"> void StorageManager::addAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection& allowedConnection)
</span><span class="cx"> {
</span><span class="cx">     auto allowedConnectionID = allowedConnection.uniqueID();
</span><ins>+    auto addResult = m_connections.add(allowedConnectionID);
+    if (addResult.isNewEntry)
+        allowedConnection.addWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName(), m_queue.get(), this);
+
</ins><span class="cx">     m_queue->dispatch([this, protectedThis = makeRef(*this), allowedConnectionID, storageNamespaceID]() mutable {
</span><span class="cx">         ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID));
</span><span class="cx"> 
</span><span class="lines">@@ -533,6 +537,9 @@
</span><span class="cx"> void StorageManager::removeAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection& allowedConnection)
</span><span class="cx"> {
</span><span class="cx">     auto allowedConnectionID = allowedConnection.uniqueID();
</span><ins>+    if (m_connections.remove(allowedConnectionID))
+        allowedConnection.removeWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName());
+
</ins><span class="cx">     m_queue->dispatch([this, protectedThis = makeRef(*this), allowedConnectionID, storageNamespaceID]() mutable {
</span><span class="cx">         ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID));
</span><span class="cx">         if (auto* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID))
</span><span class="lines">@@ -567,6 +574,9 @@
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::processDidCloseConnection(IPC::Connection& connection)
</span><span class="cx"> {
</span><ins>+    if (m_connections.removeAll(connection.uniqueID()))
+        connection.removeWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName());
+
</ins><span class="cx">     m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID()]() mutable {
</span><span class="cx">         Vector<std::pair<IPC::Connection::UniqueID, uint64_t>> connectionAndStorageMapIDPairsToRemove;
</span><span class="cx">         for (auto& storageArea : m_storageAreasByConnection) {
</span><span class="lines">@@ -729,180 +739,170 @@
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::createLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, securityOriginData = securityOriginData.isolatedCopy()]() mutable {
-        std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto connectionID = connection.uniqueID();
+    std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
</ins><span class="cx"> 
</span><del>-        ASSERT((HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair)));
</del><ins>+    ASSERT((HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair)));
</ins><span class="cx"> 
</span><del>-        auto result = m_storageAreasByConnection.add(connectionAndStorageMapIDPair, nullptr);
-        ASSERT(result.isNewEntry);
-        ASSERT((HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::isValidKey(storageNamespaceID)));
</del><ins>+    auto result = m_storageAreasByConnection.add(connectionAndStorageMapIDPair, nullptr);
+    ASSERT(result.isNewEntry);
+    ASSERT((HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::isValidKey(storageNamespaceID)));
</ins><span class="cx"> 
</span><del>-        LocalStorageNamespace* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID);
-        ASSERT(localStorageNamespace);
</del><ins>+    LocalStorageNamespace* localStorageNamespace = getOrCreateLocalStorageNamespace(storageNamespaceID);
+    ASSERT(localStorageNamespace);
</ins><span class="cx"> 
</span><del>-        auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData), m_localStorageDatabaseTracker ? StorageManager::LocalStorageNamespace::IsEphemeral::No : StorageManager::LocalStorageNamespace::IsEphemeral::Yes);
-        storageArea->addListener(connectionID, storageMapID);
</del><ins>+    auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData), m_localStorageDatabaseTracker ? StorageManager::LocalStorageNamespace::IsEphemeral::No : StorageManager::LocalStorageNamespace::IsEphemeral::Yes);
+    storageArea->addListener(connectionID, storageMapID);
</ins><span class="cx"> 
</span><del>-        result.iterator->value = WTFMove(storageArea);
-    });
</del><ins>+    result.iterator->value = WTFMove(storageArea);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::createTransientLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& topLevelOriginData, SecurityOriginData&& origin)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, topLevelOriginData = topLevelOriginData.isolatedCopy(), origin = origin.isolatedCopy()]() mutable {
-        ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID }));
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto connectionID = connection.uniqueID();
</ins><span class="cx"> 
</span><del>-        // See if we already have session storage for this connection/origin combo.
-        // If so, update the map with the new ID, otherwise keep on trucking.
-        for (auto it = m_storageAreasByConnection.begin(), end = m_storageAreasByConnection.end(); it != end; ++it) {
-            if (it->key.first != connectionID)
-                continue;
-            Ref<StorageArea> area = *it->value;
-            if (!area->isEphemeral())
-                continue;
-            if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get()))
-                continue;
-            area->addListener(connectionID, storageMapID);
-            // If the storageMapID used as key in m_storageAreasByConnection is no longer one of the StorageArea's listeners, then this means
-            // that destroyStorageMap() was already called for that storageMapID but it decided not to remove it from m_storageAreasByConnection
-            // so that we could reuse it later on for the same connection/origin combo. In this case, it is safe to remove the previous
-            // storageMapID from m_storageAreasByConnection.
-            if (!area->hasListener(connectionID, it->key.second))
-                m_storageAreasByConnection.remove(it);
-            m_storageAreasByConnection.add({ connectionID, storageMapID }, WTFMove(area));
-            return;
-        }
</del><ins>+    ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID }));
</ins><span class="cx"> 
</span><del>-        auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value;
-        ASSERT(!slot);
</del><ins>+    // See if we already have session storage for this connection/origin combo.
+    // If so, update the map with the new ID, otherwise keep on trucking.
+    for (auto it = m_storageAreasByConnection.begin(), end = m_storageAreasByConnection.end(); it != end; ++it) {
+        if (it->key.first != connectionID)
+            continue;
+        Ref<StorageArea> area = *it->value;
+        if (!area->isEphemeral())
+            continue;
+        if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get()))
+            continue;
+        area->addListener(connectionID, storageMapID);
+        // If the storageMapID used as key in m_storageAreasByConnection is no longer one of the StorageArea's listeners, then this means
+        // that destroyStorageMap() was already called for that storageMapID but it decided not to remove it from m_storageAreasByConnection
+        // so that we could reuse it later on for the same connection/origin combo. In this case, it is safe to remove the previous
+        // storageMapID from m_storageAreasByConnection.
+        if (!area->hasListener(connectionID, it->key.second))
+            m_storageAreasByConnection.remove(it);
+        m_storageAreasByConnection.add({ connectionID, storageMapID }, WTFMove(area));
+        return;
+    }
</ins><span class="cx"> 
</span><del>-        auto* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOriginData));
</del><ins>+    auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value;
+    ASSERT(!slot);
</ins><span class="cx"> 
</span><del>-        auto storageArea = transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin));
-        storageArea->addListener(connectionID, storageMapID);
</del><ins>+    auto* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOriginData));
</ins><span class="cx"> 
</span><del>-        slot = WTFMove(storageArea);
-    });
</del><ins>+    auto storageArea = transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin));
+    storageArea->addListener(connectionID, storageMapID);
+
+    slot = WTFMove(storageArea);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::createSessionStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID, storageNamespaceID, securityOriginData = securityOriginData.isolatedCopy()]() mutable {
-        ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID));
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto connectionID = connection.uniqueID();
+    ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID));
</ins><span class="cx"> 
</span><del>-        SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);
-        if (!sessionStorageNamespace) {
-            // We're getting an incoming message from the web process that's for session storage for a web page
-            // that has already been closed, just ignore it.
-            return;
-        }
</del><ins>+    SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID);
+    if (!sessionStorageNamespace) {
+        // We're getting an incoming message from the web process that's for session storage for a web page
+        // that has already been closed, just ignore it.
+        return;
+    }
</ins><span class="cx"> 
</span><del>-        ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID }));
</del><ins>+    ASSERT(m_storageAreasByConnection.isValidKey({ connectionID, storageMapID }));
</ins><span class="cx"> 
</span><del>-        auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value;
-        ASSERT(!slot);
-        ASSERT(sessionStorageNamespace->allowedConnections().contains(connectionID));
</del><ins>+    auto& slot = m_storageAreasByConnection.add({ connectionID, storageMapID }, nullptr).iterator->value;
+    ASSERT(!slot);
+    ASSERT(sessionStorageNamespace->allowedConnections().contains(connectionID));
</ins><span class="cx"> 
</span><del>-        auto storageArea = sessionStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData));
-        storageArea->addListener(connectionID, storageMapID);
</del><ins>+    auto storageArea = sessionStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData));
+    storageArea->addListener(connectionID, storageMapID);
</ins><span class="cx"> 
</span><del>-        slot = WTFMove(storageArea);
-    });
</del><ins>+    slot = WTFMove(storageArea);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::destroyStorageMap(IPC::Connection& connection, uint64_t storageMapID)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connectionID = connection.uniqueID(), storageMapID]() mutable {
-        std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
-        ASSERT(m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair));
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto connectionID = connection.uniqueID();
</ins><span class="cx"> 
</span><del>-        auto it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair);
-        if (it == m_storageAreasByConnection.end()) {
-            // The connection has been removed because the last page was closed.
-            return;
-        }
</del><ins>+    std::pair<IPC::Connection::UniqueID, uint64_t> connectionAndStorageMapIDPair(connectionID, storageMapID);
+    ASSERT(m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair));
</ins><span class="cx"> 
</span><del>-        it->value->removeListener(connectionID, storageMapID);
</del><ins>+    auto it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair);
+    if (it == m_storageAreasByConnection.end()) {
+        // The connection has been removed because the last page was closed.
+        return;
+    }
</ins><span class="cx"> 
</span><del>-        // Don't remove session storage maps. The web process may reconnect and expect the data to still be around.
-        if (it->value->isEphemeral())
-            return;
</del><ins>+    it->value->removeListener(connectionID, storageMapID);
</ins><span class="cx"> 
</span><del>-        m_storageAreasByConnection.remove(connectionAndStorageMapIDPair);
-    });
-}
</del><ins>+    // Don't remove session storage maps. The web process may reconnect and expect the data to still be around.
+    if (it->value->isEphemeral())
+        return;
</ins><span class="cx"> 
</span><del>-static void didGetValues(IPC::Connection& connection, uint64_t storageMapID, const HashMap<String, String>& items, GetValuesCallback&& completionHandler)
-{
-    RunLoop::main().dispatch([items = crossThreadCopy(items), completionHandler = WTFMove(completionHandler)]() mutable {
-        completionHandler(items);
-    });
</del><ins>+    m_storageAreasByConnection.remove(connectionAndStorageMapIDPair);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::getValues(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t storageMapSeed, GetValuesCallback&& completionHandler)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, storageMapSeed, completionHandler = WTFMove(completionHandler)]() mutable {
-        auto* storageArea = findStorageArea(connection.get(), storageMapID);
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto* storageArea = findStorageArea(connection, storageMapID);
</ins><span class="cx"> 
</span><del>-        // This is a session storage area for a page that has already been closed. Ignore it.
-        if (!storageArea)
-            return didGetValues(connection.get(), storageMapID, { }, WTFMove(completionHandler));
</del><ins>+    // This is a session storage area for a page that has already been closed. Ignore it.
+    if (!storageArea)
+        return completionHandler({ });
</ins><span class="cx"> 
</span><del>-        didGetValues(connection.get(), storageMapID, storageArea->items(), WTFMove(completionHandler));
-        connection->send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID);
-    });
</del><ins>+    completionHandler(storageArea->items());
+    connection.send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::setItem(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, key = key.isolatedCopy(), value = value.isolatedCopy(), urlString = urlString.isolatedCopy()]() mutable {
-        auto* storageArea = findStorageArea(connection.get(), storageMapID);
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto* storageArea = findStorageArea(connection, storageMapID);
</ins><span class="cx"> 
</span><del>-        // This is a session storage area for a page that has already been closed. Ignore it.
-        if (!storageArea)
-            return;
</del><ins>+    // This is a session storage area for a page that has already been closed. Ignore it.
+    if (!storageArea)
+        return;
</ins><span class="cx"> 
</span><del>-        bool quotaError;
-        storageArea->setItem(connection->uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError);
-        connection->send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID);
-    });
</del><ins>+    bool quotaError;
+    storageArea->setItem(connection.uniqueID(), sourceStorageAreaID, key, value, urlString, quotaError);
+    connection.send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::setItems(IPC::Connection& connection, uint64_t storageMapID, const HashMap<String, String>& items)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), storageMapID, items = crossThreadCopy(items)]() mutable {
-        if (auto* storageArea = findStorageArea(connection.get(), storageMapID))
-            storageArea->setItems(items);
-    });
</del><ins>+    ASSERT(!RunLoop::isMain());
+    if (auto* storageArea = findStorageArea(connection, storageMapID))
+        storageArea->setItems(items);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::removeItem(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, key = key.isolatedCopy(), urlString = urlString.isolatedCopy()]() mutable {
-        auto* storageArea = findStorageArea(connection.get(), storageMapID);
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto* storageArea = findStorageArea(connection, storageMapID);
</ins><span class="cx"> 
</span><del>-        // This is a session storage area for a page that has already been closed. Ignore it.
-        if (!storageArea)
-            return;
</del><ins>+    // This is a session storage area for a page that has already been closed. Ignore it.
+    if (!storageArea)
+        return;
</ins><span class="cx"> 
</span><del>-        storageArea->removeItem(connection->uniqueID(), sourceStorageAreaID, key, urlString);
-        connection->send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID);
-    });
</del><ins>+    storageArea->removeItem(connection.uniqueID(), sourceStorageAreaID, key, urlString);
+    connection.send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::clear(IPC::Connection& connection, WebCore::SecurityOriginData&& securityOriginData, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString)
</span><span class="cx"> {
</span><del>-    m_queue->dispatch([this, protectedThis = makeRef(*this), connection = makeRef(connection), securityOriginData = securityOriginData.isolatedCopy(), storageMapID, sourceStorageAreaID, storageMapSeed, urlString = urlString.isolatedCopy()]() mutable {
-        auto* storageArea = findStorageArea(connection.get(), storageMapID);
</del><ins>+    ASSERT(!RunLoop::isMain());
+    auto* storageArea = findStorageArea(connection, storageMapID);
</ins><span class="cx"> 
</span><del>-        // This is a session storage area for a page that has already been closed. Ignore it.
-        if (!storageArea)
-            return;
</del><ins>+    // This is a session storage area for a page that has already been closed. Ignore it.
+    if (!storageArea)
+        return;
</ins><span class="cx"> 
</span><del>-        storageArea->clear(connection->uniqueID(), sourceStorageAreaID, urlString);
-        connection->send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID);
-    });
</del><ins>+    storageArea->clear(connection.uniqueID(), sourceStorageAreaID, urlString);
+    connection.send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageManager::waitUntilTasksFinished()
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitNetworkProcessWebStorageStorageManagerh"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h      2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/NetworkProcess/WebStorage/StorageManager.h 2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include <WebCore/StorageMap.h>
</span><span class="cx"> #include <wtf/Forward.h>
</span><span class="cx"> #include <wtf/Function.h>
</span><ins>+#include <wtf/HashCountedSet.h>
</ins><span class="cx"> #include <wtf/HashSet.h>
</span><span class="cx"> #include <wtf/text/StringHash.h>
</span><span class="cx"> 
</span><span class="lines">@@ -45,7 +46,7 @@
</span><span class="cx"> 
</span><span class="cx"> using GetValuesCallback = CompletionHandler<void(const HashMap<String, String>&)>;
</span><span class="cx"> 
</span><del>-class StorageManager : public ThreadSafeRefCounted<StorageManager, WTF::DestructionThread::MainRunLoop> {
</del><ins>+class StorageManager : public IPC::Connection::WorkQueueMessageReceiver {
</ins><span class="cx"> public:
</span><span class="cx">     static Ref<StorageManager> create(String&& localStorageDirectory);
</span><span class="cx">     ~StorageManager();
</span><span class="lines">@@ -111,6 +112,7 @@
</span><span class="cx">     HashMap<uint64_t, RefPtr<SessionStorageNamespace>> m_sessionStorageNamespaces;
</span><span class="cx"> 
</span><span class="cx">     HashMap<std::pair<IPC::Connection::UniqueID, uint64_t>, RefPtr<StorageArea>> m_storageAreasByConnection;
</span><ins>+    HashCountedSet<IPC::Connection::UniqueID> m_connections;
</ins><span class="cx"> 
</span><span class="cx">     enum class State {
</span><span class="cx">         Running,
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitPlatformIPCConnectioncpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.cpp     2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.cpp        2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -307,11 +307,10 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><span class="cx"> 
</span><del>-    m_connectionQueue->dispatch([protectedThis = makeRef(*this), messageReceiverName = WTFMove(messageReceiverName), workQueue = &workQueue, workQueueMessageReceiver]() mutable {
-        ASSERT(!protectedThis->m_workQueueMessageReceivers.contains(messageReceiverName));
</del><ins>+    std::lock_guard<Lock> lock(m_workQueueMessageReceiversMutex);
+    ASSERT(!m_workQueueMessageReceivers.contains(messageReceiverName));
</ins><span class="cx"> 
</span><del>-        protectedThis->m_workQueueMessageReceivers.add(messageReceiverName, std::make_pair(workQueue, workQueueMessageReceiver));
-    });
</del><ins>+    m_workQueueMessageReceivers.add(messageReceiverName, std::make_pair(&workQueue, workQueueMessageReceiver));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Connection::removeWorkQueueMessageReceiver(StringReference messageReceiverName)
</span><span class="lines">@@ -318,10 +317,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(RunLoop::isMain());
</span><span class="cx"> 
</span><del>-    m_connectionQueue->dispatch([protectedThis = makeRef(*this), messageReceiverName = WTFMove(messageReceiverName)]() mutable {
-        ASSERT(protectedThis->m_workQueueMessageReceivers.contains(messageReceiverName));
-        protectedThis->m_workQueueMessageReceivers.remove(messageReceiverName);
-    });
</del><ins>+    std::lock_guard<Lock> lock(m_workQueueMessageReceiversMutex);
+    ASSERT(m_workQueueMessageReceivers.contains(messageReceiverName));
+    m_workQueueMessageReceivers.remove(messageReceiverName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Connection::dispatchWorkQueueMessageReceiverMessage(WorkQueueMessageReceiver& workQueueMessageReceiver, Decoder& decoder)
</span><span class="lines">@@ -693,7 +691,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_workQueueMessageReceivers.isValidKey(message->messageReceiverName())) {
</del><ins>+    if (!WorkQueueMessageReceiverMap::isValidKey(message->messageReceiverName())) {
</ins><span class="cx">         RefPtr<Connection> protectedThis(this);
</span><span class="cx">         StringReference messageReceiverNameReference = message->messageReceiverName();
</span><span class="cx">         String messageReceiverName(messageReceiverNameReference.isEmpty() ? "<unknown message receiver>" : String(messageReceiverNameReference.data(), messageReceiverNameReference.size()));
</span><span class="lines">@@ -706,13 +704,8 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto it = m_workQueueMessageReceivers.find(message->messageReceiverName());
-    if (it != m_workQueueMessageReceivers.end()) {
-        it->value.first->dispatch([protectedThis = makeRef(*this), workQueueMessageReceiver = it->value.second, decoder = WTFMove(message)]() mutable {
-            protectedThis->dispatchWorkQueueMessageReceiverMessage(*workQueueMessageReceiver, *decoder);
-        });
</del><ins>+    if (dispatchMessageToWorkQueueReceiver(message))
</ins><span class="cx">         return;
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="cx">     if (message->isSyncMessage() && m_shouldBoostMainThreadOnSyncMessage) {
</span><span class="lines">@@ -987,14 +980,37 @@
</span><span class="cx">         handler(&decoder);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx">     m_client.didReceiveMessage(*this, decoder);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool Connection::dispatchMessageToWorkQueueReceiver(std::unique_ptr<Decoder>& message)
+{
+    std::lock_guard<Lock> lock(m_workQueueMessageReceiversMutex);
+    auto it = m_workQueueMessageReceivers.find(message->messageReceiverName());
+    if (it != m_workQueueMessageReceivers.end()) {
+        it->value.first->dispatch([protectedThis = makeRef(*this), workQueueMessageReceiver = it->value.second, decoder = WTFMove(message)]() mutable {
+            protectedThis->dispatchWorkQueueMessageReceiverMessage(*workQueueMessageReceiver, *decoder);
+        });
+        return true;
+    }
+    return false;
+}
+
</ins><span class="cx"> void Connection::dispatchMessage(std::unique_ptr<Decoder> message)
</span><span class="cx"> {
</span><ins>+    ASSERT(RunLoop::isMain());
</ins><span class="cx">     if (!isValid())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    // Messages to WorkQueueMessageReceivers are normally dispatched from the IPC WorkQueue. However, there is a race if
+    // a client adds itself as a WorkQueueMessageReceiver as a result of receiving an IPC message on the main thread.
+    // The message might have already been dispatched from the IPC WorkQueue to the main thread by the time the
+    // client registers itself as a WorkQueueMessageReceiver. To address this, we check again for messages receivers
+    // once the message arrives on the main thread.
+    if (dispatchMessageToWorkQueueReceiver(message))
+        return;
+
</ins><span class="cx">     if (message->shouldUseFullySynchronousModeForTesting()) {
</span><span class="cx">         if (!m_fullySynchronousModeIsAllowedForTesting) {
</span><span class="cx">             m_client.didReceiveInvalidMessage(*this, message->messageReceiverName(), message->messageName());
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitPlatformIPCConnectionh"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.h (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.h       2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/Platform/IPC/Connection.h  2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -262,6 +262,8 @@
</span><span class="cx">     
</span><span class="cx">     std::unique_ptr<Decoder> waitForSyncReply(uint64_t syncRequestID, Seconds timeout, OptionSet<SendSyncOption>);
</span><span class="cx"> 
</span><ins>+    bool dispatchMessageToWorkQueueReceiver(std::unique_ptr<Decoder>&);
+
</ins><span class="cx">     // Called on the connection work queue.
</span><span class="cx">     void processIncomingMessage(std::unique_ptr<Decoder>);
</span><span class="cx">     void processIncomingSyncReply(std::unique_ptr<Decoder>);
</span><span class="lines">@@ -325,7 +327,9 @@
</span><span class="cx">     bool m_isConnected;
</span><span class="cx">     Ref<WorkQueue> m_connectionQueue;
</span><span class="cx"> 
</span><del>-    HashMap<StringReference, std::pair<RefPtr<WorkQueue>, RefPtr<WorkQueueMessageReceiver>>> m_workQueueMessageReceivers;
</del><ins>+    Lock m_workQueueMessageReceiversMutex;
+    using WorkQueueMessageReceiverMap = HashMap<StringReference, std::pair<RefPtr<WorkQueue>, RefPtr<WorkQueueMessageReceiver>>>;
+    WorkQueueMessageReceiverMap m_workQueueMessageReceivers;
</ins><span class="cx"> 
</span><span class="cx">     unsigned m_inSendSyncCount;
</span><span class="cx">     unsigned m_inDispatchMessageCount;
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitWebProcessWebStorageStorageAreaMapcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp        2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp   2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -181,7 +181,7 @@
</span><span class="cx">     WebProcess::singleton().ensureNetworkProcessConnection().connection().sendSync(Messages::StorageManager::GetValues(m_securityOrigin->data(), m_storageMapID, m_currentSeed), Messages::StorageManager::GetValues::Reply(values), 0);
</span><span class="cx"> 
</span><span class="cx">     m_storageMap = StorageMap::create(m_quotaInBytes);
</span><del>-    m_storageMap->importItems(values);
</del><ins>+    m_storageMap->importItems(WTFMove(values));
</ins><span class="cx"> 
</span><span class="cx">     // We want to ignore all changes until we get the DidGetValues message.
</span><span class="cx">     m_hasPendingGetValues = true;
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitLegacyChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKitLegacy/ChangeLog (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKitLegacy/ChangeLog 2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKitLegacy/ChangeLog    2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -1,3 +1,89 @@
</span><ins>+2019-07-17  Kocsen Chung  <kocsen_chung@apple.com>
+
+        Cherry-pick r247486. rdar://problem/53229738
+
+    Speed up StorageManager::getValues()
+    https://bugs.webkit.org/show_bug.cgi?id=199812
+    
+    Reviewed by Alex Christensen.
+    
+    Source/WebCore:
+    
+    * storage/StorageMap.cpp:
+    (WebCore::StorageMap::importItems):
+    * storage/StorageMap.h:
+    
+    Source/WebKit:
+    
+    Made the following performance improvements:
+    - Made StorageManager a WorkQueueMessageReceiver again (like it was before it
+      got moved from the UIProcess to the Network process). This avoids a lot of
+      thread hopping (IPC thread -> Main thread -> StorageManagerThread -> Main Thread)
+      and a lot of isolatedCopying of the strings.
+    - Move values around when possible to avoid copying.
+    - Add fast path to StorageMap::importItems() for when the StorageMap is
+      empty when importing (15ms -> 2.5ms).
+    
+    * NetworkProcess/NetworkConnectionToWebProcess.cpp:
+    (WebKit::NetworkConnectionToWebProcess::didReceiveMessage):
+    (WebKit::NetworkConnectionToWebProcess::didReceiveSyncMessage):
+    * NetworkProcess/WebStorage/LocalStorageDatabase.cpp:
+    (WebKit::LocalStorageDatabase::importItems):
+    * NetworkProcess/WebStorage/StorageManager.cpp:
+    (WebKit::StorageManager::addAllowedSessionStorageNamespaceConnection):
+    (WebKit::StorageManager::removeAllowedSessionStorageNamespaceConnection):
+    (WebKit::StorageManager::processDidCloseConnection):
+    (WebKit::StorageManager::createLocalStorageMap):
+    (WebKit::StorageManager::createTransientLocalStorageMap):
+    (WebKit::StorageManager::createSessionStorageMap):
+    (WebKit::StorageManager::destroyStorageMap):
+    (WebKit::StorageManager::getValues):
+    (WebKit::StorageManager::setItem):
+    (WebKit::StorageManager::setItems):
+    (WebKit::StorageManager::removeItem):
+    (WebKit::StorageManager::clear):
+    * NetworkProcess/WebStorage/StorageManager.h:
+    
+    * Platform/IPC/Connection.cpp:
+    (IPC::Connection::addWorkQueueMessageReceiver):
+    (IPC::Connection::removeWorkQueueMessageReceiver):
+    (IPC::Connection::processIncomingMessage):
+    (IPC::Connection::dispatchMessage):
+    (IPC::Connection::dispatchMessageToWorkQueueReceiver):
+    * Platform/IPC/Connection.h:
+    * WebProcess/WebStorage/StorageAreaMap.cpp:
+    (WebKit::StorageAreaMap::loadValuesIfNeeded):
+    Messages to WorkQueueMessageReceivers are normally dispatched from the IPC WorkQueue. However, there is a race if
+    a client (here StorageManager) adds itself as a WorkQueueMessageReceiver as a result of receiving an IPC message
+    on the main thread (here NetworkConnectionToWebProcess::WebPageWasAdded).
+    The message might have already been dispatched from the IPC WorkQueue to the main thread by the time the
+    client registers itself as a WorkQueueMessageReceiver. To address this, we check again for messages receivers
+    once the message arrives on the main thread.
+    
+    Source/WebKitLegacy:
+    
+    * Storage/StorageAreaImpl.cpp:
+    (WebKit::StorageAreaImpl::importItems):
+    * Storage/StorageAreaImpl.h:
+    * Storage/StorageAreaSync.cpp:
+    (WebKit::StorageAreaSync::performImport):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247486 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-07-16  Chris Dumez  <cdumez@apple.com>
+
+            Speed up StorageManager::getValues()
+            https://bugs.webkit.org/show_bug.cgi?id=199812
+
+            Reviewed by Alex Christensen.
+
+            * Storage/StorageAreaImpl.cpp:
+            (WebKit::StorageAreaImpl::importItems):
+            * Storage/StorageAreaImpl.h:
+            * Storage/StorageAreaSync.cpp:
+            (WebKit::StorageAreaSync::performImport):
+
</ins><span class="cx"> 2019-07-12  Alex Christensen  <achristensen@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         Begin unifying WebKitLegacy sources
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitLegacyStorageStorageAreaImplcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp       2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp  2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -194,11 +194,11 @@
</span><span class="cx">     return m_storageMap->contains(key);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StorageAreaImpl::importItems(const HashMap<String, String>& items)
</del><ins>+void StorageAreaImpl::importItems(HashMap<String, String>&& items)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_isShutdown);
</span><span class="cx"> 
</span><del>-    m_storageMap->importItems(items);
</del><ins>+    m_storageMap->importItems(WTFMove(items));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageAreaImpl::close()
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitLegacyStorageStorageAreaImplh"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.h (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.h 2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaImpl.h    2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -67,7 +67,7 @@
</span><span class="cx">     void close();
</span><span class="cx"> 
</span><span class="cx">     // Only called from a background thread.
</span><del>-    void importItems(const HashMap<String, String>& items);
</del><ins>+    void importItems(HashMap<String, String>&& items);
</ins><span class="cx"> 
</span><span class="cx">     // Used to clear a StorageArea and close db before backing db file is deleted.
</span><span class="cx">     void clearForOriginDeletion();
</span></span></pre></div>
<a id="branchessafari608branchSourceWebKitLegacyStorageStorageAreaSynccpp"></a>
<div class="modfile"><h4>Modified: branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaSync.cpp (247593 => 247594)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaSync.cpp       2019-07-18 20:23:53 UTC (rev 247593)
+++ branches/safari-608-branch/Source/WebKitLegacy/Storage/StorageAreaSync.cpp  2019-07-18 20:23:58 UTC (rev 247594)
</span><span class="lines">@@ -347,7 +347,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_storageArea->importItems(itemMap);
</del><ins>+    m_storageArea->importItems(WTFMove(itemMap));
</ins><span class="cx"> 
</span><span class="cx">     markImported();
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>