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

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

Issue 528013002: Restore in-memory parser cache for V8 compile. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 3 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 | « no previous file | Source/core/fetch/Resource.h » ('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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « no previous file | Source/core/fetch/Resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698