mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
Backed out changeset ad243db647c7 (bug 1361900)
This commit is contained in:
parent
185936c593
commit
e1ddae17f8
@ -1593,7 +1593,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
|
||||
JS::Rooted<JSScript*> script(cx);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
script = ScriptPreloader::GetChildSingleton().GetCachedScript(cx, url);
|
||||
script = ScriptPreloader::GetSingleton().GetCachedScript(cx, url);
|
||||
}
|
||||
|
||||
if (!script) {
|
||||
@ -1658,7 +1658,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
|
||||
// We don't cache data: scripts!
|
||||
if (aShouldCache && !scheme.EqualsLiteral("data")) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
ScriptPreloader::GetChildSingleton().NoteScript(url, url, script);
|
||||
ScriptPreloader::GetSingleton().NoteScript(url, url, script);
|
||||
}
|
||||
// Root the object also for caching.
|
||||
auto* holder = new nsMessageManagerScriptHolder(cx, script, aRunInGlobalScope);
|
||||
|
@ -81,54 +81,8 @@ ScriptPreloader::GetSingleton()
|
||||
{
|
||||
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) {
|
||||
singleton = new ScriptPreloader();
|
||||
if (XRE_IsParentProcess()) {
|
||||
Unused << singleton->InitCache(NS_LITERAL_STRING("scriptCache-child"));
|
||||
}
|
||||
ClearOnShutdown(&singleton);
|
||||
}
|
||||
|
||||
@ -260,7 +214,7 @@ ScriptPreloader::FlushCache()
|
||||
// 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
|
||||
// next startup.
|
||||
if (mSaveComplete && mChildCache) {
|
||||
if (mSaveComplete) {
|
||||
mSaveComplete = false;
|
||||
|
||||
Unused << NS_NewNamedThread("SaveScripts",
|
||||
@ -277,8 +231,7 @@ ScriptPreloader::Observe(nsISupports* subject, const char* topic, const char16_t
|
||||
|
||||
mStartupFinished = true;
|
||||
|
||||
|
||||
if (XRE_IsParentProcess() && mChildCache) {
|
||||
if (XRE_IsParentProcess()) {
|
||||
Unused << NS_NewNamedThread("SaveScripts",
|
||||
getter_AddRefs(mSaveThread), this);
|
||||
}
|
||||
@ -295,7 +248,7 @@ ScriptPreloader::Observe(nsISupports* subject, const char* topic, const char16_t
|
||||
|
||||
|
||||
Result<nsCOMPtr<nsIFile>, nsresult>
|
||||
ScriptPreloader::GetCacheFile(const nsAString& suffix)
|
||||
ScriptPreloader::GetCacheFile(const char* leafName)
|
||||
{
|
||||
nsCOMPtr<nsIFile> 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")));
|
||||
Unused << cacheFile->Create(nsIFile::DIRECTORY_TYPE, 0777);
|
||||
|
||||
NS_TRY(cacheFile->Append(mBaseName + suffix));
|
||||
NS_TRY(cacheFile->AppendNative(nsDependentCString(leafName)));
|
||||
|
||||
return Move(cacheFile);
|
||||
}
|
||||
@ -316,14 +269,14 @@ ScriptPreloader::OpenCache()
|
||||
NS_TRY(NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(mProfD)));
|
||||
|
||||
nsCOMPtr<nsIFile> cacheFile;
|
||||
MOZ_TRY_VAR(cacheFile, GetCacheFile(NS_LITERAL_STRING(".bin")));
|
||||
MOZ_TRY_VAR(cacheFile, GetCacheFile("scriptCache.bin"));
|
||||
|
||||
bool exists;
|
||||
NS_TRY(cacheFile->Exists(&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 {
|
||||
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));
|
||||
if (!exists) {
|
||||
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
|
||||
// cache based on its contents. See WriteCache for details of the cache file.
|
||||
Result<Ok, nsresult>
|
||||
ScriptPreloader::InitCache(const nsAString& basePath)
|
||||
ScriptPreloader::InitCache()
|
||||
{
|
||||
mCacheInitialized = true;
|
||||
mBaseName = basePath;
|
||||
|
||||
RegisterWeakMemoryReporter(this);
|
||||
|
||||
@ -383,7 +335,7 @@ ScriptPreloader::InitCache(const nsAString& basePath)
|
||||
|
||||
size_t offset = 0;
|
||||
while (!buf.finished()) {
|
||||
auto script = MakeUnique<CachedScript>(*this, buf);
|
||||
auto script = MakeUnique<CachedScript>(buf);
|
||||
|
||||
auto scriptData = data + script->mOffset;
|
||||
if (scriptData + script->mSize > end) {
|
||||
@ -421,7 +373,6 @@ ScriptPreloader::InitCache(const nsAString& basePath)
|
||||
|
||||
JS::CompileOptions options(cx, JSVERSION_LATEST);
|
||||
for (auto script : mRestoredScripts) {
|
||||
// Only async decode scripts which have been used in this process type.
|
||||
if (script->mProcessTypes.contains(CurrentProcessType()) &&
|
||||
script->mSize > MIN_OFFTHREAD_SIZE &&
|
||||
JS::CanCompileOffThread(cx, options, script->mSize)) {
|
||||
@ -451,12 +402,6 @@ ScriptPreloader::PrepareCacheWrite()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
auto cleanup = MakeScopeExit([&] () {
|
||||
if (mChildCache) {
|
||||
mChildCache->PrepareCacheWrite();
|
||||
}
|
||||
});
|
||||
|
||||
if (mDataPrepared) {
|
||||
return;
|
||||
}
|
||||
@ -486,20 +431,7 @@ ScriptPreloader::PrepareCacheWrite()
|
||||
CachedScript* script = next;
|
||||
next = script->getNext();
|
||||
|
||||
// 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 (FindScript(mChildCache->mSavedScripts, script->mCachePath)) {
|
||||
childScript->UpdateLoadTime(script->mLoadTime);
|
||||
childScript->mProcessTypes += script->mProcessTypes;
|
||||
} else {
|
||||
childScript = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (childScript || (!script->mSize && !script->XDREncode(jsapi.cx()))) {
|
||||
if (!script->mSize && !script->XDREncode(jsapi.cx())) {
|
||||
script->remove();
|
||||
delete script;
|
||||
} else {
|
||||
@ -555,7 +487,7 @@ ScriptPreloader::WriteCache()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> cacheFile;
|
||||
MOZ_TRY_VAR(cacheFile, GetCacheFile(NS_LITERAL_STRING("-new.bin")));
|
||||
MOZ_TRY_VAR(cacheFile, GetCacheFile("scriptCache-new.bin"));
|
||||
|
||||
bool exists;
|
||||
NS_TRY(cacheFile->Exists(&exists));
|
||||
@ -587,7 +519,7 @@ ScriptPreloader::WriteCache()
|
||||
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();
|
||||
}
|
||||
@ -603,11 +535,7 @@ ScriptPreloader::Run()
|
||||
// during early startup.
|
||||
mal.Wait(10000);
|
||||
|
||||
auto result = WriteCache();
|
||||
Unused << NS_WARN_IF(result.isErr());
|
||||
|
||||
result = mChildCache->WriteCache();
|
||||
Unused << NS_WARN_IF(result.isErr());
|
||||
Unused << WriteCache();
|
||||
|
||||
mSaveComplete = true;
|
||||
NS_ReleaseOnMainThread(mSaveThread.forget());
|
||||
@ -662,7 +590,7 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
|
||||
restored->mScript = script;
|
||||
restored->mReadyToExecute = true;
|
||||
} else if (!exists) {
|
||||
auto cachedScript = new CachedScript(*this, url, cachePath, script);
|
||||
auto cachedScript = new CachedScript(url, cachePath, script);
|
||||
cachedScript->mProcesses += CurrentProcessType();
|
||||
|
||||
mSavedScripts.insertBack(cachedScript);
|
||||
@ -673,15 +601,6 @@ ScriptPreloader::NoteScript(const nsCString& url, const nsCString& cachePath,
|
||||
JSScript*
|
||||
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);
|
||||
if (script) {
|
||||
return WaitForCachedScript(cx, script);
|
||||
@ -743,7 +662,7 @@ ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
|
||||
{
|
||||
auto script = static_cast<CachedScript*>(context);
|
||||
|
||||
MonitorAutoLock mal(script->mCache.mMonitor);
|
||||
MonitorAutoLock mal(GetSingleton().mMonitor);
|
||||
|
||||
if (script->mReadyToExecute) {
|
||||
// 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
|
||||
// it.
|
||||
NS_DispatchToMainThread(
|
||||
NewRunnableMethod<void*>(&script->mCache,
|
||||
NewRunnableMethod<void*>(&GetSingleton(),
|
||||
&ScriptPreloader::CancelOffThreadParse,
|
||||
token));
|
||||
return;
|
||||
@ -763,8 +682,8 @@ ScriptPreloader::OffThreadDecodeCallback(void* token, void* context)
|
||||
mal.NotifyAll();
|
||||
}
|
||||
|
||||
ScriptPreloader::CachedScript::CachedScript(ScriptPreloader& cache, InputBuffer& buf)
|
||||
: mCache(cache)
|
||||
inline
|
||||
ScriptPreloader::CachedScript::CachedScript(InputBuffer& buf)
|
||||
{
|
||||
Code(buf);
|
||||
}
|
||||
@ -790,7 +709,7 @@ void
|
||||
ScriptPreloader::CachedScript::Cancel()
|
||||
{
|
||||
if (mToken) {
|
||||
mCache.mMonitor.AssertCurrentThreadOwns();
|
||||
GetSingleton().mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
AutoSafeJSAPI jsapi;
|
||||
JS::CancelOffThreadScriptDecoder(jsapi.cx(), mToken);
|
||||
|
@ -52,7 +52,6 @@ public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
static ScriptPreloader& GetSingleton();
|
||||
static ScriptPreloader& GetChildSingleton();
|
||||
|
||||
static ProcessType GetChildProcessType(const nsAString& remoteType);
|
||||
|
||||
@ -66,7 +65,7 @@ public:
|
||||
void NoteScript(const nsCString& url, const nsCString& cachePath, JS::HandleScript script);
|
||||
|
||||
// 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);
|
||||
|
||||
@ -108,23 +107,23 @@ private:
|
||||
public:
|
||||
CachedScript(CachedScript&&) = default;
|
||||
|
||||
CachedScript(ScriptPreloader& cache, const nsCString& url, const nsCString& cachePath, JSScript* script)
|
||||
: mCache(cache)
|
||||
, mURL(url)
|
||||
CachedScript(const nsCString& url, const nsCString& cachePath, JSScript* script)
|
||||
: mURL(url)
|
||||
, mCachePath(cachePath)
|
||||
, mScript(script)
|
||||
, mReadyToExecute(true)
|
||||
{}
|
||||
|
||||
inline CachedScript(ScriptPreloader& cache, InputBuffer& buf);
|
||||
explicit inline CachedScript(InputBuffer& buf);
|
||||
|
||||
~CachedScript()
|
||||
{
|
||||
auto& cache = GetSingleton();
|
||||
#ifdef DEBUG
|
||||
auto hashValue = mCache->mScripts.Get(mCachePath);
|
||||
auto hashValue = cache.mScripts.Get(mCachePath);
|
||||
MOZ_ASSERT_IF(hashValue, hashValue == this);
|
||||
#endif
|
||||
mCache->mScripts.Remove(mCachePath);
|
||||
cache.mScripts.Remove(mCachePath);
|
||||
}
|
||||
|
||||
void Cancel();
|
||||
@ -173,8 +172,6 @@ private:
|
||||
return size;
|
||||
}
|
||||
|
||||
ScriptPreloader& mCache;
|
||||
|
||||
// The URL from which this script was initially read and compiled.
|
||||
nsCString mURL;
|
||||
// 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
|
||||
// current profile.
|
||||
Result<nsCOMPtr<nsIFile>, nsresult>
|
||||
GetCacheFile(const nsAString& suffix);
|
||||
GetCacheFile(const char* leafName);
|
||||
|
||||
static CachedScript* FindScript(LinkedList<CachedScript>& scripts, const nsCString& cachePath);
|
||||
|
||||
@ -302,10 +299,6 @@ private:
|
||||
// The process type of the current process.
|
||||
static ProcessType sProcessType;
|
||||
|
||||
RefPtr<ScriptPreloader> mChildCache;
|
||||
|
||||
nsString mBaseName;
|
||||
|
||||
nsCOMPtr<nsIFile> mProfD;
|
||||
nsCOMPtr<nsIThread> mSaveThread;
|
||||
|
||||
|
@ -710,7 +710,7 @@ NS_InitXPCOM2(nsIServiceManager** aResult,
|
||||
nsCOMPtr<nsISupports> componentLoader =
|
||||
do_GetService("@mozilla.org/moz/jsloader;1");
|
||||
|
||||
mozilla::ScriptPreloader::GetSingleton();
|
||||
Unused << mozilla::ScriptPreloader::GetSingleton().InitCache();
|
||||
mozilla::scache::StartupCache::GetSingleton();
|
||||
mozilla::AvailableMemoryTracker::Activate();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user