Title: [290223] trunk/Source
Revision
290223
Author
[email protected]
Date
2022-02-19 23:12:29 -0800 (Sat, 19 Feb 2022)

Log Message

Optimize DOM storage event dispatch
https://bugs.webkit.org/show_bug.cgi?id=236871

Reviewed by Sihui Liu.

Made the following optimization to DOM storage event dispatch:
1. Pass a SecurityOrigin around instead of a SecurityOriginData. Otherwise,
   dispatchLocalStorageEvents() / dispatchSessionStorageEvents() just keep
   reconstructing the SecurityOrigin from the SecurityOriginData for every
   frame.
2. When gathering the list of frames where we need to dispatch the storage
   event, discard the ones that do not have a "storage" event listener.

Source/WebCore:

* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didDispatchDOMStorageEventImpl):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::didDispatchDOMStorageEvent):
* inspector/agents/InspectorDOMStorageAgent.cpp:
(WebCore::InspectorDOMStorageAgent::storageId):
(WebCore::InspectorDOMStorageAgent::didDispatchDOMStorageEvent):
(WebCore::InspectorDOMStorageAgent::findStorageArea):
* inspector/agents/InspectorDOMStorageAgent.h:
* loader/EmptyClients.cpp:
* page/DOMWindow.cpp:
* storage/StorageEventDispatcher.cpp:
(WebCore::StorageEventDispatcher::dispatchSessionStorageEvents):
(WebCore::StorageEventDispatcher::dispatchLocalStorageEvents):
(WebCore::StorageEventDispatcher::dispatchSessionStorageEventsToFrames):
(WebCore::StorageEventDispatcher::dispatchLocalStorageEventsToFrames):
* storage/StorageEventDispatcher.h:
* storage/StorageNamespace.h:
* storage/StorageNamespaceProvider.cpp:
(WebCore::StorageNamespaceProvider::localStorageArea):

Source/WebKit:

* WebProcess/WebStorage/StorageAreaMap.cpp:
(WebKit::StorageAreaMap::StorageAreaMap):
(WebKit::framesForEventDispatching):
(WebKit::StorageAreaMap::dispatchSessionStorageEvent):
(WebKit::StorageAreaMap::dispatchLocalStorageEvent):
* WebProcess/WebStorage/StorageAreaMap.h:
* WebProcess/WebStorage/StorageNamespaceImpl.cpp:
(WebKit::StorageNamespaceImpl::storageArea):
* WebProcess/WebStorage/StorageNamespaceImpl.h:

Source/WebKitLegacy:

* Storage/StorageAreaImpl.cpp:
(WebKit::StorageAreaImpl::StorageAreaImpl):
(WebKit::StorageAreaImpl::create):
(WebKit::StorageAreaImpl::clearForOriginDeletion):
(WebKit::StorageAreaImpl::sync):
(WebKit::StorageAreaImpl::sessionChanged):
* Storage/StorageAreaImpl.h:
* Storage/StorageNamespaceImpl.cpp:
(WebKit::StorageNamespaceImpl::storageArea):
* Storage/StorageNamespaceImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (290222 => 290223)


--- trunk/Source/WebCore/ChangeLog	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/ChangeLog	2022-02-20 07:12:29 UTC (rev 290223)
@@ -1,3 +1,39 @@
+2022-02-19  Chris Dumez  <[email protected]>
+
+        Optimize DOM storage event dispatch
+        https://bugs.webkit.org/show_bug.cgi?id=236871
+
+        Reviewed by Sihui Liu.
+
+        Made the following optimization to DOM storage event dispatch:
+        1. Pass a SecurityOrigin around instead of a SecurityOriginData. Otherwise,
+           dispatchLocalStorageEvents() / dispatchSessionStorageEvents() just keep
+           reconstructing the SecurityOrigin from the SecurityOriginData for every
+           frame.
+        2. When gathering the list of frames where we need to dispatch the storage
+           event, discard the ones that do not have a "storage" event listener.
+
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didDispatchDOMStorageEventImpl):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::didDispatchDOMStorageEvent):
+        * inspector/agents/InspectorDOMStorageAgent.cpp:
+        (WebCore::InspectorDOMStorageAgent::storageId):
+        (WebCore::InspectorDOMStorageAgent::didDispatchDOMStorageEvent):
+        (WebCore::InspectorDOMStorageAgent::findStorageArea):
+        * inspector/agents/InspectorDOMStorageAgent.h:
+        * loader/EmptyClients.cpp:
+        * page/DOMWindow.cpp:
+        * storage/StorageEventDispatcher.cpp:
+        (WebCore::StorageEventDispatcher::dispatchSessionStorageEvents):
+        (WebCore::StorageEventDispatcher::dispatchLocalStorageEvents):
+        (WebCore::StorageEventDispatcher::dispatchSessionStorageEventsToFrames):
+        (WebCore::StorageEventDispatcher::dispatchLocalStorageEventsToFrames):
+        * storage/StorageEventDispatcher.h:
+        * storage/StorageNamespace.h:
+        * storage/StorageNamespaceProvider.cpp:
+        (WebCore::StorageNamespaceProvider::localStorageArea):
+
 2022-02-19  Mark Lam  <[email protected]>
 
         [Re-landing] Provide a WebCore subspaceImplFor template to make code more readable.

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (290222 => 290223)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -1007,7 +1007,7 @@
         databaseAgent->didOpenDatabase(database);
 }
 
