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

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

Issue 869513005: Tweak and repurpose code caching options. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData(); 149 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData();
150 if (cachedData) { 150 if (cachedData) {
151 const char* data = reinterpret_cast<const char*>(cachedData->data); 151 const char* data = reinterpret_cast<const char*>(cachedData->data);
152 int length = cachedData->length; 152 int length = cachedData->length;
153 std::string compressedOutput; 153 std::string compressedOutput;
154 if (compressed) { 154 if (compressed) {
155 snappy::Compress(data, length, &compressedOutput); 155 snappy::Compress(data, length, &compressedOutput);
156 data = compressedOutput.data(); 156 data = compressedOutput.data();
157 length = compressedOutput.length(); 157 length = compressedOutput.length();
158 } 158 }
159 if (length > 1024) {
160 // Omit histogram samples for small cache data to avoid outliers.
161 int cacheSizeRatio = static_cast<int>(100.0 * length / code->Length( ));
162 blink::Platform::current()->histogramCustomCounts("V8.CodeCacheSizeR atio", cacheSizeRatio, 0, 10000, 50);
163 }
159 resource->clearCachedMetadata(); 164 resource->clearCachedMetadata();
160 resource->setCachedMetadata(tag, data, length, cacheType); 165 resource->setCachedMetadata(tag, data, length, cacheType);
161 } 166 }
162 return script; 167 return script;
163 } 168 }
164 169
165 // Compile a script, and consume or produce a V8 Cache, depending on whether the 170 // Compile a script, and consume or produce a V8 Cache, depending on whether the
166 // given resource already has cached data available. 171 // given resource already has cached data available.
167 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) 172 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)
168 { 173 {
(...skipping 28 matching lines...) Expand all
197 202
198 // Store a timestamp to the cache as hint. 203 // Store a timestamp to the cache as hint.
199 void setCacheTimeStamp(ScriptResource* resource) 204 void setCacheTimeStamp(ScriptResource* resource)
200 { 205 {
201 double now = WTF::currentTime(); 206 double now = WTF::currentTime();
202 unsigned tag = cacheTag(CacheTagTimeStamp, resource); 207 unsigned tag = cacheTag(CacheTagTimeStamp, resource);
203 resource->setCachedMetadata(tag, reinterpret_cast<char*>(&now), sizeof(now), Resource::SendToPlatform); 208 resource->setCachedMetadata(tag, reinterpret_cast<char*>(&now), sizeof(now), Resource::SendToPlatform);
204 } 209 }
205 210
206 // Check previously stored timestamp. 211 // Check previously stored timestamp.
207 bool isResourceHotForCaching(ScriptResource* resource) 212 bool isResourceHotForCaching(ScriptResource* resource, int hotHours)
208 { 213 {
209 const double kCacheWithinSeconds = 36 * 60 * 60; 214 const double kCacheWithinSeconds = hotHours * 60 * 60;
210 unsigned tag = cacheTag(CacheTagTimeStamp, resource); 215 unsigned tag = cacheTag(CacheTagTimeStamp, resource);
211 CachedMetadata* cachedMetadata = resource->cachedMetadata(tag); 216 CachedMetadata* cachedMetadata = resource->cachedMetadata(tag);
212 if (!cachedMetadata) 217 if (!cachedMetadata)
213 return false; 218 return false;
214 double timeStamp; 219 double timeStamp;
215 const int size = sizeof(timeStamp); 220 const int size = sizeof(timeStamp);
216 ASSERT(cachedMetadata->size() == size); 221 ASSERT(cachedMetadata->size() == size);
217 memcpy(&timeStamp, cachedMetadata->data(), size); 222 memcpy(&timeStamp, cachedMetadata->data(), size);
218 return (WTF::currentTime() - timeStamp) < kCacheWithinSeconds; 223 return (WTF::currentTime() - timeStamp) < kCacheWithinSeconds;
219 } 224 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 PassOwnPtr<CompileFn> bind(const A&... args) 263 PassOwnPtr<CompileFn> bind(const A&... args)
259 { 264 {
260 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(arg s...); 265 return WTF::bind<v8::Isolate*, v8::Handle<v8::String>, v8::ScriptOrigin>(arg s...);
261 } 266 }
262 267
263 // Select a compile function from any of the above, mainly depending on 268 // Select a compile function from any of the above, mainly depending on
264 // cacheOptions. 269 // cacheOptions.
265 PassOwnPtr<CompileFn> selectCompileFunction(V8CacheOptions cacheOptions, ScriptR esource* resource, v8::Handle<v8::String> code) 270 PassOwnPtr<CompileFn> selectCompileFunction(V8CacheOptions cacheOptions, ScriptR esource* resource, v8::Handle<v8::String> code)
266 { 271 {
267 static const int minimalCodeLength = 1024; 272 static const int minimalCodeLength = 1024;
268 static const int mediumCodeLength = 300000;
269 273
270 if (cacheOptions == V8CacheOptionsNone 274 if (!resource || !resource->url().protocolIsInHTTPFamily())
271 || !resource
272 || !resource->url().protocolIsInHTTPFamily()) {
273 // Caching is not available in this case. 275 // Caching is not available in this case.
274 return bind(compileWithoutOptions, V8CompileHistogram::Noncacheable); 276 return bind(compileWithoutOptions, V8CompileHistogram::Noncacheable);
275 }
276 277
277 if (code->Length() < minimalCodeLength) { 278 if (cacheOptions == V8CacheOptionsNone)
278 // Do not cache for small scripts, though caching is available.
279 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); 279 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable);
280 }
281 280
282 // The cacheOptions will guide our strategy: 281 // The cacheOptions will guide our strategy:
282 // FIXME: Clean up code caching options. crbug.com/455187.
283 switch (cacheOptions) { 283 switch (cacheOptions) {
284 case V8CacheOptionsDefault: 284 case V8CacheOptionsDefault:
285 case V8CacheOptionsParseMemory: 285 case V8CacheOptionsParseMemory:
286 if (code->Length() < minimalCodeLength) {
287 // Do not cache for small scripts, though caching is available.
288 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable);
289 }
286 // Use parser-cache; in-memory only. 290 // Use parser-cache; in-memory only.
287 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::CacheLocally); 291 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::CacheLocally);
288 break; 292 break;
289 293
290 case V8CacheOptionsParse: 294 case V8CacheOptionsParse:
291 // Use parser-cache. 295 // Use parser-cache.
292 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::SendToPlatform); 296 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, Resource::SendToPlatform);
293 break; 297 break;
294 298
299 case V8CacheOptionsHeuristicsDefault:
295 case V8CacheOptionsCode: 300 case V8CacheOptionsCode:
296 // Always use code caching. 301 // Always use code caching.
297 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCode, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::kProduceC odeCache, false, Resource::SendToPlatform); 302 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCode, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::kProduceC odeCache, false, Resource::SendToPlatform);
298 break; 303 break;
299 304
305 case V8CacheOptionsHeuristicsDefaultMobile:
300 case V8CacheOptionsCodeCompressed: 306 case V8CacheOptionsCodeCompressed:
301 // Always use code caching. Compress depending on cacheOptions. 307 // Always use code caching. Compress depending on cacheOptions.
302 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCodeC ompressed, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler: :kProduceCodeCache, true, Resource::SendToPlatform); 308 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCodeC ompressed, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler: :kProduceCodeCache, true, Resource::SendToPlatform);
303 break; 309 break;
304 310
305 case V8CacheOptionsHeuristics: 311 case V8CacheOptionsHeuristics:
306 case V8CacheOptionsHeuristicsMobile: 312 case V8CacheOptionsHeuristicsMobile:
307 case V8CacheOptionsHeuristicsDefault:
308 case V8CacheOptionsHeuristicsDefaultMobile: {
309 // We expect compression to win on mobile devices, due to relatively
310 // slow storage.
311 bool compress = (cacheOptions == V8CacheOptionsHeuristicsMobile || cache Options == V8CacheOptionsHeuristicsDefaultMobile);
312 CacheTagKind codeTag = compress ? CacheTagCodeCompressed : CacheTagCode;
313
314 // Either code or parser caching, depending on code size and what we
315 // already have in the cache.
316 unsigned codeCacheTag = cacheTag(codeTag, resource);
317 if (resource->cachedMetadata(codeCacheTag))
318 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, compress);
319 if (code->Length() < mediumCodeLength)
320 return bind(compileAndProduceCache, resource, codeCacheTag, v8::Scri ptCompiler::kProduceCodeCache, compress, Resource::SendToPlatform);
321 Resource::MetadataCacheType cacheType = Resource::CacheLocally;
322 if (cacheOptions == V8CacheOptionsHeuristics || cacheOptions == V8CacheO ptionsHeuristicsMobile)
323 cacheType = Resource::SendToPlatform;
324 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, cacheType);
325 break;
326 }
327
328 case V8CacheOptionsRecent: 313 case V8CacheOptionsRecent:
329 case V8CacheOptionsRecentSmall: { 314 case V8CacheOptionsRecentSmall: {
330 if (cacheOptions == V8CacheOptionsRecentSmall && code->Length() >= mediu mCodeLength) 315 bool compress = (cacheOptions == V8CacheOptionsRecentSmall || cacheOptio ns == V8CacheOptionsHeuristicsMobile);
331 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagP arser, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::k ProduceParserCache, false, Resource::CacheLocally); 316 unsigned codeCacheTag = cacheTag(compress ? CacheTagCodeCompressed : Cac heTagCode, resource);
332 unsigned codeCacheTag = cacheTag(CacheTagCode, resource);
333 CachedMetadata* codeCache = resource->cachedMetadata(codeCacheTag); 317 CachedMetadata* codeCache = resource->cachedMetadata(codeCacheTag);
334 if (codeCache) 318 if (codeCache)
335 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, false); 319 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, compress);
336 if (!isResourceHotForCaching(resource)) { 320 int hotHours = (cacheOptions == V8CacheOptionsRecent || cacheOptions == V8CacheOptionsRecentSmall) ? 36 : 72;
321 if (!isResourceHotForCaching(resource, hotHours)) {
337 setCacheTimeStamp(resource); 322 setCacheTimeStamp(resource);
338 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); 323 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable);
339 } 324 }
340 return bind(compileAndProduceCache, resource, codeCacheTag, v8::ScriptCo mpiler::kProduceCodeCache, false, Resource::SendToPlatform); 325 return bind(compileAndProduceCache, resource, codeCacheTag, v8::ScriptCo mpiler::kProduceCodeCache, compress, Resource::SendToPlatform);
341 break; 326 break;
342 } 327 }
343 328
344 case V8CacheOptionsNone: 329 case V8CacheOptionsNone:
345 // Shouldn't happen, as this is handled above. 330 // Shouldn't happen, as this is handled above.
346 // Case is here so that compiler can check all cases are handles. 331 // Case is here so that compiler can check all cases are handled.
347 ASSERT_NOT_REACHED(); 332 ASSERT_NOT_REACHED();
348 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable);
349 break; 333 break;
350 } 334 }
351 335
352 // All switch branches should return and we should never get here. 336 // All switch branches should return and we should never get here.
353 // But some compilers aren't sure, hence this default. 337 // But some compilers aren't sure, hence this default.
354 ASSERT_NOT_REACHED(); 338 ASSERT_NOT_REACHED();
355 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable); 339 return bind(compileWithoutOptions, V8CompileHistogram::Cacheable);
356 } 340 }
357 341
358 // Select a compile function for a streaming compile. 342 // Select a compile function for a streaming compile.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 { 504 {
521 return cacheTag(CacheTagParser, resource); 505 return cacheTag(CacheTagParser, resource);
522 } 506 }
523 507
524 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) 508 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource)
525 { 509 {
526 return cacheTag(CacheTagCode, resource); 510 return cacheTag(CacheTagCode, resource);
527 } 511 }
528 512
529 } // namespace blink 513 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698