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

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

Issue 2674593003: [TypeFeedbackVector] Root feedback vectors at function literal site. (Closed)
Patch Set: REBASE. 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
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; 145 int generation;
150 146
151 // Probe the script generation tables. Make sure not to leak handles 147 // Probe the script generation tables. Make sure not to leak handles
152 // into the caller's handle scope. 148 // into the caller's handle scope.
153 { HandleScope scope(isolate()); 149 { HandleScope scope(isolate());
154 for (generation = 0; generation < generations(); generation++) { 150 const int generation = 0;
155 Handle<CompilationCacheTable> table = GetTable(generation); 151 DCHECK(generations() == 1);
156 Handle<Object> probe = table->Lookup(source, context, language_mode); 152 Handle<CompilationCacheTable> table = GetTable(generation);
157 if (probe->IsSharedFunctionInfo()) { 153 InfoVectorPair probe = table->LookupScript(source, context, language_mode);
158 Handle<SharedFunctionInfo> function_info = 154 if (probe.has_info()) {
159 Handle<SharedFunctionInfo>::cast(probe); 155 Handle<SharedFunctionInfo> function_info(probe.info(), isolate());
160 // Break when we've found a suitable shared function info that 156 Handle<Cell> vector_handle;
161 // matches the origin. 157 if (probe.has_vector()) {
162 if (HasOrigin(function_info, name, line_offset, column_offset, 158 vector_handle = Handle<Cell>(probe.vector(), isolate());
163 resource_options)) { 159 }
164 result = *function_info; 160 // Break when we've found a suitable shared function info that
165 break; 161 // matches the origin.
166 } 162 if (HasOrigin(function_info, name, line_offset, column_offset,
163 resource_options)) {
164 result = InfoVectorPair(*function_info,
165 probe.has_vector() ? *vector_handle : nullptr);
167 } 166 }
168 } 167 }
169 } 168 }
170 169
171 // Once outside the manacles of the handle scope, we need to recheck 170 // 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 171 // to see if we actually found a cached script. If so, we return a
173 // handle created in the caller's handle scope. 172 // handle created in the caller's handle scope.
174 if (result != NULL) { 173 if (result.has_info()) {
175 Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(result), 174 Handle<SharedFunctionInfo> shared(result.info(), isolate());
176 isolate()); 175 // TODO(mvstanton): Make sure HasOrigin can't allocate, or it will
176 // mess up our InfoVectorPair.
177 DCHECK( 177 DCHECK(
178 HasOrigin(shared, name, line_offset, column_offset, resource_options)); 178 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(); 179 isolate()->counters()->compilation_cache_hits()->Increment();
183 return shared;
184 } else { 180 } else {
185 isolate()->counters()->compilation_cache_misses()->Increment(); 181 isolate()->counters()->compilation_cache_misses()->Increment();
186 return Handle<SharedFunctionInfo>::null();
187 } 182 }
183 return result;
188 } 184 }
189 185
190 186 void CompilationCacheScript::Put(Handle<String> source, Handle<Context> context,
191 void CompilationCacheScript::Put(Handle<String> source,
192 Handle<Context> context,
193 LanguageMode language_mode, 187 LanguageMode language_mode,
194 Handle<SharedFunctionInfo> function_info) { 188 Handle<SharedFunctionInfo> function_info,
189 Handle<Cell> literals) {
195 HandleScope scope(isolate()); 190 HandleScope scope(isolate());
196 Handle<CompilationCacheTable> table = GetFirstTable(); 191 Handle<CompilationCacheTable> table = GetFirstTable();
197 SetFirstTable(CompilationCacheTable::Put(table, source, context, 192 SetFirstTable(CompilationCacheTable::PutScript(
198 language_mode, function_info)); 193 table, source, context, language_mode, function_info, literals));
199 } 194 }
200 195
201 196 InfoVectorPair CompilationCacheEval::Lookup(
202 MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
203 Handle<String> source, Handle<SharedFunctionInfo> outer_info, 197 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
204 LanguageMode language_mode, int scope_position) { 198 Handle<Context> native_context, LanguageMode language_mode,
199 int scope_position) {
205 HandleScope scope(isolate()); 200 HandleScope scope(isolate());
206 // Make sure not to leak the table into the surrounding handle 201 // Make sure not to leak the table into the surrounding handle
207 // scope. Otherwise, we risk keeping old tables around even after 202 // scope. Otherwise, we risk keeping old tables around even after
208 // having cleared the cache. 203 // having cleared the cache.
209 Handle<Object> result = isolate()->factory()->undefined_value(); 204 InfoVectorPair result;
210 int generation; 205 const int generation = 0;
211 for (generation = 0; generation < generations(); generation++) { 206 DCHECK(generations() == 1);
212 Handle<CompilationCacheTable> table = GetTable(generation); 207 Handle<CompilationCacheTable> table = GetTable(generation);
213 result = 208 result = table->LookupEval(source, outer_info, native_context, language_mode,
214 table->LookupEval(source, outer_info, language_mode, scope_position); 209 scope_position);
215 if (result->IsSharedFunctionInfo()) break; 210 if (result.has_info()) {
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(); 211 isolate()->counters()->compilation_cache_hits()->Increment();
224 return scope.CloseAndEscape(function_info);
225 } else { 212 } else {
226 isolate()->counters()->compilation_cache_misses()->Increment(); 213 isolate()->counters()->compilation_cache_misses()->Increment();
227 return MaybeHandle<SharedFunctionInfo>();
228 } 214 }
215 return result;
229 } 216 }
230 217
231
232 void CompilationCacheEval::Put(Handle<String> source, 218 void CompilationCacheEval::Put(Handle<String> source,
233 Handle<SharedFunctionInfo> outer_info, 219 Handle<SharedFunctionInfo> outer_info,
234 Handle<SharedFunctionInfo> function_info, 220 Handle<SharedFunctionInfo> function_info,
235 int scope_position) { 221 Handle<Context> native_context,
222 Handle<Cell> literals, int scope_position) {
236 HandleScope scope(isolate()); 223 HandleScope scope(isolate());
237 Handle<CompilationCacheTable> table = GetFirstTable(); 224 Handle<CompilationCacheTable> table = GetFirstTable();
238 table = CompilationCacheTable::PutEval(table, source, outer_info, 225 table =
239 function_info, scope_position); 226 CompilationCacheTable::PutEval(table, source, outer_info, function_info,
227 native_context, literals, scope_position);
240 SetFirstTable(table); 228 SetFirstTable(table);
241 } 229 }
242 230
243 231
244 MaybeHandle<FixedArray> CompilationCacheRegExp::Lookup( 232 MaybeHandle<FixedArray> CompilationCacheRegExp::Lookup(
245 Handle<String> source, 233 Handle<String> source,
246 JSRegExp::Flags flags) { 234 JSRegExp::Flags flags) {
247 HandleScope scope(isolate()); 235 HandleScope scope(isolate());
248 // Make sure not to leak the table into the surrounding handle 236 // Make sure not to leak the table into the surrounding handle
249 // scope. Otherwise, we risk keeping old tables around even after 237 // scope. Otherwise, we risk keeping old tables around even after
(...skipping 29 matching lines...) Expand all
279 267
280 268
281 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { 269 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) {
282 if (!IsEnabled()) return; 270 if (!IsEnabled()) return;
283 271
284 eval_global_.Remove(function_info); 272 eval_global_.Remove(function_info);
285 eval_contextual_.Remove(function_info); 273 eval_contextual_.Remove(function_info);
286 script_.Remove(function_info); 274 script_.Remove(function_info);
287 } 275 }
288 276
289 277 InfoVectorPair CompilationCache::LookupScript(
290 MaybeHandle<SharedFunctionInfo> CompilationCache::LookupScript(
291 Handle<String> source, Handle<Object> name, int line_offset, 278 Handle<String> source, Handle<Object> name, int line_offset,
292 int column_offset, ScriptOriginOptions resource_options, 279 int column_offset, ScriptOriginOptions resource_options,
293 Handle<Context> context, LanguageMode language_mode) { 280 Handle<Context> context, LanguageMode language_mode) {
294 if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); 281 InfoVectorPair empty_result;
282 if (!IsEnabled()) return empty_result;
295 283
296 return script_.Lookup(source, name, line_offset, column_offset, 284 return script_.Lookup(source, name, line_offset, column_offset,
297 resource_options, context, language_mode); 285 resource_options, context, language_mode);
298 } 286 }
299 287
300 288 InfoVectorPair CompilationCache::LookupEval(
301 MaybeHandle<SharedFunctionInfo> CompilationCache::LookupEval(
302 Handle<String> source, Handle<SharedFunctionInfo> outer_info, 289 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
303 Handle<Context> context, LanguageMode language_mode, int scope_position) { 290 Handle<Context> context, LanguageMode language_mode, int scope_position) {
304 if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); 291 InfoVectorPair result;
292 if (!IsEnabled()) return result;
305 293
306 MaybeHandle<SharedFunctionInfo> result;
307 if (context->IsNativeContext()) { 294 if (context->IsNativeContext()) {
308 result = 295 result = eval_global_.Lookup(source, outer_info, context, language_mode,
309 eval_global_.Lookup(source, outer_info, language_mode, scope_position); 296 scope_position);
310 } else { 297 } else {
311 DCHECK(scope_position != kNoSourcePosition); 298 DCHECK(scope_position != kNoSourcePosition);
312 result = eval_contextual_.Lookup(source, outer_info, language_mode, 299 Handle<Context> native_context(context->native_context(), isolate());
313 scope_position); 300 result = eval_contextual_.Lookup(source, outer_info, native_context,
301 language_mode, scope_position);
314 } 302 }
303
315 return result; 304 return result;
316 } 305 }
317 306
318 307
319 MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, 308 MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source,
320 JSRegExp::Flags flags) { 309 JSRegExp::Flags flags) {
321 if (!IsEnabled()) return MaybeHandle<FixedArray>(); 310 if (!IsEnabled()) return MaybeHandle<FixedArray>();
322 311
323 return reg_exp_.Lookup(source, flags); 312 return reg_exp_.Lookup(source, flags);
324 } 313 }
325 314
326 315 void CompilationCache::PutScript(Handle<String> source, Handle<Context> context,
327 void CompilationCache::PutScript(Handle<String> source,
328 Handle<Context> context,
329 LanguageMode language_mode, 316 LanguageMode language_mode,
330 Handle<SharedFunctionInfo> function_info) { 317 Handle<SharedFunctionInfo> function_info,
318 Handle<Cell> literals) {
331 if (!IsEnabled()) return; 319 if (!IsEnabled()) return;
332 320
333 script_.Put(source, context, language_mode, function_info); 321 script_.Put(source, context, language_mode, function_info, literals);
334 } 322 }
335 323
336
337 void CompilationCache::PutEval(Handle<String> source, 324 void CompilationCache::PutEval(Handle<String> source,
338 Handle<SharedFunctionInfo> outer_info, 325 Handle<SharedFunctionInfo> outer_info,
339 Handle<Context> context, 326 Handle<Context> context,
340 Handle<SharedFunctionInfo> function_info, 327 Handle<SharedFunctionInfo> function_info,
341 int scope_position) { 328 Handle<Cell> literals, int scope_position) {
342 if (!IsEnabled()) return; 329 if (!IsEnabled()) return;
343 330
344 HandleScope scope(isolate()); 331 HandleScope scope(isolate());
345 if (context->IsNativeContext()) { 332 if (context->IsNativeContext()) {
346 eval_global_.Put(source, outer_info, function_info, scope_position); 333 eval_global_.Put(source, outer_info, function_info, context, literals,
334 scope_position);
347 } else { 335 } else {
348 DCHECK(scope_position != kNoSourcePosition); 336 DCHECK(scope_position != kNoSourcePosition);
349 eval_contextual_.Put(source, outer_info, function_info, scope_position); 337 Handle<Context> native_context(context->native_context(), isolate());
338 eval_contextual_.Put(source, outer_info, function_info, native_context,
339 literals, scope_position);
350 } 340 }
351 } 341 }
352 342
353 343
354 344
355 void CompilationCache::PutRegExp(Handle<String> source, 345 void CompilationCache::PutRegExp(Handle<String> source,
356 JSRegExp::Flags flags, 346 JSRegExp::Flags flags,
357 Handle<FixedArray> data) { 347 Handle<FixedArray> data) {
358 if (!IsEnabled()) { 348 if (!IsEnabled()) {
359 return; 349 return;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 387
398 388
399 void CompilationCache::Disable() { 389 void CompilationCache::Disable() {
400 enabled_ = false; 390 enabled_ = false;
401 Clear(); 391 Clear();
402 } 392 }
403 393
404 394
405 } // namespace internal 395 } // namespace internal
406 } // namespace v8 396 } // namespace v8
OLDNEW
« no previous file with comments | « src/compilation-cache.h ('k') | src/compiler.cc » ('j') | src/debug/liveedit.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698