Bug 1729477 - Remove nsXULPrototypeCache::mStyleSheetTable. r=smaug

With a very simple tweak to SheetLoadDataHashKey::KeyEquals we should
get the same kind of caching but in a much simpler way.

Differential Revision: https://phabricator.services.mozilla.com/D124807
This commit is contained in:
Emilio Cobos Álvarez 2021-09-08 21:03:02 +00:00
parent d4d9525111
commit 2b47e33bec
4 changed files with 34 additions and 102 deletions

View File

@ -165,16 +165,6 @@ nsresult nsXULPrototypeCache::PutPrototype(nsXULPrototypeDocument* aDocument) {
return NS_OK;
}
mozilla::StyleSheet* nsXULPrototypeCache::GetStyleSheet(nsIURI* aURI) {
return mStyleSheetTable.GetWeak(aURI);
}
nsresult nsXULPrototypeCache::PutStyleSheet(RefPtr<StyleSheet>&& aStyleSheet) {
nsIURI* uri = aStyleSheet->GetSheetURI();
mStyleSheetTable.InsertOrUpdate(uri, std::move(aStyleSheet));
return NS_OK;
}
JSScript* nsXULPrototypeCache::GetScript(nsIURI* aURI) {
if (auto* entry = mScriptTable.GetEntry(aURI)) {
return entry->mScript.get();
@ -207,7 +197,6 @@ void nsXULPrototypeCache::FlushScripts() { mScriptTable.Clear(); }
void nsXULPrototypeCache::Flush() {
mPrototypeTable.Clear();
mScriptTable.Clear();
mStyleSheetTable.Clear();
}
bool nsXULPrototypeCache::IsEnabled() { return !gDisableXULCache; }
@ -507,14 +496,6 @@ void nsXULPrototypeCache::CollectMemoryReports(
other += sInstance->mPrototypeTable.ShallowSizeOfExcludingThis(mallocSizeOf);
// TODO Report content in mPrototypeTable?
other += sInstance->mStyleSheetTable.ShallowSizeOfExcludingThis(mallocSizeOf);
for (const auto& stylesheet : sInstance->mStyleSheetTable.Values()) {
// NOTE: If Loader::DoSheetComplete() is ever modified to stop clongin
// sheets before inserting into this cache, we will need to stop using
// SizeOfIncludingThis()
other += stylesheet->SizeOfIncludingThis(mallocSizeOf);
}
other += sInstance->mScriptTable.ShallowSizeOfExcludingThis(mallocSizeOf);
// TODO Report content inside mScriptTable?

View File

@ -59,18 +59,6 @@ class nsXULPrototypeCache : public nsIObserver {
JSScript* GetScript(nsIURI* aURI);
nsresult PutScript(nsIURI* aURI, JS::Handle<JSScript*> aScriptObject);
/**
* Get a style sheet by URI. If the style sheet is not in the cache,
* returns nullptr.
*/
mozilla::StyleSheet* GetStyleSheet(nsIURI* aURI);
/**
* Store a style sheet in the cache. The key, style sheet's URI is obtained
* from the style sheet itself.
*/
nsresult PutStyleSheet(RefPtr<mozilla::StyleSheet>&& aStyleSheet);
/**
* Write the XUL prototype document to a cache file. The proto must be
* fully loaded.
@ -108,11 +96,8 @@ class nsXULPrototypeCache : public nsIObserver {
static nsXULPrototypeCache* sInstance;
using StyleSheetTable = nsRefPtrHashtable<nsURIHashKey, mozilla::StyleSheet>;
nsRefPtrHashtable<nsURIHashKey, nsXULPrototypeDocument>
mPrototypeTable; // owns the prototypes
StyleSheetTable mStyleSheetTable;
class ScriptHashKey : public nsURIHashKey {
public:

View File

@ -164,6 +164,16 @@ bool SheetLoadDataHashKey::KeyEquals(const SheetLoadDataHashKey& aKey) const {
LOG_URI("KeyEquals(%s)\n", mURI);
if (mParsingMode != aKey.mParsingMode) {
LOG((" > Parsing mode mismatch\n"));
return false;
}
// Chrome URIs ignore everything else.
if (dom::IsChromeURI(mURI)) {
return true;
}
if (!mPrincipal->Equals(aKey.mPrincipal)) {
LOG((" > Principal mismatch\n"));
return false;
@ -185,11 +195,6 @@ bool SheetLoadDataHashKey::KeyEquals(const SheetLoadDataHashKey& aKey) const {
return false;
}
if (mParsingMode != aKey.mParsingMode) {
LOG((" > Parsing mode mismatch\n"));
return false;
}
if (mCompatMode != aKey.mCompatMode) {
LOG((" > Quirks mismatch\n"));
return false;

View File

@ -128,7 +128,8 @@ static void AssertComplete(const StyleSheet& aSheet) {
static void AssertIncompleteSheetMatches(const SheetLoadData& aData,
const SheetLoadDataHashKey& aKey) {
MOZ_ASSERT(aKey.Principal()->Equals(aData.mTriggeringPrincipal),
MOZ_ASSERT(aKey.Principal()->Equals(aData.mTriggeringPrincipal) ||
dom::IsChromeURI(aKey.URI()),
"Principals should be the same");
MOZ_ASSERT(!aData.mSheet->HasForcedUniqueInner(),
"CSSOM shouldn't allow access to incomplete sheets");
@ -144,30 +145,6 @@ SharedStyleSheetCache::CacheResult SharedStyleSheetCache::Lookup(
nsIURI* uri = aKey.URI();
LOG(("SharedStyleSheetCache::Lookup(%s)", uri->GetSpecOrDefault().get()));
// Try to find first in the XUL prototype cache.
if (dom::IsChromeURI(uri)) {
nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
if (cache && cache->IsEnabled()) {
if (StyleSheet* sheet = cache->GetStyleSheet(uri)) {
LOG((" From XUL cache: %p", sheet));
AssertComplete(*sheet);
// See below, we always clone on insertion so we can guarantee the
// stylesheet is not modified.
MOZ_ASSERT(!sheet->HasForcedUniqueInner());
// We need to check the parsing mode manually because the XUL cache only
// keys off the URI. But we should fix that!
if (sheet->ParsingMode() == aKey.ParsingMode()) {
aLoader.DidHitCompleteSheetCache(aKey, nullptr);
return {CloneSheet(*sheet), SheetState::Complete};
}
LOG((" Not cloning due to mismatched parsing mode"));
}
}
}
// Now complete sheets.
if (auto lookup = mCompleteSheets.Lookup(aKey)) {
const CompleteSheet& completeSheet = lookup.Data();
@ -468,50 +445,34 @@ void SharedStyleSheetCache::InsertIntoCompleteCacheIfNeeded(
// both SizeOfIncludingThis and nsXULPrototypeCache::CollectMemoryReports.
RefPtr<StyleSheet> sheet = CloneSheet(*aData.mSheet);
if (dom::IsChromeURI(aData.mURI)) {
nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
if (cache && cache->IsEnabled()) {
if (!cache->GetStyleSheet(aData.mURI)) {
LOG((" Putting sheet in XUL prototype cache"));
NS_ASSERTION(sheet->IsComplete(),
"Should only be caching complete sheets");
// NOTE: If we stop cloning sheets before insertion, we need to change
// nsXULPrototypeCache::CollectMemoryReports() to stop using
// SizeOfIncludingThis() because it will no longer own the sheets.
cache->PutStyleSheet(std::move(sheet));
}
}
} else {
LOG((" Putting style sheet in shared cache: %s",
aData.mURI->GetSpecOrDefault().get()));
SheetLoadDataHashKey key(aData);
MOZ_ASSERT(sheet->IsComplete(), "Should only be caching complete sheets");
LOG((" Putting style sheet in shared cache: %s",
aData.mURI->GetSpecOrDefault().get()));
SheetLoadDataHashKey key(aData);
MOZ_ASSERT(sheet->IsComplete(), "Should only be caching complete sheets");
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
for (const auto& entry : mCompleteSheets) {
if (!key.KeyEquals(entry.GetKey())) {
MOZ_DIAGNOSTIC_ASSERT(entry.GetData().mSheet != sheet,
"Same sheet, different keys?");
} else {
MOZ_ASSERT(
entry.GetData().Expired() || aData.mLoader->ShouldBypassCache(),
"Overriding existing complete entry?");
}
for (const auto& entry : mCompleteSheets) {
if (!key.KeyEquals(entry.GetKey())) {
MOZ_DIAGNOSTIC_ASSERT(entry.GetData().mSheet != sheet,
"Same sheet, different keys?");
} else {
MOZ_ASSERT(
entry.GetData().Expired() || aData.mLoader->ShouldBypassCache(),
"Overriding existing complete entry?");
}
}
#endif
UniquePtr<StyleUseCounters> counters;
if (aData.mUseCounters) {
// TODO(emilio): Servo_UseCounters_Clone() or something?
counters = Servo_UseCounters_Create().Consume();
Servo_UseCounters_Merge(counters.get(), aData.mUseCounters.get());
}
mCompleteSheets.InsertOrUpdate(
key, CompleteSheet{aData.mExpirationTime, std::move(counters),
std::move(sheet)});
UniquePtr<StyleUseCounters> counters;
if (aData.mUseCounters) {
// TODO(emilio): Servo_UseCounters_Clone() or something?
counters = Servo_UseCounters_Create().Consume();
Servo_UseCounters_Merge(counters.get(), aData.mUseCounters.get());
}
mCompleteSheets.InsertOrUpdate(
key, CompleteSheet{aData.mExpirationTime, std::move(counters),
std::move(sheet)});
}
void SharedStyleSheetCache::StartDeferredLoadsForLoader(