-void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents& instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin)
+void InspectorInstrumentation::didDispatchDOMStorageEventImpl(InstrumentingAgents& instrumentingAgents, const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
 {
     if (auto* domStorageAgent = instrumentingAgents.enabledDOMStorageAgent())
         domStorageAgent->didDispatchDOMStorageEvent(key, oldValue, newValue, storageType, securityOrigin);

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (290222 => 290223)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -274,7 +274,7 @@
 
     static void didOpenDatabase(Database&);
 
-    static void didDispatchDOMStorageEvent(Page&, const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*);
+    static void didDispatchDOMStorageEvent(Page&, const String& key, const String& oldValue, const String& newValue, StorageType, const SecurityOrigin&);
 
     static bool shouldWaitForDebuggerOnStart(ScriptExecutionContext&);
     static void workerStarted(WorkerInspectorProxy&);
@@ -477,7 +477,7 @@
 
     static void didOpenDatabaseImpl(InstrumentingAgents&, Database&);
 
-    static void didDispatchDOMStorageEventImpl(InstrumentingAgents&, const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*);
+    static void didDispatchDOMStorageEventImpl(InstrumentingAgents&, const String& key, const String& oldValue, const String& newValue, StorageType, const SecurityOrigin&);
 
     static bool shouldWaitForDebuggerOnStartImpl(InstrumentingAgents&);
     static void workerStartedImpl(InstrumentingAgents&, WorkerInspectorProxy&);
@@ -1325,7 +1325,7 @@
         didOpenDatabaseImpl(*agents, database);
 }
 
-inline void InspectorInstrumentation::didDispatchDOMStorageEvent(Page& page, const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin)
+inline void InspectorInstrumentation::didDispatchDOMStorageEvent(Page& page, const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
     didDispatchDOMStorageEventImpl(instrumentingAgents(page), key, oldValue, newValue, storageType, securityOrigin);

Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.cpp (290222 => 290223)


--- trunk/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -168,18 +168,18 @@
     ASSERT(window);
     Ref<SecurityOrigin> securityOrigin = document->securityOrigin();
     bool isLocalStorage = window->optionalLocalStorage() == &storage;
-    return InspectorDOMStorageAgent::storageId(securityOrigin.ptr(), isLocalStorage)->toJSONString();
+    return InspectorDOMStorageAgent::storageId(securityOrigin, isLocalStorage)->toJSONString();
 }
 
-Ref<Protocol::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage)
+Ref<Protocol::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(const SecurityOrigin& securityOrigin, bool isLocalStorage)
 {
     return Protocol::DOMStorage::StorageId::create()
-        .setSecurityOrigin(securityOrigin->toRawString())
+        .setSecurityOrigin(securityOrigin.toRawString())
         .setIsLocalStorage(isLocalStorage)
         .release();
 }
 
-void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, SecurityOrigin* securityOrigin)
+void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType storageType, const SecurityOrigin& securityOrigin)
 {
     auto id = InspectorDOMStorageAgent::storageId(securityOrigin, storageType == StorageType::Local);
 
@@ -214,7 +214,7 @@
     }
 
     if (!*isLocalStorage)
-        return m_inspectedPage.sessionStorage()->storageArea(targetFrame->document()->securityOrigin().data());
+        return m_inspectedPage.sessionStorage()->storageArea(targetFrame->document()->securityOrigin());
     return m_inspectedPage.storageNamespaceProvider().localStorageArea(*targetFrame->document());
 }
 

Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h (290222 => 290223)


