Index: src/compiler/access-info.cc |
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc |
index c3096e9974ffc3524eddbc9a066428682397a25e..9aef1651539b0c56ec62016566fae2e592c4e23e 100644 |
--- a/src/compiler/access-info.cc |
+++ b/src/compiler/access-info.cc |
@@ -133,7 +133,8 @@ PropertyAccessInfo::PropertyAccessInfo( |
field_type_(field_type), |
field_map_(field_map) {} |
-bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { |
+bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, |
+ AccessMode access_mode, Zone* zone) { |
if (this->kind_ != that->kind_) return false; |
if (this->holder_.address() != that->holder_.address()) return false; |
@@ -145,12 +146,40 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { |
case kDataConstantField: { |
// Check if we actually access the same field. |
if (this->kind_ == that->kind_ && |
- this->transition_map_.address() == that->transition_map_.address() && |
- this->field_index_ == that->field_index_ && |
- this->field_map_.address() == that->field_map_.address() && |
- this->field_type_->Is(that->field_type_) && |
- that->field_type_->Is(this->field_type_) && |
- this->field_representation_ == that->field_representation_) { |
+ this->field_index_ == that->field_index_) { |
+ switch (access_mode) { |
+ case AccessMode::kLoad: { |
+ if (this->field_representation_ != that->field_representation_) { |
+ if (!IsAnyTagged(this->field_representation_) || |
+ !IsAnyTagged(that->field_representation_)) { |
+ return false; |
+ } |
+ this->field_representation_ = MachineRepresentation::kTagged; |
+ } |
+ if (this->field_map_.address() != that->field_map_.address()) { |
+ this->field_map_ = MaybeHandle<Map>(); |
+ } |
+ break; |
+ } |
+ case AccessMode::kStore: |
+ case AccessMode::kStoreInLiteral: { |
+ // For stores, the field map and field representation information |
+ // must match exactly, otherwise we cannot merge the stores. We |
+ // also need to make sure that in case of transitioning stores, |
+ // the transition targets match. |
+ if (this->field_map_.address() != that->field_map_.address() || |
+ this->field_representation_ != that->field_representation_ || |
+ this->transition_map_.address() != |
+ that->transition_map_.address()) { |
+ return false; |
+ } |
+ break; |
+ } |
+ } |
+ // Merge the field type. |
+ this->field_type_ = |
+ Type::Union(this->field_type_, that->field_type_, zone); |
+ // Merge the receiver maps. |
this->receiver_maps_.insert(this->receiver_maps_.end(), |
that->receiver_maps_.begin(), |
that->receiver_maps_.end()); |
@@ -453,7 +482,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfos( |
// Try to merge the {access_info} with an existing one. |
bool merged = false; |
for (PropertyAccessInfo& other_info : *access_infos) { |
- if (other_info.Merge(&access_info)) { |
+ if (other_info.Merge(&access_info, access_mode, zone())) { |
merged = true; |
break; |
} |