Bug 1752209 - Put cahe type into the cache key in StartupCache/ScriptPreloader. r=nbp

Differential Revision: https://phabricator.services.mozilla.com/D143576
This commit is contained in:
Tooru Fujisawa 2022-04-13 14:08:07 +00:00
parent a738d66e34
commit 6ea9c3b12c
7 changed files with 89 additions and 30 deletions

View File

@ -131,7 +131,7 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::ipc;
static const char kMessageManagerCachePrefix[] = "mm";
#define CACHE_PREFIX(type) "mm/" type
nsFrameMessageManager::nsFrameMessageManager(MessageManagerCallback* aCallback,
MessageManagerFlags aFlags)
@ -1276,7 +1276,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
RefPtr<JS::Stencil> stencil;
if (useScriptPreloader) {
nsAutoCString cachePath;
rv = scache::PathifyURI(kMessageManagerCachePrefix, uri, cachePath);
rv = scache::PathifyURI(CACHE_PREFIX("script"), uri, cachePath);
NS_ENSURE_SUCCESS(rv, nullptr);
JS::DecodeOptions decodeOptions;
@ -1358,7 +1358,7 @@ nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
if (useScriptPreloader) {
nsAutoCString cachePath;
rv = scache::PathifyURI(kMessageManagerCachePrefix, uri, cachePath);
rv = scache::PathifyURI(CACHE_PREFIX("script"), uri, cachePath);
NS_ENSURE_SUCCESS(rv, nullptr);
ScriptPreloader::GetChildSingleton().NoteStencil(url, cachePath, stencil,
isRunOnce);

View File

@ -671,7 +671,8 @@ nsresult PrototypeDocumentContentSink::DoneWalking() {
if (IsChromeURI(mDocumentURI) &&
nsXULPrototypeCache::GetInstance()->IsEnabled()) {
bool isCachedOnDisk;
nsXULPrototypeCache::GetInstance()->HasData(mDocumentURI, &isCachedOnDisk);
nsXULPrototypeCache::GetInstance()->HasPrototype(mDocumentURI,
&isCachedOnDisk);
if (!isCachedOnDisk) {
nsXULPrototypeCache::GetInstance()->WritePrototype(mCurrentPrototype);
}

View File

@ -1670,7 +1670,7 @@ nsresult nsXULPrototypeScript::SerializeOutOfLine(
NS_ASSERTION(cache->IsEnabled(),
"writing to the cache file, but the XUL cache is off?");
bool exists;
cache->HasData(mSrcURI, &exists);
cache->HasScript(mSrcURI, &exists);
/* return will be NS_OK from GetAsciiSpec.
* that makes no sense.
@ -1680,14 +1680,14 @@ nsresult nsXULPrototypeScript::SerializeOutOfLine(
if (exists) return NS_OK;
nsCOMPtr<nsIObjectOutputStream> oos;
nsresult rv = cache->GetOutputStream(mSrcURI, getter_AddRefs(oos));
nsresult rv = cache->GetScriptOutputStream(mSrcURI, getter_AddRefs(oos));
NS_ENSURE_SUCCESS(rv, rv);
nsresult tmp = Serialize(oos, aProtoDoc, nullptr);
if (NS_FAILED(tmp)) {
rv = tmp;
}
tmp = cache->FinishOutputStream(mSrcURI);
tmp = cache->FinishScriptOutputStream(mSrcURI);
if (NS_FAILED(tmp)) {
rv = tmp;
}
@ -1754,7 +1754,7 @@ nsresult nsXULPrototypeScript::DeserializeOutOfLine(
if (!mStencil) {
if (mSrcURI) {
rv = cache->GetInputStream(mSrcURI, getter_AddRefs(objectInput));
rv = cache->GetScriptInputStream(mSrcURI, getter_AddRefs(objectInput));
}
// If !mSrcURI, we have an inline script. We shouldn't have
// to do anything else in that case, I think.
@ -1772,7 +1772,7 @@ nsresult nsXULPrototypeScript::DeserializeOutOfLine(
if (useXULCache && mSrcURI && mSrcURI->SchemeIs("chrome")) {
cache->PutStencil(mSrcURI, GetStencil());
}
cache->FinishInputStream(mSrcURI);
cache->FinishScriptInputStream(mSrcURI);
} else {
// If mSrcURI is not in the cache,
// rv will be NS_ERROR_NOT_AVAILABLE and we'll try to

View File

@ -37,7 +37,7 @@ using namespace mozilla::scache;
using mozilla::intl::LocaleService;
static const char kXULCacheInfoKey[] = "nsXULPrototypeCache.startupCache";
static const char kXULCachePrefix[] = "xulcache";
#define CACHE_PREFIX(aCompilationTarget) "xulcache/" aCompilationTarget
static void DisableXULCacheChangedCallback(const char* aPref, void* aClosure) {
if (nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance()) {
@ -110,7 +110,7 @@ nsXULPrototypeDocument* nsXULPrototypeCache::GetPrototype(nsIURI* aURI) {
// No prototype in XUL memory cache. Spin up the cache Service.
nsCOMPtr<nsIObjectInputStream> ois;
rv = GetInputStream(aURI, getter_AddRefs(ois));
rv = GetPrototypeInputStream(aURI, getter_AddRefs(ois));
if (NS_FAILED(rv)) {
return nullptr;
}
@ -197,19 +197,31 @@ nsresult nsXULPrototypeCache::WritePrototype(
nsCOMPtr<nsIURI> protoURI = aPrototypeDocument->GetURI();
nsCOMPtr<nsIObjectOutputStream> oos;
rv = GetOutputStream(protoURI, getter_AddRefs(oos));
rv = GetPrototypeOutputStream(protoURI, getter_AddRefs(oos));
NS_ENSURE_SUCCESS(rv, rv);
rv = aPrototypeDocument->Write(oos);
NS_ENSURE_SUCCESS(rv, rv);
FinishOutputStream(protoURI);
FinishPrototypeOutputStream(protoURI);
return NS_FAILED(rv) ? rv : rv2;
}
nsresult nsXULPrototypeCache::GetInputStream(nsIURI* uri,
static nsresult PathifyURIForType(nsXULPrototypeCache::CacheType cacheType,
nsIURI* in, nsACString& out) {
switch (cacheType) {
case nsXULPrototypeCache::CacheType::Prototype:
return PathifyURI(CACHE_PREFIX("proto"), in, out);
case nsXULPrototypeCache::CacheType::Script:
return PathifyURI(CACHE_PREFIX("script"), in, out);
}
MOZ_ASSERT_UNREACHABLE("unknown cache type?");
return NS_ERROR_UNEXPECTED;
}
nsresult nsXULPrototypeCache::GetInputStream(CacheType cacheType, nsIURI* uri,
nsIObjectInputStream** stream) {
nsAutoCString spec;
nsresult rv = PathifyURI(kXULCachePrefix, uri, spec);
nsresult rv = PathifyURIForType(cacheType, uri, spec);
if (NS_FAILED(rv)) return NS_ERROR_NOT_AVAILABLE;
const char* buf;
@ -261,7 +273,8 @@ nsresult nsXULPrototypeCache::GetOutputStream(nsIURI* uri,
return NS_OK;
}
nsresult nsXULPrototypeCache::FinishOutputStream(nsIURI* uri) {
nsresult nsXULPrototypeCache::FinishOutputStream(CacheType cacheType,
nsIURI* uri) {
nsresult rv;
StartupCache* sc = StartupCache::GetSingleton();
if (!sc) return NS_ERROR_NOT_AVAILABLE;
@ -279,7 +292,7 @@ nsresult nsXULPrototypeCache::FinishOutputStream(nsIURI* uri) {
if (!mStartupCacheURITable.GetEntry(uri)) {
nsAutoCString spec;
rv = PathifyURI(kXULCachePrefix, uri, spec);
rv = PathifyURIForType(cacheType, uri, spec);
if (NS_FAILED(rv)) return NS_ERROR_NOT_AVAILABLE;
rv = sc->PutBuffer(spec.get(), std::move(buf), len);
if (NS_SUCCEEDED(rv)) {
@ -293,13 +306,14 @@ nsresult nsXULPrototypeCache::FinishOutputStream(nsIURI* uri) {
// We have data if we're in the middle of writing it or we already
// have it in the cache.
nsresult nsXULPrototypeCache::HasData(nsIURI* uri, bool* exists) {
nsresult nsXULPrototypeCache::HasData(CacheType cacheType, nsIURI* uri,
bool* exists) {
if (mOutputStreamTable.Get(uri, nullptr)) {
*exists = true;
return NS_OK;
}
nsAutoCString spec;
nsresult rv = PathifyURI(kXULCachePrefix, uri, spec);
nsresult rv = PathifyURIForType(cacheType, uri, spec);
if (NS_FAILED(rv)) {
*exists = false;
return NS_OK;

View File

@ -34,6 +34,8 @@ class StyleSheet;
*/
class nsXULPrototypeCache : public nsIObserver {
public:
enum class CacheType { Prototype, Script };
// nsISupports
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
@ -71,12 +73,52 @@ class nsXULPrototypeCache : public nsIObserver {
* This interface allows partial reads and writes from the buffers in the
* startupCache.
*/
nsresult GetInputStream(nsIURI* aURI, nsIObjectInputStream** objectInput);
nsresult FinishInputStream(nsIURI* aURI);
nsresult GetOutputStream(nsIURI* aURI, nsIObjectOutputStream** objectOutput);
nsresult FinishOutputStream(nsIURI* aURI);
nsresult HasData(nsIURI* aURI, bool* exists);
inline nsresult GetPrototypeInputStream(nsIURI* aURI,
nsIObjectInputStream** objectInput) {
return GetInputStream(CacheType::Prototype, aURI, objectInput);
}
inline nsresult GetScriptInputStream(nsIURI* aURI,
nsIObjectInputStream** objectInput) {
return GetInputStream(CacheType::Script, aURI, objectInput);
}
inline nsresult FinishScriptInputStream(nsIURI* aURI) {
return FinishInputStream(aURI);
}
inline nsresult GetPrototypeOutputStream(
nsIURI* aURI, nsIObjectOutputStream** objectOutput) {
return GetOutputStream(aURI, objectOutput);
}
inline nsresult GetScriptOutputStream(nsIURI* aURI,
nsIObjectOutputStream** objectOutput) {
return GetOutputStream(aURI, objectOutput);
}
inline nsresult FinishPrototypeOutputStream(nsIURI* aURI) {
return FinishOutputStream(CacheType::Prototype, aURI);
}
inline nsresult FinishScriptOutputStream(nsIURI* aURI) {
return FinishOutputStream(CacheType::Script, aURI);
}
inline nsresult HasPrototype(nsIURI* aURI, bool* exists) {
return HasData(CacheType::Prototype, aURI, exists);
}
inline nsresult HasScript(nsIURI* aURI, bool* exists) {
return HasData(CacheType::Script, aURI, exists);
}
private:
nsresult GetInputStream(CacheType cacheType, nsIURI* uri,
nsIObjectInputStream** stream);
nsresult FinishInputStream(nsIURI* aURI);
nsresult GetOutputStream(nsIURI* aURI, nsIObjectOutputStream** objectOutput);
nsresult FinishOutputStream(CacheType cacheType, nsIURI* aURI);
nsresult HasData(CacheType cacheType, nsIURI* aURI, bool* exists);
public:
static nsXULPrototypeCache* GetInstance();
static nsXULPrototypeCache* MaybeGetInstance() { return sInstance; }

View File

@ -75,7 +75,8 @@ using namespace mozilla::loader;
using namespace xpc;
using namespace JS;
#define JS_CACHE_PREFIX(aType) "jsloader/" aType
#define JS_CACHE_PREFIX(aScopeType, aCompilationTarget) \
"jsloader/" aScopeType "/" aCompilationTarget
/**
* Buffer sizes for serialization and deserialization of scripts.
@ -748,8 +749,8 @@ nsresult mozJSComponentLoader::ObjectForLocation(
aInfo.EnsureResolvedURI();
nsAutoCString cachePath;
rv = PathifyURI(JS_CACHE_PREFIX("non-syntactic"), aInfo.ResolvedURI(),
cachePath);
rv = PathifyURI(JS_CACHE_PREFIX("non-syntactic", "script"),
aInfo.ResolvedURI(), cachePath);
NS_ENSURE_SUCCESS(rv, rv);
JS::DecodeOptions decodeOptions;

View File

@ -81,7 +81,8 @@ mozJSSubScriptLoader::~mozJSSubScriptLoader() = default;
NS_IMPL_ISUPPORTS(mozJSSubScriptLoader, mozIJSSubScriptLoader)
#define JSSUB_CACHE_PREFIX(aType) "jssubloader/" aType
#define JSSUB_CACHE_PREFIX(aScopeType, aCompilationTarget) \
"jssubloader/" aScopeType "/" aCompilationTarget
static void SubscriptCachePath(JSContext* cx, nsIURI* uri,
JS::HandleObject targetObj,
@ -89,9 +90,9 @@ static void SubscriptCachePath(JSContext* cx, nsIURI* uri,
// StartupCache must distinguish between non-syntactic vs global when
// computing the cache key.
if (!JS_IsGlobalObject(targetObj)) {
PathifyURI(JSSUB_CACHE_PREFIX("non-syntactic"), uri, cachePath);
PathifyURI(JSSUB_CACHE_PREFIX("non-syntactic", "script"), uri, cachePath);
} else {
PathifyURI(JSSUB_CACHE_PREFIX("global"), uri, cachePath);
PathifyURI(JSSUB_CACHE_PREFIX("global", "script"), uri, cachePath);
}
}