Commit 5565fad0 authored by rafaelw@chromium.org's avatar rafaelw@chromium.org

Use v8 Microtask Queue

V8 now hosts the end-of-microtask work queue. This allows consistent
scheduling of microtask work regardless of where it is implemented (v8 vs blink).

R=adamk@chromium.org

Review URL: https://codereview.chromium.org/167683003

git-svn-id: svn://svn.chromium.org/blink/trunk@169978 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 12a4cf33
......@@ -5,6 +5,7 @@ Set timer for test function.
Captured call stacks in no particular order:
Call stack:
0) mutationCallback (async-callstack-mutation-observer.html:21)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) timeout1 (async-callstack-mutation-observer.html:44)
......@@ -13,6 +14,7 @@ Call stack:
Call stack:
0) mutationCallback (async-callstack-mutation-observer.html:21)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations2 (async-callstack-mutation-observer.html:64)
1) timeout2 (async-callstack-mutation-observer.html:57)
......@@ -23,9 +25,11 @@ Call stack:
Call stack:
0) nestedMutationCallback (async-callstack-mutation-observer.html:28)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) mutationCallback (async-callstack-mutation-observer.html:20)
2) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) timeout1 (async-callstack-mutation-observer.html:44)
......@@ -34,14 +38,17 @@ Call stack:
Call stack:
0) nestedMutationCallback (async-callstack-mutation-observer.html:28)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations2 (async-callstack-mutation-observer.html:64)
1) timeoutFromNestedMutation (async-callstack-mutation-observer.html:76)
[setTimeout]
0) nestedMutationCallback (async-callstack-mutation-observer.html:30)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) mutationCallback (async-callstack-mutation-observer.html:20)
2) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) timeout1 (async-callstack-mutation-observer.html:44)
......@@ -50,6 +57,7 @@ Call stack:
0) timeoutFromMutation (async-callstack-mutation-observer.html:70)
[setTimeout]
0) mutationCallback (async-callstack-mutation-observer.html:23)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) timeout1 (async-callstack-mutation-observer.html:44)
......@@ -60,9 +68,11 @@ Call stack:
0) timeoutFromNestedMutation (async-callstack-mutation-observer.html:75)
[setTimeout]
0) nestedMutationCallback (async-callstack-mutation-observer.html:30)
1) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) mutationCallback (async-callstack-mutation-observer.html:20)
2) RunMicrotasks ((internal script):(line number))
[Mutation]
0) doMutations1 (async-callstack-mutation-observer.html:50)
1) timeout1 (async-callstack-mutation-observer.html:44)
......
......@@ -39,7 +39,7 @@ ScriptRegexp::ScriptRegexp(const String& pattern, TextCaseSensitivity caseSensit
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureRegexContext());
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureDomInJSContext());
v8::TryCatch tryCatch;
unsigned flags = v8::RegExp::kNone;
......@@ -69,7 +69,7 @@ int ScriptRegexp::match(const String& string, int startFrom, int* matchLength) c
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureRegexContext());
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureDomInJSContext());
v8::TryCatch tryCatch;
v8::Local<v8::RegExp> regex = m_regex.newLocal(isolate);
......
......@@ -125,11 +125,11 @@ void V8PerIsolateData::setDOMTemplate(void* domTemplateKey, v8::Handle<v8::Funct
currentDOMTemplateMap().add(domTemplateKey, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ));
}
v8::Local<v8::Context> V8PerIsolateData::ensureRegexContext()
v8::Local<v8::Context> V8PerIsolateData::ensureDomInJSContext()
{
if (!m_perContextDataForRegex)
m_perContextDataForRegex = V8PerContextData::create(v8::Context::New(m_isolate), DOMWrapperWorld::create());
return m_perContextDataForRegex->context();
if (!m_domInJSPerContextData)
m_domInJSPerContextData = V8PerContextData::create(v8::Context::New(m_isolate), DOMWrapperWorld::create());
return m_domInJSPerContextData->context();
}
bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value)
......
......@@ -97,7 +97,7 @@ public:
bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>);
v8::Handle<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Handle<v8::Value>);
v8::Local<v8::Context> ensureRegexContext();
v8::Local<v8::Context> ensureDomInJSContext();
const char* previousSamplingState() const { return m_previousSamplingState; }
void setPreviousSamplingState(const char* name) { m_previousSamplingState = name; }
......@@ -119,7 +119,7 @@ private:
OwnPtr<StringCache> m_stringCache;
OwnPtr<V8HiddenValue> m_hiddenValue;
ScopedPersistent<v8::Value> m_liveRoot;
OwnPtr<V8PerContextData> m_perContextDataForRegex;
OwnPtr<V8PerContextData> m_domInJSPerContextData;
const char* m_previousSamplingState;
......
......@@ -33,39 +33,48 @@
#include "bindings/v8/V8PerIsolateData.h"
#include "wtf/Vector.h"
#include <v8.h>
namespace WebCore {
typedef Vector<MicrotaskCallback> MicrotaskQueue;
static MicrotaskQueue& microtaskQueue()
{
DEFINE_STATIC_LOCAL(MicrotaskQueue, microtaskQueue, ());
return microtaskQueue;
}
void Microtask::performCheckpoint()
{
V8PerIsolateData* isolateData = V8PerIsolateData::current();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
ASSERT(isolateData);
if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint())
return;
isolateData->setPerformingMicrotaskCheckpoint(true);
while (!microtaskQueue().isEmpty()) {
Vector<MicrotaskCallback> microtasks;
microtasks.swap(microtaskQueue());
for (size_t i = 0; i < microtasks.size(); ++i) {
microtasks[i]();
}
}
v8::HandleScope handleScope(isolate);
v8::Local<v8::Context> context = isolateData->ensureDomInJSContext();
v8::Context::Scope scope(context);
v8::V8::RunMicrotasks(isolate);
isolateData->setPerformingMicrotaskCheckpoint(false);
}
COMPILE_ASSERT(sizeof(void*) == sizeof(MicrotaskCallback), VoidPtrAndFunctionPtrAreSameSize);
static void microtaskFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
MicrotaskCallback callback =
reinterpret_cast<MicrotaskCallback>(reinterpret_cast<intptr_t>(
info.Data().As<v8::External>()->Value()));
(*callback)();
}
void Microtask::enqueueMicrotask(MicrotaskCallback callback)
{
microtaskQueue().append(callback);
v8::Isolate* isolate = v8::Isolate::GetCurrent();
V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
v8::HandleScope handleScope(isolate);
v8::Local<v8::Context> context = isolateData->ensureDomInJSContext();
v8::Context::Scope scope(context);
v8::Local<v8::External> handler =
v8::External::New(isolate,
reinterpret_cast<void*>(reinterpret_cast<intptr_t>(callback)));
v8::V8::EnqueueMicrotask(isolate, v8::Function::New(isolate, &microtaskFunctionCallback, handler));
}
} // namespace WebCore
......@@ -109,6 +109,7 @@ void initialize(Platform* platform)
v8::V8::SetEntropySource(&generateEntropy);
v8::V8::SetArrayBufferAllocator(WebCore::v8ArrayBufferAllocator());
v8::V8::Initialize();
v8::V8::SetAutorunMicrotasks(isolate, false);
WebCore::V8PerIsolateData::ensureInitialized(isolate);
s_isolateInterruptor = new WebCore::V8IsolateInterruptor(v8::Isolate::GetCurrent());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment