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