--- trunk/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMStorageAgent.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -65,11 +65,11 @@
     Inspector::Protocol::ErrorStringOr<void> clearDOMStorageItems(Ref<JSON::Object>&& storageId);
 
     // InspectorInstrumentation
-    void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*);
+    void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, const SecurityOrigin&);
 
     // CommandLineAPI
     static String storageId(Storage&);
-    static Ref<Inspector::Protocol::DOMStorage::StorageId> storageId(SecurityOrigin*, bool isLocalStorage);
+    static Ref<Inspector::Protocol::DOMStorage::StorageId> storageId(const SecurityOrigin&, bool isLocalStorage);
 
 private:
     RefPtr<StorageArea> findStorageArea(Inspector::Protocol::ErrorString&, Ref<JSON::Object>&& storageId, Frame*&);

Modified: trunk/Source/WebCore/loader/EmptyClients.cpp (290222 => 290223)


--- trunk/Source/WebCore/loader/EmptyClients.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/loader/EmptyClients.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -498,7 +498,7 @@
         {
         }
     private:
-        Ref<StorageArea> storageArea(const SecurityOriginData&) final { return adoptRef(*new EmptyStorageArea); }
+        Ref<StorageArea> storageArea(const SecurityOrigin&) final { return adoptRef(*new EmptyStorageArea); }
         Ref<StorageNamespace> copy(Page&) final { return adoptRef(*new EmptyStorageNamespace { m_sessionID }); }
         PAL::SessionID sessionID() const final { return m_sessionID; }
         void setSessionIDForTesting(PAL::SessionID sessionID) final { m_sessionID = sessionID; };

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (290222 => 290223)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -830,7 +830,7 @@
     if (!page)
         return nullptr;
 
-    auto storageArea = page->sessionStorage()->storageArea(document->securityOrigin().data());
+    auto storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
     m_sessionStorage = Storage::create(*this, WTFMove(storageArea));
     return m_sessionStorage.get();
 }

Modified: trunk/Source/WebCore/storage/StorageEventDispatcher.cpp (290222 => 290223)


--- trunk/Source/WebCore/storage/StorageEventDispatcher.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/storage/StorageEventDispatcher.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -40,40 +40,40 @@
 
 namespace WebCore {
 
-void StorageEventDispatcher::dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData& securityOrigin, Frame* sourceFrame)
+void StorageEventDispatcher::dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOrigin& securityOrigin, Frame* sourceFrame)
 {
     Page* page = sourceFrame->page();
     if (!page)
         return;
 
-    Vector<RefPtr<Frame>> frames;
+    Vector<Ref<Frame>> frames;
 
     // Send events only to our page.
     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (!frame->document())
+        if (auto* window = frame->window(); !window || !window->hasEventListeners(eventNames().storageEvent))
             continue;
-        if (sourceFrame != frame && frame->document()->securityOrigin().equal(securityOrigin.securityOrigin().ptr()))
-            frames.append(frame);
+        if (sourceFrame != frame && frame->document()->securityOrigin().equal(&securityOrigin))
+            frames.append(*frame);
     }
 
     dispatchSessionStorageEventsToFrames(*page, frames, key, oldValue, newValue, sourceFrame->document()->url().string(), securityOrigin);
 }
 
-void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData& securityOrigin, Frame* sourceFrame)
+void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOrigin& securityOrigin, Frame* sourceFrame)
 {
     Page* page = sourceFrame->page();
     if (!page)
         return;
 
-    Vector<RefPtr<Frame>> frames;
+    Vector<Ref<Frame>> frames;
 
     // Send events to every page.
     for (auto& pageInGroup : page->group().pages()) {
         for (auto* frame = &pageInGroup.mainFrame(); frame; frame = frame->tree().traverseNext()) {
-            if (!frame->document())
+            if (auto* window = frame->window(); !window || !window->hasEventListeners(eventNames().storageEvent))
                 continue;
-            if (sourceFrame != frame && frame->document()->securityOrigin().equal(securityOrigin.securityOrigin().ptr()))
-                frames.append(frame);
+            if (sourceFrame != frame && frame->document()->securityOrigin().equal(&securityOrigin))
+                frames.append(*frame);
         }
     }
 
@@ -80,9 +80,9 @@
     dispatchLocalStorageEventsToFrames(page->group(), frames, key, oldValue, newValue, sourceFrame->document()->url().string(), securityOrigin);
 }
 
