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