author | Jeff Walden <jwalden@mit.edu> |
Mon, 09 Apr 2018 12:58:02 -0700 | |
changeset 412783 | d21bb4d700d80e15500f9140bae2b3e014eaeb10 |
parent 412782 | ca65fd361e412c270276850cbcc6511c5022f48e |
child 412784 | 4f2a7bac273340118c8e74c539553fd912dc2813 |
push id | 33818 |
push user | apavel@mozilla.com |
push date | Wed, 11 Apr 2018 14:36:40 +0000 |
treeherder | mozilla-central@cfe6399e142c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | arai |
bugs | 1452818 |
milestone | 61.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/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -61,17 +61,17 @@ class MOZ_STACK_CLASS BytecodeCompiler // If toString{Start,End} are not explicitly passed, assume the script's // offsets in the source used to parse it are the same as what should be // used to compute its Function.prototype.toString() value. bool createScript(); bool createScript(uint32_t toStringStart, uint32_t toStringEnd); bool emplaceEmitter(Maybe<BytecodeEmitter>& emitter, SharedContext* sharedContext); - bool handleParseFailure(const Directives& newDirectives); + bool handleParseFailure(const Directives& newDirectives, TokenStream::Position& startPosition); bool deoptimizeArgumentsInEnclosingScripts(JSContext* cx, HandleObject environment); AutoKeepAtoms keepAtoms; JSContext* cx; LifoAlloc& alloc; const ReadOnlyCompileOptions& options; SourceBufferHolder& sourceBuffer; @@ -81,17 +81,16 @@ class MOZ_STACK_CLASS BytecodeCompiler RootedScriptSource sourceObject; ScriptSource* scriptSource; Maybe<UsedNameTracker> usedNames; Maybe<Parser<SyntaxParseHandler, char16_t>> syntaxParser; Maybe<Parser<FullParseHandler, char16_t>> parser; Directives directives; - TokenStream::Position startPosition; RootedScript script; }; AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id, const ErrorReporter& errorReporter) #ifdef JS_TRACE_LOGGING : logger_(TraceLoggerForCurrentThread(cx)) @@ -152,17 +151,16 @@ BytecodeCompiler::BytecodeCompiler(JSCon cx(cx), alloc(alloc), options(options), sourceBuffer(sourceBuffer), enclosingScope(cx, enclosingScope), sourceObject(cx), scriptSource(nullptr), directives(options.strictOption), - startPosition(keepAtoms), script(cx) { MOZ_ASSERT(sourceBuffer.get()); } bool BytecodeCompiler::checkLength() { @@ -224,21 +222,17 @@ BytecodeCompiler::createParser() if (!syntaxParser->checkOptions()) return false; } parser.emplace(cx, alloc, options, sourceBuffer.get(), sourceBuffer.length(), /* foldConstants = */ true, *usedNames, syntaxParser.ptrOr(nullptr), nullptr); parser->ss = scriptSource; - if (!parser->checkOptions()) - return false; - - parser->tokenStream.tell(&startPosition); - return true; + return parser->checkOptions(); } bool BytecodeCompiler::createSourceAndParser(const Maybe<uint32_t>& parameterListEnd /* = Nothing() */) { return createScriptSource(parameterListEnd) && createParser(); } @@ -264,17 +258,18 @@ BytecodeCompiler::emplaceEmitter(Maybe<B BytecodeEmitter::EmitterMode emitterMode = options.selfHostingMode ? BytecodeEmitter::SelfHosting : BytecodeEmitter::Normal; emitter.emplace(/* parent = */ nullptr, parser.ptr(), sharedContext, script, /* lazyScript = */ nullptr, options.lineno, emitterMode); return emitter->init(); } bool -BytecodeCompiler::handleParseFailure(const Directives& newDirectives) +BytecodeCompiler::handleParseFailure(const Directives& newDirectives, + TokenStream::Position& startPosition) { if (parser->hadAbortedSyntaxParse()) { // Hit some unrecoverable ambiguity during an inner syntax parse. // Syntax parsing has now been disabled in the parser, so retry // the parse. parser->clearAbortedSyntaxParse(); } else if (parser->anyChars.hadError() || directives == newDirectives) { return false; @@ -311,16 +306,19 @@ BytecodeCompiler::deoptimizeArgumentsInE } JSScript* BytecodeCompiler::compileScript(HandleObject environment, SharedContext* sc) { if (!createSourceAndParser()) return nullptr; + TokenStream::Position startPosition(keepAtoms); + parser->tokenStream.tell(&startPosition); + if (!createScript()) return nullptr; Maybe<BytecodeEmitter> emitter; if (!emplaceEmitter(emitter, sc)) return nullptr; for (;;) { @@ -345,17 +343,17 @@ BytecodeCompiler::compileScript(HandleOb if (!NameFunctions(cx, pn)) return nullptr; parser->handler.freeTree(pn); break; } // Maybe we aborted a syntax parse. See if we can try again. - if (!handleParseFailure(directives)) + if (!handleParseFailure(directives, startPosition)) return nullptr; // Reset UsedNameTracker state before trying again. usedNames->reset(); } // We have just finished parsing the source. Inform the source so that we // can compute statistics (e.g. how much time our functions remain lazy). @@ -447,27 +445,30 @@ BytecodeCompiler::compileStandaloneFunct const Maybe<uint32_t>& parameterListEnd) { MOZ_ASSERT(fun); MOZ_ASSERT(fun->isTenured()); if (!createSourceAndParser(parameterListEnd)) return false; + TokenStream::Position startPosition(keepAtoms); + parser->tokenStream.tell(&startPosition); + // Speculatively parse using the default directives implied by the context. // If a directive is encountered (e.g., "use strict") that changes how the // function should have been parsed, we backup and reparse with the new set // of directives. ParseNode* fn; do { Directives newDirectives = directives; fn = parser->standaloneFunction(fun, enclosingScope, parameterListEnd, generatorKind, asyncKind, directives, &newDirectives); - if (!fn && !handleParseFailure(newDirectives)) + if (!fn && !handleParseFailure(newDirectives, startPosition)) return false; } while (!fn); if (fn->pn_funbox->function()->isInterpreted()) { MOZ_ASSERT(fun == fn->pn_funbox->function()); if (!createScript(fn->pn_funbox->toStringStart, fn->pn_funbox->toStringEnd)) return false;