Files
sousa-gecko/layout/style/SharedStyleSheetCache.h
Emilio Cobos Álvarez a2666940ab Bug 2065672 - Avoid inflating inline stylesheet text just to turn it into utf-8 again. r=dom-core-reviewers,smaug
Most inline stylesheets are actually ascii / use Latin1 storage, so it's
faster to just copy it out that to inflate just to deflate it before
parsing.

Do the same trick we use for <script> elements and CSP and retrieve the
two-byte text there instead. Chances are we want to just use the utf-8
text there, since that's what we end up using for the hash / nonce:

  https://searchfox.org/firefox-main/rev/2916f047242de012d1aa0c572be9e5239644cc48/dom/security/nsCSPUtils.cpp#1020-1021

But plumbing that through gets a bit annoying.

Differential Revision: https://phabricator.services.mozilla.com/D320598
2026-08-22 20:59:43 +00:00

116 lines
3.7 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_SharedStyleSheetCache_h_
#define mozilla_SharedStyleSheetCache_h_
// The shared style sheet cache is a cache that allows us to share sheets across
// documents.
#include "mozilla/MemoryReporting.h"
#include "mozilla/SharedSubResourceCache.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/css/Loader.h"
#include "nsIMemoryReporter.h"
#include "nsIObserver.h"
namespace mozilla {
struct SharedStyleSheetCacheTraits {
using Loader = css::Loader;
using Key = SheetLoadDataHashKey;
using Value = StyleSheet;
using LoadingValue = css::SheetLoadData;
static SheetLoadDataHashKey KeyFromLoadingValue(const LoadingValue& aValue) {
return SheetLoadDataHashKey(aValue);
}
};
class SharedStyleSheetCache final
: public SharedSubResourceCache<SharedStyleSheetCacheTraits,
SharedStyleSheetCache>,
public nsIMemoryReporter,
public nsIObserver {
public:
using Base = SharedSubResourceCache<SharedStyleSheetCacheTraits,
SharedStyleSheetCache>;
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
SharedStyleSheetCache();
void Init();
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) override {
return Base::DoObserve(aSubject, aTopic, aData);
}
// This has to be static because it's also called for loaders that don't have
// a sheet cache (loaders that are not owned by a document).
static void LoadCompleted(SharedStyleSheetCache*, css::SheetLoadData&,
nsresult);
using Base::LoadCompleted;
static void LoadCompletedInternal(SharedStyleSheetCache*, css::SheetLoadData&,
nsTArray<RefPtr<css::SheetLoadData>>&);
static void Clear(const Maybe<bool>& aChrome = Nothing(),
const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal = Nothing(),
const Maybe<nsCString>& aSchemelessSite = Nothing(),
const Maybe<OriginAttributesPattern>& aPattern = Nothing(),
const Maybe<nsCString>& aURL = Nothing());
void EvictPrincipal(nsIPrincipal* aPrincipal) {
Base::EvictPrincipal(aPrincipal);
mInlineSheets.Remove(aPrincipal);
}
void ClearInProcess(const Maybe<bool>& aChrome,
const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal,
const Maybe<nsCString>& aSchemelessSite,
const Maybe<OriginAttributesPattern>& aPattern,
const Maybe<nsCString>& aURL);
size_t SizeOfIncludingThis(MallocSizeOf) const;
struct InlineSheetEntry {
RefPtr<StyleSheet> mSheet;
bool mWasLoadedAsImage = false;
};
using InlineSheetCandidates = nsTArray<InlineSheetEntry>;
template <class F>
void WithInlineEntryHandle(nsIPrincipal* aPrincipal,
const nsACString& aBuffer, F&& aFunc) {
auto& principalMap = mInlineSheets.LookupOrInsert(aPrincipal);
return principalMap.WithEntryHandle(aBuffer, std::forward<F>(aFunc));
}
protected:
void InsertIfNeeded(css::SheetLoadData&);
bool ShouldIgnoreMemoryPressure() override { return false; }
void DoScheduleGC();
void GC();
nsTHashMap<PrincipalHashKey,
nsTHashMap<nsCStringHashKey, InlineSheetCandidates>>
mInlineSheets;
nsCOMPtr<nsITimer> mGCTimer;
bool mGCScheduled : 1 = false;
~SharedStyleSheetCache();
public:
static void ScheduleGC() {
if (!sSingleton || sSingleton->mGCScheduled) {
return;
}
sSingleton->DoScheduleGC();
}
};
} // namespace mozilla
#endif