18 along with this library; see the file COPYING.LIB. If not, write to |
18 along with this library; see the file COPYING.LIB. If not, write to |
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 Boston, MA 02110-1301, USA. |
20 Boston, MA 02110-1301, USA. |
21 */ |
21 */ |
22 |
22 |
23 #include "config.h" |
|
24 #include "Cache.h" |
23 #include "Cache.h" |
25 |
24 |
26 #include "CachedCSSStyleSheet.h" |
25 #include "CachedCSSStyleSheet.h" |
27 #include "CachedImage.h" |
26 #include "CachedImage.h" |
28 #include "CachedScript.h" |
27 #include "CachedScript.h" |
42 static const int cDefaultCacheCapacity = 8192 * 1024; |
41 static const int cDefaultCacheCapacity = 8192 * 1024; |
43 |
42 |
44 static const double cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. |
43 static const double cMinDelayBeforeLiveDecodedPrune = 1; // Seconds. |
45 static const float cTargetPrunePercentage = .95f; // Percentage of capacity toward which we prune, to avoid immediately pruning again. |
44 static const float cTargetPrunePercentage = .95f; // Percentage of capacity toward which we prune, to avoid immediately pruning again. |
46 |
45 |
|
46 #if PLATFORM(SYMBIAN) |
|
47 static Cache* staticCache; |
|
48 static bool staticCacheInit = false; |
|
49 #endif |
|
50 |
47 Cache* cache() |
51 Cache* cache() |
48 { |
52 { |
|
53 #if PLATFORM(SYMBIAN) |
|
54 if (!staticCacheInit) |
|
55 { |
|
56 staticCache = new Cache; |
|
57 staticCacheInit = true; |
|
58 } |
|
59 #else |
49 static Cache* staticCache = new Cache; |
60 static Cache* staticCache = new Cache; |
|
61 #endif |
50 return staticCache; |
62 return staticCache; |
51 } |
63 } |
52 |
64 |
53 Cache::Cache() |
65 Cache::Cache() |
54 : m_disabled(false) |
66 : m_disabled(false) |
59 , m_liveSize(0) |
71 , m_liveSize(0) |
60 , m_deadSize(0) |
72 , m_deadSize(0) |
61 { |
73 { |
62 } |
74 } |
63 |
75 |
64 static CachedResource* createResource(CachedResource::Type type, DocLoader* docLoader, const KURL& url, const String* charset, bool skipCanLoadCheck = false, bool sendResourceLoadCallbacks = true) |
76 static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset) |
65 { |
77 { |
66 switch (type) { |
78 switch (type) { |
67 case CachedResource::ImageResource: |
79 case CachedResource::ImageResource: |
68 // User agent images need to null check the docloader. No other resources need to. |
80 // User agent images need to null check the docloader. No other resources need to. |
69 return new CachedImage(docLoader, url.url(), true /* for cache */); |
81 return new CachedImage(url.url()); |
70 case CachedResource::CSSStyleSheet: |
82 case CachedResource::CSSStyleSheet: |
71 return new CachedCSSStyleSheet(docLoader, url.url(), *charset, skipCanLoadCheck, sendResourceLoadCallbacks); |
83 return new CachedCSSStyleSheet(url.url(), charset); |
72 case CachedResource::Script: |
84 case CachedResource::Script: |
73 return new CachedScript(docLoader, url.url(), *charset); |
85 return new CachedScript(url.url(), charset); |
74 #if ENABLE(XSLT) |
86 #if ENABLE(XSLT) |
75 case CachedResource::XSLStyleSheet: |
87 case CachedResource::XSLStyleSheet: |
76 return new CachedXSLStyleSheet(docLoader, url.url()); |
88 return new CachedXSLStyleSheet(url.url()); |
77 #endif |
89 #endif |
78 #if ENABLE(XBL) |
90 #if ENABLE(XBL) |
79 case CachedResource::XBLStyleSheet: |
91 case CachedResource::XBLStyleSheet: |
80 return new CachedXBLDocument(docLoader, url.url()); |
92 return new CachedXBLDocument(url.url()); |
81 #endif |
93 #endif |
82 default: |
94 default: |
83 break; |
95 break; |
84 } |
96 } |
85 |
97 |
86 return 0; |
98 return 0; |
87 } |
99 } |
88 |
100 |
89 #if PRELOAD_SCANNER_ENABLED |
101 #if PRELOAD_SCANNER_ENABLED |
90 CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String* charset, bool skipCanLoadCheck, bool sendResourceLoadCallbacks, bool isPreload) |
102 CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String& charset, bool isPreload) |
91 #else |
103 #else |
92 CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String* charset, bool skipCanLoadCheck, bool sendResourceLoadCallbacks) |
104 CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Type type, const KURL& url, const String& charset) |
93 #endif |
105 #endif |
94 { |
106 { |
95 // FIXME: Do we really need to special-case an empty URL? |
107 // FIXME: Do we really need to special-case an empty URL? |
96 // Would it be better to just go on with the cache code and let it fail later? |
108 // Would it be better to just go on with the cache code and let it fail later? |
97 if (url.isEmpty()) |
109 if (url.isEmpty()) |
103 if (resource) { |
115 if (resource) { |
104 #if PRELOAD_SCANNER_ENABLED |
116 #if PRELOAD_SCANNER_ENABLED |
105 if (isPreload && !resource->isPreloaded()) |
117 if (isPreload && !resource->isPreloaded()) |
106 return 0; |
118 return 0; |
107 #endif |
119 #endif |
108 if (!skipCanLoadCheck && FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(*resource, docLoader->doc())) { |
120 if (FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(*resource, docLoader->doc())) { |
109 Document* doc = docLoader->doc(); |
121 Document* doc = docLoader->doc(); |
110 if(doc) |
122 if(doc) |
111 FrameLoader::reportLocalLoadFailed(doc->page(), resource->url()); |
123 FrameLoader::reportLocalLoadFailed(doc->page(), resource->url()); |
112 |
124 |
113 return 0; |
125 return 0; |
114 } |
126 } |
115 } else { |
127 } else { |
116 if (!skipCanLoadCheck && FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(url, docLoader->doc())) { |
128 if (FrameLoader::restrictAccessToLocal() && !FrameLoader::canLoad(url, docLoader->doc())) { |
117 Document* doc = docLoader->doc(); |
129 Document* doc = docLoader->doc(); |
118 #if PRELOAD_SCANNER_ENABLED |
130 #if PRELOAD_SCANNER_ENABLED |
119 if(doc && !isPreload) |
131 if(doc && !isPreload) |
120 #else |
132 #else |
121 if(doc) |
133 if(doc) |
124 |
136 |
125 return 0; |
137 return 0; |
126 } |
138 } |
127 |
139 |
128 // The resource does not exist. Create it. |
140 // The resource does not exist. Create it. |
129 resource = createResource(type, docLoader, url, charset, skipCanLoadCheck, sendResourceLoadCallbacks); |
141 resource = createResource(type, url, charset); |
130 ASSERT(resource); |
142 ASSERT(resource); |
131 ASSERT(resource->inCache()); |
143 |
|
144 // Pretend the resource is in the cache, to prevent it from being deleted during the load() call. |
|
145 // FIXME: CachedResource should just use normal refcounting instead. |
|
146 resource->setInCache(true); |
|
147 resource->load(docLoader); |
|
148 |
132 if (!disabled()) { |
149 if (!disabled()) { |
133 m_resources.set(url.url(), resource); // The size will be added in later once the resource is loaded and calls back to us with the new size. |
150 m_resources.set(url.url(), resource); // The size will be added in later once the resource is loaded and calls back to us with the new size. |
134 |
151 |
135 // This will move the resource to the front of its LRU list and increase its access count. |
152 // This will move the resource to the front of its LRU list and increase its access count. |
136 resourceAccessed(resource); |
153 resourceAccessed(resource); |
159 #endif |
176 #endif |
160 |
177 |
161 return resource; |
178 return resource; |
162 } |
179 } |
163 |
180 |
|
181 CachedCSSStyleSheet* Cache::requestUserCSSStyleSheet(DocLoader* docLoader, const String& url, const String& charset) |
|
182 { |
|
183 if (CachedResource* existing = m_resources.get(url)) |
|
184 return existing->type() == CachedResource::CSSStyleSheet ? static_cast<CachedCSSStyleSheet*>(existing) : 0; |
|
185 |
|
186 CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(url, charset); |
|
187 |
|
188 // Pretend the resource is in the cache, to prevent it from being deleted during the load() call. |
|
189 // FIXME: CachedResource should just use normal refcounting instead. |
|
190 userSheet->setInCache(true); |
|
191 // Don't load incrementally, skip load checks, don't send resource load callbacks. |
|
192 userSheet->load(docLoader, false, true, false); |
|
193 if (!disabled()) |
|
194 m_resources.set(url, userSheet); |
|
195 else |
|
196 userSheet->setInCache(false); |
|
197 |
|
198 return userSheet; |
|
199 } |
|
200 |
164 CachedResource* Cache::resourceForURL(const String& url) |
201 CachedResource* Cache::resourceForURL(const String& url) |
165 { |
202 { |
166 return m_resources.get(url); |
203 return m_resources.get(url); |
167 } |
204 } |
168 |
205 |
300 resource->setInCache(false); |
337 resource->setInCache(false); |
301 |
338 |
302 // Remove from the appropriate LRU list. |
339 // Remove from the appropriate LRU list. |
303 removeFromLRUList(resource); |
340 removeFromLRUList(resource); |
304 removeFromLiveDecodedResourcesList(resource); |
341 removeFromLiveDecodedResourcesList(resource); |
|
342 removeFromLiveResourcesSize(resource); |
305 |
343 |
306 // Notify all doc loaders that might be observing this object still that it has been |
344 // Notify all doc loaders that might be observing this object still that it has been |
307 // extracted from the set of resources. |
345 // extracted from the set of resources. |
308 HashSet<DocLoader*>::iterator end = m_docLoaders.end(); |
346 HashSet<DocLoader*>::iterator end = m_docLoaders.end(); |
309 for (HashSet<DocLoader*>::iterator itr = m_docLoaders.begin(); itr != end; ++itr) |
347 for (HashSet<DocLoader*>::iterator itr = m_docLoaders.begin(); itr != end; ++itr) |