OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "test/cctest/test-api.h" | 8 #include "test/cctest/test-api.h" |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 return pair; | 72 return pair; |
73 } | 73 } |
74 | 74 |
75 | 75 |
76 class Expectations { | 76 class Expectations { |
77 static const int MAX_PROPERTIES = 10; | 77 static const int MAX_PROPERTIES = 10; |
78 Isolate* isolate_; | 78 Isolate* isolate_; |
79 ElementsKind elements_kind_; | 79 ElementsKind elements_kind_; |
80 PropertyKind kinds_[MAX_PROPERTIES]; | 80 PropertyKind kinds_[MAX_PROPERTIES]; |
81 PropertyLocation locations_[MAX_PROPERTIES]; | 81 PropertyLocation locations_[MAX_PROPERTIES]; |
| 82 PropertyConstness constnesses_[MAX_PROPERTIES]; |
82 PropertyAttributes attributes_[MAX_PROPERTIES]; | 83 PropertyAttributes attributes_[MAX_PROPERTIES]; |
83 Representation representations_[MAX_PROPERTIES]; | 84 Representation representations_[MAX_PROPERTIES]; |
84 // FieldType for kField, value for DATA_CONSTANT and getter for | 85 // FieldType for kField, value for DATA_CONSTANT and getter for |
85 // ACCESSOR_CONSTANT. | 86 // ACCESSOR_CONSTANT. |
86 Handle<Object> values_[MAX_PROPERTIES]; | 87 Handle<Object> values_[MAX_PROPERTIES]; |
87 // Setter for ACCESSOR_CONSTANT. | 88 // Setter for ACCESSOR_CONSTANT. |
88 Handle<Object> setter_values_[MAX_PROPERTIES]; | 89 Handle<Object> setter_values_[MAX_PROPERTIES]; |
89 int number_of_properties_; | 90 int number_of_properties_; |
90 | 91 |
91 public: | 92 public: |
92 explicit Expectations(Isolate* isolate, ElementsKind elements_kind) | 93 explicit Expectations(Isolate* isolate, ElementsKind elements_kind) |
93 : isolate_(isolate), | 94 : isolate_(isolate), |
94 elements_kind_(elements_kind), | 95 elements_kind_(elements_kind), |
95 number_of_properties_(0) {} | 96 number_of_properties_(0) {} |
96 | 97 |
97 explicit Expectations(Isolate* isolate) | 98 explicit Expectations(Isolate* isolate) |
98 : Expectations( | 99 : Expectations( |
99 isolate, | 100 isolate, |
100 isolate->object_function()->initial_map()->elements_kind()) {} | 101 isolate->object_function()->initial_map()->elements_kind()) {} |
101 | 102 |
102 void Init(int index, PropertyKind kind, PropertyAttributes attributes, | 103 void Init(int index, PropertyKind kind, PropertyAttributes attributes, |
103 PropertyLocation location, Representation representation, | 104 PropertyConstness constness, PropertyLocation location, |
104 Handle<Object> value) { | 105 Representation representation, Handle<Object> value) { |
105 CHECK(index < MAX_PROPERTIES); | 106 CHECK(index < MAX_PROPERTIES); |
106 kinds_[index] = kind; | 107 kinds_[index] = kind; |
107 locations_[index] = location; | 108 locations_[index] = location; |
| 109 constnesses_[index] = constness; |
108 attributes_[index] = attributes; | 110 attributes_[index] = attributes; |
109 representations_[index] = representation; | 111 representations_[index] = representation; |
110 values_[index] = value; | 112 values_[index] = value; |
111 } | 113 } |
112 | 114 |
113 void Print() const { | 115 void Print() const { |
114 OFStream os(stdout); | 116 OFStream os(stdout); |
115 os << "Expectations: #" << number_of_properties_ << "\n"; | 117 os << "Expectations: #" << number_of_properties_ << "\n"; |
116 for (int i = 0; i < number_of_properties_; i++) { | 118 for (int i = 0; i < number_of_properties_; i++) { |
117 os << " " << i << ": "; | 119 os << " " << i << ": "; |
118 os << "Descriptor @ "; | 120 os << "Descriptor @ "; |
119 | 121 |
120 if (kinds_[i] == kData) { | 122 if (kinds_[i] == kData) { |
121 os << Brief(*values_[i]); | 123 os << Brief(*values_[i]); |
122 } else { | 124 } else { |
123 // kAccessor | 125 // kAccessor |
124 os << "(get: " << Brief(*values_[i]) | 126 os << "(get: " << Brief(*values_[i]) |
125 << ", set: " << Brief(*setter_values_[i]) << ") "; | 127 << ", set: " << Brief(*setter_values_[i]) << ") "; |
126 } | 128 } |
127 | 129 |
128 os << " ("; | 130 os << " ("; |
| 131 if (constnesses_[i] == kConst) os << "const "; |
129 os << (kinds_[i] == kData ? "data " : "accessor "); | 132 os << (kinds_[i] == kData ? "data " : "accessor "); |
130 if (locations_[i] == kField) { | 133 if (locations_[i] == kField) { |
131 os << "field" | 134 os << "field" |
132 << ": " << representations_[i].Mnemonic(); | 135 << ": " << representations_[i].Mnemonic(); |
133 } else { | 136 } else { |
134 os << "descriptor"; | 137 os << "descriptor"; |
135 } | 138 } |
136 os << ", attrs: " << attributes_[i] << ")\n"; | 139 os << ", attrs: " << attributes_[i] << ")\n"; |
137 } | 140 } |
138 os << "\n"; | 141 os << "\n"; |
139 } | 142 } |
140 | 143 |
141 void SetElementsKind(ElementsKind elements_kind) { | 144 void SetElementsKind(ElementsKind elements_kind) { |
142 elements_kind_ = elements_kind; | 145 elements_kind_ = elements_kind; |
143 } | 146 } |
144 | 147 |
145 Handle<FieldType> GetFieldType(int index) { | 148 Handle<FieldType> GetFieldType(int index) { |
146 CHECK(index < MAX_PROPERTIES); | 149 CHECK(index < MAX_PROPERTIES); |
147 CHECK_EQ(kField, locations_[index]); | 150 CHECK_EQ(kField, locations_[index]); |
148 return Handle<FieldType>::cast(values_[index]); | 151 return Handle<FieldType>::cast(values_[index]); |
149 } | 152 } |
150 | 153 |
151 void SetDataField(int index, PropertyAttributes attrs, | 154 void SetDataField(int index, PropertyAttributes attrs, |
| 155 PropertyConstness constness, Representation representation, |
| 156 Handle<FieldType> field_type) { |
| 157 Init(index, kData, attrs, constness, kField, representation, field_type); |
| 158 } |
| 159 |
| 160 void SetDataField(int index, PropertyConstness constness, |
152 Representation representation, | 161 Representation representation, |
153 Handle<FieldType> field_type) { | 162 Handle<FieldType> field_type) { |
154 Init(index, kData, attrs, kField, representation, field_type); | 163 SetDataField(index, attributes_[index], constness, representation, |
155 } | 164 field_type); |
156 | |
157 void SetDataField(int index, Representation representation, | |
158 Handle<FieldType> field_type) { | |
159 SetDataField(index, attributes_[index], representation, field_type); | |
160 } | 165 } |
161 | 166 |
162 void SetAccessorField(int index, PropertyAttributes attrs) { | 167 void SetAccessorField(int index, PropertyAttributes attrs) { |
163 Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(), | 168 Init(index, kAccessor, attrs, kConst, kDescriptor, Representation::Tagged(), |
164 FieldType::Any(isolate_)); | 169 FieldType::Any(isolate_)); |
165 } | 170 } |
166 | 171 |
167 void SetAccessorField(int index) { | 172 void SetAccessorField(int index) { |
168 SetAccessorField(index, attributes_[index]); | 173 SetAccessorField(index, attributes_[index]); |
169 } | 174 } |
170 | 175 |
171 void SetDataConstant(int index, PropertyAttributes attrs, | 176 void SetDataConstant(int index, PropertyAttributes attrs, |
172 Handle<JSFunction> value) { | 177 Handle<JSFunction> value) { |
173 Init(index, kData, attrs, kDescriptor, Representation::HeapObject(), value); | 178 Init(index, kData, attrs, kConst, kDescriptor, Representation::HeapObject(), |
| 179 value); |
174 } | 180 } |
175 | 181 |
176 void SetDataConstant(int index, Handle<JSFunction> value) { | 182 void SetDataConstant(int index, Handle<JSFunction> value) { |
177 SetDataConstant(index, attributes_[index], value); | 183 SetDataConstant(index, attributes_[index], value); |
178 } | 184 } |
179 | 185 |
180 void SetAccessorConstant(int index, PropertyAttributes attrs, | 186 void SetAccessorConstant(int index, PropertyAttributes attrs, |
181 Handle<Object> getter, Handle<Object> setter) { | 187 Handle<Object> getter, Handle<Object> setter) { |
182 Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(), | 188 Init(index, kAccessor, attrs, kConst, kDescriptor, Representation::Tagged(), |
183 getter); | 189 getter); |
184 setter_values_[index] = setter; | 190 setter_values_[index] = setter; |
185 } | 191 } |
186 | 192 |
187 void SetAccessorConstantComponent(int index, PropertyAttributes attrs, | 193 void SetAccessorConstantComponent(int index, PropertyAttributes attrs, |
188 AccessorComponent component, | 194 AccessorComponent component, |
189 Handle<Object> accessor) { | 195 Handle<Object> accessor) { |
190 CHECK_EQ(kAccessor, kinds_[index]); | 196 CHECK_EQ(kAccessor, kinds_[index]); |
191 CHECK_EQ(kDescriptor, locations_[index]); | 197 CHECK_EQ(kDescriptor, locations_[index]); |
192 CHECK(index < number_of_properties_); | 198 CHECK(index < number_of_properties_); |
(...skipping 23 matching lines...) Expand all Loading... |
216 } | 222 } |
217 | 223 |
218 void GeneralizeRepresentation(int index) { | 224 void GeneralizeRepresentation(int index) { |
219 CHECK(index < number_of_properties_); | 225 CHECK(index < number_of_properties_); |
220 representations_[index] = Representation::Tagged(); | 226 representations_[index] = Representation::Tagged(); |
221 if (locations_[index] == kField) { | 227 if (locations_[index] == kField) { |
222 values_[index] = FieldType::Any(isolate_); | 228 values_[index] = FieldType::Any(isolate_); |
223 } | 229 } |
224 } | 230 } |
225 | 231 |
226 | |
227 bool Check(DescriptorArray* descriptors, int descriptor) const { | 232 bool Check(DescriptorArray* descriptors, int descriptor) const { |
228 PropertyDetails details = descriptors->GetDetails(descriptor); | 233 PropertyDetails details = descriptors->GetDetails(descriptor); |
229 | 234 |
230 if (details.kind() != kinds_[descriptor]) return false; | 235 if (details.kind() != kinds_[descriptor]) return false; |
231 if (details.location() != locations_[descriptor]) return false; | 236 if (details.location() != locations_[descriptor]) return false; |
| 237 if (details.constness() != constnesses_[descriptor]) return false; |
232 | 238 |
233 PropertyAttributes expected_attributes = attributes_[descriptor]; | 239 PropertyAttributes expected_attributes = attributes_[descriptor]; |
234 if (details.attributes() != expected_attributes) return false; | 240 if (details.attributes() != expected_attributes) return false; |
235 | 241 |
236 Representation expected_representation = representations_[descriptor]; | 242 Representation expected_representation = representations_[descriptor]; |
237 if (!details.representation().Equals(expected_representation)) return false; | 243 if (!details.representation().Equals(expected_representation)) return false; |
238 | 244 |
239 Object* value = descriptors->GetValue(descriptor); | 245 Object* value = descriptors->GetValue(descriptor); |
240 Object* expected_value = *values_[descriptor]; | 246 Object* expected_value = *values_[descriptor]; |
241 if (details.location() == kField) { | 247 if (details.location() == kField) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 // | 299 // |
294 | 300 |
295 Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind elements_kind) { | 301 Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind elements_kind) { |
296 elements_kind_ = elements_kind; | 302 elements_kind_ = elements_kind; |
297 map = Map::AsElementsKind(map, elements_kind); | 303 map = Map::AsElementsKind(map, elements_kind); |
298 CHECK_EQ(elements_kind_, map->elements_kind()); | 304 CHECK_EQ(elements_kind_, map->elements_kind()); |
299 return map; | 305 return map; |
300 } | 306 } |
301 | 307 |
302 Handle<Map> AddDataField(Handle<Map> map, PropertyAttributes attributes, | 308 Handle<Map> AddDataField(Handle<Map> map, PropertyAttributes attributes, |
| 309 PropertyConstness constness, |
303 Representation representation, | 310 Representation representation, |
304 Handle<FieldType> heap_type) { | 311 Handle<FieldType> heap_type) { |
305 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); | 312 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); |
306 int property_index = number_of_properties_++; | 313 int property_index = number_of_properties_++; |
307 SetDataField(property_index, attributes, representation, heap_type); | 314 SetDataField(property_index, attributes, constness, representation, |
| 315 heap_type); |
308 | 316 |
309 Handle<String> name = MakeName("prop", property_index); | 317 Handle<String> name = MakeName("prop", property_index); |
310 return Map::CopyWithField(map, name, heap_type, attributes, representation, | 318 return Map::CopyWithField(map, name, heap_type, attributes, representation, |
311 INSERT_TRANSITION) | 319 INSERT_TRANSITION) |
312 .ToHandleChecked(); | 320 .ToHandleChecked(); |
313 } | 321 } |
314 | 322 |
315 Handle<Map> AddDataConstant(Handle<Map> map, PropertyAttributes attributes, | 323 Handle<Map> AddDataConstant(Handle<Map> map, PropertyAttributes attributes, |
316 Handle<JSFunction> value) { | 324 Handle<JSFunction> value) { |
317 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); | 325 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); |
318 int property_index = number_of_properties_++; | 326 int property_index = number_of_properties_++; |
319 SetDataConstant(property_index, attributes, value); | 327 SetDataConstant(property_index, attributes, value); |
320 | 328 |
321 Handle<String> name = MakeName("prop", property_index); | 329 Handle<String> name = MakeName("prop", property_index); |
322 return Map::CopyWithConstant(map, name, value, attributes, | 330 return Map::CopyWithConstant(map, name, value, attributes, |
323 INSERT_TRANSITION) | 331 INSERT_TRANSITION) |
324 .ToHandleChecked(); | 332 .ToHandleChecked(); |
325 } | 333 } |
326 | 334 |
327 Handle<Map> TransitionToDataField(Handle<Map> map, | 335 Handle<Map> TransitionToDataField(Handle<Map> map, |
328 PropertyAttributes attributes, | 336 PropertyAttributes attributes, |
| 337 PropertyConstness constness, |
329 Representation representation, | 338 Representation representation, |
330 Handle<FieldType> heap_type, | 339 Handle<FieldType> heap_type, |
331 Handle<Object> value) { | 340 Handle<Object> value) { |
332 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); | 341 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); |
333 int property_index = number_of_properties_++; | 342 int property_index = number_of_properties_++; |
334 SetDataField(property_index, attributes, representation, heap_type); | 343 SetDataField(property_index, attributes, constness, representation, |
| 344 heap_type); |
335 | 345 |
336 Handle<String> name = MakeName("prop", property_index); | 346 Handle<String> name = MakeName("prop", property_index); |
337 return Map::TransitionToDataProperty( | 347 return Map::TransitionToDataProperty( |
338 map, name, value, attributes, Object::CERTAINLY_NOT_STORE_FROM_KEYED); | 348 map, name, value, attributes, Object::CERTAINLY_NOT_STORE_FROM_KEYED); |
339 } | 349 } |
340 | 350 |
341 Handle<Map> TransitionToDataConstant(Handle<Map> map, | 351 Handle<Map> TransitionToDataConstant(Handle<Map> map, |
342 PropertyAttributes attributes, | 352 PropertyAttributes attributes, |
343 Handle<JSFunction> value) { | 353 Handle<JSFunction> value) { |
344 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); | 354 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); |
345 int property_index = number_of_properties_++; | 355 int property_index = number_of_properties_++; |
346 SetDataConstant(property_index, attributes, value); | 356 SetDataConstant(property_index, attributes, value); |
347 | 357 |
348 Handle<String> name = MakeName("prop", property_index); | 358 Handle<String> name = MakeName("prop", property_index); |
349 return Map::TransitionToDataProperty( | 359 return Map::TransitionToDataProperty( |
350 map, name, value, attributes, Object::CERTAINLY_NOT_STORE_FROM_KEYED); | 360 map, name, value, attributes, Object::CERTAINLY_NOT_STORE_FROM_KEYED); |
351 } | 361 } |
352 | 362 |
353 Handle<Map> FollowDataTransition(Handle<Map> map, | 363 Handle<Map> FollowDataTransition(Handle<Map> map, |
354 PropertyAttributes attributes, | 364 PropertyAttributes attributes, |
| 365 PropertyConstness constness, |
355 Representation representation, | 366 Representation representation, |
356 Handle<FieldType> heap_type) { | 367 Handle<FieldType> heap_type) { |
357 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); | 368 CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors()); |
358 int property_index = number_of_properties_++; | 369 int property_index = number_of_properties_++; |
359 SetDataField(property_index, attributes, representation, heap_type); | 370 SetDataField(property_index, attributes, constness, representation, |
| 371 heap_type); |
360 | 372 |
361 Handle<String> name = MakeName("prop", property_index); | 373 Handle<String> name = MakeName("prop", property_index); |
362 Map* target = | 374 Map* target = |
363 TransitionArray::SearchTransition(*map, kData, *name, attributes); | 375 TransitionArray::SearchTransition(*map, kData, *name, attributes); |
364 CHECK(target != NULL); | 376 CHECK(target != NULL); |
365 return handle(target); | 377 return handle(target); |
366 } | 378 } |
367 | 379 |
368 Handle<Map> AddAccessorConstant(Handle<Map> map, | 380 Handle<Map> AddAccessorConstant(Handle<Map> map, |
369 PropertyAttributes attributes, | 381 PropertyAttributes attributes, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 CHECK(map->is_stable()); | 466 CHECK(map->is_stable()); |
455 CHECK(expectations.Check(*map)); | 467 CHECK(expectations.Check(*map)); |
456 | 468 |
457 Handle<Map> new_map = Map::ReconfigureProperty( | 469 Handle<Map> new_map = Map::ReconfigureProperty( |
458 map, 0, kData, NONE, Representation::None(), none_type); | 470 map, 0, kData, NONE, Representation::None(), none_type); |
459 // |map| did not change except marked unstable. | 471 // |map| did not change except marked unstable. |
460 CHECK(!map->is_deprecated()); | 472 CHECK(!map->is_deprecated()); |
461 CHECK(!map->is_stable()); | 473 CHECK(!map->is_stable()); |
462 CHECK(expectations.Check(*map)); | 474 CHECK(expectations.Check(*map)); |
463 | 475 |
464 expectations.SetDataField(0, NONE, Representation::None(), none_type); | 476 // Property kind reconfiguration always makes the field mutable. |
| 477 expectations.SetDataField(0, NONE, kMutable, Representation::None(), |
| 478 none_type); |
465 | 479 |
466 CHECK(!new_map->is_deprecated()); | 480 CHECK(!new_map->is_deprecated()); |
467 CHECK(new_map->is_stable()); | 481 CHECK(new_map->is_stable()); |
468 CHECK(expectations.Check(*new_map)); | 482 CHECK(expectations.Check(*new_map)); |
469 | 483 |
470 Handle<Map> new_map2 = Map::ReconfigureProperty( | 484 Handle<Map> new_map2 = Map::ReconfigureProperty( |
471 map, 0, kData, NONE, Representation::None(), none_type); | 485 map, 0, kData, NONE, Representation::None(), none_type); |
472 CHECK_EQ(*new_map, *new_map2); | 486 CHECK_EQ(*new_map, *new_map2); |
473 | 487 |
474 Handle<Object> value(Smi::kZero, isolate); | 488 Handle<Object> value(Smi::kZero, isolate); |
475 Handle<Map> prepared_map = Map::PrepareForDataProperty(new_map, 0, value); | 489 Handle<Map> prepared_map = Map::PrepareForDataProperty(new_map, 0, value); |
476 // None to Smi generalization is trivial, map does not change. | 490 // None to Smi generalization is trivial, map does not change. |
477 CHECK_EQ(*new_map, *prepared_map); | 491 CHECK_EQ(*new_map, *prepared_map); |
478 | 492 |
479 expectations.SetDataField(0, NONE, Representation::Smi(), any_type); | 493 expectations.SetDataField(0, NONE, kMutable, Representation::Smi(), any_type); |
480 CHECK(prepared_map->is_stable()); | 494 CHECK(prepared_map->is_stable()); |
481 CHECK(expectations.Check(*prepared_map)); | 495 CHECK(expectations.Check(*prepared_map)); |
482 | 496 |
483 // Now create an object with |map|, migrate it to |prepared_map| and ensure | 497 // Now create an object with |map|, migrate it to |prepared_map| and ensure |
484 // that the data property is uninitialized. | 498 // that the data property is uninitialized. |
485 Factory* factory = isolate->factory(); | 499 Factory* factory = isolate->factory(); |
486 Handle<JSObject> obj = factory->NewJSObjectFromMap(map); | 500 Handle<JSObject> obj = factory->NewJSObjectFromMap(map); |
487 JSObject::MigrateToMap(obj, prepared_map); | 501 JSObject::MigrateToMap(obj, prepared_map); |
488 FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, 0); | 502 FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, 0); |
489 CHECK(obj->RawFastPropertyAt(index)->IsUninitialized(isolate)); | 503 CHECK(obj->RawFastPropertyAt(index)->IsUninitialized(isolate)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 Object* the_value = obj->RawFastPropertyAt(index); | 544 Object* the_value = obj->RawFastPropertyAt(index); |
531 CHECK(the_value->IsSmi()); | 545 CHECK(the_value->IsSmi()); |
532 CHECK_EQ(42, Smi::cast(the_value)->value()); | 546 CHECK_EQ(42, Smi::cast(the_value)->value()); |
533 } | 547 } |
534 | 548 |
535 | 549 |
536 //////////////////////////////////////////////////////////////////////////////// | 550 //////////////////////////////////////////////////////////////////////////////// |
537 // A set of tests for representation generalization case. | 551 // A set of tests for representation generalization case. |
538 // | 552 // |
539 | 553 |
| 554 // <Constness, Representation, FieldType> data. |
| 555 struct CRFTData { |
| 556 PropertyConstness constness; |
| 557 Representation representation; |
| 558 Handle<FieldType> type; |
| 559 }; |
| 560 |
540 // This test ensures that representation/field type generalization at | 561 // This test ensures that representation/field type generalization at |
541 // |property_index| is done correctly independently of the fact that the |map| | 562 // |property_index| is done correctly independently of the fact that the |map| |
542 // is detached from transition tree or not. | 563 // is detached from transition tree or not. |
543 // | 564 // |
544 // {} - p0 - p1 - p2: |detach_point_map| | 565 // {} - p0 - p1 - p2: |detach_point_map| |
545 // | | 566 // | |
546 // X - detached at |detach_property_at_index| | 567 // X - detached at |detach_property_at_index| |
547 // | | 568 // | |
548 // + - p3 - p4: |map| | 569 // + - p3 - p4: |map| |
549 // | 570 // |
550 // Detaching does not happen if |detach_property_at_index| is -1. | 571 // Detaching does not happen if |detach_property_at_index| is -1. |
551 // | 572 // |
552 static void TestGeneralizeRepresentation( | 573 static void TestGeneralizeRepresentation( |
553 int detach_property_at_index, int property_index, | 574 int detach_property_at_index, int property_index, const CRFTData& from, |
554 Representation from_representation, Handle<FieldType> from_type, | 575 const CRFTData& to, const CRFTData& expected, bool expected_deprecation, |
555 Representation to_representation, Handle<FieldType> to_type, | 576 bool expected_field_type_dependency) { |
556 Representation expected_representation, Handle<FieldType> expected_type, | |
557 bool expected_deprecation, bool expected_field_type_dependency) { | |
558 Isolate* isolate = CcTest::i_isolate(); | 577 Isolate* isolate = CcTest::i_isolate(); |
559 Handle<FieldType> any_type = FieldType::Any(isolate); | 578 Handle<FieldType> any_type = FieldType::Any(isolate); |
560 | 579 |
561 CHECK(detach_property_at_index >= -1 && | 580 CHECK(detach_property_at_index >= -1 && |
562 detach_property_at_index < kPropCount); | 581 detach_property_at_index < kPropCount); |
563 CHECK(property_index < kPropCount); | 582 CHECK(property_index < kPropCount); |
564 CHECK_NE(detach_property_at_index, property_index); | 583 CHECK_NE(detach_property_at_index, property_index); |
565 | 584 |
566 const bool is_detached_map = detach_property_at_index >= 0; | 585 const bool is_detached_map = detach_property_at_index >= 0; |
567 | 586 |
568 Expectations expectations(isolate); | 587 Expectations expectations(isolate); |
569 | 588 |
570 // Create a map, add required properties to it and initialize expectations. | 589 // Create a map, add required properties to it and initialize expectations. |
571 Handle<Map> initial_map = Map::Create(isolate, 0); | 590 Handle<Map> initial_map = Map::Create(isolate, 0); |
572 Handle<Map> map = initial_map; | 591 Handle<Map> map = initial_map; |
573 Handle<Map> detach_point_map; | 592 Handle<Map> detach_point_map; |
574 for (int i = 0; i < kPropCount; i++) { | 593 for (int i = 0; i < kPropCount; i++) { |
575 if (i == property_index) { | 594 if (i == property_index) { |
576 map = | 595 map = expectations.AddDataField(map, NONE, from.constness, |
577 expectations.AddDataField(map, NONE, from_representation, from_type); | 596 from.representation, from.type); |
578 } else { | 597 } else { |
579 map = | 598 map = expectations.AddDataField(map, NONE, kMutable, |
580 expectations.AddDataField(map, NONE, Representation::Smi(), any_type); | 599 Representation::Smi(), any_type); |
581 if (i == detach_property_at_index) { | 600 if (i == detach_property_at_index) { |
582 detach_point_map = map; | 601 detach_point_map = map; |
583 } | 602 } |
584 } | 603 } |
585 } | 604 } |
586 CHECK(!map->is_deprecated()); | 605 CHECK(!map->is_deprecated()); |
587 CHECK(map->is_stable()); | 606 CHECK(map->is_stable()); |
588 CHECK(expectations.Check(*map)); | 607 CHECK(expectations.Check(*map)); |
589 | 608 |
590 Zone zone(isolate->allocator(), ZONE_NAME); | 609 Zone zone(isolate->allocator(), ZONE_NAME); |
591 | 610 |
592 if (is_detached_map) { | 611 if (is_detached_map) { |
593 detach_point_map = Map::ReconfigureProperty( | 612 detach_point_map = Map::ReconfigureProperty( |
594 detach_point_map, detach_property_at_index, kData, NONE, | 613 detach_point_map, detach_property_at_index, kData, NONE, |
595 Representation::Tagged(), any_type); | 614 Representation::Tagged(), any_type); |
596 expectations.SetDataField(detach_property_at_index, | 615 expectations.SetDataField(detach_property_at_index, kMutable, |
597 Representation::Tagged(), any_type); | 616 Representation::Tagged(), any_type); |
598 CHECK(map->is_deprecated()); | 617 CHECK(map->is_deprecated()); |
599 CHECK(expectations.Check(*detach_point_map, | 618 CHECK(expectations.Check(*detach_point_map, |
600 detach_point_map->NumberOfOwnDescriptors())); | 619 detach_point_map->NumberOfOwnDescriptors())); |
601 } | 620 } |
602 | 621 |
603 // Create new maps by generalizing representation of propX field. | 622 // Create new maps by generalizing representation of propX field. |
604 Handle<Map> field_owner(map->FindFieldOwner(property_index), isolate); | 623 Handle<Map> field_owner(map->FindFieldOwner(property_index), isolate); |
605 CompilationDependencies dependencies(isolate, &zone); | 624 CompilationDependencies dependencies(isolate, &zone); |
606 CHECK(!dependencies.HasAborted()); | 625 CHECK(!dependencies.HasAborted()); |
607 | 626 |
608 dependencies.AssumeFieldOwner(field_owner); | 627 dependencies.AssumeFieldOwner(field_owner); |
609 | 628 |
610 Handle<Map> new_map = Map::ReconfigureProperty( | 629 Handle<Map> new_map = Map::ReconfigureProperty( |
611 map, property_index, kData, NONE, to_representation, to_type); | 630 map, property_index, kData, NONE, to.representation, to.type); |
612 | 631 |
613 expectations.SetDataField(property_index, expected_representation, | 632 expectations.SetDataField(property_index, expected.constness, |
614 expected_type); | 633 expected.representation, expected.type); |
615 | 634 |
616 CHECK(!new_map->is_deprecated()); | 635 CHECK(!new_map->is_deprecated()); |
617 CHECK(expectations.Check(*new_map)); | 636 CHECK(expectations.Check(*new_map)); |
618 | 637 |
619 if (is_detached_map) { | 638 if (is_detached_map) { |
620 CHECK(!map->is_stable()); | 639 CHECK(!map->is_stable()); |
621 CHECK(map->is_deprecated()); | 640 CHECK(map->is_deprecated()); |
622 CHECK_NE(*map, *new_map); | 641 CHECK_NE(*map, *new_map); |
623 CHECK_EQ(expected_field_type_dependency && !field_owner->is_deprecated(), | 642 CHECK_EQ(expected_field_type_dependency && !field_owner->is_deprecated(), |
624 dependencies.HasAborted()); | 643 dependencies.HasAborted()); |
(...skipping 24 matching lines...) Expand all Loading... |
649 } | 668 } |
650 } | 669 } |
651 | 670 |
652 dependencies.Rollback(); // Properly cleanup compilation info. | 671 dependencies.Rollback(); // Properly cleanup compilation info. |
653 | 672 |
654 // Update all deprecated maps and check that they are now the same. | 673 // Update all deprecated maps and check that they are now the same. |
655 Handle<Map> updated_map = Map::Update(map); | 674 Handle<Map> updated_map = Map::Update(map); |
656 CHECK_EQ(*new_map, *updated_map); | 675 CHECK_EQ(*new_map, *updated_map); |
657 } | 676 } |
658 | 677 |
659 static void TestGeneralizeRepresentation( | 678 static void TestGeneralizeRepresentation(const CRFTData& from, |
660 Representation from_representation, Handle<FieldType> from_type, | 679 const CRFTData& to, |
661 Representation to_representation, Handle<FieldType> to_type, | 680 const CRFTData& expected, |
662 Representation expected_representation, Handle<FieldType> expected_type, | 681 bool expected_deprecation, |
663 bool expected_deprecation, bool expected_field_type_dependency) { | 682 bool expected_field_type_dependency) { |
664 // Check the cases when the map being reconfigured is a part of the | 683 // Check the cases when the map being reconfigured is a part of the |
665 // transition tree. | 684 // transition tree. |
666 STATIC_ASSERT(kPropCount > 4); | 685 STATIC_ASSERT(kPropCount > 4); |
667 int indices[] = {0, 2, kPropCount - 1}; | 686 int indices[] = {0, 2, kPropCount - 1}; |
668 for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) { | 687 for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) { |
669 TestGeneralizeRepresentation( | 688 TestGeneralizeRepresentation(-1, indices[i], from, to, expected, |
670 -1, indices[i], from_representation, from_type, to_representation, | 689 expected_deprecation, |
671 to_type, expected_representation, expected_type, expected_deprecation, | 690 expected_field_type_dependency); |
672 expected_field_type_dependency); | |
673 } | 691 } |
674 | 692 |
675 if (!from_representation.IsNone()) { | 693 if (!from.representation.IsNone()) { |
676 // Check the cases when the map being reconfigured is NOT a part of the | 694 // Check the cases when the map being reconfigured is NOT a part of the |
677 // transition tree. "None -> anything" representation changes make sense | 695 // transition tree. "None -> anything" representation changes make sense |
678 // only for "attached" maps. | 696 // only for "attached" maps. |
679 int indices[] = {0, kPropCount - 1}; | 697 int indices[] = {0, kPropCount - 1}; |
680 for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) { | 698 for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) { |
681 TestGeneralizeRepresentation( | 699 TestGeneralizeRepresentation(indices[i], 2, from, to, expected, |
682 indices[i], 2, from_representation, from_type, to_representation, | 700 expected_deprecation, |
683 to_type, expected_representation, expected_type, expected_deprecation, | 701 expected_field_type_dependency); |
684 expected_field_type_dependency); | |
685 } | 702 } |
686 | 703 |
687 // Check that reconfiguration to the very same field works correctly. | 704 // Check that reconfiguration to the very same field works correctly. |
688 Representation representation = from_representation; | 705 CRFTData data = from; |
689 Handle<FieldType> type = from_type; | 706 TestGeneralizeRepresentation(-1, 2, data, data, data, false, false); |
690 TestGeneralizeRepresentation(-1, 2, representation, type, representation, | |
691 type, representation, type, false, false); | |
692 } | 707 } |
693 } | 708 } |
694 | 709 |
695 static void TestGeneralizeRepresentation(Representation from_representation, | 710 static void TestGeneralizeRepresentation(const CRFTData& from, |
696 Handle<FieldType> from_type, | 711 const CRFTData& to, |
697 Representation to_representation, | 712 const CRFTData& expected) { |
698 Handle<FieldType> to_type, | |
699 Representation expected_representation, | |
700 Handle<FieldType> expected_type) { | |
701 const bool expected_deprecation = true; | 713 const bool expected_deprecation = true; |
702 const bool expected_field_type_dependency = false; | 714 const bool expected_field_type_dependency = false; |
703 | 715 |
704 TestGeneralizeRepresentation( | 716 TestGeneralizeRepresentation(from, to, expected, expected_deprecation, |
705 from_representation, from_type, to_representation, to_type, | 717 expected_field_type_dependency); |
706 expected_representation, expected_type, expected_deprecation, | |
707 expected_field_type_dependency); | |
708 } | 718 } |
709 | 719 |
710 static void TestGeneralizeRepresentationTrivial( | 720 static void TestGeneralizeRepresentationTrivial( |
711 Representation from_representation, Handle<FieldType> from_type, | 721 const CRFTData& from, const CRFTData& to, const CRFTData& expected, |
712 Representation to_representation, Handle<FieldType> to_type, | |
713 Representation expected_representation, Handle<FieldType> expected_type, | |
714 bool expected_field_type_dependency = true) { | 722 bool expected_field_type_dependency = true) { |
715 const bool expected_deprecation = false; | 723 const bool expected_deprecation = false; |
716 | 724 |
717 TestGeneralizeRepresentation( | 725 TestGeneralizeRepresentation(from, to, expected, expected_deprecation, |
718 from_representation, from_type, to_representation, to_type, | 726 expected_field_type_dependency); |
719 expected_representation, expected_type, expected_deprecation, | |
720 expected_field_type_dependency); | |
721 } | 727 } |
722 | 728 |
723 | 729 |
724 TEST(GeneralizeRepresentationSmiToDouble) { | 730 TEST(GeneralizeRepresentationSmiToDouble) { |
725 CcTest::InitializeVM(); | 731 CcTest::InitializeVM(); |
726 v8::HandleScope scope(CcTest::isolate()); | 732 v8::HandleScope scope(CcTest::isolate()); |
727 Isolate* isolate = CcTest::i_isolate(); | 733 Isolate* isolate = CcTest::i_isolate(); |
728 Handle<FieldType> any_type = FieldType::Any(isolate); | 734 Handle<FieldType> any_type = FieldType::Any(isolate); |
729 | 735 |
730 TestGeneralizeRepresentation(Representation::Smi(), any_type, | 736 TestGeneralizeRepresentation({kMutable, Representation::Smi(), any_type}, |
731 Representation::Double(), any_type, | 737 {kMutable, Representation::Double(), any_type}, |
732 Representation::Double(), any_type); | 738 {kMutable, Representation::Double(), any_type}); |
733 } | 739 } |
734 | 740 |
735 | 741 |
736 TEST(GeneralizeRepresentationSmiToTagged) { | 742 TEST(GeneralizeRepresentationSmiToTagged) { |
737 CcTest::InitializeVM(); | 743 CcTest::InitializeVM(); |
738 v8::HandleScope scope(CcTest::isolate()); | 744 v8::HandleScope scope(CcTest::isolate()); |
739 Isolate* isolate = CcTest::i_isolate(); | 745 Isolate* isolate = CcTest::i_isolate(); |
740 Handle<FieldType> any_type = FieldType::Any(isolate); | 746 Handle<FieldType> any_type = FieldType::Any(isolate); |
741 Handle<FieldType> value_type = | 747 Handle<FieldType> value_type = |
742 FieldType::Class(Map::Create(isolate, 0), isolate); | 748 FieldType::Class(Map::Create(isolate, 0), isolate); |
743 | 749 |
744 TestGeneralizeRepresentation(Representation::Smi(), any_type, | 750 TestGeneralizeRepresentation( |
745 Representation::HeapObject(), value_type, | 751 {kMutable, Representation::Smi(), any_type}, |
746 Representation::Tagged(), any_type); | 752 {kMutable, Representation::HeapObject(), value_type}, |
| 753 {kMutable, Representation::Tagged(), any_type}); |
747 } | 754 } |
748 | 755 |
749 | 756 |
750 TEST(GeneralizeRepresentationDoubleToTagged) { | 757 TEST(GeneralizeRepresentationDoubleToTagged) { |
751 CcTest::InitializeVM(); | 758 CcTest::InitializeVM(); |
752 v8::HandleScope scope(CcTest::isolate()); | 759 v8::HandleScope scope(CcTest::isolate()); |
753 Isolate* isolate = CcTest::i_isolate(); | 760 Isolate* isolate = CcTest::i_isolate(); |
754 Handle<FieldType> any_type = FieldType::Any(isolate); | 761 Handle<FieldType> any_type = FieldType::Any(isolate); |
755 Handle<FieldType> value_type = | 762 Handle<FieldType> value_type = |
756 FieldType::Class(Map::Create(isolate, 0), isolate); | 763 FieldType::Class(Map::Create(isolate, 0), isolate); |
757 | 764 |
758 TestGeneralizeRepresentation(Representation::Double(), any_type, | 765 TestGeneralizeRepresentation( |
759 Representation::HeapObject(), value_type, | 766 {kMutable, Representation::Double(), any_type}, |
760 Representation::Tagged(), any_type); | 767 {kMutable, Representation::HeapObject(), value_type}, |
| 768 {kMutable, Representation::Tagged(), any_type}); |
761 } | 769 } |
762 | 770 |
763 | 771 |
764 TEST(GeneralizeRepresentationHeapObjectToTagged) { | 772 TEST(GeneralizeRepresentationHeapObjectToTagged) { |
765 CcTest::InitializeVM(); | 773 CcTest::InitializeVM(); |
766 v8::HandleScope scope(CcTest::isolate()); | 774 v8::HandleScope scope(CcTest::isolate()); |
767 Isolate* isolate = CcTest::i_isolate(); | 775 Isolate* isolate = CcTest::i_isolate(); |
768 Handle<FieldType> any_type = FieldType::Any(isolate); | 776 Handle<FieldType> any_type = FieldType::Any(isolate); |
769 Handle<FieldType> value_type = | 777 Handle<FieldType> value_type = |
770 FieldType::Class(Map::Create(isolate, 0), isolate); | 778 FieldType::Class(Map::Create(isolate, 0), isolate); |
771 | 779 |
772 TestGeneralizeRepresentation(Representation::HeapObject(), value_type, | 780 TestGeneralizeRepresentation( |
773 Representation::Smi(), any_type, | 781 {kMutable, Representation::HeapObject(), value_type}, |
774 Representation::Tagged(), any_type); | 782 {kMutable, Representation::Smi(), any_type}, |
| 783 {kMutable, Representation::Tagged(), any_type}); |
775 } | 784 } |
776 | 785 |
777 | 786 |
778 TEST(GeneralizeRepresentationHeapObjectToHeapObject) { | 787 TEST(GeneralizeRepresentationHeapObjectToHeapObject) { |
779 CcTest::InitializeVM(); | 788 CcTest::InitializeVM(); |
780 v8::HandleScope scope(CcTest::isolate()); | 789 v8::HandleScope scope(CcTest::isolate()); |
781 Isolate* isolate = CcTest::i_isolate(); | 790 Isolate* isolate = CcTest::i_isolate(); |
782 Handle<FieldType> any_type = FieldType::Any(isolate); | 791 Handle<FieldType> any_type = FieldType::Any(isolate); |
783 | 792 |
784 Handle<FieldType> current_type = | 793 Handle<FieldType> current_type = |
785 FieldType::Class(Map::Create(isolate, 0), isolate); | 794 FieldType::Class(Map::Create(isolate, 0), isolate); |
786 | 795 |
787 Handle<FieldType> new_type = | 796 Handle<FieldType> new_type = |
788 FieldType::Class(Map::Create(isolate, 0), isolate); | 797 FieldType::Class(Map::Create(isolate, 0), isolate); |
789 | 798 |
790 Handle<FieldType> expected_type = any_type; | 799 Handle<FieldType> expected_type = any_type; |
791 | 800 |
792 TestGeneralizeRepresentationTrivial( | 801 TestGeneralizeRepresentationTrivial( |
793 Representation::HeapObject(), current_type, | 802 {kMutable, Representation::HeapObject(), current_type}, |
794 Representation::HeapObject(), new_type, Representation::HeapObject(), | 803 {kMutable, Representation::HeapObject(), new_type}, |
795 expected_type); | 804 {kMutable, Representation::HeapObject(), expected_type}); |
796 current_type = expected_type; | 805 current_type = expected_type; |
797 | 806 |
798 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); | 807 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); |
799 | 808 |
800 TestGeneralizeRepresentationTrivial( | 809 TestGeneralizeRepresentationTrivial( |
801 Representation::HeapObject(), any_type, Representation::HeapObject(), | 810 {kMutable, Representation::HeapObject(), any_type}, |
802 new_type, Representation::HeapObject(), any_type, false); | 811 {kMutable, Representation::HeapObject(), new_type}, |
| 812 {kMutable, Representation::HeapObject(), any_type}, false); |
803 } | 813 } |
804 | 814 |
805 | 815 |
806 TEST(GeneralizeRepresentationNoneToSmi) { | 816 TEST(GeneralizeRepresentationNoneToSmi) { |
807 CcTest::InitializeVM(); | 817 CcTest::InitializeVM(); |
808 v8::HandleScope scope(CcTest::isolate()); | 818 v8::HandleScope scope(CcTest::isolate()); |
809 Isolate* isolate = CcTest::i_isolate(); | 819 Isolate* isolate = CcTest::i_isolate(); |
810 Handle<FieldType> none_type = FieldType::None(isolate); | 820 Handle<FieldType> none_type = FieldType::None(isolate); |
811 Handle<FieldType> any_type = FieldType::Any(isolate); | 821 Handle<FieldType> any_type = FieldType::Any(isolate); |
812 | 822 |
813 // None -> Smi representation change is trivial. | 823 // None -> Smi representation change is trivial. |
814 TestGeneralizeRepresentationTrivial(Representation::None(), none_type, | 824 TestGeneralizeRepresentationTrivial( |
815 Representation::Smi(), any_type, | 825 {kMutable, Representation::None(), none_type}, |
816 Representation::Smi(), any_type); | 826 {kMutable, Representation::Smi(), any_type}, |
| 827 {kMutable, Representation::Smi(), any_type}); |
817 } | 828 } |
818 | 829 |
819 | 830 |
820 TEST(GeneralizeRepresentationNoneToDouble) { | 831 TEST(GeneralizeRepresentationNoneToDouble) { |
821 CcTest::InitializeVM(); | 832 CcTest::InitializeVM(); |
822 v8::HandleScope scope(CcTest::isolate()); | 833 v8::HandleScope scope(CcTest::isolate()); |
823 Isolate* isolate = CcTest::i_isolate(); | 834 Isolate* isolate = CcTest::i_isolate(); |
824 Handle<FieldType> none_type = FieldType::None(isolate); | 835 Handle<FieldType> none_type = FieldType::None(isolate); |
825 Handle<FieldType> any_type = FieldType::Any(isolate); | 836 Handle<FieldType> any_type = FieldType::Any(isolate); |
826 | 837 |
827 // None -> Double representation change is NOT trivial. | 838 // None -> Double representation change is NOT trivial. |
828 TestGeneralizeRepresentation(Representation::None(), none_type, | 839 TestGeneralizeRepresentation({kMutable, Representation::None(), none_type}, |
829 Representation::Double(), any_type, | 840 {kMutable, Representation::Double(), any_type}, |
830 Representation::Double(), any_type); | 841 {kMutable, Representation::Double(), any_type}); |
831 } | 842 } |
832 | 843 |
833 | 844 |
834 TEST(GeneralizeRepresentationNoneToHeapObject) { | 845 TEST(GeneralizeRepresentationNoneToHeapObject) { |
835 CcTest::InitializeVM(); | 846 CcTest::InitializeVM(); |
836 v8::HandleScope scope(CcTest::isolate()); | 847 v8::HandleScope scope(CcTest::isolate()); |
837 Isolate* isolate = CcTest::i_isolate(); | 848 Isolate* isolate = CcTest::i_isolate(); |
838 Handle<FieldType> none_type = FieldType::None(isolate); | 849 Handle<FieldType> none_type = FieldType::None(isolate); |
839 Handle<FieldType> value_type = | 850 Handle<FieldType> value_type = |
840 FieldType::Class(Map::Create(isolate, 0), isolate); | 851 FieldType::Class(Map::Create(isolate, 0), isolate); |
841 | 852 |
842 // None -> HeapObject representation change is trivial. | 853 // None -> HeapObject representation change is trivial. |
843 TestGeneralizeRepresentationTrivial(Representation::None(), none_type, | 854 TestGeneralizeRepresentationTrivial( |
844 Representation::HeapObject(), value_type, | 855 {kMutable, Representation::None(), none_type}, |
845 Representation::HeapObject(), value_type); | 856 {kMutable, Representation::HeapObject(), value_type}, |
| 857 {kMutable, Representation::HeapObject(), value_type}); |
846 } | 858 } |
847 | 859 |
848 | 860 |
849 TEST(GeneralizeRepresentationNoneToTagged) { | 861 TEST(GeneralizeRepresentationNoneToTagged) { |
850 CcTest::InitializeVM(); | 862 CcTest::InitializeVM(); |
851 v8::HandleScope scope(CcTest::isolate()); | 863 v8::HandleScope scope(CcTest::isolate()); |
852 Isolate* isolate = CcTest::i_isolate(); | 864 Isolate* isolate = CcTest::i_isolate(); |
853 Handle<FieldType> none_type = FieldType::None(isolate); | 865 Handle<FieldType> none_type = FieldType::None(isolate); |
854 Handle<FieldType> any_type = FieldType::Any(isolate); | 866 Handle<FieldType> any_type = FieldType::Any(isolate); |
855 | 867 |
856 // None -> HeapObject representation change is trivial. | 868 // None -> HeapObject representation change is trivial. |
857 TestGeneralizeRepresentationTrivial(Representation::None(), none_type, | 869 TestGeneralizeRepresentationTrivial( |
858 Representation::Tagged(), any_type, | 870 {kMutable, Representation::None(), none_type}, |
859 Representation::Tagged(), any_type); | 871 {kMutable, Representation::Tagged(), any_type}, |
| 872 {kMutable, Representation::Tagged(), any_type}); |
860 } | 873 } |
861 | 874 |
862 | 875 |
863 //////////////////////////////////////////////////////////////////////////////// | 876 //////////////////////////////////////////////////////////////////////////////// |
864 // A set of tests for representation generalization case with kAccessor | 877 // A set of tests for representation generalization case with kAccessor |
865 // properties. | 878 // properties. |
866 // | 879 // |
867 | 880 |
868 TEST(GeneralizeRepresentationWithAccessorProperties) { | 881 TEST(GeneralizeRepresentationWithAccessorProperties) { |
869 CcTest::InitializeVM(); | 882 CcTest::InitializeVM(); |
870 v8::HandleScope scope(CcTest::isolate()); | 883 v8::HandleScope scope(CcTest::isolate()); |
871 Isolate* isolate = CcTest::i_isolate(); | 884 Isolate* isolate = CcTest::i_isolate(); |
872 Handle<FieldType> any_type = FieldType::Any(isolate); | 885 Handle<FieldType> any_type = FieldType::Any(isolate); |
873 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 886 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
874 | 887 |
875 const int kAccessorProp = kPropCount / 2; | 888 const int kAccessorProp = kPropCount / 2; |
876 Expectations expectations(isolate); | 889 Expectations expectations(isolate); |
877 | 890 |
878 // Create a map, add required properties to it and initialize expectations. | 891 // Create a map, add required properties to it and initialize expectations. |
879 Handle<Map> initial_map = Map::Create(isolate, 0); | 892 Handle<Map> initial_map = Map::Create(isolate, 0); |
880 Handle<Map> map = initial_map; | 893 Handle<Map> map = initial_map; |
881 for (int i = 0; i < kPropCount; i++) { | 894 for (int i = 0; i < kPropCount; i++) { |
882 if (i == kAccessorProp) { | 895 if (i == kAccessorProp) { |
883 map = expectations.AddAccessorConstant(map, NONE, pair); | 896 map = expectations.AddAccessorConstant(map, NONE, pair); |
884 } else { | 897 } else { |
885 map = | 898 map = expectations.AddDataField(map, NONE, kMutable, |
886 expectations.AddDataField(map, NONE, Representation::Smi(), any_type); | 899 Representation::Smi(), any_type); |
887 } | 900 } |
888 } | 901 } |
889 CHECK(!map->is_deprecated()); | 902 CHECK(!map->is_deprecated()); |
890 CHECK(map->is_stable()); | 903 CHECK(map->is_stable()); |
891 CHECK(expectations.Check(*map)); | 904 CHECK(expectations.Check(*map)); |
892 | 905 |
893 // Create new maps by generalizing representation of propX field. | 906 // Create new maps by generalizing representation of propX field. |
894 Handle<Map> maps[kPropCount]; | 907 Handle<Map> maps[kPropCount]; |
895 for (int i = 0; i < kPropCount; i++) { | 908 for (int i = 0; i < kPropCount; i++) { |
896 if (i == kAccessorProp) { | 909 if (i == kAccessorProp) { |
897 // Skip accessor property reconfiguration. | 910 // Skip accessor property reconfiguration. |
898 maps[i] = maps[i - 1]; | 911 maps[i] = maps[i - 1]; |
899 continue; | 912 continue; |
900 } | 913 } |
901 Handle<Map> new_map = Map::ReconfigureProperty( | 914 Handle<Map> new_map = Map::ReconfigureProperty( |
902 map, i, kData, NONE, Representation::Double(), any_type); | 915 map, i, kData, NONE, Representation::Double(), any_type); |
903 maps[i] = new_map; | 916 maps[i] = new_map; |
904 | 917 |
905 expectations.SetDataField(i, Representation::Double(), any_type); | 918 expectations.SetDataField(i, kMutable, Representation::Double(), any_type); |
906 | 919 |
907 CHECK(!map->is_stable()); | 920 CHECK(!map->is_stable()); |
908 CHECK(map->is_deprecated()); | 921 CHECK(map->is_deprecated()); |
909 CHECK_NE(*map, *new_map); | 922 CHECK_NE(*map, *new_map); |
910 CHECK(i == 0 || maps[i - 1]->is_deprecated()); | 923 CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
911 | 924 |
912 CHECK(!new_map->is_deprecated()); | 925 CHECK(!new_map->is_deprecated()); |
913 CHECK(expectations.Check(*new_map)); | 926 CHECK(expectations.Check(*new_map)); |
914 } | 927 } |
915 | 928 |
(...skipping 17 matching lines...) Expand all Loading... |
933 // This test ensures that representation/field type generalization is correctly | 946 // This test ensures that representation/field type generalization is correctly |
934 // propagated from one branch of transition tree (|map2|) to another (|map|). | 947 // propagated from one branch of transition tree (|map2|) to another (|map|). |
935 // | 948 // |
936 // + - p2B - p3 - p4: |map2| | 949 // + - p2B - p3 - p4: |map2| |
937 // | | 950 // | |
938 // {} - p0 - p1 - p2A - p3 - p4: |map| | 951 // {} - p0 - p1 - p2A - p3 - p4: |map| |
939 // | 952 // |
940 // where "p2A" and "p2B" differ only in the attributes. | 953 // where "p2A" and "p2B" differ only in the attributes. |
941 // | 954 // |
942 static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation( | 955 static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
943 Representation from_representation, Handle<FieldType> from_type, | 956 const CRFTData& from, const CRFTData& to, const CRFTData& expected) { |
944 Representation to_representation, Handle<FieldType> to_type, | |
945 Representation expected_representation, Handle<FieldType> expected_type) { | |
946 Isolate* isolate = CcTest::i_isolate(); | 957 Isolate* isolate = CcTest::i_isolate(); |
947 | 958 |
948 Expectations expectations(isolate); | 959 Expectations expectations(isolate); |
949 | 960 |
950 // Create a map, add required properties to it and initialize expectations. | 961 // Create a map, add required properties to it and initialize expectations. |
951 Handle<Map> initial_map = Map::Create(isolate, 0); | 962 Handle<Map> initial_map = Map::Create(isolate, 0); |
952 Handle<Map> map = initial_map; | 963 Handle<Map> map = initial_map; |
953 for (int i = 0; i < kPropCount; i++) { | 964 for (int i = 0; i < kPropCount; i++) { |
954 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 965 map = expectations.AddDataField(map, NONE, from.constness, |
| 966 from.representation, from.type); |
955 } | 967 } |
956 CHECK(!map->is_deprecated()); | 968 CHECK(!map->is_deprecated()); |
957 CHECK(map->is_stable()); | 969 CHECK(map->is_stable()); |
958 CHECK(expectations.Check(*map)); | 970 CHECK(expectations.Check(*map)); |
959 | 971 |
960 | 972 |
961 // Create another branch in transition tree (property at index |kSplitProp| | 973 // Create another branch in transition tree (property at index |kSplitProp| |
962 // has different attributes), initialize expectations. | 974 // has different attributes), initialize expectations. |
963 const int kSplitProp = kPropCount / 2; | 975 const int kSplitProp = kPropCount / 2; |
964 Expectations expectations2(isolate); | 976 Expectations expectations2(isolate); |
965 | 977 |
966 Handle<Map> map2 = initial_map; | 978 Handle<Map> map2 = initial_map; |
967 for (int i = 0; i < kSplitProp; i++) { | 979 for (int i = 0; i < kSplitProp; i++) { |
968 map2 = expectations2.FollowDataTransition(map2, NONE, from_representation, | 980 map2 = expectations2.FollowDataTransition(map2, NONE, from.constness, |
969 from_type); | 981 from.representation, from.type); |
970 } | 982 } |
971 map2 = | 983 map2 = expectations2.AddDataField(map2, READ_ONLY, to.constness, |
972 expectations2.AddDataField(map2, READ_ONLY, to_representation, to_type); | 984 to.representation, to.type); |
973 | 985 |
974 for (int i = kSplitProp + 1; i < kPropCount; i++) { | 986 for (int i = kSplitProp + 1; i < kPropCount; i++) { |
975 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); | 987 map2 = expectations2.AddDataField(map2, NONE, to.constness, |
| 988 to.representation, to.type); |
976 } | 989 } |
977 CHECK(!map2->is_deprecated()); | 990 CHECK(!map2->is_deprecated()); |
978 CHECK(map2->is_stable()); | 991 CHECK(map2->is_stable()); |
979 CHECK(expectations2.Check(*map2)); | 992 CHECK(expectations2.Check(*map2)); |
980 | 993 |
981 Zone zone(isolate->allocator(), ZONE_NAME); | 994 Zone zone(isolate->allocator(), ZONE_NAME); |
982 Handle<Map> field_owner(map->FindFieldOwner(kSplitProp), isolate); | 995 Handle<Map> field_owner(map->FindFieldOwner(kSplitProp), isolate); |
983 CompilationDependencies dependencies(isolate, &zone); | 996 CompilationDependencies dependencies(isolate, &zone); |
984 CHECK(!dependencies.HasAborted()); | 997 CHECK(!dependencies.HasAborted()); |
985 dependencies.AssumeFieldOwner(field_owner); | 998 dependencies.AssumeFieldOwner(field_owner); |
986 | 999 |
987 // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which | 1000 // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which |
988 // should generalize representations in |map1|. | 1001 // should generalize representations in |map1|. |
989 Handle<Map> new_map = | 1002 Handle<Map> new_map = |
990 Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); | 1003 Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); |
991 | 1004 |
992 // |map2| should be left unchanged but marked unstable. | 1005 // |map2| should be left unchanged but marked unstable. |
993 CHECK(!map2->is_stable()); | 1006 CHECK(!map2->is_stable()); |
994 CHECK(!map2->is_deprecated()); | 1007 CHECK(!map2->is_deprecated()); |
995 CHECK_NE(*map2, *new_map); | 1008 CHECK_NE(*map2, *new_map); |
996 CHECK(expectations2.Check(*map2)); | 1009 CHECK(expectations2.Check(*map2)); |
997 | 1010 |
998 // |map| should be deprecated and |new_map| should match new expectations. | 1011 // |map| should be deprecated and |new_map| should match new expectations. |
999 for (int i = kSplitProp; i < kPropCount; i++) { | 1012 for (int i = kSplitProp; i < kPropCount; i++) { |
1000 expectations.SetDataField(i, expected_representation, expected_type); | 1013 expectations.SetDataField(i, expected.constness, expected.representation, |
| 1014 expected.type); |
1001 } | 1015 } |
1002 CHECK(map->is_deprecated()); | 1016 CHECK(map->is_deprecated()); |
1003 CHECK(!dependencies.HasAborted()); | 1017 CHECK(!dependencies.HasAborted()); |
1004 dependencies.Rollback(); // Properly cleanup compilation info. | 1018 dependencies.Rollback(); // Properly cleanup compilation info. |
1005 CHECK_NE(*map, *new_map); | 1019 CHECK_NE(*map, *new_map); |
1006 | 1020 |
1007 CHECK(!new_map->is_deprecated()); | 1021 CHECK(!new_map->is_deprecated()); |
1008 CHECK(expectations.Check(*new_map)); | 1022 CHECK(expectations.Check(*new_map)); |
1009 | 1023 |
1010 // Update deprecated |map|, it should become |new_map|. | 1024 // Update deprecated |map|, it should become |new_map|. |
1011 Handle<Map> updated_map = Map::Update(map); | 1025 Handle<Map> updated_map = Map::Update(map); |
1012 CHECK_EQ(*new_map, *updated_map); | 1026 CHECK_EQ(*new_map, *updated_map); |
1013 } | 1027 } |
1014 | 1028 |
1015 | 1029 |
1016 // This test ensures that trivial representation/field type generalization | 1030 // This test ensures that trivial representation/field type generalization |
1017 // (from HeapObject to HeapObject) is correctly propagated from one branch of | 1031 // (from HeapObject to HeapObject) is correctly propagated from one branch of |
1018 // transition tree (|map2|) to another (|map|). | 1032 // transition tree (|map2|) to another (|map|). |
1019 // | 1033 // |
1020 // + - p2B - p3 - p4: |map2| | 1034 // + - p2B - p3 - p4: |map2| |
1021 // | | 1035 // | |
1022 // {} - p0 - p1 - p2A - p3 - p4: |map| | 1036 // {} - p0 - p1 - p2A - p3 - p4: |map| |
1023 // | 1037 // |
1024 // where "p2A" and "p2B" differ only in the attributes. | 1038 // where "p2A" and "p2B" differ only in the attributes. |
1025 // | 1039 // |
1026 static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( | 1040 static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( |
1027 Representation from_representation, Handle<FieldType> from_type, | 1041 const CRFTData& from, const CRFTData& to, const CRFTData& expected, |
1028 Representation to_representation, Handle<FieldType> to_type, | |
1029 Representation expected_representation, Handle<FieldType> expected_type, | |
1030 bool expected_field_type_dependency = true) { | 1042 bool expected_field_type_dependency = true) { |
1031 Isolate* isolate = CcTest::i_isolate(); | 1043 Isolate* isolate = CcTest::i_isolate(); |
1032 | 1044 |
1033 Expectations expectations(isolate); | 1045 Expectations expectations(isolate); |
1034 | 1046 |
1035 // Create a map, add required properties to it and initialize expectations. | 1047 // Create a map, add required properties to it and initialize expectations. |
1036 Handle<Map> initial_map = Map::Create(isolate, 0); | 1048 Handle<Map> initial_map = Map::Create(isolate, 0); |
1037 Handle<Map> map = initial_map; | 1049 Handle<Map> map = initial_map; |
1038 for (int i = 0; i < kPropCount; i++) { | 1050 for (int i = 0; i < kPropCount; i++) { |
1039 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1051 map = expectations.AddDataField(map, NONE, from.constness, |
| 1052 from.representation, from.type); |
1040 } | 1053 } |
1041 CHECK(!map->is_deprecated()); | 1054 CHECK(!map->is_deprecated()); |
1042 CHECK(map->is_stable()); | 1055 CHECK(map->is_stable()); |
1043 CHECK(expectations.Check(*map)); | 1056 CHECK(expectations.Check(*map)); |
1044 | 1057 |
1045 | 1058 |
1046 // Create another branch in transition tree (property at index |kSplitProp| | 1059 // Create another branch in transition tree (property at index |kSplitProp| |
1047 // has different attributes), initialize expectations. | 1060 // has different attributes), initialize expectations. |
1048 const int kSplitProp = kPropCount / 2; | 1061 const int kSplitProp = kPropCount / 2; |
1049 Expectations expectations2(isolate); | 1062 Expectations expectations2(isolate); |
1050 | 1063 |
1051 Handle<Map> map2 = initial_map; | 1064 Handle<Map> map2 = initial_map; |
1052 for (int i = 0; i < kSplitProp; i++) { | 1065 for (int i = 0; i < kSplitProp; i++) { |
1053 map2 = expectations2.FollowDataTransition(map2, NONE, from_representation, | 1066 map2 = expectations2.FollowDataTransition(map2, NONE, from.constness, |
1054 from_type); | 1067 from.representation, from.type); |
1055 } | 1068 } |
1056 map2 = | 1069 map2 = expectations2.AddDataField(map2, READ_ONLY, to.constness, |
1057 expectations2.AddDataField(map2, READ_ONLY, to_representation, to_type); | 1070 to.representation, to.type); |
1058 | 1071 |
1059 for (int i = kSplitProp + 1; i < kPropCount; i++) { | 1072 for (int i = kSplitProp + 1; i < kPropCount; i++) { |
1060 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); | 1073 map2 = expectations2.AddDataField(map2, NONE, to.constness, |
| 1074 to.representation, to.type); |
1061 } | 1075 } |
1062 CHECK(!map2->is_deprecated()); | 1076 CHECK(!map2->is_deprecated()); |
1063 CHECK(map2->is_stable()); | 1077 CHECK(map2->is_stable()); |
1064 CHECK(expectations2.Check(*map2)); | 1078 CHECK(expectations2.Check(*map2)); |
1065 | 1079 |
1066 Zone zone(isolate->allocator(), ZONE_NAME); | 1080 Zone zone(isolate->allocator(), ZONE_NAME); |
1067 Handle<Map> field_owner(map->FindFieldOwner(kSplitProp), isolate); | 1081 Handle<Map> field_owner(map->FindFieldOwner(kSplitProp), isolate); |
1068 CompilationDependencies dependencies(isolate, &zone); | 1082 CompilationDependencies dependencies(isolate, &zone); |
1069 CHECK(!dependencies.HasAborted()); | 1083 CHECK(!dependencies.HasAborted()); |
1070 dependencies.AssumeFieldOwner(field_owner); | 1084 dependencies.AssumeFieldOwner(field_owner); |
1071 | 1085 |
1072 // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which | 1086 // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which |
1073 // should generalize representations in |map1|. | 1087 // should generalize representations in |map1|. |
1074 Handle<Map> new_map = | 1088 Handle<Map> new_map = |
1075 Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); | 1089 Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); |
1076 | 1090 |
1077 // |map2| should be left unchanged but marked unstable. | 1091 // |map2| should be left unchanged but marked unstable. |
1078 CHECK(!map2->is_stable()); | 1092 CHECK(!map2->is_stable()); |
1079 CHECK(!map2->is_deprecated()); | 1093 CHECK(!map2->is_deprecated()); |
1080 CHECK_NE(*map2, *new_map); | 1094 CHECK_NE(*map2, *new_map); |
1081 CHECK(expectations2.Check(*map2)); | 1095 CHECK(expectations2.Check(*map2)); |
1082 | 1096 |
1083 // In trivial case |map| should be returned as a result of the property | 1097 // In trivial case |map| should be returned as a result of the property |
1084 // reconfiguration, respective field types should be generalized and | 1098 // reconfiguration, respective field types should be generalized and |
1085 // respective code dependencies should be invalidated. |map| should be NOT | 1099 // respective code dependencies should be invalidated. |map| should be NOT |
1086 // deprecated and it should match new expectations. | 1100 // deprecated and it should match new expectations. |
1087 for (int i = kSplitProp; i < kPropCount; i++) { | 1101 for (int i = kSplitProp; i < kPropCount; i++) { |
1088 expectations.SetDataField(i, expected_representation, expected_type); | 1102 expectations.SetDataField(i, expected.constness, expected.representation, |
| 1103 expected.type); |
1089 } | 1104 } |
1090 CHECK(!map->is_deprecated()); | 1105 CHECK(!map->is_deprecated()); |
1091 CHECK_EQ(*map, *new_map); | 1106 CHECK_EQ(*map, *new_map); |
1092 CHECK_EQ(expected_field_type_dependency, dependencies.HasAborted()); | 1107 CHECK_EQ(expected_field_type_dependency, dependencies.HasAborted()); |
1093 dependencies.Rollback(); // Properly cleanup compilation info. | 1108 dependencies.Rollback(); // Properly cleanup compilation info. |
1094 | 1109 |
1095 CHECK(!new_map->is_deprecated()); | 1110 CHECK(!new_map->is_deprecated()); |
1096 CHECK(expectations.Check(*new_map)); | 1111 CHECK(expectations.Check(*new_map)); |
1097 | 1112 |
1098 Handle<Map> updated_map = Map::Update(map); | 1113 Handle<Map> updated_map = Map::Update(map); |
1099 CHECK_EQ(*new_map, *updated_map); | 1114 CHECK_EQ(*new_map, *updated_map); |
1100 } | 1115 } |
1101 | 1116 |
1102 | 1117 |
1103 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToDouble) { | 1118 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToDouble) { |
1104 CcTest::InitializeVM(); | 1119 CcTest::InitializeVM(); |
1105 v8::HandleScope scope(CcTest::isolate()); | 1120 v8::HandleScope scope(CcTest::isolate()); |
1106 Isolate* isolate = CcTest::i_isolate(); | 1121 Isolate* isolate = CcTest::i_isolate(); |
1107 Handle<FieldType> any_type = FieldType::Any(isolate); | 1122 Handle<FieldType> any_type = FieldType::Any(isolate); |
1108 | 1123 |
1109 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( | 1124 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
1110 Representation::Smi(), any_type, Representation::Double(), any_type, | 1125 {kMutable, Representation::Smi(), any_type}, |
1111 Representation::Double(), any_type); | 1126 {kMutable, Representation::Double(), any_type}, |
| 1127 {kMutable, Representation::Double(), any_type}); |
1112 } | 1128 } |
1113 | 1129 |
1114 | 1130 |
1115 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToTagged) { | 1131 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToTagged) { |
1116 CcTest::InitializeVM(); | 1132 CcTest::InitializeVM(); |
1117 v8::HandleScope scope(CcTest::isolate()); | 1133 v8::HandleScope scope(CcTest::isolate()); |
1118 Isolate* isolate = CcTest::i_isolate(); | 1134 Isolate* isolate = CcTest::i_isolate(); |
1119 Handle<FieldType> any_type = FieldType::Any(isolate); | 1135 Handle<FieldType> any_type = FieldType::Any(isolate); |
1120 Handle<FieldType> value_type = | 1136 Handle<FieldType> value_type = |
1121 FieldType::Class(Map::Create(isolate, 0), isolate); | 1137 FieldType::Class(Map::Create(isolate, 0), isolate); |
1122 | 1138 |
1123 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( | 1139 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
1124 Representation::Smi(), any_type, Representation::HeapObject(), value_type, | 1140 {kMutable, Representation::Smi(), any_type}, |
1125 Representation::Tagged(), any_type); | 1141 {kMutable, Representation::HeapObject(), value_type}, |
| 1142 {kMutable, Representation::Tagged(), any_type}); |
1126 } | 1143 } |
1127 | 1144 |
1128 | 1145 |
1129 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationDoubleToTagged) { | 1146 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationDoubleToTagged) { |
1130 CcTest::InitializeVM(); | 1147 CcTest::InitializeVM(); |
1131 v8::HandleScope scope(CcTest::isolate()); | 1148 v8::HandleScope scope(CcTest::isolate()); |
1132 Isolate* isolate = CcTest::i_isolate(); | 1149 Isolate* isolate = CcTest::i_isolate(); |
1133 Handle<FieldType> any_type = FieldType::Any(isolate); | 1150 Handle<FieldType> any_type = FieldType::Any(isolate); |
1134 Handle<FieldType> value_type = | 1151 Handle<FieldType> value_type = |
1135 FieldType::Class(Map::Create(isolate, 0), isolate); | 1152 FieldType::Class(Map::Create(isolate, 0), isolate); |
1136 | 1153 |
1137 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( | 1154 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
1138 Representation::Double(), any_type, Representation::HeapObject(), | 1155 {kMutable, Representation::Double(), any_type}, |
1139 value_type, Representation::Tagged(), any_type); | 1156 {kMutable, Representation::HeapObject(), value_type}, |
| 1157 {kMutable, Representation::Tagged(), any_type}); |
1140 } | 1158 } |
1141 | 1159 |
1142 | 1160 |
1143 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjToHeapObj) { | 1161 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjToHeapObj) { |
1144 CcTest::InitializeVM(); | 1162 CcTest::InitializeVM(); |
1145 v8::HandleScope scope(CcTest::isolate()); | 1163 v8::HandleScope scope(CcTest::isolate()); |
1146 Isolate* isolate = CcTest::i_isolate(); | 1164 Isolate* isolate = CcTest::i_isolate(); |
1147 Handle<FieldType> any_type = FieldType::Any(isolate); | 1165 Handle<FieldType> any_type = FieldType::Any(isolate); |
1148 | 1166 |
1149 Handle<FieldType> current_type = | 1167 Handle<FieldType> current_type = |
1150 FieldType::Class(Map::Create(isolate, 0), isolate); | 1168 FieldType::Class(Map::Create(isolate, 0), isolate); |
1151 | 1169 |
1152 Handle<FieldType> new_type = | 1170 Handle<FieldType> new_type = |
1153 FieldType::Class(Map::Create(isolate, 0), isolate); | 1171 FieldType::Class(Map::Create(isolate, 0), isolate); |
1154 | 1172 |
1155 Handle<FieldType> expected_type = any_type; | 1173 Handle<FieldType> expected_type = any_type; |
1156 | 1174 |
1157 TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( | 1175 TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( |
1158 Representation::HeapObject(), current_type, Representation::HeapObject(), | 1176 {kMutable, Representation::HeapObject(), current_type}, |
1159 new_type, Representation::HeapObject(), expected_type); | 1177 {kMutable, Representation::HeapObject(), new_type}, |
| 1178 {kMutable, Representation::HeapObject(), expected_type}); |
1160 current_type = expected_type; | 1179 current_type = expected_type; |
1161 | 1180 |
1162 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); | 1181 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); |
1163 | 1182 |
1164 TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( | 1183 TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial( |
1165 Representation::HeapObject(), any_type, Representation::HeapObject(), | 1184 {kMutable, Representation::HeapObject(), any_type}, |
1166 new_type, Representation::HeapObject(), any_type, false); | 1185 {kMutable, Representation::HeapObject(), new_type}, |
| 1186 {kMutable, Representation::HeapObject(), any_type}, false); |
1167 } | 1187 } |
1168 | 1188 |
1169 | 1189 |
1170 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjectToTagged) { | 1190 TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjectToTagged) { |
1171 CcTest::InitializeVM(); | 1191 CcTest::InitializeVM(); |
1172 v8::HandleScope scope(CcTest::isolate()); | 1192 v8::HandleScope scope(CcTest::isolate()); |
1173 Isolate* isolate = CcTest::i_isolate(); | 1193 Isolate* isolate = CcTest::i_isolate(); |
1174 Handle<FieldType> any_type = FieldType::Any(isolate); | 1194 Handle<FieldType> any_type = FieldType::Any(isolate); |
1175 Handle<FieldType> value_type = | 1195 Handle<FieldType> value_type = |
1176 FieldType::Class(Map::Create(isolate, 0), isolate); | 1196 FieldType::Class(Map::Create(isolate, 0), isolate); |
1177 | 1197 |
1178 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( | 1198 TestReconfigureDataFieldAttribute_GeneralizeRepresentation( |
1179 Representation::HeapObject(), value_type, Representation::Smi(), any_type, | 1199 {kMutable, Representation::HeapObject(), value_type}, |
1180 Representation::Tagged(), any_type); | 1200 {kMutable, Representation::Smi(), any_type}, |
| 1201 {kMutable, Representation::Tagged(), any_type}); |
1181 } | 1202 } |
1182 | 1203 |
1183 | 1204 |
1184 // Checks that given |map| is deprecated and that it updates to given |new_map| | 1205 // Checks that given |map| is deprecated and that it updates to given |new_map| |
1185 // which in turn should match expectations. | 1206 // which in turn should match expectations. |
1186 struct CheckDeprecated { | 1207 struct CheckDeprecated { |
1187 void Check(Handle<Map> map, Handle<Map> new_map, | 1208 void Check(Handle<Map> map, Handle<Map> new_map, |
1188 const Expectations& expectations) { | 1209 const Expectations& expectations) { |
1189 CHECK(map->is_deprecated()); | 1210 CHECK(map->is_deprecated()); |
1190 CHECK_NE(*map, *new_map); | 1211 CHECK_NE(*map, *new_map); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1270 TestConfig& config, Checker& checker) { | 1291 TestConfig& config, Checker& checker) { |
1271 Isolate* isolate = CcTest::i_isolate(); | 1292 Isolate* isolate = CcTest::i_isolate(); |
1272 Handle<FieldType> any_type = FieldType::Any(isolate); | 1293 Handle<FieldType> any_type = FieldType::Any(isolate); |
1273 | 1294 |
1274 const int kCustomPropIndex = kPropCount - 2; | 1295 const int kCustomPropIndex = kPropCount - 2; |
1275 Expectations expectations(isolate); | 1296 Expectations expectations(isolate); |
1276 | 1297 |
1277 const int kSplitProp = 2; | 1298 const int kSplitProp = 2; |
1278 CHECK(kSplitProp < kCustomPropIndex); | 1299 CHECK(kSplitProp < kCustomPropIndex); |
1279 | 1300 |
| 1301 const PropertyConstness constness = kMutable; |
1280 const Representation representation = Representation::Smi(); | 1302 const Representation representation = Representation::Smi(); |
1281 | 1303 |
1282 // Create common part of transition tree. | 1304 // Create common part of transition tree. |
1283 Handle<Map> initial_map = Map::Create(isolate, 0); | 1305 Handle<Map> initial_map = Map::Create(isolate, 0); |
1284 Handle<Map> map = initial_map; | 1306 Handle<Map> map = initial_map; |
1285 for (int i = 0; i < kSplitProp; i++) { | 1307 for (int i = 0; i < kSplitProp; i++) { |
1286 map = expectations.AddDataField(map, NONE, representation, any_type); | 1308 map = expectations.AddDataField(map, NONE, constness, representation, |
| 1309 any_type); |
1287 } | 1310 } |
1288 CHECK(!map->is_deprecated()); | 1311 CHECK(!map->is_deprecated()); |
1289 CHECK(map->is_stable()); | 1312 CHECK(map->is_stable()); |
1290 CHECK(expectations.Check(*map)); | 1313 CHECK(expectations.Check(*map)); |
1291 | 1314 |
1292 | 1315 |
1293 // Create branch to |map1|. | 1316 // Create branch to |map1|. |
1294 Handle<Map> map1 = map; | 1317 Handle<Map> map1 = map; |
1295 Expectations expectations1 = expectations; | 1318 Expectations expectations1 = expectations; |
1296 for (int i = kSplitProp; i < kCustomPropIndex; i++) { | 1319 for (int i = kSplitProp; i < kCustomPropIndex; i++) { |
1297 map1 = expectations1.AddDataField(map1, NONE, representation, any_type); | 1320 map1 = expectations1.AddDataField(map1, NONE, constness, representation, |
| 1321 any_type); |
1298 } | 1322 } |
1299 map1 = config.AddPropertyAtBranch(1, expectations1, map1); | 1323 map1 = config.AddPropertyAtBranch(1, expectations1, map1); |
1300 for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { | 1324 for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { |
1301 map1 = expectations1.AddDataField(map1, NONE, representation, any_type); | 1325 map1 = expectations1.AddDataField(map1, NONE, constness, representation, |
| 1326 any_type); |
1302 } | 1327 } |
1303 CHECK(!map1->is_deprecated()); | 1328 CHECK(!map1->is_deprecated()); |
1304 CHECK(map1->is_stable()); | 1329 CHECK(map1->is_stable()); |
1305 CHECK(expectations1.Check(*map1)); | 1330 CHECK(expectations1.Check(*map1)); |
1306 | 1331 |
1307 | 1332 |
1308 // Create another branch in transition tree (property at index |kSplitProp| | 1333 // Create another branch in transition tree (property at index |kSplitProp| |
1309 // has different attributes), initialize expectations. | 1334 // has different attributes), initialize expectations. |
1310 Handle<Map> map2 = map; | 1335 Handle<Map> map2 = map; |
1311 Expectations expectations2 = expectations; | 1336 Expectations expectations2 = expectations; |
1312 map2 = expectations2.AddDataField(map2, READ_ONLY, representation, any_type); | 1337 map2 = expectations2.AddDataField(map2, READ_ONLY, constness, representation, |
| 1338 any_type); |
1313 for (int i = kSplitProp + 1; i < kCustomPropIndex; i++) { | 1339 for (int i = kSplitProp + 1; i < kCustomPropIndex; i++) { |
1314 map2 = expectations2.AddDataField(map2, NONE, representation, any_type); | 1340 map2 = expectations2.AddDataField(map2, NONE, constness, representation, |
| 1341 any_type); |
1315 } | 1342 } |
1316 map2 = config.AddPropertyAtBranch(2, expectations2, map2); | 1343 map2 = config.AddPropertyAtBranch(2, expectations2, map2); |
1317 for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { | 1344 for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { |
1318 map2 = expectations2.AddDataField(map2, NONE, representation, any_type); | 1345 map2 = expectations2.AddDataField(map2, NONE, constness, representation, |
| 1346 any_type); |
1319 } | 1347 } |
1320 CHECK(!map2->is_deprecated()); | 1348 CHECK(!map2->is_deprecated()); |
1321 CHECK(map2->is_stable()); | 1349 CHECK(map2->is_stable()); |
1322 CHECK(expectations2.Check(*map2)); | 1350 CHECK(expectations2.Check(*map2)); |
1323 | 1351 |
1324 | 1352 |
1325 // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which | 1353 // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which |
1326 // should generalize representations in |map1|. | 1354 // should generalize representations in |map1|. |
1327 Handle<Map> new_map = | 1355 Handle<Map> new_map = |
1328 Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); | 1356 Map::ReconfigureExistingProperty(map2, kSplitProp, kData, NONE); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 } | 1424 } |
1397 | 1425 |
1398 Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations, | 1426 Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations, |
1399 Handle<Map> map) { | 1427 Handle<Map> map) { |
1400 CHECK(branch_id == 1 || branch_id == 2); | 1428 CHECK(branch_id == 1 || branch_id == 2); |
1401 Handle<JSFunction> js_func = branch_id == 1 ? js_func1_ : js_func2_; | 1429 Handle<JSFunction> js_func = branch_id == 1 ? js_func1_ : js_func2_; |
1402 return expectations.AddDataConstant(map, NONE, js_func); | 1430 return expectations.AddDataConstant(map, NONE, js_func); |
1403 } | 1431 } |
1404 | 1432 |
1405 void UpdateExpectations(int property_index, Expectations& expectations) { | 1433 void UpdateExpectations(int property_index, Expectations& expectations) { |
1406 expectations.SetDataField(property_index, Representation::HeapObject(), | 1434 expectations.SetDataField(property_index, kMutable, |
1407 function_type_); | 1435 Representation::HeapObject(), function_type_); |
1408 } | 1436 } |
1409 }; | 1437 }; |
1410 | 1438 |
1411 TestConfig config; | 1439 TestConfig config; |
1412 // Two branches are "incompatible" so the |map1| should be deprecated. | 1440 // Two branches are "incompatible" so the |map1| should be deprecated. |
1413 CheckDeprecated checker; | 1441 CheckDeprecated checker; |
1414 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); | 1442 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
1415 } | 1443 } |
1416 | 1444 |
1417 | 1445 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 TestConfig() { pair_ = CreateAccessorPair(true, true); } | 1555 TestConfig() { pair_ = CreateAccessorPair(true, true); } |
1528 | 1556 |
1529 Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations, | 1557 Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations, |
1530 Handle<Map> map) { | 1558 Handle<Map> map) { |
1531 CHECK(branch_id == 1 || branch_id == 2); | 1559 CHECK(branch_id == 1 || branch_id == 2); |
1532 if (branch_id == 1) { | 1560 if (branch_id == 1) { |
1533 return expectations.AddAccessorConstant(map, NONE, pair_); | 1561 return expectations.AddAccessorConstant(map, NONE, pair_); |
1534 } else { | 1562 } else { |
1535 Isolate* isolate = CcTest::i_isolate(); | 1563 Isolate* isolate = CcTest::i_isolate(); |
1536 Handle<FieldType> any_type = FieldType::Any(isolate); | 1564 Handle<FieldType> any_type = FieldType::Any(isolate); |
1537 return expectations.AddDataField(map, NONE, Representation::Smi(), | 1565 return expectations.AddDataField(map, NONE, kMutable, |
1538 any_type); | 1566 Representation::Smi(), any_type); |
1539 } | 1567 } |
1540 } | 1568 } |
1541 | 1569 |
1542 void UpdateExpectations(int property_index, Expectations& expectations) {} | 1570 void UpdateExpectations(int property_index, Expectations& expectations) {} |
1543 }; | 1571 }; |
1544 | 1572 |
1545 TestConfig config; | 1573 TestConfig config; |
1546 // These are completely separate branches in transition tree. | 1574 // These are completely separate branches in transition tree. |
1547 CheckUnrelated checker; | 1575 CheckUnrelated checker; |
1548 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); | 1576 TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); |
1549 } | 1577 } |
1550 | 1578 |
1551 | 1579 |
1552 //////////////////////////////////////////////////////////////////////////////// | 1580 //////////////////////////////////////////////////////////////////////////////// |
1553 // A set of tests for elements kind reconfiguration case. | 1581 // A set of tests for elements kind reconfiguration case. |
1554 // | 1582 // |
1555 | 1583 |
1556 // This test ensures that representation/field type generalization is correctly | 1584 // This test ensures that representation/field type generalization is correctly |
1557 // propagated from one branch of transition tree (|map2) to another (|map|). | 1585 // propagated from one branch of transition tree (|map2) to another (|map|). |
1558 // | 1586 // |
1559 // + - p0 - p1 - p2A - p3 - p4: |map| | 1587 // + - p0 - p1 - p2A - p3 - p4: |map| |
1560 // | | 1588 // | |
1561 // ek | 1589 // ek |
1562 // | | 1590 // | |
1563 // {} - p0 - p1 - p2B - p3 - p4: |map2| | 1591 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
1564 // | 1592 // |
1565 // where "p2A" and "p2B" differ only in the representation/field type. | 1593 // where "p2A" and "p2B" differ only in the representation/field type. |
1566 // | 1594 // |
1567 static void TestReconfigureElementsKind_GeneralizeRepresentation( | 1595 static void TestReconfigureElementsKind_GeneralizeRepresentation( |
1568 Representation from_representation, Handle<FieldType> from_type, | 1596 const CRFTData& from, const CRFTData& to, const CRFTData& expected) { |
1569 Representation to_representation, Handle<FieldType> to_type, | |
1570 Representation expected_representation, Handle<FieldType> expected_type) { | |
1571 Isolate* isolate = CcTest::i_isolate(); | 1597 Isolate* isolate = CcTest::i_isolate(); |
1572 | 1598 |
1573 Expectations expectations(isolate, FAST_SMI_ELEMENTS); | 1599 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
1574 | 1600 |
1575 // Create a map, add required properties to it and initialize expectations. | 1601 // Create a map, add required properties to it and initialize expectations. |
1576 Handle<Map> initial_map = Map::Create(isolate, 0); | 1602 Handle<Map> initial_map = Map::Create(isolate, 0); |
1577 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); | 1603 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
1578 | 1604 |
1579 Handle<Map> map = initial_map; | 1605 Handle<Map> map = initial_map; |
1580 map = expectations.AsElementsKind(map, FAST_ELEMENTS); | 1606 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
1581 for (int i = 0; i < kPropCount; i++) { | 1607 for (int i = 0; i < kPropCount; i++) { |
1582 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1608 map = expectations.AddDataField(map, NONE, from.constness, |
| 1609 from.representation, from.type); |
1583 } | 1610 } |
1584 CHECK(!map->is_deprecated()); | 1611 CHECK(!map->is_deprecated()); |
1585 CHECK(map->is_stable()); | 1612 CHECK(map->is_stable()); |
1586 CHECK(expectations.Check(*map)); | 1613 CHECK(expectations.Check(*map)); |
1587 | 1614 |
1588 // Create another branch in transition tree (property at index |kDiffProp| | 1615 // Create another branch in transition tree (property at index |kDiffProp| |
1589 // has different representatio/field type), initialize expectations. | 1616 // has different representatio/field type), initialize expectations. |
1590 const int kDiffProp = kPropCount / 2; | 1617 const int kDiffProp = kPropCount / 2; |
1591 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); | 1618 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
1592 | 1619 |
1593 Handle<Map> map2 = initial_map; | 1620 Handle<Map> map2 = initial_map; |
1594 for (int i = 0; i < kPropCount; i++) { | 1621 for (int i = 0; i < kPropCount; i++) { |
1595 if (i == kDiffProp) { | 1622 if (i == kDiffProp) { |
1596 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); | 1623 map2 = expectations2.AddDataField(map2, NONE, to.constness, |
| 1624 to.representation, to.type); |
1597 } else { | 1625 } else { |
1598 map2 = expectations2.AddDataField(map2, NONE, from_representation, | 1626 map2 = expectations2.AddDataField(map2, NONE, from.constness, |
1599 from_type); | 1627 from.representation, from.type); |
1600 } | 1628 } |
1601 } | 1629 } |
1602 CHECK(!map2->is_deprecated()); | 1630 CHECK(!map2->is_deprecated()); |
1603 CHECK(map2->is_stable()); | 1631 CHECK(map2->is_stable()); |
1604 CHECK(expectations2.Check(*map2)); | 1632 CHECK(expectations2.Check(*map2)); |
1605 | 1633 |
1606 Zone zone(isolate->allocator(), ZONE_NAME); | 1634 Zone zone(isolate->allocator(), ZONE_NAME); |
1607 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); | 1635 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
1608 CompilationDependencies dependencies(isolate, &zone); | 1636 CompilationDependencies dependencies(isolate, &zone); |
1609 CHECK(!dependencies.HasAborted()); | 1637 CHECK(!dependencies.HasAborted()); |
1610 dependencies.AssumeFieldOwner(field_owner); | 1638 dependencies.AssumeFieldOwner(field_owner); |
1611 | 1639 |
1612 // Reconfigure elements kinds of |map2|, which should generalize | 1640 // Reconfigure elements kinds of |map2|, which should generalize |
1613 // representations in |map|. | 1641 // representations in |map|. |
1614 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); | 1642 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
1615 | 1643 |
1616 // |map2| should be left unchanged but marked unstable. | 1644 // |map2| should be left unchanged but marked unstable. |
1617 CHECK(!map2->is_stable()); | 1645 CHECK(!map2->is_stable()); |
1618 CHECK(!map2->is_deprecated()); | 1646 CHECK(!map2->is_deprecated()); |
1619 CHECK_NE(*map2, *new_map); | 1647 CHECK_NE(*map2, *new_map); |
1620 CHECK(expectations2.Check(*map2)); | 1648 CHECK(expectations2.Check(*map2)); |
1621 | 1649 |
1622 // |map| should be deprecated and |new_map| should match new expectations. | 1650 // |map| should be deprecated and |new_map| should match new expectations. |
1623 expectations.SetDataField(kDiffProp, expected_representation, expected_type); | 1651 expectations.SetDataField(kDiffProp, expected.constness, |
| 1652 expected.representation, expected.type); |
1624 | 1653 |
1625 CHECK(map->is_deprecated()); | 1654 CHECK(map->is_deprecated()); |
1626 CHECK(!dependencies.HasAborted()); | 1655 CHECK(!dependencies.HasAborted()); |
1627 dependencies.Rollback(); // Properly cleanup compilation info. | 1656 dependencies.Rollback(); // Properly cleanup compilation info. |
1628 CHECK_NE(*map, *new_map); | 1657 CHECK_NE(*map, *new_map); |
1629 | 1658 |
1630 CHECK(!new_map->is_deprecated()); | 1659 CHECK(!new_map->is_deprecated()); |
1631 CHECK(expectations.Check(*new_map)); | 1660 CHECK(expectations.Check(*new_map)); |
1632 | 1661 |
1633 // Update deprecated |map|, it should become |new_map|. | 1662 // Update deprecated |map|, it should become |new_map|. |
(...skipping 16 matching lines...) Expand all Loading... |
1650 // | 1679 // |
1651 // + - p0 - p1 - p2A - p3 - p4: |map| | 1680 // + - p0 - p1 - p2A - p3 - p4: |map| |
1652 // | | 1681 // | |
1653 // ek | 1682 // ek |
1654 // | | 1683 // | |
1655 // {} - p0 - p1 - p2B - p3 - p4: |map2| | 1684 // {} - p0 - p1 - p2B - p3 - p4: |map2| |
1656 // | 1685 // |
1657 // where "p2A" and "p2B" differ only in the representation/field type. | 1686 // where "p2A" and "p2B" differ only in the representation/field type. |
1658 // | 1687 // |
1659 static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial( | 1688 static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
1660 Representation from_representation, Handle<FieldType> from_type, | 1689 const CRFTData& from, const CRFTData& to, const CRFTData& expected, |
1661 Representation to_representation, Handle<FieldType> to_type, | |
1662 Representation expected_representation, Handle<FieldType> expected_type, | |
1663 bool expected_field_type_dependency = true) { | 1690 bool expected_field_type_dependency = true) { |
1664 Isolate* isolate = CcTest::i_isolate(); | 1691 Isolate* isolate = CcTest::i_isolate(); |
1665 | 1692 |
1666 Expectations expectations(isolate, FAST_SMI_ELEMENTS); | 1693 Expectations expectations(isolate, FAST_SMI_ELEMENTS); |
1667 | 1694 |
1668 // Create a map, add required properties to it and initialize expectations. | 1695 // Create a map, add required properties to it and initialize expectations. |
1669 Handle<Map> initial_map = Map::Create(isolate, 0); | 1696 Handle<Map> initial_map = Map::Create(isolate, 0); |
1670 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); | 1697 initial_map->set_elements_kind(FAST_SMI_ELEMENTS); |
1671 | 1698 |
1672 Handle<Map> map = initial_map; | 1699 Handle<Map> map = initial_map; |
1673 map = expectations.AsElementsKind(map, FAST_ELEMENTS); | 1700 map = expectations.AsElementsKind(map, FAST_ELEMENTS); |
1674 for (int i = 0; i < kPropCount; i++) { | 1701 for (int i = 0; i < kPropCount; i++) { |
1675 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1702 map = expectations.AddDataField(map, NONE, from.constness, |
| 1703 from.representation, from.type); |
1676 } | 1704 } |
1677 CHECK(!map->is_deprecated()); | 1705 CHECK(!map->is_deprecated()); |
1678 CHECK(map->is_stable()); | 1706 CHECK(map->is_stable()); |
1679 CHECK(expectations.Check(*map)); | 1707 CHECK(expectations.Check(*map)); |
1680 | 1708 |
1681 // Create another branch in transition tree (property at index |kDiffProp| | 1709 // Create another branch in transition tree (property at index |kDiffProp| |
1682 // has different attributes), initialize expectations. | 1710 // has different attributes), initialize expectations. |
1683 const int kDiffProp = kPropCount / 2; | 1711 const int kDiffProp = kPropCount / 2; |
1684 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); | 1712 Expectations expectations2(isolate, FAST_SMI_ELEMENTS); |
1685 | 1713 |
1686 Handle<Map> map2 = initial_map; | 1714 Handle<Map> map2 = initial_map; |
1687 for (int i = 0; i < kPropCount; i++) { | 1715 for (int i = 0; i < kPropCount; i++) { |
1688 if (i == kDiffProp) { | 1716 if (i == kDiffProp) { |
1689 map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type); | 1717 map2 = expectations2.AddDataField(map2, NONE, to.constness, |
| 1718 to.representation, to.type); |
1690 } else { | 1719 } else { |
1691 map2 = expectations2.AddDataField(map2, NONE, from_representation, | 1720 map2 = expectations2.AddDataField(map2, NONE, from.constness, |
1692 from_type); | 1721 from.representation, from.type); |
1693 } | 1722 } |
1694 } | 1723 } |
1695 CHECK(!map2->is_deprecated()); | 1724 CHECK(!map2->is_deprecated()); |
1696 CHECK(map2->is_stable()); | 1725 CHECK(map2->is_stable()); |
1697 CHECK(expectations2.Check(*map2)); | 1726 CHECK(expectations2.Check(*map2)); |
1698 | 1727 |
1699 Zone zone(isolate->allocator(), ZONE_NAME); | 1728 Zone zone(isolate->allocator(), ZONE_NAME); |
1700 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); | 1729 Handle<Map> field_owner(map->FindFieldOwner(kDiffProp), isolate); |
1701 CompilationDependencies dependencies(isolate, &zone); | 1730 CompilationDependencies dependencies(isolate, &zone); |
1702 CHECK(!dependencies.HasAborted()); | 1731 CHECK(!dependencies.HasAborted()); |
1703 dependencies.AssumeFieldOwner(field_owner); | 1732 dependencies.AssumeFieldOwner(field_owner); |
1704 | 1733 |
1705 // Reconfigure elements kinds of |map2|, which should generalize | 1734 // Reconfigure elements kinds of |map2|, which should generalize |
1706 // representations in |map|. | 1735 // representations in |map|. |
1707 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); | 1736 Handle<Map> new_map = Map::ReconfigureElementsKind(map2, FAST_ELEMENTS); |
1708 | 1737 |
1709 // |map2| should be left unchanged but marked unstable. | 1738 // |map2| should be left unchanged but marked unstable. |
1710 CHECK(!map2->is_stable()); | 1739 CHECK(!map2->is_stable()); |
1711 CHECK(!map2->is_deprecated()); | 1740 CHECK(!map2->is_deprecated()); |
1712 CHECK_NE(*map2, *new_map); | 1741 CHECK_NE(*map2, *new_map); |
1713 CHECK(expectations2.Check(*map2)); | 1742 CHECK(expectations2.Check(*map2)); |
1714 | 1743 |
1715 // In trivial case |map| should be returned as a result of the elements | 1744 // In trivial case |map| should be returned as a result of the elements |
1716 // kind reconfiguration, respective field types should be generalized and | 1745 // kind reconfiguration, respective field types should be generalized and |
1717 // respective code dependencies should be invalidated. |map| should be NOT | 1746 // respective code dependencies should be invalidated. |map| should be NOT |
1718 // deprecated and it should match new expectations. | 1747 // deprecated and it should match new expectations. |
1719 expectations.SetDataField(kDiffProp, expected_representation, expected_type); | 1748 expectations.SetDataField(kDiffProp, expected.constness, |
| 1749 expected.representation, expected.type); |
1720 CHECK(!map->is_deprecated()); | 1750 CHECK(!map->is_deprecated()); |
1721 CHECK_EQ(*map, *new_map); | 1751 CHECK_EQ(*map, *new_map); |
1722 CHECK_EQ(expected_field_type_dependency, dependencies.HasAborted()); | 1752 CHECK_EQ(expected_field_type_dependency, dependencies.HasAborted()); |
1723 dependencies.Rollback(); // Properly cleanup compilation info. | 1753 dependencies.Rollback(); // Properly cleanup compilation info. |
1724 | 1754 |
1725 CHECK(!new_map->is_deprecated()); | 1755 CHECK(!new_map->is_deprecated()); |
1726 CHECK(expectations.Check(*new_map)); | 1756 CHECK(expectations.Check(*new_map)); |
1727 | 1757 |
1728 Handle<Map> updated_map = Map::Update(map); | 1758 Handle<Map> updated_map = Map::Update(map); |
1729 CHECK_EQ(*new_map, *updated_map); | 1759 CHECK_EQ(*new_map, *updated_map); |
1730 | 1760 |
1731 // Ensure Map::FindElementsKindTransitionedMap() is able to find the | 1761 // Ensure Map::FindElementsKindTransitionedMap() is able to find the |
1732 // transitioned map. | 1762 // transitioned map. |
1733 { | 1763 { |
1734 MapHandleList map_list; | 1764 MapHandleList map_list; |
1735 map_list.Add(updated_map); | 1765 map_list.Add(updated_map); |
1736 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); | 1766 Map* transitioned_map = map2->FindElementsKindTransitionedMap(&map_list); |
1737 CHECK_EQ(*updated_map, transitioned_map); | 1767 CHECK_EQ(*updated_map, transitioned_map); |
1738 } | 1768 } |
1739 } | 1769 } |
1740 | 1770 |
1741 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) { | 1771 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) { |
1742 CcTest::InitializeVM(); | 1772 CcTest::InitializeVM(); |
1743 v8::HandleScope scope(CcTest::isolate()); | 1773 v8::HandleScope scope(CcTest::isolate()); |
1744 Isolate* isolate = CcTest::i_isolate(); | 1774 Isolate* isolate = CcTest::i_isolate(); |
1745 Handle<FieldType> any_type = FieldType::Any(isolate); | 1775 Handle<FieldType> any_type = FieldType::Any(isolate); |
1746 | 1776 |
1747 TestReconfigureElementsKind_GeneralizeRepresentation( | 1777 TestReconfigureElementsKind_GeneralizeRepresentation( |
1748 Representation::Smi(), any_type, Representation::Double(), any_type, | 1778 {kMutable, Representation::Smi(), any_type}, |
1749 Representation::Double(), any_type); | 1779 {kMutable, Representation::Double(), any_type}, |
| 1780 {kMutable, Representation::Double(), any_type}); |
1750 } | 1781 } |
1751 | 1782 |
1752 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) { | 1783 TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) { |
1753 CcTest::InitializeVM(); | 1784 CcTest::InitializeVM(); |
1754 v8::HandleScope scope(CcTest::isolate()); | 1785 v8::HandleScope scope(CcTest::isolate()); |
1755 Isolate* isolate = CcTest::i_isolate(); | 1786 Isolate* isolate = CcTest::i_isolate(); |
1756 Handle<FieldType> any_type = FieldType::Any(isolate); | 1787 Handle<FieldType> any_type = FieldType::Any(isolate); |
1757 Handle<FieldType> value_type = | 1788 Handle<FieldType> value_type = |
1758 FieldType::Class(Map::Create(isolate, 0), isolate); | 1789 FieldType::Class(Map::Create(isolate, 0), isolate); |
1759 | 1790 |
1760 TestReconfigureElementsKind_GeneralizeRepresentation( | 1791 TestReconfigureElementsKind_GeneralizeRepresentation( |
1761 Representation::Smi(), any_type, Representation::HeapObject(), value_type, | 1792 {kMutable, Representation::Smi(), any_type}, |
1762 Representation::Tagged(), any_type); | 1793 {kMutable, Representation::HeapObject(), value_type}, |
| 1794 {kMutable, Representation::Tagged(), any_type}); |
1763 } | 1795 } |
1764 | 1796 |
1765 TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) { | 1797 TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) { |
1766 CcTest::InitializeVM(); | 1798 CcTest::InitializeVM(); |
1767 v8::HandleScope scope(CcTest::isolate()); | 1799 v8::HandleScope scope(CcTest::isolate()); |
1768 Isolate* isolate = CcTest::i_isolate(); | 1800 Isolate* isolate = CcTest::i_isolate(); |
1769 Handle<FieldType> any_type = FieldType::Any(isolate); | 1801 Handle<FieldType> any_type = FieldType::Any(isolate); |
1770 Handle<FieldType> value_type = | 1802 Handle<FieldType> value_type = |
1771 FieldType::Class(Map::Create(isolate, 0), isolate); | 1803 FieldType::Class(Map::Create(isolate, 0), isolate); |
1772 | 1804 |
1773 TestReconfigureElementsKind_GeneralizeRepresentation( | 1805 TestReconfigureElementsKind_GeneralizeRepresentation( |
1774 Representation::Double(), any_type, Representation::HeapObject(), | 1806 {kMutable, Representation::Double(), any_type}, |
1775 value_type, Representation::Tagged(), any_type); | 1807 {kMutable, Representation::HeapObject(), value_type}, |
| 1808 {kMutable, Representation::Tagged(), any_type}); |
1776 } | 1809 } |
1777 | 1810 |
1778 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) { | 1811 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) { |
1779 CcTest::InitializeVM(); | 1812 CcTest::InitializeVM(); |
1780 v8::HandleScope scope(CcTest::isolate()); | 1813 v8::HandleScope scope(CcTest::isolate()); |
1781 Isolate* isolate = CcTest::i_isolate(); | 1814 Isolate* isolate = CcTest::i_isolate(); |
1782 Handle<FieldType> any_type = FieldType::Any(isolate); | 1815 Handle<FieldType> any_type = FieldType::Any(isolate); |
1783 | 1816 |
1784 Handle<FieldType> current_type = | 1817 Handle<FieldType> current_type = |
1785 FieldType::Class(Map::Create(isolate, 0), isolate); | 1818 FieldType::Class(Map::Create(isolate, 0), isolate); |
1786 | 1819 |
1787 Handle<FieldType> new_type = | 1820 Handle<FieldType> new_type = |
1788 FieldType::Class(Map::Create(isolate, 0), isolate); | 1821 FieldType::Class(Map::Create(isolate, 0), isolate); |
1789 | 1822 |
1790 Handle<FieldType> expected_type = any_type; | 1823 Handle<FieldType> expected_type = any_type; |
1791 | 1824 |
1792 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( | 1825 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
1793 Representation::HeapObject(), current_type, Representation::HeapObject(), | 1826 {kMutable, Representation::HeapObject(), current_type}, |
1794 new_type, Representation::HeapObject(), expected_type); | 1827 {kMutable, Representation::HeapObject(), new_type}, |
| 1828 {kMutable, Representation::HeapObject(), expected_type}); |
1795 current_type = expected_type; | 1829 current_type = expected_type; |
1796 | 1830 |
1797 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); | 1831 new_type = FieldType::Class(Map::Create(isolate, 0), isolate); |
1798 | 1832 |
1799 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( | 1833 TestReconfigureElementsKind_GeneralizeRepresentationTrivial( |
1800 Representation::HeapObject(), any_type, Representation::HeapObject(), | 1834 {kMutable, Representation::HeapObject(), any_type}, |
1801 new_type, Representation::HeapObject(), any_type, false); | 1835 {kMutable, Representation::HeapObject(), new_type}, |
| 1836 {kMutable, Representation::HeapObject(), any_type}, false); |
1802 } | 1837 } |
1803 | 1838 |
1804 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) { | 1839 TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) { |
1805 CcTest::InitializeVM(); | 1840 CcTest::InitializeVM(); |
1806 v8::HandleScope scope(CcTest::isolate()); | 1841 v8::HandleScope scope(CcTest::isolate()); |
1807 Isolate* isolate = CcTest::i_isolate(); | 1842 Isolate* isolate = CcTest::i_isolate(); |
1808 Handle<FieldType> any_type = FieldType::Any(isolate); | 1843 Handle<FieldType> any_type = FieldType::Any(isolate); |
1809 Handle<FieldType> value_type = | 1844 Handle<FieldType> value_type = |
1810 FieldType::Class(Map::Create(isolate, 0), isolate); | 1845 FieldType::Class(Map::Create(isolate, 0), isolate); |
1811 | 1846 |
1812 TestReconfigureElementsKind_GeneralizeRepresentation( | 1847 TestReconfigureElementsKind_GeneralizeRepresentation( |
1813 Representation::HeapObject(), value_type, Representation::Smi(), any_type, | 1848 {kMutable, Representation::HeapObject(), value_type}, |
1814 Representation::Tagged(), any_type); | 1849 {kMutable, Representation::Smi(), any_type}, |
| 1850 {kMutable, Representation::Tagged(), any_type}); |
1815 } | 1851 } |
1816 | 1852 |
1817 //////////////////////////////////////////////////////////////////////////////// | 1853 //////////////////////////////////////////////////////////////////////////////// |
1818 // A set of tests checking split map deprecation. | 1854 // A set of tests checking split map deprecation. |
1819 // | 1855 // |
1820 | 1856 |
1821 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { | 1857 TEST(ReconfigurePropertySplitMapTransitionsOverflow) { |
1822 CcTest::InitializeVM(); | 1858 CcTest::InitializeVM(); |
1823 v8::HandleScope scope(CcTest::isolate()); | 1859 v8::HandleScope scope(CcTest::isolate()); |
1824 Isolate* isolate = CcTest::i_isolate(); | 1860 Isolate* isolate = CcTest::i_isolate(); |
1825 Handle<FieldType> any_type = FieldType::Any(isolate); | 1861 Handle<FieldType> any_type = FieldType::Any(isolate); |
1826 | 1862 |
1827 Expectations expectations(isolate); | 1863 Expectations expectations(isolate); |
1828 | 1864 |
1829 // Create a map, add required properties to it and initialize expectations. | 1865 // Create a map, add required properties to it and initialize expectations. |
1830 Handle<Map> initial_map = Map::Create(isolate, 0); | 1866 Handle<Map> initial_map = Map::Create(isolate, 0); |
1831 Handle<Map> map = initial_map; | 1867 Handle<Map> map = initial_map; |
1832 for (int i = 0; i < kPropCount; i++) { | 1868 for (int i = 0; i < kPropCount; i++) { |
1833 map = expectations.AddDataField(map, NONE, Representation::Smi(), any_type); | 1869 map = expectations.AddDataField(map, NONE, kMutable, Representation::Smi(), |
| 1870 any_type); |
1834 } | 1871 } |
1835 CHECK(!map->is_deprecated()); | 1872 CHECK(!map->is_deprecated()); |
1836 CHECK(map->is_stable()); | 1873 CHECK(map->is_stable()); |
1837 | 1874 |
1838 // Generalize representation of property at index |kSplitProp|. | 1875 // Generalize representation of property at index |kSplitProp|. |
1839 const int kSplitProp = kPropCount / 2; | 1876 const int kSplitProp = kPropCount / 2; |
1840 Handle<Map> split_map; | 1877 Handle<Map> split_map; |
1841 Handle<Map> map2 = initial_map; | 1878 Handle<Map> map2 = initial_map; |
1842 { | 1879 { |
1843 for (int i = 0; i < kSplitProp + 1; i++) { | 1880 for (int i = 0; i < kSplitProp + 1; i++) { |
1844 if (i == kSplitProp) { | 1881 if (i == kSplitProp) { |
1845 split_map = map2; | 1882 split_map = map2; |
1846 } | 1883 } |
1847 | 1884 |
1848 Handle<String> name = MakeName("prop", i); | 1885 Handle<String> name = MakeName("prop", i); |
1849 Map* target = | 1886 Map* target = |
1850 TransitionArray::SearchTransition(*map2, kData, *name, NONE); | 1887 TransitionArray::SearchTransition(*map2, kData, *name, NONE); |
1851 CHECK(target != NULL); | 1888 CHECK(target != NULL); |
1852 map2 = handle(target); | 1889 map2 = handle(target); |
1853 } | 1890 } |
1854 | 1891 |
1855 map2 = Map::ReconfigureProperty(map2, kSplitProp, kData, NONE, | 1892 map2 = Map::ReconfigureProperty(map2, kSplitProp, kData, NONE, |
1856 Representation::Double(), any_type); | 1893 Representation::Double(), any_type); |
1857 expectations.SetDataField(kSplitProp, Representation::Double(), any_type); | 1894 expectations.SetDataField(kSplitProp, kMutable, Representation::Double(), |
| 1895 any_type); |
1858 | 1896 |
1859 CHECK(expectations.Check(*split_map, kSplitProp)); | 1897 CHECK(expectations.Check(*split_map, kSplitProp)); |
1860 CHECK(expectations.Check(*map2, kSplitProp + 1)); | 1898 CHECK(expectations.Check(*map2, kSplitProp + 1)); |
1861 } | 1899 } |
1862 | 1900 |
1863 // At this point |map| should be deprecated and disconnected from the | 1901 // At this point |map| should be deprecated and disconnected from the |
1864 // transition tree. | 1902 // transition tree. |
1865 CHECK(map->is_deprecated()); | 1903 CHECK(map->is_deprecated()); |
1866 CHECK(!split_map->is_deprecated()); | 1904 CHECK(!split_map->is_deprecated()); |
1867 CHECK(map2->is_stable()); | 1905 CHECK(map2->is_stable()); |
1868 CHECK(!map2->is_deprecated()); | 1906 CHECK(!map2->is_deprecated()); |
1869 | 1907 |
1870 // Fill in transition tree of |map2| so that it can't have more transitions. | 1908 // Fill in transition tree of |map2| so that it can't have more transitions. |
1871 for (int i = 0; i < TransitionArray::kMaxNumberOfTransitions; i++) { | 1909 for (int i = 0; i < TransitionArray::kMaxNumberOfTransitions; i++) { |
1872 CHECK(TransitionArray::CanHaveMoreTransitions(map2)); | 1910 CHECK(TransitionArray::CanHaveMoreTransitions(map2)); |
1873 Handle<String> name = MakeName("foo", i); | 1911 Handle<String> name = MakeName("foo", i); |
1874 Map::CopyWithField(map2, name, any_type, NONE, Representation::Smi(), | 1912 Map::CopyWithField(map2, name, any_type, NONE, Representation::Smi(), |
1875 INSERT_TRANSITION) | 1913 INSERT_TRANSITION) |
1876 .ToHandleChecked(); | 1914 .ToHandleChecked(); |
1877 } | 1915 } |
1878 CHECK(!TransitionArray::CanHaveMoreTransitions(map2)); | 1916 CHECK(!TransitionArray::CanHaveMoreTransitions(map2)); |
1879 | 1917 |
1880 // Try to update |map|, since there is no place for propX transition at |map2| | 1918 // Try to update |map|, since there is no place for propX transition at |map2| |
1881 // |map| should become "copy-generalized". | 1919 // |map| should become "copy-generalized". |
1882 Handle<Map> updated_map = Map::Update(map); | 1920 Handle<Map> updated_map = Map::Update(map); |
1883 CHECK(updated_map->GetBackPointer()->IsUndefined(isolate)); | 1921 CHECK(updated_map->GetBackPointer()->IsUndefined(isolate)); |
1884 | 1922 |
1885 for (int i = 0; i < kPropCount; i++) { | 1923 for (int i = 0; i < kPropCount; i++) { |
1886 expectations.SetDataField(i, Representation::Tagged(), any_type); | 1924 expectations.SetDataField(i, kMutable, Representation::Tagged(), any_type); |
1887 } | 1925 } |
1888 CHECK(expectations.Check(*updated_map)); | 1926 CHECK(expectations.Check(*updated_map)); |
1889 } | 1927 } |
1890 | 1928 |
1891 | 1929 |
1892 //////////////////////////////////////////////////////////////////////////////// | 1930 //////////////////////////////////////////////////////////////////////////////// |
1893 // A set of tests involving special transitions (such as elements kind | 1931 // A set of tests involving special transitions (such as elements kind |
1894 // transition, observed transition or prototype transition). | 1932 // transition, observed transition or prototype transition). |
1895 // | 1933 // |
1896 | 1934 |
1897 // This test ensures that representation/field type generalization is correctly | 1935 // This test ensures that representation/field type generalization is correctly |
1898 // propagated from one branch of transition tree (|map2|) to another (|map|). | 1936 // propagated from one branch of transition tree (|map2|) to another (|map|). |
1899 // | 1937 // |
1900 // p4B: |map2| | 1938 // p4B: |map2| |
1901 // | | 1939 // | |
1902 // * - special transition | 1940 // * - special transition |
1903 // | | 1941 // | |
1904 // {} - p0 - p1 - p2A - p3 - p4A: |map| | 1942 // {} - p0 - p1 - p2A - p3 - p4A: |map| |
1905 // | 1943 // |
1906 // where "p4A" and "p4B" are exactly the same properties. | 1944 // where "p4A" and "p4B" are exactly the same properties. |
1907 // | 1945 // |
1908 // TODO(ishell): unify this test template with | 1946 // TODO(ishell): unify this test template with |
1909 // TestReconfigureDataFieldAttribute_GeneralizeRepresentation once | 1947 // TestReconfigureDataFieldAttribute_GeneralizeRepresentation once |
1910 // IS_PROTO_TRANS_ISSUE_FIXED and IS_NON_EQUIVALENT_TRANSITION_SUPPORTED are | 1948 // IS_PROTO_TRANS_ISSUE_FIXED and IS_NON_EQUIVALENT_TRANSITION_SUPPORTED are |
1911 // fixed. | 1949 // fixed. |
1912 template <typename TestConfig> | 1950 template <typename TestConfig> |
1913 static void TestGeneralizeRepresentationWithSpecialTransition( | 1951 static void TestGeneralizeRepresentationWithSpecialTransition( |
1914 TestConfig& config, Representation from_representation, | 1952 TestConfig& config, const CRFTData& from, const CRFTData& to, |
1915 Handle<FieldType> from_type, Representation to_representation, | 1953 const CRFTData& expected) { |
1916 Handle<FieldType> to_type, Representation expected_representation, | |
1917 Handle<FieldType> expected_type) { | |
1918 Isolate* isolate = CcTest::i_isolate(); | 1954 Isolate* isolate = CcTest::i_isolate(); |
1919 | 1955 |
1920 Expectations expectations(isolate); | 1956 Expectations expectations(isolate); |
1921 | 1957 |
1922 // Create a map, add required properties to it and initialize expectations. | 1958 // Create a map, add required properties to it and initialize expectations. |
1923 Handle<Map> initial_map = Map::Create(isolate, 0); | 1959 Handle<Map> initial_map = Map::Create(isolate, 0); |
1924 Handle<Map> map = initial_map; | 1960 Handle<Map> map = initial_map; |
1925 for (int i = 0; i < kPropCount; i++) { | 1961 for (int i = 0; i < kPropCount; i++) { |
1926 map = expectations.AddDataField(map, NONE, from_representation, from_type); | 1962 map = expectations.AddDataField(map, NONE, from.constness, |
| 1963 from.representation, from.type); |
1927 } | 1964 } |
1928 CHECK(!map->is_deprecated()); | 1965 CHECK(!map->is_deprecated()); |
1929 CHECK(map->is_stable()); | 1966 CHECK(map->is_stable()); |
1930 CHECK(expectations.Check(*map)); | 1967 CHECK(expectations.Check(*map)); |
1931 | 1968 |
1932 Expectations expectations2 = expectations; | 1969 Expectations expectations2 = expectations; |
1933 | 1970 |
1934 // Apply some special transition to |map|. | 1971 // Apply some special transition to |map|. |
1935 CHECK(map->owns_descriptors()); | 1972 CHECK(map->owns_descriptors()); |
1936 Handle<Map> map2 = config.Transition(map, expectations2); | 1973 Handle<Map> map2 = config.Transition(map, expectations2); |
1937 | 1974 |
1938 // |map| should still match expectations. | 1975 // |map| should still match expectations. |
1939 CHECK(!map->is_deprecated()); | 1976 CHECK(!map->is_deprecated()); |
1940 CHECK(expectations.Check(*map)); | 1977 CHECK(expectations.Check(*map)); |
1941 | 1978 |
1942 if (config.generalizes_representations()) { | 1979 if (config.generalizes_representations()) { |
1943 for (int i = 0; i < kPropCount; i++) { | 1980 for (int i = 0; i < kPropCount; i++) { |
1944 expectations2.GeneralizeRepresentation(i); | 1981 expectations2.GeneralizeRepresentation(i); |
1945 } | 1982 } |
1946 } | 1983 } |
1947 | 1984 |
1948 CHECK(!map2->is_deprecated()); | 1985 CHECK(!map2->is_deprecated()); |
1949 CHECK(map2->is_stable()); | 1986 CHECK(map2->is_stable()); |
1950 CHECK(expectations2.Check(*map2)); | 1987 CHECK(expectations2.Check(*map2)); |
1951 | 1988 |
1952 // Create new maps by generalizing representation of propX field. | 1989 // Create new maps by generalizing representation of propX field. |
1953 Handle<Map> maps[kPropCount]; | 1990 Handle<Map> maps[kPropCount]; |
1954 for (int i = 0; i < kPropCount; i++) { | 1991 for (int i = 0; i < kPropCount; i++) { |
1955 Handle<Map> new_map = Map::ReconfigureProperty(map, i, kData, NONE, | 1992 Handle<Map> new_map = Map::ReconfigureProperty(map, i, kData, NONE, |
1956 to_representation, to_type); | 1993 to.representation, to.type); |
1957 maps[i] = new_map; | 1994 maps[i] = new_map; |
1958 | 1995 |
1959 expectations.SetDataField(i, expected_representation, expected_type); | 1996 expectations.SetDataField(i, expected.constness, expected.representation, |
| 1997 expected.type); |
1960 | 1998 |
1961 CHECK(map->is_deprecated()); | 1999 CHECK(map->is_deprecated()); |
1962 CHECK_NE(*map, *new_map); | 2000 CHECK_NE(*map, *new_map); |
1963 CHECK(i == 0 || maps[i - 1]->is_deprecated()); | 2001 CHECK(i == 0 || maps[i - 1]->is_deprecated()); |
1964 CHECK(expectations.Check(*new_map)); | 2002 CHECK(expectations.Check(*new_map)); |
1965 | 2003 |
1966 Handle<Map> new_map2 = Map::Update(map2); | 2004 Handle<Map> new_map2 = Map::Update(map2); |
1967 CHECK(!new_map2->is_deprecated()); | 2005 CHECK(!new_map2->is_deprecated()); |
1968 CHECK(!new_map2->is_dictionary_map()); | 2006 CHECK(!new_map2->is_dictionary_map()); |
1969 | 2007 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2015 expectations.SetElementsKind(DICTIONARY_ELEMENTS); | 2053 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
2016 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, | 2054 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
2017 "CopyForPreventExtensions"); | 2055 "CopyForPreventExtensions"); |
2018 } | 2056 } |
2019 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2057 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
2020 bool generalizes_representations() const { return false; } | 2058 bool generalizes_representations() const { return false; } |
2021 bool is_non_equevalent_transition() const { return true; } | 2059 bool is_non_equevalent_transition() const { return true; } |
2022 }; | 2060 }; |
2023 TestConfig config; | 2061 TestConfig config; |
2024 TestGeneralizeRepresentationWithSpecialTransition( | 2062 TestGeneralizeRepresentationWithSpecialTransition( |
2025 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2063 config, {kMutable, Representation::Smi(), any_type}, |
2026 value_type, Representation::Tagged(), any_type); | 2064 {kMutable, Representation::HeapObject(), value_type}, |
| 2065 {kMutable, Representation::Tagged(), any_type}); |
2027 } | 2066 } |
2028 | 2067 |
2029 | 2068 |
2030 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { | 2069 TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { |
2031 CcTest::InitializeVM(); | 2070 CcTest::InitializeVM(); |
2032 v8::HandleScope scope(CcTest::isolate()); | 2071 v8::HandleScope scope(CcTest::isolate()); |
2033 Isolate* isolate = CcTest::i_isolate(); | 2072 Isolate* isolate = CcTest::i_isolate(); |
2034 Handle<FieldType> any_type = FieldType::Any(isolate); | 2073 Handle<FieldType> any_type = FieldType::Any(isolate); |
2035 Handle<FieldType> value_type = | 2074 Handle<FieldType> value_type = |
2036 FieldType::Class(Map::Create(isolate, 0), isolate); | 2075 FieldType::Class(Map::Create(isolate, 0), isolate); |
(...skipping 15 matching lines...) Expand all Loading... |
2052 expectations.SetElementsKind(DICTIONARY_ELEMENTS); | 2091 expectations.SetElementsKind(DICTIONARY_ELEMENTS); |
2053 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, | 2092 return Map::CopyForPreventExtensions(map, NONE, frozen_symbol, |
2054 "CopyForPreventExtensions"); | 2093 "CopyForPreventExtensions"); |
2055 } | 2094 } |
2056 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2095 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
2057 bool generalizes_representations() const { return false; } | 2096 bool generalizes_representations() const { return false; } |
2058 bool is_non_equevalent_transition() const { return true; } | 2097 bool is_non_equevalent_transition() const { return true; } |
2059 }; | 2098 }; |
2060 TestConfig config; | 2099 TestConfig config; |
2061 TestGeneralizeRepresentationWithSpecialTransition( | 2100 TestGeneralizeRepresentationWithSpecialTransition( |
2062 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2101 config, {kMutable, Representation::Smi(), any_type}, |
2063 value_type, Representation::Tagged(), any_type); | 2102 {kMutable, Representation::HeapObject(), value_type}, |
| 2103 {kMutable, Representation::Tagged(), any_type}); |
2064 } | 2104 } |
2065 | 2105 |
2066 | 2106 |
2067 TEST(PrototypeTransitionFromMapOwningDescriptor) { | 2107 TEST(PrototypeTransitionFromMapOwningDescriptor) { |
2068 CcTest::InitializeVM(); | 2108 CcTest::InitializeVM(); |
2069 v8::HandleScope scope(CcTest::isolate()); | 2109 v8::HandleScope scope(CcTest::isolate()); |
2070 Isolate* isolate = CcTest::i_isolate(); | 2110 Isolate* isolate = CcTest::i_isolate(); |
2071 | 2111 |
2072 Handle<FieldType> any_type = FieldType::Any(isolate); | 2112 Handle<FieldType> any_type = FieldType::Any(isolate); |
2073 Handle<FieldType> value_type = | 2113 Handle<FieldType> value_type = |
(...skipping 12 matching lines...) Expand all Loading... |
2086 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 2126 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
2087 } | 2127 } |
2088 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2128 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
2089 bool generalizes_representations() const { | 2129 bool generalizes_representations() const { |
2090 return !IS_PROTO_TRANS_ISSUE_FIXED; | 2130 return !IS_PROTO_TRANS_ISSUE_FIXED; |
2091 } | 2131 } |
2092 bool is_non_equevalent_transition() const { return true; } | 2132 bool is_non_equevalent_transition() const { return true; } |
2093 }; | 2133 }; |
2094 TestConfig config; | 2134 TestConfig config; |
2095 TestGeneralizeRepresentationWithSpecialTransition( | 2135 TestGeneralizeRepresentationWithSpecialTransition( |
2096 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2136 config, {kMutable, Representation::Smi(), any_type}, |
2097 value_type, Representation::Tagged(), any_type); | 2137 {kMutable, Representation::HeapObject(), value_type}, |
| 2138 {kMutable, Representation::Tagged(), any_type}); |
2098 } | 2139 } |
2099 | 2140 |
2100 | 2141 |
2101 TEST(PrototypeTransitionFromMapNotOwningDescriptor) { | 2142 TEST(PrototypeTransitionFromMapNotOwningDescriptor) { |
2102 CcTest::InitializeVM(); | 2143 CcTest::InitializeVM(); |
2103 v8::HandleScope scope(CcTest::isolate()); | 2144 v8::HandleScope scope(CcTest::isolate()); |
2104 Isolate* isolate = CcTest::i_isolate(); | 2145 Isolate* isolate = CcTest::i_isolate(); |
2105 | 2146 |
2106 Handle<FieldType> any_type = FieldType::Any(isolate); | 2147 Handle<FieldType> any_type = FieldType::Any(isolate); |
2107 Handle<FieldType> value_type = | 2148 Handle<FieldType> value_type = |
(...skipping 23 matching lines...) Expand all Loading... |
2131 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); | 2172 return Map::TransitionToPrototype(map, prototype_, REGULAR_PROTOTYPE); |
2132 } | 2173 } |
2133 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. | 2174 // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. |
2134 bool generalizes_representations() const { | 2175 bool generalizes_representations() const { |
2135 return !IS_PROTO_TRANS_ISSUE_FIXED; | 2176 return !IS_PROTO_TRANS_ISSUE_FIXED; |
2136 } | 2177 } |
2137 bool is_non_equevalent_transition() const { return true; } | 2178 bool is_non_equevalent_transition() const { return true; } |
2138 }; | 2179 }; |
2139 TestConfig config; | 2180 TestConfig config; |
2140 TestGeneralizeRepresentationWithSpecialTransition( | 2181 TestGeneralizeRepresentationWithSpecialTransition( |
2141 config, Representation::Smi(), any_type, Representation::HeapObject(), | 2182 config, {kMutable, Representation::Smi(), any_type}, |
2142 value_type, Representation::Tagged(), any_type); | 2183 {kMutable, Representation::HeapObject(), value_type}, |
| 2184 {kMutable, Representation::Tagged(), any_type}); |
2143 } | 2185 } |
2144 | 2186 |
2145 | 2187 |
2146 //////////////////////////////////////////////////////////////////////////////// | 2188 //////////////////////////////////////////////////////////////////////////////// |
2147 // A set of tests for higher level transitioning mechanics. | 2189 // A set of tests for higher level transitioning mechanics. |
2148 // | 2190 // |
2149 | 2191 |
2150 struct TransitionToDataFieldOperator { | 2192 struct TransitionToDataFieldOperator { |
| 2193 PropertyConstness constness_; |
2151 Representation representation_; | 2194 Representation representation_; |
2152 PropertyAttributes attributes_; | 2195 PropertyAttributes attributes_; |
2153 Handle<FieldType> heap_type_; | 2196 Handle<FieldType> heap_type_; |
2154 Handle<Object> value_; | 2197 Handle<Object> value_; |
2155 | 2198 |
2156 TransitionToDataFieldOperator(Representation representation, | 2199 TransitionToDataFieldOperator(PropertyConstness constness, |
| 2200 Representation representation, |
2157 Handle<FieldType> heap_type, | 2201 Handle<FieldType> heap_type, |
2158 Handle<Object> value, | 2202 Handle<Object> value, |
2159 PropertyAttributes attributes = NONE) | 2203 PropertyAttributes attributes = NONE) |
2160 : representation_(representation), | 2204 : constness_(constness), |
| 2205 representation_(representation), |
2161 attributes_(attributes), | 2206 attributes_(attributes), |
2162 heap_type_(heap_type), | 2207 heap_type_(heap_type), |
2163 value_(value) {} | 2208 value_(value) {} |
2164 | 2209 |
2165 Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { | 2210 Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { |
2166 return expectations.TransitionToDataField(map, attributes_, representation_, | 2211 return expectations.TransitionToDataField( |
2167 heap_type_, value_); | 2212 map, attributes_, constness_, representation_, heap_type_, value_); |
2168 } | 2213 } |
2169 }; | 2214 }; |
2170 | 2215 |
2171 | 2216 |
2172 struct TransitionToDataConstantOperator { | 2217 struct TransitionToDataConstantOperator { |
2173 PropertyAttributes attributes_; | 2218 PropertyAttributes attributes_; |
2174 Handle<JSFunction> value_; | 2219 Handle<JSFunction> value_; |
2175 | 2220 |
2176 TransitionToDataConstantOperator(Handle<JSFunction> value, | 2221 TransitionToDataConstantOperator(Handle<JSFunction> value, |
2177 PropertyAttributes attributes = NONE) | 2222 PropertyAttributes attributes = NONE) |
(...skipping 28 matching lines...) Expand all Loading... |
2206 ReconfigureAsDataPropertyOperator(int descriptor, | 2251 ReconfigureAsDataPropertyOperator(int descriptor, |
2207 Representation representation, | 2252 Representation representation, |
2208 Handle<FieldType> heap_type, | 2253 Handle<FieldType> heap_type, |
2209 PropertyAttributes attributes = NONE) | 2254 PropertyAttributes attributes = NONE) |
2210 : descriptor_(descriptor), | 2255 : descriptor_(descriptor), |
2211 representation_(representation), | 2256 representation_(representation), |
2212 attributes_(attributes), | 2257 attributes_(attributes), |
2213 heap_type_(heap_type) {} | 2258 heap_type_(heap_type) {} |
2214 | 2259 |
2215 Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { | 2260 Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { |
2216 expectations.SetDataField(descriptor_, representation_, heap_type_); | 2261 expectations.SetDataField(descriptor_, kMutable, representation_, |
| 2262 heap_type_); |
2217 return Map::ReconfigureExistingProperty(map, descriptor_, kData, | 2263 return Map::ReconfigureExistingProperty(map, descriptor_, kData, |
2218 attributes_); | 2264 attributes_); |
2219 } | 2265 } |
2220 }; | 2266 }; |
2221 | 2267 |
2222 | 2268 |
2223 struct ReconfigureAsAccessorPropertyOperator { | 2269 struct ReconfigureAsAccessorPropertyOperator { |
2224 int descriptor_; | 2270 int descriptor_; |
2225 PropertyAttributes attributes_; | 2271 PropertyAttributes attributes_; |
2226 | 2272 |
2227 ReconfigureAsAccessorPropertyOperator(int descriptor, | 2273 ReconfigureAsAccessorPropertyOperator(int descriptor, |
2228 PropertyAttributes attributes = NONE) | 2274 PropertyAttributes attributes = NONE) |
2229 : descriptor_(descriptor), attributes_(attributes) {} | 2275 : descriptor_(descriptor), attributes_(attributes) {} |
2230 | 2276 |
2231 Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { | 2277 Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { |
2232 expectations.SetAccessorField(descriptor_); | 2278 expectations.SetAccessorField(descriptor_); |
2233 return Map::ReconfigureExistingProperty(map, descriptor_, kAccessor, | 2279 return Map::ReconfigureExistingProperty(map, descriptor_, kAccessor, |
2234 attributes_); | 2280 attributes_); |
2235 } | 2281 } |
2236 }; | 2282 }; |
2237 | 2283 |
2238 | 2284 |
2239 // Checks that representation/field type generalization happened. | 2285 // Checks that representation/field type generalization happened. |
2240 struct FieldGeneralizationChecker { | 2286 struct FieldGeneralizationChecker { |
2241 int descriptor_; | 2287 int descriptor_; |
| 2288 PropertyConstness constness_; |
2242 Representation representation_; | 2289 Representation representation_; |
2243 PropertyAttributes attributes_; | 2290 PropertyAttributes attributes_; |
2244 Handle<FieldType> heap_type_; | 2291 Handle<FieldType> heap_type_; |
2245 | 2292 |
2246 FieldGeneralizationChecker(int descriptor, Representation representation, | 2293 FieldGeneralizationChecker(int descriptor, PropertyConstness constness, |
| 2294 Representation representation, |
2247 Handle<FieldType> heap_type, | 2295 Handle<FieldType> heap_type, |
2248 PropertyAttributes attributes = NONE) | 2296 PropertyAttributes attributes = NONE) |
2249 : descriptor_(descriptor), | 2297 : descriptor_(descriptor), |
| 2298 constness_(constness), |
2250 representation_(representation), | 2299 representation_(representation), |
2251 attributes_(attributes), | 2300 attributes_(attributes), |
2252 heap_type_(heap_type) {} | 2301 heap_type_(heap_type) {} |
2253 | 2302 |
2254 void Check(Expectations& expectations2, Handle<Map> map1, Handle<Map> map2) { | 2303 void Check(Expectations& expectations2, Handle<Map> map1, Handle<Map> map2) { |
2255 CHECK(!map2->is_deprecated()); | 2304 CHECK(!map2->is_deprecated()); |
2256 | 2305 |
2257 CHECK(map1->is_deprecated()); | 2306 CHECK(map1->is_deprecated()); |
2258 CHECK_NE(*map1, *map2); | 2307 CHECK_NE(*map1, *map2); |
2259 Handle<Map> updated_map = Map::Update(map1); | 2308 Handle<Map> updated_map = Map::Update(map1); |
2260 CHECK_EQ(*map2, *updated_map); | 2309 CHECK_EQ(*map2, *updated_map); |
2261 | 2310 |
2262 expectations2.SetDataField(descriptor_, attributes_, representation_, | 2311 expectations2.SetDataField(descriptor_, attributes_, constness_, |
2263 heap_type_); | 2312 representation_, heap_type_); |
2264 CHECK(expectations2.Check(*map2)); | 2313 CHECK(expectations2.Check(*map2)); |
2265 } | 2314 } |
2266 }; | 2315 }; |
2267 | 2316 |
2268 | 2317 |
2269 // Checks that existing transition was taken as is. | 2318 // Checks that existing transition was taken as is. |
2270 struct SameMapChecker { | 2319 struct SameMapChecker { |
2271 void Check(Expectations& expectations, Handle<Map> map1, Handle<Map> map2) { | 2320 void Check(Expectations& expectations, Handle<Map> map1, Handle<Map> map2) { |
2272 CHECK(!map2->is_deprecated()); | 2321 CHECK(!map2->is_deprecated()); |
2273 CHECK_EQ(*map1, *map2); | 2322 CHECK_EQ(*map1, *map2); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2308 TransitionOp2& transition_op2, Checker& checker) { | 2357 TransitionOp2& transition_op2, Checker& checker) { |
2309 Isolate* isolate = CcTest::i_isolate(); | 2358 Isolate* isolate = CcTest::i_isolate(); |
2310 Handle<FieldType> any_type = FieldType::Any(isolate); | 2359 Handle<FieldType> any_type = FieldType::Any(isolate); |
2311 | 2360 |
2312 Expectations expectations(isolate); | 2361 Expectations expectations(isolate); |
2313 | 2362 |
2314 // Create a map, add required properties to it and initialize expectations. | 2363 // Create a map, add required properties to it and initialize expectations. |
2315 Handle<Map> initial_map = Map::Create(isolate, 0); | 2364 Handle<Map> initial_map = Map::Create(isolate, 0); |
2316 Handle<Map> map = initial_map; | 2365 Handle<Map> map = initial_map; |
2317 for (int i = 0; i < kPropCount - 1; i++) { | 2366 for (int i = 0; i < kPropCount - 1; i++) { |
2318 map = expectations.AddDataField(map, NONE, Representation::Smi(), any_type); | 2367 map = expectations.AddDataField(map, NONE, kMutable, Representation::Smi(), |
| 2368 any_type); |
2319 } | 2369 } |
2320 CHECK(expectations.Check(*map)); | 2370 CHECK(expectations.Check(*map)); |
2321 | 2371 |
2322 Expectations expectations1 = expectations; | 2372 Expectations expectations1 = expectations; |
2323 Handle<Map> map1 = transition_op1.DoTransition(expectations1, map); | 2373 Handle<Map> map1 = transition_op1.DoTransition(expectations1, map); |
2324 CHECK(expectations1.Check(*map1)); | 2374 CHECK(expectations1.Check(*map1)); |
2325 | 2375 |
2326 Expectations expectations2 = expectations; | 2376 Expectations expectations2 = expectations; |
2327 Handle<Map> map2 = transition_op2.DoTransition(expectations2, map); | 2377 Handle<Map> map2 = transition_op2.DoTransition(expectations2, map); |
2328 | 2378 |
2329 // Let the test customization do the check. | 2379 // Let the test customization do the check. |
2330 checker.Check(expectations2, map1, map2); | 2380 checker.Check(expectations2, map1, map2); |
2331 } | 2381 } |
2332 | 2382 |
2333 | 2383 |
2334 TEST(TransitionDataFieldToDataField) { | 2384 TEST(TransitionDataFieldToDataField) { |
2335 CcTest::InitializeVM(); | 2385 CcTest::InitializeVM(); |
2336 v8::HandleScope scope(CcTest::isolate()); | 2386 v8::HandleScope scope(CcTest::isolate()); |
2337 Isolate* isolate = CcTest::i_isolate(); | 2387 Isolate* isolate = CcTest::i_isolate(); |
2338 Handle<FieldType> any_type = FieldType::Any(isolate); | 2388 Handle<FieldType> any_type = FieldType::Any(isolate); |
2339 | 2389 |
2340 Handle<Object> value1 = handle(Smi::kZero, isolate); | 2390 Handle<Object> value1 = handle(Smi::kZero, isolate); |
2341 TransitionToDataFieldOperator transition_op1(Representation::Smi(), any_type, | 2391 TransitionToDataFieldOperator transition_op1(kMutable, Representation::Smi(), |
2342 value1); | 2392 any_type, value1); |
2343 | 2393 |
2344 Handle<Object> value2 = isolate->factory()->NewHeapNumber(0); | 2394 Handle<Object> value2 = isolate->factory()->NewHeapNumber(0); |
2345 TransitionToDataFieldOperator transition_op2(Representation::Double(), | 2395 TransitionToDataFieldOperator transition_op2( |
2346 any_type, value2); | 2396 kMutable, Representation::Double(), any_type, value2); |
2347 | 2397 |
2348 FieldGeneralizationChecker checker(kPropCount - 1, Representation::Double(), | 2398 FieldGeneralizationChecker checker(kPropCount - 1, kMutable, |
2349 any_type); | 2399 Representation::Double(), any_type); |
2350 TestTransitionTo(transition_op1, transition_op2, checker); | 2400 TestTransitionTo(transition_op1, transition_op2, checker); |
2351 } | 2401 } |
2352 | 2402 |
2353 | 2403 |
2354 TEST(TransitionDataConstantToSameDataConstant) { | 2404 TEST(TransitionDataConstantToSameDataConstant) { |
2355 CcTest::InitializeVM(); | 2405 CcTest::InitializeVM(); |
2356 v8::HandleScope scope(CcTest::isolate()); | 2406 v8::HandleScope scope(CcTest::isolate()); |
2357 Isolate* isolate = CcTest::i_isolate(); | 2407 Isolate* isolate = CcTest::i_isolate(); |
2358 Factory* factory = isolate->factory(); | 2408 Factory* factory = isolate->factory(); |
2359 | 2409 |
(...skipping 20 matching lines...) Expand all Loading... |
2380 | 2430 |
2381 Handle<JSFunction> js_func1 = | 2431 Handle<JSFunction> js_func1 = |
2382 factory->NewFunction(sloppy_map, info, isolate->native_context()); | 2432 factory->NewFunction(sloppy_map, info, isolate->native_context()); |
2383 TransitionToDataConstantOperator transition_op1(js_func1); | 2433 TransitionToDataConstantOperator transition_op1(js_func1); |
2384 | 2434 |
2385 Handle<JSFunction> js_func2 = | 2435 Handle<JSFunction> js_func2 = |
2386 factory->NewFunction(sloppy_map, info, isolate->native_context()); | 2436 factory->NewFunction(sloppy_map, info, isolate->native_context()); |
2387 TransitionToDataConstantOperator transition_op2(js_func2); | 2437 TransitionToDataConstantOperator transition_op2(js_func2); |
2388 | 2438 |
2389 FieldGeneralizationChecker checker( | 2439 FieldGeneralizationChecker checker( |
2390 kPropCount - 1, Representation::HeapObject(), function_type); | 2440 kPropCount - 1, kMutable, Representation::HeapObject(), function_type); |
2391 TestTransitionTo(transition_op1, transition_op2, checker); | 2441 TestTransitionTo(transition_op1, transition_op2, checker); |
2392 } | 2442 } |
2393 | 2443 |
2394 | 2444 |
2395 TEST(TransitionDataConstantToDataField) { | 2445 TEST(TransitionDataConstantToDataField) { |
2396 CcTest::InitializeVM(); | 2446 CcTest::InitializeVM(); |
2397 v8::HandleScope scope(CcTest::isolate()); | 2447 v8::HandleScope scope(CcTest::isolate()); |
2398 Isolate* isolate = CcTest::i_isolate(); | 2448 Isolate* isolate = CcTest::i_isolate(); |
2399 Factory* factory = isolate->factory(); | 2449 Factory* factory = isolate->factory(); |
2400 Handle<FieldType> any_type = FieldType::Any(isolate); | 2450 Handle<FieldType> any_type = FieldType::Any(isolate); |
2401 | 2451 |
2402 Handle<JSFunction> js_func1 = factory->NewFunction(factory->empty_string()); | 2452 Handle<JSFunction> js_func1 = factory->NewFunction(factory->empty_string()); |
2403 TransitionToDataConstantOperator transition_op1(js_func1); | 2453 TransitionToDataConstantOperator transition_op1(js_func1); |
2404 | 2454 |
2405 Handle<Object> value2 = isolate->factory()->NewHeapNumber(0); | 2455 Handle<Object> value2 = isolate->factory()->NewHeapNumber(0); |
2406 TransitionToDataFieldOperator transition_op2(Representation::Double(), | 2456 TransitionToDataFieldOperator transition_op2( |
2407 any_type, value2); | 2457 kMutable, Representation::Double(), any_type, value2); |
2408 | 2458 |
2409 FieldGeneralizationChecker checker(kPropCount - 1, Representation::Tagged(), | 2459 FieldGeneralizationChecker checker(kPropCount - 1, kMutable, |
2410 any_type); | 2460 Representation::Tagged(), any_type); |
2411 TestTransitionTo(transition_op1, transition_op2, checker); | 2461 TestTransitionTo(transition_op1, transition_op2, checker); |
2412 } | 2462 } |
2413 | 2463 |
2414 | 2464 |
2415 TEST(TransitionAccessorConstantToSameAccessorConstant) { | 2465 TEST(TransitionAccessorConstantToSameAccessorConstant) { |
2416 CcTest::InitializeVM(); | 2466 CcTest::InitializeVM(); |
2417 v8::HandleScope scope(CcTest::isolate()); | 2467 v8::HandleScope scope(CcTest::isolate()); |
2418 | 2468 |
2419 Handle<AccessorPair> pair = CreateAccessorPair(true, true); | 2469 Handle<AccessorPair> pair = CreateAccessorPair(true, true); |
2420 TransitionToAccessorConstantOperator transition_op(pair); | 2470 TransitionToAccessorConstantOperator transition_op(pair); |
2421 | 2471 |
2422 SameMapChecker checker; | 2472 SameMapChecker checker; |
2423 TestTransitionTo(transition_op, transition_op, checker); | 2473 TestTransitionTo(transition_op, transition_op, checker); |
2424 } | 2474 } |
2425 | 2475 |
2426 TEST(FieldTypeConvertSimple) { | 2476 TEST(FieldTypeConvertSimple) { |
2427 CcTest::InitializeVM(); | 2477 CcTest::InitializeVM(); |
2428 v8::HandleScope scope(CcTest::isolate()); | 2478 v8::HandleScope scope(CcTest::isolate()); |
2429 Isolate* isolate = CcTest::i_isolate(); | 2479 Isolate* isolate = CcTest::i_isolate(); |
2430 | 2480 |
2431 Zone zone(isolate->allocator(), ZONE_NAME); | 2481 Zone zone(isolate->allocator(), ZONE_NAME); |
2432 | 2482 |
2433 CHECK_EQ(FieldType::Any()->Convert(&zone), AstType::NonInternal()); | 2483 CHECK_EQ(FieldType::Any()->Convert(&zone), AstType::NonInternal()); |
2434 CHECK_EQ(FieldType::None()->Convert(&zone), AstType::None()); | 2484 CHECK_EQ(FieldType::None()->Convert(&zone), AstType::None()); |
2435 } | 2485 } |
2436 | 2486 |
2437 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. | 2487 // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. |
2438 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) | 2488 // TEST(TransitionAccessorConstantToAnotherAccessorConstant) |
OLD | NEW |