Bug 1382329: Part 2 - Eagerly encode scripts for the startup cache. r?erahm,nbp
MozReview-Commit-ID: JqCqQZ2rO2z
--- 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);