Bug 1691749 - Simplify self-hosting stencil initialization. r=nbp
authorTed Campbell <tcampbell@mozilla.com>
Wed, 10 Feb 2021 17:59:32 +0000
changeset 566864 eb2907b5ef3e545fa9c53893347eeffc476688c9
parent 566863 5dbd804e3a4d47880dde12713198b4cc4681adae
child 566865 63167d041bb4f68e77e46ed6e941003e131ecc8e
push id38191
push userbtara@mozilla.com
push dateThu, 11 Feb 2021 05:02:45 +0000
treeherdermozilla-central@5cbcb80f72bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1691749
milestone87.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 1691749 - Simplify self-hosting stencil initialization. r=nbp Now that `CompilationStencilSet` is gone, it is possible to use a single instantiation call for both parse and xdr-decode of self-hosting. Also use a UniquePtr here since in the future this will be shared on the runtime. Differential Revision: https://phabricator.services.mozilla.com/D104542
js/src/vm/Runtime.h
js/src/vm/SelfHosting.cpp
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -638,21 +638,16 @@ struct JSRuntime {
 
   // Callback to copy the XDR content of the self-hosted code.
   using TranscodeBufferWriter = bool (*)(JSContext* cx,
                                          const JS::TranscodeBuffer&);
   TranscodeBufferWriter selfHostedXDRWriter = nullptr;
 
   static js::GlobalObject* createSelfHostingGlobal(JSContext* cx);
 
-  // Used internally to initialize the self-hosted global using XDR content.
-  bool initSelfHostingFromXDR(JSContext* cx, const JS::CompileOptions& options,
-                              js::frontend::CompilationStencil& stencil,
-                              js::MutableHandle<JSScript*> scriptOut);
-
  public:
   void getUnclonedSelfHostedValue(js::PropertyName* name, JS::Value* vp);
   JSFunction* getUnclonedSelfHostedFunction(js::PropertyName* name);
 
   MOZ_MUST_USE bool createJitRuntime(JSContext* cx);
   js::jit::JitRuntime* jitRuntime() const { return jitRuntime_.ref(); }
   bool hasJitRuntime() const { return !!jitRuntime_; }
 
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2766,47 +2766,16 @@ static bool VerifyGlobalNames(JSContext*
   if (nameMissing) {
     return Throw(cx, id, JSMSG_NO_SUCH_SELF_HOSTED_PROP);
   }
 #endif  // DEBUG
 
   return true;
 }
 
-bool JSRuntime::initSelfHostingFromXDR(JSContext* cx,
-                                       const CompileOptions& options,
-                                       frontend::CompilationStencil& stencil,
-                                       MutableHandle<JSScript*> scriptOut) {
-  MOZ_ASSERT(selfHostingGlobal_);
-  MOZ_ASSERT(selfHostedXDR.length() > 0);
-  scriptOut.set(nullptr);
-
-  // Deserialize the stencil from XDR.
-  JS::TranscodeRange xdrRange(selfHostedXDR);
-  bool decodeOk = false;
-  if (!stencil.deserializeStencils(cx, xdrRange, &decodeOk)) {
-    return false;
-  }
-  // If XDR decode failed, it's not a propagated error.
-  // Fall back to regular text parse.
-  if (!decodeOk) {
-    return true;
-  }
-
-  // Instantiate the stencil.
-  Rooted<frontend::CompilationGCOutput> output(cx);
-  if (!frontend::CompilationStencil::instantiateStencils(cx, stencil,
-                                                         output.get())) {
-    return false;
-  }
-
-  scriptOut.set(output.get().script);
-  return true;
-}
-
 bool JSRuntime::initSelfHosting(JSContext* cx) {
   MOZ_ASSERT(!selfHostingGlobal_);
 
   if (cx->runtime()->parentRuntime) {
     selfHostingGlobal_ = cx->runtime()->parentRuntime->selfHostingGlobal_;
     return true;
   }
 
@@ -2826,41 +2795,37 @@ bool JSRuntime::initSelfHosting(JSContex
    * stderr. See selfHosting_WarningReporter.
    */
   AutoSelfHostingErrorReporter errorReporter(cx);
 
   // Variables used to instantiate scripts.
   CompileOptions options(cx);
   FillSelfHostingCompileOptions(options);
 
-  RootedScript script(cx);
+  Rooted<UniquePtr<frontend::CompilationStencil>> stencil(
+      cx, MakeUnique<frontend::CompilationStencil>(cx, options));
+  if (!stencil.get()) {
+    return false;
+  }
+
+  if (!stencil->input.initForSelfHostingGlobal(cx)) {
+    return false;
+  }
 
   // Try initializing from Stencil XDR.
+  bool decodeOk = false;
   if (selfHostedXDR.length() > 0) {
-    // Initialize the compilation info that houses the stencil.
-    Rooted<frontend::CompilationStencil> stencil(
-        cx, frontend::CompilationStencil(cx, options));
-    if (!stencil.get().input.initForSelfHostingGlobal(cx)) {
-      return false;
-    }
-
-    if (!initSelfHostingFromXDR(cx, options, stencil.get(), &script)) {
+    if (!stencil->deserializeStencils(cx, selfHostedXDR, &decodeOk)) {
       return false;
     }
   }
 
   // If script wasn't generated, it means XDR was either not provided or that it
   // failed the decoding phase. Parse from text as before.
-  if (!script) {
-    Rooted<frontend::CompilationStencil> stencil(
-        cx, frontend::CompilationStencil(cx, options));
-    if (!stencil.get().input.initForSelfHostingGlobal(cx)) {
-      return false;
-    }
-
+  if (!decodeOk) {
     uint32_t srcLen = GetRawScriptsSize();
     const unsigned char* compressed = compressedSources;
     uint32_t compressedLen = GetCompressedSize();
     auto src = cx->make_pod_array<char>(srcLen);
     if (!src) {
       return false;
     }
     if (!DecompressString(compressed, compressedLen,
@@ -2869,57 +2834,58 @@ bool JSRuntime::initSelfHosting(JSContex
       return false;
     }
 
     JS::SourceText<mozilla::Utf8Unit> srcBuf;
     if (!srcBuf.init(cx, std::move(src), srcLen)) {
       return false;
     }
 
-    if (!frontend::CompileGlobalScriptToStencil(cx, stencil.get(), srcBuf,
+    if (!frontend::CompileGlobalScriptToStencil(cx, *stencil, srcBuf,
                                                 ScopeKind::Global)) {
       return false;
     }
 
     // Serialize the stencil to XDR.
     if (selfHostedXDRWriter) {
       JS::TranscodeBuffer xdrBuffer;
-      if (!stencil.get().serializeStencils(cx, xdrBuffer)) {
+      if (!stencil->serializeStencils(cx, xdrBuffer)) {
         return false;
       }
 
       if (!selfHostedXDRWriter(cx, xdrBuffer)) {
         return false;
       }
     }
-
-    // Instantiate the stencil.
+  }
+
+  // Instantiate the stencil and run the script.
+  // NOTE: Use a block here so the GC roots are dropped before freezing the Zone
+  //       below.
+  {
     Rooted<frontend::CompilationGCOutput> output(cx);
-    if (!frontend::CompilationStencil::instantiateStencils(cx, stencil.get(),
+    if (!frontend::CompilationStencil::instantiateStencils(cx, *stencil,
                                                            output.get())) {
       return false;
     }
 
-    script.set(output.get().script);
-  }
-
-  MOZ_ASSERT(script);
-  RootedValue rval(cx);
-  if (!JS_ExecuteScript(cx, script, &rval)) {
-    return false;
+    // Run the script
+    RootedScript script(cx, output.get().script);
+    RootedValue rval(cx);
+    if (!JS_ExecuteScript(cx, script, &rval)) {
+      return false;
+    }
   }
 
   if (!VerifyGlobalNames(cx, shg)) {
     return false;
   }
 
   // Garbage collect the self hosting zone once when it is created. It should
-  // not be modified after this point. Drop top-level script reference before we
-  // do this collection.
-  script.set(nullptr);
+  // not be modified after this point.
   cx->runtime()->gc.freezeSelfHostingZone();
 
   return true;
 }
 
 void JSRuntime::finishSelfHosting() { selfHostingGlobal_ = nullptr; }
 
 void JSRuntime::traceSelfHostingGlobal(JSTracer* trc) {