Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: Source/bindings/core/v8/V8ScriptRunner.cpp

Issue 929953002: CachedMetadata support for ServiceWorker script. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: incorporated tkent's comment Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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(CachedMetadataHandler::CacheLocally);
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(CachedMetadataHandler::CacheLocally);
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");
366 369
370 ASSERT(!streamer || resource);
371 ASSERT(!resource || resource->cacheHandler() == cacheHandler);
372
367 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at 373 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
368 // 1, whereas v8 starts at 0. 374 // 1, whereas v8 starts at 0.
369 v8::ScriptOrigin origin( 375 v8::ScriptOrigin origin(
370 v8String(isolate, fileName), 376 v8String(isolate, fileName),
371 v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()), 377 v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()),
372 v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()), 378 v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()),
373 v8Boolean(corsStatus == SharableCrossOrigin, isolate), 379 v8Boolean(corsStatus == SharableCrossOrigin, isolate),
374 v8::Handle<v8::Integer>(), 380 v8::Handle<v8::Integer>(),
375 v8Boolean(isInternalScript, isolate)); 381 v8Boolean(isInternalScript, isolate));
376 382
377 OwnPtr<CompileFn> compileFn = streamer 383 OwnPtr<CompileFn> compileFn = streamer
378 ? selectCompileFunction(resource, streamer) 384 ? selectCompileFunction(resource, streamer)
379 : selectCompileFunction(cacheOptions, resource, code); 385 : selectCompileFunction(cacheOptions, cacheHandler, code);
380 386
381 return (*compileFn)(isolate, code, origin); 387 return (*compileFn)(isolate, code, origin);
382 } 388 }
383 389
384 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context) 390 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8: :Handle<v8::Script> script, ExecutionContext* context)
385 { 391 {
386 if (script.IsEmpty()) 392 if (script.IsEmpty())
387 return v8::Local<v8::Value>(); 393 return v8::Local<v8::Value>();
388 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 394 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
389 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); 395 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName())));
(...skipping 14 matching lines...) Expand all
404 410
405 if (result.IsEmpty()) 411 if (result.IsEmpty())
406 return v8::Local<v8::Value>(); 412 return v8::Local<v8::Value>();
407 413
408 crashIfV8IsDead(); 414 crashIfV8IsDead();
409 return result; 415 return result;
410 } 416 }
411 417
412 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition) 418 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition)
413 { 419 {
414 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, 0, 0, isolate, SharableCrossOrigin, V8CacheOptionsDefau lt, true); 420 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, isolate, nullptr, nullptr, nullptr, SharableCrossOrigin , V8CacheOptionsDefault, true);
415 if (script.IsEmpty()) 421 if (script.IsEmpty())
416 return v8::Local<v8::Value>(); 422 return v8::Local<v8::Value>();
417 423
418 TRACE_EVENT0("v8", "v8.run"); 424 TRACE_EVENT0("v8", "v8.run");
419 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 425 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
420 V8RecursionScope::MicrotaskSuppression recursionScope(isolate); 426 V8RecursionScope::MicrotaskSuppression recursionScope(isolate);
421 v8::Local<v8::Value> result = script->Run(); 427 v8::Local<v8::Value> result = script->Run();
422 crashIfV8IsDead(); 428 crashIfV8IsDead();
423 return result; 429 return result;
424 } 430 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 TRACE_EVENT0("v8", "v8.newInstance"); 494 TRACE_EVENT0("v8", "v8.newInstance");
489 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 495 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
490 if (ScriptForbiddenScope::isScriptForbidden()) 496 if (ScriptForbiddenScope::isScriptForbidden())
491 return v8::Local<v8::Object>(); 497 return v8::Local<v8::Object>();
492 V8RecursionScope scope(isolate); 498 V8RecursionScope scope(isolate);
493 v8::Local<v8::Object> result = function->NewInstance(argc, argv); 499 v8::Local<v8::Object> result = function->NewInstance(argc, argv);
494 crashIfV8IsDead(); 500 crashIfV8IsDead();
495 return result; 501 return result;
496 } 502 }
497 503
498 unsigned V8ScriptRunner::tagForParserCache(Resource* resource) 504 unsigned V8ScriptRunner::tagForParserCache(CachedMetadataHandler* cacheHandler)
499 { 505 {
500 return cacheTag(CacheTagParser, resource); 506 return cacheTag(CacheTagParser, cacheHandler);
501 } 507 }
502 508
503 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) 509 unsigned V8ScriptRunner::tagForCodeCache(CachedMetadataHandler* cacheHandler)
504 { 510 {
505 return cacheTag(CacheTagCode, resource); 511 return cacheTag(CacheTagCode, cacheHandler);
506 } 512 }
507 513
508 } // namespace blink 514 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/V8ScriptRunner.h ('k') | Source/bindings/core/v8/V8ScriptRunnerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698