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"
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
;
25 } // namespace mozilla
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
{
37 enum class CacheType
{ Prototype
, Script
};
40 NS_DECL_THREADSAFE_ISUPPORTS
43 bool IsCached(nsIURI
* aURI
) { return GetPrototype(aURI
) != nullptr; }
47 * Whether the prototype cache is enabled.
52 * Flush the cache; remove all XUL prototype documents, style
53 * sheets, and scripts.
57 // The following methods are used to put and retrive various items into and
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
);
68 * Write the XUL prototype document to a cache file. The proto must be
71 nsresult
WritePrototype(nsXULPrototypeDocument
* aPrototypeDocument
);
74 * This interface allows partial reads and writes from the buffers in the
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
);
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
);
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
,
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
{
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__