Bug 589199 - Fix up the global lexical scope when merging off-thread compiled scripts. (r=bhackett)

This commit is contained in:
Shu-yu Guo 2015-10-06 14:00:29 -07:00
parent cdc1225070
commit e763b51eb8
4 changed files with 50 additions and 4 deletions

View File

@ -6745,6 +6745,14 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
MOZ_ASSERT(script->compartment() == source);
script->compartment_ = target;
script->setTypesGeneration(target->zone()->types.generation);
// See warning in handleParseWorkload. If we start optimizing global
// lexicals, we would need to merge the contents of the static global
// lexical scope.
if (JSObject* enclosing = script->enclosingStaticScope()) {
if (IsStaticGlobalLexicalScope(enclosing))
script->fixEnclosingStaticGlobalLexicalScope();
}
}
for (ZoneCellIter iter(source->zone(), AllocKind::BASE_SHAPE); !iter.done(); iter.next()) {
@ -6774,6 +6782,21 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
}
}
// After fixing JSFunctions' compartments, we can fix LazyScripts'
// enclosing scopes.
for (ZoneCellIter iter(source->zone(), AllocKind::LAZY_SCRIPT); !iter.done(); iter.next()) {
LazyScript* lazy = iter.get<LazyScript>();
MOZ_ASSERT(lazy->functionNonDelazifying()->compartment() == target);
// See warning in handleParseWorkload. If we start optimizing global
// lexicals, we would need to merge the contents of the static global
// lexical scope.
if (JSObject* enclosing = lazy->enclosingScope()) {
if (IsStaticGlobalLexicalScope(enclosing))
lazy->fixEnclosingStaticGlobalLexicalScope();
}
}
// The source should be the only compartment in its zone.
for (CompartmentsInZoneIter c(source->zone()); !c.done(); c.next())
MOZ_ASSERT(c.get() == source);

View File

@ -2946,6 +2946,20 @@ JSScript::uninlinedGlobal() const
return global();
}
void
JSScript::fixEnclosingStaticGlobalLexicalScope()
{
MOZ_ASSERT(IsStaticGlobalLexicalScope(enclosingStaticScope_));
enclosingStaticScope_ = &global().lexicalScope().staticBlock();
}
void
LazyScript::fixEnclosingStaticGlobalLexicalScope()
{
MOZ_ASSERT(IsStaticGlobalLexicalScope(enclosingScope_));
enclosingScope_ = &function_->global().lexicalScope().staticBlock();
}
void
JSScript::finalize(FreeOp* fop)
{

View File

@ -1644,6 +1644,10 @@ class JSScript : public js::gc::TenuredCell
return enclosingStaticScope_;
}
// Switch the script over from the off-thread compartment's static
// global lexical scope to the main thread compartment's.
void fixEnclosingStaticGlobalLexicalScope();
private:
bool makeTypes(JSContext* cx);
@ -2186,6 +2190,11 @@ class LazyScript : public gc::TenuredCell
JSObject* enclosingScope() const {
return enclosingScope_;
}
// Switch the script over from the off-thread compartment's static
// global lexical scope to the main thread compartment's.
void fixEnclosingStaticGlobalLexicalScope();
ScriptSourceObject* sourceObject() const;
ScriptSource* scriptSource() const {
return sourceObject()->source();

View File

@ -1396,16 +1396,16 @@ HelperThread::handleParseWorkload()
// ! WARNING WARNING WARNING !
//
// See comment in Parser::bindLexical about optimizing global lexical
// bindings. If we start optimizing them, passing in parseTask->cx's
// bindings. If we start optimizing them, passing in task->cx's
// global lexical scope would be incorrect!
//
// ! WARNING WARNING WARNING !
ExclusiveContext* parseCx = parseTask->cx;
ExclusiveContext* parseCx = task->cx;
Rooted<ClonedBlockObject*> globalLexical(parseCx, &parseCx->global()->lexicalScope());
Rooted<ScopeObject*> staticScope(parseCx, &globalLexical->staticBlock());
task->script = frontend::CompileScript(parseCx, &parseTask->alloc,
task->script = frontend::CompileScript(parseCx, &task->alloc,
globalLexical, staticScope, nullptr,
parseTask->options, srcBuf,
task->options, srcBuf,
/* source_ = */ nullptr,
/* extraSct = */ nullptr,
/* sourceObjectOut = */ &(task->sourceObject));