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 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1045 INLINE(bool IsStruct() const); | 1045 INLINE(bool IsStruct() const); |
1046 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \ | 1046 #define DECLARE_STRUCT_PREDICATE(NAME, Name, name) \ |
1047 INLINE(bool Is##Name() const); | 1047 INLINE(bool Is##Name() const); |
1048 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) | 1048 STRUCT_LIST(DECLARE_STRUCT_PREDICATE) |
1049 #undef DECLARE_STRUCT_PREDICATE | 1049 #undef DECLARE_STRUCT_PREDICATE |
1050 | 1050 |
1051 INLINE(bool IsSpecObject()) const; | 1051 INLINE(bool IsSpecObject()) const; |
1052 INLINE(bool IsSpecFunction()) const; | 1052 INLINE(bool IsSpecFunction()) const; |
1053 INLINE(bool IsTemplateInfo()) const; | 1053 INLINE(bool IsTemplateInfo()) const; |
1054 INLINE(bool IsNameDictionary() const); | 1054 INLINE(bool IsNameDictionary() const); |
| 1055 INLINE(bool IsGlobalDictionary() const); |
1055 INLINE(bool IsSeededNumberDictionary() const); | 1056 INLINE(bool IsSeededNumberDictionary() const); |
1056 INLINE(bool IsUnseededNumberDictionary() const); | 1057 INLINE(bool IsUnseededNumberDictionary() const); |
1057 INLINE(bool IsOrderedHashSet() const); | 1058 INLINE(bool IsOrderedHashSet() const); |
1058 INLINE(bool IsOrderedHashMap() const); | 1059 INLINE(bool IsOrderedHashMap() const); |
1059 bool IsCallable() const; | 1060 bool IsCallable() const; |
1060 static bool IsPromise(Handle<Object> object); | 1061 static bool IsPromise(Handle<Object> object); |
1061 | 1062 |
1062 // Oddball testing. | 1063 // Oddball testing. |
1063 INLINE(bool IsUndefined() const); | 1064 INLINE(bool IsUndefined() const); |
1064 INLINE(bool IsNull() const); | 1065 INLINE(bool IsNull() const); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 // Note that the map of JSObject changes during execution to enable inline | 1715 // Note that the map of JSObject changes during execution to enable inline |
1715 // caching. | 1716 // caching. |
1716 class JSObject: public JSReceiver { | 1717 class JSObject: public JSReceiver { |
1717 public: | 1718 public: |
1718 // [properties]: Backing storage for properties. | 1719 // [properties]: Backing storage for properties. |
1719 // properties is a FixedArray in the fast case and a Dictionary in the | 1720 // properties is a FixedArray in the fast case and a Dictionary in the |
1720 // slow case. | 1721 // slow case. |
1721 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. | 1722 DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. |
1722 inline void initialize_properties(); | 1723 inline void initialize_properties(); |
1723 inline bool HasFastProperties(); | 1724 inline bool HasFastProperties(); |
1724 inline NameDictionary* property_dictionary(); // Gets slow properties. | 1725 // Gets slow properties for non-global objects. |
| 1726 inline NameDictionary* property_dictionary(); |
| 1727 // Gets global object properties. |
| 1728 inline GlobalDictionary* global_dictionary(); |
1725 | 1729 |
1726 // [elements]: The elements (properties with names that are integers). | 1730 // [elements]: The elements (properties with names that are integers). |
1727 // | 1731 // |
1728 // Elements can be in two general modes: fast and slow. Each mode | 1732 // Elements can be in two general modes: fast and slow. Each mode |
1729 // corrensponds to a set of object representations of elements that | 1733 // corrensponds to a set of object representations of elements that |
1730 // have something in common. | 1734 // have something in common. |
1731 // | 1735 // |
1732 // In the fast mode elements is a FixedArray and so each element can | 1736 // In the fast mode elements is a FixedArray and so each element can |
1733 // be quickly accessed. This fact is used in the generated code. The | 1737 // be quickly accessed. This fact is used in the generated code. The |
1734 // elements array can have one of three maps in this mode: | 1738 // elements array can have one of three maps in this mode: |
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3583 | 3587 |
3584 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable); | 3588 DISALLOW_IMPLICIT_CONSTRUCTORS(StringTable); |
3585 }; | 3589 }; |
3586 | 3590 |
3587 | 3591 |
3588 enum class DictionaryEntryType { kObjects, kCells }; | 3592 enum class DictionaryEntryType { kObjects, kCells }; |
3589 | 3593 |
3590 | 3594 |
3591 template <typename Derived, typename Shape, typename Key> | 3595 template <typename Derived, typename Shape, typename Key> |
3592 class Dictionary: public HashTable<Derived, Shape, Key> { | 3596 class Dictionary: public HashTable<Derived, Shape, Key> { |
3593 protected: | |
3594 typedef HashTable<Derived, Shape, Key> DerivedHashTable; | 3597 typedef HashTable<Derived, Shape, Key> DerivedHashTable; |
3595 | 3598 |
3596 public: | 3599 public: |
3597 // Returns the value at entry. | 3600 // Returns the value at entry. |
3598 Object* ValueAt(int entry) { | 3601 Object* ValueAt(int entry) { |
3599 return this->get(DerivedHashTable::EntryToIndex(entry) + 1); | 3602 return this->get(Derived::EntryToIndex(entry) + 1); |
3600 } | 3603 } |
3601 | 3604 |
3602 // Set the value for entry. | 3605 // Set the value for entry. |
3603 void ValueAtPut(int entry, Object* value) { | 3606 void ValueAtPut(int entry, Object* value) { |
3604 this->set(DerivedHashTable::EntryToIndex(entry) + 1, value); | 3607 this->set(Derived::EntryToIndex(entry) + 1, value); |
3605 } | 3608 } |
3606 | 3609 |
3607 // Returns the property details for the property at entry. | 3610 // Returns the property details for the property at entry. |
3608 PropertyDetails DetailsAt(int entry) { | 3611 PropertyDetails DetailsAt(int entry) { |
3609 DCHECK(entry >= 0); // Not found is -1, which is not caught by get(). | 3612 DCHECK(entry >= 0); // Not found is -1, which is not caught by get(). |
3610 return PropertyDetails( | 3613 return PropertyDetails( |
3611 Smi::cast(this->get(DerivedHashTable::EntryToIndex(entry) + 2))); | 3614 Smi::cast(this->get(Derived::EntryToIndex(entry) + 2))); |
3612 } | 3615 } |
3613 | 3616 |
3614 // Set the details for entry. | 3617 // Set the details for entry. |
3615 void DetailsAtPut(int entry, PropertyDetails value) { | 3618 void DetailsAtPut(int entry, PropertyDetails value) { |
3616 this->set(DerivedHashTable::EntryToIndex(entry) + 2, value.AsSmi()); | 3619 this->set(Derived::EntryToIndex(entry) + 2, value.AsSmi()); |
3617 } | 3620 } |
3618 | 3621 |
3619 // Delete a property from the dictionary. | 3622 // Delete a property from the dictionary. |
3620 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry); | 3623 static Handle<Object> DeleteProperty(Handle<Derived> dictionary, int entry); |
3621 | 3624 |
3622 // Attempt to shrink the dictionary after deletion of key. | 3625 // Attempt to shrink the dictionary after deletion of key. |
3623 MUST_USE_RESULT static inline Handle<Derived> Shrink( | 3626 MUST_USE_RESULT static inline Handle<Derived> Shrink( |
3624 Handle<Derived> dictionary, | 3627 Handle<Derived> dictionary, |
3625 Key key) { | 3628 Key key) { |
3626 return DerivedHashTable::Shrink(dictionary, key); | 3629 return DerivedHashTable::Shrink(dictionary, key); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3696 PropertyAttributes filter, SortMode sort_mode) { | 3699 PropertyAttributes filter, SortMode sort_mode) { |
3697 if (holder->IsGlobalObject()) { | 3700 if (holder->IsGlobalObject()) { |
3698 return CopyKeysTo<DictionaryEntryType::kCells>(storage, index, filter, | 3701 return CopyKeysTo<DictionaryEntryType::kCells>(storage, index, filter, |
3699 sort_mode); | 3702 sort_mode); |
3700 } else { | 3703 } else { |
3701 return CopyKeysTo<DictionaryEntryType::kObjects>(storage, index, filter, | 3704 return CopyKeysTo<DictionaryEntryType::kObjects>(storage, index, filter, |
3702 sort_mode); | 3705 sort_mode); |
3703 } | 3706 } |
3704 } | 3707 } |
3705 | 3708 |
| 3709 // Copies enumerable keys to preallocated fixed array. |
| 3710 template <DictionaryEntryType type> |
| 3711 void CopyEnumKeysTo(FixedArray* storage); |
| 3712 void CopyEnumKeysTo(Object* holder, FixedArray* storage) { |
| 3713 if (holder->IsGlobalObject()) { |
| 3714 return CopyEnumKeysTo<DictionaryEntryType::kCells>(storage); |
| 3715 } else { |
| 3716 return CopyEnumKeysTo<DictionaryEntryType::kObjects>(storage); |
| 3717 } |
| 3718 } |
| 3719 |
3706 // Accessors for next enumeration index. | 3720 // Accessors for next enumeration index. |
3707 void SetNextEnumerationIndex(int index) { | 3721 void SetNextEnumerationIndex(int index) { |
3708 DCHECK(index != 0); | 3722 DCHECK(index != 0); |
3709 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); | 3723 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); |
3710 } | 3724 } |
3711 | 3725 |
3712 int NextEnumerationIndex() { | 3726 int NextEnumerationIndex() { |
3713 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value(); | 3727 return Smi::cast(this->get(kNextEnumerationIndexIndex))->value(); |
3714 } | 3728 } |
3715 | 3729 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3765 | 3779 |
3766 // Generate new enumeration indices to avoid enumeration index overflow. | 3780 // Generate new enumeration indices to avoid enumeration index overflow. |
3767 // Returns iteration indices array for the |dictionary|. | 3781 // Returns iteration indices array for the |dictionary|. |
3768 static Handle<FixedArray> GenerateNewEnumerationIndices( | 3782 static Handle<FixedArray> GenerateNewEnumerationIndices( |
3769 Handle<Derived> dictionary); | 3783 Handle<Derived> dictionary); |
3770 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex; | 3784 static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex; |
3771 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; | 3785 static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1; |
3772 }; | 3786 }; |
3773 | 3787 |
3774 | 3788 |
| 3789 template <typename Derived, typename Shape> |
| 3790 class NameDictionaryBase : public Dictionary<Derived, Shape, Handle<Name> > { |
| 3791 typedef Dictionary<Derived, Shape, Handle<Name> > DerivedDictionary; |
| 3792 |
| 3793 public: |
| 3794 // Find entry for key, otherwise return kNotFound. Optimized version of |
| 3795 // HashTable::FindEntry. |
| 3796 int FindEntry(Handle<Name> key); |
| 3797 }; |
| 3798 |
| 3799 |
3775 class NameDictionaryShape : public BaseShape<Handle<Name> > { | 3800 class NameDictionaryShape : public BaseShape<Handle<Name> > { |
3776 public: | 3801 public: |
3777 static inline bool IsMatch(Handle<Name> key, Object* other); | 3802 static inline bool IsMatch(Handle<Name> key, Object* other); |
3778 static inline uint32_t Hash(Handle<Name> key); | 3803 static inline uint32_t Hash(Handle<Name> key); |
3779 static inline uint32_t HashForObject(Handle<Name> key, Object* object); | 3804 static inline uint32_t HashForObject(Handle<Name> key, Object* object); |
3780 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key); | 3805 static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key); |
3781 static const int kPrefixSize = 2; | 3806 static const int kPrefixSize = 2; |
3782 static const int kEntrySize = 3; | 3807 static const int kEntrySize = 3; |
3783 static const bool kIsEnumerable = true; | 3808 static const bool kIsEnumerable = true; |
3784 }; | 3809 }; |
3785 | 3810 |
3786 | 3811 |
3787 class NameDictionary: public Dictionary<NameDictionary, | 3812 class NameDictionary |
3788 NameDictionaryShape, | 3813 : public NameDictionaryBase<NameDictionary, NameDictionaryShape> { |
3789 Handle<Name> > { | 3814 typedef NameDictionaryBase<NameDictionary, NameDictionaryShape> |
3790 typedef Dictionary< | 3815 DerivedDictionary; |
3791 NameDictionary, NameDictionaryShape, Handle<Name> > DerivedDictionary; | |
3792 | 3816 |
3793 public: | 3817 public: |
3794 DECLARE_CAST(NameDictionary) | 3818 DECLARE_CAST(NameDictionary) |
3795 | 3819 |
3796 // Copies enumerable keys to preallocated fixed array. | |
3797 template <DictionaryEntryType type> | |
3798 void CopyEnumKeysTo(FixedArray* storage); | |
3799 void CopyEnumKeysTo(Object* holder, FixedArray* storage) { | |
3800 if (holder->IsGlobalObject()) { | |
3801 return CopyEnumKeysTo<DictionaryEntryType::kCells>(storage); | |
3802 } else { | |
3803 return CopyEnumKeysTo<DictionaryEntryType::kObjects>(storage); | |
3804 } | |
3805 } | |
3806 | |
3807 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices( | 3820 inline static Handle<FixedArray> DoGenerateNewEnumerationIndices( |
3808 Handle<NameDictionary> dictionary); | 3821 Handle<NameDictionary> dictionary); |
3809 | |
3810 // Find entry for key, otherwise return kNotFound. Optimized version of | |
3811 // HashTable::FindEntry. | |
3812 int FindEntry(Handle<Name> key); | |
3813 }; | 3822 }; |
3814 | 3823 |
3815 | 3824 |
| 3825 class GlobalDictionaryShape : public NameDictionaryShape { |
| 3826 public: |
| 3827 static const int kEntrySize = 3; // Overrides NameDictionaryShape::kEntrySize |
| 3828 }; |
| 3829 |
| 3830 |
| 3831 class GlobalDictionary |
| 3832 : public NameDictionaryBase<GlobalDictionary, GlobalDictionaryShape> { |
| 3833 public: |
| 3834 DECLARE_CAST(GlobalDictionary) |
| 3835 }; |
| 3836 |
| 3837 |
3816 class NumberDictionaryShape : public BaseShape<uint32_t> { | 3838 class NumberDictionaryShape : public BaseShape<uint32_t> { |
3817 public: | 3839 public: |
3818 static inline bool IsMatch(uint32_t key, Object* other); | 3840 static inline bool IsMatch(uint32_t key, Object* other); |
3819 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key); | 3841 static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key); |
3820 static const int kEntrySize = 3; | 3842 static const int kEntrySize = 3; |
3821 static const bool kIsEnumerable = false; | 3843 static const bool kIsEnumerable = false; |
3822 }; | 3844 }; |
3823 | 3845 |
3824 | 3846 |
3825 class SeededNumberDictionaryShape : public NumberDictionaryShape { | 3847 class SeededNumberDictionaryShape : public NumberDictionaryShape { |
(...skipping 7342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11168 } else { | 11190 } else { |
11169 value &= ~(1 << bit_position); | 11191 value &= ~(1 << bit_position); |
11170 } | 11192 } |
11171 return value; | 11193 return value; |
11172 } | 11194 } |
11173 }; | 11195 }; |
11174 | 11196 |
11175 } } // namespace v8::internal | 11197 } } // namespace v8::internal |
11176 | 11198 |
11177 #endif // V8_OBJECTS_H_ | 11199 #endif // V8_OBJECTS_H_ |
OLD | NEW |