Backed out changeset ad243db647c7 (bug 1361900)

This commit is contained in:
Sebastian Hengst 2017-05-13 18:53:40 +02:00
parent 185936c593
commit e1ddae17f8
4 changed files with 30 additions and 118 deletions

View File

@ -1593,7 +1593,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
JS::Rooted<JSScript*> script(cx); JS::Rooted<JSScript*> script(cx);
if (XRE_IsParentProcess()) { if (XRE_IsParentProcess()) {
script = ScriptPreloader::GetChildSingleton().GetCachedScript(cx, url); script = ScriptPreloader::GetSingleton().GetCachedScript(cx, url);
} }
if (!script) { if (!script) {
@ -1658,7 +1658,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
// We don't cache data: scripts! // We don't cache data: scripts!
if (aShouldCache && !scheme.EqualsLiteral("data")) { if (aShouldCache && !scheme.EqualsLiteral("data")) {
if (XRE_IsParentProcess()) { if (XRE_IsParentProcess()) {
ScriptPreloader::GetChildSingleton().NoteScript(url, url, script); ScriptPreloader::GetSingleton().NoteScript(url, url, script);
} }
// Root the object also for caching. // Root the object also for caching.
auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope); auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);

View File

@ -81,54 +81,8 @@ ScriptPreloader::GetSingleton()
{ {
static RefPtr<ScriptPreloader> singleton; static RefPtr<ScriptPreloader> singleton;
if (!singleton) {
if (XRE_IsParentProcess()) {
singleton = new ScriptPreloader();
singleton->mChildCache = &GetChildSingleton();
Unused << singleton->InitCache();
} else {
singleton = &GetChildSingleton();
}
ClearOnShutdown(&singleton);
}
return *singleton;
}
// The child singleton is available in all processes, including the parent, and
// is used for scripts which are expected to be loaded into child processes
// (such as process and frame scripts), or scripts that have already been loaded
// into a child. The child caches are managed as follows:
//
// - Every startup, we open the cache file from the last session, move it to a
// new location, and begin pre-loading the scripts that are stored in it. There
// is a separate cache file for parent and content processes, but the parent
// process opens both the parent and content cache files.
//
// - Once startup is complete, we write a new cache file for the next session,
// containing only the scripts that were used during early startup, so we don't
// waste pre-loading scripts that may not be needed.
//
// - For content processes, opening and writing the cache file is handled in the
// parent process. The first content process of each type sends back the data
// for scripts that were loaded in early startup, and the parent merges them and
// writes them to a cache file.
//
// - Currently, content processes only benefit from the cache data written
// during the *previous* session. Ideally, new content processes should probably
// use the cache data written during this session if there was no previous cache
// file, but I'd rather do that as a follow-up.
ScriptPreloader&
ScriptPreloader::GetChildSingleton()
{
static RefPtr<ScriptPreloader> singleton;
if (!singleton) { if (!singleton) {
singleton = new ScriptPreloader(); singleton = new ScriptPreloader();
if (XRE_IsParentProcess()) {
Unused << singleton->InitCache(NS_LITERAL_STRING("scriptCache-child"));
}
ClearOnShutdown(&singleton); ClearOnShutdown(&singleton);
} }
@ -260,7 +214,7 @@ ScriptPreloader::FlushCache()
// of any cache file we've already written out this session, which will // of any cache file we've already written out this session, which will
// prevent us from falling back to the current session's cache file on the // prevent us from falling back to the current session's cache file on the
// next startup. // next startup.
if (mSaveComplete && mChildCache) { if (mSaveComplete) {
mSaveComplete = false; mSaveComplete = false;
Unused << NS_NewNamedThread("SaveScripts", Unused << NS_NewNamedThread("SaveScripts",
@ -277,8 +231,7 @@ ScriptPreloader::Observe(nsISupports* subject, const char* topic, const char16_t
mStartupFinished = true; mStartupFinished = true;
if (XRE_IsParentProcess()) {
if (XRE_IsParentProcess() && mChildCache) {
Unused << NS_NewNamedThread("SaveScripts", Unused << NS_NewNamedThread("SaveScripts",
getter_AddRefs(mSaveThread), this); getter_AddRefs(mSaveThread), this);
} }
@ -295,7 +248,7 @@ ScriptPreloader::Observe(nsISupports* subject, const char* topic, const char16_t
Result<nsCOMPtr<nsIFile>, nsresult> Result<nsCOMPtr<nsIFile>, nsresult>
ScriptPreloader::GetCacheFile(const nsAString& suffix) ScriptPreloader::GetCacheFile(const char* leafName)
{ {
nsCOMPtr<nsIFile> cacheFile; nsCOMPtr<nsIFile> cacheFile;
NS_TRY(mProfD->Clone(getter_AddRefs(cacheFile))); NS_TRY(mProfD->Clone(getter_AddRefs(cacheFile)));
@ -303,7 +256,7 @@ ScriptPreloader::GetCacheFile(const nsAString& suffix)
NS_TRY(cacheFile->AppendNative(NS_LITERAL_CSTRING("startupCache"))); NS_TRY(cacheFile->AppendNative(NS_LITERAL_CSTRING("startupCache")));
Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777); Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777);
NS_TRY(cacheFile->Append(mBaseName + suffix)); NS_TRY(cacheFile->AppendNative(nsDependentCString(leafName)));
return Move(cacheFile); return Move(cacheFile);
} }
@ -316,14 +269,14 @@ ScriptPreloader::OpenCache()
NS_TRY(NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(mProfD))); NS_TRY(NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(mProfD)));
nsCOMPtr<nsIFile> cacheFile; nsCOMPtr<nsIFile> cacheFile;
MOZ_TRY_VAR(cacheFile, GetCacheFile(NS_LITERAL_STRING(".bin"))); MOZ_TRY_VAR(cacheFile, GetCacheFile("scriptCache.bin"));
bool exists; bool exists;
NS_TRY(cacheFile->Exists(&exists)); NS_TRY(cacheFile->Exists(&exists));
if (exists) { if (exists) {
NS_TRY(cacheFile->MoveTo(nullptr, mBaseName + NS_LITERAL_STRING("-current.bin"))); NS_TRY(cacheFile->MoveTo(nullptr, NS_LITERAL_STRING("scriptCache-current.bin")));
} else { } else {
NS_TRY(cacheFile->SetLeafName(mBaseName + NS_LITERAL_STRING("-current.bin"))); NS_TRY(cacheFile->SetLeafName(NS_LITERAL_STRING("scriptCache-current.bin")));
NS_TRY(cacheFile->Exists(&exists)); NS_TRY(cacheFile->Exists(&exists));
if (!exists) { if (!exists) {
return Err(NS_ERROR_FILE_NOT_FOUND); return Err(NS_ERROR_FILE_NOT_FOUND);
@ -338,10 +291,9 @@ ScriptPreloader::OpenCache()
// Opens the script cache file for this session, and initializes the script // Opens the script cache file for this session, and initializes the script
// cache based on its contents. See WriteCache for details of the cache file. // cache based on its contents. See WriteCache for details of the cache file.
Result<Ok, nsresult> Result<Ok, nsresult>
ScriptPreloader::InitCache(const nsAString& basePath) ScriptPreloader::InitCache()
{ {
mCacheInitialized = true; mCacheInitialized = true;
mBaseName = basePath;
RegisterWeakMemoryReporter(this); RegisterWeakMemoryReporter(this);
@ -383,7 +335,7 @@ ScriptPreloader::InitCache(const nsAString& basePath)
size_t offset = 0; size_t offset = 0;
while (!buf.finished()) { while (!buf.finished()) {
auto script = MakeUnique<CachedScript>(*this, buf); auto script = MakeUnique<CachedScript>(buf);
auto scriptData = data + script->mOffset; auto scriptData = data + script->mOffset;
if (scriptData + script->mSize > end) { if (scriptData + script->mSize > end) {
@ -421,7 +373,6 @@ ScriptPreloader::InitCache(const nsAString& basePath)
JS::CompileOptions options(cx, JSVERSION_LATEST); JS::CompileOptions options(cx, JSVERSION_LATEST);
for (auto script : mRestoredScripts) { for (auto script : mRestoredScripts) {
// Only async decode scripts which have been used in this process type.
if (script->mProcessTypes.contains(CurrentProcessType()) && if (script->mProcessTypes.contains(CurrentProcessType()) &&
script->mSize > MIN_OFFTHREAD_SIZE && script->mSize > MIN_OFFTHREAD_SIZE &&
JS::CanCompileOffThread(cx, options, script->mSize)) { JS::CanCompileOffThread(cx, options, script->mSize)) {
@ -451,12 +402,6 @@ ScriptPreloader::PrepareCacheWrite()
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
auto cleanup = MakeScopeExit([&] () {
if (mChildCache) {
mChildCache->PrepareCacheWrite();
}
});
if (mDataPrepared) { if (mDataPrepared) {
return; return;
} }
@ -486,20 +431,7 @@ ScriptPreloader::PrepareCacheWrite()
CachedScript* script = next; CachedScript* script = next;
next = script->getNext(); next = script->getNext();
// Don't write any scripts that are also in the child cache. They'll be if (!script->mSize && !script->XDREncode(jsapi.cx())) {
// 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 (FindScript(mChildCache->mSavedScripts, script->mCachePath)) {
childScript->UpdateLoadTime(script->mLoadTime);
childScript->mProcessTypes += script->mProcessTypes;
} else {
childScript = nullptr;
}
}
if (childScript || (!script->mSize && !script->XDREncode(jsapi.cx()))) {
script->remove(); script->remove();
delete script; delete script;
} else { } else {
@ -555,7 +487,7 @@ ScriptPreloader::WriteCache()
} }
nsCOMPtr<nsIFile> cacheFile; nsCOMPtr<nsIFile> cacheFile;
MOZ_TRY_VAR(cacheFile, GetCacheFile(NS_LITERAL_STRING("-new.bin"))); MOZ_TRY_VAR(cacheFile, GetCacheFile("scriptCache-new.bin"));
bool exists; bool exists;
NS_TRY(cacheFile->Exists(&exists)); NS_TRY(cacheFile->Exists(&exists));
@ -587,7 +519,7 @@ ScriptPreloader::WriteCache()
script->mXDRData.reset(); script->mXDRData.reset();
} }
NS_TRY(cacheFile->MoveTo(nullptr, mBaseName + NS_LITERAL_STRING(".bin"))); NS_TRY(cacheFile->MoveTo(nullptr, NS_LITERAL_STRING("scriptCache.bin")));
return Ok(); return Ok();
} }
@ -603,11 +535,7 @@ ScriptPreloader::Run()
// during early startup. // during early startup.
mal.Wait(10000); mal.Wait(10000);
auto result = WriteCache(); Unused << WriteCache();
Unused << NS_WARN_IF(result.isErr());
result = mChildCache->WriteCache();
Unused << NS_WARN_IF(result.isErr());
mSaveComplete = true; mSaveComplete = true;
NS_ReleaseOnMainThread(mSaveThread.forget()); NS_ReleaseOnMainThread(mSaveThread.forget());
@ -662,7 +590,7 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
restored->mScript = script; restored->mScript = script;
restored->mReadyToExecute = true; restored->mReadyToExecute = true;
} else if (!exists) { } else if (!exists) {
auto cachedScript = new CachedScript(*this, url, cachePath, script); auto cachedScript = new CachedScript(url, cachePath, script);
cachedScript->mProcesses += CurrentProcessType(); cachedScript->mProcesses += CurrentProcessType();
mSavedScripts.insertBack(cachedScript); mSavedScripts.insertBack(cachedScript);
@ -673,15 +601,6 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
JSScript* JSScript*
ScriptPreloader::GetCachedScript(JSContext* cx, const nsCString& path) ScriptPreloader::GetCachedScript(JSContext* cx, const nsCString& path)
{ {
// If a script is used by both the parent and the child, it's stored only
// in the child cache.
if (mChildCache) {
auto script = mChildCache->GetCachedScript(cx, path);
if (script) {
return script;
}
}
auto script = mScripts.Get(path); auto script = mScripts.Get(path);
if (script) { if (script) {
return WaitForCachedScript(cx, script); return WaitForCachedScript(cx, script);
@ -743,7 +662,7 @@ ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
{ {
auto script = static_cast<CachedScript*>(context); auto script = static_cast<CachedScript*>(context);
MonitorAutoLock mal(script->mCache.mMonitor); MonitorAutoLock mal(GetSingleton().mMonitor);
if (script->mReadyToExecute) { if (script->mReadyToExecute) {
// We've already executed this script on the main thread, and opted to // We've already executed this script on the main thread, and opted to
@ -751,7 +670,7 @@ ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
// finish. So just cancel the off-thread parse rather than completing // finish. So just cancel the off-thread parse rather than completing
// it. // it.
NS_DispatchToMainThread( NS_DispatchToMainThread(
NewRunnableMethod<void*>(&script->mCache, NewRunnableMethod<void*>(&GetSingleton(),
&ScriptPreloader::CancelOffThreadParse, &ScriptPreloader::CancelOffThreadParse,
token)); token));
return; return;
@ -763,8 +682,8 @@ ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
mal.NotifyAll(); mal.NotifyAll();
} }
ScriptPreloader::CachedScript::CachedScript(ScriptPreloader& cache, InputBuffer& buf) inline
: mCache(cache) ScriptPreloader::CachedScript::CachedScript(InputBuffer& buf)
{ {
Code(buf); Code(buf);
} }
@ -790,7 +709,7 @@ void
ScriptPreloader::CachedScript::Cancel() ScriptPreloader::CachedScript::Cancel()
{ {
if (mToken) { if (mToken) {
mCache.mMonitor.AssertCurrentThreadOwns(); GetSingleton().mMonitor.AssertCurrentThreadOwns();
AutoSafeJSAPI jsapi; AutoSafeJSAPI jsapi;
JS::CancelOffThreadScriptDecoder(jsapi.cx(), mToken); JS::CancelOffThreadScriptDecoder(jsapi.cx(), mToken);

View File

@ -52,7 +52,6 @@ public:
NS_DECL_NSIRUNNABLE NS_DECL_NSIRUNNABLE
static ScriptPreloader& GetSingleton(); static ScriptPreloader& GetSingleton();
static ScriptPreloader& GetChildSingleton();
static ProcessType GetChildProcessType(const nsAString& remoteType); static ProcessType GetChildProcessType(const nsAString& remoteType);
@ -66,7 +65,7 @@ public:
void NoteScript(const nsCString& url, const nsCString& cachePath, JS::HandleScript script); void NoteScript(const nsCString& url, const nsCString& cachePath, JS::HandleScript script);
// Initializes the script cache from the startup script cache file. // Initializes the script cache from the startup script cache file.
Result<Ok, nsresult> InitCache(const nsAString& = NS_LITERAL_STRING("scriptCache")); Result<Ok, nsresult> InitCache();
void Trace(JSTracer* trc); void Trace(JSTracer* trc);
@ -108,23 +107,23 @@ private:
public: public:
CachedScript(CachedScript&&) = default; CachedScript(CachedScript&&) = default;
CachedScript(ScriptPreloader& cache, const nsCString& url, const nsCString& cachePath, JSScript* script) CachedScript(const nsCString& url, const nsCString& cachePath, JSScript* script)
: mCache(cache) : mURL(url)
, mURL(url)
, mCachePath(cachePath) , mCachePath(cachePath)
, mScript(script) , mScript(script)
, mReadyToExecute(true) , mReadyToExecute(true)
{} {}
inline CachedScript(ScriptPreloader& cache, InputBuffer& buf); explicit inline CachedScript(InputBuffer& buf);
~CachedScript() ~CachedScript()
{ {
auto& cache = GetSingleton();
#ifdef DEBUG #ifdef DEBUG
auto hashValue = mCache->mScripts.Get(mCachePath); auto hashValue = cache.mScripts.Get(mCachePath);
MOZ_ASSERT_IF(hashValue, hashValue == this); MOZ_ASSERT_IF(hashValue, hashValue == this);
#endif #endif
mCache->mScripts.Remove(mCachePath); cache.mScripts.Remove(mCachePath);
} }
void Cancel(); void Cancel();
@ -173,8 +172,6 @@ private:
return size; return size;
} }
ScriptPreloader& mCache;
// The URL from which this script was initially read and compiled. // The URL from which this script was initially read and compiled.
nsCString mURL; nsCString mURL;
// A unique identifier for this script's filesystem location, used as a // A unique identifier for this script's filesystem location, used as a
@ -250,7 +247,7 @@ private:
// Returns a file pointer for the cache file with the given name in the // Returns a file pointer for the cache file with the given name in the
// current profile. // current profile.
Result<nsCOMPtr<nsIFile>, nsresult> Result<nsCOMPtr<nsIFile>, nsresult>
GetCacheFile(const nsAString& suffix); GetCacheFile(const char* leafName);
static CachedScript* FindScript(LinkedList<CachedScript>& scripts, const nsCString& cachePath); static CachedScript* FindScript(LinkedList<CachedScript>& scripts, const nsCString& cachePath);
@ -302,10 +299,6 @@ private:
// The process type of the current process. // The process type of the current process.
static ProcessType sProcessType; static ProcessType sProcessType;
RefPtr<ScriptPreloader> mChildCache;
nsString mBaseName;
nsCOMPtr<nsIFile> mProfD; nsCOMPtr<nsIFile> mProfD;
nsCOMPtr<nsIThread> mSaveThread; nsCOMPtr<nsIThread> mSaveThread;

View File

@ -710,7 +710,7 @@ NS_InitXPCOM2(nsIServiceManager** aResult,
nsCOMPtr<nsISupports> componentLoader = nsCOMPtr<nsISupports> componentLoader =
do_GetService("@mozilla.org/moz/jsloader;1"); do_GetService("@mozilla.org/moz/jsloader;1");
mozilla::ScriptPreloader::GetSingleton(); Unused << mozilla::ScriptPreloader::GetSingleton().InitCache();
mozilla::scache::StartupCache::GetSingleton(); mozilla::scache::StartupCache::GetSingleton();
mozilla::AvailableMemoryTracker::Activate(); mozilla::AvailableMemoryTracker::Activate();