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/scopeinfo.h" | 5 #include "src/scopeinfo.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/scopes.h" | 10 #include "src/scopes.h" |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 return i - start + first_slot_index; | 517 return i - start + first_slot_index; |
518 } | 518 } |
519 } | 519 } |
520 } | 520 } |
521 return -1; | 521 return -1; |
522 } | 522 } |
523 | 523 |
524 | 524 |
525 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, | 525 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
526 Handle<String> name, VariableMode* mode, | 526 Handle<String> name, VariableMode* mode, |
527 VariableLocation* location, | |
528 InitializationFlag* init_flag, | 527 InitializationFlag* init_flag, |
529 MaybeAssignedFlag* maybe_assigned_flag) { | 528 MaybeAssignedFlag* maybe_assigned_flag) { |
530 DCHECK(name->IsInternalizedString()); | 529 DCHECK(name->IsInternalizedString()); |
531 DCHECK(mode != NULL); | 530 DCHECK(mode != NULL); |
532 DCHECK(location != NULL); | |
533 DCHECK(init_flag != NULL); | 531 DCHECK(init_flag != NULL); |
534 if (scope_info->length() > 0) { | 532 if (scope_info->length() > 0) { |
535 ContextSlotCache* context_slot_cache = | 533 ContextSlotCache* context_slot_cache = |
536 scope_info->GetIsolate()->context_slot_cache(); | 534 scope_info->GetIsolate()->context_slot_cache(); |
537 int result = context_slot_cache->Lookup(*scope_info, *name, mode, location, | 535 int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag, |
538 init_flag, maybe_assigned_flag); | 536 maybe_assigned_flag); |
539 if (result != ContextSlotCache::kNotFound) { | 537 if (result != ContextSlotCache::kNotFound) { |
540 DCHECK(result < scope_info->ContextLength()); | 538 DCHECK(result < scope_info->ContextLength()); |
541 return result; | 539 return result; |
542 } | 540 } |
543 | 541 |
544 DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(), | |
545 scope_info->ContextLocalNameEntriesIndex() + | |
546 scope_info->ContextLocalCount()); | |
547 int start = scope_info->ContextLocalNameEntriesIndex(); | 542 int start = scope_info->ContextLocalNameEntriesIndex(); |
548 int end = scope_info->ContextGlobalNameEntriesIndex() + | 543 int end = scope_info->ContextLocalNameEntriesIndex() + |
549 scope_info->ContextGlobalCount(); | 544 scope_info->ContextLocalCount(); |
550 for (int i = start; i < end; ++i) { | 545 for (int i = start; i < end; ++i) { |
551 if (*name == scope_info->get(i)) { | 546 if (*name == scope_info->get(i)) { |
552 int var = i - start; | 547 int var = i - start; |
553 *mode = scope_info->ContextLocalMode(var); | 548 *mode = scope_info->ContextLocalMode(var); |
554 *init_flag = scope_info->ContextLocalInitFlag(var); | 549 *init_flag = scope_info->ContextLocalInitFlag(var); |
555 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); | 550 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); |
| 551 result = Context::MIN_CONTEXT_SLOTS + var; |
556 | 552 |
557 if (var < scope_info->ContextLocalCount()) { | 553 context_slot_cache->Update(scope_info, name, *mode, *init_flag, |
558 *location = VariableLocation::CONTEXT; | 554 *maybe_assigned_flag, result); |
559 result = Context::MIN_CONTEXT_SLOTS + var; | |
560 } else { | |
561 var -= scope_info->ContextLocalCount(); | |
562 *location = VariableLocation::GLOBAL; | |
563 result = Context::MIN_CONTEXT_SLOTS + | |
564 scope_info->ContextLocalCount() + var; | |
565 } | |
566 | |
567 context_slot_cache->Update(scope_info, name, *mode, *location, | |
568 *init_flag, *maybe_assigned_flag, result); | |
569 DCHECK(result < scope_info->ContextLength()); | 555 DCHECK(result < scope_info->ContextLength()); |
570 return result; | 556 return result; |
571 } | 557 } |
572 } | 558 } |
573 // Cache as not found. Mode, location, init flag and maybe assigned flag | 559 // Cache as not found. Mode, init flag and maybe assigned flag don't matter. |
574 // don't matter. | |
575 context_slot_cache->Update(scope_info, name, TEMPORARY, | 560 context_slot_cache->Update(scope_info, name, TEMPORARY, |
576 VariableLocation::CONTEXT, kNeedsInitialization, | 561 kNeedsInitialization, kNotAssigned, -1); |
577 kNotAssigned, -1); | |
578 } | 562 } |
579 return -1; | 563 return -1; |
580 } | 564 } |
| 565 |
| 566 |
| 567 int ScopeInfo::ContextGlobalSlotIndex(Handle<ScopeInfo> scope_info, |
| 568 Handle<String> name, VariableMode* mode, |
| 569 InitializationFlag* init_flag, |
| 570 MaybeAssignedFlag* maybe_assigned_flag) { |
| 571 DCHECK(name->IsInternalizedString()); |
| 572 DCHECK(mode != NULL); |
| 573 DCHECK(init_flag != NULL); |
| 574 if (scope_info->length() > 0) { |
| 575 // This is to ensure that ContextLocalMode() and co. queries would work. |
| 576 DCHECK_EQ(scope_info->ContextGlobalNameEntriesIndex(), |
| 577 scope_info->ContextLocalNameEntriesIndex() + |
| 578 scope_info->ContextLocalCount()); |
| 579 int base = scope_info->ContextLocalNameEntriesIndex(); |
| 580 int start = scope_info->ContextGlobalNameEntriesIndex(); |
| 581 int end = scope_info->ContextGlobalNameEntriesIndex() + |
| 582 scope_info->ContextGlobalCount(); |
| 583 for (int i = start; i < end; ++i) { |
| 584 if (*name == scope_info->get(i)) { |
| 585 int var = i - base; |
| 586 *mode = scope_info->ContextLocalMode(var); |
| 587 *init_flag = scope_info->ContextLocalInitFlag(var); |
| 588 *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var); |
| 589 int result = Context::MIN_CONTEXT_SLOTS + var; |
| 590 DCHECK(result < scope_info->ContextLength()); |
| 591 return result; |
| 592 } |
| 593 } |
| 594 } |
| 595 return -1; |
| 596 } |
581 | 597 |
582 | 598 |
583 String* ScopeInfo::ContextSlotName(int slot_index) { | 599 String* ScopeInfo::ContextSlotName(int slot_index) { |
584 int const var = slot_index - Context::MIN_CONTEXT_SLOTS; | 600 int const var = slot_index - Context::MIN_CONTEXT_SLOTS; |
585 DCHECK_LE(0, var); | 601 DCHECK_LE(0, var); |
586 DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount()); | 602 DCHECK_LT(var, ContextLocalCount() + ContextGlobalCount()); |
587 return ContextLocalName(var); | 603 return ContextLocalName(var); |
588 } | 604 } |
589 | 605 |
590 | 606 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 | 710 |
695 int ContextSlotCache::Hash(Object* data, String* name) { | 711 int ContextSlotCache::Hash(Object* data, String* name) { |
696 // Uses only lower 32 bits if pointers are larger. | 712 // Uses only lower 32 bits if pointers are larger. |
697 uintptr_t addr_hash = | 713 uintptr_t addr_hash = |
698 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 714 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
699 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 715 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
700 } | 716 } |
701 | 717 |
702 | 718 |
703 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, | 719 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, |
704 VariableLocation* location, | |
705 InitializationFlag* init_flag, | 720 InitializationFlag* init_flag, |
706 MaybeAssignedFlag* maybe_assigned_flag) { | 721 MaybeAssignedFlag* maybe_assigned_flag) { |
707 int index = Hash(data, name); | 722 int index = Hash(data, name); |
708 Key& key = keys_[index]; | 723 Key& key = keys_[index]; |
709 if ((key.data == data) && key.name->Equals(name)) { | 724 if ((key.data == data) && key.name->Equals(name)) { |
710 Value result(values_[index]); | 725 Value result(values_[index]); |
711 if (mode != NULL) *mode = result.mode(); | 726 if (mode != NULL) *mode = result.mode(); |
712 if (location != NULL) *location = result.location(); | |
713 if (init_flag != NULL) *init_flag = result.initialization_flag(); | 727 if (init_flag != NULL) *init_flag = result.initialization_flag(); |
714 if (maybe_assigned_flag != NULL) | 728 if (maybe_assigned_flag != NULL) |
715 *maybe_assigned_flag = result.maybe_assigned_flag(); | 729 *maybe_assigned_flag = result.maybe_assigned_flag(); |
716 return result.index() + kNotFound; | 730 return result.index() + kNotFound; |
717 } | 731 } |
718 return kNotFound; | 732 return kNotFound; |
719 } | 733 } |
720 | 734 |
721 | 735 |
722 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, | 736 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, |
723 VariableMode mode, VariableLocation location, | 737 VariableMode mode, InitializationFlag init_flag, |
724 InitializationFlag init_flag, | |
725 MaybeAssignedFlag maybe_assigned_flag, | 738 MaybeAssignedFlag maybe_assigned_flag, |
726 int slot_index) { | 739 int slot_index) { |
727 DisallowHeapAllocation no_gc; | 740 DisallowHeapAllocation no_gc; |
728 Handle<String> internalized_name; | 741 Handle<String> internalized_name; |
729 DCHECK(slot_index > kNotFound); | 742 DCHECK(slot_index > kNotFound); |
730 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | 743 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). |
731 ToHandle(&internalized_name)) { | 744 ToHandle(&internalized_name)) { |
732 int index = Hash(*data, *internalized_name); | 745 int index = Hash(*data, *internalized_name); |
733 Key& key = keys_[index]; | 746 Key& key = keys_[index]; |
734 key.data = *data; | 747 key.data = *data; |
735 key.name = *internalized_name; | 748 key.name = *internalized_name; |
736 // Please note value only takes a uint as index. | 749 // Please note value only takes a uint as index. |
737 values_[index] = Value(mode, location, init_flag, maybe_assigned_flag, | 750 values_[index] = Value(mode, init_flag, maybe_assigned_flag, |
738 slot_index - kNotFound).raw(); | 751 slot_index - kNotFound).raw(); |
739 #ifdef DEBUG | 752 #ifdef DEBUG |
740 ValidateEntry(data, name, mode, location, init_flag, maybe_assigned_flag, | 753 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); |
741 slot_index); | |
742 #endif | 754 #endif |
743 } | 755 } |
744 } | 756 } |
745 | 757 |
746 | 758 |
747 void ContextSlotCache::Clear() { | 759 void ContextSlotCache::Clear() { |
748 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; | 760 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; |
749 } | 761 } |
750 | 762 |
751 | 763 |
752 #ifdef DEBUG | 764 #ifdef DEBUG |
753 | 765 |
754 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, | 766 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, |
755 VariableMode mode, | 767 VariableMode mode, |
756 VariableLocation location, | |
757 InitializationFlag init_flag, | 768 InitializationFlag init_flag, |
758 MaybeAssignedFlag maybe_assigned_flag, | 769 MaybeAssignedFlag maybe_assigned_flag, |
759 int slot_index) { | 770 int slot_index) { |
760 DisallowHeapAllocation no_gc; | 771 DisallowHeapAllocation no_gc; |
761 Handle<String> internalized_name; | 772 Handle<String> internalized_name; |
762 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | 773 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). |
763 ToHandle(&internalized_name)) { | 774 ToHandle(&internalized_name)) { |
764 int index = Hash(*data, *name); | 775 int index = Hash(*data, *name); |
765 Key& key = keys_[index]; | 776 Key& key = keys_[index]; |
766 DCHECK(key.data == *data); | 777 DCHECK(key.data == *data); |
767 DCHECK(key.name->Equals(*name)); | 778 DCHECK(key.name->Equals(*name)); |
768 Value result(values_[index]); | 779 Value result(values_[index]); |
769 DCHECK(result.mode() == mode); | 780 DCHECK(result.mode() == mode); |
770 DCHECK(result.location() == location); | |
771 DCHECK(result.initialization_flag() == init_flag); | 781 DCHECK(result.initialization_flag() == init_flag); |
772 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); | 782 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); |
773 DCHECK(result.index() + kNotFound == slot_index); | 783 DCHECK(result.index() + kNotFound == slot_index); |
774 } | 784 } |
775 } | 785 } |
776 | 786 |
777 | 787 |
778 static void PrintList(const char* list_name, | 788 static void PrintList(const char* list_name, |
779 int nof_internal_slots, | 789 int nof_internal_slots, |
780 int start, | 790 int start, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 info->set_mode(i, var->mode()); | 848 info->set_mode(i, var->mode()); |
839 DCHECK(var->index() >= 0); | 849 DCHECK(var->index() >= 0); |
840 info->set_index(i, var->index()); | 850 info->set_index(i, var->index()); |
841 } | 851 } |
842 DCHECK(i == info->length()); | 852 DCHECK(i == info->length()); |
843 return info; | 853 return info; |
844 } | 854 } |
845 | 855 |
846 } // namespace internal | 856 } // namespace internal |
847 } // namespace v8 | 857 } // namespace v8 |
OLD | NEW |