Commit 126de837 authored by jochen@chromium.org's avatar jochen@chromium.org

Switch blink to use a gin-managed isolate.

This also moves the basic V8 initialization to gin. The main advantage
is that we now initialize V8 first and then start creating isolates. It
also removes some code duplication.

BUG=none
R=haraken@chromium.org,andrewhayden@chromium.org

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

git-svn-id: svn://svn.chromium.org/blink/trunk@181832 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 4c2a747b
......@@ -189,10 +189,6 @@ static void timerTraceProfilerInMainThread(const char* name, int status)
static void initializeV8Common(v8::Isolate* isolate)
{
v8::ResourceConstraints constraints;
constraints.ConfigureDefaults(static_cast<uint64_t>(blink::Platform::current()->physicalMemoryMB()) << 20, static_cast<uint32_t>(blink::Platform::current()->virtualMemoryLimitMB()) << 20, static_cast<uint32_t>(blink::Platform::current()->numberOfProcessors()));
v8::SetResourceConstraints(isolate, &constraints);
v8::V8::AddGCPrologueCallback(V8GCController::gcPrologue);
v8::V8::AddGCEpilogueCallback(V8GCController::gcEpilogue);
......@@ -201,7 +197,7 @@ static void initializeV8Common(v8::Isolate* isolate)
isolate->SetAutorunMicrotasks(false);
}
void V8Initializer::initializeMainThreadIfNeeded(v8::Isolate* isolate)
void V8Initializer::initializeMainThreadIfNeeded()
{
ASSERT(isMainThread());
......@@ -210,10 +206,13 @@ void V8Initializer::initializeMainThreadIfNeeded(v8::Isolate* isolate)
return;
initialized = true;
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode, v8ArrayBufferAllocator());
v8::Isolate* isolate = V8PerIsolateData::initialize();
initializeV8Common(isolate);
v8::V8::SetFatalErrorHandler(reportFatalErrorInMainThread);
V8PerIsolateData::ensureInitialized(isolate);
v8::V8::AddMessageListener(messageHandlerInMainThread);
v8::V8::SetFailedAccessCheckCallbackFunction(failedAccessCheckCallbackInMainThread);
v8::V8::SetAllowCodeGenerationFromStringsCallback(codeGenerationCheckCallbackInMainThread);
......
......@@ -32,7 +32,7 @@ namespace blink {
class V8Initializer {
public:
static void initializeMainThreadIfNeeded(v8::Isolate*);
static void initializeMainThreadIfNeeded();
static void initializeWorker(v8::Isolate*);
};
......
......@@ -61,10 +61,9 @@ static void useCounterCallback(v8::Isolate* isolate, v8::Isolate::UseCounterFeat
}
}
V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
: m_isolate(isolate)
, m_isolateHolder(adoptPtr(new gin::IsolateHolder(m_isolate, v8ArrayBufferAllocator())))
, m_stringCache(adoptPtr(new StringCache(m_isolate)))
V8PerIsolateData::V8PerIsolateData()
: m_isolateHolder(adoptPtr(new gin::IsolateHolder()))
, m_stringCache(adoptPtr(new StringCache(isolate())))
, m_hiddenValue(adoptPtr(new V8HiddenValue()))
, m_constructorMode(ConstructorMode::CreateNewObject)
, m_recursionLevel(0)
......@@ -75,16 +74,18 @@ V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate)
, m_gcEventData(adoptPtr(new GCEventData()))
, m_performingMicrotaskCheckpoint(false)
{
// FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
isolate()->Enter();
#if ENABLE(ASSERT)
// currentThread will always be non-null in production, but can be null in Chromium unit tests.
if (blink::Platform::current()->currentThread())
isolate->AddCallCompletedCallback(&assertV8RecursionScope);
isolate()->AddCallCompletedCallback(&assertV8RecursionScope);
#endif
if (isMainThread()) {
mainThreadPerIsolateData = this;
PageScriptDebugServer::setMainThreadIsolate(isolate);
PageScriptDebugServer::setMainThreadIsolate(isolate());
}
isolate->SetUseCounterCallback(&useCounterCallback);
isolate()->SetUseCounterCallback(&useCounterCallback);
}
V8PerIsolateData::~V8PerIsolateData()
......@@ -102,19 +103,18 @@ v8::Isolate* V8PerIsolateData::mainThreadIsolate()
return mainThreadPerIsolateData->isolate();
}
void V8PerIsolateData::ensureInitialized(v8::Isolate* isolate)
v8::Isolate* V8PerIsolateData::initialize()
{
ASSERT(isolate);
if (!isolate->GetData(gin::kEmbedderBlink)) {
V8PerIsolateData* data = new V8PerIsolateData(isolate);
isolate->SetData(gin::kEmbedderBlink, data);
}
V8PerIsolateData* data = new V8PerIsolateData();
v8::Isolate* isolate = data->isolate();
isolate->SetData(gin::kEmbedderBlink, data);
return isolate;
}
v8::Persistent<v8::Value>& V8PerIsolateData::ensureLiveRoot()
{
if (m_liveRoot.isEmpty())
m_liveRoot.set(m_isolate, v8::Null(m_isolate));
m_liveRoot.set(isolate(), v8::Null(isolate()));
return m_liveRoot.getUnsafe();
}
......@@ -125,13 +125,14 @@ void V8PerIsolateData::dispose(v8::Isolate* isolate)
isolate->RemoveCallCompletedCallback(&assertV8RecursionScope);
#endif
void* data = isolate->GetData(gin::kEmbedderBlink);
// FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone.
isolate->Exit();
delete static_cast<V8PerIsolateData*>(data);
isolate->SetData(gin::kEmbedderBlink, 0);
}
V8PerIsolateData::DOMTemplateMap& V8PerIsolateData::currentDOMTemplateMap()
{
if (DOMWrapperWorld::current(m_isolate).isMainWorld())
if (DOMWrapperWorld::current(isolate()).isMainWorld())
return m_domTemplateMapForMainWorld;
return m_domTemplateMapForNonMainWorld;
}
......@@ -141,10 +142,10 @@ v8::Handle<v8::FunctionTemplate> V8PerIsolateData::domTemplate(void* domTemplate
DOMTemplateMap& domTemplateMap = currentDOMTemplateMap();
DOMTemplateMap::iterator result = domTemplateMap.find(domTemplateKey);
if (result != domTemplateMap.end())
return result->value.Get(m_isolate);
return result->value.Get(isolate());
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(m_isolate, callback, data, signature, length);
domTemplateMap.add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, templ));
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate(), callback, data, signature, length);
domTemplateMap.add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(isolate(), templ));
return templ;
}
......@@ -153,19 +154,19 @@ v8::Handle<v8::FunctionTemplate> V8PerIsolateData::existingDOMTemplate(void* dom
DOMTemplateMap& domTemplateMap = currentDOMTemplateMap();
DOMTemplateMap::iterator result = domTemplateMap.find(domTemplateKey);
if (result != domTemplateMap.end())
return result->value.Get(m_isolate);
return result->value.Get(isolate());
return v8::Local<v8::FunctionTemplate>();
}
void V8PerIsolateData::setDOMTemplate(void* domTemplateKey, v8::Handle<v8::FunctionTemplate> templ)
{
currentDOMTemplateMap().add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, v8::Local<v8::FunctionTemplate>(templ)));
currentDOMTemplateMap().add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(isolate(), v8::Local<v8::FunctionTemplate>(templ)));
}
v8::Local<v8::Context> V8PerIsolateData::ensureScriptRegexpContext()
{
if (!m_scriptRegexpScriptState) {
v8::Local<v8::Context> context(v8::Context::New(m_isolate));
v8::Local<v8::Context> context(v8::Context::New(isolate()));
m_scriptRegexpScriptState = ScriptState::create(context, DOMWrapperWorld::create());
}
return m_scriptRegexpScriptState->context();
......@@ -182,7 +183,7 @@ bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::V
DOMTemplateMap::iterator result = domTemplateMap.find(info);
if (result == domTemplateMap.end())
return false;
v8::Handle<v8::FunctionTemplate> templ = result->value.Get(m_isolate);
v8::Handle<v8::FunctionTemplate> templ = result->value.Get(isolate());
return templ->HasInstance(value);
}
......@@ -201,7 +202,7 @@ v8::Handle<v8::Object> V8PerIsolateData::findInstanceInPrototypeChain(const Wrap
DOMTemplateMap::iterator result = domTemplateMap.find(info);
if (result == domTemplateMap.end())
return v8::Handle<v8::Object>();
v8::Handle<v8::FunctionTemplate> templ = result->value.Get(m_isolate);
v8::Handle<v8::FunctionTemplate> templ = result->value.Get(isolate());
return v8::Handle<v8::Object>::Cast(value)->FindInstanceInPrototypeChain(templ);
}
......@@ -226,8 +227,8 @@ static void constructorOfToString(const v8::FunctionCallbackInfo<v8::Value>& inf
v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate()
{
if (m_toStringTemplate.isEmpty())
m_toStringTemplate.set(m_isolate, v8::FunctionTemplate::New(m_isolate, constructorOfToString));
return m_toStringTemplate.newLocal(m_isolate);
m_toStringTemplate.set(isolate(), v8::FunctionTemplate::New(isolate(), constructorOfToString));
return m_toStringTemplate.newLocal(isolate());
}
} // namespace blink
......@@ -51,7 +51,7 @@ typedef WTF::Vector<DOMDataStore*> DOMDataStoreList;
class V8PerIsolateData {
public:
static void ensureInitialized(v8::Isolate*);
static v8::Isolate* initialize();
static V8PerIsolateData* from(v8::Isolate* isolate)
{
ASSERT(isolate);
......@@ -61,7 +61,7 @@ public:
static void dispose(v8::Isolate*);
static v8::Isolate* mainThreadIsolate();
v8::Isolate* isolate() { return m_isolate; }
v8::Isolate* isolate() { return m_isolateHolder->isolate(); }
v8::Handle<v8::FunctionTemplate> toStringTemplate();
......@@ -100,7 +100,7 @@ public:
void setPreviousSamplingState(const char* name) { m_previousSamplingState = name; }
private:
explicit V8PerIsolateData(v8::Isolate*);
V8PerIsolateData();
~V8PerIsolateData();
typedef HashMap<const void*, v8::Eternal<v8::FunctionTemplate> > DOMTemplateMap;
......@@ -108,7 +108,6 @@ private:
bool hasInstance(const WrapperTypeInfo*, v8::Handle<v8::Value>, DOMTemplateMap&);
v8::Handle<v8::Object> findInstanceInPrototypeChain(const WrapperTypeInfo*, v8::Handle<v8::Value>, DOMTemplateMap&);
v8::Isolate* m_isolate;
OwnPtr<gin::IsolateHolder> m_isolateHolder;
DOMTemplateMap m_domTemplateMapForMainWorld;
DOMTemplateMap m_domTemplateMapForNonMainWorld;
......
......@@ -105,16 +105,14 @@ public:
};
WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalScope)
: m_isolate(v8::Isolate::New())
: m_isolate(0)
, m_workerGlobalScope(workerGlobalScope)
, m_executionForbidden(false)
, m_executionScheduledToTerminate(false)
, m_globalScopeExecutionState(0)
{
m_isolate->Enter();
m_isolate = V8PerIsolateData::initialize();
V8Initializer::initializeWorker(m_isolate);
v8::V8::Initialize();
V8PerIsolateData::ensureInitialized(m_isolate);
m_world = DOMWrapperWorld::create(WorkerWorldId);
m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate));
ThreadState::current()->addInterruptor(m_interruptor.get());
......@@ -133,8 +131,6 @@ public:
virtual void postCleanup()
{
V8PerIsolateData::dispose(m_isolate);
m_isolate->Exit();
m_isolate->Dispose();
}
private:
......
......@@ -92,29 +92,13 @@ static ThreadState::Interruptor* s_isolateInterruptor = 0;
// Doing so may cause hard to reproduce crashes.
static bool s_webKitInitialized = false;
static bool generateEntropy(unsigned char* buffer, size_t length)
{
if (Platform::current()) {
Platform::current()->cryptographicallyRandomValues(buffer, length);
return true;
}
return false;
}
void initialize(Platform* platform)
{
initializeWithoutV8(platform);
v8::V8::InitializePlatform(gin::V8Platform::Get());
v8::Isolate* isolate = v8::Isolate::New();
isolate->Enter();
V8Initializer::initializeMainThreadIfNeeded(isolate);
v8::V8::SetEntropySource(&generateEntropy);
v8::V8::SetArrayBufferAllocator(v8ArrayBufferAllocator());
v8::V8::Initialize();
V8PerIsolateData::ensureInitialized(isolate);
V8Initializer::initializeMainThreadIfNeeded();
s_isolateInterruptor = new V8IsolateInterruptor(v8::Isolate::GetCurrent());
s_isolateInterruptor = new V8IsolateInterruptor(V8PerIsolateData::mainThreadIsolate());
ThreadState::current()->addInterruptor(s_isolateInterruptor);
// currentThread will always be non-null in production, but can be null in Chromium unit tests.
......@@ -224,8 +208,6 @@ void shutdown()
v8::Isolate* isolate = V8PerIsolateData::mainThreadIsolate();
V8PerIsolateData::dispose(isolate);
isolate->Exit();
isolate->Dispose();
shutdownWithoutV8();
}
......
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