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