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