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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/objects.h" | 7 #include "src/objects.h" |
8 #include "src/transitions-inl.h" | 8 #include "src/transitions-inl.h" |
9 #include "src/utils.h" | 9 #include "src/utils.h" |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, | 44 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, |
45 Handle<Name> name, | 45 Handle<Name> name, |
46 Handle<Map> target, | 46 Handle<Map> target, |
47 SimpleTransitionFlag flag) { | 47 SimpleTransitionFlag flag) { |
48 Handle<TransitionArray> result; | 48 Handle<TransitionArray> result; |
49 Isolate* isolate = name->GetIsolate(); | 49 Isolate* isolate = name->GetIsolate(); |
50 | 50 |
51 if (flag == SIMPLE_PROPERTY_TRANSITION) { | 51 if (flag == SIMPLE_TRANSITION) { |
52 result = AllocateSimple(isolate, target); | 52 result = AllocateSimple(isolate, target); |
53 } else { | 53 } else { |
54 result = Allocate(isolate, 1); | 54 result = Allocate(isolate, 1); |
55 result->NoIncrementalWriteBarrierSet(0, *name, *target); | 55 result->NoIncrementalWriteBarrierSet(0, *name, *target); |
56 } | 56 } |
57 result->set_back_pointer_storage(map->GetBackPointer()); | 57 result->set_back_pointer_storage(map->GetBackPointer()); |
58 return result; | 58 return result; |
59 } | 59 } |
60 | 60 |
61 | 61 |
(...skipping 25 matching lines...) Expand all Loading... |
87 Handle<Name> name, | 87 Handle<Name> name, |
88 Handle<Map> target, | 88 Handle<Map> target, |
89 SimpleTransitionFlag flag) { | 89 SimpleTransitionFlag flag) { |
90 if (!map->HasTransitionArray()) { | 90 if (!map->HasTransitionArray()) { |
91 return TransitionArray::NewWith(map, name, target, flag); | 91 return TransitionArray::NewWith(map, name, target, flag); |
92 } | 92 } |
93 | 93 |
94 int number_of_transitions = map->transitions()->number_of_transitions(); | 94 int number_of_transitions = map->transitions()->number_of_transitions(); |
95 int new_nof = number_of_transitions; | 95 int new_nof = number_of_transitions; |
96 | 96 |
97 bool is_special_transition = flag == SPECIAL_TRANSITION; | 97 int insertion_index = kNotFound; |
98 DCHECK_EQ(is_special_transition, IsSpecialTransition(*name)); | 98 int index = map->transitions()->Search(*name, &insertion_index); |
99 PropertyDetails details = is_special_transition | |
100 ? PropertyDetails(NONE, NORMAL, 0) | |
101 : GetTargetDetails(*name, *target); | |
102 | 99 |
103 int insertion_index = kNotFound; | |
104 int index = | |
105 is_special_transition | |
106 ? map->transitions()->SearchSpecial(Symbol::cast(*name), | |
107 &insertion_index) | |
108 : map->transitions()->Search(details.type(), *name, | |
109 details.attributes(), &insertion_index); | |
110 if (index == kNotFound) { | 100 if (index == kNotFound) { |
111 ++new_nof; | 101 ++new_nof; |
112 } else { | 102 } else { |
113 insertion_index = index; | 103 insertion_index = index; |
114 } | 104 } |
115 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); | 105 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); |
116 | 106 |
117 CHECK(new_nof <= kMaxNumberOfTransitions); | 107 CHECK(new_nof <= kMaxNumberOfTransitions); |
118 | 108 |
119 if (new_nof <= map->transitions()->number_of_transitions_storage()) { | 109 if (new_nof <= map->transitions()->number_of_transitions_storage()) { |
120 DisallowHeapAllocation no_gc; | 110 DisallowHeapAllocation no_gc; |
121 TransitionArray* array = map->transitions(); | 111 TransitionArray* array = map->transitions(); |
122 | 112 |
123 if (index != kNotFound) { | 113 if (index != kNotFound) { |
124 array->SetTarget(index, *target); | 114 array->SetTarget(index, *target); |
125 return handle(array); | 115 return handle(array); |
126 } | 116 } |
127 | 117 |
128 array->SetNumberOfTransitions(new_nof); | 118 array->SetNumberOfTransitions(new_nof); |
129 for (index = number_of_transitions; index > insertion_index; --index) { | 119 for (index = number_of_transitions; index > insertion_index; --index) { |
130 Name* key = array->GetKey(index - 1); | 120 Name* key = array->GetKey(index - 1); |
| 121 DCHECK(key->Hash() > name->Hash()); |
131 array->SetKey(index, key); | 122 array->SetKey(index, key); |
132 array->SetTarget(index, array->GetTarget(index - 1)); | 123 array->SetTarget(index, array->GetTarget(index - 1)); |
133 } | 124 } |
134 array->SetKey(index, *name); | 125 array->SetKey(index, *name); |
135 array->SetTarget(index, *target); | 126 array->SetTarget(index, *target); |
136 SLOW_DCHECK(array->IsSortedNoDuplicates()); | |
137 return handle(array); | 127 return handle(array); |
138 } | 128 } |
139 | 129 |
140 Handle<TransitionArray> result = Allocate( | 130 Handle<TransitionArray> result = Allocate( |
141 map->GetIsolate(), new_nof, | 131 map->GetIsolate(), new_nof, |
142 Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions)); | 132 Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions)); |
143 | 133 |
144 // The map's transition array may grown smaller during the allocation above as | 134 // The map's transition array may grown smaller during the allocation above as |
145 // it was weakly traversed, though it is guaranteed not to disappear. Trim the | 135 // it was weakly traversed, though it is guaranteed not to disappear. Trim the |
146 // result copy if needed, and recompute variables. | 136 // result copy if needed, and recompute variables. |
147 DCHECK(map->HasTransitionArray()); | 137 DCHECK(map->HasTransitionArray()); |
148 DisallowHeapAllocation no_gc; | 138 DisallowHeapAllocation no_gc; |
149 TransitionArray* array = map->transitions(); | 139 TransitionArray* array = map->transitions(); |
150 if (array->number_of_transitions() != number_of_transitions) { | 140 if (array->number_of_transitions() != number_of_transitions) { |
151 DCHECK(array->number_of_transitions() < number_of_transitions); | 141 DCHECK(array->number_of_transitions() < number_of_transitions); |
152 | 142 |
153 number_of_transitions = array->number_of_transitions(); | 143 number_of_transitions = array->number_of_transitions(); |
154 new_nof = number_of_transitions; | 144 new_nof = number_of_transitions; |
155 | 145 |
156 insertion_index = kNotFound; | 146 insertion_index = kNotFound; |
157 index = is_special_transition ? map->transitions()->SearchSpecial( | 147 index = array->Search(*name, &insertion_index); |
158 Symbol::cast(*name), &insertion_index) | |
159 : map->transitions()->Search( | |
160 details.type(), *name, | |
161 details.attributes(), &insertion_index); | |
162 if (index == kNotFound) { | 148 if (index == kNotFound) { |
163 ++new_nof; | 149 ++new_nof; |
164 } else { | 150 } else { |
165 insertion_index = index; | 151 insertion_index = index; |
166 } | 152 } |
167 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); | 153 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); |
168 | 154 |
169 result->Shrink(ToKeyIndex(new_nof)); | 155 result->Shrink(ToKeyIndex(new_nof)); |
170 result->SetNumberOfTransitions(new_nof); | 156 result->SetNumberOfTransitions(new_nof); |
171 } | 157 } |
172 | 158 |
173 if (array->HasPrototypeTransitions()) { | 159 if (array->HasPrototypeTransitions()) { |
174 result->SetPrototypeTransitions(array->GetPrototypeTransitions()); | 160 result->SetPrototypeTransitions(array->GetPrototypeTransitions()); |
175 } | 161 } |
176 | 162 |
177 DCHECK_NE(kNotFound, insertion_index); | 163 DCHECK_NE(kNotFound, insertion_index); |
178 for (int i = 0; i < insertion_index; ++i) { | 164 for (int i = 0; i < insertion_index; ++i) { |
179 result->NoIncrementalWriteBarrierCopyFrom(array, i, i); | 165 result->NoIncrementalWriteBarrierCopyFrom(array, i, i); |
180 } | 166 } |
181 result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); | 167 result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); |
182 for (int i = insertion_index; i < number_of_transitions; ++i) { | 168 for (int i = insertion_index; i < number_of_transitions; ++i) { |
183 result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1); | 169 result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1); |
184 } | 170 } |
185 | 171 |
186 result->set_back_pointer_storage(array->back_pointer_storage()); | 172 result->set_back_pointer_storage(array->back_pointer_storage()); |
187 SLOW_DCHECK(result->IsSortedNoDuplicates()); | |
188 return result; | 173 return result; |
189 } | 174 } |
190 | 175 |
191 | 176 |
192 int TransitionArray::SearchDetails(int transition, PropertyType type, | |
193 PropertyAttributes attributes, | |
194 int* out_insertion_index) { | |
195 int nof_transitions = number_of_transitions(); | |
196 DCHECK(transition < nof_transitions); | |
197 Name* key = GetKey(transition); | |
198 bool is_data = type == FIELD || type == CONSTANT; | |
199 for (; transition < nof_transitions && GetKey(transition) == key; | |
200 transition++) { | |
201 Map* target = GetTarget(transition); | |
202 PropertyDetails target_details = GetTargetDetails(key, target); | |
203 | |
204 bool target_is_data = | |
205 target_details.type() == FIELD || target_details.type() == CONSTANT; | |
206 | |
207 int cmp = CompareDetails(is_data, attributes, target_is_data, | |
208 target_details.attributes()); | |
209 if (cmp == 0) { | |
210 return transition; | |
211 } else if (cmp < 0) { | |
212 break; | |
213 } | |
214 } | |
215 if (out_insertion_index != NULL) *out_insertion_index = transition; | |
216 return kNotFound; | |
217 } | |
218 | |
219 | |
220 int TransitionArray::Search(PropertyType type, Name* name, | |
221 PropertyAttributes attributes, | |
222 int* out_insertion_index) { | |
223 int transition = SearchName(name, out_insertion_index); | |
224 if (transition == kNotFound) { | |
225 return kNotFound; | |
226 } | |
227 return SearchDetails(transition, type, attributes, out_insertion_index); | |
228 } | |
229 } } // namespace v8::internal | 177 } } // namespace v8::internal |
OLD | NEW |