author | caroline <ccullen@mozilla.com> |
Tue, 28 Apr 2020 14:27:00 +0000 | |
changeset 526521 | b1766549aa1d7296555910c05512bf64041d15e2 |
parent 526520 | b989206ee3fc9b3275788f2a50bd2f300d51f805 |
child 526522 | 9555dcc88ac9fcc0486559a1cef6ff71dba3bb21 |
push id | 114319 |
push user | ccullen@mozilla.com |
push date | Tue, 28 Apr 2020 16:21:09 +0000 |
treeherder | autoland@b1766549aa1d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tcampbell |
bugs | 1632286 |
milestone | 77.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -306,16 +306,18 @@ static bool EvalKernel(JSContext* cx, Ha if (introducerFilename) { options.setFileAndLine(filename, 1); options.setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset); } else { options.setFileAndLine("eval", 1); options.setIntroductionType("eval"); } + options.setNonSyntacticScope( + enclosing->hasOnChain(ScopeKind::NonSyntactic)); AutoStableStringChars linearChars(cx); if (!linearChars.initTwoByte(cx, linearStr)) { return false; } SourceText<char16_t> srcBuf; @@ -406,16 +408,18 @@ bool js::DirectEvalStringFromIon(JSConte if (introducerFilename) { options.setFileAndLine(filename, 1); options.setIntroductionInfo(introducerFilename, "eval", lineno, callerScript, pcOffset); } else { options.setFileAndLine("eval", 1); options.setIntroductionType("eval"); } + options.setNonSyntacticScope( + enclosing->hasOnChain(ScopeKind::NonSyntactic)); AutoStableStringChars linearChars(cx); if (!linearChars.initTwoByte(cx, linearStr)) { return false; } SourceText<char16_t> srcBuf;
--- a/js/src/debugger/Frame.cpp +++ b/js/src/debugger/Frame.cpp @@ -981,16 +981,17 @@ static bool EvaluateInEnv(JSContext* cx, cx, frame && frame.hasScript() ? frame.script() : nullptr); RootedScript script(cx); ScopeKind scopeKind; if (IsGlobalLexicalEnvironment(env)) { scopeKind = ScopeKind::Global; } else { scopeKind = ScopeKind::NonSyntactic; + options.setNonSyntacticScope(true); } if (frame) { MOZ_ASSERT(scopeKind == ScopeKind::NonSyntactic); RootedScope scope(cx, GlobalScope::createEmpty(cx, ScopeKind::NonSyntactic)); if (!scope) { return false;
--- a/js/src/frontend/BCEScriptStencil.cpp +++ b/js/src/frontend/BCEScriptStencil.cpp @@ -21,20 +21,18 @@ BCEScriptStencil::BCEScriptStencil(Bytec } void BCEScriptStencil::init(BytecodeEmitter& bce, UniquePtr<ImmutableScriptData> immutableData) { natoms = bce.perScriptData().atomIndices()->count(); immutableFlags = bce.sc->immutableFlags(); - // Update the flags generated by BCE. - immutableFlags.setFlag( - ImmutableFlags::HasNonSyntacticScope, - bce.outermostScope().hasOnChain(ScopeKind::NonSyntactic)); + MOZ_ASSERT(bce.outermostScope().hasOnChain(ScopeKind::NonSyntactic) == + immutableFlags.hasFlag(ImmutableFlags::HasNonSyntacticScope)); gcThings = bce.perScriptData().gcThingList().stealGCThings(); // Hand over the ImmutableScriptData instance generated by BCE. immutableScriptData = std::move(immutableData); // Update flags specific to functions. if (isFunction()) {
--- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -922,33 +922,16 @@ ModuleObject* frontend::CompileModule(JS } ModuleObject* frontend::CompileModule(JSContext* cx, const JS::ReadOnlyCompileOptions& options, SourceText<Utf8Unit>& srcBuf) { return CreateModule(cx, options, srcBuf); } -static void CheckFlagsOnDelazification(uint32_t lazy, uint32_t nonLazy) { -#ifdef DEBUG - // These flags are expect to be unset for lazy scripts and are only valid - // after a script has been compiled with the full parser. - // - // NOTE: Keep in sync with JSScript::relazify(). - constexpr uint32_t NonLazyFlagsMask = - uint32_t(BaseScript::ImmutableFlags::HasNonSyntacticScope); - - // These flags are expected to match between lazy and full parsing. - constexpr uint32_t MatchedFlagsMask = ~NonLazyFlagsMask; - - MOZ_ASSERT((lazy & NonLazyFlagsMask) == 0); - MOZ_ASSERT((lazy & MatchedFlagsMask) == (nonLazy & MatchedFlagsMask)); -#endif // DEBUG -} - template <typename Unit> static bool CompileLazyFunctionImpl(JSContext* cx, Handle<BaseScript*> lazy, const Unit* units, size_t length) { MOZ_ASSERT(cx->compartment() == lazy->compartment()); // We can only compile functions whose parents have previously been // compiled, because compilation requires full information about the // function's immediately enclosing scope. @@ -1002,30 +985,34 @@ static bool CompileLazyFunctionImpl(JSCo lazy->generatorKind(), lazy->asyncKind()); if (!pn) { return false; } if (!parser.publishDeferredFunctions()) { return false; } - uint32_t lazyFlags = lazy->immutableFlags(); + mozilla::DebugOnly<uint32_t> lazyFlags = + static_cast<uint32_t>(lazy->immutableFlags()); BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->funbox(), compilationInfo, BytecodeEmitter::LazyFunction); if (!bce.init(pn->pn_pos)) { return false; } if (!bce.emitFunctionScript(pn, BytecodeEmitter::TopLevelFunction::Yes)) { return false; } - CheckFlagsOnDelazification(lazyFlags, - bce.getResultScript()->immutableFlags()); + MOZ_ASSERT(lazyFlags == bce.getResultScript()->immutableFlags()); + MOZ_ASSERT(bce.getResultScript()->outermostScope()->hasOnChain( + ScopeKind::NonSyntactic) == + bce.getResultScript()->immutableFlags().hasFlag( + JSScript::ImmutableFlags::HasNonSyntacticScope)); assertException.reset(); return true; } bool frontend::CompileLazyFunction(JSContext* cx, Handle<BaseScript*> lazy, const char16_t* units, size_t length) { return CompileLazyFunctionImpl(cx, lazy, units, length);
--- a/js/src/frontend/SharedContext.cpp +++ b/js/src/frontend/SharedContext.cpp @@ -14,16 +14,51 @@ #include "wasm/AsmJS.h" #include "frontend/ParseContext-inl.h" #include "vm/EnvironmentObject-inl.h" namespace js { namespace frontend { +SharedContext::SharedContext(JSContext* cx, Kind kind, + CompilationInfo& compilationInfo, + Directives directives, SourceExtent extent, + ImmutableScriptFlags immutableFlags) + : cx_(cx), + kind_(kind), + compilationInfo_(compilationInfo), + thisBinding_(ThisBinding::Global), + extent(extent), + allowNewTarget_(false), + allowSuperProperty_(false), + allowSuperCall_(false), + allowArguments_(true), + inWith_(false), + needsThisTDZChecks_(false), + localStrict(false), + hasExplicitUseStrict_(false), + immutableFlags_(immutableFlags) { + if (kind_ == Kind::FunctionBox) { + immutableFlags_.setFlag(ImmutableFlags::IsFunction); + } else if (kind_ == Kind::Module) { + MOZ_ASSERT(!compilationInfo.options.nonSyntacticScope); + immutableFlags_.setFlag(ImmutableFlags::IsModule); + } else if (kind_ == Kind::Eval) { + immutableFlags_.setFlag(ImmutableFlags::IsForEval); + } else { + MOZ_ASSERT(kind_ == Kind::Global); + } + + immutableFlags_.setFlag(ImmutableFlags::Strict, directives.strict()); + + immutableFlags_.setFlag(ImmutableFlags::HasNonSyntacticScope, + compilationInfo.options.nonSyntacticScope); +} + void SharedContext::computeAllowSyntax(Scope* scope) { for (ScopeIter si(scope); si; si++) { if (si.kind() == ScopeKind::Function) { FunctionScope* funScope = &si.scope()->as<FunctionScope>(); JSFunction* fun = funScope->canonicalFunction(); if (fun->isArrow()) { continue; }
--- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -145,43 +145,17 @@ class SharedContext { void computeAllowSyntax(Scope* scope); void computeInWith(Scope* scope); void computeThisBinding(Scope* scope); public: SharedContext(JSContext* cx, Kind kind, CompilationInfo& compilationInfo, Directives directives, SourceExtent extent, - ImmutableScriptFlags immutableFlags = {}) - : cx_(cx), - kind_(kind), - compilationInfo_(compilationInfo), - thisBinding_(ThisBinding::Global), - extent(extent), - allowNewTarget_(false), - allowSuperProperty_(false), - allowSuperCall_(false), - allowArguments_(true), - inWith_(false), - needsThisTDZChecks_(false), - localStrict(false), - hasExplicitUseStrict_(false), - immutableFlags_(immutableFlags) { - if (kind_ == Kind::FunctionBox) { - immutableFlags_.setFlag(ImmutableFlags::IsFunction); - } else if (kind_ == Kind::Module) { - immutableFlags_.setFlag(ImmutableFlags::IsModule); - } else if (kind_ == Kind::Eval) { - immutableFlags_.setFlag(ImmutableFlags::IsForEval); - } else { - MOZ_ASSERT(kind_ == Kind::Global); - } - - immutableFlags_.setFlag(ImmutableFlags::Strict, directives.strict()); - } + ImmutableScriptFlags immutableFlags = {}); // If this is the outermost SharedContext, the Scope that encloses // it. Otherwise nullptr. virtual Scope* compilationEnclosingScope() const = 0; bool isFunctionBox() const { return kind_ == Kind::FunctionBox; } inline FunctionBox* asFunctionBox(); bool isModuleContext() const { return kind_ == Kind::Module; }
--- a/js/src/vm/CompilationAndEvaluation.cpp +++ b/js/src/vm/CompilationAndEvaluation.cpp @@ -257,17 +257,17 @@ class FunctionCompiler { } template <typename Unit> inline MOZ_MUST_USE bool addFunctionBody(const SourceText<Unit>& srcBuf) { return funStr_.append(srcBuf.get(), srcBuf.length()); } JSFunction* finish(HandleObjectVector envChain, - const ReadOnlyCompileOptions& options) { + const ReadOnlyCompileOptions& optionsArg) { if (!funStr_.append(FunctionConstructorFinalBrace)) { return nullptr; } size_t newLen = funStr_.length(); UniqueTwoByteChars stolen(funStr_.stealChars()); if (!stolen) { return nullptr; @@ -297,16 +297,20 @@ class FunctionCompiler { return nullptr; } // Make sure the static scope chain matches up when we have a // non-syntactic scope. MOZ_ASSERT_IF(!IsGlobalLexicalEnvironment(enclosingEnv), enclosingScope->hasOnChain(ScopeKind::NonSyntactic)); + CompileOptions options(cx_, optionsArg); + options.setNonSyntacticScope( + enclosingScope->hasOnChain(ScopeKind::NonSyntactic)); + if (!js::frontend::CompileStandaloneFunction( cx_, &fun, options, newSrcBuf, mozilla::Some(parameterListEnd_), enclosingScope)) { return nullptr; } // When the function name isn't a valid identifier, the generated function // source in srcBuf won't include the name, so name the function manually. @@ -470,16 +474,17 @@ static bool EvaluateSourceBuffer(JSConte CompileOptions options(cx, optionsArg); MOZ_ASSERT(!cx->zone()->isAtomsZone()); AssertHeapIsIdle(); CHECK_THREAD(cx); cx->check(env); MOZ_ASSERT_IF(!IsGlobalLexicalEnvironment(env), scopeKind == ScopeKind::NonSyntactic); + options.setNonSyntacticScope(scopeKind == ScopeKind::NonSyntactic); options.setIsRunOnce(true); RootedScript script(cx); { LifoAllocScope allocScope(&cx->tempLifoAlloc()); frontend::CompilationInfo compilationInfo(cx, allocScope, options); if (!compilationInfo.init(cx)) { return false;
--- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -4022,22 +4022,16 @@ void JSScript::relazify(JSRuntime* rt) { // Release the bytecode and gcthings list. // NOTE: We clear the PrivateScriptData to nullptr. This is fine because we // only allowed relazification (via AllowRelazify) if the original lazy // script we compiled from had a nullptr PrivateScriptData. swapData(scriptData); freeSharedData(); - // Clear flags that are only set by the BytecodeEmitter. This ensures that - // CheckFlagsOnDelazification is still valid on next compile. - // - // NOTE: Keep in sync with CheckFlagsOnDelazification. - clearFlag(ImmutableFlags::HasNonSyntacticScope); - // We should not still be in any side-tables for the debugger or // code-coverage. The finalizer will not be able to clean them up once // bytecode is released. We check in JSFunction::maybeRelazify() for these // conditions before requesting relazification. MOZ_ASSERT(!coverage::IsLCovEnabled()); MOZ_ASSERT(!hasScriptCounts()); MOZ_ASSERT(!hasDebugScript()); @@ -4844,26 +4838,27 @@ static JSScript* CopyScriptImpl(JSContex return nullptr; } /* NB: Keep this in sync with XDRScript. */ // Some embeddings are not careful to use ExposeObjectToActiveJS as needed. JS::AssertObjectIsNotGray(sourceObject); + ImmutableScriptFlags flags = src->immutableFlags(); + flags.setFlag(JSScript::ImmutableFlags::HasNonSyntacticScope, + scopes[0]->hasOnChain(ScopeKind::NonSyntactic)); + // Create a new JSScript to fill in. RootedScript dst(cx, JSScript::Create(cx, functionOrGlobal, sourceObject, - src->extent(), src->immutableFlags())); + src->extent(), flags)); if (!dst) { return nullptr; } - dst->setFlag(JSScript::ImmutableFlags::HasNonSyntacticScope, - scopes[0]->hasOnChain(ScopeKind::NonSyntactic)); - // Reset the mutable flags to request arguments analysis as needed. dst->resetArgsUsageAnalysis(); // Clone the PrivateScriptData into dst if (!PrivateScriptData::Clone(cx, src, dst, scopes)) { return nullptr; }