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