OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 // only be used for storing old space objects or smis. | 2032 // only be used for storing old space objects or smis. |
2033 static inline void fast_set(FixedArray* array, int index, Object* value); | 2033 static inline void fast_set(FixedArray* array, int index, Object* value); |
2034 | 2034 |
2035 private: | 2035 private: |
2036 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); | 2036 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); |
2037 }; | 2037 }; |
2038 | 2038 |
2039 | 2039 |
2040 // DescriptorArrays are fixed arrays used to hold instance descriptors. | 2040 // DescriptorArrays are fixed arrays used to hold instance descriptors. |
2041 // The format of the these objects is: | 2041 // The format of the these objects is: |
2042 // [0]: point to a fixed array with (value, detail) pairs. | 2042 // TODO(1399): It should be possible to make room for bit_field3 in the map |
2043 // [1]: next enumeration index (Smi), or pointer to small fixed array: | 2043 // without overloading the instance descriptors field in the map |
| 2044 // (and storing it in the DescriptorArray when the map has one). |
| 2045 // [0]: storage for bit_field3 for Map owning this object (Smi) |
| 2046 // [1]: point to a fixed array with (value, detail) pairs. |
| 2047 // [2]: next enumeration index (Smi), or pointer to small fixed array: |
2044 // [0]: next enumeration index (Smi) | 2048 // [0]: next enumeration index (Smi) |
2045 // [1]: pointer to fixed array with enum cache | 2049 // [1]: pointer to fixed array with enum cache |
2046 // [2]: first key | 2050 // [3]: first key |
2047 // [length() - 1]: last key | 2051 // [length() - 1]: last key |
2048 // | 2052 // |
2049 class DescriptorArray: public FixedArray { | 2053 class DescriptorArray: public FixedArray { |
2050 public: | 2054 public: |
2051 // Is this the singleton empty_descriptor_array? | 2055 // Returns true for both shared empty_descriptor_array and for smis, which the |
| 2056 // map uses to encode additional bit fields when the descriptor array is not |
| 2057 // yet used. |
2052 inline bool IsEmpty(); | 2058 inline bool IsEmpty(); |
2053 | 2059 |
2054 // Returns the number of descriptors in the array. | 2060 // Returns the number of descriptors in the array. |
2055 int number_of_descriptors() { | 2061 int number_of_descriptors() { |
2056 ASSERT(length() > kFirstIndex || IsEmpty()); | 2062 ASSERT(length() > kFirstIndex || IsEmpty()); |
2057 int len = length(); | 2063 int len = length(); |
2058 return len <= kFirstIndex ? 0 : len - kFirstIndex; | 2064 return len <= kFirstIndex ? 0 : len - kFirstIndex; |
2059 } | 2065 } |
2060 | 2066 |
2061 int NextEnumerationIndex() { | 2067 int NextEnumerationIndex() { |
(...skipping 16 matching lines...) Expand all Loading... |
2078 bool HasEnumCache() { | 2084 bool HasEnumCache() { |
2079 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); | 2085 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); |
2080 } | 2086 } |
2081 | 2087 |
2082 Object* GetEnumCache() { | 2088 Object* GetEnumCache() { |
2083 ASSERT(HasEnumCache()); | 2089 ASSERT(HasEnumCache()); |
2084 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); | 2090 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); |
2085 return bridge->get(kEnumCacheBridgeCacheIndex); | 2091 return bridge->get(kEnumCacheBridgeCacheIndex); |
2086 } | 2092 } |
2087 | 2093 |
| 2094 // TODO(1399): It should be possible to make room for bit_field3 in the map |
| 2095 // without overloading the instance descriptors field in the map |
| 2096 // (and storing it in the DescriptorArray when the map has one). |
| 2097 inline int bit_field3_storage(); |
| 2098 inline void set_bit_field3_storage(int value); |
| 2099 |
2088 // Initialize or change the enum cache, | 2100 // Initialize or change the enum cache, |
2089 // using the supplied storage for the small "bridge". | 2101 // using the supplied storage for the small "bridge". |
2090 void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache); | 2102 void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache); |
2091 | 2103 |
2092 // Accessors for fetching instance descriptor at descriptor number. | 2104 // Accessors for fetching instance descriptor at descriptor number. |
2093 inline String* GetKey(int descriptor_number); | 2105 inline String* GetKey(int descriptor_number); |
2094 inline Object* GetValue(int descriptor_number); | 2106 inline Object* GetValue(int descriptor_number); |
2095 inline Smi* GetDetails(int descriptor_number); | 2107 inline Smi* GetDetails(int descriptor_number); |
2096 inline PropertyType GetType(int descriptor_number); | 2108 inline PropertyType GetType(int descriptor_number); |
2097 inline int GetFieldIndex(int descriptor_number); | 2109 inline int GetFieldIndex(int descriptor_number); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 // Allocates a DescriptorArray, but returns the singleton | 2168 // Allocates a DescriptorArray, but returns the singleton |
2157 // empty descriptor array object if number_of_descriptors is 0. | 2169 // empty descriptor array object if number_of_descriptors is 0. |
2158 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); | 2170 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); |
2159 | 2171 |
2160 // Casting. | 2172 // Casting. |
2161 static inline DescriptorArray* cast(Object* obj); | 2173 static inline DescriptorArray* cast(Object* obj); |
2162 | 2174 |
2163 // Constant for denoting key was not found. | 2175 // Constant for denoting key was not found. |
2164 static const int kNotFound = -1; | 2176 static const int kNotFound = -1; |
2165 | 2177 |
2166 static const int kContentArrayIndex = 0; | 2178 static const int kBitField3StorageIndex = 0; |
2167 static const int kEnumerationIndexIndex = 1; | 2179 static const int kContentArrayIndex = 1; |
2168 static const int kFirstIndex = 2; | 2180 static const int kEnumerationIndexIndex = 2; |
| 2181 static const int kFirstIndex = 3; |
2169 | 2182 |
2170 // The length of the "bridge" to the enum cache. | 2183 // The length of the "bridge" to the enum cache. |
2171 static const int kEnumCacheBridgeLength = 2; | 2184 static const int kEnumCacheBridgeLength = 2; |
2172 static const int kEnumCacheBridgeEnumIndex = 0; | 2185 static const int kEnumCacheBridgeEnumIndex = 0; |
2173 static const int kEnumCacheBridgeCacheIndex = 1; | 2186 static const int kEnumCacheBridgeCacheIndex = 1; |
2174 | 2187 |
2175 // Layout description. | 2188 // Layout description. |
2176 static const int kContentArrayOffset = FixedArray::kHeaderSize; | 2189 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; |
| 2190 static const int kContentArrayOffset = kBitField3StorageOffset + kPointerSize; |
2177 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; | 2191 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; |
2178 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; | 2192 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; |
2179 | 2193 |
2180 // Layout description for the bridge array. | 2194 // Layout description for the bridge array. |
2181 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; | 2195 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; |
2182 static const int kEnumCacheBridgeCacheOffset = | 2196 static const int kEnumCacheBridgeCacheOffset = |
2183 kEnumCacheBridgeEnumOffset + kPointerSize; | 2197 kEnumCacheBridgeEnumOffset + kPointerSize; |
2184 | 2198 |
2185 #ifdef OBJECT_PRINT | 2199 #ifdef OBJECT_PRINT |
2186 // Print all the descriptors. | 2200 // Print all the descriptors. |
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3638 inline void set_unused_property_fields(int value); | 3652 inline void set_unused_property_fields(int value); |
3639 | 3653 |
3640 // Bit field. | 3654 // Bit field. |
3641 inline byte bit_field(); | 3655 inline byte bit_field(); |
3642 inline void set_bit_field(byte value); | 3656 inline void set_bit_field(byte value); |
3643 | 3657 |
3644 // Bit field 2. | 3658 // Bit field 2. |
3645 inline byte bit_field2(); | 3659 inline byte bit_field2(); |
3646 inline void set_bit_field2(byte value); | 3660 inline void set_bit_field2(byte value); |
3647 | 3661 |
| 3662 // Bit field 3. |
| 3663 // TODO(1399): It should be possible to make room for bit_field3 in the map |
| 3664 // without overloading the instance descriptors field (and storing it in the |
| 3665 // DescriptorArray when the map has one). |
| 3666 inline int bit_field3(); |
| 3667 inline void set_bit_field3(int value); |
| 3668 |
3648 // Tells whether the object in the prototype property will be used | 3669 // Tells whether the object in the prototype property will be used |
3649 // for instances created from this function. If the prototype | 3670 // for instances created from this function. If the prototype |
3650 // property is set to a value that is not a JSObject, the prototype | 3671 // property is set to a value that is not a JSObject, the prototype |
3651 // property will not be used to create instances of the function. | 3672 // property will not be used to create instances of the function. |
3652 // See ECMA-262, 13.2.2. | 3673 // See ECMA-262, 13.2.2. |
3653 inline void set_non_instance_prototype(bool value); | 3674 inline void set_non_instance_prototype(bool value); |
3654 inline bool has_non_instance_prototype(); | 3675 inline bool has_non_instance_prototype(); |
3655 | 3676 |
3656 // Tells whether function has special prototype property. If not, prototype | 3677 // Tells whether function has special prototype property. If not, prototype |
3657 // property will not be created when accessed (will return undefined), | 3678 // property will not be created when accessed (will return undefined), |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3759 inline bool is_access_check_needed(); | 3780 inline bool is_access_check_needed(); |
3760 | 3781 |
3761 // [prototype]: implicit prototype object. | 3782 // [prototype]: implicit prototype object. |
3762 DECL_ACCESSORS(prototype, Object) | 3783 DECL_ACCESSORS(prototype, Object) |
3763 | 3784 |
3764 // [constructor]: points back to the function responsible for this map. | 3785 // [constructor]: points back to the function responsible for this map. |
3765 DECL_ACCESSORS(constructor, Object) | 3786 DECL_ACCESSORS(constructor, Object) |
3766 | 3787 |
3767 inline JSFunction* unchecked_constructor(); | 3788 inline JSFunction* unchecked_constructor(); |
3768 | 3789 |
| 3790 // Should only be called by the code that initializes map to set initial valid |
| 3791 // value of the instance descriptor member. |
| 3792 inline void init_instance_descriptors(); |
| 3793 |
3769 // [instance descriptors]: describes the object. | 3794 // [instance descriptors]: describes the object. |
3770 DECL_ACCESSORS(instance_descriptors, DescriptorArray) | 3795 DECL_ACCESSORS(instance_descriptors, DescriptorArray) |
3771 | 3796 |
| 3797 // Sets the instance descriptor array for the map to be an empty descriptor |
| 3798 // array. |
| 3799 inline void clear_instance_descriptors(); |
| 3800 |
3772 // [stub cache]: contains stubs compiled for this map. | 3801 // [stub cache]: contains stubs compiled for this map. |
3773 DECL_ACCESSORS(code_cache, Object) | 3802 DECL_ACCESSORS(code_cache, Object) |
3774 | 3803 |
3775 // [prototype transitions]: cache of prototype transitions. | 3804 // [prototype transitions]: cache of prototype transitions. |
3776 // Prototype transition is a transition that happens | 3805 // Prototype transition is a transition that happens |
3777 // when we change object's prototype to a new one. | 3806 // when we change object's prototype to a new one. |
3778 // Cache format: | 3807 // Cache format: |
3779 // 0: finger - index of the first free cell in the cache | 3808 // 0: finger - index of the first free cell in the cache |
3780 // 1 + 2 * i: prototype | 3809 // 1 + 2 * i: prototype |
3781 // 2 + 2 * i: target map | 3810 // 2 + 2 * i: target map |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3887 | 3916 |
3888 MaybeObject* PutPrototypeTransition(Object* prototype, Map* map); | 3917 MaybeObject* PutPrototypeTransition(Object* prototype, Map* map); |
3889 | 3918 |
3890 static const int kMaxPreAllocatedPropertyFields = 255; | 3919 static const int kMaxPreAllocatedPropertyFields = 255; |
3891 | 3920 |
3892 // Layout description. | 3921 // Layout description. |
3893 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 3922 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
3894 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 3923 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
3895 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; | 3924 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; |
3896 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; | 3925 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; |
3897 static const int kInstanceDescriptorsOffset = | 3926 // Storage for instance descriptors is overloaded to also contain additional |
| 3927 // map flags when unused (bit_field3). When the map has instance descriptors, |
| 3928 // the flags are transferred to the instance descriptor array and accessed |
| 3929 // through an extra indirection. |
| 3930 // TODO(1399): It should be possible to make room for bit_field3 in the map |
| 3931 // without overloading the instance descriptors field, but the map is |
| 3932 // currently perfectly aligned to 32 bytes and extending it at all would |
| 3933 // double its size. After the increment GC work lands, this size restriction |
| 3934 // could be loosened and bit_field3 moved directly back in the map. |
| 3935 static const int kInstanceDescriptorsOrBitField3Offset = |
3898 kConstructorOffset + kPointerSize; | 3936 kConstructorOffset + kPointerSize; |
3899 static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize; | 3937 static const int kCodeCacheOffset = |
| 3938 kInstanceDescriptorsOrBitField3Offset + kPointerSize; |
3900 static const int kPrototypeTransitionsOffset = | 3939 static const int kPrototypeTransitionsOffset = |
3901 kCodeCacheOffset + kPointerSize; | 3940 kCodeCacheOffset + kPointerSize; |
3902 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; | 3941 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; |
3903 static const int kSize = MAP_POINTER_ALIGN(kPadStart); | 3942 static const int kSize = MAP_POINTER_ALIGN(kPadStart); |
3904 | 3943 |
3905 // Layout of pointer fields. Heap iteration code relies on them | 3944 // Layout of pointer fields. Heap iteration code relies on them |
3906 // being continiously allocated. | 3945 // being continiously allocated. |
3907 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; | 3946 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; |
3908 static const int kPointerFieldsEndOffset = | 3947 static const int kPointerFieldsEndOffset = |
3909 Map::kPrototypeTransitionsOffset + kPointerSize; | 3948 Map::kPrototypeTransitionsOffset + kPointerSize; |
(...skipping 2871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6781 } else { | 6820 } else { |
6782 value &= ~(1 << bit_position); | 6821 value &= ~(1 << bit_position); |
6783 } | 6822 } |
6784 return value; | 6823 return value; |
6785 } | 6824 } |
6786 }; | 6825 }; |
6787 | 6826 |
6788 } } // namespace v8::internal | 6827 } } // namespace v8::internal |
6789 | 6828 |
6790 #endif // V8_OBJECTS_H_ | 6829 #endif // V8_OBJECTS_H_ |
OLD | NEW |