| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 7db54aa811e7ce2ed260f4ec729675231fd830bd..1666d40b28a530e9193c7162ea718ad557fa1780 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -2726,10 +2726,23 @@ void Map::UpdateFieldType(int descriptor, Handle<Name> name,
|
| }
|
|
|
|
|
| +bool FieldTypeIsCleared(Representation rep, Handle<HeapType> type) {
|
| + return type->Is(HeapType::None()) && rep.IsHeapObject();
|
| +}
|
| +
|
| +
|
| // static
|
| -Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
|
| +Handle<HeapType> Map::GeneralizeFieldType(Representation rep1,
|
| + Handle<HeapType> type1,
|
| + Representation rep2,
|
| Handle<HeapType> type2,
|
| Isolate* isolate) {
|
| + // Cleared field types need special treatment. They represent lost knowledge,
|
| + // so we must be conservative, so their generalization with any other type
|
| + // is "Any".
|
| + if (FieldTypeIsCleared(rep1, type1) || FieldTypeIsCleared(rep2, type2)) {
|
| + return HeapType::Any(isolate);
|
| + }
|
| if (type1->NowIs(type2)) return type2;
|
| if (type2->NowIs(type1)) return type1;
|
| return HeapType::Any(isolate);
|
| @@ -2750,10 +2763,13 @@ void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
|
| isolate);
|
|
|
| if (old_representation.Equals(new_representation) &&
|
| + !FieldTypeIsCleared(new_representation, new_field_type) &&
|
| + // Checking old_field_type for being cleared is not necessary because
|
| + // the NowIs check below would fail anyway in that case.
|
| new_field_type->NowIs(old_field_type)) {
|
| - DCHECK(Map::GeneralizeFieldType(old_field_type,
|
| - new_field_type,
|
| - isolate)->NowIs(old_field_type));
|
| + DCHECK(Map::GeneralizeFieldType(old_representation, old_field_type,
|
| + new_representation, new_field_type, isolate)
|
| + ->NowIs(old_field_type));
|
| return;
|
| }
|
|
|
| @@ -2762,17 +2778,10 @@ void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
|
| Handle<DescriptorArray> descriptors(
|
| field_owner->instance_descriptors(), isolate);
|
| DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index));
|
| - bool old_field_type_was_cleared =
|
| - old_field_type->Is(HeapType::None()) && old_representation.IsHeapObject();
|
|
|
| - // Determine the generalized new field type. Conservatively assume type Any
|
| - // for cleared field types because the cleared type could have been a
|
| - // deprecated map and there still could be live instances with a non-
|
| - // deprecated version of the map.
|
| new_field_type =
|
| - old_field_type_was_cleared
|
| - ? HeapType::Any(isolate)
|
| - : Map::GeneralizeFieldType(old_field_type, new_field_type, isolate);
|
| + Map::GeneralizeFieldType(old_representation, old_field_type,
|
| + new_representation, new_field_type, isolate);
|
|
|
| PropertyDetails details = descriptors->GetDetails(modify_index);
|
| Handle<Name> name(descriptors->GetKey(modify_index));
|
| @@ -2996,8 +3005,10 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
|
| Handle<HeapType> old_field_type =
|
| GetFieldType(isolate, old_descriptors, i,
|
| old_details.location(), tmp_representation);
|
| - next_field_type =
|
| - GeneralizeFieldType(next_field_type, old_field_type, isolate);
|
| + Representation old_representation = old_details.representation();
|
| + next_field_type = GeneralizeFieldType(
|
| + old_representation, old_field_type, new_representation,
|
| + next_field_type, isolate);
|
| }
|
| } else {
|
| Handle<HeapType> old_field_type =
|
| @@ -3161,21 +3172,24 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
|
|
|
| Handle<HeapType> next_field_type;
|
| if (modify_index == i) {
|
| - next_field_type =
|
| - GeneralizeFieldType(target_field_type, new_field_type, isolate);
|
| + next_field_type = GeneralizeFieldType(
|
| + target_details.representation(), target_field_type,
|
| + new_representation, new_field_type, isolate);
|
| if (!property_kind_reconfiguration) {
|
| Handle<HeapType> old_field_type =
|
| GetFieldType(isolate, old_descriptors, i,
|
| old_details.location(), next_representation);
|
| - next_field_type =
|
| - GeneralizeFieldType(next_field_type, old_field_type, isolate);
|
| + next_field_type = GeneralizeFieldType(
|
| + old_details.representation(), old_field_type,
|
| + next_representation, next_field_type, isolate);
|
| }
|
| } else {
|
| Handle<HeapType> old_field_type =
|
| GetFieldType(isolate, old_descriptors, i, old_details.location(),
|
| next_representation);
|
| - next_field_type =
|
| - GeneralizeFieldType(target_field_type, old_field_type, isolate);
|
| + next_field_type = GeneralizeFieldType(
|
| + old_details.representation(), old_field_type, next_representation,
|
| + target_field_type, isolate);
|
| }
|
| Handle<Object> wrapped_type(WrapType(next_field_type));
|
| DataDescriptor d(target_key, current_offset, wrapped_type,
|
| @@ -3236,8 +3250,9 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
|
| Handle<HeapType> old_field_type =
|
| GetFieldType(isolate, old_descriptors, i,
|
| old_details.location(), next_representation);
|
| - next_field_type =
|
| - GeneralizeFieldType(next_field_type, old_field_type, isolate);
|
| + next_field_type = GeneralizeFieldType(
|
| + old_details.representation(), old_field_type,
|
| + next_representation, next_field_type, isolate);
|
| }
|
| } else {
|
| Handle<HeapType> old_field_type =
|
| @@ -3798,6 +3813,11 @@ MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
|
| Object);
|
| }
|
|
|
| +#if VERIFY_HEAP
|
| + if (FLAG_verify_heap) {
|
| + receiver->JSObjectVerify();
|
| + }
|
| +#endif
|
| return value;
|
| }
|
|
|
| @@ -3920,6 +3940,11 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
|
| it->factory()->the_hole_value()),
|
| Object);
|
| }
|
| +#if VERIFY_HEAP
|
| + if (FLAG_verify_heap) {
|
| + receiver->JSObjectVerify();
|
| + }
|
| +#endif
|
| }
|
|
|
| return value;
|
| @@ -4572,6 +4597,11 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
|
| if (FLAG_trace_migration) {
|
| object->PrintInstanceMigration(stdout, *original_map, *map);
|
| }
|
| +#if VERIFY_HEAP
|
| + if (FLAG_verify_heap) {
|
| + object->JSObjectVerify();
|
| + }
|
| +#endif
|
| }
|
|
|
|
|
| @@ -4588,6 +4618,11 @@ bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
|
| if (FLAG_trace_migration) {
|
| object->PrintInstanceMigration(stdout, *original_map, object->map());
|
| }
|
| +#if VERIFY_HEAP
|
| + if (FLAG_verify_heap) {
|
| + object->JSObjectVerify();
|
| + }
|
| +#endif
|
| return true;
|
| }
|
|
|
| @@ -4696,7 +4731,6 @@ MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
|
| it->TransitionToAccessorPair(new_data, attributes);
|
| } else {
|
| it->ReconfigureDataProperty(value, attributes);
|
| - it->WriteDataValue(value);
|
| }
|
|
|
| if (is_observed) {
|
| @@ -4732,7 +4766,6 @@ MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
|
| if (is_observed) old_value = it->GetDataValue();
|
|
|
| it->ReconfigureDataProperty(value, attributes);
|
| - it->WriteDataValue(value);
|
|
|
| if (is_observed) {
|
| if (old_value->SameValue(*value)) {
|
|
|