-void StorageEventDispatcher::dispatchSessionStorageEventsToFrames(Page& page, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData& securityOrigin)
+void StorageEventDispatcher::dispatchSessionStorageEventsToFrames(Page& page, const Vector<Ref<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOrigin& securityOrigin)
 {
-    InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, StorageType::Session, securityOrigin.securityOrigin().ptr());
+    InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, StorageType::Session, securityOrigin);
 
     for (auto& frame : frames) {
         RefPtr document = frame->document();
@@ -92,10 +92,10 @@
     }
 }
 
-void StorageEventDispatcher::dispatchLocalStorageEventsToFrames(PageGroup& pageGroup, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData& securityOrigin)
+void StorageEventDispatcher::dispatchLocalStorageEventsToFrames(PageGroup& pageGroup, const Vector<Ref<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOrigin& securityOrigin)
 {
     for (auto& page : pageGroup.pages())
-        InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, StorageType::Local, securityOrigin.securityOrigin().ptr());
+        InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, StorageType::Local, securityOrigin);
 
     for (auto& frame : frames) {
         RefPtr document = frame->document();

Modified: trunk/Source/WebCore/storage/StorageEventDispatcher.h (290222 => 290223)


--- trunk/Source/WebCore/storage/StorageEventDispatcher.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/storage/StorageEventDispatcher.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -36,15 +36,15 @@
 class Frame;
 class Page;
 class PageGroup;
-struct SecurityOriginData;
+class SecurityOrigin;
 
 class StorageEventDispatcher {
 public:
-    WEBCORE_EXPORT static void dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData&, Frame* sourceFrame);
-    WEBCORE_EXPORT static void dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOriginData&, Frame* sourceFrame);
+    WEBCORE_EXPORT static void dispatchSessionStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOrigin&, Frame* sourceFrame);
+    WEBCORE_EXPORT static void dispatchLocalStorageEvents(const String& key, const String& oldValue, const String& newValue, const SecurityOrigin&, Frame* sourceFrame);
 
-    WEBCORE_EXPORT static void dispatchSessionStorageEventsToFrames(Page&, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData&);
-    WEBCORE_EXPORT static void dispatchLocalStorageEventsToFrames(PageGroup&, const Vector<RefPtr<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOriginData&);
+    WEBCORE_EXPORT static void dispatchSessionStorageEventsToFrames(Page&, const Vector<Ref<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOrigin&);
+    WEBCORE_EXPORT static void dispatchLocalStorageEventsToFrames(PageGroup&, const Vector<Ref<Frame>>& frames, const String& key, const String& oldValue, const String& newValue, const String& url, const SecurityOrigin&);
 private:
     // Do not instantiate.
     StorageEventDispatcher();

Modified: trunk/Source/WebCore/storage/StorageNamespace.h (290222 => 290223)


