SharedStyleSheetCache.h (4124B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_SharedStyleSheetCache_h__ 8 #define mozilla_SharedStyleSheetCache_h__ 9 10 // The shared style sheet cache is a cache that allows us to share sheets across 11 // documents. 12 // 13 // It's generally a singleton, but it is different from GlobalStyleSheetCache in 14 // the sense that: 15 // 16 // * It needs to be cycle-collectable, as it can keep alive style sheets from 17 // various documents. 18 // 19 // * It is conceptually a singleton, but given its cycle-collectable nature, we 20 // might re-create it. 21 22 #include "mozilla/MemoryReporting.h" 23 #include "mozilla/SharedSubResourceCache.h" 24 #include "mozilla/css/Loader.h" 25 26 namespace mozilla { 27 28 class StyleSheet; 29 class SheetLoadDataHashKey; 30 31 namespace css { 32 class SheetLoadData; 33 class Loader; 34 } // namespace css 35 36 struct SharedStyleSheetCacheTraits { 37 using Loader = css::Loader; 38 using Key = SheetLoadDataHashKey; 39 using Value = StyleSheet; 40 using LoadingValue = css::SheetLoadData; 41 42 static SheetLoadDataHashKey KeyFromLoadingValue(const LoadingValue& aValue) { 43 return SheetLoadDataHashKey(aValue); 44 } 45 }; 46 47 class SharedStyleSheetCache final 48 : public SharedSubResourceCache<SharedStyleSheetCacheTraits, 49 SharedStyleSheetCache>, 50 public nsIMemoryReporter { 51 public: 52 using Base = SharedSubResourceCache<SharedStyleSheetCacheTraits, 53 SharedStyleSheetCache>; 54 55 NS_DECL_ISUPPORTS 56 NS_DECL_NSIMEMORYREPORTER 57 58 SharedStyleSheetCache(); 59 void Init(); 60 61 // This has to be static because it's also called for loaders that don't have 62 // a sheet cache (loaders that are not owned by a document). 63 static void LoadCompleted(SharedStyleSheetCache*, css::SheetLoadData&, 64 nsresult); 65 using Base::LoadCompleted; 66 static void LoadCompletedInternal(SharedStyleSheetCache*, css::SheetLoadData&, 67 nsTArray<RefPtr<css::SheetLoadData>>&); 68 static void Clear(const Maybe<bool>& aChrome = Nothing(), 69 const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal = Nothing(), 70 const Maybe<nsCString>& aSchemelessSite = Nothing(), 71 const Maybe<OriginAttributesPattern>& aPattern = Nothing(), 72 const Maybe<nsCString>& aURL = Nothing()); 73 74 void EvictPrincipal(nsIPrincipal* aPrincipal) { 75 Base::EvictPrincipal(aPrincipal); 76 mInlineSheets.Remove(aPrincipal); 77 } 78 79 void ClearInProcess(const Maybe<bool>& aChrome, 80 const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal, 81 const Maybe<nsCString>& aSchemelessSite, 82 const Maybe<OriginAttributesPattern>& aPattern, 83 const Maybe<nsCString>& aURL); 84 85 size_t SizeOfIncludingThis(MallocSizeOf) const; 86 87 auto LookupInline(nsIPrincipal* aPrincipal, const nsAString& aBuffer) { 88 auto& principalMap = mInlineSheets.LookupOrInsert(aPrincipal); 89 return principalMap.Lookup(aBuffer); 90 } 91 92 struct InlineSheetEntry { 93 RefPtr<StyleSheet> mSheet; 94 bool mWasLoadedAsImage = false; 95 }; 96 using InlineSheetCandidates = nsTArray<InlineSheetEntry>; 97 98 void InsertInline(nsIPrincipal* aPrincipal, const nsAString& aBuffer, 99 InlineSheetEntry&& aEntry) { 100 // TODO(emilio): Maybe a better eviction policy for inline sheets, or an 101 // expiration tracker or so? 102 auto& principalMap = mInlineSheets.LookupOrInsert(aPrincipal); 103 principalMap 104 .LookupOrInsertWith(aBuffer, [] { return InlineSheetCandidates(); }) 105 .AppendElement(std::move(aEntry)); 106 } 107 108 protected: 109 void InsertIfNeeded(css::SheetLoadData&); 110 nsTHashMap<PrincipalHashKey, 111 nsTHashMap<nsStringHashKey, InlineSheetCandidates>> 112 mInlineSheets; 113 114 ~SharedStyleSheetCache(); 115 }; 116 117 } // namespace mozilla 118 119 #endif