OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <ostream> | 5 #include <ostream> |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
9 #include "src/compiler/access-info.h" | 9 #include "src/compiler/access-info.h" |
10 #include "src/compiler/type-cache.h" | 10 #include "src/compiler/type-cache.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 Type* field_type, MaybeHandle<Map> field_map, MapList const& receiver_maps) | 126 Type* field_type, MaybeHandle<Map> field_map, MapList const& receiver_maps) |
127 : kind_(kind), | 127 : kind_(kind), |
128 receiver_maps_(receiver_maps), | 128 receiver_maps_(receiver_maps), |
129 transition_map_(transition_map), | 129 transition_map_(transition_map), |
130 holder_(holder), | 130 holder_(holder), |
131 field_index_(field_index), | 131 field_index_(field_index), |
132 field_representation_(field_representation), | 132 field_representation_(field_representation), |
133 field_type_(field_type), | 133 field_type_(field_type), |
134 field_map_(field_map) {} | 134 field_map_(field_map) {} |
135 | 135 |
136 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { | 136 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that, |
| 137 AccessMode access_mode, Zone* zone) { |
137 if (this->kind_ != that->kind_) return false; | 138 if (this->kind_ != that->kind_) return false; |
138 if (this->holder_.address() != that->holder_.address()) return false; | 139 if (this->holder_.address() != that->holder_.address()) return false; |
139 | 140 |
140 switch (this->kind_) { | 141 switch (this->kind_) { |
141 case kInvalid: | 142 case kInvalid: |
142 break; | 143 break; |
143 | 144 |
144 case kDataField: | 145 case kDataField: |
145 case kDataConstantField: { | 146 case kDataConstantField: { |
146 // Check if we actually access the same field. | 147 // Check if we actually access the same field. |
147 if (this->kind_ == that->kind_ && | 148 if (this->kind_ == that->kind_ && |
148 this->transition_map_.address() == that->transition_map_.address() && | 149 this->field_index_ == that->field_index_) { |
149 this->field_index_ == that->field_index_ && | 150 switch (access_mode) { |
150 this->field_map_.address() == that->field_map_.address() && | 151 case AccessMode::kLoad: { |
151 this->field_type_->Is(that->field_type_) && | 152 if (this->field_representation_ != that->field_representation_) { |
152 that->field_type_->Is(this->field_type_) && | 153 if (!IsAnyTagged(this->field_representation_) || |
153 this->field_representation_ == that->field_representation_) { | 154 !IsAnyTagged(that->field_representation_)) { |
| 155 return false; |
| 156 } |
| 157 this->field_representation_ = MachineRepresentation::kTagged; |
| 158 } |
| 159 if (this->field_map_.address() != that->field_map_.address()) { |
| 160 this->field_map_ = MaybeHandle<Map>(); |
| 161 } |
| 162 break; |
| 163 } |
| 164 case AccessMode::kStore: |
| 165 case AccessMode::kStoreInLiteral: { |
| 166 // For stores, the field map and field representation information |
| 167 // must match exactly, otherwise we cannot merge the stores. We |
| 168 // also need to make sure that in case of transitioning stores, |
| 169 // the transition targets match. |
| 170 if (this->field_map_.address() != that->field_map_.address() || |
| 171 this->field_representation_ != that->field_representation_ || |
| 172 this->transition_map_.address() != |
| 173 that->transition_map_.address()) { |
| 174 return false; |
| 175 } |
| 176 break; |
| 177 } |
| 178 } |
| 179 // Merge the field type. |
| 180 this->field_type_ = |
| 181 Type::Union(this->field_type_, that->field_type_, zone); |
| 182 // Merge the receiver maps. |
154 this->receiver_maps_.insert(this->receiver_maps_.end(), | 183 this->receiver_maps_.insert(this->receiver_maps_.end(), |
155 that->receiver_maps_.begin(), | 184 that->receiver_maps_.begin(), |
156 that->receiver_maps_.end()); | 185 that->receiver_maps_.end()); |
157 return true; | 186 return true; |
158 } | 187 } |
159 return false; | 188 return false; |
160 } | 189 } |
161 | 190 |
162 case kDataConstant: | 191 case kDataConstant: |
163 case kAccessorConstant: { | 192 case kAccessorConstant: { |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 ZoneVector<PropertyAccessInfo>* access_infos) { | 475 ZoneVector<PropertyAccessInfo>* access_infos) { |
447 for (Handle<Map> map : maps) { | 476 for (Handle<Map> map : maps) { |
448 if (Map::TryUpdate(map).ToHandle(&map)) { | 477 if (Map::TryUpdate(map).ToHandle(&map)) { |
449 PropertyAccessInfo access_info; | 478 PropertyAccessInfo access_info; |
450 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) { | 479 if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) { |
451 return false; | 480 return false; |
452 } | 481 } |
453 // Try to merge the {access_info} with an existing one. | 482 // Try to merge the {access_info} with an existing one. |
454 bool merged = false; | 483 bool merged = false; |
455 for (PropertyAccessInfo& other_info : *access_infos) { | 484 for (PropertyAccessInfo& other_info : *access_infos) { |
456 if (other_info.Merge(&access_info)) { | 485 if (other_info.Merge(&access_info, access_mode, zone())) { |
457 merged = true; | 486 merged = true; |
458 break; | 487 break; |
459 } | 488 } |
460 } | 489 } |
461 if (!merged) access_infos->push_back(access_info); | 490 if (!merged) access_infos->push_back(access_info); |
462 } | 491 } |
463 } | 492 } |
464 return true; | 493 return true; |
465 } | 494 } |
466 | 495 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 } | 591 } |
563 return false; | 592 return false; |
564 } | 593 } |
565 | 594 |
566 | 595 |
567 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } | 596 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } |
568 | 597 |
569 } // namespace compiler | 598 } // namespace compiler |
570 } // namespace internal | 599 } // namespace internal |
571 } // namespace v8 | 600 } // namespace v8 |
OLD | NEW |