--- trunk/Source/WebCore/storage/StorageNamespace.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/storage/StorageNamespace.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -35,13 +35,13 @@
 namespace WebCore {
 
 class Page;
+class SecurityOrigin;
 class StorageArea;
-struct SecurityOriginData;
 
 class StorageNamespace : public RefCounted<StorageNamespace> {
 public:
     virtual ~StorageNamespace() = default;
-    virtual Ref<StorageArea> storageArea(const SecurityOriginData&) = 0;
+    virtual Ref<StorageArea> storageArea(const SecurityOrigin&) = 0;
 
     // FIXME: This is only valid for session storage and should probably be moved to a subclass.
     virtual Ref<StorageNamespace> copy(Page& newPage) = 0;

Modified: trunk/Source/WebCore/storage/StorageNamespaceProvider.cpp (290222 => 290223)


--- trunk/Source/WebCore/storage/StorageNamespaceProvider.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebCore/storage/StorageNamespaceProvider.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -60,7 +60,7 @@
     else
         storageNamespace = &localStorageNamespace(document.page()->sessionID());
 
-    return storageNamespace->storageArea(document.securityOrigin().data());
+    return storageNamespace->storageArea(document.securityOrigin());
 }
 
 StorageNamespace& StorageNamespaceProvider::localStorageNamespace(PAL::SessionID sessionID)

Modified: trunk/Source/WebKit/ChangeLog (290222 => 290223)


--- trunk/Source/WebKit/ChangeLog	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKit/ChangeLog	2022-02-20 07:12:29 UTC (rev 290223)
@@ -1,3 +1,28 @@
+2022-02-19  Chris Dumez  <[email protected]>
+
+        Optimize DOM storage event dispatch
+        https://bugs.webkit.org/show_bug.cgi?id=236871
+
+        Reviewed by Sihui Liu.
+
+        Made the following optimization to DOM storage event dispatch:
+        1. Pass a SecurityOrigin around instead of a SecurityOriginData. Otherwise,
+           dispatchLocalStorageEvents() / dispatchSessionStorageEvents() just keep
+           reconstructing the SecurityOrigin from the SecurityOriginData for every
+           frame.
+        2. When gathering the list of frames where we need to dispatch the storage
+           event, discard the ones that do not have a "storage" event listener.
+
+        * WebProcess/WebStorage/StorageAreaMap.cpp:
+        (WebKit::StorageAreaMap::StorageAreaMap):
+        (WebKit::framesForEventDispatching):
+        (WebKit::StorageAreaMap::dispatchSessionStorageEvent):
+        (WebKit::StorageAreaMap::dispatchLocalStorageEvent):
+        * WebProcess/WebStorage/StorageAreaMap.h:
+        * WebProcess/WebStorage/StorageNamespaceImpl.cpp:
+        (WebKit::StorageNamespaceImpl::storageArea):
+        * WebProcess/WebStorage/StorageNamespaceImpl.h:
+
 2022-02-19  Tim Horton  <[email protected]>
 
         macCatalyst: WKWebView crashes whenever the view frame changes

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp (290222 => 290223)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -38,6 +38,7 @@
 #include "WebProcess.h"
 #include <WebCore/DOMWindow.h>
 #include <WebCore/Document.h>
+#include <WebCore/EventNames.h>
 #include <WebCore/Frame.h>
 #include <WebCore/Page.h>
 #include <WebCore/PageGroup.h>
@@ -50,7 +51,7 @@
 namespace WebKit {
 using namespace WebCore;
 
-StorageAreaMap::StorageAreaMap(StorageNamespaceImpl& storageNamespace, Ref<WebCore::SecurityOrigin>&& securityOrigin)
+StorageAreaMap::StorageAreaMap(StorageNamespaceImpl& storageNamespace, Ref<const WebCore::SecurityOrigin>&& securityOrigin)
     : m_identifier(StorageAreaMapIdentifier::generate())
     , m_namespace(storageNamespace)
     , m_securityOrigin(WTFMove(securityOrigin))
@@ -295,15 +296,15 @@
     resetValues();
 }
 
-static Vector<RefPtr<Frame>> framesForEventDispatching(Page& page, SecurityOrigin& origin, StorageType storageType, const std::optional<StorageAreaImplIdentifier>& storageAreaImplID)
+static Vector<Ref<Frame>> framesForEventDispatching(Page& page, const SecurityOrigin& origin, StorageType storageType, const std::optional<StorageAreaImplIdentifier>& storageAreaImplID)
 {
-    Vector<RefPtr<Frame>> frames;
+    Vector<Ref<Frame>> frames;
     page.forEachDocument([&](auto& document) {
         if (!document.securityOrigin().equal(&origin))
             return;
 
         auto* window = document.domWindow();
-        if (!window)
+        if (!window || !window->hasEventListeners(eventNames().storageEvent))
             return;
         
         Storage* storage = nullptr;
@@ -327,7 +328,7 @@
         }
        
         if (auto* frame = document.frame()) 
-            frames.append(frame);
+            frames.append(*frame);
     });
     return frames;
 }
@@ -345,7 +346,7 @@
         return;
 
     auto frames = framesForEventDispatching(*page, m_securityOrigin, StorageType::Session, storageAreaImplID);
-    StorageEventDispatcher::dispatchSessionStorageEventsToFrames(*page, frames, key, oldValue, newValue, urlString, m_securityOrigin->data());
+    StorageEventDispatcher::dispatchSessionStorageEventsToFrames(*page, frames, key, oldValue, newValue, urlString, m_securityOrigin);
 }
 
 void StorageAreaMap::dispatchLocalStorageEvent(const std::optional<StorageAreaImplIdentifier>& storageAreaImplID, const String& key, const String& oldValue, const String& newValue, const String& urlString)
