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 5874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5885 || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS; | 5885 || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS; |
5886 } | 5886 } |
5887 | 5887 |
5888 static bool IsValidElementsTransition(ElementsKind from_kind, | 5888 static bool IsValidElementsTransition(ElementsKind from_kind, |
5889 ElementsKind to_kind); | 5889 ElementsKind to_kind); |
5890 | 5890 |
5891 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a | 5891 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a |
5892 // map with DICTIONARY_ELEMENTS was found in the prototype chain. | 5892 // map with DICTIONARY_ELEMENTS was found in the prototype chain. |
5893 bool DictionaryElementsInPrototypeChainOnly(); | 5893 bool DictionaryElementsInPrototypeChainOnly(); |
5894 | 5894 |
5895 inline bool HasTransitionArray() const; | 5895 inline Map* ElementsTransitionMap(); |
5896 inline bool HasElementsTransition(); | |
5897 inline Map* elements_transition_map(); | |
5898 | 5896 |
5899 inline Map* GetTransition(int transition_index); | |
5900 inline int SearchSpecialTransition(Symbol* name); | |
5901 inline int SearchTransition(PropertyKind kind, Name* name, | |
5902 PropertyAttributes attributes); | |
5903 inline FixedArrayBase* GetInitialElements(); | 5897 inline FixedArrayBase* GetInitialElements(); |
5904 | 5898 |
5905 DECL_ACCESSORS(transitions, TransitionArray) | 5899 // [raw_transitions]: Provides access to the transitions storage field. |
5906 inline void init_transitions(Object* undefined); | 5900 // Don't call set_raw_transitions() directly to overwrite transitions, use |
5907 | 5901 // the TransitionArray::ReplaceTransitions() wrapper instead! |
5908 static inline Handle<String> ExpectedTransitionKey(Handle<Map> map); | 5902 DECL_ACCESSORS(raw_transitions, Object) |
5909 static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map); | |
5910 | |
5911 // Try to follow an existing transition to a field with attributes NONE. The | |
5912 // return value indicates whether the transition was successful. | |
5913 static inline Handle<Map> FindTransitionToField(Handle<Map> map, | |
5914 Handle<Name> key); | |
5915 | 5903 |
5916 Map* FindRootMap(); | 5904 Map* FindRootMap(); |
5917 Map* FindFieldOwner(int descriptor); | 5905 Map* FindFieldOwner(int descriptor); |
5918 | 5906 |
5919 inline int GetInObjectPropertyOffset(int index); | 5907 inline int GetInObjectPropertyOffset(int index); |
5920 | 5908 |
5921 int NumberOfFields(); | 5909 int NumberOfFields(); |
5922 | 5910 |
5923 // TODO(ishell): candidate with JSObject::MigrateToMap(). | 5911 // TODO(ishell): candidate with JSObject::MigrateToMap(). |
5924 bool InstancesNeedRewriting(Map* target, int target_number_of_fields, | 5912 bool InstancesNeedRewriting(Map* target, int target_number_of_fields, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5978 bool CanUseOptimizationsBasedOnPrototypeRegistry(); | 5966 bool CanUseOptimizationsBasedOnPrototypeRegistry(); |
5979 | 5967 |
5980 // [constructor]: points back to the function responsible for this map. | 5968 // [constructor]: points back to the function responsible for this map. |
5981 // The field overlaps with the back pointer. All maps in a transition tree | 5969 // The field overlaps with the back pointer. All maps in a transition tree |
5982 // have the same constructor, so maps with back pointers can walk the | 5970 // have the same constructor, so maps with back pointers can walk the |
5983 // back pointer chain until they find the map holding their constructor. | 5971 // back pointer chain until they find the map holding their constructor. |
5984 DECL_ACCESSORS(constructor_or_backpointer, Object) | 5972 DECL_ACCESSORS(constructor_or_backpointer, Object) |
5985 inline Object* GetConstructor() const; | 5973 inline Object* GetConstructor() const; |
5986 inline void SetConstructor(Object* constructor, | 5974 inline void SetConstructor(Object* constructor, |
5987 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 5975 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 5976 // [back pointer]: points back to the parent map from which a transition |
| 5977 // leads to this map. The field overlaps with the constructor (see above). |
5988 inline Object* GetBackPointer(); | 5978 inline Object* GetBackPointer(); |
5989 inline void SetBackPointer(Object* value, | 5979 inline void SetBackPointer(Object* value, |
5990 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 5980 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
5991 | 5981 |
5992 // [instance descriptors]: describes the object. | 5982 // [instance descriptors]: describes the object. |
5993 DECL_ACCESSORS(instance_descriptors, DescriptorArray) | 5983 DECL_ACCESSORS(instance_descriptors, DescriptorArray) |
5994 | 5984 |
5995 // [layout descriptor]: describes the object layout. | 5985 // [layout descriptor]: describes the object layout. |
5996 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor) | 5986 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor) |
5997 // |layout descriptor| accessor which can be used from GC. | 5987 // |layout descriptor| accessor which can be used from GC. |
(...skipping 12 matching lines...) Expand all Loading... |
6010 | 6000 |
6011 // [stub cache]: contains stubs compiled for this map. | 6001 // [stub cache]: contains stubs compiled for this map. |
6012 DECL_ACCESSORS(code_cache, Object) | 6002 DECL_ACCESSORS(code_cache, Object) |
6013 | 6003 |
6014 // [dependent code]: list of optimized codes that weakly embed this map. | 6004 // [dependent code]: list of optimized codes that weakly embed this map. |
6015 DECL_ACCESSORS(dependent_code, DependentCode) | 6005 DECL_ACCESSORS(dependent_code, DependentCode) |
6016 | 6006 |
6017 // [weak cell cache]: cache that stores a weak cell pointing to this map. | 6007 // [weak cell cache]: cache that stores a weak cell pointing to this map. |
6018 DECL_ACCESSORS(weak_cell_cache, Object) | 6008 DECL_ACCESSORS(weak_cell_cache, Object) |
6019 | 6009 |
6020 // [prototype transitions]: cache of prototype transitions. | |
6021 // Prototype transition is a transition that happens | |
6022 // when we change object's prototype to a new one. | |
6023 // Cache format: | |
6024 // 0: finger - index of the first free cell in the cache | |
6025 // 1 + i: target map | |
6026 inline FixedArray* GetPrototypeTransitions(); | |
6027 inline bool HasPrototypeTransitions(); | |
6028 | |
6029 static const int kProtoTransitionNumberOfEntriesOffset = 0; | |
6030 static const int kProtoTransitionHeaderSize = 1; | |
6031 | |
6032 inline int NumberOfProtoTransitions() { | |
6033 FixedArray* cache = GetPrototypeTransitions(); | |
6034 if (cache->length() == 0) return 0; | |
6035 return | |
6036 Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value(); | |
6037 } | |
6038 | |
6039 inline void SetNumberOfProtoTransitions(int value) { | |
6040 FixedArray* cache = GetPrototypeTransitions(); | |
6041 DCHECK(cache->length() != 0); | |
6042 cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value)); | |
6043 } | |
6044 | |
6045 inline PropertyDetails GetLastDescriptorDetails(); | 6010 inline PropertyDetails GetLastDescriptorDetails(); |
6046 | 6011 |
6047 // The size of transition arrays are limited so they do not end up in large | |
6048 // object space. Otherwise ClearNonLiveTransitions would leak memory while | |
6049 // applying in-place right trimming. | |
6050 inline bool CanHaveMoreTransitions(); | |
6051 | |
6052 int LastAdded() { | 6012 int LastAdded() { |
6053 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 6013 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
6054 DCHECK(number_of_own_descriptors > 0); | 6014 DCHECK(number_of_own_descriptors > 0); |
6055 return number_of_own_descriptors - 1; | 6015 return number_of_own_descriptors - 1; |
6056 } | 6016 } |
6057 | 6017 |
6058 int NumberOfOwnDescriptors() { | 6018 int NumberOfOwnDescriptors() { |
6059 return NumberOfOwnDescriptorsBits::decode(bit_field3()); | 6019 return NumberOfOwnDescriptorsBits::decode(bit_field3()); |
6060 } | 6020 } |
6061 | 6021 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6209 // Returns the found code or undefined if absent. | 6169 // Returns the found code or undefined if absent. |
6210 Object* FindInCodeCache(Name* name, Code::Flags flags); | 6170 Object* FindInCodeCache(Name* name, Code::Flags flags); |
6211 | 6171 |
6212 // Returns the non-negative index of the code object if it is in the | 6172 // Returns the non-negative index of the code object if it is in the |
6213 // cache and -1 otherwise. | 6173 // cache and -1 otherwise. |
6214 int IndexInCodeCache(Object* name, Code* code); | 6174 int IndexInCodeCache(Object* name, Code* code); |
6215 | 6175 |
6216 // Removes a code object from the code cache at the given index. | 6176 // Removes a code object from the code cache at the given index. |
6217 void RemoveFromCodeCache(Name* name, Code* code, int index); | 6177 void RemoveFromCodeCache(Name* name, Code* code, int index); |
6218 | 6178 |
6219 // Set all map transitions from this map to dead maps to null. Also clear | |
6220 // back pointers in transition targets so that we do not process this map | |
6221 // again while following back pointers. | |
6222 void ClearNonLiveTransitions(Heap* heap); | |
6223 | |
6224 // Computes a hash value for this map, to be used in HashTables and such. | 6179 // Computes a hash value for this map, to be used in HashTables and such. |
6225 int Hash(); | 6180 int Hash(); |
6226 | 6181 |
6227 // Returns the map that this map transitions to if its elements_kind | 6182 // Returns the map that this map transitions to if its elements_kind |
6228 // is changed to |elements_kind|, or NULL if no such map is cached yet. | 6183 // is changed to |elements_kind|, or NULL if no such map is cached yet. |
6229 // |safe_to_add_transitions| is set to false if adding transitions is not | 6184 // |safe_to_add_transitions| is set to false if adding transitions is not |
6230 // allowed. | 6185 // allowed. |
6231 Map* LookupElementsTransitionMap(ElementsKind elements_kind); | 6186 Map* LookupElementsTransitionMap(ElementsKind elements_kind); |
6232 | 6187 |
6233 // Returns the transitioned map for this map with the most generic | 6188 // Returns the transitioned map for this map with the most generic |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6279 DECLARE_VERIFIER(Map) | 6234 DECLARE_VERIFIER(Map) |
6280 | 6235 |
6281 #ifdef VERIFY_HEAP | 6236 #ifdef VERIFY_HEAP |
6282 void DictionaryMapVerify(); | 6237 void DictionaryMapVerify(); |
6283 void VerifyOmittedMapChecks(); | 6238 void VerifyOmittedMapChecks(); |
6284 #endif | 6239 #endif |
6285 | 6240 |
6286 inline int visitor_id(); | 6241 inline int visitor_id(); |
6287 inline void set_visitor_id(int visitor_id); | 6242 inline void set_visitor_id(int visitor_id); |
6288 | 6243 |
6289 typedef void (*TraverseCallback)(Map* map, void* data); | |
6290 | |
6291 void TraverseTransitionTree(TraverseCallback callback, void* data); | |
6292 | |
6293 // When you set the prototype of an object using the __proto__ accessor you | |
6294 // need a new map for the object (the prototype is stored in the map). In | |
6295 // order not to multiply maps unnecessarily we store these as transitions in | |
6296 // the original map. That way we can transition to the same map if the same | |
6297 // prototype is set, rather than creating a new map every time. The | |
6298 // transitions are in the form of a map where the keys are prototype objects | |
6299 // and the values are the maps they transition to. | |
6300 static const int kMaxCachedPrototypeTransitions = 256; | |
6301 static Handle<Map> TransitionToPrototype(Handle<Map> map, | 6244 static Handle<Map> TransitionToPrototype(Handle<Map> map, |
6302 Handle<Object> prototype, | 6245 Handle<Object> prototype, |
6303 PrototypeOptimizationMode mode); | 6246 PrototypeOptimizationMode mode); |
6304 | 6247 |
6305 static const int kMaxPreAllocatedPropertyFields = 255; | 6248 static const int kMaxPreAllocatedPropertyFields = 255; |
6306 | 6249 |
6307 // Layout description. | 6250 // Layout description. |
6308 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 6251 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
6309 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 6252 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
6310 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize; | 6253 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize; |
6311 static const int kPrototypeOffset = kBitField3Offset + kPointerSize; | 6254 static const int kPrototypeOffset = kBitField3Offset + kPointerSize; |
6312 static const int kConstructorOrBackPointerOffset = | 6255 static const int kConstructorOrBackPointerOffset = |
6313 kPrototypeOffset + kPointerSize; | 6256 kPrototypeOffset + kPointerSize; |
| 6257 // When there is only one transition, it is stored directly in this field; |
| 6258 // otherwise a transition array is used. |
| 6259 // For prototype maps, this slot is used to store a pointer to the prototype |
| 6260 // object using this map. |
6314 static const int kTransitionsOffset = | 6261 static const int kTransitionsOffset = |
6315 kConstructorOrBackPointerOffset + kPointerSize; | 6262 kConstructorOrBackPointerOffset + kPointerSize; |
6316 static const int kDescriptorsOffset = kTransitionsOffset + kPointerSize; | 6263 static const int kDescriptorsOffset = kTransitionsOffset + kPointerSize; |
6317 #if V8_DOUBLE_FIELDS_UNBOXING | 6264 #if V8_DOUBLE_FIELDS_UNBOXING |
6318 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize; | 6265 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize; |
6319 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize; | 6266 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize; |
6320 #else | 6267 #else |
6321 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed. | 6268 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed. |
6322 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize; | 6269 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize; |
6323 #endif | 6270 #endif |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6446 PropertyNormalizationMode mode); | 6393 PropertyNormalizationMode mode); |
6447 | 6394 |
6448 // Fires when the layout of an object with a leaf map changes. | 6395 // Fires when the layout of an object with a leaf map changes. |
6449 // This includes adding transitions to the leaf map or changing | 6396 // This includes adding transitions to the leaf map or changing |
6450 // the descriptor array. | 6397 // the descriptor array. |
6451 inline void NotifyLeafMapLayoutChange(); | 6398 inline void NotifyLeafMapLayoutChange(); |
6452 | 6399 |
6453 static Handle<Map> TransitionElementsToSlow(Handle<Map> object, | 6400 static Handle<Map> TransitionElementsToSlow(Handle<Map> object, |
6454 ElementsKind to_kind); | 6401 ElementsKind to_kind); |
6455 | 6402 |
6456 // Zaps the contents of backing data structures. Note that the | |
6457 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects | |
6458 // holding weak references when incremental marking is used, because it also | |
6459 // iterates over objects that are otherwise unreachable. | |
6460 // In general we only want to call these functions in release mode when | |
6461 // heap verification is turned on. | |
6462 void ZapPrototypeTransitions(); | |
6463 void ZapTransitions(); | |
6464 | |
6465 void DeprecateTransitionTree(); | 6403 void DeprecateTransitionTree(); |
6466 bool DeprecateTarget(PropertyKind kind, Name* key, | 6404 bool DeprecateTarget(PropertyKind kind, Name* key, |
6467 PropertyAttributes attributes, | 6405 PropertyAttributes attributes, |
6468 DescriptorArray* new_descriptors, | 6406 DescriptorArray* new_descriptors, |
6469 LayoutDescriptor* new_layout_descriptor); | 6407 LayoutDescriptor* new_layout_descriptor); |
6470 | 6408 |
6471 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); | 6409 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); |
6472 | 6410 |
6473 // Update field type of the given descriptor to new representation and new | 6411 // Update field type of the given descriptor to new representation and new |
6474 // type. The type must be prepared for storing in descriptor array: | 6412 // type. The type must be prepared for storing in descriptor array: |
6475 // it must be either a simple type or a map wrapped in a weak cell. | 6413 // it must be either a simple type or a map wrapped in a weak cell. |
6476 void UpdateFieldType(int descriptor_number, Handle<Name> name, | 6414 void UpdateFieldType(int descriptor_number, Handle<Name> name, |
6477 Representation new_representation, | 6415 Representation new_representation, |
6478 Handle<Object> new_wrapped_type); | 6416 Handle<Object> new_wrapped_type); |
6479 | 6417 |
6480 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, | 6418 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, |
6481 PropertyAttributes attributes); | 6419 PropertyAttributes attributes); |
6482 void PrintGeneralization(FILE* file, | 6420 void PrintGeneralization(FILE* file, |
6483 const char* reason, | 6421 const char* reason, |
6484 int modify_index, | 6422 int modify_index, |
6485 int split, | 6423 int split, |
6486 int descriptors, | 6424 int descriptors, |
6487 bool constant_to_field, | 6425 bool constant_to_field, |
6488 Representation old_representation, | 6426 Representation old_representation, |
6489 Representation new_representation, | 6427 Representation new_representation, |
6490 HeapType* old_field_type, | 6428 HeapType* old_field_type, |
6491 HeapType* new_field_type); | 6429 HeapType* new_field_type); |
6492 | 6430 |
6493 static inline void SetPrototypeTransitions( | |
6494 Handle<Map> map, | |
6495 Handle<FixedArray> prototype_transitions); | |
6496 | |
6497 static Handle<Map> GetPrototypeTransition(Handle<Map> map, | |
6498 Handle<Object> prototype); | |
6499 static Handle<Map> PutPrototypeTransition(Handle<Map> map, | |
6500 Handle<Object> prototype, | |
6501 Handle<Map> target_map); | |
6502 | |
6503 static const int kFastPropertiesSoftLimit = 12; | 6431 static const int kFastPropertiesSoftLimit = 12; |
6504 static const int kMaxFastProperties = 128; | 6432 static const int kMaxFastProperties = 128; |
6505 | 6433 |
6506 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); | 6434 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); |
6507 }; | 6435 }; |
6508 | 6436 |
6509 | 6437 |
6510 // An abstract superclass, a marker class really, for simple structure classes. | 6438 // An abstract superclass, a marker class really, for simple structure classes. |
6511 // It doesn't carry much functionality but allows struct classes to be | 6439 // It doesn't carry much functionality but allows struct classes to be |
6512 // identified in the type system. | 6440 // identified in the type system. |
(...skipping 4493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11006 } else { | 10934 } else { |
11007 value &= ~(1 << bit_position); | 10935 value &= ~(1 << bit_position); |
11008 } | 10936 } |
11009 return value; | 10937 return value; |
11010 } | 10938 } |
11011 }; | 10939 }; |
11012 | 10940 |
11013 } } // namespace v8::internal | 10941 } } // namespace v8::internal |
11014 | 10942 |
11015 #endif // V8_OBJECTS_H_ | 10943 #endif // V8_OBJECTS_H_ |
OLD | NEW |