| 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 |