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