OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 <stdlib.h> | 5 #include <stdlib.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
11 #include "src/execution.h" | 11 #include "src/execution.h" |
12 #include "src/factory.h" | 12 #include "src/factory.h" |
13 #include "src/global-handles.h" | 13 #include "src/global-handles.h" |
14 #include "test/cctest/cctest.h" | 14 #include "test/cctest/cctest.h" |
15 | 15 |
16 using namespace v8::internal; | 16 using namespace v8::internal; |
17 | 17 |
18 | 18 |
19 // | 19 // |
20 // Helper functions. | 20 // Helper functions. |
21 // | 21 // |
22 | 22 |
| 23 static void ConnectTransition(Handle<Map> parent, |
| 24 Handle<TransitionArray> transitions, |
| 25 Handle<Map> child) { |
| 26 if (!parent->HasTransitionArray() || *transitions != parent->transitions()) { |
| 27 parent->set_transitions(*transitions); |
| 28 } |
| 29 child->SetBackPointer(*parent); |
| 30 } |
| 31 |
| 32 |
23 static void CheckPropertyDetailsFieldsConsistency(PropertyType type, | 33 static void CheckPropertyDetailsFieldsConsistency(PropertyType type, |
24 PropertyKind kind, | 34 PropertyKind kind, |
25 PropertyLocation location) { | 35 PropertyLocation location) { |
26 int type_value = PropertyDetails::TypeField::encode(type); | 36 int type_value = PropertyDetails::TypeField::encode(type); |
27 int kind_location_value = PropertyDetails::KindField::encode(kind) | | 37 int kind_location_value = PropertyDetails::KindField::encode(kind) | |
28 PropertyDetails::LocationField::encode(location); | 38 PropertyDetails::LocationField::encode(location); |
29 CHECK_EQ(type_value, kind_location_value); | 39 CHECK_EQ(type_value, kind_location_value); |
30 } | 40 } |
31 | 41 |
32 | 42 |
(...skipping 19 matching lines...) Expand all Loading... |
52 Handle<Map> map0 = Map::Create(isolate, 0); | 62 Handle<Map> map0 = Map::Create(isolate, 0); |
53 Handle<Map> map1 = | 63 Handle<Map> map1 = |
54 Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate), | 64 Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate), |
55 attributes, Representation::Tagged(), | 65 attributes, Representation::Tagged(), |
56 OMIT_TRANSITION).ToHandleChecked(); | 66 OMIT_TRANSITION).ToHandleChecked(); |
57 Handle<Map> map2 = | 67 Handle<Map> map2 = |
58 Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate), | 68 Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate), |
59 attributes, Representation::Tagged(), | 69 attributes, Representation::Tagged(), |
60 OMIT_TRANSITION).ToHandleChecked(); | 70 OMIT_TRANSITION).ToHandleChecked(); |
61 | 71 |
62 CHECK(map0->raw_transitions()->IsSmi()); | 72 CHECK(!map0->HasTransitionArray()); |
| 73 Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0); |
| 74 CHECK(transitions->IsFullTransitionArray()); |
63 | 75 |
64 TransitionArray::Insert(map0, name1, map1, SIMPLE_PROPERTY_TRANSITION); | 76 int transition; |
65 CHECK(TransitionArray::IsSimpleTransition(map0->raw_transitions())); | 77 transitions = |
66 CHECK_EQ(*map1, | 78 transitions->Insert(map0, name1, map1, SIMPLE_PROPERTY_TRANSITION); |
67 TransitionArray::SearchTransition(*map0, kData, *name1, attributes)); | 79 ConnectTransition(map0, transitions, map1); |
68 CHECK_EQ(1, TransitionArray::NumberOfTransitions(map0->raw_transitions())); | 80 CHECK(transitions->IsSimpleTransition()); |
69 CHECK_EQ(*name1, TransitionArray::GetKey(map0->raw_transitions(), 0)); | 81 transition = transitions->Search(kData, *name1, attributes); |
70 CHECK_EQ(*map1, TransitionArray::GetTarget(map0->raw_transitions(), 0)); | 82 CHECK_EQ(TransitionArray::kSimpleTransitionIndex, transition); |
| 83 CHECK_EQ(*name1, transitions->GetKey(transition)); |
| 84 CHECK_EQ(*map1, transitions->GetTarget(transition)); |
71 | 85 |
72 TransitionArray::Insert(map0, name2, map2, SIMPLE_PROPERTY_TRANSITION); | 86 transitions = |
73 CHECK(TransitionArray::IsFullTransitionArray(map0->raw_transitions())); | 87 transitions->Insert(map0, name2, map2, SIMPLE_PROPERTY_TRANSITION); |
| 88 ConnectTransition(map0, transitions, map2); |
| 89 CHECK(transitions->IsFullTransitionArray()); |
74 | 90 |
75 CHECK_EQ(*map1, | 91 transition = transitions->Search(kData, *name1, attributes); |
76 TransitionArray::SearchTransition(*map0, kData, *name1, attributes)); | 92 CHECK_EQ(*name1, transitions->GetKey(transition)); |
77 CHECK_EQ(*map2, | 93 CHECK_EQ(*map1, transitions->GetTarget(transition)); |
78 TransitionArray::SearchTransition(*map0, kData, *name2, attributes)); | |
79 CHECK_EQ(2, TransitionArray::NumberOfTransitions(map0->raw_transitions())); | |
80 for (int i = 0; i < 2; i++) { | |
81 Name* key = TransitionArray::GetKey(map0->raw_transitions(), i); | |
82 Map* target = TransitionArray::GetTarget(map0->raw_transitions(), i); | |
83 CHECK((key == *name1 && target == *map1) || | |
84 (key == *name2 && target == *map2)); | |
85 } | |
86 | 94 |
87 DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); | 95 transition = transitions->Search(kData, *name2, attributes); |
| 96 CHECK_EQ(*name2, transitions->GetKey(transition)); |
| 97 CHECK_EQ(*map2, transitions->GetTarget(transition)); |
| 98 |
| 99 DCHECK(transitions->IsSortedNoDuplicates()); |
88 } | 100 } |
89 | 101 |
90 | 102 |
91 TEST(TransitionArray_FullFieldTransitions) { | 103 TEST(TransitionArray_FullFieldTransitions) { |
92 CcTest::InitializeVM(); | 104 CcTest::InitializeVM(); |
93 v8::HandleScope scope(CcTest::isolate()); | 105 v8::HandleScope scope(CcTest::isolate()); |
94 Isolate* isolate = CcTest::i_isolate(); | 106 Isolate* isolate = CcTest::i_isolate(); |
95 Factory* factory = isolate->factory(); | 107 Factory* factory = isolate->factory(); |
96 | 108 |
97 Handle<String> name1 = factory->InternalizeUtf8String("foo"); | 109 Handle<String> name1 = factory->InternalizeUtf8String("foo"); |
98 Handle<String> name2 = factory->InternalizeUtf8String("bar"); | 110 Handle<String> name2 = factory->InternalizeUtf8String("bar"); |
99 PropertyAttributes attributes = NONE; | 111 PropertyAttributes attributes = NONE; |
100 | 112 |
101 Handle<Map> map0 = Map::Create(isolate, 0); | 113 Handle<Map> map0 = Map::Create(isolate, 0); |
102 Handle<Map> map1 = | 114 Handle<Map> map1 = |
103 Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate), | 115 Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate), |
104 attributes, Representation::Tagged(), | 116 attributes, Representation::Tagged(), |
105 OMIT_TRANSITION).ToHandleChecked(); | 117 OMIT_TRANSITION).ToHandleChecked(); |
106 Handle<Map> map2 = | 118 Handle<Map> map2 = |
107 Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate), | 119 Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate), |
108 attributes, Representation::Tagged(), | 120 attributes, Representation::Tagged(), |
109 OMIT_TRANSITION).ToHandleChecked(); | 121 OMIT_TRANSITION).ToHandleChecked(); |
110 | 122 |
111 CHECK(map0->raw_transitions()->IsSmi()); | 123 CHECK(!map0->HasTransitionArray()); |
| 124 Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0); |
| 125 CHECK(transitions->IsFullTransitionArray()); |
112 | 126 |
113 TransitionArray::Insert(map0, name1, map1, PROPERTY_TRANSITION); | 127 int transition; |
114 CHECK(TransitionArray::IsFullTransitionArray(map0->raw_transitions())); | 128 transitions = transitions->Insert(map0, name1, map1, PROPERTY_TRANSITION); |
115 CHECK_EQ(*map1, | 129 ConnectTransition(map0, transitions, map1); |
116 TransitionArray::SearchTransition(*map0, kData, *name1, attributes)); | 130 CHECK(transitions->IsFullTransitionArray()); |
117 CHECK_EQ(1, TransitionArray::NumberOfTransitions(map0->raw_transitions())); | 131 transition = transitions->Search(kData, *name1, attributes); |
118 CHECK_EQ(*name1, TransitionArray::GetKey(map0->raw_transitions(), 0)); | 132 CHECK_EQ(*name1, transitions->GetKey(transition)); |
119 CHECK_EQ(*map1, TransitionArray::GetTarget(map0->raw_transitions(), 0)); | 133 CHECK_EQ(*map1, transitions->GetTarget(transition)); |
120 | 134 |
121 TransitionArray::Insert(map0, name2, map2, PROPERTY_TRANSITION); | 135 transitions = transitions->Insert(map0, name2, map2, PROPERTY_TRANSITION); |
122 CHECK(TransitionArray::IsFullTransitionArray(map0->raw_transitions())); | 136 ConnectTransition(map0, transitions, map2); |
| 137 CHECK(transitions->IsFullTransitionArray()); |
123 | 138 |
124 CHECK_EQ(*map1, | 139 transition = transitions->Search(kData, *name1, attributes); |
125 TransitionArray::SearchTransition(*map0, kData, *name1, attributes)); | 140 CHECK_EQ(*name1, transitions->GetKey(transition)); |
126 CHECK_EQ(*map2, | 141 CHECK_EQ(*map1, transitions->GetTarget(transition)); |
127 TransitionArray::SearchTransition(*map0, kData, *name2, attributes)); | |
128 CHECK_EQ(2, TransitionArray::NumberOfTransitions(map0->raw_transitions())); | |
129 for (int i = 0; i < 2; i++) { | |
130 Name* key = TransitionArray::GetKey(map0->raw_transitions(), i); | |
131 Map* target = TransitionArray::GetTarget(map0->raw_transitions(), i); | |
132 CHECK((key == *name1 && target == *map1) || | |
133 (key == *name2 && target == *map2)); | |
134 } | |
135 | 142 |
136 DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); | 143 transition = transitions->Search(kData, *name2, attributes); |
| 144 CHECK_EQ(*name2, transitions->GetKey(transition)); |
| 145 CHECK_EQ(*map2, transitions->GetTarget(transition)); |
| 146 |
| 147 DCHECK(transitions->IsSortedNoDuplicates()); |
137 } | 148 } |
138 | 149 |
139 | 150 |
140 TEST(TransitionArray_DifferentFieldNames) { | 151 TEST(TransitionArray_DifferentFieldNames) { |
141 CcTest::InitializeVM(); | 152 CcTest::InitializeVM(); |
142 v8::HandleScope scope(CcTest::isolate()); | 153 v8::HandleScope scope(CcTest::isolate()); |
143 Isolate* isolate = CcTest::i_isolate(); | 154 Isolate* isolate = CcTest::i_isolate(); |
144 Factory* factory = isolate->factory(); | 155 Factory* factory = isolate->factory(); |
145 | 156 |
146 const int PROPS_COUNT = 10; | 157 const int PROPS_COUNT = 10; |
147 Handle<String> names[PROPS_COUNT]; | 158 Handle<String> names[PROPS_COUNT]; |
148 Handle<Map> maps[PROPS_COUNT]; | 159 Handle<Map> maps[PROPS_COUNT]; |
149 PropertyAttributes attributes = NONE; | 160 PropertyAttributes attributes = NONE; |
150 | 161 |
151 Handle<Map> map0 = Map::Create(isolate, 0); | 162 Handle<Map> map0 = Map::Create(isolate, 0); |
152 CHECK(map0->raw_transitions()->IsSmi()); | 163 CHECK(!map0->HasTransitionArray()); |
| 164 Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0); |
| 165 CHECK(transitions->IsFullTransitionArray()); |
153 | 166 |
154 for (int i = 0; i < PROPS_COUNT; i++) { | 167 for (int i = 0; i < PROPS_COUNT; i++) { |
155 EmbeddedVector<char, 64> buffer; | 168 EmbeddedVector<char, 64> buffer; |
156 SNPrintF(buffer, "prop%d", i); | 169 SNPrintF(buffer, "prop%d", i); |
157 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); | 170 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); |
158 Handle<Map> map = | 171 Handle<Map> map = |
159 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), | 172 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), |
160 attributes, Representation::Tagged(), | 173 attributes, Representation::Tagged(), |
161 OMIT_TRANSITION).ToHandleChecked(); | 174 OMIT_TRANSITION).ToHandleChecked(); |
162 names[i] = name; | 175 names[i] = name; |
163 maps[i] = map; | 176 maps[i] = map; |
164 | 177 |
165 TransitionArray::Insert(map0, name, map, PROPERTY_TRANSITION); | 178 transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); |
| 179 ConnectTransition(map0, transitions, map); |
166 } | 180 } |
167 | 181 |
168 for (int i = 0; i < PROPS_COUNT; i++) { | 182 for (int i = 0; i < PROPS_COUNT; i++) { |
169 CHECK_EQ(*maps[i], TransitionArray::SearchTransition( | 183 int transition = transitions->Search(kData, *names[i], attributes); |
170 *map0, kData, *names[i], attributes)); | 184 CHECK_EQ(*names[i], transitions->GetKey(transition)); |
171 } | 185 CHECK_EQ(*maps[i], transitions->GetTarget(transition)); |
172 for (int i = 0; i < PROPS_COUNT; i++) { | |
173 Name* key = TransitionArray::GetKey(map0->raw_transitions(), i); | |
174 Map* target = TransitionArray::GetTarget(map0->raw_transitions(), i); | |
175 for (int j = 0; j < PROPS_COUNT; j++) { | |
176 if (*names[i] == key) { | |
177 CHECK_EQ(*maps[i], target); | |
178 break; | |
179 } | |
180 } | |
181 } | 186 } |
182 | 187 |
183 DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); | 188 DCHECK(transitions->IsSortedNoDuplicates()); |
184 } | 189 } |
185 | 190 |
186 | 191 |
187 TEST(TransitionArray_SameFieldNamesDifferentAttributesSimple) { | 192 TEST(TransitionArray_SameFieldNamesDifferentAttributesSimple) { |
188 CcTest::InitializeVM(); | 193 CcTest::InitializeVM(); |
189 v8::HandleScope scope(CcTest::isolate()); | 194 v8::HandleScope scope(CcTest::isolate()); |
190 Isolate* isolate = CcTest::i_isolate(); | 195 Isolate* isolate = CcTest::i_isolate(); |
191 Factory* factory = isolate->factory(); | 196 Factory* factory = isolate->factory(); |
192 | 197 |
193 Handle<Map> map0 = Map::Create(isolate, 0); | 198 Handle<Map> map0 = Map::Create(isolate, 0); |
194 CHECK(map0->raw_transitions()->IsSmi()); | 199 CHECK(!map0->HasTransitionArray()); |
| 200 Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0); |
| 201 CHECK(transitions->IsFullTransitionArray()); |
195 | 202 |
196 const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1; | 203 const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1; |
197 STATIC_ASSERT(ATTRS_COUNT == 8); | 204 STATIC_ASSERT(ATTRS_COUNT == 8); |
198 Handle<Map> attr_maps[ATTRS_COUNT]; | 205 Handle<Map> attr_maps[ATTRS_COUNT]; |
199 Handle<String> name = factory->InternalizeUtf8String("foo"); | 206 Handle<String> name = factory->InternalizeUtf8String("foo"); |
200 | 207 |
201 // Add transitions for same field name but different attributes. | 208 // Add transitions for same field name but different attributes. |
202 for (int i = 0; i < ATTRS_COUNT; i++) { | 209 for (int i = 0; i < ATTRS_COUNT; i++) { |
203 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); | 210 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); |
204 | 211 |
205 Handle<Map> map = | 212 Handle<Map> map = |
206 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), | 213 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), |
207 attributes, Representation::Tagged(), | 214 attributes, Representation::Tagged(), |
208 OMIT_TRANSITION).ToHandleChecked(); | 215 OMIT_TRANSITION).ToHandleChecked(); |
209 attr_maps[i] = map; | 216 attr_maps[i] = map; |
210 | 217 |
211 TransitionArray::Insert(map0, name, map, PROPERTY_TRANSITION); | 218 transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); |
| 219 ConnectTransition(map0, transitions, map); |
212 } | 220 } |
213 | 221 |
214 // Ensure that transitions for |name| field are valid. | 222 // Ensure that transitions for |name| field are valid. |
215 for (int i = 0; i < ATTRS_COUNT; i++) { | 223 for (int i = 0; i < ATTRS_COUNT; i++) { |
216 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); | 224 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); |
217 CHECK_EQ(*attr_maps[i], TransitionArray::SearchTransition( | 225 |
218 *map0, kData, *name, attributes)); | 226 int transition = transitions->Search(kData, *name, attributes); |
219 // All transitions use the same key, so this check doesn't need to | 227 CHECK_EQ(*name, transitions->GetKey(transition)); |
220 // care about ordering. | 228 CHECK_EQ(*attr_maps[i], transitions->GetTarget(transition)); |
221 CHECK_EQ(*name, TransitionArray::GetKey(map0->raw_transitions(), i)); | |
222 } | 229 } |
223 | 230 |
224 DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); | 231 DCHECK(transitions->IsSortedNoDuplicates()); |
225 } | 232 } |
226 | 233 |
227 | 234 |
228 TEST(TransitionArray_SameFieldNamesDifferentAttributes) { | 235 TEST(TransitionArray_SameFieldNamesDifferentAttributes) { |
229 CcTest::InitializeVM(); | 236 CcTest::InitializeVM(); |
230 v8::HandleScope scope(CcTest::isolate()); | 237 v8::HandleScope scope(CcTest::isolate()); |
231 Isolate* isolate = CcTest::i_isolate(); | 238 Isolate* isolate = CcTest::i_isolate(); |
232 Factory* factory = isolate->factory(); | 239 Factory* factory = isolate->factory(); |
233 | 240 |
234 const int PROPS_COUNT = 10; | 241 const int PROPS_COUNT = 10; |
235 Handle<String> names[PROPS_COUNT]; | 242 Handle<String> names[PROPS_COUNT]; |
236 Handle<Map> maps[PROPS_COUNT]; | 243 Handle<Map> maps[PROPS_COUNT]; |
237 | 244 |
238 Handle<Map> map0 = Map::Create(isolate, 0); | 245 Handle<Map> map0 = Map::Create(isolate, 0); |
239 CHECK(map0->raw_transitions()->IsSmi()); | 246 CHECK(!map0->HasTransitionArray()); |
| 247 Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0); |
| 248 CHECK(transitions->IsFullTransitionArray()); |
240 | 249 |
241 // Some number of fields. | 250 // Some number of fields. |
242 for (int i = 0; i < PROPS_COUNT; i++) { | 251 for (int i = 0; i < PROPS_COUNT; i++) { |
243 EmbeddedVector<char, 64> buffer; | 252 EmbeddedVector<char, 64> buffer; |
244 SNPrintF(buffer, "prop%d", i); | 253 SNPrintF(buffer, "prop%d", i); |
245 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); | 254 Handle<String> name = factory->InternalizeUtf8String(buffer.start()); |
246 Handle<Map> map = | 255 Handle<Map> map = |
247 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), NONE, | 256 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), NONE, |
248 Representation::Tagged(), | 257 Representation::Tagged(), |
249 OMIT_TRANSITION).ToHandleChecked(); | 258 OMIT_TRANSITION).ToHandleChecked(); |
250 names[i] = name; | 259 names[i] = name; |
251 maps[i] = map; | 260 maps[i] = map; |
252 | 261 |
253 TransitionArray::Insert(map0, name, map, PROPERTY_TRANSITION); | 262 transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); |
| 263 ConnectTransition(map0, transitions, map); |
254 } | 264 } |
255 | 265 |
256 const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1; | 266 const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1; |
257 STATIC_ASSERT(ATTRS_COUNT == 8); | 267 STATIC_ASSERT(ATTRS_COUNT == 8); |
258 Handle<Map> attr_maps[ATTRS_COUNT]; | 268 Handle<Map> attr_maps[ATTRS_COUNT]; |
259 Handle<String> name = factory->InternalizeUtf8String("foo"); | 269 Handle<String> name = factory->InternalizeUtf8String("foo"); |
260 | 270 |
261 // Add transitions for same field name but different attributes. | 271 // Add transitions for same field name but different attributes. |
262 for (int i = 0; i < ATTRS_COUNT; i++) { | 272 for (int i = 0; i < ATTRS_COUNT; i++) { |
263 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); | 273 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); |
264 | 274 |
265 Handle<Map> map = | 275 Handle<Map> map = |
266 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), | 276 Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), |
267 attributes, Representation::Tagged(), | 277 attributes, Representation::Tagged(), |
268 OMIT_TRANSITION).ToHandleChecked(); | 278 OMIT_TRANSITION).ToHandleChecked(); |
269 attr_maps[i] = map; | 279 attr_maps[i] = map; |
270 | 280 |
271 TransitionArray::Insert(map0, name, map, PROPERTY_TRANSITION); | 281 transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION); |
| 282 ConnectTransition(map0, transitions, map); |
272 } | 283 } |
273 | 284 |
274 // Ensure that transitions for |name| field are valid. | 285 // Ensure that transitions for |name| field are valid. |
275 for (int i = 0; i < ATTRS_COUNT; i++) { | 286 for (int i = 0; i < ATTRS_COUNT; i++) { |
276 PropertyAttributes attr = static_cast<PropertyAttributes>(i); | 287 PropertyAttributes attributes = static_cast<PropertyAttributes>(i); |
277 CHECK_EQ(*attr_maps[i], | 288 |
278 TransitionArray::SearchTransition(*map0, kData, *name, attr)); | 289 int transition = transitions->Search(kData, *name, attributes); |
| 290 CHECK_EQ(*name, transitions->GetKey(transition)); |
| 291 CHECK_EQ(*attr_maps[i], transitions->GetTarget(transition)); |
279 } | 292 } |
280 | 293 |
281 // Ensure that info about the other fields still valid. | 294 // Ensure that info about the other fields still valid. |
282 CHECK_EQ(PROPS_COUNT + ATTRS_COUNT, | 295 for (int i = 0; i < PROPS_COUNT; i++) { |
283 TransitionArray::NumberOfTransitions(map0->raw_transitions())); | 296 int transition = transitions->Search(kData, *names[i], NONE); |
284 for (int i = 0; i < PROPS_COUNT + ATTRS_COUNT; i++) { | 297 CHECK_EQ(*names[i], transitions->GetKey(transition)); |
285 Name* key = TransitionArray::GetKey(map0->raw_transitions(), i); | 298 CHECK_EQ(*maps[i], transitions->GetTarget(transition)); |
286 Map* target = TransitionArray::GetTarget(map0->raw_transitions(), i); | |
287 if (key == *name) { | |
288 // Attributes transition. | |
289 PropertyAttributes attributes = | |
290 target->GetLastDescriptorDetails().attributes(); | |
291 CHECK_EQ(*attr_maps[static_cast<int>(attributes)], target); | |
292 } else { | |
293 for (int j = 0; j < PROPS_COUNT; j++) { | |
294 if (*names[j] == key) { | |
295 CHECK_EQ(*maps[j], target); | |
296 break; | |
297 } | |
298 } | |
299 } | |
300 } | 299 } |
301 | 300 |
302 DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); | 301 DCHECK(transitions->IsSortedNoDuplicates()); |
303 } | 302 } |
OLD | NEW |