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