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/ast/scopeinfo.h" | 5 #include "src/ast/scopeinfo.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
| 9 #include "src/ast/context-slot-cache.h" |
9 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
10 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 | 16 |
16 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, | 17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
17 Scope* scope) { | 18 Scope* scope) { |
18 // Collect stack and context locals. | 19 // Collect stack and context locals. |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 | 631 |
631 int ScopeInfo::ReceiverEntryIndex() { | 632 int ScopeInfo::ReceiverEntryIndex() { |
632 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); | 633 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
633 } | 634 } |
634 | 635 |
635 | 636 |
636 int ScopeInfo::FunctionNameEntryIndex() { | 637 int ScopeInfo::FunctionNameEntryIndex() { |
637 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); | 638 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
638 } | 639 } |
639 | 640 |
640 | |
641 int ContextSlotCache::Hash(Object* data, String* name) { | |
642 // Uses only lower 32 bits if pointers are larger. | |
643 uintptr_t addr_hash = | |
644 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | |
645 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | |
646 } | |
647 | |
648 | |
649 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, | |
650 InitializationFlag* init_flag, | |
651 MaybeAssignedFlag* maybe_assigned_flag) { | |
652 int index = Hash(data, name); | |
653 Key& key = keys_[index]; | |
654 if ((key.data == data) && key.name->Equals(name)) { | |
655 Value result(values_[index]); | |
656 if (mode != NULL) *mode = result.mode(); | |
657 if (init_flag != NULL) *init_flag = result.initialization_flag(); | |
658 if (maybe_assigned_flag != NULL) | |
659 *maybe_assigned_flag = result.maybe_assigned_flag(); | |
660 return result.index() + kNotFound; | |
661 } | |
662 return kNotFound; | |
663 } | |
664 | |
665 | |
666 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, | |
667 VariableMode mode, InitializationFlag init_flag, | |
668 MaybeAssignedFlag maybe_assigned_flag, | |
669 int slot_index) { | |
670 DisallowHeapAllocation no_gc; | |
671 Handle<String> internalized_name; | |
672 DCHECK(slot_index > kNotFound); | |
673 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | |
674 ToHandle(&internalized_name)) { | |
675 int index = Hash(*data, *internalized_name); | |
676 Key& key = keys_[index]; | |
677 key.data = *data; | |
678 key.name = *internalized_name; | |
679 // Please note value only takes a uint as index. | |
680 values_[index] = Value(mode, init_flag, maybe_assigned_flag, | |
681 slot_index - kNotFound).raw(); | |
682 #ifdef DEBUG | 641 #ifdef DEBUG |
683 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); | |
684 #endif | |
685 } | |
686 } | |
687 | |
688 | |
689 void ContextSlotCache::Clear() { | |
690 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; | |
691 } | |
692 | |
693 | |
694 #ifdef DEBUG | |
695 | |
696 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, | |
697 VariableMode mode, | |
698 InitializationFlag init_flag, | |
699 MaybeAssignedFlag maybe_assigned_flag, | |
700 int slot_index) { | |
701 DisallowHeapAllocation no_gc; | |
702 Handle<String> internalized_name; | |
703 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name). | |
704 ToHandle(&internalized_name)) { | |
705 int index = Hash(*data, *name); | |
706 Key& key = keys_[index]; | |
707 DCHECK(key.data == *data); | |
708 DCHECK(key.name->Equals(*name)); | |
709 Value result(values_[index]); | |
710 DCHECK(result.mode() == mode); | |
711 DCHECK(result.initialization_flag() == init_flag); | |
712 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); | |
713 DCHECK(result.index() + kNotFound == slot_index); | |
714 } | |
715 } | |
716 | |
717 | 642 |
718 static void PrintList(const char* list_name, | 643 static void PrintList(const char* list_name, |
719 int nof_internal_slots, | 644 int nof_internal_slots, |
720 int start, | 645 int start, |
721 int end, | 646 int end, |
722 ScopeInfo* scope_info) { | 647 ScopeInfo* scope_info) { |
723 if (start < end) { | 648 if (start < end) { |
724 PrintF("\n // %s\n", list_name); | 649 PrintF("\n // %s\n", list_name); |
725 if (nof_internal_slots > 0) { | 650 if (nof_internal_slots > 0) { |
726 PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1); | 651 PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1); |
(...skipping 26 matching lines...) Expand all Loading... |
753 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); | 678 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); |
754 } | 679 } |
755 | 680 |
756 PrintF("}\n"); | 681 PrintF("}\n"); |
757 } | 682 } |
758 #endif // DEBUG | 683 #endif // DEBUG |
759 | 684 |
760 | 685 |
761 } // namespace internal | 686 } // namespace internal |
762 } // namespace v8 | 687 } // namespace v8 |
OLD | NEW |