Backed out 2 changesets (bug 1908320) for causing wr failures on align-items-baseline...
[gecko.git] / dom / xul / nsXULPrototypeCache.h
blob657bf9251131a2a89160d9a6d49e15800930c676
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsXULPrototypeCache_h__
7 #define nsXULPrototypeCache_h__
9 #include "nsBaseHashtable.h"
10 #include "nsCOMPtr.h"
11 #include "nsIObserver.h"
12 #include "nsInterfaceHashtable.h"
13 #include "nsRefPtrHashtable.h"
14 #include "nsURIHashKey.h"
15 #include "nsXULPrototypeDocument.h"
16 #include "nsIStorageStream.h"
18 #include "mozilla/scache/StartupCache.h"
19 #include "js/experimental/JSStencil.h"
20 #include "mozilla/RefPtr.h"
22 class nsIHandleReportCallback;
23 namespace mozilla {
24 class StyleSheet;
25 } // namespace mozilla
27 /**
28 * The XUL prototype cache can be used to store and retrieve shared data for
29 * XUL documents, style sheets, XBL, and scripts.
31 * The cache has two levels:
32 * 1. In-memory hashtables
33 * 2. The on-disk cache file.
35 class nsXULPrototypeCache : public nsIObserver {
36 public:
37 enum class CacheType { Prototype, Script };
39 // nsISupports
40 NS_DECL_THREADSAFE_ISUPPORTS
41 NS_DECL_NSIOBSERVER
43 bool IsCached(nsIURI* aURI) { return GetPrototype(aURI) != nullptr; }
44 void AbortCaching();
46 /**
47 * Whether the prototype cache is enabled.
49 bool IsEnabled();
51 /**
52 * Flush the cache; remove all XUL prototype documents, style
53 * sheets, and scripts.
55 void Flush();
57 // The following methods are used to put and retrive various items into and
58 // from the cache.
60 nsXULPrototypeDocument* GetPrototype(nsIURI* aURI);
61 nsresult PutPrototype(nsXULPrototypeDocument* aDocument);
62 void RemovePrototype(nsIURI* aURI) { mPrototypeTable.Remove(aURI); }
64 JS::Stencil* GetStencil(nsIURI* aURI);
65 nsresult PutStencil(nsIURI* aURI, JS::Stencil* aStencil);
67 /**
68 * Write the XUL prototype document to a cache file. The proto must be
69 * fully loaded.
71 nsresult WritePrototype(nsXULPrototypeDocument* aPrototypeDocument);
73 /**
74 * This interface allows partial reads and writes from the buffers in the
75 * startupCache.
78 inline nsresult GetPrototypeInputStream(nsIURI* aURI,
79 nsIObjectInputStream** objectInput) {
80 return GetInputStream(CacheType::Prototype, aURI, objectInput);
82 inline nsresult GetScriptInputStream(nsIURI* aURI,
83 nsIObjectInputStream** objectInput) {
84 return GetInputStream(CacheType::Script, aURI, objectInput);
86 inline nsresult FinishScriptInputStream(nsIURI* aURI) {
87 return FinishInputStream(aURI);
90 inline nsresult GetPrototypeOutputStream(
91 nsIURI* aURI, nsIObjectOutputStream** objectOutput) {
92 return GetOutputStream(aURI, objectOutput);
94 inline nsresult GetScriptOutputStream(nsIURI* aURI,
95 nsIObjectOutputStream** objectOutput) {
96 return GetOutputStream(aURI, objectOutput);
99 inline nsresult FinishPrototypeOutputStream(nsIURI* aURI) {
100 return FinishOutputStream(CacheType::Prototype, aURI);
102 inline nsresult FinishScriptOutputStream(nsIURI* aURI) {
103 return FinishOutputStream(CacheType::Script, aURI);
106 inline nsresult HasPrototype(nsIURI* aURI, bool* exists) {
107 return HasData(CacheType::Prototype, aURI, exists);
109 inline nsresult HasScript(nsIURI* aURI, bool* exists) {
110 return HasData(CacheType::Script, aURI, exists);
113 private:
114 nsresult GetInputStream(CacheType cacheType, nsIURI* uri,
115 nsIObjectInputStream** stream);
116 nsresult FinishInputStream(nsIURI* aURI);
118 nsresult GetOutputStream(nsIURI* aURI, nsIObjectOutputStream** objectOutput);
119 nsresult FinishOutputStream(CacheType cacheType, nsIURI* aURI);
120 nsresult HasData(CacheType cacheType, nsIURI* aURI, bool* exists);
122 public:
123 static nsXULPrototypeCache* GetInstance();
124 static nsXULPrototypeCache* MaybeGetInstance() { return sInstance; }
126 static void ReleaseGlobals() { NS_IF_RELEASE(sInstance); }
128 void MarkInCCGeneration(uint32_t aGeneration);
130 static void CollectMemoryReports(nsIHandleReportCallback* aHandleReport,
131 nsISupports* aData);
133 protected:
134 friend nsresult NS_NewXULPrototypeCache(REFNSIID aIID, void** aResult);
136 nsXULPrototypeCache();
137 virtual ~nsXULPrototypeCache() = default;
139 static nsXULPrototypeCache* sInstance;
141 nsRefPtrHashtable<nsURIHashKey, nsXULPrototypeDocument>
142 mPrototypeTable; // owns the prototypes
144 class StencilHashKey : public nsURIHashKey {
145 public:
146 explicit StencilHashKey(const nsIURI* aKey) : nsURIHashKey(aKey) {}
147 StencilHashKey(StencilHashKey&&) = default;
149 RefPtr<JS::Stencil> mStencil;
152 nsTHashtable<StencilHashKey> mStencilTable;
154 // URIs already written to the startup cache, to prevent double-caching.
155 nsTHashtable<nsURIHashKey> mStartupCacheURITable;
157 nsInterfaceHashtable<nsURIHashKey, nsIStorageStream> mOutputStreamTable;
158 nsInterfaceHashtable<nsURIHashKey, nsIObjectInputStream> mInputStreamTable;
160 // Bootstrap caching service
161 nsresult BeginCaching(nsIURI* aDocumentURI);
164 #endif // nsXULPrototypeCache_h__