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