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

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

Issue 845923003: Add experimental v8 code cache options. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 11 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 | « Source/bindings/core/v8/V8CacheOptions.h ('k') | Source/web/AssertMatchingEnums.cpp » ('j') | 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 20 matching lines...) Expand all
31 #include "bindings/core/v8/V8Binding.h" 31 #include "bindings/core/v8/V8Binding.h"
32 #include "bindings/core/v8/V8GCController.h" 32 #include "bindings/core/v8/V8GCController.h"
33 #include "bindings/core/v8/V8RecursionScope.h" 33 #include "bindings/core/v8/V8RecursionScope.h"
34 #include "bindings/core/v8/V8ThrowException.h" 34 #include "bindings/core/v8/V8ThrowException.h"
35 #include "core/dom/ExecutionContext.h" 35 #include "core/dom/ExecutionContext.h"
36 #include "core/fetch/CachedMetadata.h" 36 #include "core/fetch/CachedMetadata.h"
37 #include "core/fetch/ScriptResource.h" 37 #include "core/fetch/ScriptResource.h"
38 #include "platform/ScriptForbiddenScope.h" 38 #include "platform/ScriptForbiddenScope.h"
39 #include "platform/TraceEvent.h" 39 #include "platform/TraceEvent.h"
40 #include "third_party/snappy/src/snappy.h" 40 #include "third_party/snappy/src/snappy.h"
41 #include "wtf/CurrentTime.h"
41 42
42 #if defined(WTF_OS_WIN) 43 #if defined(WTF_OS_WIN)
43 #include <malloc.h> 44 #include <malloc.h>
44 #else 45 #else
45 #include <alloca.h> 46 #include <alloca.h>
46 #endif 47 #endif
47 48
48 namespace blink { 49 namespace blink {
49 50
50 namespace { 51 namespace {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 { 150 {
150 return resource->cachedMetadata(tag) 151 return resource->cachedMetadata(tag)
151 ? compileAndConsumeCache(resource, tag, consumeOptions, compressed, isol ate, code, origin) 152 ? compileAndConsumeCache(resource, tag, consumeOptions, compressed, isol ate, code, origin)
152 : compileAndProduceCache(resource, tag, produceOptions, compressed, cach eType, isolate, code, origin); 153 : compileAndProduceCache(resource, tag, produceOptions, compressed, cach eType, isolate, code, origin);
153 } 154 }
154 155
155 enum CacheTagKind { 156 enum CacheTagKind {
156 CacheTagParser = 0, 157 CacheTagParser = 0,
157 CacheTagCode = 1, 158 CacheTagCode = 1,
158 CacheTagCodeCompressed = 2, 159 CacheTagCodeCompressed = 2,
159 160 CacheTagTimeStamp = 3,
160 CacheTagLast 161 CacheTagLast
161 }; 162 };
162 163
163 static const int kCacheTagKindSize = 2; 164 static const int kCacheTagKindSize = 2;
164 165
165 unsigned cacheTag(CacheTagKind kind, Resource* resource) 166 unsigned cacheTag(CacheTagKind kind, Resource* resource)
166 { 167 {
167 static_assert((1 << kCacheTagKindSize) >= CacheTagLast, "CacheTagLast must b e large enough"); 168 static_assert((1 << kCacheTagKindSize) >= CacheTagLast, "CacheTagLast must b e large enough");
168 169
169 static unsigned v8CacheDataVersion = v8::ScriptCompiler::CachedDataVersionTa g() << kCacheTagKindSize; 170 static unsigned v8CacheDataVersion = v8::ScriptCompiler::CachedDataVersionTa g() << kCacheTagKindSize;
170 171
171 // A script can be (successfully) interpreted with different encodings, 172 // A script can be (successfully) interpreted with different encodings,
172 // depending on the page it appears in. The cache doesn't know anything 173 // depending on the page it appears in. The cache doesn't know anything
173 // about encodings, but the cached data is specific to one encoding. If we 174 // about encodings, but the cached data is specific to one encoding. If we
174 // later load the script from the cache and interpret it with a different 175 // later load the script from the cache and interpret it with a different
175 // encoding, the cached data is not valid for that encoding. 176 // encoding, the cached data is not valid for that encoding.
176 return (v8CacheDataVersion | kind) + StringHash::hash(resource->encoding()); 177 return (v8CacheDataVersion | kind) + StringHash::hash(resource->encoding());
177 } 178 }
178 179
180 // Store a timestamp to the cache as hint.
181 void setCacheTimeStamp(ScriptResource* resource)
182 {
183 double now = currentTime();
184 unsigned tag = cacheTag(CacheTagTimeStamp, resource);
185 resource->setCachedMetadata(tag, reinterpret_cast<char*>(&now), sizeof(now), Resource::SendToPlatform);
186 }
187
188 // Check previously stored timestamp.
189 bool isResourceHotForCaching(ScriptResource* resource)
190 {
191 const double kCacheWithinSeconds = 36 * 60 * 60;
192 unsigned tag = cacheTag(CacheTagTimeStamp, resource);
193 CachedMetadata* cachedMetadata = resource->cachedMetadata(tag);
194 if (!cachedMetadata)
195 return false;
196 double timeStamp;
197 const int size = sizeof(timeStamp);
198 ASSERT(cachedMetadata->size() == size);
199 memcpy(&timeStamp, cachedMetadata->data(), size);
200 return (currentTime() - timeStamp) < kCacheWithinSeconds;
201 }
202
179 // Final compile call for a streamed compilation. Most decisions have already 203 // Final compile call for a streamed compilation. Most decisions have already
180 // been made, but we need to write back data into the cache. 204 // been made, but we need to write back data into the cache.
181 v8::Local<v8::Script> postStreamCompile(ScriptResource* resource, ScriptStreamer * streamer, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin origin) 205 v8::Local<v8::Script> postStreamCompile(ScriptResource* resource, ScriptStreamer * streamer, v8::Isolate* isolate, v8::Handle<v8::String> code, v8::ScriptOrigin origin)
182 { 206 {
183 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, streamer ->source(), code, origin); 207 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, streamer ->source(), code, origin);
184 208
185 // Whether to produce the cached data or not is decided when the 209 // Whether to produce the cached data or not is decided when the
186 // streamer is started. Here we only need to get the data out. 210 // streamer is started. Here we only need to get the data out.
187 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source()->Ge tCachedData(); 211 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source()->Ge tCachedData();
188 if (newCachedData) { 212 if (newCachedData) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 // Always use code caching. 273 // Always use code caching.
250 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCode, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::kProduceC odeCache, false, Resource::SendToPlatform); 274 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCode, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler::kProduceC odeCache, false, Resource::SendToPlatform);
251 break; 275 break;
252 276
253 case V8CacheOptionsCodeCompressed: 277 case V8CacheOptionsCodeCompressed:
254 // Always use code caching. Compress depending on cacheOptions. 278 // Always use code caching. Compress depending on cacheOptions.
255 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCodeC ompressed, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler: :kProduceCodeCache, true, Resource::SendToPlatform); 279 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagCodeC ompressed, resource), v8::ScriptCompiler::kConsumeCodeCache, v8::ScriptCompiler: :kProduceCodeCache, true, Resource::SendToPlatform);
256 break; 280 break;
257 281
258 case V8CacheOptionsHeuristics: 282 case V8CacheOptionsHeuristics:
259 case V8CacheOptionsHeuristicsMobile: { 283 case V8CacheOptionsHeuristicsMobile:
284 case V8CacheOptionsHeuristicsDefault:
285 case V8CacheOptionsHeuristicsDefaultMobile: {
260 // We expect compression to win on mobile devices, due to relatively 286 // We expect compression to win on mobile devices, due to relatively
261 // slow storage. 287 // slow storage.
262 bool compress = cacheOptions == V8CacheOptionsHeuristicsMobile; 288 bool compress = cacheOptions == V8CacheOptionsHeuristicsMobile;
263 CacheTagKind codeTag = compress ? CacheTagCodeCompressed : CacheTagCode; 289 CacheTagKind codeTag = compress ? CacheTagCodeCompressed : CacheTagCode;
264 290
265 // Either code or parser caching, depending on code size and what we 291 // Either code or parser caching, depending on code size and what we
266 // already have in the cache. 292 // already have in the cache.
267 unsigned codeCacheTag = cacheTag(codeTag, resource); 293 unsigned codeCacheTag = cacheTag(codeTag, resource);
268 if (resource->cachedMetadata(codeCacheTag)) 294 if (resource->cachedMetadata(codeCacheTag))
269 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, compress); 295 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, compress);
270 if (code->Length() < mediumCodeLength) 296 if (code->Length() < mediumCodeLength)
271 return bind(compileAndProduceCache, resource, codeCacheTag, v8::Scri ptCompiler::kProduceCodeCache, compress, Resource::SendToPlatform); 297 return bind(compileAndProduceCache, resource, codeCacheTag, v8::Scri ptCompiler::kProduceCodeCache, compress, Resource::SendToPlatform);
272 unsigned parserCacheTag = cacheTag(CacheTagParser, resource); 298 Resource::MetadataCacheType cacheType = Resource::CacheLocally;
273 if (resource->cachedMetadata(parserCacheTag)) 299 if (cacheOptions == V8CacheOptionsHeuristics || cacheOptions == V8CacheO ptionsHeuristicsMobile)
274 return bind(compileAndConsumeCache, resource, parserCacheTag, v8::Sc riptCompiler::kConsumeParserCache, false); 300 cacheType = Resource::SendToPlatform;
275 return bind(compileAndProduceCache, resource, parserCacheTag, v8::Script Compiler::kProduceParserCache, false, Resource::SendToPlatform); 301 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagParse r, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::kProd uceParserCache, false, cacheType);
276 break; 302 break;
277 } 303 }
278 304
305 case V8CacheOptionsRecent:
306 case V8CacheOptionsRecentSmall: {
307 if (cacheOptions == V8CacheOptionsRecentSmall && code->Length() >= mediu mCodeLength)
308 return bind(compileAndConsumeOrProduce, resource, cacheTag(CacheTagP arser, resource), v8::ScriptCompiler::kConsumeParserCache, v8::ScriptCompiler::k ProduceParserCache, false, Resource::CacheLocally);
309 unsigned codeCacheTag = cacheTag(CacheTagCode, resource);
310 CachedMetadata* codeCache = resource->cachedMetadata(codeCacheTag);
311 if (codeCache)
312 return bind(compileAndConsumeCache, resource, codeCacheTag, v8::Scri ptCompiler::kConsumeCodeCache, false);
313 if (!isResourceHotForCaching(resource)) {
marja 2015/01/20 13:14:32 So this caches the code if we have recently compil
314 setCacheTimeStamp(resource);
315 return bind(compileWithoutOptions);
316 }
317 return bind(compileAndProduceCache, resource, codeCacheTag, v8::ScriptCo mpiler::kProduceCodeCache, false, Resource::SendToPlatform);
318 break;
319 }
320
279 case V8CacheOptionsNone: 321 case V8CacheOptionsNone:
280 // Shouldn't happen, as this is handled above. 322 // Shouldn't happen, as this is handled above.
281 // Case is here so that compiler can check all cases are handles. 323 // Case is here so that compiler can check all cases are handles.
282 ASSERT_NOT_REACHED(); 324 ASSERT_NOT_REACHED();
283 return bind(compileWithoutOptions); 325 return bind(compileWithoutOptions);
284 break; 326 break;
285 } 327 }
286 328
287 // All switch branches should return and we should never get here. 329 // All switch branches should return and we should never get here.
288 // But some compilers aren't sure, hence this default. 330 // But some compilers aren't sure, hence this default.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 { 499 {
458 return cacheTag(CacheTagParser, resource); 500 return cacheTag(CacheTagParser, resource);
459 } 501 }
460 502
461 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) 503 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource)
462 { 504 {
463 return cacheTag(CacheTagCode, resource); 505 return cacheTag(CacheTagCode, resource);
464 } 506 }
465 507
466 } // namespace blink 508 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/V8CacheOptions.h ('k') | Source/web/AssertMatchingEnums.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698