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

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

Issue 368283002: Stream scripts to V8 as they load - Blink side. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: renaming Created 6 years, 4 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 | Annotate | Revision Log
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 12 matching lines...) Expand all
23 * THE POSSIBILITY OF SUCH DAMAGE. 23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "config.h" 26 #include "config.h"
27 #include "bindings/core/v8/V8ScriptRunner.h" 27 #include "bindings/core/v8/V8ScriptRunner.h"
28 28
29 #include "bindings/core/v8/ScriptSourceCode.h" 29 #include "bindings/core/v8/ScriptSourceCode.h"
30 #include "bindings/core/v8/V8Binding.h" 30 #include "bindings/core/v8/V8Binding.h"
31 #include "bindings/core/v8/V8GCController.h" 31 #include "bindings/core/v8/V8GCController.h"
32 #include "bindings/core/v8/V8RecursionScope.h" 32 #include "bindings/core/v8/V8RecursionScope.h"
33 #include "bindings/core/v8/V8ScriptStreamer.h"
33 #include "bindings/core/v8/V8ThrowException.h" 34 #include "bindings/core/v8/V8ThrowException.h"
34 #include "core/dom/ExecutionContext.h" 35 #include "core/dom/ExecutionContext.h"
35 #include "core/fetch/CachedMetadata.h" 36 #include "core/fetch/CachedMetadata.h"
36 #include "core/fetch/ScriptResource.h" 37 #include "core/fetch/ScriptResource.h"
37 #include "platform/TraceEvent.h" 38 #include "platform/TraceEvent.h"
38 39
39 namespace blink { 40 namespace blink {
40 41
41 namespace { 42 namespace {
42 43
(...skipping 12 matching lines...) Expand all
55 // If we are already handling a recursion level error, we should 56 // If we are already handling a recursion level error, we should
56 // not invoke v8::Function::Call. 57 // not invoke v8::Function::Call.
57 return v8::Undefined(isolate); 58 return v8::Undefined(isolate);
58 } 59 }
59 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true); 60 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(true);
60 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0); 61 v8::Local<v8::Value> result = v8::Function::New(isolate, throwStackOverflowE xception)->Call(v8::Undefined(isolate), 0, 0);
61 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false); 62 V8PerIsolateData::from(isolate)->setIsHandlingRecursionLevelError(false);
62 return result; 63 return result;
63 } 64 }
64 65
65 // Make a decision on whether we want to use V8 caching and how.
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 {
75 if (!resource || !resource->url().protocolIsInHTTPFamily() || code->Length() < 1024)
76 cacheOptions = V8CacheOptionsOff;
77
78 bool useCache = false;
79 switch (cacheOptions) {
80 case V8CacheOptionsOff:
81 *compileOption = v8::ScriptCompiler::kNoCompileOptions;
82 useCache = false;
83 break;
84 case V8CacheOptionsParse:
85 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2;
86 *produce = !resource->cachedMetadata(*dataType);
87 *compileOption = *produce ? v8::ScriptCompiler::kProduceParserCache : v8 ::ScriptCompiler::kConsumeParserCache;
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 }
99
100 } // namespace 66 } // namespace
101 67
102 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions) 68 v8::Local<v8::Script> V8ScriptRunner::compileScript(const ScriptSourceCode& sour ce, v8::Isolate* isolate, AccessControlStatus corsStatus, V8CacheOptions cacheOp tions)
103 { 69 {
104 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), isolate, corsStatus, cacheOptions); 70 return compileScript(v8String(isolate, source.source()), source.url(), sourc e.startPosition(), source.resource(), source.streamer(), isolate, corsStatus, ca cheOptions);
105 } 71 }
106 72
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) 73 v8::Local<v8::Script> V8ScriptRunner::compileScript(v8::Handle<v8::String> code, const String& fileName, const TextPosition& scriptStartPosition, ScriptResource * resource, V8ScriptStreamer* streamer, v8::Isolate* isolate, AccessControlStatu s corsStatus, V8CacheOptions cacheOptions)
108 { 74 {
109 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); 75 TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8());
110 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); 76 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile");
111 77
112 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at 78 // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
113 // 1, whereas v8 starts at 0. 79 // 1, whereas v8 starts at 0.
114 v8::Handle<v8::String> name = v8String(isolate, fileName); 80 v8::Handle<v8::String> name = v8String(isolate, fileName);
115 v8::Handle<v8::Integer> line = v8::Integer::New(isolate, scriptStartPosition .m_line.zeroBasedInt()); 81 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()); 82 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); 83 v8::Handle<v8::Boolean> isSharedCrossOrigin = corsStatus == SharableCrossOri gin ? v8::True(isolate) : v8::False(isolate);
118 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin); 84 v8::ScriptOrigin origin(name, line, column, isSharedCrossOrigin);
119 85
120 // V8 supports several forms of caching. Decide on the cache mode and call 86 // V8 supports several forms of caching. Decide on the cache mode and call
121 // ScriptCompiler::Compile with suitable options. 87 // ScriptCompiler::Compile with suitable options.
122 unsigned dataTypeID = 0; 88 unsigned dataTypeID = 0;
123 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions; 89 v8::ScriptCompiler::CompileOptions compileOption = v8::ScriptCompiler::kNoCo mpileOptions;
124 bool produce; 90 bool produce;
125 v8::Local<v8::Script> script; 91 v8::Local<v8::Script> script;
126 if (CacheDecider(code, resource, cacheOptions, &dataTypeID, &compileOption, &produce)) { 92 if (streamer) {
93 // We don't stream scripts which don't have a Resource.
94 ASSERT(resource);
95 // Failed resources should never get this far.
96 ASSERT(!resource->errorOccurred());
97 script = v8::ScriptCompiler::Compile(isolate, streamer->source(), code, origin);
98 // Whether to produce the cached data or not is decided when the
99 // streamer is started. Here we only need to get the data out.
100 const v8::ScriptCompiler::CachedData* newCachedData = streamer->source() ->GetCachedData();
101 if (newCachedData) {
102 resource->setCachedMetadata(streamer->cachedDataDataType(), reinterp ret_cast<const char*>(newCachedData->data), newCachedData->length);
haraken 2014/08/17 16:05:25 Don't you need to call resource->clearCachedMetada
marja 2014/08/20 11:45:54 Done.
103 }
104 } else if (CacheDecider(code->Length(), resource, cacheOptions, &dataTypeID, &compileOption, &produce)) {
127 if (produce) { 105 if (produce) {
128 // Produce new cache data: 106 // Produce new cache data:
129 v8::ScriptCompiler::Source source(code, origin); 107 v8::ScriptCompiler::Source source(code, origin);
130 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption ); 108 script = v8::ScriptCompiler::Compile(isolate, &source, compileOption );
131 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedD ata(); 109 const v8::ScriptCompiler::CachedData* cachedData = source.GetCachedD ata();
132 if (cachedData) { 110 if (cachedData) {
133 resource->clearCachedMetadata(); 111 resource->clearCachedMetadata();
134 resource->setCachedMetadata( 112 resource->setCachedMetadata(
135 dataTypeID, 113 dataTypeID,
136 reinterpret_cast<const char*>(cachedData->data), 114 reinterpret_cast<const char*>(cachedData->data),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 return v8::Local<v8::Value>(); 156 return v8::Local<v8::Value>();
179 157
180 crashIfV8IsDead(); 158 crashIfV8IsDead();
181 return result; 159 return result;
182 } 160 }
183 161
184 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition) 162 v8::Local<v8::Value> V8ScriptRunner::compileAndRunInternalScript(v8::Handle<v8:: String> source, v8::Isolate* isolate, const String& fileName, const TextPosition & scriptStartPosition)
185 { 163 {
186 TRACE_EVENT0("v8", "v8.run"); 164 TRACE_EVENT0("v8", "v8.run");
187 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 165 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
188 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, 0, isolate); 166 v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, fileNa me, scriptStartPosition, 0, 0, isolate);
189 if (script.IsEmpty()) 167 if (script.IsEmpty())
190 return v8::Local<v8::Value>(); 168 return v8::Local<v8::Value>();
191 169
192 V8RecursionScope::MicrotaskSuppression recursionScope(isolate); 170 V8RecursionScope::MicrotaskSuppression recursionScope(isolate);
193 v8::Local<v8::Value> result = script->Run(); 171 v8::Local<v8::Value> result = script->Run();
194 crashIfV8IsDead(); 172 crashIfV8IsDead();
195 return result; 173 return result;
196 } 174 }
197 175
198 v8::Local<v8::Value> V8ScriptRunner::callFunction(v8::Handle<v8::Function> funct ion, ExecutionContext* context, v8::Handle<v8::Value> receiver, int argc, v8::Ha ndle<v8::Value> args[], v8::Isolate* isolate) 176 v8::Local<v8::Value> V8ScriptRunner::callFunction(v8::Handle<v8::Function> funct ion, ExecutionContext* context, v8::Handle<v8::Value> receiver, int argc, v8::Ha ndle<v8::Value> args[], v8::Isolate* isolate)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 v8::Local<v8::Object> V8ScriptRunner::instantiateObjectInDocument(v8::Isolate* i solate, v8::Handle<v8::Function> function, ExecutionContext* context, int argc, v8::Handle<v8::Value> argv[]) 235 v8::Local<v8::Object> V8ScriptRunner::instantiateObjectInDocument(v8::Isolate* i solate, v8::Handle<v8::Function> function, ExecutionContext* context, int argc, v8::Handle<v8::Value> argv[])
258 { 236 {
259 TRACE_EVENT0("v8", "v8.newInstance"); 237 TRACE_EVENT0("v8", "v8.newInstance");
260 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); 238 TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution");
261 V8RecursionScope scope(isolate, context); 239 V8RecursionScope scope(isolate, context);
262 v8::Local<v8::Object> result = function->NewInstance(argc, argv); 240 v8::Local<v8::Object> result = function->NewInstance(argc, argv);
263 crashIfV8IsDead(); 241 crashIfV8IsDead();
264 return result; 242 return result;
265 } 243 }
266 244
245 bool V8ScriptRunner::CacheDecider(
246 unsigned codeLength,
247 const ScriptResource* resource,
248 V8CacheOptions cacheOptions,
249 unsigned* dataType,
250 v8::ScriptCompiler::CompileOptions* compileOption,
251 bool* produce)
252 {
253 // Code length 0 means that we don't know it yet; don't make decisions based on it.
254 if (!resource || !resource->url().protocolIsInHTTPFamily() || (codeLength > 0 && codeLength < 1024))
255 cacheOptions = V8CacheOptionsOff;
256
257 bool useCache = false;
258 switch (cacheOptions) {
259 case V8CacheOptionsOff:
260 *compileOption = v8::ScriptCompiler::kNoCompileOptions;
261 useCache = false;
262 break;
263 case V8CacheOptionsParse:
264 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2;
265 *produce = !resource->cachedMetadata(*dataType);
266 *compileOption = *produce ? v8::ScriptCompiler::kProduceParserCache : v8 ::ScriptCompiler::kConsumeParserCache;
267 useCache = true;
268 break;
269 case V8CacheOptionsCode:
270 *dataType = StringHash::hash(v8::V8::GetVersion()) * 2 + 1;
271 *produce = !resource->cachedMetadata(*dataType);
272 *compileOption = *produce ? v8::ScriptCompiler::kProduceCodeCache : v8:: ScriptCompiler::kConsumeCodeCache;
273 useCache = true;
274 break;
275 }
276 return useCache;
277 }
278
279
267 } // namespace blink 280 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698