Bug 1382329: Part 1 - Enable lazy source whenever compiling for the preloader. r?mccr8,nbp draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 19 Jul 2017 11:57:18 -0700
changeset 611520 25c094d7481e1935565ced1f1bdf31653775335b
parent 610380 9b44720d645bc7f4d9698ecdc0c7ffbf073b36e6
child 611521 be3b9390fed01785718ad7370fa41651368ff5c4
push id69255
push usermaglione.k@gmail.com
push dateWed, 19 Jul 2017 21:25:43 +0000
reviewersmccr8, nbp
bugs1382329, 1367896
milestone56.0a1
Bug 1382329: Part 1 - Enable lazy source whenever compiling for the preloader. r?mccr8,nbp In general, we always want to compile with lazy source whenever we intend to store code in the startup bytecode cache. Currently, we only do so when the main StartupCache is available (which is only in the parent process), even if we'll be storing code in the ScriptPreloader cache. The main side-effect of this is that scripts which are used in a content process do not use lazy source, but *do* use lazy parsing. And since we need to clone pre-loaded scripts into their target compartment before executing, we end up eagerly compiling those lazy functions on the main athreads soon as we execute the script, in order to clone them. And this causes two side-effects of its own: 1) It's terrible for startup performance. 2) It creates new scope chains which didn't exist when the clone began, and which are likely responsible for bug 1367896. MozReview-Commit-ID: 6lZLb68zitp
js/xpconnect/loader/ScriptPreloader.cpp
js/xpconnect/loader/ScriptPreloader.h
js/xpconnect/loader/mozJSComponentLoader.cpp
--- a/js/xpconnect/loader/ScriptPreloader.cpp
+++ b/js/xpconnect/loader/ScriptPreloader.cpp
@@ -691,17 +691,17 @@ ScriptPreloader::Run()
 }
 
 void
 ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
                             JS::HandleScript jsscript)
 {
     // Don't bother trying to cache any URLs with cache-busting query
     // parameters.
-    if (mStartupFinished || !mCacheInitialized || cachePath.FindChar('?') >= 0) {
+    if (!Active() || cachePath.FindChar('?') >= 0) {
         return;
     }
 
     // Don't bother caching files that belong to the mochitest harness.
     NS_NAMED_LITERAL_CSTRING(mochikitPrefix, "chrome://mochikit/");
     if (StringHead(url, mochikitPrefix.Length()) == mochikitPrefix) {
         return;
     }
@@ -935,17 +935,18 @@ ScriptPreloader::DecodeNextBatch(size_t 
         return;
     }
 
     AutoJSAPI jsapi;
     MOZ_RELEASE_ASSERT(jsapi.Init(xpc::CompilationScope()));
     JSContext* cx = jsapi.cx();
 
     JS::CompileOptions options(cx, JSVERSION_LATEST);
-    options.setNoScriptRval(true);
+    options.setNoScriptRval(true)
+           .setSourceIsLazy(true);
 
     if (!JS::CanCompileOffThread(cx, options, size) ||
         !JS::DecodeMultiOffThreadScripts(cx, options, mParsingSources,
                                          OffThreadDecodeCallback,
                                          static_cast<void*>(this))) {
         // If we fail here, we don't move on to process the next batch, so make
         // sure we don't have any other scripts left to process.
         MOZ_ASSERT(mPendingScripts.isEmpty());
--- a/js/xpconnect/loader/ScriptPreloader.h
+++ b/js/xpconnect/loader/ScriptPreloader.h
@@ -86,16 +86,21 @@ public:
                     ProcessType processType, nsTArray<uint8_t>&& xdrData,
                     TimeStamp loadTime);
 
     // Initializes the script cache from the startup script cache file.
     Result<Ok, nsresult> InitCache(const nsAString& = NS_LITERAL_STRING("scriptCache"));
 
     Result<Ok, nsresult> InitCache(const Maybe<ipc::FileDescriptor>& cacheFile, ScriptCacheChild* cacheChild);
 
+    bool Active()
+    {
+      return mCacheInitialized && !mStartupFinished;
+    }
+
 private:
     Result<Ok, nsresult> InitCacheInternal();
 
 public:
     void Trace(JSTracer* trc);
 
     static ProcessType CurrentProcessType()
     {
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -642,17 +642,17 @@ mozJSComponentLoader::ObjectForLocation(
         // XDR encoded modules in omni.ja). Also, XDR decoding is relatively
         // fast. When we're not using the startup cache, we want to use non-lazy
         // source code so that we can use lazy parsing.
         // See bug 1303754.
         CompileOptions options(cx);
         options.setNoScriptRval(true)
                .setVersion(JSVERSION_LATEST)
                .setFileAndLine(nativePath.get(), 1)
-               .setSourceIsLazy(!!cache);
+               .setSourceIsLazy(cache || ScriptPreloader::GetSingleton().Active());
 
         if (realFile) {
             AutoMemMap map;
             MOZ_TRY(map.init(aComponentFile));
 
             // Note: exceptions will get handled further down;
             // don't early return for them here.
             auto buf = map.get<char>();