@@ -352,7 +353,7 @@
 {
     ASSERT(isLocalStorage(type()));
 
-    Vector<RefPtr<Frame>> frames;
+    Vector<Ref<Frame>> frames;
 
     // Namespace IDs for local storage namespaces are currently equivalent to web page group IDs.
     auto& pageGroup = *WebProcess::singleton().webPageGroup(m_namespace.pageGroupID())->corePageGroup();
@@ -359,7 +360,7 @@
     for (auto& page : pageGroup.pages())
         frames.appendVector(framesForEventDispatching(page, m_securityOrigin, StorageType::Local, storageAreaImplID));
 
-    StorageEventDispatcher::dispatchLocalStorageEventsToFrames(pageGroup, frames, key, oldValue, newValue, urlString, m_securityOrigin->data());
+    StorageEventDispatcher::dispatchLocalStorageEventsToFrames(pageGroup, frames, key, oldValue, newValue, urlString, m_securityOrigin);
 }
 
 void StorageAreaMap::sendConnectMessage(SendMode mode)

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h (290222 => 290223)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageAreaMap.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -50,7 +50,7 @@
 class StorageAreaMap final : public IPC::MessageReceiver {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    StorageAreaMap(StorageNamespaceImpl&, Ref<WebCore::SecurityOrigin>&&);
+    StorageAreaMap(StorageNamespaceImpl&, Ref<const WebCore::SecurityOrigin>&&);
     ~StorageAreaMap();
 
     WebCore::StorageType type() const { return m_type; }
@@ -100,7 +100,7 @@
     StorageAreaMapIdentifier m_identifier;
     uint64_t m_lastHandledMessageIdentifier { 0 };
     StorageNamespaceImpl& m_namespace;
-    Ref<WebCore::SecurityOrigin> m_securityOrigin;
+    Ref<const WebCore::SecurityOrigin> m_securityOrigin;
     std::unique_ptr<WebCore::StorageMap> m_map;
     std::optional<StorageAreaIdentifier> m_remoteAreaIdentifier;
     HashCountedSet<String> m_pendingValueChanges;

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp (290222 => 290223)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -100,10 +100,10 @@
     m_storageAreaMaps.remove(map.securityOrigin().data());
 }
 
