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, Resource::MetadataCacheType ca cheType) |
haraken
2014/09/05 16:16:13
Move the Isolate* to the first parameter.
vogelheim
2014/09/05 17:47:29
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 cacheType); | |
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 |
100 } // namespace | 93 } // namespace |
101 | 94 |
102 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) | 95 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) |
103 { | 96 { |
104 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus, cacheOptions); | 97 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus, cacheOptions); |
105 } | 98 } |
106 | 99 |
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) | 100 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 { | 101 { |
109 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); | 102 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); |
110 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); | 103 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); |
111 | 104 |
112 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at | 105 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at |
113 // 1, whereas v8 starts at 0. | 106 // 1, whereas v8 starts at 0. |
114 v8::Handle<v8::String> name = v8String(isolate, fileName); | 107 v8::Handle<v8::String> name = v8String(isolate, fileName); |
115 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt()); | 108 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()); | 109 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); | 110 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate); |
118 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); | 111 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); |
119 | 112 |
120 // V8 supports several forms of caching. Decide on the cache mode and call | |
121 // ScriptCompiler::Compile with suitable options. | |
122 unsigned dataTypeID = 0; | |
123 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions; | |
124 bool produce; | |
125 v8::Local<v8::Script> script; | 113 v8::Local<v8::Script> script; |
126 if (CacheDecider(code, resource, cacheOptions, &dataTypeID, &compileOption, &produce)) { | 114 unsigned cacheTag = 0; |
127 if (produce) { | 115 if (!resource || !resource->url().protocolIsInHTTPFamily() || code->Length() < 1024) { |
128 // Produce new cache data: | 116 v8::ScriptCompiler::Source source(code, origin); |
129 v8::ScriptCompiler::Source source(code, origin); | 117 script = v8::ScriptCompiler::Compile(isolate, &source, v8::ScriptCompile r::kNoCompileOptions); |
130 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption ); | 118 } else { |
131 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedD ata(); | 119 switch (cacheOptions) { |
132 if (cachedData) { | 120 case V8CacheOptionsParse: |
133 resource->clearCachedMetadata(); | 121 cacheTag = StringHash::hash(v8::V8::GetVersion()) * 2; |
134 resource->setCachedMetadata( | 122 script = resource->cachedMetadata(cacheTag) |
135 dataTypeID, | 123 ? compileAndConsumeCache(code, origin, resource, isolate, v8::Sc riptCompiler::kConsumeParserCache, cacheTag) |
136 reinterpret_cast<const char*>(cachedData->data), | 124 : compileAndProduceCache(code, origin, resource, isolate, v8::Sc riptCompiler::kProduceParserCache, cacheTag, Resource::SendToPlatform); |
137 cachedData->length); | 125 break; |
138 } | 126 case V8CacheOptionsCode: |
139 } else { | 127 cacheTag = StringHash::hash(v8::V8::GetVersion()) * 2 + 1; |
140 // Consume existing cache data: | 128 script = resource->cachedMetadata(cacheTag) |
141 CachedMetadata* cachedMetadata = resource->cachedMetadata(dataTypeID ); | 129 ? compileAndConsumeCache(code, origin, resource, isolate, v8::Sc riptCompiler::kConsumeCodeCache, cacheTag) |
142 v8::ScriptCompiler::CachedData* cachedData = new v8::ScriptCompiler: :CachedData( | 130 : compileAndProduceCache(code, origin, resource, isolate, v8::Sc riptCompiler::kProduceCodeCache, cacheTag, Resource::SendToPlatform); |
143 reinterpret_cast<const uint8_t*>(cachedMetadata->data()), | 131 break; |
144 cachedMetadata->size(), | 132 case V8CacheOptionsOff: |
haraken
2014/09/05 16:16:13
How about just putting the 'case V8CacheOptionsOff
vogelheim
2014/09/05 17:47:29
This is unlikely to stay that way. I'd prefer not
| |
145 v8::ScriptCompiler::CachedData::BufferNotOwned); | 133 // Previous behaviour was to always generate an in-memory parser |
146 v8::ScriptCompiler::Source source(code, origin, cachedData); | 134 // cache. We emulate this here. |
147 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption ); | 135 // TODO(vogelheim): Determine whether this should get its own |
haraken
2014/09/05 16:16:13
TODO(vogelheim) => FIXME
vogelheim
2014/09/05 17:47:29
Done.
| |
136 // setting, so we can also have a true 'off'. | |
137 cacheTag = StringHash::hash(v8::V8::GetVersion()) * 2; | |
138 script = resource->cachedMetadata(cacheTag) | |
139 ? compileAndConsumeCache(code, origin, resource, isolate, v8::Sc riptCompiler::kConsumeParserCache, cacheTag) | |
140 : compileAndProduceCache(code, origin, resource, isolate, v8::Sc riptCompiler::kProduceParserCache, cacheTag, Resource::CacheLocally); | |
141 break; | |
148 } | 142 } |
149 } else { | |
150 // No caching: | |
151 v8::ScriptCompiler::Source source(code, origin); | |
152 script = v8::ScriptCompiler::Compile( | |
153 isolate, &source, v8::ScriptCompiler::kNoCompileOptions); | |
154 } | 143 } |
155 return script; | 144 return script; |
156 } | 145 } |
157 | 146 |
158 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc ript, ExecutionContext* context, v8::Isolate* isolate) | 147 v8::Local<v8::Value> V8ScriptRunner::runCompiledScript(v8::Handle<v8::Script> sc ript, ExecutionContext* context, v8::Isolate* isolate) |
159 { | 148 { |
160 if (script.IsEmpty()) | 149 if (script.IsEmpty()) |
161 return v8::Local<v8::Value>(); | 150 return v8::Local<v8::Value>(); |
162 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 151 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
163 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); | 152 TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Val ue(script->GetUnboundScript()->GetScriptName()))); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 { | 257 { |
269 TRACE_EVENT0("v8", "v8.newInstance"); | 258 TRACE_EVENT0("v8", "v8.newInstance"); |
270 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); | 259 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); |
271 V8RecursionScope scope(isolate, context); | 260 V8RecursionScope scope(isolate, context); |
272 v8::Local<v8::Object> result = function->NewInstance(argc, argv); | 261 v8::Local<v8::Object> result = function->NewInstance(argc, argv); |
273 crashIfV8IsDead(); | 262 crashIfV8IsDead(); |
274 return result; | 263 return result; |
275 } | 264 } |
276 | 265 |
277 } // namespace blink | 266 } // namespace blink |
OLD | NEW |