Chromium Code Reviews| 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(); |
|
michaeln
2015/02/18 03:13:18
Maybe pass in CachedMetadataHandler::CacheLocally
horo
2015/02/18 03:45:04
Done.
| |
| 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(); |
|
michaeln
2015/02/18 03:13:18
and here
horo
2015/02/18 03:45:03
Done.
| |
| 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 Loading... | |
| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 TRACE_EVENT0("v8", "v8.newInstance"); | 505 TRACE_EVENT0("v8", "v8.newInstance"); |
| 500 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 506 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
| 501 if (ScriptForbiddenScope::isScriptForbidden()) | 507 if (ScriptForbiddenScope::isScriptForbidden()) |
| 502 return v8::Local<v8::Object>(); | 508 return v8::Local<v8::Object>(); |
| 503 V8RecursionScope scope(isolate); | 509 V8RecursionScope scope(isolate); |
| 504 v8::Local<v8::Object> result = function->NewInstance(argc, argv); | 510 v8::Local<v8::Object> result = function->NewInstance(argc, argv); |
| 505 crashIfV8IsDead(); | 511 crashIfV8IsDead(); |
| 506 return result; | 512 return result; |
| 507 } | 513 } |
| 508 | 514 |
| 509 unsigned V8ScriptRunner::tagForParserCache(Resource* resource) | 515 unsigned V8ScriptRunner::tagForParserCache(CachedMetadataHandler* cacheHandler) |
| 510 { | 516 { |
| 511 return cacheTag(CacheTagParser, resource); | 517 return cacheTag(CacheTagParser, cacheHandler); |
| 512 } | 518 } |
| 513 | 519 |
| 514 unsigned V8ScriptRunner::tagForCodeCache(Resource* resource) | 520 unsigned V8ScriptRunner::tagForCodeCache(CachedMetadataHandler* cacheHandler) |
| 515 { | 521 { |
| 516 return cacheTag(CacheTagCode, resource); | 522 return cacheTag(CacheTagCode, cacheHandler); |
| 517 } | 523 } |
| 518 | 524 |
| 519 } // namespace blink | 525 } // namespace blink |
| OLD | NEW |