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 ...@@ -40,7 +40,7 @@ ScriptRegexp::ScriptRegexp(const String& pattern, TextCaseSensitivity caseSensit
{ {
v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate); v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureDomInJSContext()); v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureScriptRegexpContext());
v8::TryCatch tryCatch; v8::TryCatch tryCatch;
unsigned flags = v8::RegExp::kNone; unsigned flags = v8::RegExp::kNone;
...@@ -72,7 +72,7 @@ int ScriptRegexp::match(const String& string, int startFrom, int* matchLength) c ...@@ -72,7 +72,7 @@ int ScriptRegexp::match(const String& string, int startFrom, int* matchLength) c
v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate); v8::HandleScope handleScope(isolate);
v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureDomInJSContext()); v8::Context::Scope contextScope(V8PerIsolateData::from(isolate)->ensureScriptRegexpContext());
v8::TryCatch tryCatch; v8::TryCatch tryCatch;
v8::Local<v8::RegExp> regex = m_regex.newLocal(isolate); v8::Local<v8::RegExp> regex = m_regex.newLocal(isolate);
......
...@@ -75,8 +75,8 @@ V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate) ...@@ -75,8 +75,8 @@ V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
V8PerIsolateData::~V8PerIsolateData() V8PerIsolateData::~V8PerIsolateData()
{ {
if (m_blinkInJSScriptState) if (m_scriptRegexpScriptState)
m_blinkInJSScriptState->disposePerContextData(); m_scriptRegexpScriptState->disposePerContextData();
if (isMainThread()) if (isMainThread())
mainThreadPerIsolateData = 0; mainThreadPerIsolateData = 0;
} }
...@@ -148,14 +148,13 @@ void V8PerIsolateData::setDOMTemplate(void* domTemplateKey, v8::Handle<v8::Funct ...@@ -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))); 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)); v8::Local<v8::Context> context(v8::Context::New(m_isolate));
if (!context.IsEmpty()) m_scriptRegexpScriptState = ScriptState::create(context, DOMWrapperWorld::create());
m_blinkInJSScriptState = 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) bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value)
......
...@@ -92,8 +92,7 @@ public: ...@@ -92,8 +92,7 @@ public:
bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>); bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>);
v8::Handle<v8::Object> findInstanceInPrototypeChain(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> ensureScriptRegexpContext();
v8::Local<v8::Context> ensureDomInJSContext();
const char* previousSamplingState() const { return m_previousSamplingState; } const char* previousSamplingState() const { return m_previousSamplingState; }
void setPreviousSamplingState(const char* name) { m_previousSamplingState = name; } void setPreviousSamplingState(const char* name) { m_previousSamplingState = name; }
...@@ -115,7 +114,7 @@ private: ...@@ -115,7 +114,7 @@ private:
OwnPtr<StringCache> m_stringCache; OwnPtr<StringCache> m_stringCache;
OwnPtr<V8HiddenValue> m_hiddenValue; OwnPtr<V8HiddenValue> m_hiddenValue;
ScopedPersistent<v8::Value> m_liveRoot; ScopedPersistent<v8::Value> m_liveRoot;
RefPtr<ScriptState> m_blinkInJSScriptState; RefPtr<ScriptState> m_scriptRegexpScriptState;
const char* m_previousSamplingState; const char* m_previousSamplingState;
......
...@@ -51,22 +51,16 @@ void Microtask::performCheckpoint() ...@@ -51,22 +51,16 @@ void Microtask::performCheckpoint()
isolateData->setPerformingMicrotaskCheckpoint(false); 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(); task->run();
} }
void Microtask::enqueueMicrotask(PassOwnPtr<blink::WebThread::Task> callback) void Microtask::enqueueMicrotask(PassOwnPtr<blink::WebThread::Task> callback)
{ {
v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::Isolate* isolate = v8::Isolate::GetCurrent();
V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate); isolate->EnqueueMicrotask(&microtaskFunctionCallback, callback.leakPtr());
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));
} }
void Microtask::enqueueMicrotask(const Closure& callback) 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