-Ref<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOriginData& securityOriginData)
+Ref<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOrigin& securityOrigin)
 {
-    auto& map = m_storageAreaMaps.ensure(securityOriginData, [&] {
-        return makeUnique<StorageAreaMap>(*this, securityOriginData.securityOrigin());
+    auto& map = m_storageAreaMaps.ensure(securityOrigin.data(), [&] {
+        return makeUnique<StorageAreaMap>(*this, securityOrigin);
     }).iterator->value;
     return StorageAreaImpl::create(*map);
 }

Modified: trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h (290222 => 290223)


--- trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKit/WebProcess/WebStorage/StorageNamespaceImpl.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -67,7 +67,7 @@
 private:
     StorageNamespaceImpl(WebCore::StorageType, Identifier, const std::optional<WebCore::PageIdentifier>&, WebCore::SecurityOrigin* topLevelOrigin, unsigned quotaInBytes);
 
-    Ref<WebCore::StorageArea> storageArea(const WebCore::SecurityOriginData&) override;
+    Ref<WebCore::StorageArea> storageArea(const WebCore::SecurityOrigin&) final;
     uint64_t storageAreaMapCountForTesting() const final { return m_storageAreaMaps.size(); }
 
     // FIXME: This is only valid for session storage and should probably be moved to a subclass.

Modified: trunk/Source/WebKitLegacy/ChangeLog (290222 => 290223)


--- trunk/Source/WebKitLegacy/ChangeLog	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKitLegacy/ChangeLog	2022-02-20 07:12:29 UTC (rev 290223)
@@ -1,3 +1,29 @@
+2022-02-19  Chris Dumez  <[email protected]>
+
+        Optimize DOM storage event dispatch
+        https://bugs.webkit.org/show_bug.cgi?id=236871
+
+        Reviewed by Sihui Liu.
+
+        Made the following optimization to DOM storage event dispatch:
+        1. Pass a SecurityOrigin around instead of a SecurityOriginData. Otherwise,
+           dispatchLocalStorageEvents() / dispatchSessionStorageEvents() just keep
+           reconstructing the SecurityOrigin from the SecurityOriginData for every
+           frame.
+        2. When gathering the list of frames where we need to dispatch the storage
+           event, discard the ones that do not have a "storage" event listener.
+
+        * Storage/StorageAreaImpl.cpp:
+        (WebKit::StorageAreaImpl::StorageAreaImpl):
+        (WebKit::StorageAreaImpl::create):
+        (WebKit::StorageAreaImpl::clearForOriginDeletion):
+        (WebKit::StorageAreaImpl::sync):
+        (WebKit::StorageAreaImpl::sessionChanged):
+        * Storage/StorageAreaImpl.h:
+        * Storage/StorageNamespaceImpl.cpp:
+        (WebKit::StorageNamespaceImpl::storageArea):
+        * Storage/StorageNamespaceImpl.h:
+
 2022-02-09  Sihui Liu  <[email protected]>
 
         Manage IndexedDB storage by origin

Modified: trunk/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp (290222 => 290223)


--- trunk/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKitLegacy/Storage/StorageAreaImpl.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -44,7 +44,7 @@
     ASSERT(isMainThread());
 }
 
-inline StorageAreaImpl::StorageAreaImpl(StorageType storageType, const SecurityOriginData& origin, RefPtr<StorageSyncManager>&& syncManager, unsigned quota)
+inline StorageAreaImpl::StorageAreaImpl(StorageType storageType, const SecurityOrigin& origin, RefPtr<StorageSyncManager>&& syncManager, unsigned quota)
     : m_storageType(storageType)
     , m_securityOrigin(origin)
     , m_storageMap(quota)
@@ -53,19 +53,19 @@
     , m_closeDatabaseTimer(*this, &StorageAreaImpl::closeDatabaseTimerFired)
 {
     ASSERT(isMainThread());
-    
-    // Accessing the shared global StorageTracker when a StorageArea is created 
+
+    // Accessing the shared global StorageTracker when a StorageArea is created
     // ensures that the tracker is properly initialized before anyone actually needs to use it.
     StorageTracker::tracker();
 }
 
-Ref<StorageAreaImpl> StorageAreaImpl::create(StorageType storageType, const SecurityOriginData& origin, RefPtr<StorageSyncManager>&& syncManager, unsigned quota)
+Ref<StorageAreaImpl> StorageAreaImpl::create(StorageType storageType, const SecurityOrigin& origin, RefPtr<StorageSyncManager>&& syncManager, unsigned quota)
 {
     Ref<StorageAreaImpl> area = adoptRef(*new StorageAreaImpl(storageType, origin, WTFMove(syncManager), quota));
     // FIXME: If there's no backing storage for LocalStorage, the default WebKit behavior should be that of private browsing,
     // not silently ignoring it. https://bugs.webkit.org/show_bug.cgi?id=25894
     if (area->m_storageSyncManager) {
-        area->m_storageAreaSync = StorageAreaSync::create(area->m_storageSyncManager.get(), area.copyRef(), area->m_securityOrigin.databaseIdentifier());
+        area->m_storageAreaSync = StorageAreaSync::create(area->m_storageSyncManager.get(), area.copyRef(), area->m_securityOrigin->data().databaseIdentifier());
         ASSERT(area->m_storageAreaSync);
     }
     return area;
@@ -203,7 +203,7 @@
 {
     ASSERT(!m_isShutdown);
     blockUntilImportComplete();
-    
+
     m_storageMap.clear();
 
     if (m_storageAreaSync) {
@@ -211,12 +211,12 @@
         m_storageAreaSync->scheduleCloseDatabase();
     }
 }
-    
+
 void StorageAreaImpl::sync()
 {
     ASSERT(!m_isShutdown);
     blockUntilImportComplete();
-    
+
     if (m_storageAreaSync)
         m_storageAreaSync->scheduleSync();
 }
@@ -287,7 +287,7 @@
     m_storageMap.clear();
 
     if (isNewSessionPersistent && !m_storageAreaSync && m_storageSyncManager) {
-        m_storageAreaSync = StorageAreaSync::create(m_storageSyncManager.get(), *this, m_securityOrigin.databaseIdentifier());
+        m_storageAreaSync = StorageAreaSync::create(m_storageSyncManager.get(), *this, m_securityOrigin->data().databaseIdentifier());
         return;
     }
 

Modified: trunk/Source/WebKitLegacy/Storage/StorageAreaImpl.h (290222 => 290223)


--- trunk/Source/WebKitLegacy/Storage/StorageAreaImpl.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKitLegacy/Storage/StorageAreaImpl.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -43,7 +43,7 @@
 
 class StorageAreaImpl : public WebCore::StorageArea {
 public:
-    static Ref<StorageAreaImpl> create(WebCore::StorageType, const WebCore::SecurityOriginData&, RefPtr<WebCore::StorageSyncManager>&&, unsigned quota);
+    static Ref<StorageAreaImpl> create(WebCore::StorageType, const WebCore::SecurityOrigin&, RefPtr<WebCore::StorageSyncManager>&&, unsigned quota);
     virtual ~StorageAreaImpl();
 
     unsigned length() override;
@@ -76,7 +76,7 @@
     void sessionChanged(bool isNewSessionPersistent);
 
 private:
-    StorageAreaImpl(WebCore::StorageType, const WebCore::SecurityOriginData&, RefPtr<WebCore::StorageSyncManager>&&, unsigned quota);
+    StorageAreaImpl(WebCore::StorageType, const WebCore::SecurityOrigin&, RefPtr<WebCore::StorageSyncManager>&&, unsigned quota);
     explicit StorageAreaImpl(const StorageAreaImpl&);
 
     void blockUntilImportComplete() const;
@@ -85,7 +85,7 @@
     void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, WebCore::Frame* sourceFrame);
 
     WebCore::StorageType m_storageType;
-    WebCore::SecurityOriginData m_securityOrigin;
+    Ref<const WebCore::SecurityOrigin> m_securityOrigin;
     WebCore::StorageMap m_storageMap;
 
     RefPtr<StorageAreaSync> m_storageAreaSync;

Modified: trunk/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp (290222 => 290223)


--- trunk/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp	2022-02-20 07:12:29 UTC (rev 290223)
@@ -28,6 +28,7 @@
 #include "StorageAreaImpl.h"
 #include "StorageSyncManager.h"
 #include "StorageTracker.h"
+#include <WebCore/SecurityOrigin.h>
 #include <WebCore/StorageMap.h>
 #include <WebCore/StorageType.h>
 #include <wtf/MainThread.h>
@@ -102,17 +103,14 @@
     return WTFMove(newNamespace);
 }
 
-Ref<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOriginData& origin)
+Ref<StorageArea> StorageNamespaceImpl::storageArea(const SecurityOrigin& origin)
 {
     ASSERT(isMainThread());
     ASSERT(!m_isShutdown);
 
-    if (RefPtr<StorageAreaImpl> storageArea = m_storageAreaMap.get(origin))
-        return storageArea.releaseNonNull();
-
-    auto storageArea = StorageAreaImpl::create(m_storageType, origin, m_syncManager.get(), m_quota);
-    m_storageAreaMap.set(origin, storageArea.ptr());
-    return WTFMove(storageArea);
+    return *m_storageAreaMap.ensure(origin.data(), [&] {
+        return StorageAreaImpl::create(m_storageType, origin, m_syncManager.get(), m_quota);
+    }).iterator->value;
 }
 
 void StorageNamespaceImpl::close()

