From e763b51eb85d4e8bb77694a2c679113c5ef0cd68 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Tue, 6 Oct 2015 14:00:29 -0700 Subject: [PATCH] Bug 589199 - Fix up the global lexical scope when merging off-thread compiled scripts. (r=bhackett) --- js/src/jsgc.cpp | 23 +++++++++++++++++++++++ js/src/jsscript.cpp | 14 ++++++++++++++ js/src/jsscript.h | 9 +++++++++ js/src/vm/HelperThreads.cpp | 8 ++++---- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 6eb74ceea6c..8c480749ede 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -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(); + 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); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 55cb5abb329..70f64b45da1 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -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) { diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 6688df2c9cb..244070fc663 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -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(); diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index beb46ed4c9c..d6980801352 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -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 globalLexical(parseCx, &parseCx->global()->lexicalScope()); Rooted 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));