Commit 5d9090f2 authored by adamk@chromium.org's avatar adamk@chromium.org

Enqueue Blink microtasks using V8's C++ API

This avoids allocating a v8::Function to wrap Blink microtask callbacks, which
allows us to avoid entering a v8::Context to enqueue tasks.

ScriptRegexp is now the only use of the v8::Context stored in V8PerIsolateData.

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

git-svn-id: svn://svn.chromium.org/blink/trunk@175676 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 7b10a551
......@@ -40,7 +40,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)->ensureDomInJSContext());
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureScriptRegexpContext());
v8::TryCatch tryCatch;
unsigned flags = v8::RegExp::kNone;
......@@ -72,7 +72,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)->ensureDomInJSContext());
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureScriptRegexpContext());
v8::TryCatch tryCatch;
v8::Local<v8::RegExp> regex = m_regex.newLocal(isolate);
......
......@@ -75,8 +75,8 @@ V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
V8PerIsolateData::~V8PerIsolateData()
{
if (m_blinkInJSScriptState)
m_blinkInJSScriptState->disposePerContextData();
if (m_scriptRegexpScriptState)
m_scriptRegexpScriptState->disposePerContextData();
if (isMainThread())
mainThreadPerIsolateData = 0;
}
......@@ -148,14 +148,13 @@ void V8PerIsolateData::setDOMTemplate(void* domTemplateKey, v8::Handle<v8::Funct
currentDOMTemplateMap().add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, v8::Local<v8::FunctionTemplate>(templ)));
}
v8::Local<v8::Context> V8PerIsolateData::ensureDomInJSContext()
v8::Local<v8::Context> V8PerIsolateData::ensureScriptRegexpContext()
{
if (!m_blinkInJSScriptState) {
if (!m_scriptRegexpScriptState) {
v8::Local<v8::Context> context(v8::Context::New(m_isolate));
if (!context.IsEmpty())
m_blinkInJSScriptState = ScriptState::create(context, DOMWrapperWorld::create());
m_scriptRegexpScriptState = ScriptState::create(context, DOMWrapperWorld::create());
}
return m_blinkInJSScriptState ? m_blinkInJSScriptState->context() : v8::Local<v8::Context>();
return m_scriptRegexpScriptState->context();
}
bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value)
......
......@@ -92,8 +92,7 @@ public:
bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>);
v8::Handle<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Handle<v8::Value>);
// FIXME: This method should go away, because we shouldn't need a random context to be able to enqueue microtasks.
v8::Local<v8::Context> ensureDomInJSContext();
v8::Local<v8::Context> ensureScriptRegexpContext();
const char* previousSamplingState() const { return m_previousSamplingState; }
void setPreviousSamplingState(const char* name) { m_previousSamplingState = name; }
......@@ -115,7 +114,7 @@ private:
OwnPtr<StringCache> m_stringCache;
OwnPtr<V8HiddenValue> m_hiddenValue;
ScopedPersistent<v8::Value> m_liveRoot;
RefPtr<ScriptState> m_blinkInJSScriptState;
RefPtr<ScriptState> m_scriptRegexpScriptState;
const char* m_previousSamplingState;
......
......@@ -51,22 +51,16 @@ void Microtask::performCheckpoint()
isolateData->setPerformingMicrotaskCheckpoint(false);
}
static void microtaskFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
static void microtaskFunctionCallback(void* data)
{
OwnPtr<blink::WebThread::Task> task = adoptPtr(static_cast<blink::WebThread::Task*>(info.Data().As<v8::External>()->Value()));
OwnPtr<blink::WebThread::Task> task = adoptPtr(static_cast<blink::WebThread::Task*>(data));
task->run();
}
void Microtask::enqueueMicrotask(PassOwnPtr<blink::WebThread::Task> callback)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
v8::HandleScope handleScope(isolate);
v8::Local<v8::Context> context = isolateData->ensureDomInJSContext();
ASSERT(!context.IsEmpty());
v8::Context::Scope scope(context);
v8::Local<v8::External> handler = v8::External::New(isolate, callback.leakPtr());
isolate->EnqueueMicrotask(v8::Function::New(isolate, &microtaskFunctionCallback, handler));
isolate->EnqueueMicrotask(&microtaskFunctionCallback, callback.leakPtr());
}
void Microtask::enqueueMicrotask(const Closure& callback)
......
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