Modified: trunk/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h (290222 => 290223)


--- trunk/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h	2022-02-20 05:15:56 UTC (rev 290222)
+++ trunk/Source/WebKitLegacy/Storage/StorageNamespaceImpl.h	2022-02-20 07:12:29 UTC (rev 290223)
@@ -37,7 +37,7 @@
 
 class StorageAreaImpl;
 
-class StorageNamespaceImpl : public WebCore::StorageNamespace {
+class StorageNamespaceImpl final : public WebCore::StorageNamespace {
 public:
     static Ref<StorageNamespaceImpl> createSessionStorageNamespace(unsigned quota, PAL::SessionID);
     static Ref<StorageNamespaceImpl> getOrCreateLocalStorageNamespace(const String& databasePath, unsigned quota, PAL::SessionID);
@@ -54,14 +54,14 @@
     void sync();
     void closeIdleLocalStorageDatabases();
 
-    PAL::SessionID sessionID() const override { return m_sessionID; }
-    void setSessionIDForTesting(PAL::SessionID) override;
+    PAL::SessionID sessionID() const final { return m_sessionID; }
+    void setSessionIDForTesting(PAL::SessionID) final;
 
 private:
     StorageNamespaceImpl(WebCore::StorageType, const String& path, unsigned quota, PAL::SessionID);
 
-    Ref<WebCore::StorageArea> storageArea(const WebCore::SecurityOriginData&) override;
-    Ref<StorageNamespace> copy(WebCore::Page& newPage) override;
+    Ref<WebCore::StorageArea> storageArea(const WebCore::SecurityOrigin&) final;
+    Ref<StorageNamespace> copy(WebCore::Page& newPage) final;
 
     typedef HashMap<WebCore::SecurityOriginData, RefPtr<StorageAreaImpl>> StorageAreaMap;
     StorageAreaMap m_storageAreaMap;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to