| OLD | NEW |
| 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/contexts.h" | 5 #include "src/contexts.h" |
| 6 | 6 |
| 7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 | 10 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 } while (follow_context_chain); | 405 } while (follow_context_chain); |
| 406 | 406 |
| 407 if (FLAG_trace_contexts) { | 407 if (FLAG_trace_contexts) { |
| 408 PrintF("=> no property/slot found\n"); | 408 PrintF("=> no property/slot found\n"); |
| 409 } | 409 } |
| 410 return Handle<Object>::null(); | 410 return Handle<Object>::null(); |
| 411 } | 411 } |
| 412 | 412 |
| 413 static const int kSharedOffset = 0; | 413 static const int kSharedOffset = 0; |
| 414 static const int kCachedCodeOffset = 1; | 414 static const int kCachedCodeOffset = 1; |
| 415 static const int kOsrAstIdOffset = 2; | 415 static const int kLiteralsOffset = 2; |
| 416 static const int kEntryLength = 3; | 416 static const int kOsrAstIdOffset = 3; |
| 417 static const int kEntryLength = 4; |
| 417 static const int kInitialLength = kEntryLength; | 418 static const int kInitialLength = kEntryLength; |
| 418 | 419 |
| 419 int Context::SearchOptimizedCodeMapEntry(SharedFunctionInfo* shared, | 420 int Context::SearchOptimizedCodeMapEntry(SharedFunctionInfo* shared, |
| 420 BailoutId osr_ast_id) { | 421 BailoutId osr_ast_id) { |
| 421 DisallowHeapAllocation no_gc; | 422 DisallowHeapAllocation no_gc; |
| 422 DCHECK(this->IsNativeContext()); | 423 DCHECK(this->IsNativeContext()); |
| 423 if (!OptimizedCodeMapIsCleared()) { | 424 if (!OptimizedCodeMapIsCleared()) { |
| 424 FixedArray* optimized_code_map = this->osr_code_table(); | 425 FixedArray* optimized_code_map = this->osr_code_table(); |
| 425 int length = optimized_code_map->length(); | 426 int length = optimized_code_map->length(); |
| 426 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | 427 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
| 427 for (int i = 0; i < length; i += kEntryLength) { | 428 for (int i = 0; i < length; i += kEntryLength) { |
| 428 if (WeakCell::cast(optimized_code_map->get(i + kSharedOffset))->value() == | 429 if (WeakCell::cast(optimized_code_map->get(i + kSharedOffset))->value() == |
| 429 shared && | 430 shared && |
| 430 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { | 431 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
| 431 return i; | 432 return i; |
| 432 } | 433 } |
| 433 } | 434 } |
| 434 } | 435 } |
| 435 return -1; | 436 return -1; |
| 436 } | 437 } |
| 437 | 438 |
| 438 Code* Context::SearchOptimizedCodeMap(SharedFunctionInfo* shared, | 439 void Context::SearchOptimizedCodeMap(SharedFunctionInfo* shared, |
| 439 BailoutId osr_ast_id) { | 440 BailoutId osr_ast_id, Code** pcode, |
| 441 LiteralsArray** pliterals) { |
| 440 DCHECK(this->IsNativeContext()); | 442 DCHECK(this->IsNativeContext()); |
| 441 int entry = SearchOptimizedCodeMapEntry(shared, osr_ast_id); | 443 int entry = SearchOptimizedCodeMapEntry(shared, osr_ast_id); |
| 442 if (entry != -1) { | 444 if (entry != -1) { |
| 443 FixedArray* code_map = osr_code_table(); | 445 FixedArray* code_map = osr_code_table(); |
| 444 DCHECK_LE(entry + kEntryLength, code_map->length()); | 446 DCHECK_LE(entry + kEntryLength, code_map->length()); |
| 445 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); | 447 WeakCell* cell = WeakCell::cast(code_map->get(entry + kCachedCodeOffset)); |
| 448 WeakCell* literals_cell = |
| 449 WeakCell::cast(code_map->get(entry + kLiteralsOffset)); |
| 446 | 450 |
| 447 return cell->cleared() ? nullptr : Code::cast(cell->value()); | 451 *pcode = cell->cleared() ? nullptr : Code::cast(cell->value()); |
| 452 *pliterals = literals_cell->cleared() |
| 453 ? nullptr |
| 454 : LiteralsArray::cast(literals_cell->value()); |
| 455 } else { |
| 456 *pcode = nullptr; |
| 457 *pliterals = nullptr; |
| 448 } | 458 } |
| 449 return nullptr; | |
| 450 } | 459 } |
| 451 | 460 |
| 452 void Context::AddToOptimizedCodeMap(Handle<Context> native_context, | 461 void Context::AddToOptimizedCodeMap(Handle<Context> native_context, |
| 453 Handle<SharedFunctionInfo> shared, | 462 Handle<SharedFunctionInfo> shared, |
| 454 Handle<Code> code, | 463 Handle<Code> code, |
| 464 Handle<LiteralsArray> literals, |
| 455 BailoutId osr_ast_id) { | 465 BailoutId osr_ast_id) { |
| 456 DCHECK(native_context->IsNativeContext()); | 466 DCHECK(native_context->IsNativeContext()); |
| 457 Isolate* isolate = native_context->GetIsolate(); | 467 Isolate* isolate = native_context->GetIsolate(); |
| 458 if (isolate->serializer_enabled()) return; | 468 if (isolate->serializer_enabled()) return; |
| 459 | 469 |
| 460 STATIC_ASSERT(kEntryLength == 3); | 470 STATIC_ASSERT(kEntryLength == 4); |
| 461 Handle<FixedArray> new_code_map; | 471 Handle<FixedArray> new_code_map; |
| 462 int entry; | 472 int entry; |
| 463 | 473 |
| 464 if (native_context->OptimizedCodeMapIsCleared()) { | 474 if (native_context->OptimizedCodeMapIsCleared()) { |
| 465 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); | 475 new_code_map = isolate->factory()->NewFixedArray(kInitialLength, TENURED); |
| 466 entry = 0; | 476 entry = 0; |
| 467 } else { | 477 } else { |
| 468 Handle<FixedArray> old_code_map(native_context->osr_code_table(), isolate); | 478 Handle<FixedArray> old_code_map(native_context->osr_code_table(), isolate); |
| 469 entry = native_context->SearchOptimizedCodeMapEntry(*shared, osr_ast_id); | 479 entry = native_context->SearchOptimizedCodeMapEntry(*shared, osr_ast_id); |
| 470 if (entry >= 0) { | 480 if (entry >= 0) { |
| 471 // Just set the code of the entry. | 481 // Just set the code and literals of the entry. |
| 472 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); | 482 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); |
| 473 old_code_map->set(entry + kCachedCodeOffset, *code_cell); | 483 old_code_map->set(entry + kCachedCodeOffset, *code_cell); |
| 484 Handle<WeakCell> literals_cell = |
| 485 isolate->factory()->NewWeakCell(literals); |
| 486 old_code_map->set(entry + kLiteralsOffset, *literals_cell); |
| 474 return; | 487 return; |
| 475 } | 488 } |
| 476 | 489 |
| 477 // Can we reuse an entry? | 490 // Can we reuse an entry? |
| 478 DCHECK(entry < 0); | 491 DCHECK(entry < 0); |
| 479 int length = old_code_map->length(); | 492 int length = old_code_map->length(); |
| 480 for (int i = 0; i < length; i += kEntryLength) { | 493 for (int i = 0; i < length; i += kEntryLength) { |
| 481 if (WeakCell::cast(old_code_map->get(i + kSharedOffset))->cleared()) { | 494 if (WeakCell::cast(old_code_map->get(i + kSharedOffset))->cleared()) { |
| 482 new_code_map = old_code_map; | 495 new_code_map = old_code_map; |
| 483 entry = i; | 496 entry = i; |
| 484 break; | 497 break; |
| 485 } | 498 } |
| 486 } | 499 } |
| 487 | 500 |
| 488 if (entry < 0) { | 501 if (entry < 0) { |
| 489 // Copy old optimized code map and append one new entry. | 502 // Copy old optimized code map and append one new entry. |
| 490 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( | 503 new_code_map = isolate->factory()->CopyFixedArrayAndGrow( |
| 491 old_code_map, kEntryLength, TENURED); | 504 old_code_map, kEntryLength, TENURED); |
| 492 entry = old_code_map->length(); | 505 entry = old_code_map->length(); |
| 493 } | 506 } |
| 494 } | 507 } |
| 495 | 508 |
| 496 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); | 509 Handle<WeakCell> code_cell = isolate->factory()->NewWeakCell(code); |
| 510 Handle<WeakCell> literals_cell = isolate->factory()->NewWeakCell(literals); |
| 497 Handle<WeakCell> shared_cell = isolate->factory()->NewWeakCell(shared); | 511 Handle<WeakCell> shared_cell = isolate->factory()->NewWeakCell(shared); |
| 498 | 512 |
| 499 new_code_map->set(entry + kSharedOffset, *shared_cell); | 513 new_code_map->set(entry + kSharedOffset, *shared_cell); |
| 500 new_code_map->set(entry + kCachedCodeOffset, *code_cell); | 514 new_code_map->set(entry + kCachedCodeOffset, *code_cell); |
| 515 new_code_map->set(entry + kLiteralsOffset, *literals_cell); |
| 501 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); | 516 new_code_map->set(entry + kOsrAstIdOffset, Smi::FromInt(osr_ast_id.ToInt())); |
| 502 | 517 |
| 503 #ifdef DEBUG | 518 #ifdef DEBUG |
| 504 for (int i = 0; i < new_code_map->length(); i += kEntryLength) { | 519 for (int i = 0; i < new_code_map->length(); i += kEntryLength) { |
| 505 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kSharedOffset)); | 520 WeakCell* cell = WeakCell::cast(new_code_map->get(i + kSharedOffset)); |
| 506 DCHECK(cell->cleared() || cell->value()->IsSharedFunctionInfo()); | 521 DCHECK(cell->cleared() || cell->value()->IsSharedFunctionInfo()); |
| 507 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); | 522 cell = WeakCell::cast(new_code_map->get(i + kCachedCodeOffset)); |
| 508 DCHECK(cell->cleared() || | 523 DCHECK(cell->cleared() || |
| 509 (cell->value()->IsCode() && | 524 (cell->value()->IsCode() && |
| 510 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); | 525 Code::cast(cell->value())->kind() == Code::OPTIMIZED_FUNCTION)); |
| 526 cell = WeakCell::cast(new_code_map->get(i + kLiteralsOffset)); |
| 527 DCHECK(cell->cleared() || cell->value()->IsFixedArray()); |
| 511 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); | 528 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
| 512 } | 529 } |
| 513 #endif | 530 #endif |
| 514 | 531 |
| 515 FixedArray* old_code_map = native_context->osr_code_table(); | 532 FixedArray* old_code_map = native_context->osr_code_table(); |
| 516 if (old_code_map != *new_code_map) { | 533 if (old_code_map != *new_code_map) { |
| 517 native_context->set_osr_code_table(*new_code_map); | 534 native_context->set_osr_code_table(*new_code_map); |
| 518 } | 535 } |
| 519 } | 536 } |
| 520 | 537 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 541 PrintF(" (osr ast id %d)]\n", osr.ToInt()); | 558 PrintF(" (osr ast id %d)]\n", osr.ToInt()); |
| 542 } | 559 } |
| 543 // Evict the src entry by not copying it to the dst entry. | 560 // Evict the src entry by not copying it to the dst entry. |
| 544 continue; | 561 continue; |
| 545 } | 562 } |
| 546 // Keep the src entry by copying it to the dst entry. | 563 // Keep the src entry by copying it to the dst entry. |
| 547 if (dst != src) { | 564 if (dst != src) { |
| 548 code_map->set(dst + kSharedOffset, code_map->get(src + kSharedOffset)); | 565 code_map->set(dst + kSharedOffset, code_map->get(src + kSharedOffset)); |
| 549 code_map->set(dst + kCachedCodeOffset, | 566 code_map->set(dst + kCachedCodeOffset, |
| 550 code_map->get(src + kCachedCodeOffset)); | 567 code_map->get(src + kCachedCodeOffset)); |
| 568 code_map->set(dst + kLiteralsOffset, |
| 569 code_map->get(src + kLiteralsOffset)); |
| 551 code_map->set(dst + kOsrAstIdOffset, | 570 code_map->set(dst + kOsrAstIdOffset, |
| 552 code_map->get(src + kOsrAstIdOffset)); | 571 code_map->get(src + kOsrAstIdOffset)); |
| 553 } | 572 } |
| 554 dst += kEntryLength; | 573 dst += kEntryLength; |
| 555 } | 574 } |
| 556 if (dst != length) { | 575 if (dst != length) { |
| 557 // Always trim even when array is cleared because of heap verifier. | 576 // Always trim even when array is cleared because of heap verifier. |
| 558 heap->RightTrimFixedArray(code_map, length - dst); | 577 heap->RightTrimFixedArray(code_map, length - dst); |
| 559 if (code_map->length() == 0) { | 578 if (code_map->length() == 0) { |
| 560 ClearOptimizedCodeMap(); | 579 ClearOptimizedCodeMap(); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 | 770 |
| 752 int previous_value = errors_thrown()->value(); | 771 int previous_value = errors_thrown()->value(); |
| 753 set_errors_thrown(Smi::FromInt(previous_value + 1)); | 772 set_errors_thrown(Smi::FromInt(previous_value + 1)); |
| 754 } | 773 } |
| 755 | 774 |
| 756 | 775 |
| 757 int Context::GetErrorsThrown() { return errors_thrown()->value(); } | 776 int Context::GetErrorsThrown() { return errors_thrown()->value(); } |
| 758 | 777 |
| 759 } // namespace internal | 778 } // namespace internal |
| 760 } // namespace v8 | 779 } // namespace v8 |
| OLD | NEW |