OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 | 103 |
104 // Compile a script without any caching or compile options. | 104 // Compile a script without any caching or compile options. |
105 v8::Local<v8::Script> compileWithoutOptions(V8CompileHistogram::Cacheability cac heability, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin o rigin) | 105 v8::Local<v8::Script> compileWithoutOptions(V8CompileHistogram::Cacheability cac heability, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin o rigin) |
106 { | 106 { |
107 V8CompileHistogram histogramScope(cacheability); | 107 V8CompileHistogram histogramScope(cacheability); |
108 v8::ScriptCompiler::Source source(code, origin); | 108 v8::ScriptCompiler::Source source(code, origin); |
109 return v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompiler::kNo CompileOptions); | 109 return v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompiler::kNo CompileOptions); |
110 } | 110 } |
111 | 111 |
112 // Compile a script, and consume a V8 cache that was generated previously. | 112 // Compile a script, and consume a V8 cache that was generated previously. |
113 v8::Local<v8::Script> compileAndConsumeCache(ScriptResource* resource, unsigned tag, v8::ScriptCompiler::CompileOptions compileOptions, bool compressed, v8::Iso late* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin origin) | 113 v8::Local<v8::Script> compileAndConsumeCache(CachedMetadataHandler* cacheHandler , unsigned tag, v8::ScriptCompiler::CompileOptions compileOptions, bool compress ed, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin origin) |
114 { | 114 { |
115 V8CompileHistogram histogramScope(V8CompileHistogram::Cacheable); | 115 V8CompileHistogram histogramScope(V8CompileHistogram::Cacheable); |
116 CachedMetadata* cachedMetadata = resource->cachedMetadata(tag); | 116 CachedMetadata* cachedMetadata = cacheHandler->cachedMetadata(tag); |
117 const char* data = cachedMetadata->data(); | 117 const char* data = cachedMetadata->data(); |
118 int length = cachedMetadata->size(); | 118 int length = cachedMetadata->size(); |
119 std::string uncompressedOutput; | 119 std::string uncompressedOutput; |
120 bool invalidCache = false; | 120 bool invalidCache = false; |
121 if (compressed) { | 121 if (compressed) { |
122 if (snappy::Uncompress(data, length, &uncompressedOutput)) { | 122 if (snappy::Uncompress(data, length, &uncompressedOutput)) { |
123 data = uncompressedOutput.data(); | 123 data = uncompressedOutput.data(); |
124 length = uncompressedOutput.length(); | 124 length = uncompressedOutput.length(); |
125 } else { | 125 } else { |
126 invalidCache = true; | 126 invalidCache = true; |
127 } | 127 } |
128 } | 128 } |
129 v8::Local<v8::Script> script; | 129 v8::Local<v8::Script> script; |
130 if (invalidCache) { | 130 if (invalidCache) { |
131 v8::ScriptCompiler::Source source(code, origin); | 131 v8::ScriptCompiler::Source source(code, origin); |
132 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions); | 132 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions); |
133 } else { | 133 } else { |
134 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::Cac hedData( | 134 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::Cac hedData( |
135 reinterpret_cast<const uint8_t*>(data), length, v8::ScriptCompiler:: CachedData::BufferNotOwned); | 135 reinterpret_cast<const uint8_t*>(data), length, v8::ScriptCompiler:: CachedData::BufferNotOwned); |
136 v8::ScriptCompiler::Source source(code, origin, cachedData); | 136 v8::ScriptCompiler::Source source(code, origin, cachedData); |
137 script = v8::ScriptCompiler::Compile(isolate, &source, compileOptions); | 137 script = v8::ScriptCompiler::Compile(isolate, &source, compileOptions); |
138 invalidCache = cachedData->rejected; | 138 invalidCache = cachedData->rejected; |
139 } | 139 } |
140 if (invalidCache) | 140 if (invalidCache) |
141 resource->clearCachedMetadata(Resource::SendToPlatform); | 141 cacheHandler->clearCachedMetadata(CachedMetadataHandler::SendToPlatform) ; |
142 return script; | 142 return script; |
143 } | 143 } |
144 | 144 |
145 // Compile a script, and produce a V8 cache for future use. | 145 // Compile a script, and produce a V8 cache for future use. |
146 v8::Local<v8::Script> compileAndProduceCache(ScriptResource* resource, unsigned tag, v8::ScriptCompiler::CompileOptions compileOptions, bool compressed, Resourc e::MetadataCacheType cacheType, v8::Isolate* isolate, v8::Handle<v8::String> cod e, v8::ScriptOrigin origin) | 146 v8::Local<v8::Script> compileAndProduceCache(CachedMetadataHandler* cacheHandler , unsigned tag, v8::ScriptCompiler::CompileOptions compileOptions, bool compress ed, CachedMetadataHandler::CacheType cacheType, v8::Isolate* isolate, v8::Handle <v8::String> code, v8::ScriptOrigin origin) |
147 { | 147 { |
148 V8CompileHistogram histogramScope(V8CompileHistogram::Cacheable); | 148 V8CompileHistogram histogramScope(V8CompileHistogram::Cacheable); |
149 v8::ScriptCompiler::Source source(code, origin); | 149 v8::ScriptCompiler::Source source(code, origin); |
150 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, compileOptions); | 150 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, compileOptions); |
151 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData(); | 151 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData(); |
152 if (cachedData) { | 152 if (cachedData) { |
153 const char* data = reinterpret_cast<const char*>(cachedData->data); | 153 const char* data = reinterpret_cast<const char*>(cachedData->data); |
154 int length = cachedData->length; | 154 int length = cachedData->length; |
155 std::string compressedOutput; | 155 std::string compressedOutput; |
156 if (compressed) { | 156 if (compressed) { |
157 snappy::Compress(data, length, &compressedOutput); | 157 snappy::Compress(data, length, &compressedOutput); |
158 data = compressedOutput.data(); | 158 data = compressedOutput.data(); |
159 length = compressedOutput.length(); | 159 length = compressedOutput.length(); |
160 } | 160 } |
161 if (length > 1024) { | 161 if (length > 1024) { |
162 // Omit histogram samples for small cache data to avoid outliers. | 162 // Omit histogram samples for small cache data to avoid outliers. |
163 int cacheSizeRatio = static_cast<int>(100.0 * length / code->Length( )); | 163 int cacheSizeRatio = static_cast<int>(100.0 * length / code->Length( )); |
164 blink::Platform::current()->histogramCustomCounts("V8.CodeCacheSizeR atio", cacheSizeRatio, 0, 10000, 50); | 164 blink::Platform::current()->histogramCustomCounts("V8.CodeCacheSizeR atio", cacheSizeRatio, 0, 10000, 50); |
165 } | 165 } |
166 resource->clearCachedMetadata(); | 166 cacheHandler->clearCachedMetadata(); |
167 resource->setCachedMetadata(tag, data, length, cacheType); | 167 cacheHandler->setCachedMetadata(tag, data, length, cacheType); |
168 } | 168 } |
169 return script; | 169 return script; |
170 } | 170 } |
171 | 171 |
172 // Compile a script, and consume or produce a V8 Cache, depending on whether the | 172 // Compile a script, and consume or produce a V8 Cache, depending on whether the |
173 // given resource already has cached data available. | 173 // given resource already has cached data available. |
174 v8::Local<v8::Script> compileAndConsumeOrProduce(ScriptResource* resource, unsig ned tag, v8::ScriptCompiler::CompileOptions consumeOptions, v8::ScriptCompiler:: CompileOptions produceOptions, bool compressed, Resource::MetadataCacheType cach eType, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin origi n) | 174 v8::Local<v8::Script> compileAndConsumeOrProduce(CachedMetadataHandler* cacheHan dler, unsigned tag, v8::ScriptCompiler::CompileOptions consumeOptions, v8::Scrip tCompiler::CompileOptions produceOptions, bool compressed, CachedMetadataHandler ::CacheType cacheType, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::Sc riptOrigin origin) |
175 { | 175 { |
176 return resource->cachedMetadata(tag) | 176 return cacheHandler->cachedMetadata(tag) |
177 ? compileAndConsumeCache(resource, tag, consumeOptions, compressed, isol ate, code, origin) | 177 ? compileAndConsumeCache(cacheHandler, tag, consumeOptions, compressed, isolate, code, origin) |
178 : compileAndProduceCache(resource, tag, produceOptions, compressed, cach eType, isolate, code, origin); | 178 : compileAndProduceCache(cacheHandler, tag, produceOptions, compressed, cacheType, isolate, code, origin); |
179 } | 179 } |
180 | 180 |
181 enum CacheTagKind { | 181 enum CacheTagKind { |
182 CacheTagParser = 0, | 182 CacheTagParser = 0, |
183 CacheTagCode = 1, | 183 CacheTagCode = 1, |
184 CacheTagCodeCompressed = 2, | 184 CacheTagCodeCompressed = 2, |
185 CacheTagTimeStamp = 3, | 185 CacheTagTimeStamp = 3, |
186 CacheTagLast | 186 CacheTagLast |
187 }; | 187 }; |
188 | 188 |
189 static const int kCacheTagKindSize = 2; | 189 static const int kCacheTagKindSize = 2; |
190 | 190 |
191 unsigned cacheTag(CacheTagKind kind, Resource* resource) | 191 unsigned cacheTag(CacheTagKind kind, CachedMetadataHandler* cacheHandler) |
192 { | 192 { |
193 static_assert((1 << kCacheTagKindSize) >= CacheTagLast, "CacheTagLast must b e large enough"); | 193 static_assert((1 << kCacheTagKindSize) >= CacheTagLast, "CacheTagLast must b e large enough"); |
194 | 194 |
195 static unsigned v8CacheDataVersion = v8::ScriptCompiler::CachedDataVersionTa g() << kCacheTagKindSize; | 195 static unsigned v8CacheDataVersion = v8::ScriptCompiler::CachedDataVersionTa g() << kCacheTagKindSize; |
196 | 196 |
197 // A script can be (successfully) interpreted with different encodings, | 197 // A script can be (successfully) interpreted with different encodings, |
198 // depending on the page it appears in. The cache doesn't know anything | 198 // depending on the page it appears in. The cache doesn't know anything |
199 // about encodings, but the cached data is specific to one encoding. If we | 199 // about encodings, but the cached data is specific to one encoding. If we |
200 // later load the script from the cache and interpret it with a different | 200 // later load the script from the cache and interpret it with a different |
201 // encoding, the cached data is not valid for that encoding. | 201 // encoding, the cached data is not valid for that encoding. |
202 return (v8CacheDataVersion | kind) + StringHash::hash(resource->encoding()); | 202 return (v8CacheDataVersion | kind) + StringHash::hash(cacheHandler->encoding ()); |
203 } | 203 } |
204 | 204 |
205 // Store a timestamp to the cache as hint. | 205 // Store a timestamp to the cache as hint. |
206 void setCacheTimeStamp(ScriptResource* resource) | 206 void setCacheTimeStamp(CachedMetadataHandler* cacheHandler) |
207 { | 207 { |
208 double now = WTF::currentTime(); | 208 double now = WTF::currentTime(); |
209 unsigned tag = cacheTag(CacheTagTimeStamp, resource); | 209 unsigned tag = cacheTag(CacheTagTimeStamp, cacheHandler); |
210 resource->setCachedMetadata(tag, reinterpret_cast<char*>(&now), sizeof(now), Resource::SendToPlatform); | 210 cacheHandler->setCachedMetadata(tag, reinterpret_cast<char*>(&now), sizeof(n ow), CachedMetadataHandler::SendToPlatform); |
211 } | 211 } |
212 | 212 |
213 // Check previously stored timestamp. | 213 // Check previously stored timestamp. |
214 bool isResourceHotForCaching(ScriptResource* resource, int hotHours) | 214 bool isResourceHotForCaching(CachedMetadataHandler* cacheHandler, int hotHours) |
215 { | 215 { |
216 const double kCacheWithinSeconds = hotHours * 60 * 60; | 216 const double kCacheWithinSeconds = hotHours * 60 * 60; |
217 unsigned tag = cacheTag(CacheTagTimeStamp, resource); | 217 unsigned tag = cacheTag(CacheTagTimeStamp, cacheHandler); |
218 CachedMetadata* cachedMetadata = resource->cachedMetadata(tag); | 218 CachedMetadata* cachedMetadata = cacheHandler->cachedMetadata(tag); |
219 if (!cachedMetadata) | 219 if (!cachedMetadata) |
220 return false; | 220 return false; |
221 double timeStamp; | 221 double timeStamp; |
222 const int size = sizeof(timeStamp); | 222 const int size = sizeof(timeStamp); |
223 ASSERT(cachedMetadata->size() == size); | 223 ASSERT(cachedMetadata->size() == size); |
224 memcpy(&timeStamp, cachedMetadata->data(), size); | 224 memcpy(&timeStamp, cachedMetadata->data(), size); |
225 return (WTF::currentTime() - timeStamp) < kCacheWithinSeconds; | 225 return (WTF::currentTime() - timeStamp) < kCacheWithinSeconds; |
226 } | 226 } |
227 | 227 |
228 // Final compile call for a streamed compilation. Most decisions have already | 228 // Final compile call for a streamed compilation. Most decisions have already |
229 // been made, but we need to write back data into the cache. | 229 // been made, but we need to write back data into the cache. |
230 v8::Local<v8::Script> postStreamCompile(ScriptResource* resource, ScriptStreamer * streamer, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin origin) | 230 v8::Local<v8::Script> postStreamCompile(CachedMetadataHandler* cacheHandler, Scr iptStreamer* streamer, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::Sc riptOrigin origin) |
231 { | 231 { |
232 V8CompileHistogram histogramScope(V8CompileHistogram::Noncacheable); | 232 V8CompileHistogram histogramScope(V8CompileHistogram::Noncacheable); |
233 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, streamer ->source(), code, origin); | 233 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, streamer ->source(), code, origin); |
234 | 234 |
235 // Whether to produce the cached data or not is decided when the | 235 // Whether to produce the cached data or not is decided when the |
236 // streamer is started. Here we only need to get the data out. | 236 // streamer is started. Here we only need to get the data out. |
237 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source()->Ge tCachedData(); | 237 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source()->Ge tCachedData(); |
238 if (newCachedData) { | 238 if (newCachedData) { |
239 resource->clearCachedMetadata(); | 239 cacheHandler->clearCachedMetadata(); |
240 v8::ScriptCompiler::CompileOptions options = streamer->compileOptions(); | 240 v8::ScriptCompiler::CompileOptions options = streamer->compileOptions(); |
241 switch (options) { | 241 switch (options) { |
242 case v8::ScriptCompiler::kProduceParserCache: | 242 case v8::ScriptCompiler::kProduceParserCache: |
243 resource->setCachedMetadata(cacheTag(CacheTagParser, resource), rein terpret_cast<const char*>(newCachedData->data), newCachedData->length, Resource: :CacheLocally); | 243 cacheHandler->setCachedMetadata(cacheTag(CacheTagParser, cacheHandle r), reinterpret_cast<const char*>(newCachedData->data), newCachedData->length, C achedMetadataHandler::CacheLocally); |
244 break; | 244 break; |
245 case v8::ScriptCompiler::kProduceCodeCache: | 245 case v8::ScriptCompiler::kProduceCodeCache: |
246 resource->setCachedMetadata(cacheTag(CacheTagCode, resource), reinte rpret_cast<const char*>(newCachedData->data), newCachedData->length, Resource::S endToPlatform); | 246 cacheHandler->setCachedMetadata(cacheTag(CacheTagCode, cacheHandler) , reinterpret_cast<const char*>(newCachedData->data), newCachedData->length, Cac hedMetadataHandler::SendToPlatform); |
247 break; | 247 break; |
248 default: | 248 default: |
249 break; | 249 break; |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 return script; | 253 return script; |
254 } | 254 } |
255 | 255 |
256 typedef Function<v8::Local<v8::Script>(v8::Isolate*, v8::Handle<v8::String>, v8: :ScriptOrigin)> CompileFn; | 256 typedef Function<v8::Local<v8::Script>(v8::Isolate*, v8::Handle<v8::String>, v8: :ScriptOrigin)> CompileFn; |
257 | 257 |
258 // A notation convenience: WTF::bind<...> needs to be given the right argument | 258 // A notation convenience: WTF::bind<...> needs to be given the right argument |
259 // types. We have an awful lot of bind calls below, all with the same types, so | 259 // types. We have an awful lot of bind calls below, all with the same types, so |
260 // this local bind lets WTF::bind to all the work, but 'knows' the right | 260 // this local bind lets WTF::bind to all the work, but 'knows' the right |
261 // parameter types. | 261 // parameter types. |
262 // This version isn't quite as smart as the real WTF::bind, though, so you | 262 // This version isn't quite as smart as the real WTF::bind, though, so you |
263 // sometimes may still have to call the original. | 263 // sometimes may still have to call the original. |
264 template<typename... A> | 264 template<typename... A> |
265 PassOwnPtr<CompileFn> bind(const A&... args) | 265 PassOwnPtr<CompileFn> bind(const A&... args) |
266 { | 266 { |
267 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(arg s...); | 267 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(arg s...); |
268 } | 268 } |
269 | 269 |
270 // Select a compile function from any of the above, mainly depending on | 270 // Select a compile function from any of the above, mainly depending on |
271 // cacheOptions. | 271 // cacheOptions. |
272 PassOwnPtr<CompileFn> selectCompileFunction(V8CacheOptions cacheOptions, ScriptR esource* resource, v8::Handle<v8::String> code) | 272 PassOwnPtr<CompileFn> selectCompileFunction(V8CacheOptions cacheOptions, ScriptR esource* resource, CachedMetadataHandler* cacheHandler, v8::Handle<v8::String> c ode) |
273 { | 273 { |
274 static const int minimalCodeLength = 1024; | 274 static const int minimalCodeLength = 1024; |
275 | 275 |
276 if (!resource || !resource->url().protocolIsInHTTPFamily()) | 276 if ((resource && !resource->url().protocolIsInHTTPFamily()) || (!resource && !cacheHandler)) |
vogelheim
2015/02/16 13:12:04
Hmm.. I find this odd. Below, all usages of resour
horo
2015/02/16 16:20:11
I agree.
I changed Resource.cacheHandler() to retu
| |
277 // Caching is not available in this case. | 277 // Caching is not available in this case. |
278 return bind(compileWithoutOptions, V8CompileHistogram::Noncacheable); | 278 return bind(compileWithoutOptions, V8CompileHistogram::Noncacheable); |
279 | 279 |
kinuko
2015/02/16 14:18:38
It looks it's possible to reach here when cacheHan
horo
2015/02/16 16:20:11
Done.
| |
280 if (cacheOptions == V8CacheOptionsNone) | 280 if (cacheOptions == V8CacheOptionsNone) |
281 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 281 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
282 | 282 |
283 // The cacheOptions will guide our strategy: | 283 // The cacheOptions will guide our strategy: |
284 // FIXME: Clean up code caching options. crbug.com/455187. | 284 // FIXME: Clean up code caching options. crbug.com/455187. |
285 switch (cacheOptions) { | 285 switch (cacheOptions) { |
286 case V8CacheOptionsDefault: | 286 case V8CacheOptionsDefault: |
287 case V8CacheOptionsParseMemory: | 287 case V8CacheOptionsParseMemory: |
288 if (code->Length() < minimalCodeLength) { | 288 if (code->Length() < minimalCodeLength) { |
289 // Do not cache for small scripts, though caching is available. | 289 // Do not cache for small scripts, though caching is available. |
290 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 290 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
291 } | 291 } |
292 // Use parser-cache; in-memory only. | 292 // Use parser-cache; in-memory only. |
293 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::CacheLocally); | 293 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagP arser, cacheHandler), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompile r::kProduceParserCache, false, CachedMetadataHandler::CacheLocally); |
294 break; | 294 break; |
295 | 295 |
296 case V8CacheOptionsParse: | 296 case V8CacheOptionsParse: |
297 // Use parser-cache. | 297 // Use parser-cache. |
298 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::SendToPlatform); | 298 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagP arser, cacheHandler), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompile r::kProduceParserCache, false, CachedMetadataHandler::SendToPlatform); |
299 break; | 299 break; |
300 | 300 |
301 case V8CacheOptionsHeuristicsDefault: | 301 case V8CacheOptionsHeuristicsDefault: |
302 case V8CacheOptionsCode: | 302 case V8CacheOptionsCode: |
303 // Always use code caching. | 303 // Always use code caching. |
304 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCode, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::kProduceC odeCache, false, Resource::SendToPlatform); | 304 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagC ode, cacheHandler), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::k ProduceCodeCache, false, CachedMetadataHandler::SendToPlatform); |
305 break; | 305 break; |
306 | 306 |
307 case V8CacheOptionsHeuristicsDefaultMobile: | 307 case V8CacheOptionsHeuristicsDefaultMobile: |
308 case V8CacheOptionsCodeCompressed: | 308 case V8CacheOptionsCodeCompressed: |
309 // Always use code caching. Compress depending on cacheOptions. | 309 // Always use code caching. Compress depending on cacheOptions. |
310 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCodeC ompressed, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler: :kProduceCodeCache, true, Resource::SendToPlatform); | 310 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagC odeCompressed, cacheHandler), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptC ompiler::kProduceCodeCache, true, CachedMetadataHandler::SendToPlatform); |
311 break; | 311 break; |
312 | 312 |
313 case V8CacheOptionsHeuristics: | 313 case V8CacheOptionsHeuristics: |
314 case V8CacheOptionsHeuristicsMobile: | 314 case V8CacheOptionsHeuristicsMobile: |
315 case V8CacheOptionsRecent: | 315 case V8CacheOptionsRecent: |
316 case V8CacheOptionsRecentSmall: { | 316 case V8CacheOptionsRecentSmall: { |
317 bool compress = (cacheOptions == V8CacheOptionsRecentSmall || cacheOptio ns == V8CacheOptionsHeuristicsMobile); | 317 bool compress = (cacheOptions == V8CacheOptionsRecentSmall || cacheOptio ns == V8CacheOptionsHeuristicsMobile); |
318 unsigned codeCacheTag = cacheTag(compress ? CacheTagCodeCompressed : Cac heTagCode, resource); | 318 unsigned codeCacheTag = cacheTag(compress ? CacheTagCodeCompressed : Cac heTagCode, cacheHandler); |
319 CachedMetadata* codeCache = resource->cachedMetadata(codeCacheTag); | 319 CachedMetadata* codeCache = cacheHandler->cachedMetadata(codeCacheTag); |
320 if (codeCache) | 320 if (codeCache) |
321 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, compress); | 321 return bind(compileAndConsumeCache, cacheHandler, codeCacheTag, v8:: ScriptCompiler::kConsumeCodeCache, compress); |
322 int hotHours = (cacheOptions == V8CacheOptionsRecent || cacheOptions == V8CacheOptionsRecentSmall) ? 36 : 72; | 322 int hotHours = (cacheOptions == V8CacheOptionsRecent || cacheOptions == V8CacheOptionsRecentSmall) ? 36 : 72; |
323 if (!isResourceHotForCaching(resource, hotHours)) { | 323 if (!isResourceHotForCaching(cacheHandler, hotHours)) { |
324 setCacheTimeStamp(resource); | 324 setCacheTimeStamp(cacheHandler); |
325 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 325 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
326 } | 326 } |
327 return bind(compileAndProduceCache, resource, codeCacheTag, v8::ScriptCo mpiler::kProduceCodeCache, compress, Resource::SendToPlatform); | 327 return bind(compileAndProduceCache, cacheHandler, codeCacheTag, v8::Scri ptCompiler::kProduceCodeCache, compress, CachedMetadataHandler::SendToPlatform); |
328 break; | 328 break; |
329 } | 329 } |
330 | 330 |
331 case V8CacheOptionsNone: | 331 case V8CacheOptionsNone: |
332 // Shouldn't happen, as this is handled above. | 332 // Shouldn't happen, as this is handled above. |
333 // Case is here so that compiler can check all cases are handled. | 333 // Case is here so that compiler can check all cases are handled. |
334 ASSERT_NOT_REACHED(); | 334 ASSERT_NOT_REACHED(); |
335 break; | 335 break; |
336 } | 336 } |
337 | 337 |
338 // All switch branches should return and we should never get here. | 338 // All switch branches should return and we should never get here. |
339 // But some compilers aren't sure, hence this default. | 339 // But some compilers aren't sure, hence this default. |
340 ASSERT_NOT_REACHED(); | 340 ASSERT_NOT_REACHED(); |
341 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 341 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
342 } | 342 } |
343 | 343 |
344 // Select a compile function for a streaming compile. | 344 // Select a compile function for a streaming compile. |
345 PassOwnPtr<CompileFn> selectCompileFunction(ScriptResource* resource, ScriptStre amer* streamer) | 345 PassOwnPtr<CompileFn> selectCompileFunction(ScriptResource* resource, ScriptStre amer* streamer) |
346 { | 346 { |
347 // We don't stream scripts which don't have a Resource. | 347 // We don't stream scripts which don't have a Resource. |
348 ASSERT(resource); | 348 ASSERT(resource); |
349 // Failed resources should never get this far. | 349 // Failed resources should never get this far. |
350 ASSERT(!resource->errorOccurred()); | 350 ASSERT(!resource->errorOccurred()); |
351 ASSERT(streamer->isFinished()); | 351 ASSERT(streamer->isFinished()); |
352 ASSERT(!streamer->streamingSuppressed()); | 352 ASSERT(!streamer->streamingSuppressed()); |
353 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(pos tStreamCompile, resource, streamer); | 353 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(pos tStreamCompile, resource->cacheHandler(), streamer); |
354 } | 354 } |
355 } // namespace | 355 } // namespace |
356 | 356 |
357 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) | 357 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) |
358 { | 358 { |
359 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions); | 359 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), isolate, source.resource(), source.streamer(), nullptr, corsS tatus, cacheOptions); |
360 } | 360 } |
361 | 361 |
362 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, ScriptStreamer* streamer, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOptions, bool isInternalScript) | 362 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, v8::Isolate* i solate, ScriptResource* resource, ScriptStreamer* streamer, CachedMetadataHandle r* cacheHandler, AccessControlStatus corsStatus, V8CacheOptions cacheOptions, bo ol isInternalScript) |
363 { | 363 { |
364 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); | 364 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); |
365 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); | 365 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); |
366 | 366 |
367 if (!cacheHandler && resource) | |
368 cacheHandler = resource->cacheHandler(); | |
369 | |
367 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at | 370 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at |
368 // 1, whereas v8 starts at 0. | 371 // 1, whereas v8 starts at 0. |
369 v8::ScriptOrigin origin( | 372 v8::ScriptOrigin origin( |
370 v8String(isolate, fileName), | 373 v8String(isolate, fileName), |
371 v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()), | 374 v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()), |
372 v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()), | 375 v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()), |
373 v8Boolean(corsStatus == SharableCrossOrigin, isolate), | 376 v8Boolean(corsStatus == SharableCrossOrigin, isolate), |
374 v8::Handle<v8::Integer>(), | 377 v8::Handle<v8::Integer>(), |
375 v8Boolean(isInternalScript, isolate)); | 378 v8Boolean(isInternalScript, isolate)); |
376 | 379 |
377 OwnPtr<CompileFn> compileFn = streamer | 380 OwnPtr<CompileFn> compileFn = streamer |
378 ? selectCompileFunction(resource, streamer) | 381 ? selectCompileFunction(resource, streamer) |
379 : selectCompileFunction(cacheOptions, resource, code); | 382 : selectCompileFunction(cacheOptions, resource, cacheHandler, code); |
380 | 383 |
381 return (*compileFn)(isolate, code, origin); | 384 return (*compileFn)(isolate, code, origin); |
382 } | 385 } |
383 | 386 |
384 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) | 387 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) |
385 { | 388 { |
386 if (script.IsEmpty()) | 389 if (script.IsEmpty()) |
387 return v8::Local<v8::Value>(); | 390 return v8::Local<v8::Value>(); |
388 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 391 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
389 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); | 392 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); |
(...skipping 14 matching lines...) Expand all Loading... | |
404 | 407 |
405 if (result.IsEmpty()) | 408 if (result.IsEmpty()) |
406 return v8::Local<v8::Value>(); | 409 return v8::Local<v8::Value>(); |
407 | 410 |
408 crashIfV8IsDead(); | 411 crashIfV8IsDead(); |
409 return result; | 412 return result; |
410 } | 413 } |
411 | 414 |
412 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition) | 415 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition) |
413 { | 416 { |
414 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, 0, 0, isolate, SharableCrossOrigin, V8CacheOptionsDefau lt, true); | 417 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, isolate, nullptr, nullptr, nullptr, SharableCrossOrigin , V8CacheOptionsDefault, true); |
415 if (script.IsEmpty()) | 418 if (script.IsEmpty()) |
416 return v8::Local<v8::Value>(); | 419 return v8::Local<v8::Value>(); |
417 | 420 |
418 TRACE_EVENT0("v8", "v8.run"); | 421 TRACE_EVENT0("v8", "v8.run"); |
419 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 422 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
420 V8RecursionScope::MicrotaskSuppression recursionScope(isolate); | 423 V8RecursionScope::MicrotaskSuppression recursionScope(isolate); |
421 v8::Local<v8::Value> result = script->Run(); | 424 v8::Local<v8::Value> result = script->Run(); |
422 crashIfV8IsDead(); | 425 crashIfV8IsDead(); |
423 return result; | 426 return result; |
424 } | 427 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
501 if (ScriptForbiddenScope::isScriptForbidden()) | 504 if (ScriptForbiddenScope::isScriptForbidden()) |
502 return v8::Local<v8::Object>(); | 505 return v8::Local<v8::Object>(); |
503 V8RecursionScope scope(isolate); | 506 V8RecursionScope scope(isolate); |
504 v8::Local<v8::Object> result = function->NewInstance(argc, argv); | 507 v8::Local<v8::Object> result = function->NewInstance(argc, argv); |
505 crashIfV8IsDead(); | 508 crashIfV8IsDead(); |
506 return result; | 509 return result; |
507 } | 510 } |
508 | 511 |
509 unsigned V8ScriptRunner::tagForParserCache(Resource* resource) | 512 unsigned V8ScriptRunner::tagForParserCache(Resource* resource) |
510 { | 513 { |
511 return cacheTag(CacheTagParser, resource); | 514 return cacheTag(CacheTagParser, resource->cacheHandler()); |
512 } | 515 } |
513 | 516 |
514 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) | 517 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) |
515 { | 518 { |
516 return cacheTag(CacheTagCode, resource); | 519 return cacheTag(CacheTagCode, resource->cacheHandler()); |
517 } | 520 } |
518 | 521 |
519 } // namespace blink | 522 } // namespace blink |
OLD | NEW |