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
);
63 JS::Stencil
* GetStencil(nsIURI
* aURI
);
64 nsresult
PutStencil(nsIURI
* aURI
, JS::Stencil
* aStencil
);
67 * Write the XUL prototype document to a cache file. The proto must be
70 nsresult
WritePrototype(nsXULPrototypeDocument
* aPrototypeDocument
);
73 * This interface allows partial reads and writes from the buffers in the
77 inline nsresult
GetPrototypeInputStream(nsIURI
* aURI
,
78 nsIObjectInputStream
** objectInput
) {
79 return GetInputStream(CacheType::Prototype
, aURI
, objectInput
);
81 inline nsresult
GetScriptInputStream(nsIURI
* aURI
,
82 nsIObjectInputStream
** objectInput
) {
83 return GetInputStream(CacheType::Script
, aURI
, objectInput
);
85 inline nsresult
FinishScriptInputStream(nsIURI
* aURI
) {
86 return FinishInputStream(aURI
);
89 inline nsresult
GetPrototypeOutputStream(
90 nsIURI
* aURI
, nsIObjectOutputStream
** objectOutput
) {
91 return GetOutputStream(aURI
, objectOutput
);
93 inline nsresult
GetScriptOutputStream(nsIURI
* aURI
,
94 nsIObjectOutputStream
** objectOutput
) {
95 return GetOutputStream(aURI
, objectOutput
);
98 inline nsresult
FinishPrototypeOutputStream(nsIURI
* aURI
) {
99 return FinishOutputStream(CacheType::Prototype
, aURI
);
101 inline nsresult
FinishScriptOutputStream(nsIURI
* aURI
) {
102 return FinishOutputStream(CacheType::Script
, aURI
);
105 inline nsresult
HasPrototype(nsIURI
* aURI
, bool* exists
) {
106 return HasData(CacheType::Prototype
, aURI
, exists
);
108 inline nsresult
HasScript(nsIURI
* aURI
, bool* exists
) {
109 return HasData(CacheType::Script
, aURI
, exists
);
113 nsresult
GetInputStream(CacheType cacheType
, nsIURI
* uri
,
114 nsIObjectInputStream
** stream
);
115 nsresult
FinishInputStream(nsIURI
* aURI
);
117 nsresult
GetOutputStream(nsIURI
* aURI
, nsIObjectOutputStream
** objectOutput
);
118 nsresult
FinishOutputStream(CacheType cacheType
, nsIURI
* aURI
);
119 nsresult
HasData(CacheType cacheType
, nsIURI
* aURI
, bool* exists
);
122 static nsXULPrototypeCache
* GetInstance();
123 static nsXULPrototypeCache
* MaybeGetInstance() { return sInstance
; }
125 static void ReleaseGlobals() { NS_IF_RELEASE(sInstance
); }
127 void MarkInCCGeneration(uint32_t aGeneration
);
129 static void CollectMemoryReports(nsIHandleReportCallback
* aHandleReport
,
133 friend nsresult
NS_NewXULPrototypeCache(REFNSIID aIID
, void** aResult
);
135 nsXULPrototypeCache();
136 virtual ~nsXULPrototypeCache() = default;
138 static nsXULPrototypeCache
* sInstance
;
140 nsRefPtrHashtable
<nsURIHashKey
, nsXULPrototypeDocument
>
141 mPrototypeTable
; // owns the prototypes
143 class StencilHashKey
: public nsURIHashKey
{
145 explicit StencilHashKey(const nsIURI
* aKey
) : nsURIHashKey(aKey
) {}
146 StencilHashKey(StencilHashKey
&&) = default;
148 RefPtr
<JS::Stencil
> mStencil
;
151 nsTHashtable
<StencilHashKey
> mStencilTable
;
153 // URIs already written to the startup cache, to prevent double-caching.
154 nsTHashtable
<nsURIHashKey
> mStartupCacheURITable
;
156 nsInterfaceHashtable
<nsURIHashKey
, nsIStorageStream
> mOutputStreamTable
;
157 nsInterfaceHashtable
<nsURIHashKey
, nsIObjectInputStream
> mInputStreamTable
;
159 // Bootstrap caching service
160 nsresult
BeginCaching(nsIURI
* aDocumentURI
);
163 #endif // nsXULPrototypeCache_h__