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 // [0]: storage for bit_field3 for Map owning this object (Smi) |
Mads Ager (chromium)
2011/05/23 10:14:51
Add a TODO(bugnumber) comment about moving this to
danno
2011/06/01 13:15:11
Done.
| |
2043 // [1]: next enumeration index (Smi), or pointer to small fixed array: | 2043 // [1]: point to a fixed array with (value, detail) pairs. |
2044 // [2]: next enumeration index (Smi), or pointer to small fixed array: | |
2044 // [0]: next enumeration index (Smi) | 2045 // [0]: next enumeration index (Smi) |
2045 // [1]: pointer to fixed array with enum cache | 2046 // [1]: pointer to fixed array with enum cache |
2046 // [2]: first key | 2047 // [3]: first key |
2047 // [length() - 1]: last key | 2048 // [length() - 1]: last key |
2048 // | 2049 // |
2049 class DescriptorArray: public FixedArray { | 2050 class DescriptorArray: public FixedArray { |
2050 public: | 2051 public: |
2051 // Is this the singleton empty_descriptor_array? | 2052 // Returns true for both shared empty_descriptor_array and for smis, which the |
2053 // map uses to encode additional bit fields when the descriptor array is not | |
2054 // yet used. | |
2052 inline bool IsEmpty(); | 2055 inline bool IsEmpty(); |
2053 | 2056 |
2054 // Returns the number of descriptors in the array. | 2057 // Returns the number of descriptors in the array. |
2055 int number_of_descriptors() { | 2058 int number_of_descriptors() { |
2056 ASSERT(length() > kFirstIndex || IsEmpty()); | 2059 ASSERT(length() > kFirstIndex || IsEmpty()); |
2057 int len = length(); | 2060 int len = length(); |
2058 return len <= kFirstIndex ? 0 : len - kFirstIndex; | 2061 return len <= kFirstIndex ? 0 : len - kFirstIndex; |
2059 } | 2062 } |
2060 | 2063 |
2061 int NextEnumerationIndex() { | 2064 int NextEnumerationIndex() { |
(...skipping 16 matching lines...) Expand all Loading... | |
2078 bool HasEnumCache() { | 2081 bool HasEnumCache() { |
2079 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); | 2082 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); |
2080 } | 2083 } |
2081 | 2084 |
2082 Object* GetEnumCache() { | 2085 Object* GetEnumCache() { |
2083 ASSERT(HasEnumCache()); | 2086 ASSERT(HasEnumCache()); |
2084 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); | 2087 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); |
2085 return bridge->get(kEnumCacheBridgeCacheIndex); | 2088 return bridge->get(kEnumCacheBridgeCacheIndex); |
2086 } | 2089 } |
2087 | 2090 |
2091 inline int bit_field3_storage(); | |
Mads Ager (chromium)
2011/05/23 10:14:51
I would probably repeat the TODO(bugnumber) commen
danno
2011/06/01 13:15:11
Done.
| |
2092 inline void set_bit_field3_storage(int value); | |
2093 | |
2088 // Initialize or change the enum cache, | 2094 // Initialize or change the enum cache, |
2089 // using the supplied storage for the small "bridge". | 2095 // using the supplied storage for the small "bridge". |
2090 void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache); | 2096 void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache); |
2091 | 2097 |
2092 // Accessors for fetching instance descriptor at descriptor number. | 2098 // Accessors for fetching instance descriptor at descriptor number. |
2093 inline String* GetKey(int descriptor_number); | 2099 inline String* GetKey(int descriptor_number); |
2094 inline Object* GetValue(int descriptor_number); | 2100 inline Object* GetValue(int descriptor_number); |
2095 inline Smi* GetDetails(int descriptor_number); | 2101 inline Smi* GetDetails(int descriptor_number); |
2096 inline PropertyType GetType(int descriptor_number); | 2102 inline PropertyType GetType(int descriptor_number); |
2097 inline int GetFieldIndex(int descriptor_number); | 2103 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 | 2162 // Allocates a DescriptorArray, but returns the singleton |
2157 // empty descriptor array object if number_of_descriptors is 0. | 2163 // empty descriptor array object if number_of_descriptors is 0. |
2158 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); | 2164 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); |
2159 | 2165 |
2160 // Casting. | 2166 // Casting. |
2161 static inline DescriptorArray* cast(Object* obj); | 2167 static inline DescriptorArray* cast(Object* obj); |
2162 | 2168 |
2163 // Constant for denoting key was not found. | 2169 // Constant for denoting key was not found. |
2164 static const int kNotFound = -1; | 2170 static const int kNotFound = -1; |
2165 | 2171 |
2166 static const int kContentArrayIndex = 0; | 2172 static const int kBitField3StorageIndex = 0; |
2167 static const int kEnumerationIndexIndex = 1; | 2173 static const int kContentArrayIndex = 1; |
2168 static const int kFirstIndex = 2; | 2174 static const int kEnumerationIndexIndex = 2; |
2175 static const int kFirstIndex = 3; | |
2169 | 2176 |
2170 // The length of the "bridge" to the enum cache. | 2177 // The length of the "bridge" to the enum cache. |
2171 static const int kEnumCacheBridgeLength = 2; | 2178 static const int kEnumCacheBridgeLength = 2; |
2172 static const int kEnumCacheBridgeEnumIndex = 0; | 2179 static const int kEnumCacheBridgeEnumIndex = 0; |
2173 static const int kEnumCacheBridgeCacheIndex = 1; | 2180 static const int kEnumCacheBridgeCacheIndex = 1; |
2174 | 2181 |
2175 // Layout description. | 2182 // Layout description. |
2176 static const int kContentArrayOffset = FixedArray::kHeaderSize; | 2183 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; |
2184 static const int kContentArrayOffset = kBitField3StorageOffset + kPointerSize; | |
2177 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; | 2185 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; |
2178 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; | 2186 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; |
2179 | 2187 |
2180 // Layout description for the bridge array. | 2188 // Layout description for the bridge array. |
2181 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; | 2189 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; |
2182 static const int kEnumCacheBridgeCacheOffset = | 2190 static const int kEnumCacheBridgeCacheOffset = |
2183 kEnumCacheBridgeEnumOffset + kPointerSize; | 2191 kEnumCacheBridgeEnumOffset + kPointerSize; |
2184 | 2192 |
2185 #ifdef OBJECT_PRINT | 2193 #ifdef OBJECT_PRINT |
2186 // Print all the descriptors. | 2194 // 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); | 3646 inline void set_unused_property_fields(int value); |
3639 | 3647 |
3640 // Bit field. | 3648 // Bit field. |
3641 inline byte bit_field(); | 3649 inline byte bit_field(); |
3642 inline void set_bit_field(byte value); | 3650 inline void set_bit_field(byte value); |
3643 | 3651 |
3644 // Bit field 2. | 3652 // Bit field 2. |
3645 inline byte bit_field2(); | 3653 inline byte bit_field2(); |
3646 inline void set_bit_field2(byte value); | 3654 inline void set_bit_field2(byte value); |
3647 | 3655 |
3656 // Bit field 3. | |
Mads Ager (chromium)
2011/05/23 10:14:51
TODO(bugnumber) comment explaining that this is re
danno
2011/06/01 13:15:11
Done.
| |
3657 inline int bit_field3(); | |
3658 inline void set_bit_field3(int value); | |
3659 | |
3648 // Tells whether the object in the prototype property will be used | 3660 // Tells whether the object in the prototype property will be used |
3649 // for instances created from this function. If the prototype | 3661 // for instances created from this function. If the prototype |
3650 // property is set to a value that is not a JSObject, the prototype | 3662 // 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. | 3663 // property will not be used to create instances of the function. |
3652 // See ECMA-262, 13.2.2. | 3664 // See ECMA-262, 13.2.2. |
3653 inline void set_non_instance_prototype(bool value); | 3665 inline void set_non_instance_prototype(bool value); |
3654 inline bool has_non_instance_prototype(); | 3666 inline bool has_non_instance_prototype(); |
3655 | 3667 |
3656 // Tells whether function has special prototype property. If not, prototype | 3668 // Tells whether function has special prototype property. If not, prototype |
3657 // property will not be created when accessed (will return undefined), | 3669 // 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(); | 3771 inline bool is_access_check_needed(); |
3760 | 3772 |
3761 // [prototype]: implicit prototype object. | 3773 // [prototype]: implicit prototype object. |
3762 DECL_ACCESSORS(prototype, Object) | 3774 DECL_ACCESSORS(prototype, Object) |
3763 | 3775 |
3764 // [constructor]: points back to the function responsible for this map. | 3776 // [constructor]: points back to the function responsible for this map. |
3765 DECL_ACCESSORS(constructor, Object) | 3777 DECL_ACCESSORS(constructor, Object) |
3766 | 3778 |
3767 inline JSFunction* unchecked_constructor(); | 3779 inline JSFunction* unchecked_constructor(); |
3768 | 3780 |
3781 // Should only be called by the code that initializes map to set initial valid | |
3782 // value the instance descriptor member. | |
Mads Ager (chromium)
2011/05/23 10:14:51
value the -> value of the?
danno
2011/06/01 13:15:11
Done.
| |
3783 inline void init_instance_descriptors(); | |
3784 | |
3769 // [instance descriptors]: describes the object. | 3785 // [instance descriptors]: describes the object. |
3770 DECL_ACCESSORS(instance_descriptors, DescriptorArray) | 3786 DECL_ACCESSORS(instance_descriptors, DescriptorArray) |
3771 | 3787 |
3788 // Sets the instance descriptor array for the map to be an empty descriptor | |
3789 // list. | |
Mads Ager (chromium)
2011/05/23 10:14:51
list -> array
danno
2011/06/01 13:15:11
Done.
| |
3790 inline void clear_instance_descriptors(); | |
3791 | |
3772 // [stub cache]: contains stubs compiled for this map. | 3792 // [stub cache]: contains stubs compiled for this map. |
3773 DECL_ACCESSORS(code_cache, Object) | 3793 DECL_ACCESSORS(code_cache, Object) |
3774 | 3794 |
3775 // [prototype transitions]: cache of prototype transitions. | 3795 // [prototype transitions]: cache of prototype transitions. |
3776 // Prototype transition is a transition that happens | 3796 // Prototype transition is a transition that happens |
3777 // when we change object's prototype to a new one. | 3797 // when we change object's prototype to a new one. |
3778 // Cache format: | 3798 // Cache format: |
3779 // 0: finger - index of the first free cell in the cache | 3799 // 0: finger - index of the first free cell in the cache |
3780 // 1 + 2 * i: prototype | 3800 // 1 + 2 * i: prototype |
3781 // 2 + 2 * i: target map | 3801 // 2 + 2 * i: target map |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3887 | 3907 |
3888 MaybeObject* PutPrototypeTransition(Object* prototype, Map* map); | 3908 MaybeObject* PutPrototypeTransition(Object* prototype, Map* map); |
3889 | 3909 |
3890 static const int kMaxPreAllocatedPropertyFields = 255; | 3910 static const int kMaxPreAllocatedPropertyFields = 255; |
3891 | 3911 |
3892 // Layout description. | 3912 // Layout description. |
3893 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 3913 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
3894 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 3914 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
3895 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; | 3915 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; |
3896 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; | 3916 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; |
3897 static const int kInstanceDescriptorsOffset = | 3917 // Storage for instance descriptors is overloaded to also contain additional |
3918 // map flags when unused (bit_field3). When the map has instance descriptors, | |
3919 // the flags are transferred to the instance descriptor array and accessed | |
3920 // through an extra indirection. | |
3921 // TODO(1399): It should be possible to make room for bit_field3 in the map | |
3922 // without overloading the instance descriptors field, but the map is | |
3923 // currently perfectly aligned to 32 bytes and extending it at all would | |
3924 // double its size. After the increment GC work lands, this size restriction | |
3925 // could be loosened and bit_field3 moved directly back in the map. | |
3926 static const int kInstanceDescriptorsOrBitField3Offset = | |
3898 kConstructorOffset + kPointerSize; | 3927 kConstructorOffset + kPointerSize; |
3899 static const int kCodeCacheOffset = kInstanceDescriptorsOffset + kPointerSize; | 3928 static const int kCodeCacheOffset = |
3929 kInstanceDescriptorsOrBitField3Offset + kPointerSize; | |
3900 static const int kPrototypeTransitionsOffset = | 3930 static const int kPrototypeTransitionsOffset = |
3901 kCodeCacheOffset + kPointerSize; | 3931 kCodeCacheOffset + kPointerSize; |
3902 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; | 3932 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; |
3903 static const int kSize = MAP_POINTER_ALIGN(kPadStart); | 3933 static const int kSize = MAP_POINTER_ALIGN(kPadStart); |
3904 | 3934 |
3905 // Layout of pointer fields. Heap iteration code relies on them | 3935 // Layout of pointer fields. Heap iteration code relies on them |
3906 // being continiously allocated. | 3936 // being continiously allocated. |
3907 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; | 3937 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; |
3908 static const int kPointerFieldsEndOffset = | 3938 static const int kPointerFieldsEndOffset = |
3909 Map::kPrototypeTransitionsOffset + kPointerSize; | 3939 Map::kPrototypeTransitionsOffset + kPointerSize; |
(...skipping 2866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6776 } else { | 6806 } else { |
6777 value &= ~(1 << bit_position); | 6807 value &= ~(1 << bit_position); |
6778 } | 6808 } |
6779 return value; | 6809 return value; |
6780 } | 6810 } |
6781 }; | 6811 }; |
6782 | 6812 |
6783 } } // namespace v8::internal | 6813 } } // namespace v8::internal |
6784 | 6814 |
6785 #endif // V8_OBJECTS_H_ | 6815 #endif // V8_OBJECTS_H_ |
OLD | NEW |