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 if (!cacheHandler) | |
236 return script; | |
237 | |
235 // Whether to produce the cached data or not is decided when the | 238 // 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. | 239 // streamer is started. Here we only need to get the data out. |
237 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source()->Ge tCachedData(); | 240 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source()->Ge tCachedData(); |
238 if (newCachedData) { | 241 if (newCachedData) { |
239 resource->clearCachedMetadata(); | 242 cacheHandler->clearCachedMetadata(); |
240 v8::ScriptCompiler::CompileOptions options = streamer->compileOptions(); | 243 v8::ScriptCompiler::CompileOptions options = streamer->compileOptions(); |
241 switch (options) { | 244 switch (options) { |
242 case v8::ScriptCompiler::kProduceParserCache: | 245 case v8::ScriptCompiler::kProduceParserCache: |
243 resource->setCachedMetadata(cacheTag(CacheTagParser, resource), rein terpret_cast<const char*>(newCachedData->data), newCachedData->length, Resource: :CacheLocally); | 246 cacheHandler->setCachedMetadata(cacheTag(CacheTagParser, cacheHandle r), reinterpret_cast<const char*>(newCachedData->data), newCachedData->length, C achedMetadataHandler::CacheLocally); |
244 break; | 247 break; |
245 case v8::ScriptCompiler::kProduceCodeCache: | 248 case v8::ScriptCompiler::kProduceCodeCache: |
246 resource->setCachedMetadata(cacheTag(CacheTagCode, resource), reinte rpret_cast<const char*>(newCachedData->data), newCachedData->length, Resource::S endToPlatform); | 249 cacheHandler->setCachedMetadata(cacheTag(CacheTagCode, cacheHandler) , reinterpret_cast<const char*>(newCachedData->data), newCachedData->length, Cac hedMetadataHandler::SendToPlatform); |
247 break; | 250 break; |
248 default: | 251 default: |
249 break; | 252 break; |
250 } | 253 } |
251 } | 254 } |
252 | 255 |
253 return script; | 256 return script; |
254 } | 257 } |
255 | 258 |
256 typedef Function<v8::Local<v8::Script>(v8::Isolate*, v8::Handle<v8::String>, v8: :ScriptOrigin)> CompileFn; | 259 typedef Function<v8::Local<v8::Script>(v8::Isolate*, v8::Handle<v8::String>, v8: :ScriptOrigin)> CompileFn; |
257 | 260 |
258 // A notation convenience: WTF::bind<...> needs to be given the right argument | 261 // 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 | 262 // 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 | 263 // this local bind lets WTF::bind to all the work, but 'knows' the right |
261 // parameter types. | 264 // parameter types. |
262 // This version isn't quite as smart as the real WTF::bind, though, so you | 265 // This version isn't quite as smart as the real WTF::bind, though, so you |
263 // sometimes may still have to call the original. | 266 // sometimes may still have to call the original. |
264 template<typename... A> | 267 template<typename... A> |
265 PassOwnPtr<CompileFn> bind(const A&... args) | 268 PassOwnPtr<CompileFn> bind(const A&... args) |
266 { | 269 { |
267 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(arg s...); | 270 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(arg s...); |
268 } | 271 } |
269 | 272 |
270 // Select a compile function from any of the above, mainly depending on | 273 // Select a compile function from any of the above, mainly depending on |
271 // cacheOptions. | 274 // cacheOptions. |
272 PassOwnPtr<CompileFn> selectCompileFunction(V8CacheOptions cacheOptions, ScriptR esource* resource, v8::Handle<v8::String> code) | 275 PassOwnPtr<CompileFn> selectCompileFunction(V8CacheOptions cacheOptions, CachedM etadataHandler* cacheHandler, v8::Handle<v8::String> code) |
273 { | 276 { |
274 static const int minimalCodeLength = 1024; | 277 static const int minimalCodeLength = 1024; |
275 | 278 |
276 if (!resource || !resource->url().protocolIsInHTTPFamily()) | 279 if (!cacheHandler) |
277 // Caching is not available in this case. | 280 // Caching is not available in this case. |
278 return bind(compileWithoutOptions, V8CompileHistogram::Noncacheable); | 281 return bind(compileWithoutOptions, V8CompileHistogram::Noncacheable); |
279 | 282 |
280 if (cacheOptions == V8CacheOptionsNone) | 283 if (cacheOptions == V8CacheOptionsNone) |
281 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 284 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
282 | 285 |
283 // The cacheOptions will guide our strategy: | 286 // The cacheOptions will guide our strategy: |
284 // FIXME: Clean up code caching options. crbug.com/455187. | 287 // FIXME: Clean up code caching options. crbug.com/455187. |
285 switch (cacheOptions) { | 288 switch (cacheOptions) { |
286 case V8CacheOptionsDefault: | 289 case V8CacheOptionsDefault: |
287 case V8CacheOptionsParseMemory: | 290 case V8CacheOptionsParseMemory: |
288 if (code->Length() < minimalCodeLength) { | 291 if (code->Length() < minimalCodeLength) { |
289 // Do not cache for small scripts, though caching is available. | 292 // Do not cache for small scripts, though caching is available. |
290 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 293 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
291 } | 294 } |
292 // Use parser-cache; in-memory only. | 295 // 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); | 296 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagP arser, cacheHandler), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompile r::kProduceParserCache, false, CachedMetadataHandler::CacheLocally); |
294 break; | 297 break; |
295 | 298 |
296 case V8CacheOptionsParse: | 299 case V8CacheOptionsParse: |
297 // Use parser-cache. | 300 // Use parser-cache. |
298 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::SendToPlatform); | 301 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagP arser, cacheHandler), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompile r::kProduceParserCache, false, CachedMetadataHandler::SendToPlatform); |
299 break; | 302 break; |
300 | 303 |
301 case V8CacheOptionsHeuristicsDefault: | 304 case V8CacheOptionsHeuristicsDefault: |
302 case V8CacheOptionsCode: | 305 case V8CacheOptionsCode: |
303 // Always use code caching. | 306 // Always use code caching. |
304 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCode, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::kProduceC odeCache, false, Resource::SendToPlatform); | 307 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagC ode, cacheHandler), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::k ProduceCodeCache, false, CachedMetadataHandler::SendToPlatform); |
305 break; | 308 break; |
306 | 309 |
307 case V8CacheOptionsHeuristicsDefaultMobile: | 310 case V8CacheOptionsHeuristicsDefaultMobile: |
308 case V8CacheOptionsCodeCompressed: | 311 case V8CacheOptionsCodeCompressed: |
309 // Always use code caching. Compress depending on cacheOptions. | 312 // 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); | 313 return bind(compileAndConsumeOrProduce, cacheHandler, cacheTag(CacheTagC odeCompressed, cacheHandler), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptC ompiler::kProduceCodeCache, true, CachedMetadataHandler::SendToPlatform); |
311 break; | 314 break; |
312 | 315 |
313 case V8CacheOptionsHeuristics: | 316 case V8CacheOptionsHeuristics: |
314 case V8CacheOptionsHeuristicsMobile: | 317 case V8CacheOptionsHeuristicsMobile: |
315 case V8CacheOptionsRecent: | 318 case V8CacheOptionsRecent: |
316 case V8CacheOptionsRecentSmall: { | 319 case V8CacheOptionsRecentSmall: { |
317 bool compress = (cacheOptions == V8CacheOptionsRecentSmall || cacheOptio ns == V8CacheOptionsHeuristicsMobile); | 320 bool compress = (cacheOptions == V8CacheOptionsRecentSmall || cacheOptio ns == V8CacheOptionsHeuristicsMobile); |
318 unsigned codeCacheTag = cacheTag(compress ? CacheTagCodeCompressed : Cac heTagCode, resource); | 321 unsigned codeCacheTag = cacheTag(compress ? CacheTagCodeCompressed : Cac heTagCode, cacheHandler); |
319 CachedMetadata* codeCache = resource->cachedMetadata(codeCacheTag); | 322 CachedMetadata* codeCache = cacheHandler->cachedMetadata(codeCacheTag); |
320 if (codeCache) | 323 if (codeCache) |
321 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, compress); | 324 return bind(compileAndConsumeCache, cacheHandler, codeCacheTag, v8:: ScriptCompiler::kConsumeCodeCache, compress); |
322 int hotHours = (cacheOptions == V8CacheOptionsRecent || cacheOptions == V8CacheOptionsRecentSmall) ? 36 : 72; | 325 int hotHours = (cacheOptions == V8CacheOptionsRecent || cacheOptions == V8CacheOptionsRecentSmall) ? 36 : 72; |
323 if (!isResourceHotForCaching(resource, hotHours)) { | 326 if (!isResourceHotForCaching(cacheHandler, hotHours)) { |
324 setCacheTimeStamp(resource); | 327 setCacheTimeStamp(cacheHandler); |
325 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 328 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
326 } | 329 } |
327 return bind(compileAndProduceCache, resource, codeCacheTag, v8::ScriptCo mpiler::kProduceCodeCache, compress, Resource::SendToPlatform); | 330 return bind(compileAndProduceCache, cacheHandler, codeCacheTag, v8::Scri ptCompiler::kProduceCodeCache, compress, CachedMetadataHandler::SendToPlatform); |
328 break; | 331 break; |
329 } | 332 } |
330 | 333 |
331 case V8CacheOptionsNone: | 334 case V8CacheOptionsNone: |
332 // Shouldn't happen, as this is handled above. | 335 // Shouldn't happen, as this is handled above. |
333 // Case is here so that compiler can check all cases are handled. | 336 // Case is here so that compiler can check all cases are handled. |
334 ASSERT_NOT_REACHED(); | 337 ASSERT_NOT_REACHED(); |
335 break; | 338 break; |
336 } | 339 } |
337 | 340 |
338 // All switch branches should return and we should never get here. | 341 // All switch branches should return and we should never get here. |
339 // But some compilers aren't sure, hence this default. | 342 // But some compilers aren't sure, hence this default. |
340 ASSERT_NOT_REACHED(); | 343 ASSERT_NOT_REACHED(); |
341 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); | 344 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); |
342 } | 345 } |
343 | 346 |
344 // Select a compile function for a streaming compile. | 347 // Select a compile function for a streaming compile. |
345 PassOwnPtr<CompileFn> selectCompileFunction(ScriptResource* resource, ScriptStre amer* streamer) | 348 PassOwnPtr<CompileFn> selectCompileFunction(ScriptResource* resource, ScriptStre amer* streamer) |
346 { | 349 { |
347 // We don't stream scripts which don't have a Resource. | 350 // We don't stream scripts which don't have a Resource. |
348 ASSERT(resource); | 351 ASSERT(resource); |
349 // Failed resources should never get this far. | 352 // Failed resources should never get this far. |
350 ASSERT(!resource->errorOccurred()); | 353 ASSERT(!resource->errorOccurred()); |
351 ASSERT(streamer->isFinished()); | 354 ASSERT(streamer->isFinished()); |
352 ASSERT(!streamer->streamingSuppressed()); | 355 ASSERT(!streamer->streamingSuppressed()); |
353 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(pos tStreamCompile, resource, streamer); | 356 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(pos tStreamCompile, resource->cacheHandler(), streamer); |
354 } | 357 } |
355 } // namespace | 358 } // namespace |
356 | 359 |
357 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) | 360 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) |
358 { | 361 { |
359 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions); | 362 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), isolate, source.resource(), source.streamer(), source.resourc e() ? source.resource()->cacheHandler() : nullptr, corsStatus, cacheOptions); |
360 } | 363 } |
361 | 364 |
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) | 365 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 { | 366 { |
364 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); | 367 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); |
365 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); | 368 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); |
369 // When streamer is set, resource must be set. | |
marja
2015/02/17 12:45:59
This comment is unnecessary though :)
horo
2015/02/17 12:53:42
Done.
| |
370 ASSERT(!streamer || resource); | |
marja
2015/02/17 12:45:59
I'd add here an ASSERT which says the if there is
horo
2015/02/17 12:53:43
Done.
| |
366 | 371 |
367 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at | 372 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at |
368 // 1, whereas v8 starts at 0. | 373 // 1, whereas v8 starts at 0. |
369 v8::ScriptOrigin origin( | 374 v8::ScriptOrigin origin( |
370 v8String(isolate, fileName), | 375 v8String(isolate, fileName), |
371 v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()), | 376 v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()), |
372 v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()), | 377 v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()), |
373 v8Boolean(corsStatus == SharableCrossOrigin, isolate), | 378 v8Boolean(corsStatus == SharableCrossOrigin, isolate), |
374 v8::Handle<v8::Integer>(), | 379 v8::Handle<v8::Integer>(), |
375 v8Boolean(isInternalScript, isolate)); | 380 v8Boolean(isInternalScript, isolate)); |
376 | 381 |
377 OwnPtr<CompileFn> compileFn = streamer | 382 OwnPtr<CompileFn> compileFn = streamer |
378 ? selectCompileFunction(resource, streamer) | 383 ? selectCompileFunction(resource, streamer) |
379 : selectCompileFunction(cacheOptions, resource, code); | 384 : selectCompileFunction(cacheOptions, cacheHandler, code); |
380 | 385 |
381 return (*compileFn)(isolate, code, origin); | 386 return (*compileFn)(isolate, code, origin); |
382 } | 387 } |
383 | 388 |
384 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) | 389 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) |
385 { | 390 { |
386 if (script.IsEmpty()) | 391 if (script.IsEmpty()) |
387 return v8::Local<v8::Value>(); | 392 return v8::Local<v8::Value>(); |
388 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 393 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
389 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); | 394 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); |
(...skipping 14 matching lines...) Expand all Loading... | |
404 | 409 |
405 if (result.IsEmpty()) | 410 if (result.IsEmpty()) |
406 return v8::Local<v8::Value>(); | 411 return v8::Local<v8::Value>(); |
407 | 412 |
408 crashIfV8IsDead(); | 413 crashIfV8IsDead(); |
409 return result; | 414 return result; |
410 } | 415 } |
411 | 416 |
412 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition) | 417 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition) |
413 { | 418 { |
414 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, 0, 0, isolate, SharableCrossOrigin, V8CacheOptionsDefau lt, true); | 419 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, isolate, nullptr, nullptr, nullptr, SharableCrossOrigin , V8CacheOptionsDefault, true); |
415 if (script.IsEmpty()) | 420 if (script.IsEmpty()) |
416 return v8::Local<v8::Value>(); | 421 return v8::Local<v8::Value>(); |
417 | 422 |
418 TRACE_EVENT0("v8", "v8.run"); | 423 TRACE_EVENT0("v8", "v8.run"); |
419 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 424 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
420 V8RecursionScope::MicrotaskSuppression recursionScope(isolate); | 425 V8RecursionScope::MicrotaskSuppression recursionScope(isolate); |
421 v8::Local<v8::Value> result = script->Run(); | 426 v8::Local<v8::Value> result = script->Run(); |
422 crashIfV8IsDead(); | 427 crashIfV8IsDead(); |
423 return result; | 428 return result; |
424 } | 429 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 TRACE_EVENT0("v8", "v8.newInstance"); | 504 TRACE_EVENT0("v8", "v8.newInstance"); |
500 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 505 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
501 if (ScriptForbiddenScope::isScriptForbidden()) | 506 if (ScriptForbiddenScope::isScriptForbidden()) |
502 return v8::Local<v8::Object>(); | 507 return v8::Local<v8::Object>(); |
503 V8RecursionScope scope(isolate); | 508 V8RecursionScope scope(isolate); |
504 v8::Local<v8::Object> result = function->NewInstance(argc, argv); | 509 v8::Local<v8::Object> result = function->NewInstance(argc, argv); |
505 crashIfV8IsDead(); | 510 crashIfV8IsDead(); |
506 return result; | 511 return result; |
507 } | 512 } |
508 | 513 |
509 unsigned V8ScriptRunner::tagForParserCache(Resource* resource) | 514 unsigned V8ScriptRunner::tagForParserCache(CachedMetadataHandler* cacheHandler) |
510 { | 515 { |
511 return cacheTag(CacheTagParser, resource); | 516 return cacheTag(CacheTagParser, cacheHandler); |
512 } | 517 } |
513 | 518 |
514 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) | 519 unsigned V8ScriptRunner::tagForCodeCache(CachedMetadataHandler* cacheHandler) |
515 { | 520 { |
516 return cacheTag(CacheTagCode, resource); | 521 return cacheTag(CacheTagCode, cacheHandler); |
517 } | 522 } |
518 | 523 |
519 } // namespace blink | 524 } // namespace blink |
OLD | NEW |