| 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 5851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5862 || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS; | 5862 || elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS; |
| 5863 } | 5863 } |
| 5864 | 5864 |
| 5865 static bool IsValidElementsTransition(ElementsKind from_kind, | 5865 static bool IsValidElementsTransition(ElementsKind from_kind, |
| 5866 ElementsKind to_kind); | 5866 ElementsKind to_kind); |
| 5867 | 5867 |
| 5868 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a | 5868 // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a |
| 5869 // map with DICTIONARY_ELEMENTS was found in the prototype chain. | 5869 // map with DICTIONARY_ELEMENTS was found in the prototype chain. |
| 5870 bool DictionaryElementsInPrototypeChainOnly(); | 5870 bool DictionaryElementsInPrototypeChainOnly(); |
| 5871 | 5871 |
| 5872 inline bool HasTransitionArray() const; | 5872 inline Map* ElementsTransitionMap(); |
| 5873 inline bool HasElementsTransition(); | |
| 5874 inline Map* elements_transition_map(); | |
| 5875 | 5873 |
| 5876 inline Map* GetTransition(int transition_index); | |
| 5877 inline int SearchSpecialTransition(Symbol* name); | |
| 5878 inline int SearchTransition(PropertyKind kind, Name* name, | |
| 5879 PropertyAttributes attributes); | |
| 5880 inline FixedArrayBase* GetInitialElements(); | 5874 inline FixedArrayBase* GetInitialElements(); |
| 5881 | 5875 |
| 5882 DECL_ACCESSORS(transitions, TransitionArray) | 5876 DECL_ACCESSORS(raw_transitions, Object) |
| 5883 inline void init_transitions(Object* undefined); | |
| 5884 | |
| 5885 static inline Handle<String> ExpectedTransitionKey(Handle<Map> map); | |
| 5886 static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map); | |
| 5887 | |
| 5888 // Try to follow an existing transition to a field with attributes NONE. The | |
| 5889 // return value indicates whether the transition was successful. | |
| 5890 static inline Handle<Map> FindTransitionToField(Handle<Map> map, | |
| 5891 Handle<Name> key); | |
| 5892 | 5877 |
| 5893 Map* FindRootMap(); | 5878 Map* FindRootMap(); |
| 5894 Map* FindFieldOwner(int descriptor); | 5879 Map* FindFieldOwner(int descriptor); |
| 5895 | 5880 |
| 5896 inline int GetInObjectPropertyOffset(int index); | 5881 inline int GetInObjectPropertyOffset(int index); |
| 5897 | 5882 |
| 5898 int NumberOfFields(); | 5883 int NumberOfFields(); |
| 5899 | 5884 |
| 5900 // TODO(ishell): candidate with JSObject::MigrateToMap(). | 5885 // TODO(ishell): candidate with JSObject::MigrateToMap(). |
| 5901 bool InstancesNeedRewriting(Map* target, int target_number_of_fields, | 5886 bool InstancesNeedRewriting(Map* target, int target_number_of_fields, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5955 bool CanUseOptimizationsBasedOnPrototypeRegistry(); | 5940 bool CanUseOptimizationsBasedOnPrototypeRegistry(); |
| 5956 | 5941 |
| 5957 // [constructor]: points back to the function responsible for this map. | 5942 // [constructor]: points back to the function responsible for this map. |
| 5958 // The field overlaps with the back pointer. All maps in a transition tree | 5943 // The field overlaps with the back pointer. All maps in a transition tree |
| 5959 // have the same constructor, so maps with back pointers can walk the | 5944 // have the same constructor, so maps with back pointers can walk the |
| 5960 // back pointer chain until they find the map holding their constructor. | 5945 // back pointer chain until they find the map holding their constructor. |
| 5961 DECL_ACCESSORS(constructor_or_backpointer, Object) | 5946 DECL_ACCESSORS(constructor_or_backpointer, Object) |
| 5962 inline Object* GetConstructor() const; | 5947 inline Object* GetConstructor() const; |
| 5963 inline void SetConstructor(Object* constructor, | 5948 inline void SetConstructor(Object* constructor, |
| 5964 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 5949 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 5950 // [back pointer]: points back to the parent map from which a transition |
| 5951 // leads to this map. The field overlaps with the constructor (see above). |
| 5965 inline Object* GetBackPointer(); | 5952 inline Object* GetBackPointer(); |
| 5966 inline void SetBackPointer(Object* value, | 5953 inline void SetBackPointer(Object* value, |
| 5967 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 5954 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 5968 | 5955 |
| 5969 // [instance descriptors]: describes the object. | 5956 // [instance descriptors]: describes the object. |
| 5970 DECL_ACCESSORS(instance_descriptors, DescriptorArray) | 5957 DECL_ACCESSORS(instance_descriptors, DescriptorArray) |
| 5971 | 5958 |
| 5972 // [layout descriptor]: describes the object layout. | 5959 // [layout descriptor]: describes the object layout. |
| 5973 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor) | 5960 DECL_ACCESSORS(layout_descriptor, LayoutDescriptor) |
| 5974 // |layout descriptor| accessor which can be used from GC. | 5961 // |layout descriptor| accessor which can be used from GC. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5987 | 5974 |
| 5988 // [stub cache]: contains stubs compiled for this map. | 5975 // [stub cache]: contains stubs compiled for this map. |
| 5989 DECL_ACCESSORS(code_cache, Object) | 5976 DECL_ACCESSORS(code_cache, Object) |
| 5990 | 5977 |
| 5991 // [dependent code]: list of optimized codes that weakly embed this map. | 5978 // [dependent code]: list of optimized codes that weakly embed this map. |
| 5992 DECL_ACCESSORS(dependent_code, DependentCode) | 5979 DECL_ACCESSORS(dependent_code, DependentCode) |
| 5993 | 5980 |
| 5994 // [weak cell cache]: cache that stores a weak cell pointing to this map. | 5981 // [weak cell cache]: cache that stores a weak cell pointing to this map. |
| 5995 DECL_ACCESSORS(weak_cell_cache, Object) | 5982 DECL_ACCESSORS(weak_cell_cache, Object) |
| 5996 | 5983 |
| 5997 // [prototype transitions]: cache of prototype transitions. | |
| 5998 // Prototype transition is a transition that happens | |
| 5999 // when we change object's prototype to a new one. | |
| 6000 // Cache format: | |
| 6001 // 0: finger - index of the first free cell in the cache | |
| 6002 // 1 + i: target map | |
| 6003 inline FixedArray* GetPrototypeTransitions(); | |
| 6004 inline bool HasPrototypeTransitions(); | |
| 6005 | |
| 6006 static const int kProtoTransitionNumberOfEntriesOffset = 0; | |
| 6007 static const int kProtoTransitionHeaderSize = 1; | |
| 6008 | |
| 6009 inline int NumberOfProtoTransitions() { | |
| 6010 FixedArray* cache = GetPrototypeTransitions(); | |
| 6011 if (cache->length() == 0) return 0; | |
| 6012 return | |
| 6013 Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value(); | |
| 6014 } | |
| 6015 | |
| 6016 inline void SetNumberOfProtoTransitions(int value) { | |
| 6017 FixedArray* cache = GetPrototypeTransitions(); | |
| 6018 DCHECK(cache->length() != 0); | |
| 6019 cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value)); | |
| 6020 } | |
| 6021 | |
| 6022 inline PropertyDetails GetLastDescriptorDetails(); | 5984 inline PropertyDetails GetLastDescriptorDetails(); |
| 6023 | 5985 |
| 6024 // The size of transition arrays are limited so they do not end up in large | |
| 6025 // object space. Otherwise ClearNonLiveTransitions would leak memory while | |
| 6026 // applying in-place right trimming. | |
| 6027 inline bool CanHaveMoreTransitions(); | |
| 6028 | |
| 6029 int LastAdded() { | 5986 int LastAdded() { |
| 6030 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 5987 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 6031 DCHECK(number_of_own_descriptors > 0); | 5988 DCHECK(number_of_own_descriptors > 0); |
| 6032 return number_of_own_descriptors - 1; | 5989 return number_of_own_descriptors - 1; |
| 6033 } | 5990 } |
| 6034 | 5991 |
| 6035 int NumberOfOwnDescriptors() { | 5992 int NumberOfOwnDescriptors() { |
| 6036 return NumberOfOwnDescriptorsBits::decode(bit_field3()); | 5993 return NumberOfOwnDescriptorsBits::decode(bit_field3()); |
| 6037 } | 5994 } |
| 6038 | 5995 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6186 // Returns the found code or undefined if absent. | 6143 // Returns the found code or undefined if absent. |
| 6187 Object* FindInCodeCache(Name* name, Code::Flags flags); | 6144 Object* FindInCodeCache(Name* name, Code::Flags flags); |
| 6188 | 6145 |
| 6189 // Returns the non-negative index of the code object if it is in the | 6146 // Returns the non-negative index of the code object if it is in the |
| 6190 // cache and -1 otherwise. | 6147 // cache and -1 otherwise. |
| 6191 int IndexInCodeCache(Object* name, Code* code); | 6148 int IndexInCodeCache(Object* name, Code* code); |
| 6192 | 6149 |
| 6193 // Removes a code object from the code cache at the given index. | 6150 // Removes a code object from the code cache at the given index. |
| 6194 void RemoveFromCodeCache(Name* name, Code* code, int index); | 6151 void RemoveFromCodeCache(Name* name, Code* code, int index); |
| 6195 | 6152 |
| 6196 // Set all map transitions from this map to dead maps to null. Also clear | |
| 6197 // back pointers in transition targets so that we do not process this map | |
| 6198 // again while following back pointers. | |
| 6199 void ClearNonLiveTransitions(Heap* heap); | |
| 6200 | |
| 6201 // Computes a hash value for this map, to be used in HashTables and such. | 6153 // Computes a hash value for this map, to be used in HashTables and such. |
| 6202 int Hash(); | 6154 int Hash(); |
| 6203 | 6155 |
| 6204 // Returns the map that this map transitions to if its elements_kind | 6156 // Returns the map that this map transitions to if its elements_kind |
| 6205 // is changed to |elements_kind|, or NULL if no such map is cached yet. | 6157 // is changed to |elements_kind|, or NULL if no such map is cached yet. |
| 6206 // |safe_to_add_transitions| is set to false if adding transitions is not | 6158 // |safe_to_add_transitions| is set to false if adding transitions is not |
| 6207 // allowed. | 6159 // allowed. |
| 6208 Map* LookupElementsTransitionMap(ElementsKind elements_kind); | 6160 Map* LookupElementsTransitionMap(ElementsKind elements_kind); |
| 6209 | 6161 |
| 6210 // Returns the transitioned map for this map with the most generic | 6162 // Returns the transitioned map for this map with the most generic |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6256 DECLARE_VERIFIER(Map) | 6208 DECLARE_VERIFIER(Map) |
| 6257 | 6209 |
| 6258 #ifdef VERIFY_HEAP | 6210 #ifdef VERIFY_HEAP |
| 6259 void DictionaryMapVerify(); | 6211 void DictionaryMapVerify(); |
| 6260 void VerifyOmittedMapChecks(); | 6212 void VerifyOmittedMapChecks(); |
| 6261 #endif | 6213 #endif |
| 6262 | 6214 |
| 6263 inline int visitor_id(); | 6215 inline int visitor_id(); |
| 6264 inline void set_visitor_id(int visitor_id); | 6216 inline void set_visitor_id(int visitor_id); |
| 6265 | 6217 |
| 6266 typedef void (*TraverseCallback)(Map* map, void* data); | |
| 6267 | |
| 6268 void TraverseTransitionTree(TraverseCallback callback, void* data); | |
| 6269 | |
| 6270 // When you set the prototype of an object using the __proto__ accessor you | |
| 6271 // need a new map for the object (the prototype is stored in the map). In | |
| 6272 // order not to multiply maps unnecessarily we store these as transitions in | |
| 6273 // the original map. That way we can transition to the same map if the same | |
| 6274 // prototype is set, rather than creating a new map every time. The | |
| 6275 // transitions are in the form of a map where the keys are prototype objects | |
| 6276 // and the values are the maps they transition to. | |
| 6277 static const int kMaxCachedPrototypeTransitions = 256; | |
| 6278 static Handle<Map> TransitionToPrototype(Handle<Map> map, | 6218 static Handle<Map> TransitionToPrototype(Handle<Map> map, |
| 6279 Handle<Object> prototype, | 6219 Handle<Object> prototype, |
| 6280 PrototypeOptimizationMode mode); | 6220 PrototypeOptimizationMode mode); |
| 6281 | 6221 |
| 6282 static const int kMaxPreAllocatedPropertyFields = 255; | 6222 static const int kMaxPreAllocatedPropertyFields = 255; |
| 6283 | 6223 |
| 6284 // Layout description. | 6224 // Layout description. |
| 6285 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 6225 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
| 6286 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 6226 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
| 6287 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize; | 6227 static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize; |
| 6288 static const int kPrototypeOffset = kBitField3Offset + kPointerSize; | 6228 static const int kPrototypeOffset = kBitField3Offset + kPointerSize; |
| 6289 static const int kConstructorOrBackPointerOffset = | 6229 static const int kConstructorOrBackPointerOffset = |
| 6290 kPrototypeOffset + kPointerSize; | 6230 kPrototypeOffset + kPointerSize; |
| 6231 // When there is only one transition, it is stored directly in this field; |
| 6232 // otherwise a transition array is used. |
| 6233 // For prototype maps, this slot is used to store a pointer to the prototype |
| 6234 // object using this map. |
| 6291 static const int kTransitionsOffset = | 6235 static const int kTransitionsOffset = |
| 6292 kConstructorOrBackPointerOffset + kPointerSize; | 6236 kConstructorOrBackPointerOffset + kPointerSize; |
| 6293 static const int kDescriptorsOffset = kTransitionsOffset + kPointerSize; | 6237 static const int kDescriptorsOffset = kTransitionsOffset + kPointerSize; |
| 6294 #if V8_DOUBLE_FIELDS_UNBOXING | 6238 #if V8_DOUBLE_FIELDS_UNBOXING |
| 6295 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize; | 6239 static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize; |
| 6296 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize; | 6240 static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize; |
| 6297 #else | 6241 #else |
| 6298 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed. | 6242 static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed. |
| 6299 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize; | 6243 static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize; |
| 6300 #endif | 6244 #endif |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6423 PropertyNormalizationMode mode); | 6367 PropertyNormalizationMode mode); |
| 6424 | 6368 |
| 6425 // Fires when the layout of an object with a leaf map changes. | 6369 // Fires when the layout of an object with a leaf map changes. |
| 6426 // This includes adding transitions to the leaf map or changing | 6370 // This includes adding transitions to the leaf map or changing |
| 6427 // the descriptor array. | 6371 // the descriptor array. |
| 6428 inline void NotifyLeafMapLayoutChange(); | 6372 inline void NotifyLeafMapLayoutChange(); |
| 6429 | 6373 |
| 6430 static Handle<Map> TransitionElementsToSlow(Handle<Map> object, | 6374 static Handle<Map> TransitionElementsToSlow(Handle<Map> object, |
| 6431 ElementsKind to_kind); | 6375 ElementsKind to_kind); |
| 6432 | 6376 |
| 6433 // Zaps the contents of backing data structures. Note that the | |
| 6434 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects | |
| 6435 // holding weak references when incremental marking is used, because it also | |
| 6436 // iterates over objects that are otherwise unreachable. | |
| 6437 // In general we only want to call these functions in release mode when | |
| 6438 // heap verification is turned on. | |
| 6439 void ZapPrototypeTransitions(); | |
| 6440 void ZapTransitions(); | |
| 6441 | |
| 6442 void DeprecateTransitionTree(); | 6377 void DeprecateTransitionTree(); |
| 6443 bool DeprecateTarget(PropertyKind kind, Name* key, | 6378 bool DeprecateTarget(PropertyKind kind, Name* key, |
| 6444 PropertyAttributes attributes, | 6379 PropertyAttributes attributes, |
| 6445 DescriptorArray* new_descriptors, | 6380 DescriptorArray* new_descriptors, |
| 6446 LayoutDescriptor* new_layout_descriptor); | 6381 LayoutDescriptor* new_layout_descriptor); |
| 6447 | 6382 |
| 6448 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); | 6383 Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors); |
| 6449 | 6384 |
| 6450 // Update field type of the given descriptor to new representation and new | 6385 // Update field type of the given descriptor to new representation and new |
| 6451 // type. The type must be prepared for storing in descriptor array: | 6386 // type. The type must be prepared for storing in descriptor array: |
| 6452 // it must be either a simple type or a map wrapped in a weak cell. | 6387 // it must be either a simple type or a map wrapped in a weak cell. |
| 6453 void UpdateFieldType(int descriptor_number, Handle<Name> name, | 6388 void UpdateFieldType(int descriptor_number, Handle<Name> name, |
| 6454 Representation new_representation, | 6389 Representation new_representation, |
| 6455 Handle<Object> new_wrapped_type); | 6390 Handle<Object> new_wrapped_type); |
| 6456 | 6391 |
| 6457 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, | 6392 void PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind, |
| 6458 PropertyAttributes attributes); | 6393 PropertyAttributes attributes); |
| 6459 void PrintGeneralization(FILE* file, | 6394 void PrintGeneralization(FILE* file, |
| 6460 const char* reason, | 6395 const char* reason, |
| 6461 int modify_index, | 6396 int modify_index, |
| 6462 int split, | 6397 int split, |
| 6463 int descriptors, | 6398 int descriptors, |
| 6464 bool constant_to_field, | 6399 bool constant_to_field, |
| 6465 Representation old_representation, | 6400 Representation old_representation, |
| 6466 Representation new_representation, | 6401 Representation new_representation, |
| 6467 HeapType* old_field_type, | 6402 HeapType* old_field_type, |
| 6468 HeapType* new_field_type); | 6403 HeapType* new_field_type); |
| 6469 | 6404 |
| 6470 static inline void SetPrototypeTransitions( | |
| 6471 Handle<Map> map, | |
| 6472 Handle<FixedArray> prototype_transitions); | |
| 6473 | |
| 6474 static Handle<Map> GetPrototypeTransition(Handle<Map> map, | |
| 6475 Handle<Object> prototype); | |
| 6476 static Handle<Map> PutPrototypeTransition(Handle<Map> map, | |
| 6477 Handle<Object> prototype, | |
| 6478 Handle<Map> target_map); | |
| 6479 | |
| 6480 static const int kFastPropertiesSoftLimit = 12; | 6405 static const int kFastPropertiesSoftLimit = 12; |
| 6481 static const int kMaxFastProperties = 128; | 6406 static const int kMaxFastProperties = 128; |
| 6482 | 6407 |
| 6483 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); | 6408 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); |
| 6484 }; | 6409 }; |
| 6485 | 6410 |
| 6486 | 6411 |
| 6487 // An abstract superclass, a marker class really, for simple structure classes. | 6412 // An abstract superclass, a marker class really, for simple structure classes. |
| 6488 // It doesn't carry much functionality but allows struct classes to be | 6413 // It doesn't carry much functionality but allows struct classes to be |
| 6489 // identified in the type system. | 6414 // identified in the type system. |
| (...skipping 4493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10983 } else { | 10908 } else { |
| 10984 value &= ~(1 << bit_position); | 10909 value &= ~(1 << bit_position); |
| 10985 } | 10910 } |
| 10986 return value; | 10911 return value; |
| 10987 } | 10912 } |
| 10988 }; | 10913 }; |
| 10989 | 10914 |
| 10990 } } // namespace v8::internal | 10915 } } // namespace v8::internal |
| 10991 | 10916 |
| 10992 #endif // V8_OBJECTS_H_ | 10917 #endif // V8_OBJECTS_H_ |
| OLD | NEW |