| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 01b4a1aca09f61e9504b67a41f7f6abb66971e39..578fd95428b8a3a1e06dbc75dd0f72a7f106329d 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -2354,6 +2354,7 @@ Map* Map::FindFieldOwner(int descriptor) {
|
|
|
|
|
| void Map::UpdateFieldType(int descriptor, Handle<Name> name,
|
| + Representation new_representation,
|
| Handle<HeapType> new_type) {
|
| DisallowHeapAllocation no_allocation;
|
| PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
|
| @@ -2361,13 +2362,18 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
|
| if (HasTransitionArray()) {
|
| TransitionArray* transitions = this->transitions();
|
| for (int i = 0; i < transitions->number_of_transitions(); ++i) {
|
| - transitions->GetTarget(i)->UpdateFieldType(descriptor, name, new_type);
|
| + transitions->GetTarget(i)
|
| + ->UpdateFieldType(descriptor, name, new_representation, new_type);
|
| }
|
| }
|
| + // It is allowed to change representation here only from None to something.
|
| + DCHECK(details.representation().Equals(new_representation) ||
|
| + details.representation().IsNone());
|
| +
|
| // Skip if already updated the shared descriptor.
|
| if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return;
|
| FieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor),
|
| - new_type, details.attributes(), details.representation());
|
| + new_type, details.attributes(), new_representation);
|
| instance_descriptors()->Replace(descriptor, &d);
|
| }
|
|
|
| @@ -2393,15 +2399,20 @@ Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
|
|
|
|
|
| // static
|
| -void Map::GeneralizeFieldType(Handle<Map> map,
|
| - int modify_index,
|
| +void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
|
| + Representation new_representation,
|
| Handle<HeapType> new_field_type) {
|
| Isolate* isolate = map->GetIsolate();
|
|
|
| // Check if we actually need to generalize the field type at all.
|
| - Handle<HeapType> old_field_type(
|
| - map->instance_descriptors()->GetFieldType(modify_index), isolate);
|
| - if (new_field_type->NowIs(old_field_type)) {
|
| + Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
|
| + Representation old_representation =
|
| + old_descriptors->GetDetails(modify_index).representation();
|
| + Handle<HeapType> old_field_type(old_descriptors->GetFieldType(modify_index),
|
| + isolate);
|
| +
|
| + if (old_representation.Equals(new_representation) &&
|
| + new_field_type->NowIs(old_field_type)) {
|
| DCHECK(Map::GeneralizeFieldType(old_field_type,
|
| new_field_type,
|
| isolate)->NowIs(old_field_type));
|
| @@ -2420,7 +2431,8 @@ void Map::GeneralizeFieldType(Handle<Map> map,
|
|
|
| PropertyDetails details = descriptors->GetDetails(modify_index);
|
| Handle<Name> name(descriptors->GetKey(modify_index));
|
| - field_owner->UpdateFieldType(modify_index, name, new_field_type);
|
| + field_owner->UpdateFieldType(modify_index, name, new_representation,
|
| + new_field_type);
|
| field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
|
| isolate, DependentCode::kFieldTypeGroup);
|
|
|
| @@ -2471,12 +2483,9 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
|
| // modification to the object, because the default uninitialized value for
|
| // representation None can be overwritten by both smi and tagged values.
|
| // Doubles, however, would require a box allocation.
|
| - if (old_representation.IsNone() &&
|
| - !new_representation.IsNone() &&
|
| + if (old_representation.IsNone() && !new_representation.IsNone() &&
|
| !new_representation.IsDouble()) {
|
| DCHECK(old_details.type() == FIELD);
|
| - DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(
|
| - HeapType::None()));
|
| if (FLAG_trace_generalization) {
|
| old_map->PrintGeneralization(
|
| stdout, "uninitialized field",
|
| @@ -2485,8 +2494,13 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
|
| old_representation, new_representation,
|
| old_descriptors->GetFieldType(modify_index), *new_field_type);
|
| }
|
| - old_descriptors->SetRepresentation(modify_index, new_representation);
|
| - old_descriptors->SetValue(modify_index, *new_field_type);
|
| + Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate);
|
| +
|
| + GeneralizeFieldType(field_owner, modify_index, new_representation,
|
| + new_field_type);
|
| + DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals(
|
| + new_representation));
|
| + DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type));
|
| return old_map;
|
| }
|
|
|
| @@ -2547,7 +2561,7 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
|
| old_field_type = GeneralizeFieldType(
|
| new_field_type, old_field_type, isolate);
|
| }
|
| - GeneralizeFieldType(tmp_map, i, old_field_type);
|
| + GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type);
|
| } else if (tmp_type == CONSTANT) {
|
| if (old_type != CONSTANT ||
|
| old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) {
|
|
|