Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
5 :
6 : #ifndef nsXULPrototypeCache_h__
7 : #define nsXULPrototypeCache_h__
8 :
9 : #include "nsCOMPtr.h"
10 : #include "nsIObserver.h"
11 : #include "nsXBLDocumentInfo.h"
12 : #include "nsJSThingHashtable.h"
13 : #include "nsInterfaceHashtable.h"
14 : #include "nsRefPtrHashtable.h"
15 : #include "nsURIHashKey.h"
16 : #include "nsXULPrototypeDocument.h"
17 : #include "nsIInputStream.h"
18 : #include "nsIStorageStream.h"
19 :
20 : #include "mozilla/scache/StartupCache.h"
21 :
22 : namespace mozilla {
23 : class StyleSheet;
24 : } // namespace mozilla
25 :
26 : /**
27 : * The XUL prototype cache can be used to store and retrieve shared data for
28 : * XUL documents, style sheets, XBL, and scripts.
29 : *
30 : * The cache has two levels:
31 : * 1. In-memory hashtables
32 : * 2. The on-disk cache file.
33 : */
34 : class nsXULPrototypeCache : public nsIObserver
35 : {
36 : public:
37 : // nsISupports
38 : NS_DECL_THREADSAFE_ISUPPORTS
39 : NS_DECL_NSIOBSERVER
40 :
41 : bool IsCached(nsIURI* aURI) {
42 : return GetPrototype(aURI) != nullptr;
43 : }
44 : void AbortCaching();
45 :
46 :
47 : /**
48 : * Whether the prototype cache is enabled.
49 : */
50 : bool IsEnabled();
51 :
52 : /**
53 : * Flush the cache; remove all XUL prototype documents, style
54 : * sheets, and scripts.
55 : */
56 : void Flush();
57 :
58 :
59 : // The following methods are used to put and retrive various items into and
60 : // from the cache.
61 :
62 : nsXULPrototypeDocument* GetPrototype(nsIURI* aURI);
63 : nsresult PutPrototype(nsXULPrototypeDocument* aDocument);
64 :
65 : JSScript* GetScript(nsIURI* aURI);
66 : nsresult PutScript(nsIURI* aURI, JS::Handle<JSScript*> aScriptObject);
67 :
68 : nsXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURL,
69 : mozilla::StyleBackendType aType);
70 :
71 : nsresult PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo);
72 :
73 : /**
74 : * Get a style sheet by URI. If the style sheet is not in the cache,
75 : * returns nullptr.
76 : */
77 : mozilla::StyleSheet* GetStyleSheet(nsIURI* aURI,
78 : mozilla::StyleBackendType aType);
79 :
80 : /**
81 : * Store a style sheet in the cache. The key, style sheet's URI is obtained
82 : * from the style sheet itself.
83 : */
84 : nsresult PutStyleSheet(mozilla::StyleSheet* aStyleSheet,
85 : mozilla::StyleBackendType aType);
86 :
87 : /**
88 : * Write the XUL prototype document to a cache file. The proto must be
89 : * fully loaded.
90 : */
91 : nsresult WritePrototype(nsXULPrototypeDocument* aPrototypeDocument);
92 :
93 : /**
94 : * This interface allows partial reads and writes from the buffers in the
95 : * startupCache.
96 : */
97 : nsresult GetInputStream(nsIURI* aURI, nsIObjectInputStream** objectInput);
98 : nsresult FinishInputStream(nsIURI* aURI);
99 : nsresult GetOutputStream(nsIURI* aURI, nsIObjectOutputStream** objectOutput);
100 : nsresult FinishOutputStream(nsIURI* aURI);
101 : nsresult HasData(nsIURI* aURI, bool* exists);
102 :
103 : static nsXULPrototypeCache* GetInstance();
104 1 : static nsXULPrototypeCache* MaybeGetInstance() { return sInstance; }
105 :
106 0 : static void ReleaseGlobals()
107 : {
108 0 : NS_IF_RELEASE(sInstance);
109 0 : }
110 :
111 : void MarkInCCGeneration(uint32_t aGeneration);
112 : void MarkInGC(JSTracer* aTrc);
113 : void FlushScripts();
114 : protected:
115 : friend nsresult
116 : NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult);
117 :
118 : nsXULPrototypeCache();
119 : virtual ~nsXULPrototypeCache();
120 :
121 : static nsXULPrototypeCache* sInstance;
122 :
123 : void FlushSkinFiles();
124 :
125 : using StyleSheetTable = nsRefPtrHashtable<nsURIHashKey, mozilla::StyleSheet>;
126 : using XBLDocTable = nsRefPtrHashtable<nsURIHashKey, nsXBLDocumentInfo>;
127 :
128 126 : StyleSheetTable& StyleSheetTableFor(mozilla::StyleBackendType aType) {
129 : return aType == mozilla::StyleBackendType::Gecko ? mGeckoStyleSheetTable
130 126 : : mServoStyleSheetTable;
131 : }
132 :
133 52 : XBLDocTable& XBLDocTableFor(mozilla::StyleBackendType aType) {
134 : return aType == mozilla::StyleBackendType::Gecko ? mGeckoXBLDocTable
135 52 : : mServoXBLDocTable;
136 : }
137 :
138 : nsRefPtrHashtable<nsURIHashKey,nsXULPrototypeDocument> mPrototypeTable; // owns the prototypes
139 : StyleSheetTable mGeckoStyleSheetTable;
140 : StyleSheetTable mServoStyleSheetTable;
141 : nsJSThingHashtable<nsURIHashKey, JSScript*> mScriptTable;
142 : XBLDocTable mGeckoXBLDocTable;
143 : XBLDocTable mServoXBLDocTable;
144 :
145 : // URIs already written to the startup cache, to prevent double-caching.
146 : nsTHashtable<nsURIHashKey> mStartupCacheURITable;
147 :
148 : nsInterfaceHashtable<nsURIHashKey, nsIStorageStream> mOutputStreamTable;
149 : nsInterfaceHashtable<nsURIHashKey, nsIObjectInputStream> mInputStreamTable;
150 :
151 : // Bootstrap caching service
152 : nsresult BeginCaching(nsIURI* aDocumentURI);
153 : };
154 :
155 : #endif // nsXULPrototypeCache_h__
|