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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 // If we are already handling a recursion level error, we should | 55 // If we are already handling a recursion level error, we should |
| 56 // not invoke v8::Function::Call. | 56 // not invoke v8::Function::Call. |
| 57 return v8::Undefined(isolate); | 57 return v8::Undefined(isolate); |
| 58 } | 58 } |
| 59 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true); | 59 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true); |
| 60 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0); | 60 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0); |
| 61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false); | 61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false); |
| 62 return result; | 62 return result; |
| 63 } | 63 } |
| 64 | 64 |
| 65 // Make a decision on whether we want to use V8 caching and how. | 65 v8::Local<v8::Script> CompileAndProduceCache(v8::Handle<v8::String> code, v8::Sc riptOrigin origin, ScriptResource* resource, v8::Isolate* isolate, v8::ScriptCom piler::CompileOptions options, unsigned cacheTag, bool persistCache) |
|
haraken
2014/09/03 04:11:43
CompileAndProduceCache => compileAndProduceCache
vogelheim
2014/09/03 11:21:34
Done.
| |
| 66 // dataType, produceOption, consumeOption are out parameters. | |
| 67 bool CacheDecider( | |
| 68 const v8::Handle<v8::String> code, | |
| 69 const ScriptResource* resource, | |
| 70 V8CacheOptions cacheOptions, | |
| 71 unsigned* dataType, | |
| 72 v8::ScriptCompiler::CompileOptions* compileOption, | |
| 73 bool* produce) | |
| 74 { | 66 { |
| 75 if (!resource || !resource->url().protocolIsInHTTPFamily() || code->Length() < 1024) | 67 v8::ScriptCompiler::Source source(code, origin); |
| 76 cacheOptions = V8CacheOptionsOff; | 68 v8::Local<v8::Script> script = v8::ScriptCompiler::Compile(isolate, &source, options); |
| 69 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedData(); | |
| 70 if (resource && cachedData) { | |
| 71 resource->clearCachedMetadata(); | |
| 72 resource->setCachedMetadata( | |
| 73 cacheTag, | |
| 74 reinterpret_cast<const char*>(cachedData->data), | |
| 75 cachedData->length, | |
| 76 persistCache); | |
| 77 } | |
| 78 return script; | |
| 79 } | |
| 77 | 80 |
| 78 bool useCache = false; | 81 v8::Local<v8::Script> CompileAndConsumeCache(v8::Handle<v8::String> code, v8::Sc riptOrigin origin, ScriptResource* resource, v8::Isolate* isolate, v8::ScriptCom piler::CompileOptions options, unsigned cacheTag) |
| 79 switch (cacheOptions) { | 82 { |
| 80 case V8CacheOptionsOff: | 83 // Consume existing cache data: |
| 81 *compileOption = v8::ScriptCompiler::kNoCompileOptions; | 84 CachedMetadata* cachedMetadata = resource->cachedMetadata(cacheTag); |
| 82 useCache = false; | 85 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler::CachedD ata( |
| 83 break; | 86 reinterpret_cast<const uint8_t*>(cachedMetadata->data()), |
| 84 case V8CacheOptionsParse: | 87 cachedMetadata->size(), |
| 85 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2; | 88 v8::ScriptCompiler::CachedData::BufferNotOwned); |
| 86 *produce = !resource->cachedMetadata(*dataType); | 89 v8::ScriptCompiler::Source source(code, origin, cachedData); |
| 87 *compileOption = *produce ? v8::ScriptCompiler::kProduceParserCache : v8 ::ScriptCompiler::kConsumeParserCache; | 90 return v8::ScriptCompiler::Compile(isolate, &source, options); |
| 88 useCache = true; | |
| 89 break; | |
| 90 case V8CacheOptionsCode: | |
| 91 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2 + 1; | |
| 92 *produce = !resource->cachedMetadata(*dataType); | |
| 93 *compileOption = *produce ? v8::ScriptCompiler::kProduceCodeCache : v8:: ScriptCompiler::kConsumeCodeCache; | |
| 94 useCache = true; | |
| 95 break; | |
| 96 } | |
| 97 return useCache; | |
| 98 } | 91 } |
| 99 | 92 |
| 93 // Locally used enum to enumerate the actions for V8ScriptRunner::compileScript | |
| 94 enum CompileScriptAction { | |
| 95 ConsumeParserCache, | |
| 96 ConsumeCodeCache, | |
| 97 ProduceParserCache, | |
| 98 ProduceCodeCache, | |
| 99 ProduceInMemoryParserCache, | |
| 100 Off | |
| 101 }; | |
| 102 | |
| 100 } // namespace | 103 } // namespace |
| 101 | 104 |
| 102 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) | 105 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) |
| 103 { | 106 { |
| 104 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus, cacheOptions); | 107 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus, cacheOptions); |
| 105 } | 108 } |
| 106 | 109 |
| 107 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOptions) | 110 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOptions) |
| 108 { | 111 { |
| 109 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); | 112 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); |
| 110 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); | 113 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); |
| 111 | 114 |
| 112 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at | 115 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at |
| 113 // 1, whereas v8 starts at 0. | 116 // 1, whereas v8 starts at 0. |
| 114 v8::Handle<v8::String> name = v8String(isolate, fileName); | 117 v8::Handle<v8::String> name = v8String(isolate, fileName); |
| 115 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt()); | 118 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt()); |
| 116 v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPositi on.m_column.zeroBasedInt()); | 119 v8::Handle<v8::Integer> column = v8::Integer::New(isolate, scriptStartPositi on.m_column.zeroBasedInt()); |
| 117 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate); | 120 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate); |
| 118 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); | 121 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); |
| 119 | 122 |
| 120 // V8 supports several forms of caching. Decide on the cache mode and call | 123 // Device on the compile options (caching). |
|
marja
2014/09/03 07:17:47
"Device on"? (Obvsly I'm not a native speaker but
vogelheim
2014/09/03 11:21:34
I meant: "Decide on ...". Not sure what happened t
| |
| 121 // ScriptCompiler::Compile with suitable options. | 124 CompileScriptAction compileScriptAction; |
| 122 unsigned dataTypeID = 0; | 125 unsigned cacheTag = 0; |
| 123 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions; | 126 if (!resource || !resource->url().protocolIsInHTTPFamily() || code->Length() < 1024) { |
| 124 bool produce; | 127 compileScriptAction = Off; |
| 128 } else { | |
| 129 switch (cacheOptions) { | |
| 130 case V8CacheOptionsParse: | |
| 131 cacheTag = StringHash::hash(v8::V8::GetVersion()) * 2; | |
| 132 compileScriptAction = resource->cachedMetadata(cacheTag) | |
| 133 ? ConsumeParserCache : ProduceParserCache; | |
| 134 break; | |
| 135 case V8CacheOptionsCode: | |
| 136 cacheTag = StringHash::hash(v8::V8::GetVersion()) * 2 + 1; | |
| 137 compileScriptAction = resource->cachedMetadata(cacheTag) | |
| 138 ? ConsumeCodeCache : ProduceCodeCache; | |
| 139 break; | |
| 140 case V8CacheOptionsOff: | |
| 141 default: | |
| 142 // Previous behaviour was to always generate an in-memory parser | |
| 143 // cache. We emulate this here. | |
| 144 // TODO(vogelheim): Determine whether this should get its own | |
| 145 // setting, so we can also have a true 'off'. | |
| 146 cacheTag = StringHash::hash(v8::V8::GetVersion()) * 2; | |
| 147 compileScriptAction = resource->cachedMetadata(cacheTag) | |
| 148 ? ConsumeParserCache : ProduceInMemoryParserCache; | |
| 149 break; | |
| 150 }; | |
| 151 } | |
| 152 | |
| 125 v8::Local<v8::Script> script; | 153 v8::Local<v8::Script> script; |
| 126 if (CacheDecider(code, resource, cacheOptions, &dataTypeID, &compileOption, &produce)) { | 154 switch (compileScriptAction) { |
|
marja
2014/09/03 07:17:47
Sounds a bit duplicate to first gather all the inf
vogelheim
2014/09/03 11:21:34
Hmm. Done. That was meant to separate the decision
| |
| 127 if (produce) { | 155 case ProduceParserCache: |
| 128 // Produce new cache data: | 156 script = CompileAndProduceCache(code, origin, resource, isolate, v8::Scr iptCompiler::kProduceParserCache, cacheTag, true); |
| 129 v8::ScriptCompiler::Source source(code, origin); | 157 break; |
| 130 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption ); | 158 case ProduceCodeCache: |
| 131 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedD ata(); | 159 script = CompileAndProduceCache(code, origin, resource, isolate, v8::Scr iptCompiler::kProduceCodeCache, cacheTag, true); |
| 132 if (cachedData) { | 160 break; |
| 133 resource->clearCachedMetadata(); | 161 case ConsumeParserCache: |
| 134 resource->setCachedMetadata( | 162 script = CompileAndConsumeCache(code, origin, resource, isolate, v8::Scr iptCompiler::kConsumeParserCache, cacheTag); |
| 135 dataTypeID, | 163 break; |
| 136 reinterpret_cast<const char*>(cachedData->data), | 164 case ConsumeCodeCache: |
| 137 cachedData->length); | 165 script = CompileAndConsumeCache(code, origin, resource, isolate, v8::Scr iptCompiler::kConsumeCodeCache, cacheTag); |
| 138 } | 166 break; |
| 139 } else { | 167 case ProduceInMemoryParserCache: |
| 140 // Consume existing cache data: | 168 script = CompileAndProduceCache(code, origin, resource, isolate, v8::Scr iptCompiler::kProduceParserCache, cacheTag, false); |
| 141 CachedMetadata* cachedMetadata = resource->cachedMetadata(dataTypeID ); | 169 break; |
| 142 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler: :CachedData( | 170 case Off: |
| 143 reinterpret_cast<const uint8_t*>(cachedMetadata->data()), | |
| 144 cachedMetadata->size(), | |
| 145 v8::ScriptCompiler::CachedData::BufferNotOwned); | |
| 146 v8::ScriptCompiler::Source source(code, origin, cachedData); | |
| 147 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption ); | |
| 148 } | |
| 149 } else { | |
| 150 // No caching: | |
| 151 v8::ScriptCompiler::Source source(code, origin); | 171 v8::ScriptCompiler::Source source(code, origin); |
| 152 script = v8::ScriptCompiler::Compile( | 172 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions); |
| 153 isolate, &source, v8::ScriptCompiler::kNoCompileOptions); | 173 break; |
| 154 } | 174 } |
| 175 | |
| 155 return script; | 176 return script; |
| 156 } | 177 } |
| 157 | 178 |
| 158 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc ript, ExecutionContext* context, v8::Isolate* isolate) | 179 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc ript, ExecutionContext* context, v8::Isolate* isolate) |
| 159 { | 180 { |
| 160 if (script.IsEmpty()) | 181 if (script.IsEmpty()) |
| 161 return v8::Local<v8::Value>(); | 182 return v8::Local<v8::Value>(); |
| 162 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 183 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
| 163 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); | 184 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); |
| 164 | 185 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 268 { | 289 { |
| 269 TRACE_EVENT0("v8", "v8.newInstance"); | 290 TRACE_EVENT0("v8", "v8.newInstance"); |
| 270 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 291 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
| 271 V8RecursionScope scope(isolate, context); | 292 V8RecursionScope scope(isolate, context); |
| 272 v8::Local<v8::Object> result = function->NewInstance(argc, argv); | 293 v8::Local<v8::Object> result = function->NewInstance(argc, argv); |
| 273 crashIfV8IsDead(); | 294 crashIfV8IsDead(); |
| 274 return result; | 295 return result; |
| 275 } | 296 } |
| 276 | 297 |
| 277 } // namespace blink | 298 } // namespace blink |
| OLD | NEW |