OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef V8_OBJECTS_H_ | 5 #ifndef V8_OBJECTS_H_ |
6 #define V8_OBJECTS_H_ | 6 #define V8_OBJECTS_H_ |
7 | 7 |
8 #include <iosfwd> | 8 #include <iosfwd> |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
(...skipping 3580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3591 DECLARE_CAST(StringTable) | 3591 DECLARE_CAST(StringTable) |
3592 | 3592 |
3593 private: | 3593 private: |
3594 template <bool seq_one_byte> | 3594 template <bool seq_one_byte> |
3595 friend class JsonParser; | 3595 friend class JsonParser; |
3596 | 3596 |
3597 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable); | 3597 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable); |
3598 }; | 3598 }; |
3599 | 3599 |
3600 | 3600 |
3601 enum class DictionaryEntryType { kObjects, kCells }; | |
3602 | |
3603 | |
3604 template <typename Derived, typename Shape, typename Key> | 3601 template <typename Derived, typename Shape, typename Key> |
3605 class Dictionary: public HashTable<Derived, Shape, Key> { | 3602 class Dictionary: public HashTable<Derived, Shape, Key> { |
3606 typedef HashTable<Derived, Shape, Key> DerivedHashTable; | 3603 typedef HashTable<Derived, Shape, Key> DerivedHashTable; |
3607 | 3604 |
3608 public: | 3605 public: |
3609 // Returns the value at entry. | 3606 // Returns the value at entry. |
3610 Object* ValueAt(int entry) { | 3607 Object* ValueAt(int entry) { |
3611 return this->get(Derived::EntryToIndex(entry) + 1); | 3608 return this->get(Derived::EntryToIndex(entry) + 1); |
3612 } | 3609 } |
3613 | 3610 |
3614 // Set the value for entry. | 3611 // Set the value for entry. |
3615 void ValueAtPut(int entry, Object* value) { | 3612 void ValueAtPut(int entry, Object* value) { |
3616 this->set(Derived::EntryToIndex(entry) + 1, value); | 3613 this->set(Derived::EntryToIndex(entry) + 1, value); |
3617 } | 3614 } |
3618 | 3615 |
3619 // Returns the property details for the property at entry. | 3616 // Returns the property details for the property at entry. |
3620 PropertyDetails DetailsAt(int entry) { | 3617 PropertyDetails DetailsAt(int entry) { |
3621 DCHECK(entry >= 0); // Not found is -1, which is not caught by get(). | 3618 DCHECK(entry >= 0); // Not found is -1, which is not caught by get(). |
3622 return PropertyDetails( | 3619 return PropertyDetails( |
3623 Smi::cast(this->get(Derived::EntryToIndex(entry) + 2))); | 3620 Smi::cast(this->get(Derived::EntryToIndex(entry) + 2))); |
3624 } | 3621 } |
3625 | 3622 |
3626 // Set the details for entry. | 3623 // Set the details for entry. |
3627 void DetailsAtPut(int entry, PropertyDetails value) { | 3624 void DetailsAtPut(int entry, PropertyDetails value) { |
3628 this->set(Derived::EntryToIndex(entry) + 2, value.AsSmi()); | 3625 this->set(Derived::EntryToIndex(entry) + 2, value.AsSmi()); |
3629 } | 3626 } |
3630 | 3627 |
| 3628 // Returns true if property at given entry is deleted. |
| 3629 bool IsDeleted(int entry) { |
| 3630 return Shape::IsDeleted(static_cast<Derived*>(this), entry); |
| 3631 } |
| 3632 |
3631 // Delete a property from the dictionary. | 3633 // Delete a property from the dictionary. |
3632 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry); | 3634 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry); |
3633 | 3635 |
3634 // Attempt to shrink the dictionary after deletion of key. | 3636 // Attempt to shrink the dictionary after deletion of key. |
3635 MUST_USE_RESULT static inline Handle<Derived> Shrink( | 3637 MUST_USE_RESULT static inline Handle<Derived> Shrink( |
3636 Handle<Derived> dictionary, | 3638 Handle<Derived> dictionary, |
3637 Key key) { | 3639 Key key) { |
3638 return DerivedHashTable::Shrink(dictionary, key); | 3640 return DerivedHashTable::Shrink(dictionary, key); |
3639 } | 3641 } |
3640 | 3642 |
3641 // Sorting support | 3643 // Sorting support |
3642 // TODO(dcarney): templatize or move to SeededNumberDictionary | 3644 // TODO(dcarney): templatize or move to SeededNumberDictionary |
3643 void CopyValuesTo(FixedArray* elements); | 3645 void CopyValuesTo(FixedArray* elements); |
3644 | 3646 |
3645 // Returns the number of elements in the dictionary filtering out properties | 3647 // Returns the number of elements in the dictionary filtering out properties |
3646 // with the specified attributes. | 3648 // with the specified attributes. |
3647 template <DictionaryEntryType type> | |
3648 int NumberOfElementsFilterAttributes(PropertyAttributes filter); | 3649 int NumberOfElementsFilterAttributes(PropertyAttributes filter); |
3649 int NumberOfElementsFilterAttributes(Object* holder, | |
3650 PropertyAttributes filter) { | |
3651 if (holder->IsGlobalObject()) { | |
3652 return NumberOfElementsFilterAttributes<DictionaryEntryType::kCells>( | |
3653 filter); | |
3654 } else { | |
3655 return NumberOfElementsFilterAttributes<DictionaryEntryType::kObjects>( | |
3656 filter); | |
3657 } | |
3658 } | |
3659 | 3650 |
3660 // Returns the number of enumerable elements in the dictionary. | 3651 // Returns the number of enumerable elements in the dictionary. |
3661 template <DictionaryEntryType type> | |
3662 int NumberOfEnumElements() { | 3652 int NumberOfEnumElements() { |
3663 return NumberOfElementsFilterAttributes<type>( | 3653 return NumberOfElementsFilterAttributes( |
3664 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 3654 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
3665 } | 3655 } |
3666 int NumberOfEnumElements(Object* holder) { | |
3667 if (holder->IsGlobalObject()) { | |
3668 return NumberOfEnumElements<DictionaryEntryType::kCells>(); | |
3669 } else { | |
3670 return NumberOfEnumElements<DictionaryEntryType::kObjects>(); | |
3671 } | |
3672 } | |
3673 | 3656 |
3674 // Returns true if the dictionary contains any elements that are non-writable, | 3657 // Returns true if the dictionary contains any elements that are non-writable, |
3675 // non-configurable, non-enumerable, or have getters/setters. | 3658 // non-configurable, non-enumerable, or have getters/setters. |
3676 template <DictionaryEntryType type> | |
3677 bool HasComplexElements(); | 3659 bool HasComplexElements(); |
3678 bool HasComplexElements(Object* holder) { | |
3679 if (holder->IsGlobalObject()) { | |
3680 return HasComplexElements<DictionaryEntryType::kCells>(); | |
3681 } else { | |
3682 return HasComplexElements<DictionaryEntryType::kObjects>(); | |
3683 } | |
3684 } | |
3685 | 3660 |
3686 enum SortMode { UNSORTED, SORTED }; | 3661 enum SortMode { UNSORTED, SORTED }; |
3687 | 3662 |
3688 // Copies keys to preallocated fixed array. | 3663 // Copies keys to preallocated fixed array. |
3689 template <DictionaryEntryType type> | |
3690 void CopyKeysTo(FixedArray* storage, PropertyAttributes filter, | 3664 void CopyKeysTo(FixedArray* storage, PropertyAttributes filter, |
3691 SortMode sort_mode); | 3665 SortMode sort_mode); |
3692 void CopyKeysTo(Object* holder, FixedArray* storage, | |
3693 PropertyAttributes filter, SortMode sort_mode) { | |
3694 if (holder->IsGlobalObject()) { | |
3695 return CopyKeysTo<DictionaryEntryType::kCells>(storage, filter, | |
3696 sort_mode); | |
3697 } else { | |
3698 return CopyKeysTo<DictionaryEntryType::kObjects>(storage, filter, | |
3699 sort_mode); | |
3700 } | |
3701 } | |
3702 | 3666 |
3703 // Fill in details for properties into storage. | 3667 // Fill in details for properties into storage. |
3704 template <DictionaryEntryType type> | |
3705 void CopyKeysTo(FixedArray* storage, int index, PropertyAttributes filter, | 3668 void CopyKeysTo(FixedArray* storage, int index, PropertyAttributes filter, |
3706 SortMode sort_mode); | 3669 SortMode sort_mode); |
3707 void CopyKeysTo(Object* holder, FixedArray* storage, int index, | |
3708 PropertyAttributes filter, SortMode sort_mode) { | |
3709 if (holder->IsGlobalObject()) { | |
3710 return CopyKeysTo<DictionaryEntryType::kCells>(storage, index, filter, | |
3711 sort_mode); | |
3712 } else { | |
3713 return CopyKeysTo<DictionaryEntryType::kObjects>(storage, index, filter, | |
3714 sort_mode); | |
3715 } | |
3716 } | |
3717 | 3670 |
3718 // Copies enumerable keys to preallocated fixed array. | 3671 // Copies enumerable keys to preallocated fixed array. |
3719 template <DictionaryEntryType type> | |
3720 void CopyEnumKeysTo(FixedArray* storage); | 3672 void CopyEnumKeysTo(FixedArray* storage); |
3721 void CopyEnumKeysTo(Object* holder, FixedArray* storage) { | |
3722 if (holder->IsGlobalObject()) { | |
3723 return CopyEnumKeysTo<DictionaryEntryType::kCells>(storage); | |
3724 } else { | |
3725 return CopyEnumKeysTo<DictionaryEntryType::kObjects>(storage); | |
3726 } | |
3727 } | |
3728 | 3673 |
3729 // Accessors for next enumeration index. | 3674 // Accessors for next enumeration index. |
3730 void SetNextEnumerationIndex(int index) { | 3675 void SetNextEnumerationIndex(int index) { |
3731 DCHECK(index != 0); | 3676 DCHECK(index != 0); |
3732 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); | 3677 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); |
3733 } | 3678 } |
3734 | 3679 |
3735 int NextEnumerationIndex() { | 3680 int NextEnumerationIndex() { |
3736 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value(); | 3681 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value(); |
3737 } | 3682 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3799 class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > { | 3744 class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > { |
3800 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary; | 3745 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary; |
3801 | 3746 |
3802 public: | 3747 public: |
3803 // Find entry for key, otherwise return kNotFound. Optimized version of | 3748 // Find entry for key, otherwise return kNotFound. Optimized version of |
3804 // HashTable::FindEntry. | 3749 // HashTable::FindEntry. |
3805 int FindEntry(Handle<Name> key); | 3750 int FindEntry(Handle<Name> key); |
3806 }; | 3751 }; |
3807 | 3752 |
3808 | 3753 |
3809 class NameDictionaryShape : public BaseShape<Handle<Name> > { | 3754 template <typename Key> |
| 3755 class BaseDictionaryShape : public BaseShape<Key> { |
| 3756 public: |
| 3757 template <typename Dictionary> |
| 3758 static bool IsDeleted(Dictionary* dict, int entry) { |
| 3759 return false; |
| 3760 } |
| 3761 }; |
| 3762 |
| 3763 |
| 3764 class NameDictionaryShape : public BaseDictionaryShape<Handle<Name> > { |
3810 public: | 3765 public: |
3811 static inline bool IsMatch(Handle<Name> key, Object* other); | 3766 static inline bool IsMatch(Handle<Name> key, Object* other); |
3812 static inline uint32_t Hash(Handle<Name> key); | 3767 static inline uint32_t Hash(Handle<Name> key); |
3813 static inline uint32_t HashForObject(Handle<Name> key, Object* object); | 3768 static inline uint32_t HashForObject(Handle<Name> key, Object* object); |
3814 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key); | 3769 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key); |
3815 static const int kPrefixSize = 2; | 3770 static const int kPrefixSize = 2; |
3816 static const int kEntrySize = 3; | 3771 static const int kEntrySize = 3; |
3817 static const bool kIsEnumerable = true; | 3772 static const bool kIsEnumerable = true; |
3818 }; | 3773 }; |
3819 | 3774 |
3820 | 3775 |
3821 class NameDictionary | 3776 class NameDictionary |
3822 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> { | 3777 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> { |
3823 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape> | 3778 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape> |
3824 DerivedDictionary; | 3779 DerivedDictionary; |
3825 | 3780 |
3826 public: | 3781 public: |
3827 DECLARE_CAST(NameDictionary) | 3782 DECLARE_CAST(NameDictionary) |
3828 | 3783 |
3829 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices( | 3784 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices( |
3830 Handle<NameDictionary> dictionary); | 3785 Handle<NameDictionary> dictionary); |
3831 }; | 3786 }; |
3832 | 3787 |
3833 | 3788 |
3834 class GlobalDictionaryShape : public NameDictionaryShape { | 3789 class GlobalDictionaryShape : public NameDictionaryShape { |
3835 public: | 3790 public: |
3836 static const int kEntrySize = 3; // Overrides NameDictionaryShape::kEntrySize | 3791 static const int kEntrySize = 3; // Overrides NameDictionaryShape::kEntrySize |
| 3792 |
| 3793 template <typename Dictionary> |
| 3794 static bool IsDeleted(Dictionary* dict, int entry); |
3837 }; | 3795 }; |
3838 | 3796 |
3839 | 3797 |
3840 class GlobalDictionary | 3798 class GlobalDictionary |
3841 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> { | 3799 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> { |
3842 public: | 3800 public: |
3843 DECLARE_CAST(GlobalDictionary) | 3801 DECLARE_CAST(GlobalDictionary) |
3844 }; | 3802 }; |
3845 | 3803 |
3846 | 3804 |
3847 class NumberDictionaryShape : public BaseShape<uint32_t> { | 3805 class NumberDictionaryShape : public BaseDictionaryShape<uint32_t> { |
3848 public: | 3806 public: |
3849 static inline bool IsMatch(uint32_t key, Object* other); | 3807 static inline bool IsMatch(uint32_t key, Object* other); |
3850 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key); | 3808 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key); |
3851 static const int kEntrySize = 3; | 3809 static const int kEntrySize = 3; |
3852 static const bool kIsEnumerable = false; | 3810 static const bool kIsEnumerable = false; |
3853 }; | 3811 }; |
3854 | 3812 |
3855 | 3813 |
3856 class SeededNumberDictionaryShape : public NumberDictionaryShape { | 3814 class SeededNumberDictionaryShape : public NumberDictionaryShape { |
3857 public: | 3815 public: |
(...skipping 7354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11212 } else { | 11170 } else { |
11213 value &= ~(1 << bit_position); | 11171 value &= ~(1 << bit_position); |
11214 } | 11172 } |
11215 return value; | 11173 return value; |
11216 } | 11174 } |
11217 }; | 11175 }; |
11218 | 11176 |
11219 } } // namespace v8::internal | 11177 } } // namespace v8::internal |
11220 | 11178 |
11221 #endif // V8_OBJECTS_H_ | 11179 #endif // V8_OBJECTS_H_ |
OLD | NEW |