aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-field-type-tracking.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-05-02 10:50:00 +0200
committerMichaël Zasso <targos@protonmail.com>2017-05-06 20:02:35 +0200
commit60d1aac8d225e844e68ae48e8f3d58802e635fbe (patch)
tree922f347dd054db18d88666fad7181e5a777f4022 /deps/v8/test/cctest/test-field-type-tracking.cc
parent73d9c0f903ae371cd5011af64c3a6f69a1bda978 (diff)
downloadandroid-node-v8-60d1aac8d225e844e68ae48e8f3d58802e635fbe.tar.gz
android-node-v8-60d1aac8d225e844e68ae48e8f3d58802e635fbe.tar.bz2
android-node-v8-60d1aac8d225e844e68ae48e8f3d58802e635fbe.zip
deps: update V8 to 5.8.283.38
PR-URL: https://github.com/nodejs/node/pull/12784 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
Diffstat (limited to 'deps/v8/test/cctest/test-field-type-tracking.cc')
-rw-r--r--deps/v8/test/cctest/test-field-type-tracking.cc888
1 files changed, 580 insertions, 308 deletions
diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc
index 4abde16cd6..04e23790ad 100644
--- a/deps/v8/test/cctest/test-field-type-tracking.cc
+++ b/deps/v8/test/cctest/test-field-type-tracking.cc
@@ -18,13 +18,16 @@
#include "src/global-handles.h"
#include "src/ic/stub-cache.h"
#include "src/macro-assembler.h"
+#include "src/objects-inl.h"
+#include "src/property.h"
+#include "src/transitions.h"
using namespace v8::internal;
// TODO(ishell): fix this once TransitionToPrototype stops generalizing
// all field representations (similar to crbug/448711 where elements kind
-// and observed transitions caused generalization of all field representations).
+// and observed transitions caused generalization of all fields).
const bool IS_PROTO_TRANS_ISSUE_FIXED = false;
@@ -79,6 +82,7 @@ class Expectations {
ElementsKind elements_kind_;
PropertyKind kinds_[MAX_PROPERTIES];
PropertyLocation locations_[MAX_PROPERTIES];
+ PropertyConstness constnesses_[MAX_PROPERTIES];
PropertyAttributes attributes_[MAX_PROPERTIES];
Representation representations_[MAX_PROPERTIES];
// FieldType for kField, value for DATA_CONSTANT and getter for
@@ -100,11 +104,12 @@ class Expectations {
isolate->object_function()->initial_map()->elements_kind()) {}
void Init(int index, PropertyKind kind, PropertyAttributes attributes,
- PropertyLocation location, Representation representation,
- Handle<Object> value) {
+ PropertyConstness constness, PropertyLocation location,
+ Representation representation, Handle<Object> value) {
CHECK(index < MAX_PROPERTIES);
kinds_[index] = kind;
locations_[index] = location;
+ constnesses_[index] = constness;
attributes_[index] = attributes;
representations_[index] = representation;
values_[index] = value;
@@ -126,6 +131,7 @@ class Expectations {
}
os << " (";
+ if (constnesses_[i] == kConst) os << "const ";
os << (kinds_[i] == kData ? "data " : "accessor ");
if (locations_[i] == kField) {
os << "field"
@@ -149,18 +155,20 @@ class Expectations {
}
void SetDataField(int index, PropertyAttributes attrs,
- Representation representation,
+ PropertyConstness constness, Representation representation,
Handle<FieldType> field_type) {
- Init(index, kData, attrs, kField, representation, field_type);
+ Init(index, kData, attrs, constness, kField, representation, field_type);
}
- void SetDataField(int index, Representation representation,
+ void SetDataField(int index, PropertyConstness constness,
+ Representation representation,
Handle<FieldType> field_type) {
- SetDataField(index, attributes_[index], representation, field_type);
+ SetDataField(index, attributes_[index], constness, representation,
+ field_type);
}
void SetAccessorField(int index, PropertyAttributes attrs) {
- Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(),
+ Init(index, kAccessor, attrs, kConst, kDescriptor, Representation::Tagged(),
FieldType::Any(isolate_));
}
@@ -170,7 +178,15 @@ class Expectations {
void SetDataConstant(int index, PropertyAttributes attrs,
Handle<JSFunction> value) {
- Init(index, kData, attrs, kDescriptor, Representation::HeapObject(), value);
+ if (FLAG_track_constant_fields) {
+ Handle<FieldType> field_type(FieldType::Class(value->map()), isolate_);
+ Init(index, kData, attrs, kConst, kField, Representation::HeapObject(),
+ field_type);
+
+ } else {
+ Init(index, kData, attrs, kConst, kDescriptor,
+ Representation::HeapObject(), value);
+ }
}
void SetDataConstant(int index, Handle<JSFunction> value) {
@@ -179,7 +195,7 @@ class Expectations {
void SetAccessorConstant(int index, PropertyAttributes attrs,
Handle<Object> getter, Handle<Object> setter) {
- Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(),
+ Init(index, kAccessor, attrs, kConst, kDescriptor, Representation::Tagged(),
getter);
setter_values_[index] = setter;
}
@@ -215,7 +231,7 @@ class Expectations {
SetAccessorConstant(index, getter, setter);
}
- void GeneralizeRepresentation(int index) {
+ void GeneralizeField(int index) {
CHECK(index < number_of_properties_);
representations_[index] = Representation::Tagged();
if (locations_[index] == kField) {
@@ -223,12 +239,12 @@ class Expectations {
}
}
-
bool Check(DescriptorArray* descriptors, int descriptor) const {
PropertyDetails details = descriptors->GetDetails(descriptor);
if (details.kind() != kinds_[descriptor]) return false;
if (details.location() != locations_[descriptor]) return false;
+ if (details.constness() != constnesses_[descriptor]) return false;
PropertyAttributes expected_attributes = attributes_[descriptor];
if (details.attributes() != expected_attributes) return false;
@@ -250,6 +266,7 @@ class Expectations {
} else {
// kDescriptor
if (details.kind() == kData) {
+ CHECK(!FLAG_track_constant_fields);
return value == expected_value;
} else {
// kAccessor
@@ -300,15 +317,17 @@ class Expectations {
}
Handle<Map> AddDataField(Handle<Map> map, PropertyAttributes attributes,
+ PropertyConstness constness,
Representation representation,
Handle<FieldType> heap_type) {
CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors());
int property_index = number_of_properties_++;
- SetDataField(property_index, attributes, representation, heap_type);
+ SetDataField(property_index, attributes, constness, representation,
+ heap_type);
Handle<String> name = MakeName("prop", property_index);
- return Map::CopyWithField(map, name, heap_type, attributes, representation,
- INSERT_TRANSITION)
+ return Map::CopyWithField(map, name, heap_type, attributes, constness,
+ representation, INSERT_TRANSITION)
.ToHandleChecked();
}
@@ -326,16 +345,19 @@ class Expectations {
Handle<Map> TransitionToDataField(Handle<Map> map,
PropertyAttributes attributes,
+ PropertyConstness constness,
Representation representation,
Handle<FieldType> heap_type,
Handle<Object> value) {
CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors());
int property_index = number_of_properties_++;
- SetDataField(property_index, attributes, representation, heap_type);
+ SetDataField(property_index, attributes, constness, representation,
+ heap_type);
Handle<String> name = MakeName("prop", property_index);
return Map::TransitionToDataProperty(
- map, name, value, attributes, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
+ map, name, value, attributes, constness,
+ Object::CERTAINLY_NOT_STORE_FROM_KEYED);
}
Handle<Map> TransitionToDataConstant(Handle<Map> map,
@@ -347,16 +369,19 @@ class Expectations {
Handle<String> name = MakeName("prop", property_index);
return Map::TransitionToDataProperty(
- map, name, value, attributes, Object::CERTAINLY_NOT_STORE_FROM_KEYED);
+ map, name, value, attributes, kConst,
+ Object::CERTAINLY_NOT_STORE_FROM_KEYED);
}
Handle<Map> FollowDataTransition(Handle<Map> map,
PropertyAttributes attributes,
+ PropertyConstness constness,
Representation representation,
Handle<FieldType> heap_type) {
CHECK_EQ(number_of_properties_, map->NumberOfOwnDescriptors());
int property_index = number_of_properties_++;
- SetDataField(property_index, attributes, representation, heap_type);
+ SetDataField(property_index, attributes, constness, representation,
+ heap_type);
Handle<String> name = MakeName("prop", property_index);
Map* target =
@@ -461,7 +486,9 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
CHECK(!map->is_stable());
CHECK(expectations.Check(*map));
- expectations.SetDataField(0, NONE, Representation::None(), none_type);
+ // Property kind reconfiguration always makes the field mutable.
+ expectations.SetDataField(0, NONE, kMutable, Representation::None(),
+ none_type);
CHECK(!new_map->is_deprecated());
CHECK(new_map->is_stable());
@@ -472,11 +499,12 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
CHECK_EQ(*new_map, *new_map2);
Handle<Object> value(Smi::kZero, isolate);
- Handle<Map> prepared_map = Map::PrepareForDataProperty(new_map, 0, value);
+ Handle<Map> prepared_map =
+ Map::PrepareForDataProperty(new_map, 0, kConst, value);
// None to Smi generalization is trivial, map does not change.
CHECK_EQ(*new_map, *prepared_map);
- expectations.SetDataField(0, NONE, Representation::Smi(), any_type);
+ expectations.SetDataField(0, NONE, kMutable, Representation::Smi(), any_type);
CHECK(prepared_map->is_stable());
CHECK(expectations.Check(*prepared_map));
@@ -534,12 +562,19 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) {
////////////////////////////////////////////////////////////////////////////////
-// A set of tests for representation generalization case.
+// A set of tests for field generalization case.
//
-// This test ensures that representation/field type generalization at
-// |property_index| is done correctly independently of the fact that the |map|
-// is detached from transition tree or not.
+// <Constness, Representation, FieldType> data.
+struct CRFTData {
+ PropertyConstness constness;
+ Representation representation;
+ Handle<FieldType> type;
+};
+
+// This test ensures that field generalization at |property_index| is done
+// correctly independently of the fact that the |map| is detached from
+// transition tree or not.
//
// {} - p0 - p1 - p2: |detach_point_map|
// |
@@ -549,12 +584,11 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) {
//
// Detaching does not happen if |detach_property_at_index| is -1.
//
-static void TestGeneralizeRepresentation(
- int detach_property_at_index, int property_index,
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type,
- bool expected_deprecation, bool expected_field_type_dependency) {
+static void TestGeneralizeField(int detach_property_at_index,
+ int property_index, const CRFTData& from,
+ const CRFTData& to, const CRFTData& expected,
+ bool expected_deprecation,
+ bool expected_field_type_dependency) {
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
@@ -573,11 +607,11 @@ static void TestGeneralizeRepresentation(
Handle<Map> detach_point_map;
for (int i = 0; i < kPropCount; i++) {
if (i == property_index) {
- map =
- expectations.AddDataField(map, NONE, from_representation, from_type);
+ map = expectations.AddDataField(map, NONE, from.constness,
+ from.representation, from.type);
} else {
- map =
- expectations.AddDataField(map, NONE, Representation::Smi(), any_type);
+ map = expectations.AddDataField(map, NONE, kDefaultFieldConstness,
+ Representation::Smi(), any_type);
if (i == detach_property_at_index) {
detach_point_map = map;
}
@@ -593,7 +627,7 @@ static void TestGeneralizeRepresentation(
detach_point_map = Map::ReconfigureProperty(
detach_point_map, detach_property_at_index, kData, NONE,
Representation::Tagged(), any_type);
- expectations.SetDataField(detach_property_at_index,
+ expectations.SetDataField(detach_property_at_index, kDefaultFieldConstness,
Representation::Tagged(), any_type);
CHECK(map->is_deprecated());
CHECK(expectations.Check(*detach_point_map,
@@ -608,10 +642,10 @@ static void TestGeneralizeRepresentation(
dependencies.AssumeFieldOwner(field_owner);
Handle<Map> new_map = Map::ReconfigureProperty(
- map, property_index, kData, NONE, to_representation, to_type);
+ map, property_index, kData, NONE, to.representation, to.type);
- expectations.SetDataField(property_index, expected_representation,
- expected_type);
+ expectations.SetDataField(property_index, expected.constness,
+ expected.representation, expected.type);
CHECK(!new_map->is_deprecated());
CHECK(expectations.Check(*new_map));
@@ -656,84 +690,65 @@ static void TestGeneralizeRepresentation(
CHECK_EQ(*new_map, *updated_map);
}
-static void TestGeneralizeRepresentation(
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type,
- bool expected_deprecation, bool expected_field_type_dependency) {
+static void TestGeneralizeField(const CRFTData& from, const CRFTData& to,
+ const CRFTData& expected,
+ bool expected_deprecation,
+ bool expected_field_type_dependency) {
// Check the cases when the map being reconfigured is a part of the
// transition tree.
STATIC_ASSERT(kPropCount > 4);
int indices[] = {0, 2, kPropCount - 1};
for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) {
- TestGeneralizeRepresentation(
- -1, indices[i], from_representation, from_type, to_representation,
- to_type, expected_representation, expected_type, expected_deprecation,
- expected_field_type_dependency);
+ TestGeneralizeField(-1, indices[i], from, to, expected,
+ expected_deprecation, expected_field_type_dependency);
}
- if (!from_representation.IsNone()) {
+ if (!from.representation.IsNone()) {
// Check the cases when the map being reconfigured is NOT a part of the
// transition tree. "None -> anything" representation changes make sense
// only for "attached" maps.
int indices[] = {0, kPropCount - 1};
for (int i = 0; i < static_cast<int>(arraysize(indices)); i++) {
- TestGeneralizeRepresentation(
- indices[i], 2, from_representation, from_type, to_representation,
- to_type, expected_representation, expected_type, expected_deprecation,
- expected_field_type_dependency);
+ TestGeneralizeField(indices[i], 2, from, to, expected,
+ expected_deprecation, expected_field_type_dependency);
}
// Check that reconfiguration to the very same field works correctly.
- Representation representation = from_representation;
- Handle<FieldType> type = from_type;
- TestGeneralizeRepresentation(-1, 2, representation, type, representation,
- type, representation, type, false, false);
+ CRFTData data = from;
+ TestGeneralizeField(-1, 2, data, data, data, false, false);
}
}
-static void TestGeneralizeRepresentation(Representation from_representation,
- Handle<FieldType> from_type,
- Representation to_representation,
- Handle<FieldType> to_type,
- Representation expected_representation,
- Handle<FieldType> expected_type) {
+static void TestGeneralizeField(const CRFTData& from, const CRFTData& to,
+ const CRFTData& expected) {
const bool expected_deprecation = true;
const bool expected_field_type_dependency = false;
- TestGeneralizeRepresentation(
- from_representation, from_type, to_representation, to_type,
- expected_representation, expected_type, expected_deprecation,
- expected_field_type_dependency);
+ TestGeneralizeField(from, to, expected, expected_deprecation,
+ expected_field_type_dependency);
}
-static void TestGeneralizeRepresentationTrivial(
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type,
+static void TestGeneralizeFieldTrivial(
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected,
bool expected_field_type_dependency = true) {
const bool expected_deprecation = false;
- TestGeneralizeRepresentation(
- from_representation, from_type, to_representation, to_type,
- expected_representation, expected_type, expected_deprecation,
- expected_field_type_dependency);
+ TestGeneralizeField(from, to, expected, expected_deprecation,
+ expected_field_type_dependency);
}
-
-TEST(GeneralizeRepresentationSmiToDouble) {
+TEST(GeneralizeSmiFieldToDouble) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
- TestGeneralizeRepresentation(Representation::Smi(), any_type,
- Representation::Double(), any_type,
- Representation::Double(), any_type);
+ TestGeneralizeField({kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
}
-
-TEST(GeneralizeRepresentationSmiToTagged) {
+TEST(GeneralizeSmiFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -741,13 +756,12 @@ TEST(GeneralizeRepresentationSmiToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestGeneralizeRepresentation(Representation::Smi(), any_type,
- Representation::HeapObject(), value_type,
- Representation::Tagged(), any_type);
+ TestGeneralizeField({kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
-
-TEST(GeneralizeRepresentationDoubleToTagged) {
+TEST(GeneralizeDoubleFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -755,13 +769,12 @@ TEST(GeneralizeRepresentationDoubleToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestGeneralizeRepresentation(Representation::Double(), any_type,
- Representation::HeapObject(), value_type,
- Representation::Tagged(), any_type);
+ TestGeneralizeField({kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
-
-TEST(GeneralizeRepresentationHeapObjectToTagged) {
+TEST(GeneralizeHeapObjectFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -769,13 +782,12 @@ TEST(GeneralizeRepresentationHeapObjectToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestGeneralizeRepresentation(Representation::HeapObject(), value_type,
- Representation::Smi(), any_type,
- Representation::Tagged(), any_type);
+ TestGeneralizeField({kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Tagged(), any_type});
}
-
-TEST(GeneralizeRepresentationHeapObjectToHeapObject) {
+TEST(GeneralizeHeapObjectFieldToHeapObject) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -789,21 +801,21 @@ TEST(GeneralizeRepresentationHeapObjectToHeapObject) {
Handle<FieldType> expected_type = any_type;
- TestGeneralizeRepresentationTrivial(
- Representation::HeapObject(), current_type,
- Representation::HeapObject(), new_type, Representation::HeapObject(),
- expected_type);
- current_type = expected_type;
+ TestGeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), current_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
+ current_type = expected_type;
- new_type = FieldType::Class(Map::Create(isolate, 0), isolate);
+ new_type = FieldType::Class(Map::Create(isolate, 0), isolate);
- TestGeneralizeRepresentationTrivial(
- Representation::HeapObject(), any_type, Representation::HeapObject(),
- new_type, Representation::HeapObject(), any_type, false);
+ TestGeneralizeFieldTrivial({kMutable, Representation::HeapObject(), any_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type},
+ false);
}
-
-TEST(GeneralizeRepresentationNoneToSmi) {
+TEST(GeneralizeNoneFieldToSmi) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -811,13 +823,12 @@ TEST(GeneralizeRepresentationNoneToSmi) {
Handle<FieldType> any_type = FieldType::Any(isolate);
// None -> Smi representation change is trivial.
- TestGeneralizeRepresentationTrivial(Representation::None(), none_type,
- Representation::Smi(), any_type,
- Representation::Smi(), any_type);
+ TestGeneralizeFieldTrivial({kMutable, Representation::None(), none_type},
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Smi(), any_type});
}
-
-TEST(GeneralizeRepresentationNoneToDouble) {
+TEST(GeneralizeNoneFieldToDouble) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -825,13 +836,12 @@ TEST(GeneralizeRepresentationNoneToDouble) {
Handle<FieldType> any_type = FieldType::Any(isolate);
// None -> Double representation change is NOT trivial.
- TestGeneralizeRepresentation(Representation::None(), none_type,
- Representation::Double(), any_type,
- Representation::Double(), any_type);
+ TestGeneralizeField({kMutable, Representation::None(), none_type},
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
}
-
-TEST(GeneralizeRepresentationNoneToHeapObject) {
+TEST(GeneralizeNoneFieldToHeapObject) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -840,13 +850,13 @@ TEST(GeneralizeRepresentationNoneToHeapObject) {
FieldType::Class(Map::Create(isolate, 0), isolate);
// None -> HeapObject representation change is trivial.
- TestGeneralizeRepresentationTrivial(Representation::None(), none_type,
- Representation::HeapObject(), value_type,
- Representation::HeapObject(), value_type);
+ TestGeneralizeFieldTrivial(
+ {kMutable, Representation::None(), none_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::HeapObject(), value_type});
}
-
-TEST(GeneralizeRepresentationNoneToTagged) {
+TEST(GeneralizeNoneFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -854,18 +864,17 @@ TEST(GeneralizeRepresentationNoneToTagged) {
Handle<FieldType> any_type = FieldType::Any(isolate);
// None -> HeapObject representation change is trivial.
- TestGeneralizeRepresentationTrivial(Representation::None(), none_type,
- Representation::Tagged(), any_type,
- Representation::Tagged(), any_type);
+ TestGeneralizeFieldTrivial({kMutable, Representation::None(), none_type},
+ {kMutable, Representation::Tagged(), any_type},
+ {kMutable, Representation::Tagged(), any_type});
}
////////////////////////////////////////////////////////////////////////////////
-// A set of tests for representation generalization case with kAccessor
-// properties.
+// A set of tests for field generalization case with kAccessor properties.
//
-TEST(GeneralizeRepresentationWithAccessorProperties) {
+TEST(GeneralizeFieldWithAccessorProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -882,8 +891,8 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
if (i == kAccessorProp) {
map = expectations.AddAccessorConstant(map, NONE, pair);
} else {
- map =
- expectations.AddDataField(map, NONE, Representation::Smi(), any_type);
+ map = expectations.AddDataField(map, NONE, kMutable,
+ Representation::Smi(), any_type);
}
}
CHECK(!map->is_deprecated());
@@ -902,7 +911,7 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
map, i, kData, NONE, Representation::Double(), any_type);
maps[i] = new_map;
- expectations.SetDataField(i, Representation::Double(), any_type);
+ expectations.SetDataField(i, kMutable, Representation::Double(), any_type);
CHECK(!map->is_stable());
CHECK(map->is_deprecated());
@@ -930,8 +939,8 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
// A set of tests for attribute reconfiguration case.
//
-// This test ensures that representation/field type generalization is correctly
-// propagated from one branch of transition tree (|map2|) to another (|map|).
+// This test ensures that field generalization is correctly propagated from one
+// branch of transition tree (|map2|) to another (|map|).
//
// + - p2B - p3 - p4: |map2|
// |
@@ -939,10 +948,8 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
//
// where "p2A" and "p2B" differ only in the attributes.
//
-static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type) {
+static void TestReconfigureDataFieldAttribute_GeneralizeField(
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate);
@@ -951,7 +958,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
Handle<Map> initial_map = Map::Create(isolate, 0);
Handle<Map> map = initial_map;
for (int i = 0; i < kPropCount; i++) {
- map = expectations.AddDataField(map, NONE, from_representation, from_type);
+ map = expectations.AddDataField(map, NONE, from.constness,
+ from.representation, from.type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -965,14 +973,15 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
Handle<Map> map2 = initial_map;
for (int i = 0; i < kSplitProp; i++) {
- map2 = expectations2.FollowDataTransition(map2, NONE, from_representation,
- from_type);
+ map2 = expectations2.FollowDataTransition(map2, NONE, from.constness,
+ from.representation, from.type);
}
- map2 =
- expectations2.AddDataField(map2, READ_ONLY, to_representation, to_type);
+ map2 = expectations2.AddDataField(map2, READ_ONLY, to.constness,
+ to.representation, to.type);
for (int i = kSplitProp + 1; i < kPropCount; i++) {
- map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type);
+ map2 = expectations2.AddDataField(map2, NONE, to.constness,
+ to.representation, to.type);
}
CHECK(!map2->is_deprecated());
CHECK(map2->is_stable());
@@ -997,7 +1006,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
// |map| should be deprecated and |new_map| should match new expectations.
for (int i = kSplitProp; i < kPropCount; i++) {
- expectations.SetDataField(i, expected_representation, expected_type);
+ expectations.SetDataField(i, expected.constness, expected.representation,
+ expected.type);
}
CHECK(map->is_deprecated());
CHECK(!dependencies.HasAborted());
@@ -1012,10 +1022,9 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
CHECK_EQ(*new_map, *updated_map);
}
-
-// This test ensures that trivial representation/field type generalization
-// (from HeapObject to HeapObject) is correctly propagated from one branch of
-// transition tree (|map2|) to another (|map|).
+// This test ensures that trivial field generalization (from HeapObject to
+// HeapObject) is correctly propagated from one branch of transition tree
+// (|map2|) to another (|map|).
//
// + - p2B - p3 - p4: |map2|
// |
@@ -1023,10 +1032,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
//
// where "p2A" and "p2B" differ only in the attributes.
//
-static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type,
+static void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected,
bool expected_field_type_dependency = true) {
Isolate* isolate = CcTest::i_isolate();
@@ -1036,7 +1043,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
Handle<Map> initial_map = Map::Create(isolate, 0);
Handle<Map> map = initial_map;
for (int i = 0; i < kPropCount; i++) {
- map = expectations.AddDataField(map, NONE, from_representation, from_type);
+ map = expectations.AddDataField(map, NONE, from.constness,
+ from.representation, from.type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -1050,14 +1058,15 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
Handle<Map> map2 = initial_map;
for (int i = 0; i < kSplitProp; i++) {
- map2 = expectations2.FollowDataTransition(map2, NONE, from_representation,
- from_type);
+ map2 = expectations2.FollowDataTransition(map2, NONE, from.constness,
+ from.representation, from.type);
}
- map2 =
- expectations2.AddDataField(map2, READ_ONLY, to_representation, to_type);
+ map2 = expectations2.AddDataField(map2, READ_ONLY, to.constness,
+ to.representation, to.type);
for (int i = kSplitProp + 1; i < kPropCount; i++) {
- map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type);
+ map2 = expectations2.AddDataField(map2, NONE, to.constness,
+ to.representation, to.type);
}
CHECK(!map2->is_deprecated());
CHECK(map2->is_stable());
@@ -1085,7 +1094,8 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
// respective code dependencies should be invalidated. |map| should be NOT
// deprecated and it should match new expectations.
for (int i = kSplitProp; i < kPropCount; i++) {
- expectations.SetDataField(i, expected_representation, expected_type);
+ expectations.SetDataField(i, expected.constness, expected.representation,
+ expected.type);
}
CHECK(!map->is_deprecated());
CHECK_EQ(*map, *new_map);
@@ -1099,20 +1109,36 @@ static void TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
CHECK_EQ(*new_map, *updated_map);
}
-
-TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToDouble) {
+TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToDouble) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
- TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
- Representation::Smi(), any_type, Representation::Double(), any_type,
- Representation::Double(), any_type);
-}
+ if (FLAG_track_constant_fields) {
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kConst, Representation::Double(), any_type},
+ {kConst, Representation::Double(), any_type});
+
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
+
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kConst, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
+ }
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
+}
-TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToTagged) {
+TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1120,13 +1146,30 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationSmiToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
- Representation::Smi(), any_type, Representation::HeapObject(), value_type,
- Representation::Tagged(), any_type);
-}
+ if (FLAG_track_constant_fields) {
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kConst, Representation::Tagged(), any_type});
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+ }
-TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationDoubleToTagged) {
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+}
+
+TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1134,13 +1177,30 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationDoubleToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
- Representation::Double(), any_type, Representation::HeapObject(),
- value_type, Representation::Tagged(), any_type);
-}
+ if (FLAG_track_constant_fields) {
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::Double(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kConst, Representation::Tagged(), any_type});
+
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::Double(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::Double(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+ }
+
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+}
-TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjToHeapObj) {
+TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjFieldToHeapObj) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1154,20 +1214,59 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjToHeapObj) {
Handle<FieldType> expected_type = any_type;
- TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
- Representation::HeapObject(), current_type, Representation::HeapObject(),
- new_type, Representation::HeapObject(), expected_type);
+ // Check generalizations that trigger deopts.
+ if (FLAG_track_constant_fields) {
+ TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ {kConst, Representation::HeapObject(), current_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kConst, Representation::HeapObject(), expected_type});
+
+ // Currently, kConst to kMutable migration causes map change, therefore
+ // non-trivial generalization.
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::HeapObject(), current_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
+
+ TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), current_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
+ }
+ TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), current_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
current_type = expected_type;
+ // Check generalizations that do not trigger deopts.
new_type = FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureDataFieldAttribute_GeneralizeRepresentationTrivial(
- Representation::HeapObject(), any_type, Representation::HeapObject(),
- new_type, Representation::HeapObject(), any_type, false);
+ if (FLAG_track_constant_fields) {
+ TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ {kConst, Representation::HeapObject(), any_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kConst, Representation::HeapObject(), any_type}, false);
+
+ // Currently, kConst to kMutable migration causes map change, therefore
+ // non-trivial generalization.
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kConst, Representation::HeapObject(), any_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type});
+
+ TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), any_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type}, false);
+ }
+ TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), any_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type}, false);
}
-
-TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjectToTagged) {
+TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjectFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1175,9 +1274,10 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeRepresentationHeapObjectToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureDataFieldAttribute_GeneralizeRepresentation(
- Representation::HeapObject(), value_type, Representation::Smi(), any_type,
- Representation::Tagged(), any_type);
+ TestReconfigureDataFieldAttribute_GeneralizeField(
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Tagged(), any_type});
}
@@ -1243,7 +1343,7 @@ struct CheckCopyGeneralizeAllFields {
CHECK(new_map->GetBackPointer()->IsUndefined(map->GetIsolate()));
for (int i = 0; i < kPropCount; i++) {
- expectations.GeneralizeRepresentation(i);
+ expectations.GeneralizeField(i);
}
CHECK(!new_map->is_deprecated());
@@ -1251,9 +1351,8 @@ struct CheckCopyGeneralizeAllFields {
}
};
-
-// This test ensures that representation/field type generalization is correctly
-// propagated from one branch of transition tree (|map2|) to another (|map1|).
+// This test ensures that field generalization is correctly propagated from one
+// branch of transition tree (|map2|) to another (|map1|).
//
// + - p2B - p3 - p4: |map2|
// |
@@ -1277,13 +1376,15 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap(
const int kSplitProp = 2;
CHECK(kSplitProp < kCustomPropIndex);
+ const PropertyConstness constness = kMutable;
const Representation representation = Representation::Smi();
// Create common part of transition tree.
Handle<Map> initial_map = Map::Create(isolate, 0);
Handle<Map> map = initial_map;
for (int i = 0; i < kSplitProp; i++) {
- map = expectations.AddDataField(map, NONE, representation, any_type);
+ map = expectations.AddDataField(map, NONE, constness, representation,
+ any_type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -1294,11 +1395,13 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap(
Handle<Map> map1 = map;
Expectations expectations1 = expectations;
for (int i = kSplitProp; i < kCustomPropIndex; i++) {
- map1 = expectations1.AddDataField(map1, NONE, representation, any_type);
+ map1 = expectations1.AddDataField(map1, NONE, constness, representation,
+ any_type);
}
map1 = config.AddPropertyAtBranch(1, expectations1, map1);
for (int i = kCustomPropIndex + 1; i < kPropCount; i++) {
- map1 = expectations1.AddDataField(map1, NONE, representation, any_type);
+ map1 = expectations1.AddDataField(map1, NONE, constness, representation,
+ any_type);
}
CHECK(!map1->is_deprecated());
CHECK(map1->is_stable());
@@ -1309,13 +1412,16 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap(
// has different attributes), initialize expectations.
Handle<Map> map2 = map;
Expectations expectations2 = expectations;
- map2 = expectations2.AddDataField(map2, READ_ONLY, representation, any_type);
+ map2 = expectations2.AddDataField(map2, READ_ONLY, constness, representation,
+ any_type);
for (int i = kSplitProp + 1; i < kCustomPropIndex; i++) {
- map2 = expectations2.AddDataField(map2, NONE, representation, any_type);
+ map2 = expectations2.AddDataField(map2, NONE, constness, representation,
+ any_type);
}
map2 = config.AddPropertyAtBranch(2, expectations2, map2);
for (int i = kCustomPropIndex + 1; i < kPropCount; i++) {
- map2 = expectations2.AddDataField(map2, NONE, representation, any_type);
+ map2 = expectations2.AddDataField(map2, NONE, constness, representation,
+ any_type);
}
CHECK(!map2->is_deprecated());
CHECK(map2->is_stable());
@@ -1403,15 +1509,23 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
}
void UpdateExpectations(int property_index, Expectations& expectations) {
- expectations.SetDataField(property_index, Representation::HeapObject(),
- function_type_);
+ PropertyConstness expected_constness =
+ FLAG_track_constant_fields ? kConst : kMutable;
+ expectations.SetDataField(property_index, expected_constness,
+ Representation::HeapObject(), function_type_);
}
};
TestConfig config;
- // Two branches are "incompatible" so the |map1| should be deprecated.
- CheckDeprecated checker;
- TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
+ if (FLAG_track_constant_fields) {
+ CheckSameMap checker;
+ TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
+
+ } else {
+ // Two branches are "incompatible" so the |map1| should be deprecated.
+ CheckDeprecated checker;
+ TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
+ }
}
@@ -1534,8 +1648,8 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
} else {
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
- return expectations.AddDataField(map, NONE, Representation::Smi(),
- any_type);
+ return expectations.AddDataField(map, NONE, kDefaultFieldConstness,
+ Representation::Smi(), any_type);
}
}
@@ -1553,8 +1667,8 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
// A set of tests for elements kind reconfiguration case.
//
-// This test ensures that representation/field type generalization is correctly
-// propagated from one branch of transition tree (|map2) to another (|map|).
+// This test ensures that field generalization is correctly propagated from one
+// branch of transition tree (|map2) to another (|map|).
//
// + - p0 - p1 - p2A - p3 - p4: |map|
// |
@@ -1564,10 +1678,8 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) {
//
// where "p2A" and "p2B" differ only in the representation/field type.
//
-static void TestReconfigureElementsKind_GeneralizeRepresentation(
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type) {
+static void TestReconfigureElementsKind_GeneralizeField(
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate, FAST_SMI_ELEMENTS);
@@ -1579,7 +1691,8 @@ static void TestReconfigureElementsKind_GeneralizeRepresentation(
Handle<Map> map = initial_map;
map = expectations.AsElementsKind(map, FAST_ELEMENTS);
for (int i = 0; i < kPropCount; i++) {
- map = expectations.AddDataField(map, NONE, from_representation, from_type);
+ map = expectations.AddDataField(map, NONE, from.constness,
+ from.representation, from.type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -1593,10 +1706,11 @@ static void TestReconfigureElementsKind_GeneralizeRepresentation(
Handle<Map> map2 = initial_map;
for (int i = 0; i < kPropCount; i++) {
if (i == kDiffProp) {
- map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type);
+ map2 = expectations2.AddDataField(map2, NONE, to.constness,
+ to.representation, to.type);
} else {
- map2 = expectations2.AddDataField(map2, NONE, from_representation,
- from_type);
+ map2 = expectations2.AddDataField(map2, NONE, from.constness,
+ from.representation, from.type);
}
}
CHECK(!map2->is_deprecated());
@@ -1620,7 +1734,8 @@ static void TestReconfigureElementsKind_GeneralizeRepresentation(
CHECK(expectations2.Check(*map2));
// |map| should be deprecated and |new_map| should match new expectations.
- expectations.SetDataField(kDiffProp, expected_representation, expected_type);
+ expectations.SetDataField(kDiffProp, expected.constness,
+ expected.representation, expected.type);
CHECK(map->is_deprecated());
CHECK(!dependencies.HasAborted());
@@ -1644,9 +1759,9 @@ static void TestReconfigureElementsKind_GeneralizeRepresentation(
}
}
-// This test ensures that trivial representation/field type generalization
-// (from HeapObject to HeapObject) is correctly propagated from one branch of
-// transition tree (|map2|) to another (|map|).
+// This test ensures that trivial field generalization (from HeapObject to
+// HeapObject) is correctly propagated from one branch of transition tree
+// (|map2|) to another (|map|).
//
// + - p0 - p1 - p2A - p3 - p4: |map|
// |
@@ -1656,10 +1771,8 @@ static void TestReconfigureElementsKind_GeneralizeRepresentation(
//
// where "p2A" and "p2B" differ only in the representation/field type.
//
-static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
- Representation from_representation, Handle<FieldType> from_type,
- Representation to_representation, Handle<FieldType> to_type,
- Representation expected_representation, Handle<FieldType> expected_type,
+static void TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected,
bool expected_field_type_dependency = true) {
Isolate* isolate = CcTest::i_isolate();
@@ -1672,7 +1785,8 @@ static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
Handle<Map> map = initial_map;
map = expectations.AsElementsKind(map, FAST_ELEMENTS);
for (int i = 0; i < kPropCount; i++) {
- map = expectations.AddDataField(map, NONE, from_representation, from_type);
+ map = expectations.AddDataField(map, NONE, from.constness,
+ from.representation, from.type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -1686,10 +1800,11 @@ static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
Handle<Map> map2 = initial_map;
for (int i = 0; i < kPropCount; i++) {
if (i == kDiffProp) {
- map2 = expectations2.AddDataField(map2, NONE, to_representation, to_type);
+ map2 = expectations2.AddDataField(map2, NONE, to.constness,
+ to.representation, to.type);
} else {
- map2 = expectations2.AddDataField(map2, NONE, from_representation,
- from_type);
+ map2 = expectations2.AddDataField(map2, NONE, from.constness,
+ from.representation, from.type);
}
}
CHECK(!map2->is_deprecated());
@@ -1716,7 +1831,8 @@ static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
// kind reconfiguration, respective field types should be generalized and
// respective code dependencies should be invalidated. |map| should be NOT
// deprecated and it should match new expectations.
- expectations.SetDataField(kDiffProp, expected_representation, expected_type);
+ expectations.SetDataField(kDiffProp, expected.constness,
+ expected.representation, expected.type);
CHECK(!map->is_deprecated());
CHECK_EQ(*map, *new_map);
CHECK_EQ(expected_field_type_dependency, dependencies.HasAborted());
@@ -1738,18 +1854,35 @@ static void TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
}
}
-TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToDouble) {
+TEST(ReconfigureElementsKind_GeneralizeSmiFieldToDouble) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<FieldType> any_type = FieldType::Any(isolate);
- TestReconfigureElementsKind_GeneralizeRepresentation(
- Representation::Smi(), any_type, Representation::Double(), any_type,
- Representation::Double(), any_type);
+ if (FLAG_track_constant_fields) {
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kConst, Representation::Double(), any_type},
+ {kConst, Representation::Double(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kConst, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
+ }
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::Double(), any_type});
}
-TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) {
+TEST(ReconfigureElementsKind_GeneralizeSmiFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1757,12 +1890,29 @@ TEST(ReconfigureElementsKind_GeneralizeRepresentationSmiToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureElementsKind_GeneralizeRepresentation(
- Representation::Smi(), any_type, Representation::HeapObject(), value_type,
- Representation::Tagged(), any_type);
+ if (FLAG_track_constant_fields) {
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kConst, Representation::Tagged(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+ }
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
-TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) {
+TEST(ReconfigureElementsKind_GeneralizeDoubleFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1770,12 +1920,29 @@ TEST(ReconfigureElementsKind_GeneralizeRepresentationDoubleToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureElementsKind_GeneralizeRepresentation(
- Representation::Double(), any_type, Representation::HeapObject(),
- value_type, Representation::Tagged(), any_type);
+ if (FLAG_track_constant_fields) {
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::Double(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kConst, Representation::Tagged(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::Double(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::Double(), any_type},
+ {kConst, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
+ }
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::Double(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
-TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) {
+TEST(ReconfigureElementsKind_GeneralizeHeapObjFieldToHeapObj) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1789,19 +1956,59 @@ TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjToHeapObj) {
Handle<FieldType> expected_type = any_type;
- TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
- Representation::HeapObject(), current_type, Representation::HeapObject(),
- new_type, Representation::HeapObject(), expected_type);
+ // Check generalizations that trigger deopts.
+ if (FLAG_track_constant_fields) {
+ TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ {kConst, Representation::HeapObject(), current_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kConst, Representation::HeapObject(), expected_type});
+
+ // Currently, kConst to kMutable migration causes map change, therefore
+ // non-trivial generalization.
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::HeapObject(), current_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
+
+ TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), current_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
+ }
+ TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), current_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), expected_type});
current_type = expected_type;
+ // Check generalizations that do not trigger deopts.
new_type = FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureElementsKind_GeneralizeRepresentationTrivial(
- Representation::HeapObject(), any_type, Representation::HeapObject(),
- new_type, Representation::HeapObject(), any_type, false);
+ if (FLAG_track_constant_fields) {
+ TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ {kConst, Representation::HeapObject(), any_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kConst, Representation::HeapObject(), any_type}, false);
+
+ // Currently, kConst to kMutable migration causes map change, therefore
+ // non-trivial generalization.
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::HeapObject(), any_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), any_type},
+ {kConst, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type}, false);
+ }
+ TestReconfigureElementsKind_GeneralizeFieldTrivial(
+ {kMutable, Representation::HeapObject(), any_type},
+ {kMutable, Representation::HeapObject(), new_type},
+ {kMutable, Representation::HeapObject(), any_type}, false);
}
-TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) {
+TEST(ReconfigureElementsKind_GeneralizeHeapObjectFieldToTagged) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
@@ -1809,9 +2016,26 @@ TEST(ReconfigureElementsKind_GeneralizeRepresentationHeapObjectToTagged) {
Handle<FieldType> value_type =
FieldType::Class(Map::Create(isolate, 0), isolate);
- TestReconfigureElementsKind_GeneralizeRepresentation(
- Representation::HeapObject(), value_type, Representation::Smi(), any_type,
- Representation::Tagged(), any_type);
+ if (FLAG_track_constant_fields) {
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::HeapObject(), value_type},
+ {kConst, Representation::Smi(), any_type},
+ {kConst, Representation::Tagged(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kConst, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Tagged(), any_type});
+
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::HeapObject(), value_type},
+ {kConst, Representation::Smi(), any_type},
+ {kMutable, Representation::Tagged(), any_type});
+ }
+ TestReconfigureElementsKind_GeneralizeField(
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::Tagged(), any_type});
}
////////////////////////////////////////////////////////////////////////////////
@@ -1830,7 +2054,8 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
Handle<Map> initial_map = Map::Create(isolate, 0);
Handle<Map> map = initial_map;
for (int i = 0; i < kPropCount; i++) {
- map = expectations.AddDataField(map, NONE, Representation::Smi(), any_type);
+ map = expectations.AddDataField(map, NONE, kMutable, Representation::Smi(),
+ any_type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -1854,7 +2079,8 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
map2 = Map::ReconfigureProperty(map2, kSplitProp, kData, NONE,
Representation::Double(), any_type);
- expectations.SetDataField(kSplitProp, Representation::Double(), any_type);
+ expectations.SetDataField(kSplitProp, kMutable, Representation::Double(),
+ any_type);
CHECK(expectations.Check(*split_map, kSplitProp));
CHECK(expectations.Check(*map2, kSplitProp + 1));
@@ -1871,8 +2097,8 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
for (int i = 0; i < TransitionArray::kMaxNumberOfTransitions; i++) {
CHECK(TransitionArray::CanHaveMoreTransitions(map2));
Handle<String> name = MakeName("foo", i);
- Map::CopyWithField(map2, name, any_type, NONE, Representation::Smi(),
- INSERT_TRANSITION)
+ Map::CopyWithField(map2, name, any_type, NONE, kMutable,
+ Representation::Smi(), INSERT_TRANSITION)
.ToHandleChecked();
}
CHECK(!TransitionArray::CanHaveMoreTransitions(map2));
@@ -1883,7 +2109,7 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
CHECK(updated_map->GetBackPointer()->IsUndefined(isolate));
for (int i = 0; i < kPropCount; i++) {
- expectations.SetDataField(i, Representation::Tagged(), any_type);
+ expectations.SetDataField(i, kMutable, Representation::Tagged(), any_type);
}
CHECK(expectations.Check(*updated_map));
}
@@ -1894,8 +2120,8 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
// transition, observed transition or prototype transition).
//
-// This test ensures that representation/field type generalization is correctly
-// propagated from one branch of transition tree (|map2|) to another (|map|).
+// This test ensures that field generalization is correctly propagated from one
+// branch of transition tree (|map2|) to another (|map|).
//
// p4B: |map2|
// |
@@ -1906,15 +2132,14 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
// where "p4A" and "p4B" are exactly the same properties.
//
// TODO(ishell): unify this test template with
-// TestReconfigureDataFieldAttribute_GeneralizeRepresentation once
+// TestReconfigureDataFieldAttribute_GeneralizeField once
// IS_PROTO_TRANS_ISSUE_FIXED and IS_NON_EQUIVALENT_TRANSITION_SUPPORTED are
// fixed.
template <typename TestConfig>
-static void TestGeneralizeRepresentationWithSpecialTransition(
- TestConfig& config, Representation from_representation,
- Handle<FieldType> from_type, Representation to_representation,
- Handle<FieldType> to_type, Representation expected_representation,
- Handle<FieldType> expected_type) {
+static void TestGeneralizeFieldWithSpecialTransition(TestConfig& config,
+ const CRFTData& from,
+ const CRFTData& to,
+ const CRFTData& expected) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate);
@@ -1923,7 +2148,8 @@ static void TestGeneralizeRepresentationWithSpecialTransition(
Handle<Map> initial_map = Map::Create(isolate, 0);
Handle<Map> map = initial_map;
for (int i = 0; i < kPropCount; i++) {
- map = expectations.AddDataField(map, NONE, from_representation, from_type);
+ map = expectations.AddDataField(map, NONE, from.constness,
+ from.representation, from.type);
}
CHECK(!map->is_deprecated());
CHECK(map->is_stable());
@@ -1941,7 +2167,7 @@ static void TestGeneralizeRepresentationWithSpecialTransition(
if (config.generalizes_representations()) {
for (int i = 0; i < kPropCount; i++) {
- expectations2.GeneralizeRepresentation(i);
+ expectations2.GeneralizeField(i);
}
}
@@ -1953,10 +2179,11 @@ static void TestGeneralizeRepresentationWithSpecialTransition(
Handle<Map> maps[kPropCount];
for (int i = 0; i < kPropCount; i++) {
Handle<Map> new_map = Map::ReconfigureProperty(map, i, kData, NONE,
- to_representation, to_type);
+ to.representation, to.type);
maps[i] = new_map;
- expectations.SetDataField(i, expected_representation, expected_type);
+ expectations.SetDataField(i, expected.constness, expected.representation,
+ expected.type);
CHECK(map->is_deprecated());
CHECK_NE(*map, *new_map);
@@ -1978,7 +2205,7 @@ static void TestGeneralizeRepresentationWithSpecialTransition(
// In case of non-equivalent transition currently we generalize all
// representations.
for (int i = 0; i < kPropCount; i++) {
- expectations2.GeneralizeRepresentation(i);
+ expectations2.GeneralizeField(i);
}
CHECK(new_map2->GetBackPointer()->IsUndefined(isolate));
CHECK(expectations2.Check(*new_map2));
@@ -2021,9 +2248,10 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) {
bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
- TestGeneralizeRepresentationWithSpecialTransition(
- config, Representation::Smi(), any_type, Representation::HeapObject(),
- value_type, Representation::Tagged(), any_type);
+ TestGeneralizeFieldWithSpecialTransition(
+ config, {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
@@ -2043,7 +2271,7 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) {
// Add one more transition to |map| in order to prevent descriptors
// ownership.
CHECK(map->owns_descriptors());
- Map::CopyWithField(map, MakeString("foo"), any_type, NONE,
+ Map::CopyWithField(map, MakeString("foo"), any_type, NONE, kMutable,
Representation::Smi(), INSERT_TRANSITION)
.ToHandleChecked();
CHECK(!map->owns_descriptors());
@@ -2058,9 +2286,10 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) {
bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
- TestGeneralizeRepresentationWithSpecialTransition(
- config, Representation::Smi(), any_type, Representation::HeapObject(),
- value_type, Representation::Tagged(), any_type);
+ TestGeneralizeFieldWithSpecialTransition(
+ config, {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
@@ -2092,9 +2321,10 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) {
bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
- TestGeneralizeRepresentationWithSpecialTransition(
- config, Representation::Smi(), any_type, Representation::HeapObject(),
- value_type, Representation::Tagged(), any_type);
+ TestGeneralizeFieldWithSpecialTransition(
+ config, {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
@@ -2123,7 +2353,7 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) {
// Add one more transition to |map| in order to prevent descriptors
// ownership.
CHECK(map->owns_descriptors());
- Map::CopyWithField(map, MakeString("foo"), any_type, NONE,
+ Map::CopyWithField(map, MakeString("foo"), any_type, NONE, kMutable,
Representation::Smi(), INSERT_TRANSITION)
.ToHandleChecked();
CHECK(!map->owns_descriptors());
@@ -2137,9 +2367,10 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) {
bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
- TestGeneralizeRepresentationWithSpecialTransition(
- config, Representation::Smi(), any_type, Representation::HeapObject(),
- value_type, Representation::Tagged(), any_type);
+ TestGeneralizeFieldWithSpecialTransition(
+ config, {kMutable, Representation::Smi(), any_type},
+ {kMutable, Representation::HeapObject(), value_type},
+ {kMutable, Representation::Tagged(), any_type});
}
@@ -2148,23 +2379,26 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) {
//
struct TransitionToDataFieldOperator {
+ PropertyConstness constness_;
Representation representation_;
PropertyAttributes attributes_;
Handle<FieldType> heap_type_;
Handle<Object> value_;
- TransitionToDataFieldOperator(Representation representation,
+ TransitionToDataFieldOperator(PropertyConstness constness,
+ Representation representation,
Handle<FieldType> heap_type,
Handle<Object> value,
PropertyAttributes attributes = NONE)
- : representation_(representation),
+ : constness_(constness),
+ representation_(representation),
attributes_(attributes),
heap_type_(heap_type),
value_(value) {}
Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) {
- return expectations.TransitionToDataField(map, attributes_, representation_,
- heap_type_, value_);
+ return expectations.TransitionToDataField(
+ map, attributes_, constness_, representation_, heap_type_, value_);
}
};
@@ -2213,7 +2447,8 @@ struct ReconfigureAsDataPropertyOperator {
heap_type_(heap_type) {}
Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) {
- expectations.SetDataField(descriptor_, representation_, heap_type_);
+ expectations.SetDataField(descriptor_, kMutable, representation_,
+ heap_type_);
return Map::ReconfigureExistingProperty(map, descriptor_, kData,
attributes_);
}
@@ -2235,18 +2470,20 @@ struct ReconfigureAsAccessorPropertyOperator {
}
};
-
-// Checks that representation/field type generalization happened.
+// Checks that field generalization happened.
struct FieldGeneralizationChecker {
int descriptor_;
+ PropertyConstness constness_;
Representation representation_;
PropertyAttributes attributes_;
Handle<FieldType> heap_type_;
- FieldGeneralizationChecker(int descriptor, Representation representation,
+ FieldGeneralizationChecker(int descriptor, PropertyConstness constness,
+ Representation representation,
Handle<FieldType> heap_type,
PropertyAttributes attributes = NONE)
: descriptor_(descriptor),
+ constness_(constness),
representation_(representation),
attributes_(attributes),
heap_type_(heap_type) {}
@@ -2259,8 +2496,8 @@ struct FieldGeneralizationChecker {
Handle<Map> updated_map = Map::Update(map1);
CHECK_EQ(*map2, *updated_map);
- expectations2.SetDataField(descriptor_, attributes_, representation_,
- heap_type_);
+ expectations2.SetDataField(descriptor_, attributes_, constness_,
+ representation_, heap_type_);
CHECK(expectations2.Check(*map2));
}
};
@@ -2315,7 +2552,8 @@ static void TestTransitionTo(TransitionOp1& transition_op1,
Handle<Map> initial_map = Map::Create(isolate, 0);
Handle<Map> map = initial_map;
for (int i = 0; i < kPropCount - 1; i++) {
- map = expectations.AddDataField(map, NONE, Representation::Smi(), any_type);
+ map = expectations.AddDataField(map, NONE, kMutable, Representation::Smi(),
+ any_type);
}
CHECK(expectations.Check(*map));
@@ -2338,15 +2576,15 @@ TEST(TransitionDataFieldToDataField) {
Handle<FieldType> any_type = FieldType::Any(isolate);
Handle<Object> value1 = handle(Smi::kZero, isolate);
- TransitionToDataFieldOperator transition_op1(Representation::Smi(), any_type,
- value1);
+ TransitionToDataFieldOperator transition_op1(kMutable, Representation::Smi(),
+ any_type, value1);
Handle<Object> value2 = isolate->factory()->NewHeapNumber(0);
- TransitionToDataFieldOperator transition_op2(Representation::Double(),
- any_type, value2);
+ TransitionToDataFieldOperator transition_op2(
+ kMutable, Representation::Double(), any_type, value2);
- FieldGeneralizationChecker checker(kPropCount - 1, Representation::Double(),
- any_type);
+ FieldGeneralizationChecker checker(kPropCount - 1, kMutable,
+ Representation::Double(), any_type);
TestTransitionTo(transition_op1, transition_op2, checker);
}
@@ -2386,9 +2624,15 @@ TEST(TransitionDataConstantToAnotherDataConstant) {
factory->NewFunction(sloppy_map, info, isolate->native_context());
TransitionToDataConstantOperator transition_op2(js_func2);
- FieldGeneralizationChecker checker(
- kPropCount - 1, Representation::HeapObject(), function_type);
- TestTransitionTo(transition_op1, transition_op2, checker);
+ if (FLAG_track_constant_fields) {
+ SameMapChecker checker;
+ TestTransitionTo(transition_op1, transition_op2, checker);
+
+ } else {
+ FieldGeneralizationChecker checker(
+ kPropCount - 1, kMutable, Representation::HeapObject(), function_type);
+ TestTransitionTo(transition_op1, transition_op2, checker);
+ }
}
@@ -2403,11 +2647,11 @@ TEST(TransitionDataConstantToDataField) {
TransitionToDataConstantOperator transition_op1(js_func1);
Handle<Object> value2 = isolate->factory()->NewHeapNumber(0);
- TransitionToDataFieldOperator transition_op2(Representation::Double(),
- any_type, value2);
+ TransitionToDataFieldOperator transition_op2(
+ kMutable, Representation::Double(), any_type, value2);
- FieldGeneralizationChecker checker(kPropCount - 1, Representation::Tagged(),
- any_type);
+ FieldGeneralizationChecker checker(kPropCount - 1, kMutable,
+ Representation::Tagged(), any_type);
TestTransitionTo(transition_op1, transition_op2, checker);
}
@@ -2436,3 +2680,31 @@ TEST(FieldTypeConvertSimple) {
// TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported.
// TEST(TransitionAccessorConstantToAnotherAccessorConstant)
+
+TEST(HoleyMutableHeapNumber) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+
+ Handle<HeapNumber> mhn = isolate->factory()->NewMutableHeapNumber();
+ CHECK_EQ(kHoleNanInt64, mhn->value_as_bits());
+
+ mhn = isolate->factory()->NewHeapNumber(0.0, MUTABLE);
+ CHECK_EQ(V8_UINT64_C(0), mhn->value_as_bits());
+
+ mhn->set_value_as_bits(kHoleNanInt64);
+ CHECK_EQ(kHoleNanInt64, mhn->value_as_bits());
+
+ // Ensure that new storage for uninitialized value or mutable heap number
+ // with uninitialized sentinel (kHoleNanInt64) is a mutable heap number
+ // with uninitialized sentinel.
+ Handle<Object> obj =
+ Object::NewStorageFor(isolate, isolate->factory()->uninitialized_value(),
+ Representation::Double());
+ CHECK(obj->IsMutableHeapNumber());
+ CHECK_EQ(kHoleNanInt64, HeapNumber::cast(*obj)->value_as_bits());
+
+ obj = Object::NewStorageFor(isolate, mhn, Representation::Double());
+ CHECK(obj->IsMutableHeapNumber());
+ CHECK_EQ(kHoleNanInt64, HeapNumber::cast(*obj)->value_as_bits());
+}