OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 | 137 |
138 Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); | 138 Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); |
139 | 139 |
140 void Put(Handle<String> source, | 140 void Put(Handle<String> source, |
141 JSRegExp::Flags flags, | 141 JSRegExp::Flags flags, |
142 Handle<FixedArray> data); | 142 Handle<FixedArray> data); |
143 | 143 |
144 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); | 144 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); |
145 }; | 145 }; |
146 | 146 |
| 147 class CompilationCachePrivateData { |
| 148 public: |
| 149 // Current enable state of the compilation cache. |
| 150 bool enabled_; |
| 151 CompilationCacheScript script_; |
| 152 CompilationCacheEval eval_global_; |
| 153 CompilationCacheEval eval_contextual_; |
| 154 CompilationCacheRegExp reg_exp_; |
| 155 CompilationSubCache* subcaches_[kSubCacheCount]; |
147 | 156 |
148 // Statically allocate all the sub-caches. | 157 CompilationCachePrivateData() |
149 static CompilationCacheScript script(kScriptGenerations); | 158 : enabled_(true), |
150 static CompilationCacheEval eval_global(kEvalGlobalGenerations); | 159 script_(kScriptGenerations), |
151 static CompilationCacheEval eval_contextual(kEvalContextualGenerations); | 160 eval_global_(kEvalGlobalGenerations), |
152 static CompilationCacheRegExp reg_exp(kRegExpGenerations); | 161 eval_contextual_(kEvalContextualGenerations), |
153 static CompilationSubCache* subcaches[kSubCacheCount] = | 162 reg_exp_(kRegExpGenerations) { |
154 {&script, &eval_global, &eval_contextual, ®_exp}; | 163 CompilationSubCache* subcaches[kSubCacheCount] = |
| 164 {&script_, &eval_global_, &eval_contextual_, ®_exp_}; |
155 | 165 |
| 166 for (int i = 0; i < kSubCacheCount; ++i) { |
| 167 subcaches_[i] = subcaches[i]; |
| 168 } |
| 169 } |
| 170 }; |
156 | 171 |
157 // Current enable state of the compilation cache. | 172 CompilationCacheData::CompilationCacheData() |
158 static bool enabled = true; | 173 :private_data_(*new CompilationCachePrivateData()) { |
| 174 } |
| 175 |
| 176 CompilationCacheData::~CompilationCacheData() { |
| 177 delete &private_data_; |
| 178 } |
| 179 |
159 static inline bool IsEnabled() { | 180 static inline bool IsEnabled() { |
160 return FLAG_compilation_cache && enabled; | 181 return FLAG_compilation_cache && |
| 182 v8_context()->compilation_cache_data_.private_data_.enabled_; |
161 } | 183 } |
162 | 184 |
163 | 185 |
164 static Handle<CompilationCacheTable> AllocateTable(int size) { | 186 static Handle<CompilationCacheTable> AllocateTable(int size) { |
165 CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), | 187 CALL_HEAP_FUNCTION(CompilationCacheTable::Allocate(size), |
166 CompilationCacheTable); | 188 CompilationCacheTable); |
167 } | 189 } |
168 | 190 |
169 | 191 |
170 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { | 192 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 293 |
272 // Once outside the manacles of the handle scope, we need to recheck | 294 // Once outside the manacles of the handle scope, we need to recheck |
273 // to see if we actually found a cached script. If so, we return a | 295 // to see if we actually found a cached script. If so, we return a |
274 // handle created in the caller's handle scope. | 296 // handle created in the caller's handle scope. |
275 if (result != NULL) { | 297 if (result != NULL) { |
276 Handle<JSFunction> boilerplate(JSFunction::cast(result)); | 298 Handle<JSFunction> boilerplate(JSFunction::cast(result)); |
277 ASSERT(HasOrigin(boilerplate, name, line_offset, column_offset)); | 299 ASSERT(HasOrigin(boilerplate, name, line_offset, column_offset)); |
278 // If the script was found in a later generation, we promote it to | 300 // If the script was found in a later generation, we promote it to |
279 // the first generation to let it survive longer in the cache. | 301 // the first generation to let it survive longer in the cache. |
280 if (generation != 0) Put(source, boilerplate); | 302 if (generation != 0) Put(source, boilerplate); |
281 Counters::compilation_cache_hits.Increment(); | 303 INC_COUNTER(compilation_cache_hits); |
282 return boilerplate; | 304 return boilerplate; |
283 } else { | 305 } else { |
284 Counters::compilation_cache_misses.Increment(); | 306 INC_COUNTER(compilation_cache_misses); |
285 return Handle<JSFunction>::null(); | 307 return Handle<JSFunction>::null(); |
286 } | 308 } |
287 } | 309 } |
288 | 310 |
289 | 311 |
290 void CompilationCacheScript::Put(Handle<String> source, | 312 void CompilationCacheScript::Put(Handle<String> source, |
291 Handle<JSFunction> boilerplate) { | 313 Handle<JSFunction> boilerplate) { |
292 HandleScope scope; | 314 HandleScope scope; |
293 ASSERT(boilerplate->IsBoilerplate()); | 315 ASSERT(boilerplate->IsBoilerplate()); |
294 Handle<CompilationCacheTable> table = GetTable(0); | 316 Handle<CompilationCacheTable> table = GetTable(0); |
(...skipping 15 matching lines...) Expand all Loading... |
310 if (result->IsJSFunction()) { | 332 if (result->IsJSFunction()) { |
311 break; | 333 break; |
312 } | 334 } |
313 } | 335 } |
314 } | 336 } |
315 if (result->IsJSFunction()) { | 337 if (result->IsJSFunction()) { |
316 Handle<JSFunction> boilerplate(JSFunction::cast(result)); | 338 Handle<JSFunction> boilerplate(JSFunction::cast(result)); |
317 if (generation != 0) { | 339 if (generation != 0) { |
318 Put(source, context, boilerplate); | 340 Put(source, context, boilerplate); |
319 } | 341 } |
320 Counters::compilation_cache_hits.Increment(); | 342 INC_COUNTER(compilation_cache_hits); |
321 return boilerplate; | 343 return boilerplate; |
322 } else { | 344 } else { |
323 Counters::compilation_cache_misses.Increment(); | 345 INC_COUNTER(compilation_cache_misses); |
324 return Handle<JSFunction>::null(); | 346 return Handle<JSFunction>::null(); |
325 } | 347 } |
326 } | 348 } |
327 | 349 |
328 | 350 |
329 void CompilationCacheEval::Put(Handle<String> source, | 351 void CompilationCacheEval::Put(Handle<String> source, |
330 Handle<Context> context, | 352 Handle<Context> context, |
331 Handle<JSFunction> boilerplate) { | 353 Handle<JSFunction> boilerplate) { |
332 HandleScope scope; | 354 HandleScope scope; |
333 ASSERT(boilerplate->IsBoilerplate()); | 355 ASSERT(boilerplate->IsBoilerplate()); |
(...skipping 16 matching lines...) Expand all Loading... |
350 if (result->IsFixedArray()) { | 372 if (result->IsFixedArray()) { |
351 break; | 373 break; |
352 } | 374 } |
353 } | 375 } |
354 } | 376 } |
355 if (result->IsFixedArray()) { | 377 if (result->IsFixedArray()) { |
356 Handle<FixedArray> data(FixedArray::cast(result)); | 378 Handle<FixedArray> data(FixedArray::cast(result)); |
357 if (generation != 0) { | 379 if (generation != 0) { |
358 Put(source, flags, data); | 380 Put(source, flags, data); |
359 } | 381 } |
360 Counters::compilation_cache_hits.Increment(); | 382 INC_COUNTER(compilation_cache_hits); |
361 return data; | 383 return data; |
362 } else { | 384 } else { |
363 Counters::compilation_cache_misses.Increment(); | 385 INC_COUNTER(compilation_cache_misses); |
364 return Handle<FixedArray>::null(); | 386 return Handle<FixedArray>::null(); |
365 } | 387 } |
366 } | 388 } |
367 | 389 |
368 | 390 |
369 void CompilationCacheRegExp::Put(Handle<String> source, | 391 void CompilationCacheRegExp::Put(Handle<String> source, |
370 JSRegExp::Flags flags, | 392 JSRegExp::Flags flags, |
371 Handle<FixedArray> data) { | 393 Handle<FixedArray> data) { |
372 HandleScope scope; | 394 HandleScope scope; |
373 Handle<CompilationCacheTable> table = GetTable(0); | 395 Handle<CompilationCacheTable> table = GetTable(0); |
374 CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data)); | 396 CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data)); |
375 } | 397 } |
376 | 398 |
377 | 399 |
378 Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source, | 400 Handle<JSFunction> CompilationCache::LookupScript(Handle<String> source, |
379 Handle<Object> name, | 401 Handle<Object> name, |
380 int line_offset, | 402 int line_offset, |
381 int column_offset) { | 403 int column_offset) { |
382 if (!IsEnabled()) { | 404 if (!IsEnabled()) { |
383 return Handle<JSFunction>::null(); | 405 return Handle<JSFunction>::null(); |
384 } | 406 } |
385 | 407 |
386 return script.Lookup(source, name, line_offset, column_offset); | 408 return v8_context()->compilation_cache_data_.private_data_. |
| 409 script_.Lookup(source, name, line_offset, column_offset); |
387 } | 410 } |
388 | 411 |
389 | 412 |
390 Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source, | 413 Handle<JSFunction> CompilationCache::LookupEval(Handle<String> source, |
391 Handle<Context> context, | 414 Handle<Context> context, |
392 bool is_global) { | 415 bool is_global) { |
393 if (!IsEnabled()) { | 416 if (!IsEnabled()) { |
394 return Handle<JSFunction>::null(); | 417 return Handle<JSFunction>::null(); |
395 } | 418 } |
396 | 419 |
397 Handle<JSFunction> result; | 420 Handle<JSFunction> result; |
398 if (is_global) { | 421 if (is_global) { |
399 result = eval_global.Lookup(source, context); | 422 result = v8_context()->compilation_cache_data_.private_data_. |
| 423 eval_global_.Lookup(source, context); |
400 } else { | 424 } else { |
401 result = eval_contextual.Lookup(source, context); | 425 result = v8_context()->compilation_cache_data_.private_data_. |
| 426 eval_contextual_.Lookup(source, context); |
402 } | 427 } |
403 return result; | 428 return result; |
404 } | 429 } |
405 | 430 |
406 | 431 |
407 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, | 432 Handle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, |
408 JSRegExp::Flags flags) { | 433 JSRegExp::Flags flags) { |
409 if (!IsEnabled()) { | 434 if (!IsEnabled()) { |
410 return Handle<FixedArray>::null(); | 435 return Handle<FixedArray>::null(); |
411 } | 436 } |
412 | 437 |
413 return reg_exp.Lookup(source, flags); | 438 return v8_context()->compilation_cache_data_.private_data_. |
| 439 reg_exp_.Lookup(source, flags); |
414 } | 440 } |
415 | 441 |
416 | 442 |
417 void CompilationCache::PutScript(Handle<String> source, | 443 void CompilationCache::PutScript(Handle<String> source, |
418 Handle<JSFunction> boilerplate) { | 444 Handle<JSFunction> boilerplate) { |
419 if (!IsEnabled()) { | 445 if (!IsEnabled()) { |
420 return; | 446 return; |
421 } | 447 } |
422 | 448 |
423 ASSERT(boilerplate->IsBoilerplate()); | 449 ASSERT(boilerplate->IsBoilerplate()); |
424 script.Put(source, boilerplate); | 450 v8_context()->compilation_cache_data_.private_data_. |
| 451 script_.Put(source, boilerplate); |
425 } | 452 } |
426 | 453 |
427 | 454 |
428 void CompilationCache::PutEval(Handle<String> source, | 455 void CompilationCache::PutEval(Handle<String> source, |
429 Handle<Context> context, | 456 Handle<Context> context, |
430 bool is_global, | 457 bool is_global, |
431 Handle<JSFunction> boilerplate) { | 458 Handle<JSFunction> boilerplate) { |
432 if (!IsEnabled()) { | 459 if (!IsEnabled()) { |
433 return; | 460 return; |
434 } | 461 } |
435 | 462 |
436 HandleScope scope; | 463 HandleScope scope; |
437 ASSERT(boilerplate->IsBoilerplate()); | 464 ASSERT(boilerplate->IsBoilerplate()); |
438 if (is_global) { | 465 if (is_global) { |
439 eval_global.Put(source, context, boilerplate); | 466 v8_context()->compilation_cache_data_.private_data_. |
| 467 eval_global_.Put(source, context, boilerplate); |
440 } else { | 468 } else { |
441 eval_contextual.Put(source, context, boilerplate); | 469 v8_context()->compilation_cache_data_.private_data_. |
| 470 eval_contextual_.Put(source, context, boilerplate); |
442 } | 471 } |
443 } | 472 } |
444 | 473 |
445 | 474 |
446 | 475 |
447 void CompilationCache::PutRegExp(Handle<String> source, | 476 void CompilationCache::PutRegExp(Handle<String> source, |
448 JSRegExp::Flags flags, | 477 JSRegExp::Flags flags, |
449 Handle<FixedArray> data) { | 478 Handle<FixedArray> data) { |
450 if (!IsEnabled()) { | 479 if (!IsEnabled()) { |
451 return; | 480 return; |
452 } | 481 } |
453 | 482 |
454 reg_exp.Put(source, flags, data); | 483 v8_context()->compilation_cache_data_.private_data_. |
| 484 reg_exp_.Put(source, flags, data); |
455 } | 485 } |
456 | 486 |
457 | 487 |
458 void CompilationCache::Clear() { | 488 void CompilationCache::Clear() { |
| 489 CompilationCachePrivateData& data = |
| 490 v8_context()->compilation_cache_data_.private_data_; |
459 for (int i = 0; i < kSubCacheCount; i++) { | 491 for (int i = 0; i < kSubCacheCount; i++) { |
460 subcaches[i]->Clear(); | 492 data.subcaches_[i]->Clear(); |
461 } | 493 } |
462 } | 494 } |
463 | 495 |
464 | 496 |
465 void CompilationCache::Iterate(ObjectVisitor* v) { | 497 void CompilationCache::Iterate(ObjectVisitor* v) { |
| 498 CompilationCachePrivateData& data = |
| 499 v8_context()->compilation_cache_data_.private_data_; |
466 for (int i = 0; i < kSubCacheCount; i++) { | 500 for (int i = 0; i < kSubCacheCount; i++) { |
467 subcaches[i]->Iterate(v); | 501 data.subcaches_[i]->Iterate(v); |
468 } | 502 } |
469 } | 503 } |
470 | 504 |
471 | 505 |
472 void CompilationCache::MarkCompactPrologue() { | 506 void CompilationCache::MarkCompactPrologue() { |
| 507 CompilationCachePrivateData& data = |
| 508 v8_context()->compilation_cache_data_.private_data_; |
473 for (int i = 0; i < kSubCacheCount; i++) { | 509 for (int i = 0; i < kSubCacheCount; i++) { |
474 subcaches[i]->Age(); | 510 data.subcaches_[i]->Age(); |
475 } | 511 } |
476 } | 512 } |
477 | 513 |
478 | 514 |
479 void CompilationCache::Enable() { | 515 void CompilationCache::Enable() { |
480 enabled = true; | 516 v8_context()->compilation_cache_data_.private_data_.enabled_ = true; |
481 } | 517 } |
482 | 518 |
483 | 519 |
484 void CompilationCache::Disable() { | 520 void CompilationCache::Disable() { |
485 enabled = false; | 521 v8_context()->compilation_cache_data_.private_data_.enabled_ = false; |
486 Clear(); | 522 Clear(); |
487 } | 523 } |
488 | 524 |
489 | 525 |
490 } } // namespace v8::internal | 526 } } // namespace v8::internal |
OLD | NEW |