Bug 1498320 - Create a BytecodeCompiler subclass to perform global script compilation. r=tcampbell
authorJeff Walden <jwalden@mit.edu>
Thu, 01 Nov 2018 17:34:54 -0700
changeset 446424 43b8810bb3eda6bc628dddda9209153c57de653b
parent 446423 c489ba287b497b77e6bb7d4b7550e0792670726c
child 446425 76feab5328edddcedcacf16353b3fd8c05b2eedf
push id109874
push userjwalden@mit.edu
push dateWed, 14 Nov 2018 23:38:56 +0000
treeherdermozilla-inbound@5b0d24759be6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1498320
milestone65.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
Bug 1498320 - Create a BytecodeCompiler subclass to perform global script compilation. r=tcampbell
js/src/frontend/BytecodeCompiler.cpp
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -70,17 +70,16 @@ class MOZ_STACK_CLASS BytecodeCompiler
         return sourceObject.get();
     }
 
     // Call this before calling compile{Global,Eval}Script.
     MOZ_MUST_USE bool prepareScriptParse() {
         return createSourceAndParser(ParseGoal::Script) && createCompleteScript();
     }
 
-    JSScript* compileGlobalScript(ScopeKind scopeKind);
     JSScript* compileEvalScript(HandleObject environment, HandleScope enclosingScope);
 
     // Call this before calling compileModule.
     MOZ_MUST_USE bool prepareModuleParse() {
         return createSourceAndParser(ParseGoal::Module) && createCompleteScript();
     }
 
     ModuleObject* compileModule(HandleScope enclosingScope);
@@ -93,30 +92,32 @@ class MOZ_STACK_CLASS BytecodeCompiler
     // Call this before calling compileStandaloneFunction.
     CodeNode* parseStandaloneFunction(MutableHandleFunction fun, GeneratorKind generatorKind,
                                       FunctionAsyncKind asyncKind,
                                       const Maybe<uint32_t>& parameterListEnd,
                                       HandleScope enclosingScope);
 
     bool compileStandaloneFunction(CodeNode* parsedFunction, MutableHandleFunction fun);
 
+  protected:
+    JSScript* compileScript(HandleObject environment, SharedContext* sc);
+
   private:
     void assertSourceAndParserCreated() const {
         MOZ_ASSERT(sourceObject != nullptr);
         MOZ_ASSERT(scriptSource != nullptr);
         MOZ_ASSERT(usedNames.isSome());
         MOZ_ASSERT(parser.isSome());
     }
 
     void assertSourceParserAndScriptCreated() const {
         assertSourceAndParserCreated();
         MOZ_ASSERT(script != nullptr);
     }
 
-    JSScript* compileScript(HandleObject environment, SharedContext* sc);
     bool createScriptSource(const Maybe<uint32_t>& parameterListEnd);
     bool canLazilyParse();
     bool createParser(ParseGoal goal);
     bool createSourceAndParser(ParseGoal goal,
                                const Maybe<uint32_t>& parameterListEnd = Nothing());
 
     // This assumes the created script's offsets in the source used to parse it
     // are the same as are used to compute its Function.prototype.toString()
@@ -129,16 +130,38 @@ class MOZ_STACK_CLASS BytecodeCompiler
 
     using TokenStreamPosition = frontend::TokenStreamPosition<char16_t>;
 
     bool emplaceEmitter(Maybe<BytecodeEmitter>& emitter, SharedContext* sharedContext);
     bool handleParseFailure(const Directives& newDirectives, TokenStreamPosition& startPosition);
     bool deoptimizeArgumentsInEnclosingScripts(JSContext* cx, HandleObject environment);
 };
 
+class MOZ_STACK_CLASS GlobalScriptBytecodeCompiler final
+  : public BytecodeCompiler
+{
+    GlobalSharedContext globalsc_;
+
+  public:
+    GlobalScriptBytecodeCompiler(JSContext* cx, const ReadOnlyCompileOptions& options,
+                                 SourceBufferHolder& sourceBuffer, ScopeKind scopeKind)
+      : BytecodeCompiler(cx, options, sourceBuffer),
+        globalsc_(cx, scopeKind, directives, options.extraWarningsOption)
+    {
+        MOZ_ASSERT(scopeKind == ScopeKind::Global || scopeKind == ScopeKind::NonSyntactic);
+    }
+
+    JSScript* compile() {
+        if (!prepareScriptParse()) {
+            return nullptr;
+        }
+        return compileScript(nullptr, &globalsc_);
+    }
+};
+
 AutoFrontendTraceLog::AutoFrontendTraceLog(JSContext* cx, const TraceLoggerTextId id,
                                            const ErrorReporter& errorReporter)
 #ifdef JS_TRACE_LOGGING
   : logger_(TraceLoggerForCurrentThread(cx))
 {
     // If the tokenizer hasn't yet gotten any tokens, use the line and column
     // numbers from CompileOptions.
     uint32_t line, column;
@@ -396,28 +419,16 @@ BytecodeCompiler::compileScript(HandleOb
     }
 
     MOZ_ASSERT_IF(!cx->helperThread(), !cx->isExceptionPending());
 
     return script;
 }
 
 JSScript*
-BytecodeCompiler::compileGlobalScript(ScopeKind scopeKind)
-{
-    GlobalSharedContext globalsc(cx, scopeKind, directives, options.extraWarningsOption);
-
-    if (!prepareScriptParse()) {
-        return nullptr;
-    }
-
-    return compileScript(nullptr, &globalsc);
-}
-
-JSScript*
 BytecodeCompiler::compileEvalScript(HandleObject environment, HandleScope enclosingScope)
 {
     EvalSharedContext evalsc(cx, environment, enclosingScope,
                              directives, options.extraWarningsOption);
 
     if (!prepareScriptParse()) {
         return nullptr;
     }
@@ -646,23 +657,27 @@ class MOZ_RAII AutoAssertReportedExcepti
 
 JSScript*
 frontend::CompileGlobalScript(JSContext* cx, ScopeKind scopeKind,
                               const ReadOnlyCompileOptions& options,
                               SourceBufferHolder& srcBuf,
                               ScriptSourceObject** sourceObjectOut)
 {
     MOZ_ASSERT(scopeKind == ScopeKind::Global || scopeKind == ScopeKind::NonSyntactic);
+
     AutoAssertReportedException assertException(cx);
-    BytecodeCompiler compiler(cx, options, srcBuf);
+
+    GlobalScriptBytecodeCompiler compiler(cx, options, srcBuf, scopeKind);
     AutoInitializeSourceObject autoSSO(compiler, sourceObjectOut);
-    JSScript* script = compiler.compileGlobalScript(scopeKind);
+
+    JSScript* script = compiler.compile();
     if (!script) {
         return nullptr;
     }
+
     assertException.reset();
     return script;
 }
 
 #if defined(JS_BUILD_BINAST)
 
 JSScript*
 frontend::CompileGlobalBinASTScript(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,