Title: [268822] trunk/Source/WebCore
Revision
268822
Author
[email protected]
Date
2020-10-21 14:15:48 -0700 (Wed, 21 Oct 2020)

Log Message

Share more code between WorkerGlobalScope and WorkletGlobalScope
https://bugs.webkit.org/show_bug.cgi?id=217995

Reviewed by Darin Adler.

Share more code between WorkerGlobalScope and WorkletGlobalScope by
moving shared logic to WorkerOrWorkletGlobalScope.

No new tests, no Web-facing behavior change.

* Modules/webaudio/AudioWorkletGlobalScope.cpp:
(WebCore::AudioWorkletGlobalScope::prepareForDestruction):
* Modules/webaudio/AudioWorkletGlobalScope.h:
* Modules/webaudio/AudioWorkletThread.cpp:
(WebCore::AudioWorkletThread::stop):
* workers/WorkerEventLoop.cpp:
(WebCore::WorkerEventLoop::create):
(WebCore::WorkerEventLoop::WorkerEventLoop):
* workers/WorkerEventLoop.h:
* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::WorkerGlobalScope):
(WebCore::WorkerGlobalScope::prepareForDestruction):
(WebCore::WorkerGlobalScope::removeAllEventListeners):
(WebCore::WorkerGlobalScope::suspend):
(WebCore::WorkerGlobalScope::resume):
(WebCore::WorkerGlobalScope::close):
(WebCore::WorkerGlobalScope::wrapCryptoKey):
(WebCore::WorkerGlobalScope::unwrapCryptoKey):
(WebCore::WorkerGlobalScope::thread const):
* workers/WorkerGlobalScope.h:
* workers/WorkerOrWorkletGlobalScope.cpp:
(WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
(WebCore::WorkerOrWorkletGlobalScope::prepareForDestruction):
(WebCore::WorkerOrWorkletGlobalScope::disableEval):
(WebCore::WorkerOrWorkletGlobalScope::disableWebAssembly):
(WebCore::WorkerOrWorkletGlobalScope::isJSExecutionForbidden const):
(WebCore::WorkerOrWorkletGlobalScope::eventLoop):
(WebCore::WorkerOrWorkletGlobalScope::isContextThread const):
(WebCore::WorkerOrWorkletGlobalScope::postTask):
* workers/WorkerOrWorkletGlobalScope.h:
(WebCore::WorkerOrWorkletGlobalScope::isClosing const):
(WebCore::WorkerOrWorkletGlobalScope::workerOrWorkletThread const):
(WebCore::WorkerOrWorkletGlobalScope::markAsClosing):
* workers/WorkerThread.cpp:
(WebCore::WorkerThread::stop):
* worklets/WorkletGlobalScope.cpp:
(WebCore::WorkletGlobalScope::WorkletGlobalScope):
(WebCore::WorkletGlobalScope::prepareForDestruction):
* worklets/WorkletGlobalScope.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (268821 => 268822)


--- trunk/Source/WebCore/ChangeLog	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/ChangeLog	2020-10-21 21:15:48 UTC (rev 268822)
@@ -1,3 +1,55 @@
+2020-10-21  Chris Dumez  <[email protected]>
+
+        Share more code between WorkerGlobalScope and WorkletGlobalScope
+        https://bugs.webkit.org/show_bug.cgi?id=217995
+
+        Reviewed by Darin Adler.
+
+        Share more code between WorkerGlobalScope and WorkletGlobalScope by
+        moving shared logic to WorkerOrWorkletGlobalScope.
+
+        No new tests, no Web-facing behavior change.
+
+        * Modules/webaudio/AudioWorkletGlobalScope.cpp:
+        (WebCore::AudioWorkletGlobalScope::prepareForDestruction):
+        * Modules/webaudio/AudioWorkletGlobalScope.h:
+        * Modules/webaudio/AudioWorkletThread.cpp:
+        (WebCore::AudioWorkletThread::stop):
+        * workers/WorkerEventLoop.cpp:
+        (WebCore::WorkerEventLoop::create):
+        (WebCore::WorkerEventLoop::WorkerEventLoop):
+        * workers/WorkerEventLoop.h:
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::WorkerGlobalScope):
+        (WebCore::WorkerGlobalScope::prepareForDestruction):
+        (WebCore::WorkerGlobalScope::removeAllEventListeners):
+        (WebCore::WorkerGlobalScope::suspend):
+        (WebCore::WorkerGlobalScope::resume):
+        (WebCore::WorkerGlobalScope::close):
+        (WebCore::WorkerGlobalScope::wrapCryptoKey):
+        (WebCore::WorkerGlobalScope::unwrapCryptoKey):
+        (WebCore::WorkerGlobalScope::thread const):
+        * workers/WorkerGlobalScope.h:
+        * workers/WorkerOrWorkletGlobalScope.cpp:
+        (WebCore::WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope):
+        (WebCore::WorkerOrWorkletGlobalScope::prepareForDestruction):
+        (WebCore::WorkerOrWorkletGlobalScope::disableEval):
+        (WebCore::WorkerOrWorkletGlobalScope::disableWebAssembly):
+        (WebCore::WorkerOrWorkletGlobalScope::isJSExecutionForbidden const):
+        (WebCore::WorkerOrWorkletGlobalScope::eventLoop):
+        (WebCore::WorkerOrWorkletGlobalScope::isContextThread const):
+        (WebCore::WorkerOrWorkletGlobalScope::postTask):
+        * workers/WorkerOrWorkletGlobalScope.h:
+        (WebCore::WorkerOrWorkletGlobalScope::isClosing const):
+        (WebCore::WorkerOrWorkletGlobalScope::workerOrWorkletThread const):
+        (WebCore::WorkerOrWorkletGlobalScope::markAsClosing):
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::stop):
+        * worklets/WorkletGlobalScope.cpp:
+        (WebCore::WorkletGlobalScope::WorkletGlobalScope):
+        (WebCore::WorkletGlobalScope::prepareForDestruction):
+        * worklets/WorkletGlobalScope.h:
+
 2020-10-21  Zalan Bujtas  <[email protected]>
 
         [LFC][IFC] Line may be able to fit some more content when the current candidate is trimmable

Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp (268821 => 268822)


