summaryrefslogtreecommitdiff
path: root/deps/v8/src/map-updater.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/map-updater.cc')
-rw-r--r--deps/v8/src/map-updater.cc41
1 files changed, 39 insertions, 2 deletions
diff --git a/deps/v8/src/map-updater.cc b/deps/v8/src/map-updater.cc
index bfd2f80443..9157f8d7aa 100644
--- a/deps/v8/src/map-updater.cc
+++ b/deps/v8/src/map-updater.cc
@@ -123,6 +123,9 @@ Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor,
new_field_type_ = field_type;
}
+ GeneralizeIfTransitionableFastElementsKind(
+ &new_constness_, &new_representation_, &new_field_type_);
+
if (TryRecofigureToDataFieldInplace() == kEnd) return result_map_;
if (FindRootMap() == kEnd) return result_map_;
if (FindTargetMap() == kEnd) return result_map_;
@@ -134,6 +137,8 @@ Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor,
Handle<Map> MapUpdater::ReconfigureElementsKind(ElementsKind elements_kind) {
DCHECK_EQ(kInitialized, state_);
new_elements_kind_ = elements_kind;
+ is_transitionable_fast_elements_kind_ =
+ IsTransitionableFastElementsKind(new_elements_kind_);
if (FindRootMap() == kEnd) return result_map_;
if (FindTargetMap() == kEnd) return result_map_;
@@ -153,6 +158,28 @@ Handle<Map> MapUpdater::Update() {
return result_map_;
}
+void MapUpdater::GeneralizeIfTransitionableFastElementsKind(
+ PropertyConstness* constness, Representation* representation,
+ Handle<FieldType>* field_type) {
+ DCHECK_EQ(is_transitionable_fast_elements_kind_,
+ IsTransitionableFastElementsKind(new_elements_kind_));
+ if (is_transitionable_fast_elements_kind_ &&
+ Map::IsInplaceGeneralizableField(*constness, *representation,
+ **field_type)) {
+ // We don't support propagation of field generalization through elements
+ // kind transitions because they are inserted into the transition tree
+ // before field transitions. In order to avoid complexity of handling
+ // such a case we ensure that all maps with transitionable elements kinds
+ // do not have fields that can be generalized in-place (without creation
+ // of a new map).
+ if (FLAG_track_constant_fields && FLAG_modify_map_inplace) {
+ *constness = kMutable;
+ }
+ DCHECK(representation->IsHeapObject());
+ *field_type = FieldType::Any(isolate_);
+ }
+}
+
void MapUpdater::GeneralizeField(Handle<Map> map, int modify_index,
PropertyConstness new_constness,
Representation new_representation,
@@ -489,6 +516,9 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
old_details.representation(), old_field_type, next_representation,
target_field_type, isolate_);
+ GeneralizeIfTransitionableFastElementsKind(
+ &next_constness, &next_representation, &next_field_type);
+
Handle<Object> wrapped_type(Map::WrapFieldType(next_field_type));
Descriptor d;
if (next_kind == kData) {
@@ -532,10 +562,17 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
Descriptor d;
if (next_location == kField) {
- Handle<FieldType> old_field_type =
+ Handle<FieldType> next_field_type =
GetOrComputeFieldType(i, old_details.location(), next_representation);
- Handle<Object> wrapped_type(Map::WrapFieldType(old_field_type));
+ // If the |new_elements_kind_| is still transitionable then the old map's
+ // elements kind is also transitionable and therefore the old descriptors
+ // array must already have non in-place generalizable fields.
+ CHECK_IMPLIES(is_transitionable_fast_elements_kind_,
+ !Map::IsInplaceGeneralizableField(
+ next_constness, next_representation, *next_field_type));
+
+ Handle<Object> wrapped_type(Map::WrapFieldType(next_field_type));
Descriptor d;
if (next_kind == kData) {
DCHECK_IMPLIES(!FLAG_track_constant_fields, next_constness == kMutable);