| 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 |