| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 // Initial size of each compilation cache table allocated. | 45 // Initial size of each compilation cache table allocated. |
| 46 static const int kInitialCacheSize = 64; | 46 static const int kInitialCacheSize = 64; |
| 47 | 47 |
| 48 | 48 |
| 49 CompilationCache::CompilationCache() | 49 CompilationCache::CompilationCache() |
| 50 : script_(kScriptGenerations), | 50 : script_(kScriptGenerations), |
| 51 eval_global_(kEvalGlobalGenerations), | 51 eval_global_(kEvalGlobalGenerations), |
| 52 eval_contextual_(kEvalContextualGenerations), | 52 eval_contextual_(kEvalContextualGenerations), |
| 53 reg_exp_(kRegExpGenerations), | 53 reg_exp_(kRegExpGenerations), |
| 54 enabled_(true) { | 54 enabled_(true), |
| 55 eager_optimizing_set_(NULL) { |
| 55 CompilationSubCache* subcaches[kSubCacheCount] = | 56 CompilationSubCache* subcaches[kSubCacheCount] = |
| 56 {&script_, &eval_global_, &eval_contextual_, ®_exp_}; | 57 {&script_, &eval_global_, &eval_contextual_, ®_exp_}; |
| 57 for (int i = 0; i < kSubCacheCount; ++i) { | 58 for (int i = 0; i < kSubCacheCount; ++i) { |
| 58 subcaches_[i] = subcaches[i]; | 59 subcaches_[i] = subcaches[i]; |
| 59 } | 60 } |
| 60 } | 61 } |
| 61 | 62 |
| 62 | 63 |
| 64 CompilationCache::~CompilationCache() { |
| 65 delete eager_optimizing_set_; |
| 66 eager_optimizing_set_ = NULL; |
| 67 } |
| 68 |
| 69 |
| 63 static Handle<CompilationCacheTable> AllocateTable(int size) { | 70 static Handle<CompilationCacheTable> AllocateTable(int size) { |
| 64 Isolate* isolate = Isolate::Current(); | 71 Isolate* isolate = Isolate::Current(); |
| 65 CALL_HEAP_FUNCTION(isolate, | 72 CALL_HEAP_FUNCTION(isolate, |
| 66 CompilationCacheTable::Allocate(size), | 73 CompilationCacheTable::Allocate(size), |
| 67 CompilationCacheTable); | 74 CompilationCacheTable); |
| 68 } | 75 } |
| 69 | 76 |
| 70 | 77 |
| 71 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { | 78 Handle<CompilationCacheTable> CompilationSubCache::GetTable(int generation) { |
| 72 ASSERT(generation < generations_); | 79 ASSERT(generation < generations_); |
| 73 Handle<CompilationCacheTable> result; | 80 Handle<CompilationCacheTable> result; |
| 74 if (tables_[generation]->IsUndefined()) { | 81 if (tables_[generation]->IsUndefined()) { |
| 75 result = AllocateTable(kInitialCacheSize); | 82 result = AllocateTable(kInitialCacheSize); |
| 76 tables_[generation] = *result; | 83 tables_[generation] = *result; |
| 77 } else { | 84 } else { |
| 78 CompilationCacheTable* table = | 85 CompilationCacheTable* table = |
| 79 CompilationCacheTable::cast(tables_[generation]); | 86 CompilationCacheTable::cast(tables_[generation]); |
| 80 result = Handle<CompilationCacheTable>(table); | 87 result = Handle<CompilationCacheTable>(table); |
| 81 } | 88 } |
| 82 return result; | 89 return result; |
| 83 } | 90 } |
| 84 | 91 |
| 85 | |
| 86 void CompilationSubCache::Age() { | 92 void CompilationSubCache::Age() { |
| 87 // Age the generations implicitly killing off the oldest. | 93 // Age the generations implicitly killing off the oldest. |
| 88 for (int i = generations_ - 1; i > 0; i--) { | 94 for (int i = generations_ - 1; i > 0; i--) { |
| 89 tables_[i] = tables_[i - 1]; | 95 tables_[i] = tables_[i - 1]; |
| 90 } | 96 } |
| 91 | 97 |
| 92 // Set the first generation as unborn. | 98 // Set the first generation as unborn. |
| 93 tables_[0] = HEAP->undefined_value(); | 99 tables_[0] = HEAP->undefined_value(); |
| 94 } | 100 } |
| 95 | 101 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 107 void CompilationSubCache::Iterate(ObjectVisitor* v) { | 113 void CompilationSubCache::Iterate(ObjectVisitor* v) { |
| 108 v->VisitPointers(&tables_[0], &tables_[generations_]); | 114 v->VisitPointers(&tables_[0], &tables_[generations_]); |
| 109 } | 115 } |
| 110 | 116 |
| 111 | 117 |
| 112 void CompilationSubCache::Clear() { | 118 void CompilationSubCache::Clear() { |
| 113 MemsetPointer(tables_, HEAP->undefined_value(), generations_); | 119 MemsetPointer(tables_, HEAP->undefined_value(), generations_); |
| 114 } | 120 } |
| 115 | 121 |
| 116 | 122 |
| 123 void CompilationSubCache::Remove(Handle<SharedFunctionInfo> function_info) { |
| 124 // Probe the script generation tables. Make sure not to leak handles |
| 125 // into the caller's handle scope. |
| 126 { HandleScope scope; |
| 127 for (int generation = 0; generation < generations(); generation++) { |
| 128 Handle<CompilationCacheTable> table = GetTable(generation); |
| 129 table->Remove(*function_info); |
| 130 } |
| 131 } |
| 132 } |
| 133 |
| 134 |
| 117 CompilationCacheScript::CompilationCacheScript(int generations) | 135 CompilationCacheScript::CompilationCacheScript(int generations) |
| 118 : CompilationSubCache(generations), | 136 : CompilationSubCache(generations), |
| 119 script_histogram_(NULL), | 137 script_histogram_(NULL), |
| 120 script_histogram_initialized_(false) { | 138 script_histogram_initialized_(false) { |
| 121 } | 139 } |
| 122 | 140 |
| 123 | 141 |
| 124 // We only re-use a cached function for some script source code if the | 142 // We only re-use a cached function for some script source code if the |
| 125 // script originates from the same place. This is to avoid issues | 143 // script originates from the same place. This is to avoid issues |
| 126 // when reporting errors, etc. | 144 // when reporting errors, etc. |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 | 362 |
| 345 | 363 |
| 346 void CompilationCacheRegExp::Put(Handle<String> source, | 364 void CompilationCacheRegExp::Put(Handle<String> source, |
| 347 JSRegExp::Flags flags, | 365 JSRegExp::Flags flags, |
| 348 Handle<FixedArray> data) { | 366 Handle<FixedArray> data) { |
| 349 HandleScope scope; | 367 HandleScope scope; |
| 350 SetFirstTable(TablePut(source, flags, data)); | 368 SetFirstTable(TablePut(source, flags, data)); |
| 351 } | 369 } |
| 352 | 370 |
| 353 | 371 |
| 372 void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { |
| 373 if (!IsEnabled()) return; |
| 374 |
| 375 eval_global_.Remove(function_info); |
| 376 eval_contextual_.Remove(function_info); |
| 377 script_.Remove(function_info); |
| 378 } |
| 379 |
| 380 |
| 354 Handle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source, | 381 Handle<SharedFunctionInfo> CompilationCache::LookupScript(Handle<String> source, |
| 355 Handle<Object> name, | 382 Handle<Object> name, |
| 356 int line_offset, | 383 int line_offset, |
| 357 int column_offset) { | 384 int column_offset) { |
| 358 if (!IsEnabled()) { | 385 if (!IsEnabled()) { |
| 359 return Handle<SharedFunctionInfo>::null(); | 386 return Handle<SharedFunctionInfo>::null(); |
| 360 } | 387 } |
| 361 | 388 |
| 362 return script_.Lookup(source, name, line_offset, column_offset); | 389 return script_.Lookup(source, name, line_offset, column_offset); |
| 363 } | 390 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 JSRegExp::Flags flags, | 449 JSRegExp::Flags flags, |
| 423 Handle<FixedArray> data) { | 450 Handle<FixedArray> data) { |
| 424 if (!IsEnabled()) { | 451 if (!IsEnabled()) { |
| 425 return; | 452 return; |
| 426 } | 453 } |
| 427 | 454 |
| 428 reg_exp_.Put(source, flags, data); | 455 reg_exp_.Put(source, flags, data); |
| 429 } | 456 } |
| 430 | 457 |
| 431 | 458 |
| 459 static bool SourceHashCompare(void* key1, void* key2) { |
| 460 return key1 == key2; |
| 461 } |
| 462 |
| 463 |
| 464 HashMap* CompilationCache::EagerOptimizingSet() { |
| 465 if (eager_optimizing_set_ == NULL) { |
| 466 eager_optimizing_set_ = new HashMap(&SourceHashCompare); |
| 467 } |
| 468 return eager_optimizing_set_; |
| 469 } |
| 470 |
| 471 |
| 472 bool CompilationCache::ShouldOptimizeEagerly(Handle<JSFunction> function) { |
| 473 if (FLAG_opt_eagerly) return true; |
| 474 uint32_t hash = function->SourceHash(); |
| 475 void* key = reinterpret_cast<void*>(hash); |
| 476 return EagerOptimizingSet()->Lookup(key, hash, false) != NULL; |
| 477 } |
| 478 |
| 479 |
| 480 void CompilationCache::MarkForEagerOptimizing(Handle<JSFunction> function) { |
| 481 uint32_t hash = function->SourceHash(); |
| 482 void* key = reinterpret_cast<void*>(hash); |
| 483 EagerOptimizingSet()->Lookup(key, hash, true); |
| 484 } |
| 485 |
| 486 |
| 487 void CompilationCache::MarkForLazyOptimizing(Handle<JSFunction> function) { |
| 488 uint32_t hash = function->SourceHash(); |
| 489 void* key = reinterpret_cast<void*>(hash); |
| 490 EagerOptimizingSet()->Remove(key, hash); |
| 491 } |
| 492 |
| 493 |
| 494 void CompilationCache::ResetEagerOptimizingData() { |
| 495 HashMap* set = EagerOptimizingSet(); |
| 496 if (set->occupancy() > 0) set->Clear(); |
| 497 } |
| 498 |
| 499 |
| 432 void CompilationCache::Clear() { | 500 void CompilationCache::Clear() { |
| 433 for (int i = 0; i < kSubCacheCount; i++) { | 501 for (int i = 0; i < kSubCacheCount; i++) { |
| 434 subcaches_[i]->Clear(); | 502 subcaches_[i]->Clear(); |
| 435 } | 503 } |
| 436 } | 504 } |
| 437 | 505 |
| 438 | 506 |
| 439 void CompilationCache::Iterate(ObjectVisitor* v) { | 507 void CompilationCache::Iterate(ObjectVisitor* v) { |
| 440 for (int i = 0; i < kSubCacheCount; i++) { | 508 for (int i = 0; i < kSubCacheCount; i++) { |
| 441 subcaches_[i]->Iterate(v); | 509 subcaches_[i]->Iterate(v); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 462 } | 530 } |
| 463 | 531 |
| 464 | 532 |
| 465 void CompilationCache::Disable() { | 533 void CompilationCache::Disable() { |
| 466 enabled_ = false; | 534 enabled_ = false; |
| 467 Clear(); | 535 Clear(); |
| 468 } | 536 } |
| 469 | 537 |
| 470 | 538 |
| 471 } } // namespace v8::internal | 539 } } // namespace v8::internal |
| OLD | NEW |