--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -143,29 +143,13 @@
     return &jsProcessor.wrapped();
 }
 
-void AudioWorkletGlobalScope::prepareForTermination()
+void AudioWorkletGlobalScope::prepareForDestruction()
 {
-    if (auto* defaultTaskGroup = this->defaultTaskGroup())
-        defaultTaskGroup->stopAndDiscardAllTasks();
-    stopActiveDOMObjects();
-
     m_processorConstructorMap.clear();
 
-    // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
-    // which become dangling once Heap is destroyed.
-    removeAllEventListeners();
-
-    // MicrotaskQueue and RejectedPromiseTracker reference Heap.
-    if (auto* eventLoop = this->existingEventLoop())
-        eventLoop->clearMicrotaskQueue();
-    removeRejectedPromiseTracker();
+    WorkletGlobalScope::prepareForDestruction();
 }
 
-void AudioWorkletGlobalScope::postTask(Task&& task)
-{
-    thread().runLoop().postTask(WTFMove(task));
-}
-
 std::unique_ptr<AudioWorkletProcessorConstructionData> AudioWorkletGlobalScope::takePendingProcessorConstructionData()
 {
     return std::exchange(m_pendingProcessorConstructionData, nullptr);

Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.h (268821 => 268822)


--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.h	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.h	2020-10-21 21:15:48 UTC (rev 268822)
@@ -61,10 +61,8 @@
     double currentTime() const { return m_sampleRate > 0.0 ? m_currentFrame / static_cast<double>(m_sampleRate) : 0.0; }
 
     AudioWorkletThread& thread() const;
-    void prepareForTermination();
+    void prepareForDestruction() final;
 
-    void postTask(Task&&) final;
-
     std::unique_ptr<AudioWorkletProcessorConstructionData> takePendingProcessorConstructionData();
 
     void handlePreRenderTasks();

Modified: trunk/Source/WebCore/Modules/webaudio/AudioWorkletThread.cpp (268821 => 268822)


--- trunk/Source/WebCore/Modules/webaudio/AudioWorkletThread.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/Modules/webaudio/AudioWorkletThread.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -87,7 +87,7 @@
         m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) {
             auto& workletGlobalScope = downcast<AudioWorkletGlobalScope>(context);
 
-            workletGlobalScope.prepareForTermination();
+            workletGlobalScope.prepareForDestruction();
 
             // Stick a shutdown command at the end of the queue, so that we deal
             // with all the cleanup tasks the databases post first.

Modified: trunk/Source/WebCore/workers/WorkerEventLoop.cpp (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerEventLoop.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerEventLoop.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -27,22 +27,16 @@
 #include "WorkerEventLoop.h"
 
 #include "Microtasks.h"
-#include "WorkerGlobalScope.h"
-#include "WorkletGlobalScope.h"
+#include "WorkerOrWorkletGlobalScope.h"
 
 namespace WebCore {
 
-Ref<WorkerEventLoop> WorkerEventLoop::create(WorkerGlobalScope& context)
+Ref<WorkerEventLoop> WorkerEventLoop::create(WorkerOrWorkletGlobalScope& context)
 {
     return adoptRef(*new WorkerEventLoop(context));
 }
 
-Ref<WorkerEventLoop> WorkerEventLoop::create(WorkletGlobalScope& context)
-{
-    return adoptRef(*new WorkerEventLoop(context));
-}
-
-WorkerEventLoop::WorkerEventLoop(ScriptExecutionContext& context)
+WorkerEventLoop::WorkerEventLoop(WorkerOrWorkletGlobalScope& context)
     : ContextDestructionObserver(&context)
 {
 }

Modified: trunk/Source/WebCore/workers/WorkerEventLoop.h (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerEventLoop.h	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerEventLoop.h	2020-10-21 21:15:48 UTC (rev 268822)
@@ -30,14 +30,11 @@
 
 namespace WebCore {
 
-class WorkerGlobalScope;
-class WorkletGlobalScope;
+class WorkerOrWorkletGlobalScope;
 
 class WorkerEventLoop final : public EventLoop, private ContextDestructionObserver {
 public:
-    // Explicitly take WorkerGlobalScope and WorkletGlobalScope for documentation purposes.
-    static Ref<WorkerEventLoop> create(WorkerGlobalScope&);
-    static Ref<WorkerEventLoop> create(WorkletGlobalScope&);
+    static Ref<WorkerEventLoop> create(WorkerOrWorkletGlobalScope&);
 
     virtual ~WorkerEventLoop();
 
@@ -45,7 +42,7 @@
     void clearMicrotaskQueue();
 
 private:
-    explicit WorkerEventLoop(ScriptExecutionContext&);
+    explicit WorkerEventLoop(WorkerOrWorkletGlobalScope&);
 
     void scheduleToRun() final;
     bool isContextThread() const;

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -43,7 +43,6 @@
 #include "SecurityOriginPolicy.h"
 #include "ServiceWorkerGlobalScope.h"
 #include "SocketProvider.h"
-#include "WorkerEventLoop.h"
 #include "WorkerInspectorController.h"
 #include "WorkerLoaderProxy.h"
 #include "WorkerLocation.h"
@@ -62,10 +61,10 @@
 WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerGlobalScope);
 
 WorkerGlobalScope::WorkerGlobalScope(const WorkerParameters& params, Ref<SecurityOrigin>&& origin, WorkerThread& thread, Ref<SecurityOrigin>&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider)
-    : m_url(params.scriptURL)
+    : WorkerOrWorkletGlobalScope(JSC::VM::create(), &thread)
+    , m_url(params.scriptURL)
     , m_identifier(params.identifier)
     , m_userAgent(params.userAgent)
-    , m_thread(thread)
     , m_inspectorController(makeUnique<WorkerInspectorController>(*this))
     , m_isOnline(params.isOnline)
     , m_shouldBypassMainWorldContentSecurityPolicy(params.shouldBypassMainWorldContentSecurityPolicy)
@@ -106,18 +105,6 @@
     thread().workerReportingProxy().workerGlobalScopeDestroyed();
 }
 
-EventLoopTaskGroup& WorkerGlobalScope::eventLoop()
-{
-    ASSERT(isContextThread());
-    if (UNLIKELY(!m_defaultTaskGroup)) {
-        m_eventLoop = WorkerEventLoop::create(*this);
-        m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
-        if (activeDOMObjectsAreStopped())
-            m_defaultTaskGroup->stopAndDiscardAllTasks();
-    }
-    return *m_defaultTaskGroup;
-}
-
 String WorkerGlobalScope::origin() const
 {
     auto* securityOrigin = this->securityOrigin();
@@ -124,34 +111,23 @@
     return securityOrigin ? securityOrigin->toString() : emptyString();
 }
 
-void WorkerGlobalScope::prepareForTermination()
+void WorkerGlobalScope::prepareForDestruction()
 {
+    WorkerOrWorkletGlobalScope::prepareForDestruction();
+
 #if ENABLE(INDEXED_DATABASE)
     stopIndexedDatabase();
 #endif
 
-    if (m_defaultTaskGroup)
-        m_defaultTaskGroup->stopAndDiscardAllTasks();
-    stopActiveDOMObjects();
-
     if (m_cacheStorageConnection)
         m_cacheStorageConnection->clearPendingRequests();
 
     m_inspectorController->workerTerminating();
-
-    // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
-    // which become dangling once Heap is destroyed.
-    removeAllEventListeners();
-
-    // MicrotaskQueue and RejectedPromiseTracker reference Heap.
-    if (m_eventLoop)
-        m_eventLoop->clearMicrotaskQueue();
-    removeRejectedPromiseTracker();
 }
 
 void WorkerGlobalScope::removeAllEventListeners()
 {
-    EventTarget::removeAllEventListeners();
+    WorkerOrWorkletGlobalScope::removeAllEventListeners();
     m_performance->removeAllEventListeners();
     m_performance->removeAllObservers();
 }
@@ -184,16 +160,6 @@
     return m_userAgent;
 }
 
-void WorkerGlobalScope::disableEval(const String& errorMessage)
-{
-    script()->disableEval(errorMessage);
-}
-
-void WorkerGlobalScope::disableWebAssembly(const String& errorMessage)
-{
-    script()->disableWebAssembly(errorMessage);
-}
-
 SocketProvider* WorkerGlobalScope::socketProvider()
 {
     return m_socketProvider.get();
@@ -222,7 +188,7 @@
 {
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
     if (m_connectionProxy)
-        m_connectionProxy->setContextSuspended(*scriptExecutionContext(), true);
+        m_connectionProxy->setContextSuspended(*this, true);
 #endif
 }
 
@@ -230,7 +196,7 @@
 {
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
     if (m_connectionProxy)
-        m_connectionProxy->setContextSuspended(*scriptExecutionContext(), false);
+        m_connectionProxy->setContextSuspended(*this, false);
 #endif
 }
 
@@ -245,13 +211,13 @@
 
 void WorkerGlobalScope::close()
 {
-    if (m_closing)
+    if (isClosing())
         return;
 
     // Let current script run to completion but prevent future script evaluations.
     // After m_closing is set, all the tasks in the queue continue to be fetched but only
     // tasks with isCleanupTask()==true will be executed.
-    m_closing = true;
+    markAsClosing();
     postTask({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context) {
         ASSERT_WITH_SECURITY_IMPLICATION(is<WorkerGlobalScope>(context));
         WorkerGlobalScope& workerGlobalScope = downcast<WorkerGlobalScope>(context);
@@ -274,11 +240,6 @@
         m_navigator->setIsOnline(isOnline);
 }
 
-void WorkerGlobalScope::postTask(Task&& task)
-{
-    thread().runLoop().postTask(WTFMove(task));
-}
-
 ExceptionOr<int> WorkerGlobalScope::setTimeout(JSC::JSGlobalObject& state, std::unique_ptr<ScheduledAction> action, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
     // FIXME: Should this check really happen here? Or should it happen when code is about to eval?
@@ -406,16 +367,6 @@
     InspectorInstrumentation::addMessageToConsole(*this, WTFMove(message));
 }
 
-bool WorkerGlobalScope::isContextThread() const
-{
-    return thread().thread() == &Thread::current();
-}
-
-bool WorkerGlobalScope::isJSExecutionForbidden() const
-{
-    return script()->isExecutionForbidden();
-}
-
 #if ENABLE(WEB_CRYPTO)
 
 class CryptoBufferContainer : public ThreadSafeRefCounted<CryptoBufferContainer> {
@@ -443,7 +394,7 @@
     auto resultContainer = CryptoBooleanContainer::create();
     auto doneContainer = CryptoBooleanContainer::create();
     auto wrappedKeyContainer = CryptoBufferContainer::create();
-    m_thread.workerLoaderProxy().postTaskToLoader([resultContainer, key, wrappedKeyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(m_thread.workerLoaderProxy()))](ScriptExecutionContext& context) {
+    thread().workerLoaderProxy().postTaskToLoader([resultContainer, key, wrappedKeyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(thread().workerLoaderProxy()))](ScriptExecutionContext& context) {
         resultContainer->setBoolean(context.wrapCryptoKey(key, wrappedKeyContainer->buffer()));
         doneContainer->setBoolean(true);
         workerMessagingProxy->postTaskForModeToWorkerOrWorkletGlobalScope([](ScriptExecutionContext& context) {
@@ -453,7 +404,7 @@
 
     auto waitResult = MessageQueueMessageReceived;
     while (!doneContainer->boolean() && waitResult != MessageQueueTerminated)
-        waitResult = m_thread.runLoop().runInMode(this, WorkerRunLoop::defaultMode());
+        waitResult = thread().runLoop().runInMode(this, WorkerRunLoop::defaultMode());
 
     if (doneContainer->boolean())
         wrappedKey.swap(wrappedKeyContainer->buffer());
@@ -466,7 +417,7 @@
     auto resultContainer = CryptoBooleanContainer::create();
     auto doneContainer = CryptoBooleanContainer::create();
     auto keyContainer = CryptoBufferContainer::create();
-    m_thread.workerLoaderProxy().postTaskToLoader([resultContainer, wrappedKey, keyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(m_thread.workerLoaderProxy()))](ScriptExecutionContext& context) {
+    thread().workerLoaderProxy().postTaskToLoader([resultContainer, wrappedKey, keyContainer, doneContainer, workerMessagingProxy = makeRef(downcast<WorkerMessagingProxy>(thread().workerLoaderProxy()))](ScriptExecutionContext& context) {
         resultContainer->setBoolean(context.unwrapCryptoKey(wrappedKey, keyContainer->buffer()));
         doneContainer->setBoolean(true);
         workerMessagingProxy->postTaskForModeToWorkerOrWorkletGlobalScope([](ScriptExecutionContext& context) {
@@ -476,7 +427,7 @@
 
     auto waitResult = MessageQueueMessageReceived;
     while (!doneContainer->boolean() && waitResult != MessageQueueTerminated)
-        waitResult = m_thread.runLoop().runInMode(this, WorkerRunLoop::defaultMode());
+        waitResult = thread().runLoop().runInMode(this, WorkerRunLoop::defaultMode());
 
     if (doneContainer->boolean())
         key.swap(keyContainer->buffer());
@@ -542,4 +493,9 @@
     return m_referrerPolicy;
 }
 
+WorkerThread& WorkerGlobalScope::thread() const
+{
+    return *static_cast<WorkerThread*>(workerOrWorkletThread());
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerGlobalScope.h	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h	2020-10-21 21:15:48 UTC (rev 268822)
@@ -28,7 +28,6 @@
 
 #include "Base64Utilities.h"
 #include "CacheStorageConnection.h"
-#include "EventTarget.h"
 #include "ImageBitmap.h"
 #include "ScriptExecutionContext.h"
 #include "Supplementable.h"
@@ -46,10 +45,8 @@
 class CSSValuePool;
 class ContentSecurityPolicyResponseHeaders;
 class Crypto;
-class EventLoopTaskGroup;
 class Performance;
 class ScheduledAction;
-class WorkerEventLoop;
 class WorkerInspectorController;
 class WorkerLocation;
 class WorkerNavigator;
@@ -60,7 +57,7 @@
 class IDBConnectionProxy;
 }
 
-class WorkerGlobalScope : public RefCounted<WorkerGlobalScope>, public Supplementable<WorkerGlobalScope>, public EventTargetWithInlineData, public Base64Utilities, public WorkerOrWorkletGlobalScope {
+class WorkerGlobalScope : public Supplementable<WorkerGlobalScope>, public Base64Utilities, public WorkerOrWorkletGlobalScope {
     WTF_MAKE_ISO_ALLOCATED(WorkerGlobalScope);
 public:
     virtual ~WorkerGlobalScope();
@@ -68,8 +65,6 @@
     virtual bool isDedicatedWorkerGlobalScope() const { return false; }
     virtual bool isServiceWorkerGlobalScope() const { return false; }
 
-    EventLoopTaskGroup& eventLoop() final;
-
     const URL& url() const final { return m_url; }
     String origin() const;
     const String& identifier() const { return m_identifier; }
@@ -88,12 +83,10 @@
 
     WorkerInspectorController& inspectorController() const { return *m_inspectorController; }
 
-    WorkerThread& thread() const { return m_thread; }
+    WorkerThread& thread() const;
 
     using ScriptExecutionContext::hasPendingActivity;
 
-    void postTask(Task&&) final; // Executes the task on context's thread asynchronously.
-
     WorkerGlobalScope& self() { return *this; }
     WorkerLocation& location() const;
     void close();
@@ -108,17 +101,11 @@
     ExceptionOr<int> setInterval(JSC::JSGlobalObject&, std::unique_ptr<ScheduledAction>, int timeout, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
     void clearInterval(int timeoutId);
 
-    bool isContextThread() const final;
     bool isSecureContext() const final;
 
     WorkerNavigator* optionalNavigator() const { return m_navigator.get(); }
     WorkerLocation* optionalLocation() const { return m_location.get(); }
 
-    using RefCounted::ref;
-    using RefCounted::deref;
-
-    bool isClosing() const final { return m_closing; }
-
     void addConsoleMessage(std::unique_ptr<Inspector::ConsoleMessage>&&) final;
 
     SecurityOrigin& topOrigin() const final { return m_topOrigin.get(); }
@@ -126,7 +113,7 @@
     Crypto& crypto();
     Performance& performance() const;
 
-    void prepareForTermination();
+    void prepareForDestruction() final;
 
     void removeAllEventListeners() final;
 
@@ -147,12 +134,6 @@
     void applyContentSecurityPolicyResponseHeaders(const ContentSecurityPolicyResponseHeaders&);
 
 private:
-    void refScriptExecutionContext() final { ref(); }
-    void derefScriptExecutionContext() final { deref(); }
-
-    void refEventTarget() final { ref(); }
-    void derefEventTarget() final { deref(); }
-
     void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) final;
 
     // The following addMessage and addConsoleMessage functions are deprecated.
@@ -161,19 +142,14 @@
     void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier) final;
 
     bool isWorkerGlobalScope() const final { return true; }
-    WorkerThread* workerOrWorkletThread() const final { return &m_thread; }
 
-    ScriptExecutionContext* scriptExecutionContext() const final { return const_cast<WorkerGlobalScope*>(this); }
     URL completeURL(const String&, ForceUTF8 = ForceUTF8::No) const final;
     String userAgent(const URL&) const final;
-    void disableEval(const String& errorMessage) final;
-    void disableWebAssembly(const String& errorMessage) final;
     EventTarget* errorEventTarget() final;
     String resourceRequestIdentifier() const final { return m_identifier; }
     SocketProvider* socketProvider() final;
 
     bool shouldBypassMainWorldContentSecurityPolicy() const final { return m_shouldBypassMainWorldContentSecurityPolicy; }
-    bool isJSExecutionForbidden() const final;
 
 #if ENABLE(WEB_CRYPTO)
     bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) final;
@@ -191,17 +167,12 @@
     mutable RefPtr<WorkerLocation> m_location;
     mutable RefPtr<WorkerNavigator> m_navigator;
 
-    WorkerThread& m_thread;
     std::unique_ptr<WorkerOrWorkletScriptController> m_script;
     std::unique_ptr<WorkerInspectorController> m_inspectorController;
 
-    bool m_closing { false };
     bool m_isOnline;
     bool m_shouldBypassMainWorldContentSecurityPolicy;
 
-    RefPtr<WorkerEventLoop> m_eventLoop;
-    std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
-
     Ref<SecurityOrigin> m_topOrigin;
 
 #if ENABLE(INDEXED_DATABASE)

Modified: trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -26,18 +26,37 @@
 #include "config.h"
 #include "WorkerOrWorkletGlobalScope.h"
 
+#include "WorkerEventLoop.h"
 #include "WorkerOrWorkletScriptController.h"
+#include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
 
-WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope()
-    : m_script(makeUnique<WorkerOrWorkletScriptController>(this))
+WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerOrWorkletGlobalScope);
+
+WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(Ref<JSC::VM>&& vm, WorkerOrWorkletThread* thread)
+    : m_script(makeUnique<WorkerOrWorkletScriptController>(WTFMove(vm), this))
+    , m_thread(thread)
 {
 }
 
-WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(Ref<JSC::VM>&& vm)
-    : m_script(makeUnique<WorkerOrWorkletScriptController>(WTFMove(vm), this))
+WorkerOrWorkletGlobalScope::~WorkerOrWorkletGlobalScope() = default;
+
+void WorkerOrWorkletGlobalScope::prepareForDestruction()
 {
+    if (m_defaultTaskGroup)
+        m_defaultTaskGroup->stopAndDiscardAllTasks();
+
+    stopActiveDOMObjects();
+
+    // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
+    // which become dangling once Heap is destroyed.
+    removeAllEventListeners();
+
+    // MicrotaskQueue and RejectedPromiseTracker reference Heap.
+    if (m_eventLoop)
+        m_eventLoop->clearMicrotaskQueue();
+    removeRejectedPromiseTracker();
 }
 
 void WorkerOrWorkletGlobalScope::clearScript()
@@ -45,4 +64,43 @@
     m_script = nullptr;
 }
 
+void WorkerOrWorkletGlobalScope::disableEval(const String& errorMessage)
+{
+    m_script->disableEval(errorMessage);
+}
+
+void WorkerOrWorkletGlobalScope::disableWebAssembly(const String& errorMessage)
+{
+    m_script->disableWebAssembly(errorMessage);
+}
+
+bool WorkerOrWorkletGlobalScope::isJSExecutionForbidden() const
+{
+    return !m_script || m_script->isExecutionForbidden();
+}
+
+EventLoopTaskGroup& WorkerOrWorkletGlobalScope::eventLoop()
+{
+    ASSERT(isContextThread());
+    if (UNLIKELY(!m_defaultTaskGroup)) {
+        m_eventLoop = WorkerEventLoop::create(*this);
+        m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
+        if (activeDOMObjectsAreStopped())
+            m_defaultTaskGroup->stopAndDiscardAllTasks();
+    }
+    return *m_defaultTaskGroup;
+}
+
+bool WorkerOrWorkletGlobalScope::isContextThread() const
+{
+    auto* thread = workerOrWorkletThread();
+    return thread ? thread->thread() == &Thread::current() : isMainThread();
+}
+
+void WorkerOrWorkletGlobalScope::postTask(Task&& task)
+{
+    ASSERT(workerOrWorkletThread());
+    workerOrWorkletThread()->runLoop().postTask(WTFMove(task));
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h	2020-10-21 21:15:48 UTC (rev 268822)
@@ -25,19 +25,24 @@
 
 #pragma once
 
+#include "EventTarget.h"
 #include "ScriptExecutionContext.h"
 
 namespace WebCore {
 
+class EventLoopTaskGroup;
+class WorkerEventLoop;
 class WorkerOrWorkletScriptController;
 class WorkerOrWorkletThread;
 
-class WorkerOrWorkletGlobalScope : public ScriptExecutionContext {
+class WorkerOrWorkletGlobalScope : public ScriptExecutionContext, public RefCounted<WorkerOrWorkletGlobalScope>, public EventTargetWithInlineData {
+    WTF_MAKE_ISO_ALLOCATED(WorkerOrWorkletGlobalScope);
+    WTF_MAKE_NONCOPYABLE(WorkerOrWorkletGlobalScope);
 public:
-    virtual ~WorkerOrWorkletGlobalScope() = default;
+    virtual ~WorkerOrWorkletGlobalScope();
 
-    virtual bool isClosing() const = 0;
-    virtual WorkerOrWorkletThread* workerOrWorkletThread() const = 0;
+    bool isClosing() const { return m_isClosing; }
+    WorkerOrWorkletThread* workerOrWorkletThread() const { return m_thread; }
 
     WorkerOrWorkletScriptController* script() const { return m_script.get(); }
     void clearScript();
@@ -44,13 +49,42 @@
 
     unsigned long createUniqueIdentifier() { return m_uniqueIdentifier++; }
 
+    // ScriptExecutionContext.
+    EventLoopTaskGroup& eventLoop() final;
+    bool isContextThread() const final;
+    void postTask(Task&&) final; // Executes the task on context's thread asynchronously.
+
+    virtual void prepareForDestruction();
+
+    using RefCounted::ref;
+    using RefCounted::deref;
+
 protected:
-    WorkerOrWorkletGlobalScope();
-    explicit WorkerOrWorkletGlobalScope(Ref<JSC::VM>&&);
+    WorkerOrWorkletGlobalScope(Ref<JSC::VM>&&, WorkerOrWorkletThread*);
 
+    // ScriptExecutionContext.
+    bool isJSExecutionForbidden() const final;
+
+    void markAsClosing() { m_isClosing = true; }
+
 private:
+    // ScriptExecutionContext.
+    void disableEval(const String& errorMessage) final;
+    void disableWebAssembly(const String& errorMessage) final;
+    void refScriptExecutionContext() final { ref(); }
+    void derefScriptExecutionContext() final { deref(); }
+
+    // EventTarget.
+    ScriptExecutionContext* scriptExecutionContext() const final { return const_cast<WorkerOrWorkletGlobalScope*>(this); }
+    void refEventTarget() final { ref(); }
+    void derefEventTarget() final { deref(); }
+
     std::unique_ptr<WorkerOrWorkletScriptController> m_script;
+    WorkerOrWorkletThread* m_thread;
+    RefPtr<WorkerEventLoop> m_eventLoop;
+    std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
     unsigned long m_uniqueIdentifier { 1 };
+    bool m_isClosing { false };
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/WorkerThread.cpp (268821 => 268822)


--- trunk/Source/WebCore/workers/WorkerThread.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/workers/WorkerThread.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -320,7 +320,7 @@
         m_runLoop.postTaskAndTerminate({ ScriptExecutionContext::Task::CleanupTask, [] (ScriptExecutionContext& context ) {
             WorkerGlobalScope& workerGlobalScope = downcast<WorkerGlobalScope>(context);
 
-            workerGlobalScope.prepareForTermination();
+            workerGlobalScope.prepareForDestruction();
 
             // Stick a shutdown command at the end of the queue, so that we deal
             // with all the cleanup tasks the databases post first.

Modified: trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp (268821 => 268822)


--- trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/worklets/WorkletGlobalScope.cpp	2020-10-21 21:15:48 UTC (rev 268822)
@@ -33,7 +33,6 @@
 #include "PageConsoleClient.h"
 #include "SecurityOriginPolicy.h"
 #include "Settings.h"
-#include "WorkerEventLoop.h"
 #include "WorkerMessagePortChannelProvider.h"
 #include "WorkerOrWorkletThread.h"
 #include "WorkerScriptLoader.h"
@@ -49,7 +48,7 @@
 WTF_MAKE_ISO_ALLOCATED_IMPL(WorkletGlobalScope);
 
 WorkletGlobalScope::WorkletGlobalScope(WorkerOrWorkletThread& thread, const WorkletParameters& parameters)
-    : m_thread(&thread)
+    : WorkerOrWorkletGlobalScope(JSC::VM::create(), &thread)
     , m_topOrigin(SecurityOrigin::createUnique())
     , m_url(parameters.windowURL)
     , m_jsRuntimeFlags(parameters.jsRuntimeFlags)
@@ -62,7 +61,7 @@
 }
 
 WorkletGlobalScope::WorkletGlobalScope(Document& document, Ref<JSC::VM>&& vm, ScriptSourceCode&& code)
-    : WorkerOrWorkletGlobalScope(WTFMove(vm))
+    : WorkerOrWorkletGlobalScope(WTFMove(vm), nullptr)
     , m_document(makeWeakPtr(document))
     , m_topOrigin(SecurityOrigin::createUnique())
     , m_url(code.url())
@@ -88,17 +87,12 @@
 
 void WorkletGlobalScope::prepareForDestruction()
 {
-    if (!script())
-        return;
-    if (m_defaultTaskGroup)
-        m_defaultTaskGroup->stopAndDiscardAllTasks();
-    stopActiveDOMObjects();
-    removeAllEventListeners();
-    if (m_eventLoop)
-        m_eventLoop->clearMicrotaskQueue();
-    removeRejectedPromiseTracker();
-    script()->vm().notifyNeedTermination();
-    clearScript();
+    WorkerOrWorkletGlobalScope::prepareForDestruction();
+
+    if (script()) {
+        script()->vm().notifyNeedTermination();
+        clearScript();
+    }
 }
 
 auto WorkletGlobalScope::allWorkletGlobalScopesSet() -> WorkletGlobalScopesSet&
@@ -107,17 +101,6 @@
     return scopes;
 }
 
-EventLoopTaskGroup& WorkletGlobalScope::eventLoop()
-{
-    if (UNLIKELY(!m_defaultTaskGroup)) {
-        m_eventLoop = WorkerEventLoop::create(*this);
-        m_defaultTaskGroup = makeUnique<EventLoopTaskGroup>(*m_eventLoop);
-        if (activeDOMObjectsAreStopped())
-            m_defaultTaskGroup->stopAndDiscardAllTasks();
-    }
-    return *m_defaultTaskGroup;
-}
-
 String WorkletGlobalScope::userAgent(const URL& url) const
 {
     if (!m_document)
@@ -131,21 +114,6 @@
         script()->evaluate(*m_code);
 }
 
-bool WorkletGlobalScope::isJSExecutionForbidden() const
-{
-    return !script() || script()->isExecutionForbidden();
-}
-
-void WorkletGlobalScope::disableEval(const String& errorMessage)
-{
-    script()->disableEval(errorMessage);
-}
-
-void WorkletGlobalScope::disableWebAssembly(const String& errorMessage)
-{
-    script()->disableWebAssembly(errorMessage);
-}
-
 URL WorkletGlobalScope::completeURL(const String& url, ForceUTF8) const
 {
     if (url.isNull())
@@ -257,11 +225,4 @@
     return *m_messagePortChannelProvider;
 }
 
-bool WorkletGlobalScope::isContextThread() const
-{
-    if (m_thread)
-        return m_thread->thread() == &Thread::current();
-    return isMainThread();
-}
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/worklets/WorkletGlobalScope.h (268821 => 268822)


--- trunk/Source/WebCore/worklets/WorkletGlobalScope.h	2020-10-21 20:40:40 UTC (rev 268821)
+++ trunk/Source/WebCore/worklets/WorkletGlobalScope.h	2020-10-21 21:15:48 UTC (rev 268822)
@@ -27,12 +27,10 @@
 #pragma once
 
 #include "Document.h"
-#include "EventTarget.h"
 #include "ExceptionOr.h"
 #include "FetchRequestCredentials.h"
 #include "ScriptExecutionContext.h"
 #include "ScriptSourceCode.h"
-#include "WorkerEventLoop.h"
 #include "WorkerOrWorkletGlobalScope.h"
 #include "WorkerOrWorkletScriptController.h"
 #include "WorkerScriptLoaderClient.h"
@@ -47,9 +45,7 @@
 
 namespace WebCore {
 
-class EventLoopTaskGroup;
 class MessagePortChannelProvider;
-class WorkerEventLoop;
 class WorkerMessagePortChannelProvider;
 class WorkerScriptLoader;
 
@@ -58,7 +54,7 @@
 enum WorkletGlobalScopeIdentifierType { };
 using WorkletGlobalScopeIdentifier = ObjectIdentifier<WorkletGlobalScopeIdentifierType>;
 
-class WorkletGlobalScope : public RefCounted<WorkletGlobalScope>, public EventTargetWithInlineData, public WorkerOrWorkletGlobalScope, public WorkerScriptLoaderClient {
+class WorkletGlobalScope : public WorkerOrWorkletGlobalScope, public WorkerScriptLoaderClient {
     WTF_MAKE_ISO_ALLOCATED(WorkletGlobalScope);
 public:
     virtual ~WorkletGlobalScope();
@@ -75,8 +71,6 @@
 
     MessagePortChannelProvider& messagePortChannelProvider();
 
-    EventLoopTaskGroup& eventLoop() final;
-
     const URL& url() const final { return m_url; }
 
     void evaluate();
@@ -83,27 +77,17 @@
 
     ReferrerPolicy referrerPolicy() const final;
 
-    using RefCounted::ref;
-    using RefCounted::deref;
-
-    WorkerOrWorkletThread* workerOrWorkletThread() const final { return m_thread.get(); }
-
     void addConsoleMessage(std::unique_ptr<Inspector::ConsoleMessage>&&) final;
 
-    bool isJSExecutionForbidden() const final;
     SecurityOrigin& topOrigin() const final { return m_topOrigin.get(); }
 
     SocketProvider* socketProvider() final { return nullptr; }
 
-    // WorkerOrWorkletGlobalScope.
-    bool isClosing() const final { return m_isClosing; }
-
-    bool isContextThread() const final;
     bool isSecureContext() const final { return false; }
 
     JSC::RuntimeFlags jsRuntimeFlags() const { return m_jsRuntimeFlags; }
 
-    virtual void prepareForDestruction();
+    void prepareForDestruction() override;
 
     void fetchAndInvokeScript(const URL&, FetchRequestCredentials, CompletionHandler<void(Optional<Exception>&&)>&&);
 
@@ -113,26 +97,13 @@
 protected:
     WorkletGlobalScope(WorkerOrWorkletThread&, const WorkletParameters&);
     WorkletGlobalScope(Document&, Ref<JSC::VM>&&, ScriptSourceCode&&);
-    WorkletGlobalScope(const WorkletGlobalScope&) = delete;
-    WorkletGlobalScope(WorkletGlobalScope&&) = delete;
 
-    WorkerEventLoop* existingEventLoop() const { return m_eventLoop.get(); }
-    EventLoopTaskGroup* defaultTaskGroup() const { return m_defaultTaskGroup.get(); }
-
 private:
 #if ENABLE(INDEXED_DATABASE)
     IDBClient::IDBConnectionProxy* idbConnectionProxy() final { ASSERT_NOT_REACHED(); return nullptr; }
 #endif
 
-    void postTask(Task&&) override { ASSERT_NOT_REACHED(); }
-
-    void refScriptExecutionContext() final { ref(); }
-    void derefScriptExecutionContext() final { deref(); }
-
-    void refEventTarget() final { ref(); }
-    void derefEventTarget() final { deref(); }
-
-    ScriptExecutionContext* scriptExecutionContext() const final { return const_cast<WorkletGlobalScope*>(this); }
+    // EventTarget.
     EventTargetInterface eventTargetInterface() const final { return WorkletGlobalScopeEventTargetInterfaceType; }
 
     bool isWorkletGlobalScope() const final { return true; }
@@ -153,8 +124,6 @@
 #endif
     URL completeURL(const String&, ForceUTF8 = ForceUTF8::No) const final;
     String userAgent(const URL&) const final;
-    void disableEval(const String&) final;
-    void disableWebAssembly(const String&) final;
 
     struct ScriptFetchJob {
         URL moduleURL;
@@ -166,13 +135,9 @@
     void didCompleteScriptFetchJob(ScriptFetchJob&&, Optional<Exception>);
 
     WeakPtr<Document> m_document;
-    RefPtr<WorkerOrWorkletThread> m_thread;
 
     Ref<SecurityOrigin> m_topOrigin;
 
-    RefPtr<WorkerEventLoop> m_eventLoop;
-    std::unique_ptr<EventLoopTaskGroup> m_defaultTaskGroup;
-
     URL m_url;
     JSC::RuntimeFlags m_jsRuntimeFlags;
     Optional<ScriptSourceCode> m_code;
@@ -182,8 +147,6 @@
     RefPtr<WorkerScriptLoader> m_scriptLoader;
     Deque<ScriptFetchJob> m_scriptFetchJobs;
     HashSet<URL> m_evaluatedModules;
-
-    bool m_isClosing { false };
 };
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to