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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 } | 88 } |
89 | 89 |
90 // static | 90 // static |
91 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( | 91 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( |
92 MapList const& receiver_maps, Handle<Object> constant, | 92 MapList const& receiver_maps, Handle<Object> constant, |
93 MaybeHandle<JSObject> holder) { | 93 MaybeHandle<JSObject> holder) { |
94 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); | 94 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); |
95 } | 95 } |
96 | 96 |
97 // static | 97 // static |
| 98 PropertyAccessInfo PropertyAccessInfo::FunctionPrototype( |
| 99 MapList const& receiver_maps) { |
| 100 return PropertyAccessInfo(kFunctionPrototype, MaybeHandle<JSObject>(), |
| 101 Handle<Object>(), receiver_maps); |
| 102 } |
| 103 |
| 104 // static |
98 PropertyAccessInfo PropertyAccessInfo::Generic(MapList const& receiver_maps) { | 105 PropertyAccessInfo PropertyAccessInfo::Generic(MapList const& receiver_maps) { |
99 return PropertyAccessInfo(kGeneric, MaybeHandle<JSObject>(), Handle<Object>(), | 106 return PropertyAccessInfo(kGeneric, MaybeHandle<JSObject>(), Handle<Object>(), |
100 receiver_maps); | 107 receiver_maps); |
101 } | 108 } |
102 | 109 |
103 PropertyAccessInfo::PropertyAccessInfo() | 110 PropertyAccessInfo::PropertyAccessInfo() |
104 : kind_(kInvalid), | 111 : kind_(kInvalid), |
105 field_representation_(MachineRepresentation::kNone), | 112 field_representation_(MachineRepresentation::kNone), |
106 field_type_(Type::None()) {} | 113 field_type_(Type::None()) {} |
107 | 114 |
(...skipping 29 matching lines...) Expand all Loading... |
137 field_map_(field_map) {} | 144 field_map_(field_map) {} |
138 | 145 |
139 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { | 146 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { |
140 if (this->kind_ != that->kind_) return false; | 147 if (this->kind_ != that->kind_) return false; |
141 if (this->holder_.address() != that->holder_.address()) return false; | 148 if (this->holder_.address() != that->holder_.address()) return false; |
142 | 149 |
143 switch (this->kind_) { | 150 switch (this->kind_) { |
144 case kInvalid: | 151 case kInvalid: |
145 break; | 152 break; |
146 | 153 |
147 case kNotFound: | |
148 return true; | |
149 | |
150 case kDataField: { | 154 case kDataField: { |
151 // Check if we actually access the same field. | 155 // Check if we actually access the same field. |
152 if (this->transition_map_.address() == that->transition_map_.address() && | 156 if (this->transition_map_.address() == that->transition_map_.address() && |
153 this->field_index_ == that->field_index_ && | 157 this->field_index_ == that->field_index_ && |
154 this->field_type_->Is(that->field_type_) && | 158 this->field_type_->Is(that->field_type_) && |
155 that->field_type_->Is(this->field_type_) && | 159 that->field_type_->Is(this->field_type_) && |
156 this->field_representation_ == that->field_representation_) { | 160 this->field_representation_ == that->field_representation_) { |
157 this->receiver_maps_.insert(this->receiver_maps_.end(), | 161 this->receiver_maps_.insert(this->receiver_maps_.end(), |
158 that->receiver_maps_.begin(), | 162 that->receiver_maps_.begin(), |
159 that->receiver_maps_.end()); | 163 that->receiver_maps_.end()); |
160 return true; | 164 return true; |
161 } | 165 } |
162 return false; | 166 return false; |
163 } | 167 } |
164 | 168 |
165 case kDataConstant: | 169 case kDataConstant: |
166 case kAccessorConstant: { | 170 case kAccessorConstant: { |
167 // Check if we actually access the same constant. | 171 // Check if we actually access the same constant. |
168 if (this->constant_.address() == that->constant_.address()) { | 172 if (this->constant_.address() == that->constant_.address()) { |
169 this->receiver_maps_.insert(this->receiver_maps_.end(), | 173 this->receiver_maps_.insert(this->receiver_maps_.end(), |
170 that->receiver_maps_.begin(), | 174 that->receiver_maps_.begin(), |
171 that->receiver_maps_.end()); | 175 that->receiver_maps_.end()); |
172 return true; | 176 return true; |
173 } | 177 } |
174 return false; | 178 return false; |
175 } | 179 } |
| 180 |
| 181 case kNotFound: |
| 182 case kFunctionPrototype: |
176 case kGeneric: { | 183 case kGeneric: { |
177 this->receiver_maps_.insert(this->receiver_maps_.end(), | 184 this->receiver_maps_.insert(this->receiver_maps_.end(), |
178 that->receiver_maps_.begin(), | 185 that->receiver_maps_.begin(), |
179 that->receiver_maps_.end()); | 186 that->receiver_maps_.end()); |
180 return true; | 187 return true; |
181 } | 188 } |
182 } | 189 } |
183 | 190 |
184 UNREACHABLE(); | 191 UNREACHABLE(); |
185 return false; | 192 return false; |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 } | 449 } |
443 if (!merged) access_infos->push_back(access_info); | 450 if (!merged) access_infos->push_back(access_info); |
444 } | 451 } |
445 } | 452 } |
446 return true; | 453 return true; |
447 } | 454 } |
448 | 455 |
449 | 456 |
450 bool AccessInfoFactory::LookupSpecialFieldAccessor( | 457 bool AccessInfoFactory::LookupSpecialFieldAccessor( |
451 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { | 458 Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) { |
| 459 // Check for Function::prototype accessor. |
| 460 if (map->IsJSFunctionMap() && map->is_constructor() && |
| 461 name.is_identical_to(factory()->prototype_string())) { |
| 462 DCHECK(!map->has_non_instance_prototype()); |
| 463 *access_info = PropertyAccessInfo::FunctionPrototype(MapList{map}); |
| 464 return true; |
| 465 } |
452 // Check for special JSObject field accessors. | 466 // Check for special JSObject field accessors. |
453 int offset; | 467 int offset; |
454 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { | 468 if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) { |
455 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); | 469 FieldIndex field_index = FieldIndex::ForInObjectOffset(offset); |
456 Type* field_type = Type::NonInternal(); | 470 Type* field_type = Type::NonInternal(); |
457 MachineRepresentation field_representation = MachineRepresentation::kTagged; | 471 MachineRepresentation field_representation = MachineRepresentation::kTagged; |
458 if (map->IsStringMap()) { | 472 if (map->IsStringMap()) { |
459 DCHECK(Name::Equals(factory()->length_string(), name)); | 473 DCHECK(Name::Equals(factory()->length_string(), name)); |
460 // The String::length property is always a smi in the range | 474 // The String::length property is always a smi in the range |
461 // [0, String::kMaxLength]. | 475 // [0, String::kMaxLength]. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 } | 560 } |
547 return false; | 561 return false; |
548 } | 562 } |
549 | 563 |
550 | 564 |
551 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } | 565 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } |
552 | 566 |
553 } // namespace compiler | 567 } // namespace compiler |
554 } // namespace internal | 568 } // namespace internal |
555 } // namespace v8 | 569 } // namespace v8 |
OLD | NEW |