Index: src/objects.h |
diff --git a/src/objects.h b/src/objects.h |
index 9a553fd3770e3ac1be4aec6192f1835dee306670..8ddcd8b04fc7a8d0cf4171f598cf2ba50ecfc65f 100644 |
--- a/src/objects.h |
+++ b/src/objects.h |
@@ -5869,11 +5869,26 @@ |
// map with DICTIONARY_ELEMENTS was found in the prototype chain. |
bool DictionaryElementsInPrototypeChainOnly(); |
- inline Map* ElementsTransitionMap(); |
- |
+ inline bool HasTransitionArray() const; |
+ inline bool HasElementsTransition(); |
+ inline Map* elements_transition_map(); |
+ |
+ inline Map* GetTransition(int transition_index); |
+ inline int SearchSpecialTransition(Symbol* name); |
+ inline int SearchTransition(PropertyKind kind, Name* name, |
+ PropertyAttributes attributes); |
inline FixedArrayBase* GetInitialElements(); |
- DECL_ACCESSORS(raw_transitions, Object) |
+ DECL_ACCESSORS(transitions, TransitionArray) |
+ inline void init_transitions(Object* undefined); |
+ |
+ static inline Handle<String> ExpectedTransitionKey(Handle<Map> map); |
+ static inline Handle<Map> ExpectedTransitionTarget(Handle<Map> map); |
+ |
+ // Try to follow an existing transition to a field with attributes NONE. The |
+ // return value indicates whether the transition was successful. |
+ static inline Handle<Map> FindTransitionToField(Handle<Map> map, |
+ Handle<Name> key); |
Map* FindRootMap(); |
Map* FindFieldOwner(int descriptor); |
@@ -5947,8 +5962,6 @@ |
inline Object* GetConstructor() const; |
inline void SetConstructor(Object* constructor, |
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
- // [back pointer]: points back to the parent map from which a transition |
- // leads to this map. The field overlaps with the constructor (see above). |
inline Object* GetBackPointer(); |
inline void SetBackPointer(Object* value, |
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
@@ -5981,7 +5994,37 @@ |
// [weak cell cache]: cache that stores a weak cell pointing to this map. |
DECL_ACCESSORS(weak_cell_cache, Object) |
+ // [prototype transitions]: cache of prototype transitions. |
+ // Prototype transition is a transition that happens |
+ // when we change object's prototype to a new one. |
+ // Cache format: |
+ // 0: finger - index of the first free cell in the cache |
+ // 1 + i: target map |
+ inline FixedArray* GetPrototypeTransitions(); |
+ inline bool HasPrototypeTransitions(); |
+ |
+ static const int kProtoTransitionNumberOfEntriesOffset = 0; |
+ static const int kProtoTransitionHeaderSize = 1; |
+ |
+ inline int NumberOfProtoTransitions() { |
+ FixedArray* cache = GetPrototypeTransitions(); |
+ if (cache->length() == 0) return 0; |
+ return |
+ Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value(); |
+ } |
+ |
+ inline void SetNumberOfProtoTransitions(int value) { |
+ FixedArray* cache = GetPrototypeTransitions(); |
+ DCHECK(cache->length() != 0); |
+ cache->set(kProtoTransitionNumberOfEntriesOffset, Smi::FromInt(value)); |
+ } |
+ |
inline PropertyDetails GetLastDescriptorDetails(); |
+ |
+ // The size of transition arrays are limited so they do not end up in large |
+ // object space. Otherwise ClearNonLiveTransitions would leak memory while |
+ // applying in-place right trimming. |
+ inline bool CanHaveMoreTransitions(); |
int LastAdded() { |
int number_of_own_descriptors = NumberOfOwnDescriptors(); |
@@ -6150,6 +6193,11 @@ |
// Removes a code object from the code cache at the given index. |
void RemoveFromCodeCache(Name* name, Code* code, int index); |
+ // Set all map transitions from this map to dead maps to null. Also clear |
+ // back pointers in transition targets so that we do not process this map |
+ // again while following back pointers. |
+ void ClearNonLiveTransitions(Heap* heap); |
+ |
// Computes a hash value for this map, to be used in HashTables and such. |
int Hash(); |
@@ -6215,6 +6263,18 @@ |
inline int visitor_id(); |
inline void set_visitor_id(int visitor_id); |
+ typedef void (*TraverseCallback)(Map* map, void* data); |
+ |
+ void TraverseTransitionTree(TraverseCallback callback, void* data); |
+ |
+ // When you set the prototype of an object using the __proto__ accessor you |
+ // need a new map for the object (the prototype is stored in the map). In |
+ // order not to multiply maps unnecessarily we store these as transitions in |
+ // the original map. That way we can transition to the same map if the same |
+ // prototype is set, rather than creating a new map every time. The |
+ // transitions are in the form of a map where the keys are prototype objects |
+ // and the values are the maps they transition to. |
+ static const int kMaxCachedPrototypeTransitions = 256; |
static Handle<Map> TransitionToPrototype(Handle<Map> map, |
Handle<Object> prototype, |
PrototypeOptimizationMode mode); |
@@ -6228,10 +6288,6 @@ |
static const int kPrototypeOffset = kBitField3Offset + kPointerSize; |
static const int kConstructorOrBackPointerOffset = |
kPrototypeOffset + kPointerSize; |
- // When there is only one transition, it is stored directly in this field; |
- // otherwise a transition array is used. |
- // For prototype maps, this slot is used to store a pointer to the prototype |
- // object using this map. |
static const int kTransitionsOffset = |
kConstructorOrBackPointerOffset + kPointerSize; |
static const int kDescriptorsOffset = kTransitionsOffset + kPointerSize; |
@@ -6374,6 +6430,15 @@ |
static Handle<Map> TransitionElementsToSlow(Handle<Map> object, |
ElementsKind to_kind); |
+ // Zaps the contents of backing data structures. Note that the |
+ // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects |
+ // holding weak references when incremental marking is used, because it also |
+ // iterates over objects that are otherwise unreachable. |
+ // In general we only want to call these functions in release mode when |
+ // heap verification is turned on. |
+ void ZapPrototypeTransitions(); |
+ void ZapTransitions(); |
+ |
void DeprecateTransitionTree(); |
bool DeprecateTarget(PropertyKind kind, Name* key, |
PropertyAttributes attributes, |
@@ -6401,6 +6466,16 @@ |
Representation new_representation, |
HeapType* old_field_type, |
HeapType* new_field_type); |
+ |
+ static inline void SetPrototypeTransitions( |
+ Handle<Map> map, |
+ Handle<FixedArray> prototype_transitions); |
+ |
+ static Handle<Map> GetPrototypeTransition(Handle<Map> map, |
+ Handle<Object> prototype); |
+ static Handle<Map> PutPrototypeTransition(Handle<Map> map, |
+ Handle<Object> prototype, |
+ Handle<Map> target_map); |
static const int kFastPropertiesSoftLimit = 12; |
static const int kMaxFastProperties = 128; |