/* 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, public nsIMemoryReporter, public nsIObserver { public: using Base = SharedSubResourceCache; 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>&); static void Clear(const Maybe& aChrome = Nothing(), const Maybe>& aPrincipal = Nothing(), const Maybe& aSchemelessSite = Nothing(), const Maybe& aPattern = Nothing(), const Maybe& aURL = Nothing()); void EvictPrincipal(nsIPrincipal* aPrincipal) { Base::EvictPrincipal(aPrincipal); mInlineSheets.Remove(aPrincipal); } void ClearInProcess(const Maybe& aChrome, const Maybe>& aPrincipal, const Maybe& aSchemelessSite, const Maybe& aPattern, const Maybe& aURL); size_t SizeOfIncludingThis(MallocSizeOf) const; struct InlineSheetEntry { RefPtr mSheet; bool mWasLoadedAsImage = false; }; using InlineSheetCandidates = nsTArray; template void WithInlineEntryHandle(nsIPrincipal* aPrincipal, const nsACString& aBuffer, F&& aFunc) { auto& principalMap = mInlineSheets.LookupOrInsert(aPrincipal); return principalMap.WithEntryHandle(aBuffer, std::forward(aFunc)); } protected: void InsertIfNeeded(css::SheetLoadData&); bool ShouldIgnoreMemoryPressure() override { return false; } void DoScheduleGC(); void GC(); nsTHashMap> mInlineSheets; nsCOMPtr mGCTimer; bool mGCScheduled : 1 = false; ~SharedStyleSheetCache(); public: static void ScheduleGC() { if (!sSingleton || sSingleton->mGCScheduled) { return; } sSingleton->DoScheduleGC(); } }; } // namespace mozilla #endif