| 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;
|
| }
|
|
|