Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Unified Diff: Source/bindings/core/v8/V8Initializer.cpp

Issue 897523002: Handle rejected promises better for workers. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: tidying Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/core/v8/V8Initializer.h ('k') | Source/bindings/core/v8/WorkerScriptController.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/core/v8/V8Initializer.cpp
diff --git a/Source/bindings/core/v8/V8Initializer.cpp b/Source/bindings/core/v8/V8Initializer.cpp
index 939d7928a04d57ddcd9d8bfae897a9eb4205ebe2..2f3c879468b6456de3265dd281a7d3c74f0b563e 100644
--- a/Source/bindings/core/v8/V8Initializer.cpp
+++ b/Source/bindings/core/v8/V8Initializer.cpp
@@ -27,6 +27,7 @@
#include "bindings/core/v8/V8Initializer.h"
#include "bindings/core/v8/DOMWrapperWorld.h"
+#include "bindings/core/v8/RejectedPromises.h"
#include "bindings/core/v8/ScriptCallStackFactory.h"
#include "bindings/core/v8/ScriptController.h"
#include "bindings/core/v8/ScriptProfiler.h"
@@ -40,6 +41,7 @@
#include "bindings/core/v8/V8Location.h"
#include "bindings/core/v8/V8PerContextData.h"
#include "bindings/core/v8/V8Window.h"
+#include "bindings/core/v8/WorkerScriptController.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/fetch/AccessControlStatus.h"
@@ -47,9 +49,9 @@
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
-#include "core/inspector/ConsoleMessage.h"
#include "core/inspector/ScriptArguments.h"
#include "core/inspector/ScriptCallStack.h"
+#include "core/workers/WorkerGlobalScope.h"
#include "platform/EventDispatchForbiddenScope.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
@@ -58,7 +60,6 @@
#include "public/platform/Platform.h"
#include "wtf/ArrayBufferContents.h"
#include "wtf/RefPtr.h"
-#include "wtf/ThreadSpecific.h"
#include "wtf/text/WTFString.h"
#include <v8-debug.h>
@@ -185,110 +186,18 @@ static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Hand
namespace {
-class PromiseRejectMessage {
- ALLOW_ONLY_INLINE_ALLOCATION();
-public:
- PromiseRejectMessage(const ScriptValue& promise, const ScriptValue& exception, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
- : m_promise(promise)
- , m_exception(exception)
- , m_errorMessage(errorMessage)
- , m_resourceName(resourceName)
- , m_scriptId(scriptId)
- , m_lineNumber(lineNumber)
- , m_columnNumber(columnNumber)
- , m_callStack(callStack)
- {
- }
-
- void trace(Visitor* visitor)
- {
- visitor->trace(m_callStack);
- }
-
- const ScriptValue m_promise;
- const ScriptValue m_exception;
- const String m_errorMessage;
- const String m_resourceName;
- const int m_scriptId;
- const int m_lineNumber;
- const int m_columnNumber;
- const RefPtrWillBeMember<ScriptCallStack> m_callStack;
-};
-
-class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- virtual void* Allocate(size_t size) override
- {
- void* data;
- WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data);
- return data;
- }
-
- virtual void* AllocateUninitialized(size_t size) override
- {
- void* data;
- WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::DontInitialize, data);
- return data;
- }
-
- virtual void Free(void* data, size_t size) override
- {
- WTF::ArrayBufferContents::freeMemory(data, size);
- }
-};
-
-} // namespace
-
-typedef Deque<PromiseRejectMessage> PromiseRejectMessageQueue;
-
-static PromiseRejectMessageQueue& promiseRejectMessageQueue()
+static RejectedPromises& rejectedPromisesOnMainThread()
{
- AtomicallyInitializedStaticReference(ThreadSpecific<PromiseRejectMessageQueue>, queue, new ThreadSpecific<PromiseRejectMessageQueue>);
- return *queue;
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<RejectedPromises>, rejectedPromises, (adoptPtrWillBeNoop(new RejectedPromises())));
+ return *rejectedPromises;
}
-void V8Initializer::reportRejectedPromises()
-{
- PromiseRejectMessageQueue& queue = promiseRejectMessageQueue();
- while (!queue.isEmpty()) {
- PromiseRejectMessage message = queue.takeFirst();
- ScriptState* scriptState = message.m_promise.scriptState();
- if (!scriptState->contextIsValid())
- continue;
- // If execution termination has been triggered, quietly bail out.
- if (v8::V8::IsExecutionTerminating(scriptState->isolate()))
- continue;
- ExecutionContext* executionContext = scriptState->executionContext();
- if (!executionContext)
- continue;
-
- ScriptState::Scope scope(scriptState);
-
- ASSERT(!message.m_promise.isEmpty());
- v8::Handle<v8::Value> value = message.m_promise.v8Value();
- ASSERT(!value.IsEmpty() && value->IsPromise());
- if (v8::Handle<v8::Promise>::Cast(value)->HasHandler())
- continue;
-
- const String errorMessage = "Uncaught (in promise)";
- Vector<ScriptValue> args;
- args.append(ScriptValue(scriptState, v8String(scriptState->isolate(), errorMessage)));
- args.append(message.m_exception);
- RefPtrWillBeRawPtr<ScriptArguments> arguments = ScriptArguments::create(scriptState, args);
-
- String embedderErrorMessage = message.m_errorMessage;
- if (embedderErrorMessage.isEmpty()) {
- embedderErrorMessage = errorMessage;
- } else {
- if (embedderErrorMessage.startsWith("Uncaught "))
- embedderErrorMessage.insert(" (in promise)", 8);
- }
+} // namespace
- RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, embedderErrorMessage, message.m_resourceName, message.m_lineNumber, message.m_columnNumber);
- consoleMessage->setScriptArguments(arguments);
- consoleMessage->setCallStack(message.m_callStack);
- consoleMessage->setScriptId(message.m_scriptId);
- executionContext->addConsoleMessage(consoleMessage.release());
- }
+void V8Initializer::reportRejectedPromisesOnMainThread()
+{
+ rejectedPromisesOnMainThread().processQueue();
}
static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data)
@@ -355,7 +264,7 @@ static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data)
errorMessage = "Uncaught " + messageForConsole;
ScriptState* scriptState = ScriptState::from(context);
- promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), ScriptValue(scriptState, data.GetValue()), errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack));
+ rejectedPromisesOnMainThread().add(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack);
}
static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
@@ -367,10 +276,18 @@ static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
// Bail out if called during context initialization.
v8::Isolate* isolate = promise->GetIsolate();
- v8::Handle<v8::Context> context = isolate->GetCurrentContext();
- if (context.IsEmpty())
+ ScriptState* scriptState = ScriptState::current(isolate);
+ if (!scriptState->contextIsValid())
return;
+ ExecutionContext* executionContext = scriptState->executionContext();
+ if (!executionContext)
+ return;
+
+ ASSERT(executionContext->isWorkerGlobalScope());
+ WorkerScriptController* scriptController = toWorkerGlobalScope(executionContext)->script();
+ ASSERT(scriptController);
+
int scriptId = 0;
int lineNumber = 0;
int columnNumber = 0;
@@ -385,9 +302,7 @@ static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
columnNumber = message->GetStartColumn() + 1;
errorMessage = toCoreString(message->Get());
}
-
- ScriptState* scriptState = ScriptState::from(context);
- promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), ScriptValue(scriptState, data.GetValue()), errorMessage, resourceName, scriptId, lineNumber, columnNumber, nullptr));
+ scriptController->rejectedPromises()->add(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, nullptr);
}
static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data)
@@ -457,6 +372,31 @@ static void initializeV8Common(v8::Isolate* isolate)
isolate->SetAutorunMicrotasks(false);
}
+namespace {
+
+class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
+ virtual void* Allocate(size_t size) override
+ {
+ void* data;
+ WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data);
+ return data;
+ }
+
+ virtual void* AllocateUninitialized(size_t size) override
+ {
+ void* data;
+ WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::DontInitialize, data);
+ return data;
+ }
+
+ virtual void Free(void* data, size_t size) override
+ {
+ WTF::ArrayBufferContents::freeMemory(data, size);
+ }
+};
+
+} // namespace
+
void V8Initializer::initializeMainThreadIfNeeded()
{
ASSERT(isMainThread());
« no previous file with comments | « Source/bindings/core/v8/V8Initializer.h ('k') | Source/bindings/core/v8/WorkerScriptController.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698