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_TRANSITIONS_H_ | 5 #ifndef V8_TRANSITIONS_H_ |
6 #define V8_TRANSITIONS_H_ | 6 #define V8_TRANSITIONS_H_ |
7 | 7 |
8 #include "src/checks.h" | 8 #include "src/checks.h" |
9 #include "src/elements-kind.h" | 9 #include "src/elements-kind.h" |
10 #include "src/heap/heap.h" | 10 #include "src/heap/heap.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 // map. In the case of a simple transition, the key is also read from the | 23 // map. In the case of a simple transition, the key is also read from the |
24 // descriptor array of the target map. | 24 // descriptor array of the target map. |
25 // | 25 // |
26 // The simple format of the these objects is: | 26 // The simple format of the these objects is: |
27 // [0] Undefined or back pointer map | 27 // [0] Undefined or back pointer map |
28 // [1] Single transition | 28 // [1] Single transition |
29 // | 29 // |
30 // The full format is: | 30 // The full format is: |
31 // [0] Undefined or back pointer map | 31 // [0] Undefined or back pointer map |
32 // [1] Smi(0) or fixed array of prototype transitions | 32 // [1] Smi(0) or fixed array of prototype transitions |
33 // [2] First transition | 33 // [2] Number of transitions |
34 // [length() - kTransitionSize] Last transition | 34 // [3] First transition |
| 35 // [3 + number of transitions * kTransitionSize]: start of slack |
35 class TransitionArray: public FixedArray { | 36 class TransitionArray: public FixedArray { |
36 public: | 37 public: |
37 // Accessors for fetching instance transition at transition number. | 38 // Accessors for fetching instance transition at transition number. |
38 inline Name* GetKey(int transition_number); | 39 inline Name* GetKey(int transition_number); |
39 inline void SetKey(int transition_number, Name* value); | 40 inline void SetKey(int transition_number, Name* value); |
40 inline Object** GetKeySlot(int transition_number); | 41 inline Object** GetKeySlot(int transition_number); |
41 int GetSortedKeyIndex(int transition_number) { return transition_number; } | 42 int GetSortedKeyIndex(int transition_number) { return transition_number; } |
42 | 43 |
43 Name* GetSortedKey(int transition_number) { | 44 Name* GetSortedKey(int transition_number) { |
44 return GetKey(transition_number); | 45 return GetKey(transition_number); |
(...skipping 14 matching lines...) Expand all Loading... |
59 inline FixedArray* GetPrototypeTransitions(); | 60 inline FixedArray* GetPrototypeTransitions(); |
60 inline void SetPrototypeTransitions( | 61 inline void SetPrototypeTransitions( |
61 FixedArray* prototype_transitions, | 62 FixedArray* prototype_transitions, |
62 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 63 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
63 inline Object** GetPrototypeTransitionsSlot(); | 64 inline Object** GetPrototypeTransitionsSlot(); |
64 inline bool HasPrototypeTransitions(); | 65 inline bool HasPrototypeTransitions(); |
65 | 66 |
66 // Returns the number of transitions in the array. | 67 // Returns the number of transitions in the array. |
67 int number_of_transitions() { | 68 int number_of_transitions() { |
68 if (IsSimpleTransition()) return 1; | 69 if (IsSimpleTransition()) return 1; |
69 int len = length(); | 70 if (length() <= kFirstIndex) return 0; |
70 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kTransitionSize; | 71 return Smi::cast(get(kTransitionLengthIndex))->value(); |
71 } | 72 } |
72 | 73 |
| 74 int number_of_transitions_storage() { |
| 75 if (IsSimpleTransition()) return 1; |
| 76 if (length() <= kFirstIndex) return 0; |
| 77 return (length() - kFirstIndex) / kTransitionSize; |
| 78 } |
| 79 |
| 80 int NumberOfSlackTransitions() { |
| 81 return number_of_transitions_storage() - number_of_transitions(); |
| 82 } |
| 83 |
| 84 inline void SetNumberOfTransitions(int number_of_transitions); |
73 inline int number_of_entries() { return number_of_transitions(); } | 85 inline int number_of_entries() { return number_of_transitions(); } |
74 | 86 |
75 // Creates a FullTransitionArray from a SimpleTransitionArray in | 87 // Creates a FullTransitionArray from a SimpleTransitionArray in |
76 // containing_map. | 88 // containing_map. |
77 static Handle<TransitionArray> ExtendToFullTransitionArray( | 89 static Handle<TransitionArray> ExtendToFullTransitionArray( |
78 Handle<Map> containing_map); | 90 Handle<Map> containing_map); |
79 | 91 |
80 // Create a transition array, copying from the owning map if it already has | 92 // Return a transition array, using the array from the owning map if it |
81 // one, otherwise creating a new one according to flag. | 93 // already has one (copying into a larger array if necessary), otherwise |
| 94 // creating a new one according to flag. |
82 // TODO(verwaest): This should not cause an existing transition to be | 95 // TODO(verwaest): This should not cause an existing transition to be |
83 // overwritten. | 96 // overwritten. |
84 static Handle<TransitionArray> CopyInsert(Handle<Map> map, | 97 static Handle<TransitionArray> Insert(Handle<Map> map, Handle<Name> name, |
85 Handle<Name> name, | 98 Handle<Map> target, |
86 Handle<Map> target, | 99 SimpleTransitionFlag flag); |
87 SimpleTransitionFlag flag); | |
88 | 100 |
89 // Search a transition for a given property name. | 101 // Search a transition for a given property name. |
90 inline int Search(Name* name); | 102 inline int Search(Name* name); |
91 | 103 |
92 // Allocates a TransitionArray. | 104 // Allocates a TransitionArray. |
93 static Handle<TransitionArray> Allocate( | 105 static Handle<TransitionArray> Allocate(Isolate* isolate, |
94 Isolate* isolate, int number_of_transitions); | 106 int number_of_transitions, |
| 107 int slack = 0); |
95 | 108 |
96 bool IsSimpleTransition() { | 109 bool IsSimpleTransition() { |
97 return length() == kSimpleTransitionSize && | 110 return length() == kSimpleTransitionSize && |
98 get(kSimpleTransitionTarget)->IsHeapObject() && | 111 get(kSimpleTransitionTarget)->IsHeapObject() && |
99 // The IntrusivePrototypeTransitionIterator may have set the map of the | 112 // The IntrusivePrototypeTransitionIterator may have set the map of the |
100 // prototype transitions array to a smi. In that case, there are | 113 // prototype transitions array to a smi. In that case, there are |
101 // prototype transitions, hence this transition array is a full | 114 // prototype transitions, hence this transition array is a full |
102 // transition array. | 115 // transition array. |
103 HeapObject::cast(get(kSimpleTransitionTarget))->map()->IsMap() && | 116 HeapObject::cast(get(kSimpleTransitionTarget))->map()->IsMap() && |
104 get(kSimpleTransitionTarget)->IsMap(); | 117 get(kSimpleTransitionTarget)->IsMap(); |
105 } | 118 } |
106 | 119 |
107 bool IsFullTransitionArray() { | 120 bool IsFullTransitionArray() { |
108 return length() > kFirstIndex || | 121 return length() > kFirstIndex || |
109 (length() == kFirstIndex && !IsSimpleTransition()); | 122 (length() == kFirstIndex && !IsSimpleTransition()); |
110 } | 123 } |
111 | 124 |
112 // Casting. | 125 // Casting. |
113 static inline TransitionArray* cast(Object* obj); | 126 static inline TransitionArray* cast(Object* obj); |
114 | 127 |
115 // Constant for denoting key was not found. | 128 // Constant for denoting key was not found. |
116 static const int kNotFound = -1; | 129 static const int kNotFound = -1; |
117 | 130 |
118 static const int kBackPointerStorageIndex = 0; | 131 static const int kBackPointerStorageIndex = 0; |
119 | 132 |
120 // Layout for full transition arrays. | 133 // Layout for full transition arrays. |
121 static const int kPrototypeTransitionsIndex = 1; | 134 static const int kPrototypeTransitionsIndex = 1; |
122 static const int kFirstIndex = 2; | 135 static const int kTransitionLengthIndex = 2; |
| 136 static const int kFirstIndex = 3; |
123 | 137 |
124 // Layout for simple transition arrays. | 138 // Layout for simple transition arrays. |
125 static const int kSimpleTransitionTarget = 1; | 139 static const int kSimpleTransitionTarget = 1; |
126 static const int kSimpleTransitionSize = 2; | 140 static const int kSimpleTransitionSize = 2; |
127 static const int kSimpleTransitionIndex = 0; | 141 static const int kSimpleTransitionIndex = 0; |
128 STATIC_ASSERT(kSimpleTransitionIndex != kNotFound); | 142 STATIC_ASSERT(kSimpleTransitionIndex != kNotFound); |
129 | 143 |
130 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; | 144 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; |
131 | 145 |
132 // Layout for the full transition array header. | 146 // Layout for the full transition array header. |
133 static const int kPrototypeTransitionsOffset = kBackPointerStorageOffset + | 147 static const int kPrototypeTransitionsOffset = kBackPointerStorageOffset + |
134 kPointerSize; | 148 kPointerSize; |
| 149 static const int kTransitionLengthOffset = |
| 150 kPrototypeTransitionsOffset + kPointerSize; |
135 | 151 |
136 // Layout of map transition entries in full transition arrays. | 152 // Layout of map transition entries in full transition arrays. |
137 static const int kTransitionKey = 0; | 153 static const int kTransitionKey = 0; |
138 static const int kTransitionTarget = 1; | 154 static const int kTransitionTarget = 1; |
139 static const int kTransitionSize = 2; | 155 static const int kTransitionSize = 2; |
140 | 156 |
141 #ifdef OBJECT_PRINT | 157 #ifdef OBJECT_PRINT |
142 // Print all the transitions. | 158 // Print all the transitions. |
143 void PrintTransitions(std::ostream& os); // NOLINT | 159 void PrintTransitions(std::ostream& os); // NOLINT |
144 #endif | 160 #endif |
145 | 161 |
146 #ifdef DEBUG | 162 #ifdef DEBUG |
147 bool IsSortedNoDuplicates(int valid_entries = -1); | 163 bool IsSortedNoDuplicates(int valid_entries = -1); |
148 bool IsConsistentWithBackPointers(Map* current_map); | 164 bool IsConsistentWithBackPointers(Map* current_map); |
149 bool IsEqualTo(TransitionArray* other); | 165 bool IsEqualTo(TransitionArray* other); |
150 #endif | 166 #endif |
151 | 167 |
152 // The maximum number of transitions we want in a transition array (should | 168 // The maximum number of transitions we want in a transition array (should |
153 // fit in a page). | 169 // fit in a page). |
154 static const int kMaxNumberOfTransitions = 1024 + 512; | 170 static const int kMaxNumberOfTransitions = 1024 + 512; |
155 | 171 |
| 172 // Returns the fixed array length required to hold number_of_transitions |
| 173 // transitions. |
| 174 static int LengthFor(int number_of_transitions) { |
| 175 return ToKeyIndex(number_of_transitions); |
| 176 } |
| 177 |
156 private: | 178 private: |
157 // Conversion from transition number to array indices. | 179 // Conversion from transition number to array indices. |
158 static int ToKeyIndex(int transition_number) { | 180 static int ToKeyIndex(int transition_number) { |
159 return kFirstIndex + | 181 return kFirstIndex + |
160 (transition_number * kTransitionSize) + | 182 (transition_number * kTransitionSize) + |
161 kTransitionKey; | 183 kTransitionKey; |
162 } | 184 } |
163 | 185 |
164 static int ToTargetIndex(int transition_number) { | 186 static int ToTargetIndex(int transition_number) { |
165 return kFirstIndex + | 187 return kFirstIndex + |
(...skipping 19 matching lines...) Expand all Loading... |
185 int origin_transition, | 207 int origin_transition, |
186 int target_transition); | 208 int target_transition); |
187 | 209 |
188 DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray); | 210 DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray); |
189 }; | 211 }; |
190 | 212 |
191 | 213 |
192 } } // namespace v8::internal | 214 } } // namespace v8::internal |
193 | 215 |
194 #endif // V8_TRANSITIONS_H_ | 216 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |