Bug 1364974: Part 4 - Replace CachedScript::mStatus and related logic with original and final process sets. r=erahm

The current logic is fairly hard to follow, and fails to account for changes
in the set of processes a script needs to be executed in when deciding whether
to write a new cache file. These changes simplify that logic considerably,
increase the chances that we'll correctly pre-decode a script that's needed in
a given process during startup.

MozReview-Commit-ID: BvqjKU8FDHW
This commit is contained in:
Kris Maglione
2017-05-22 23:01:39 -07:00
parent be4d29f747
commit db12e89b0a
2 changed files with 40 additions and 39 deletions

View File

@@ -530,39 +530,37 @@ ScriptPreloader::PrepareCacheWrite()
return;
}
bool found = Find(IterHash(mScripts), [] (CachedScript* script) {
return (script->mStatus == ScriptStatus::Restored ||
!script->HasRange() || script->HasArray());
});
if (!found) {
mSaveComplete = true;
return;
}
AutoSafeJSAPI jsapi;
bool found = false;
for (auto& script : IterHash(mScripts, Match<ScriptStatus::Saved>())) {
// Don't write any scripts that are also in the child cache. They'll be
// loaded from the child cache in that case, so there's no need to write
// them twice.
CachedScript* childScript = mChildCache ? mChildCache->mScripts.Get(script->mCachePath) : nullptr;
if (childScript) {
if (childScript->mStatus == ScriptStatus::Saved) {
childScript->UpdateLoadTime(script->mLoadTime);
childScript->mProcessTypes += script->mProcessTypes;
} else {
childScript = nullptr;
}
if (childScript && !childScript->mProcessTypes.isEmpty()) {
childScript->UpdateLoadTime(script->mLoadTime);
childScript->mProcessTypes += script->mProcessTypes;
script.Remove();
continue;
}
if (childScript || (!script->mSize && !script->XDREncode(jsapi.cx()))) {
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;
}
mDataPrepared = true;
}
@@ -693,9 +691,7 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
auto script = mScripts.LookupOrAdd(cachePath, *this, url, cachePath, jsscript);
if (script->mStatus == ScriptStatus::Restored) {
script->mStatus = ScriptStatus::Saved;
if (!script->mScript) {
MOZ_ASSERT(jsscript);
script->mScript = jsscript;
script->mReadyToExecute = true;
@@ -712,20 +708,14 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
{
auto script = mScripts.LookupOrAdd(cachePath, *this, url, cachePath, nullptr);
if (script->mStatus == ScriptStatus::Restored) {
script->mStatus = ScriptStatus::Saved;
if (!script->HasRange()) {
MOZ_ASSERT(!script->HasArray());
script->mReadyToExecute = true;
} else {
if (!script->HasRange()) {
MOZ_ASSERT(!script->HasArray());
script->mSize = xdrData.Length();
script->mXDRData.construct<nsTArray<uint8_t>>(Forward<nsTArray<uint8_t>>(xdrData));
script->mSize = xdrData.Length();
script->mXDRData.construct<nsTArray<uint8_t>>(Forward<nsTArray<uint8_t>>(xdrData));
auto& data = script->Array();
script->mXDRRange.emplace(data.Elements(), data.Length());
}
auto& data = script->Array();
script->mXDRRange.emplace(data.Elements(), data.Length());
}
if (!script->mSize && !script->mScript) {
@@ -842,9 +832,14 @@ ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
ScriptPreloader::CachedScript::CachedScript(ScriptPreloader& cache, InputBuffer& buf)
: mCache(cache)
, mStatus(ScriptStatus::Restored)
{
Code(buf);
// Swap the mProcessTypes and mOriginalProcessTypes values, since we want to
// start with an empty set of processes loaded into for this session, and
// compare against last session's values later.
mOriginalProcessTypes = mProcessTypes;
mProcessTypes = {};
}
bool