| Index: src/map-updater.cc
|
| diff --git a/src/map-updater.cc b/src/map-updater.cc
|
| index a9b9a60f6d06522fe5e22806a526ece70178f90e..e6dec658fd56ef531f7014a15cda175d42b0bff8 100644
|
| --- a/src/map-updater.cc
|
| +++ b/src/map-updater.cc
|
| @@ -22,10 +22,6 @@ inline bool EqualImmutableValues(Object* obj1, Object* obj2) {
|
| return false;
|
| }
|
|
|
| -inline bool LocationFitsInto(PropertyLocation what, PropertyLocation where) {
|
| - return where == kField || what == kDescriptor;
|
| -}
|
| -
|
| } // namespace
|
|
|
| Name* MapUpdater::GetKey(int descriptor) const {
|
| @@ -36,7 +32,7 @@ PropertyDetails MapUpdater::GetDetails(int descriptor) const {
|
| DCHECK_LE(0, descriptor);
|
| if (descriptor == modified_descriptor_) {
|
| return PropertyDetails(new_kind_, new_attributes_, new_location_,
|
| - new_representation_);
|
| + new_constness_, new_representation_);
|
| }
|
| return old_descriptors_->GetDetails(descriptor);
|
| }
|
| @@ -98,8 +94,6 @@ Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor,
|
| new_kind_ = kData;
|
| new_attributes_ = attributes;
|
| new_location_ = kField;
|
| - new_representation_ = representation;
|
| - new_field_type_ = field_type;
|
|
|
| PropertyDetails old_details =
|
| old_descriptors_->GetDetails(modified_descriptor_);
|
| @@ -107,16 +101,25 @@ Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor,
|
| // If property kind is not reconfigured merge the result with
|
| // representation/field type from the old descriptor.
|
| if (old_details.kind() == new_kind_) {
|
| + new_constness_ = old_details.constness();
|
| +
|
| Representation old_representation = old_details.representation();
|
| - new_representation_ = new_representation_.generalize(old_representation);
|
| + new_representation_ = representation.generalize(old_representation);
|
|
|
| Handle<FieldType> old_field_type =
|
| GetOrComputeFieldType(old_descriptors_, modified_descriptor_,
|
| old_details.location(), new_representation_);
|
|
|
| - new_field_type_ = Map::GeneralizeFieldType(
|
| - old_representation, old_field_type, new_representation_,
|
| - new_field_type_, isolate_);
|
| + new_field_type_ =
|
| + Map::GeneralizeFieldType(old_representation, old_field_type,
|
| + new_representation_, field_type, isolate_);
|
| + } else {
|
| + // We don't know if this is a first property kind reconfiguration
|
| + // and we don't know which value was in this property previously
|
| + // therefore we can't treat such a property as constant.
|
| + new_constness_ = kMutable;
|
| + new_representation_ = representation;
|
| + new_field_type_ = field_type;
|
| }
|
|
|
| if (TryRecofigureToDataFieldInplace() == kEnd) return result_map_;
|
| @@ -228,10 +231,11 @@ MapUpdater::State MapUpdater::FindRootMap() {
|
| old_details.attributes() != new_attributes_) {
|
| return CopyGeneralizeAllFields("GenAll_RootModification1");
|
| }
|
| - if (!new_representation_.fits_into(old_details.representation())) {
|
| + if (old_details.location() != kField) {
|
| return CopyGeneralizeAllFields("GenAll_RootModification2");
|
| }
|
| - if (old_details.location() != kField) {
|
| + DCHECK_EQ(kMutable, old_details.constness());
|
| + if (!new_representation_.fits_into(old_details.representation())) {
|
| return CopyGeneralizeAllFields("GenAll_RootModification3");
|
| }
|
| DCHECK_EQ(kData, old_details.kind());
|
| @@ -276,8 +280,12 @@ MapUpdater::State MapUpdater::FindTargetMap() {
|
| // TODO(ishell): mutable accessors are not implemented yet.
|
| return CopyGeneralizeAllFields("GenAll_Incompatible");
|
| }
|
| + // Check if old constness fits into tmp constness.
|
| + if (!IsGeneralizableTo(old_details.constness(), tmp_details.constness())) {
|
| + break;
|
| + }
|
| // Check if old location fits into tmp location.
|
| - if (!LocationFitsInto(old_details.location(), tmp_details.location())) {
|
| + if (!IsGeneralizableTo(old_details.location(), tmp_details.location())) {
|
| break;
|
| }
|
|
|
| @@ -341,7 +349,6 @@ MapUpdater::State MapUpdater::FindTargetMap() {
|
| Handle<Map> tmp_map(transition, isolate_);
|
| Handle<DescriptorArray> tmp_descriptors(tmp_map->instance_descriptors(),
|
| isolate_);
|
| -
|
| #ifdef DEBUG
|
| // Check that target map is compatible.
|
| PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
|
| @@ -404,6 +411,14 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
|
|
| PropertyKind next_kind = old_details.kind();
|
| PropertyAttributes next_attributes = old_details.attributes();
|
| + DCHECK_EQ(next_kind, target_details.kind());
|
| + DCHECK_EQ(next_attributes, target_details.attributes());
|
| +
|
| + PropertyConstness next_constness = GeneralizeConstness(
|
| + old_details.constness(), target_details.constness());
|
| +
|
| + // Note: failed values equality check does not invalidate per-object
|
| + // property constness.
|
| PropertyLocation next_location =
|
| old_details.location() == kField ||
|
| target_details.location() == kField ||
|
| @@ -412,13 +427,15 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
| ? kField
|
| : kDescriptor;
|
|
|
| + // TODO(ishell): remove once constant field tracking is done.
|
| + if (next_location == kField) next_constness = kMutable;
|
| + // Ensure that mutable values are stored in fields.
|
| + DCHECK_IMPLIES(next_constness == kMutable, next_location == kField);
|
| +
|
| Representation next_representation =
|
| old_details.representation().generalize(
|
| target_details.representation());
|
|
|
| - DCHECK_EQ(next_kind, target_details.kind());
|
| - DCHECK_EQ(next_attributes, target_details.attributes());
|
| -
|
| if (next_location == kField) {
|
| Handle<FieldType> old_field_type =
|
| GetOrComputeFieldType(i, old_details.location(), next_representation);
|
| @@ -434,8 +451,9 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
| Handle<Object> wrapped_type(Map::WrapFieldType(next_field_type));
|
| Descriptor d;
|
| if (next_kind == kData) {
|
| - d = Descriptor::DataField(key, current_offset, wrapped_type,
|
| - next_attributes, next_representation);
|
| + d = Descriptor::DataField(key, current_offset, next_attributes,
|
| + next_constness, next_representation,
|
| + wrapped_type);
|
| } else {
|
| // TODO(ishell): mutable accessors are not implemented yet.
|
| UNIMPLEMENTED();
|
| @@ -444,6 +462,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
| new_descriptors->Set(i, &d);
|
| } else {
|
| DCHECK_EQ(kDescriptor, next_location);
|
| + DCHECK_EQ(kConst, next_constness);
|
|
|
| Handle<Object> value(GetValue(i), isolate_);
|
| Descriptor d;
|
| @@ -465,19 +484,22 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
|
|
| PropertyKind next_kind = old_details.kind();
|
| PropertyAttributes next_attributes = old_details.attributes();
|
| + PropertyConstness next_constness = old_details.constness();
|
| PropertyLocation next_location = old_details.location();
|
| Representation next_representation = old_details.representation();
|
|
|
| Descriptor d;
|
| if (next_location == kField) {
|
| + DCHECK_EQ(kMutable, next_constness);
|
| Handle<FieldType> old_field_type =
|
| GetOrComputeFieldType(i, old_details.location(), next_representation);
|
|
|
| Handle<Object> wrapped_type(Map::WrapFieldType(old_field_type));
|
| Descriptor d;
|
| if (next_kind == kData) {
|
| - d = Descriptor::DataField(key, current_offset, wrapped_type,
|
| - next_attributes, next_representation);
|
| + d = Descriptor::DataField(key, current_offset, next_attributes,
|
| + next_constness, next_representation,
|
| + wrapped_type);
|
| } else {
|
| // TODO(ishell): mutable accessors are not implemented yet.
|
| UNIMPLEMENTED();
|
| @@ -486,6 +508,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() {
|
| new_descriptors->Set(i, &d);
|
| } else {
|
| DCHECK_EQ(kDescriptor, next_location);
|
| + DCHECK_EQ(kConst, next_constness);
|
|
|
| Handle<Object> value(GetValue(i), isolate_);
|
| if (next_kind == kData) {
|
| @@ -518,6 +541,7 @@ Handle<Map> MapUpdater::FindSplitMap(Handle<DescriptorArray> descriptors) {
|
| PropertyDetails next_details = next_descriptors->GetDetails(i);
|
| DCHECK_EQ(details.kind(), next_details.kind());
|
| DCHECK_EQ(details.attributes(), next_details.attributes());
|
| + if (details.constness() != next_details.constness()) break;
|
| if (details.location() != next_details.location()) break;
|
| if (!details.representation().Equals(next_details.representation())) break;
|
|
|
|
|