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

Side by Side Diff: src/compilation-cache.cc

Issue 2674593003: [TypeFeedbackVector] Root feedback vectors at function literal site. (Closed)
Patch Set: REBASE+liveedit fix. Created 3 years, 10 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 | « src/compilation-cache.h ('k') | src/compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compilation-cache.h" 5 #include "src/compilation-cache.h"
6 6
7 #include "src/counters.h" 7 #include "src/counters.h"
8 #include "src/factory.h" 8 #include "src/factory.h"
9 #include "src/globals.h" 9 #include "src/globals.h"
10 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 // The number of generations for each sub cache. 16 // The number of generations for each sub cache.
17 static const int kRegExpGenerations = 2; 17 static const int kRegExpGenerations = 2;
18 18
19 // Initial size of each compilation cache table allocated. 19 // Initial size of each compilation cache table allocated.
20 static const int kInitialCacheSize = 64; 20 static const int kInitialCacheSize = 64;
21 21
22
23 CompilationCache::CompilationCache(Isolate* isolate) 22 CompilationCache::CompilationCache(Isolate* isolate)
24 : isolate_(isolate), 23 : isolate_(isolate),
25 script_(isolate, 1), 24 script_(isolate),
26 eval_global_(isolate, 1), 25 eval_global_(isolate),
27 eval_contextual_(isolate, 1), 26 eval_contextual_(isolate),
28 reg_exp_(isolate, kRegExpGenerations), 27 reg_exp_(isolate, kRegExpGenerations),
29 enabled_(true) { 28 enabled_(true) {
30 CompilationSubCache* subcaches[kSubCacheCount] = 29 CompilationSubCache* subcaches[kSubCacheCount] =
31 {&script_, &eval_global_, &eval_contextual_, &reg_exp_}; 30 {&script_, &eval_global_, &eval_contextual_, &reg_exp_};
32 for (int i = 0; i < kSubCacheCount; ++i) { 31 for (int i = 0; i < kSubCacheCount; ++i) {
33 subcaches_[i] = subcaches[i]; 32 subcaches_[i] = subcaches[i];
34 } 33 }
35 } 34 }
36 35
37 36
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 // Probe the script generation tables. Make sure not to leak handles 95 // Probe the script generation tables. Make sure not to leak handles
97 // into the caller's handle scope. 96 // into the caller's handle scope.
98 { HandleScope scope(isolate()); 97 { HandleScope scope(isolate());
99 for (int generation = 0; generation < generations(); generation++) { 98 for (int generation = 0; generation < generations(); generation++) {
100 Handle<CompilationCacheTable> table = GetTable(generation); 99 Handle<CompilationCacheTable> table = GetTable(generation);
101 table->Remove(*function_info); 100 table->Remove(*function_info);
102 } 101 }
103 } 102 }
104 } 103 }
105 104
106 105 CompilationCacheScript::CompilationCacheScript(Isolate* isolate)
107 CompilationCacheScript::CompilationCacheScript(Isolate* isolate, 106 : CompilationSubCache(isolate, 1) {}
108 int generations)
109 : CompilationSubCache(isolate, generations) {}
110
111 107
112 // We only re-use a cached function for some script source code if the 108 // We only re-use a cached function for some script source code if the
113 // script originates from the same place. This is to avoid issues 109 // script originates from the same place. This is to avoid issues
114 // when reporting errors, etc. 110 // when reporting errors, etc.
115 bool CompilationCacheScript::HasOrigin(Handle<SharedFunctionInfo> function_info, 111 bool CompilationCacheScript::HasOrigin(Handle<SharedFunctionInfo> function_info,
116 Handle<Object> name, int line_offset, 112 Handle<Object> name, int line_offset,
117 int column_offset, 113 int column_offset,
118 ScriptOriginOptions resource_options) { 114 ScriptOriginOptions resource_options) {
119 Handle<Script> script = 115 Handle<Script> script =
120 Handle<Script>(Script::cast(function_info->script()), isolate()); 116 Handle<Script>(Script::cast(function_info->script()), isolate());
(...skipping 13 matching lines...) Expand all
134 // Compare the two name strings for equality. 130 // Compare the two name strings for equality.
135 return String::Equals(Handle<String>::cast(name), 131 return String::Equals(Handle<String>::cast(name),
136 Handle<String>(String::cast(script->name()))); 132 Handle<String>(String::cast(script->name())));
137 } 133 }
138 134
139 135
140 // TODO(245): Need to allow identical code from different contexts to 136 // TODO(245): Need to allow identical code from different contexts to
141 // be cached in the same script generation. Currently the first use 137 // be cached in the same script generation. Currently the first use
142 // will be cached, but subsequent code from different source / line 138 // will be cached, but subsequent code from different source / line
143 // won't. 139 // won't.
144 Handle<SharedFunctionInfo> CompilationCacheScript::Lookup( 140 InfoVectorPair CompilationCacheScript::Lookup(
145 Handle<String> source, Handle<Object> name, int line_offset, 141 Handle<String> source, Handle<Object> name, int line_offset,
146 int column_offset, ScriptOriginOptions resource_options, 142 int column_offset, ScriptOriginOptions resource_options,
147 Handle<Context> context, LanguageMode language_mode) { 143 Handle<Context> context, LanguageMode language_mode) {
148 Object* result = NULL; 144 InfoVectorPair result;
149 int generation;
150 145
151 // Probe the script generation tables. Make sure not to leak handles 146 // Probe the script generation tables. Make sure not to leak handles
152 // into the caller's handle scope. 147 // into the caller's handle scope.
153 { HandleScope scope(isolate()); 148 { HandleScope scope(isolate());
154 for (generation = 0; generation < generations(); generation++) { 149 const int generation = 0;
155 Handle<CompilationCacheTable> table = GetTable(generation); 150 DCHECK(generations() == 1);
156 Handle<Object> probe = table->Lookup(source, context, language_mode); 151 Handle<CompilationCacheTable> table = GetTable(generation);
157 if (probe->IsSharedFunctionInfo()) { 152 InfoVectorPair probe = table->LookupScript(source, context, language_mode);
158 Handle<SharedFunctionInfo> function_info = 153 if (probe.has_shared()) {
159 Handle<SharedFunctionInfo>::cast(probe); 154 Handle<SharedFunctionInfo> function_info(probe.shared(), isolate());
160 // Break when we've found a suitable shared function info that 155 Handle<Cell> vector_handle;
161 // matches the origin. 156 if (probe.has_vector()) {
162 if (HasOrigin(function_info, name, line_offset, column_offset, 157 vector_handle = Handle<Cell>(probe.vector(), isolate());
163 resource_options)) { 158 }
164 result = *function_info; 159 // Break when we've found a suitable shared function info that
165 break; 160 // matches the origin.
166 } 161 if (HasOrigin(function_info, name, line_offset, column_offset,
162 resource_options)) {
163 result = InfoVectorPair(*function_info,
164 probe.has_vector() ? *vector_handle : nullptr);
167 } 165 }
168 } 166 }
169 } 167 }
170 168
171 // Once outside the manacles of the handle scope, we need to recheck 169 // Once outside the manacles of the handle scope, we need to recheck
172 // to see if we actually found a cached script. If so, we return a 170 // to see if we actually found a cached script. If so, we return a
173 // handle created in the caller's handle scope. 171 // handle created in the caller's handle scope.
174 if (result != NULL) { 172 if (result.has_shared()) {
175 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result), 173 Handle<SharedFunctionInfo> shared(result.shared(), isolate());
176 isolate()); 174 // TODO(mvstanton): Make sure HasOrigin can't allocate, or it will
175 // mess up our InfoVectorPair.
177 DCHECK( 176 DCHECK(
178 HasOrigin(shared, name, line_offset, column_offset, resource_options)); 177 HasOrigin(shared, name, line_offset, column_offset, resource_options));
179 // If the script was found in a later generation, we promote it to
180 // the first generation to let it survive longer in the cache.
181 if (generation != 0) Put(source, context, language_mode, shared);
182 isolate()->counters()->compilation_cache_hits()->Increment(); 178 isolate()->counters()->compilation_cache_hits()->Increment();
183 return shared;
184 } else { 179 } else {
185 isolate()->counters()->compilation_cache_misses()->Increment(); 180 isolate()->counters()->compilation_cache_misses()->Increment();
186 return Handle<SharedFunctionInfo>::null();
187 } 181 }
182 return result;
188 } 183 }
189 184
190 185 void CompilationCacheScript::Put(Handle<String> source, Handle<Context> context,
191 void CompilationCacheScript::Put(Handle<String> source,
192 Handle<Context> context,
193 LanguageMode language_mode, 186 LanguageMode language_mode,
194 Handle<SharedFunctionInfo> function_info) { 187 Handle<SharedFunctionInfo> function_info,
188 Handle<Cell> literals) {
195 HandleScope scope(isolate()); 189 HandleScope scope(isolate());
196 Handle<CompilationCacheTable> table = GetFirstTable(); 190 Handle<CompilationCacheTable> table = GetFirstTable();
197 SetFirstTable(CompilationCacheTable::Put(table, source, context, 191 SetFirstTable(CompilationCacheTable::PutScript(
198 language_mode, function_info)); 192 table, source, context, language_mode, function_info, literals));
199 } 193 }
200 194
201 195 InfoVectorPair CompilationCacheEval::Lookup(
202 MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
203 Handle<String> source, Handle<SharedFunctionInfo> outer_info, 196 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
204 LanguageMode language_mode, int scope_position) { 197 Handle<Context> native_context, LanguageMode language_mode,
198 int scope_position) {
205 HandleScope scope(isolate()); 199 HandleScope scope(isolate());
206 // Make sure not to leak the table into the surrounding handle 200 // Make sure not to leak the table into the surrounding handle
207 // scope. Otherwise, we risk keeping old tables around even after 201 // scope. Otherwise, we risk keeping old tables around even after
208 // having cleared the cache. 202 // having cleared the cache.
209 Handle<Object> result = isolate()->factory()->undefined_value(); 203 InfoVectorPair result;
210 int generation; 204 const int generation = 0;
211 for (generation = 0; generation < generations(); generation++) { 205 DCHECK(generations() == 1);
212 Handle<CompilationCacheTable> table = GetTable(generation); 206 Handle<CompilationCacheTable> table = GetTable(generation);
213 result = 207 result = table->LookupEval(source, outer_info, native_context, language_mode,
214 table->LookupEval(source, outer_info, language_mode, scope_position); 208 scope_position);
215 if (result->IsSharedFunctionInfo()) break; 209 if (result.has_shared()) {
216 }
217 if (result->IsSharedFunctionInfo()) {
218 Handle<SharedFunctionInfo> function_info =
219 Handle<SharedFunctionInfo>::cast(result);
220 if (generation != 0) {
221 Put(source, outer_info, function_info, scope_position);
222 }
223 isolate()->counters()->compilation_cache_hits()->Increment(); 210 isolate()->counters()->compilation_cache_hits()->Increment();
224 return scope.CloseAndEscape(function_info);
225 } else { 211 } else {
226 isolate()->counters()->compilation_cache_misses()->Increment(); 212 isolate()->counters()->compilation_cache_misses()->Increment();
227 return MaybeHandle<SharedFunctionInfo>();
228 } 213 }
214 return result;
229 } 215 }
230 216
231
232 void CompilationCacheEval::Put(Handle<String> source, 217 void CompilationCacheEval::Put(Handle<String> source,
233 Handle<SharedFunctionInfo> outer_info, 218 Handle<SharedFunctionInfo> outer_info,
234 Handle<SharedFunctionInfo> function_info, 219 Handle<SharedFunctionInfo> function_info,
235 int scope_position) { 220 Handle<Context> native_context,
221 Handle<Cell> literals, int scope_position) {
236 HandleScope scope(isolate()); 222 HandleScope scope(isolate());
237 Handle<CompilationCacheTable> table = GetFirstTable(); 223 Handle<CompilationCacheTable> table = GetFirstTable();
238 table = CompilationCacheTable::PutEval(table, source, outer_info, 224 table =
239 function_info, scope_position); 225 CompilationCacheTable::PutEval(table, source, outer_info, function_info,
226 native_context, literals, scope_position);
240 SetFirstTable(table); 227 SetFirstTable(table);
241 } 228 }
242 229
243 230
244 MaybeHandle<FixedArray> CompilationCacheRegExp::Lookup( 231 MaybeHandle<FixedArray> CompilationCacheRegExp::Lookup(
245 Handle<String> source, 232 Handle<String> source,
246 JSRegExp::Flags flags) { 233 JSRegExp::Flags flags) {
247 HandleScope scope(isolate()); 234 HandleScope scope(isolate());
248 // Make sure not to leak the table into the surrounding handle 235 // Make sure not to leak the table into the surrounding handle
249 // scope. Otherwise, we risk keeping old tables around even after 236 // scope. Otherwise, we risk keeping old tables around even after
(...skipping 29 matching lines...) Expand all
279 266
280 267
281 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { 268 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
282 if (!IsEnabled()) return; 269 if (!IsEnabled()) return;
283 270
284 eval_global_.Remove(function_info); 271 eval_global_.Remove(function_info);
285 eval_contextual_.Remove(function_info); 272 eval_contextual_.Remove(function_info);
286 script_.Remove(function_info); 273 script_.Remove(function_info);
287 } 274 }
288 275
289 276 InfoVectorPair CompilationCache::LookupScript(
290 MaybeHandle<SharedFunctionInfo> CompilationCache::LookupScript(
291 Handle<String> source, Handle<Object> name, int line_offset, 277 Handle<String> source, Handle<Object> name, int line_offset,
292 int column_offset, ScriptOriginOptions resource_options, 278 int column_offset, ScriptOriginOptions resource_options,
293 Handle<Context> context, LanguageMode language_mode) { 279 Handle<Context> context, LanguageMode language_mode) {
294 if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); 280 InfoVectorPair empty_result;
281 if (!IsEnabled()) return empty_result;
295 282
296 return script_.Lookup(source, name, line_offset, column_offset, 283 return script_.Lookup(source, name, line_offset, column_offset,
297 resource_options, context, language_mode); 284 resource_options, context, language_mode);
298 } 285 }
299 286
300 287 InfoVectorPair CompilationCache::LookupEval(
301 MaybeHandle<SharedFunctionInfo> CompilationCache::LookupEval(
302 Handle<String> source, Handle<SharedFunctionInfo> outer_info, 288 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
303 Handle<Context> context, LanguageMode language_mode, int scope_position) { 289 Handle<Context> context, LanguageMode language_mode, int scope_position) {
304 if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); 290 InfoVectorPair result;
291 if (!IsEnabled()) return result;
305 292
306 MaybeHandle<SharedFunctionInfo> result;
307 if (context->IsNativeContext()) { 293 if (context->IsNativeContext()) {
308 result = 294 result = eval_global_.Lookup(source, outer_info, context, language_mode,
309 eval_global_.Lookup(source, outer_info, language_mode, scope_position); 295 scope_position);
310 } else { 296 } else {
311 DCHECK(scope_position != kNoSourcePosition); 297 DCHECK(scope_position != kNoSourcePosition);
312 result = eval_contextual_.Lookup(source, outer_info, language_mode, 298 Handle<Context> native_context(context->native_context(), isolate());
313 scope_position); 299 result = eval_contextual_.Lookup(source, outer_info, native_context,
300 language_mode, scope_position);
314 } 301 }
302
315 return result; 303 return result;
316 } 304 }
317 305
318 306
319 MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, 307 MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
320 JSRegExp::Flags flags) { 308 JSRegExp::Flags flags) {
321 if (!IsEnabled()) return MaybeHandle<FixedArray>(); 309 if (!IsEnabled()) return MaybeHandle<FixedArray>();
322 310
323 return reg_exp_.Lookup(source, flags); 311 return reg_exp_.Lookup(source, flags);
324 } 312 }
325 313
326 314 void CompilationCache::PutScript(Handle<String> source, Handle<Context> context,
327 void CompilationCache::PutScript(Handle<String> source,
328 Handle<Context> context,
329 LanguageMode language_mode, 315 LanguageMode language_mode,
330 Handle<SharedFunctionInfo> function_info) { 316 Handle<SharedFunctionInfo> function_info,
317 Handle<Cell> literals) {
331 if (!IsEnabled()) return; 318 if (!IsEnabled()) return;
332 319
333 script_.Put(source, context, language_mode, function_info); 320 script_.Put(source, context, language_mode, function_info, literals);
334 } 321 }
335 322
336
337 void CompilationCache::PutEval(Handle<String> source, 323 void CompilationCache::PutEval(Handle<String> source,
338 Handle<SharedFunctionInfo> outer_info, 324 Handle<SharedFunctionInfo> outer_info,
339 Handle<Context> context, 325 Handle<Context> context,
340 Handle<SharedFunctionInfo> function_info, 326 Handle<SharedFunctionInfo> function_info,
341 int scope_position) { 327 Handle<Cell> literals, int scope_position) {
342 if (!IsEnabled()) return; 328 if (!IsEnabled()) return;
343 329
344 HandleScope scope(isolate()); 330 HandleScope scope(isolate());
345 if (context->IsNativeContext()) { 331 if (context->IsNativeContext()) {
346 eval_global_.Put(source, outer_info, function_info, scope_position); 332 eval_global_.Put(source, outer_info, function_info, context, literals,
333 scope_position);
347 } else { 334 } else {
348 DCHECK(scope_position != kNoSourcePosition); 335 DCHECK(scope_position != kNoSourcePosition);
349 eval_contextual_.Put(source, outer_info, function_info, scope_position); 336 Handle<Context> native_context(context->native_context(), isolate());
337 eval_contextual_.Put(source, outer_info, function_info, native_context,
338 literals, scope_position);
350 } 339 }
351 } 340 }
352 341
353 342
354 343
355 void CompilationCache::PutRegExp(Handle<String> source, 344 void CompilationCache::PutRegExp(Handle<String> source,
356 JSRegExp::Flags flags, 345 JSRegExp::Flags flags,
357 Handle<FixedArray> data) { 346 Handle<FixedArray> data) {
358 if (!IsEnabled()) { 347 if (!IsEnabled()) {
359 return; 348 return;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 386
398 387
399 void CompilationCache::Disable() { 388 void CompilationCache::Disable() {
400 enabled_ = false; 389 enabled_ = false;
401 Clear(); 390 Clear();
402 } 391 }
403 392
404 393
405 } // namespace internal 394 } // namespace internal
406 } // namespace v8 395 } // namespace v8
OLDNEW
« no previous file with comments | « src/compilation-cache.h ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698