Bug 1382329: Part 2 - Eagerly encode scripts for the startup cache. r?erahm,nbp draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 19 Jul 2017 12:44:17 -0700
changeset 611521 be3b9390fed01785718ad7370fa41651368ff5c4
parent 611520 25c094d7481e1935565ced1f1bdf31653775335b
child 611522 800aad98f57bacb85f412e074e0ca35fe2d2dfa7
child 611645 89491b1bda252e5bbf9e0390a6aa10fb473c26d5
push id69255
push usermaglione.k@gmail.com
push dateWed, 19 Jul 2017 21:25:43 +0000
reviewerserahm, nbp
bugs1382329
milestone56.0a1
Bug 1382329: Part 2 - Eagerly encode scripts for the startup cache. r?erahm,nbp MozReview-Commit-ID: JqCqQZ2rO2z
js/xpconnect/loader/ScriptPreloader.cpp
--- a/js/xpconnect/loader/ScriptPreloader.cpp
+++ b/js/xpconnect/loader/ScriptPreloader.cpp
@@ -543,18 +543,16 @@ ScriptPreloader::PrepareCacheWriteIntern
 
         if (!(script->mProcessTypes == script->mOriginalProcessTypes)) {
             // Note: EnumSet doesn't support operator!=, hence the weird form above.
             found = true;
         }
 
         if (!script->mSize && !script->XDREncode(jsapi.cx())) {
             script.Remove();
-        } else {
-            script->mSize = script->Range().length();
         }
     }
 
     if (!found) {
         mSaveComplete = true;
         return;
     }
 
@@ -709,16 +707,28 @@ ScriptPreloader::NoteScript(const nsCStr
     auto script = mScripts.LookupOrAdd(cachePath, *this, url, cachePath, jsscript);
 
     if (!script->mScript) {
         MOZ_ASSERT(jsscript);
         script->mScript = jsscript;
         script->mReadyToExecute = true;
     }
 
+    // If we don't already have bytecode for this script, and it doesn't already
+    // exist in the child cache, encode it now, before it's ever executed.
+    //
+    // Ideally, we would like to do the encoding lazily, during idle slices.
+    // There are subtle issues with encoding scripts which have already been
+    // executed, though, which makes that somewhat risky. So until that
+    // situation is improved, and thoroughly tested, we need to encode eagerly.
+    if (!script->mSize && !(mChildCache && mChildCache->mScripts.Get(cachePath))) {
+        AutoSafeJSAPI jsapi;
+        Unused << script->XDREncode(jsapi.cx());
+    }
+
     script->UpdateLoadTime(TimeStamp::Now());
     script->mProcessTypes += CurrentProcessType();
 }
 
 void
 ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
                             ProcessType processType, nsTArray<uint8_t>&& xdrData,
                             TimeStamp loadTime)
@@ -986,18 +996,20 @@ ScriptPreloader::CachedScript::XDREncode
     JSAutoCompartment ac(cx, mScript);
     JS::RootedScript jsscript(cx, mScript);
 
     mXDRData.construct<JS::TranscodeBuffer>();
 
     JS::TranscodeResult code = JS::EncodeScript(cx, Buffer(), jsscript);
     if (code == JS::TranscodeResult_Ok) {
         mXDRRange.emplace(Buffer().begin(), Buffer().length());
+        mSize = Range().length();
         return true;
     }
+    mXDRData.destroy();
     JS_ClearPendingException(cx);
     return false;
 }
 
 JSScript*
 ScriptPreloader::CachedScript::GetJSScript(JSContext* cx)
 {
     MOZ_ASSERT(mReadyToExecute);