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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 PropertyAccessInfo PropertyAccessInfo::DataConstant( | 74 PropertyAccessInfo PropertyAccessInfo::DataConstant( |
75 MapList const& receiver_maps, Handle<Object> constant, | 75 MapList const& receiver_maps, Handle<Object> constant, |
76 MaybeHandle<JSObject> holder) { | 76 MaybeHandle<JSObject> holder) { |
77 return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps); | 77 return PropertyAccessInfo(kDataConstant, holder, constant, receiver_maps); |
78 } | 78 } |
79 | 79 |
80 // static | 80 // static |
81 PropertyAccessInfo PropertyAccessInfo::DataField( | 81 PropertyAccessInfo PropertyAccessInfo::DataField( |
82 MapList const& receiver_maps, FieldIndex field_index, | 82 MapList const& receiver_maps, FieldIndex field_index, |
83 MachineRepresentation field_representation, Type* field_type, | 83 MachineRepresentation field_representation, Type* field_type, |
84 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map) { | 84 MaybeHandle<Map> field_map, MaybeHandle<JSObject> holder, |
| 85 MaybeHandle<Map> transition_map) { |
85 return PropertyAccessInfo(holder, transition_map, field_index, | 86 return PropertyAccessInfo(holder, transition_map, field_index, |
86 field_representation, field_type, receiver_maps); | 87 field_representation, field_type, field_map, |
| 88 receiver_maps); |
87 } | 89 } |
88 | 90 |
89 // static | 91 // static |
90 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( | 92 PropertyAccessInfo PropertyAccessInfo::AccessorConstant( |
91 MapList const& receiver_maps, Handle<Object> constant, | 93 MapList const& receiver_maps, Handle<Object> constant, |
92 MaybeHandle<JSObject> holder) { | 94 MaybeHandle<JSObject> holder) { |
93 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); | 95 return PropertyAccessInfo(kAccessorConstant, holder, constant, receiver_maps); |
94 } | 96 } |
95 | 97 |
96 PropertyAccessInfo::PropertyAccessInfo() | 98 PropertyAccessInfo::PropertyAccessInfo() |
(...skipping 15 matching lines...) Expand all Loading... |
112 : kind_(kind), | 114 : kind_(kind), |
113 receiver_maps_(receiver_maps), | 115 receiver_maps_(receiver_maps), |
114 constant_(constant), | 116 constant_(constant), |
115 holder_(holder), | 117 holder_(holder), |
116 field_representation_(MachineRepresentation::kNone), | 118 field_representation_(MachineRepresentation::kNone), |
117 field_type_(Type::Any()) {} | 119 field_type_(Type::Any()) {} |
118 | 120 |
119 PropertyAccessInfo::PropertyAccessInfo( | 121 PropertyAccessInfo::PropertyAccessInfo( |
120 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map, | 122 MaybeHandle<JSObject> holder, MaybeHandle<Map> transition_map, |
121 FieldIndex field_index, MachineRepresentation field_representation, | 123 FieldIndex field_index, MachineRepresentation field_representation, |
122 Type* field_type, MapList const& receiver_maps) | 124 Type* field_type, MaybeHandle<Map> field_map, MapList const& receiver_maps) |
123 : kind_(kDataField), | 125 : kind_(kDataField), |
124 receiver_maps_(receiver_maps), | 126 receiver_maps_(receiver_maps), |
125 transition_map_(transition_map), | 127 transition_map_(transition_map), |
126 holder_(holder), | 128 holder_(holder), |
127 field_index_(field_index), | 129 field_index_(field_index), |
128 field_representation_(field_representation), | 130 field_representation_(field_representation), |
129 field_type_(field_type) {} | 131 field_type_(field_type), |
| 132 field_map_(field_map) {} |
130 | 133 |
131 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { | 134 bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) { |
132 if (this->kind_ != that->kind_) return false; | 135 if (this->kind_ != that->kind_) return false; |
133 if (this->holder_.address() != that->holder_.address()) return false; | 136 if (this->holder_.address() != that->holder_.address()) return false; |
134 | 137 |
135 switch (this->kind_) { | 138 switch (this->kind_) { |
136 case kInvalid: | 139 case kInvalid: |
137 break; | 140 break; |
138 | 141 |
139 case kNotFound: | 142 case kNotFound: |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 *access_info = PropertyAccessInfo::DataConstant( | 289 *access_info = PropertyAccessInfo::DataConstant( |
287 MapList{receiver_map}, | 290 MapList{receiver_map}, |
288 handle(descriptors->GetValue(number), isolate()), holder); | 291 handle(descriptors->GetValue(number), isolate()), holder); |
289 return true; | 292 return true; |
290 } | 293 } |
291 case DATA: { | 294 case DATA: { |
292 int index = descriptors->GetFieldIndex(number); | 295 int index = descriptors->GetFieldIndex(number); |
293 Representation details_representation = details.representation(); | 296 Representation details_representation = details.representation(); |
294 FieldIndex field_index = FieldIndex::ForPropertyIndex( | 297 FieldIndex field_index = FieldIndex::ForPropertyIndex( |
295 *map, index, details_representation.IsDouble()); | 298 *map, index, details_representation.IsDouble()); |
296 Type* field_type = Type::Tagged(); | 299 Type* field_type = Type::NonInternal(); |
297 MachineRepresentation field_representation = | 300 MachineRepresentation field_representation = |
298 MachineRepresentation::kTagged; | 301 MachineRepresentation::kTagged; |
| 302 MaybeHandle<Map> field_map; |
299 if (details_representation.IsSmi()) { | 303 if (details_representation.IsSmi()) { |
300 field_type = type_cache_.kSmi; | 304 field_type = type_cache_.kSmi; |
301 field_representation = MachineRepresentation::kTaggedSigned; | 305 field_representation = MachineRepresentation::kTaggedSigned; |
302 } else if (details_representation.IsDouble()) { | 306 } else if (details_representation.IsDouble()) { |
303 field_type = type_cache_.kFloat64; | 307 field_type = type_cache_.kFloat64; |
304 field_representation = MachineRepresentation::kFloat64; | 308 field_representation = MachineRepresentation::kFloat64; |
305 } else if (details_representation.IsHeapObject()) { | 309 } else if (details_representation.IsHeapObject()) { |
306 // Extract the field type from the property details (make sure its | 310 // Extract the field type from the property details (make sure its |
307 // representation is TaggedPointer to reflect the heap object case). | 311 // representation is TaggedPointer to reflect the heap object case). |
308 field_representation = MachineRepresentation::kTaggedPointer; | 312 field_representation = MachineRepresentation::kTaggedPointer; |
309 field_type = descriptors->GetFieldType(number)->Convert(zone()); | 313 Handle<FieldType> descriptors_field_type( |
310 if (field_type->Is(Type::None())) { | 314 descriptors->GetFieldType(number), isolate()); |
| 315 if (descriptors_field_type->IsNone()) { |
311 // Store is not safe if the field type was cleared. | 316 // Store is not safe if the field type was cleared. |
312 if (access_mode == AccessMode::kStore) return false; | 317 if (access_mode == AccessMode::kStore) return false; |
313 | 318 |
314 // The field type was cleared by the GC, so we don't know anything | 319 // The field type was cleared by the GC, so we don't know anything |
315 // about the contents now. | 320 // about the contents now. |
316 // TODO(bmeurer): It would be awesome to make this saner in the | 321 } else if (descriptors_field_type->IsClass()) { |
317 // runtime/GC interaction. | |
318 field_type = Type::Any(); | |
319 } else if (!Type::Any()->Is(field_type)) { | |
320 // Add proper code dependencies in case of stable field map(s). | 322 // Add proper code dependencies in case of stable field map(s). |
321 field_representation = MachineRepresentation::kTaggedPointer; | |
322 Handle<Map> field_owner_map(map->FindFieldOwner(number), | 323 Handle<Map> field_owner_map(map->FindFieldOwner(number), |
323 isolate()); | 324 isolate()); |
324 dependencies()->AssumeFieldType(field_owner_map); | 325 dependencies()->AssumeFieldType(field_owner_map); |
| 326 |
| 327 // Remember the field map, and try to infer a useful type. |
| 328 field_type = Type::For(descriptors_field_type->AsClass()); |
| 329 field_map = descriptors_field_type->AsClass(); |
325 } | 330 } |
326 } | 331 } |
327 *access_info = PropertyAccessInfo::DataField( | 332 *access_info = PropertyAccessInfo::DataField( |
328 MapList{receiver_map}, field_index, field_representation, | 333 MapList{receiver_map}, field_index, field_representation, |
329 field_type, holder); | 334 field_type, field_map, holder); |
330 return true; | 335 return true; |
331 } | 336 } |
332 case ACCESSOR_CONSTANT: { | 337 case ACCESSOR_CONSTANT: { |
333 Handle<Object> accessors(descriptors->GetValue(number), isolate()); | 338 Handle<Object> accessors(descriptors->GetValue(number), isolate()); |
334 if (!accessors->IsAccessorPair()) return false; | 339 if (!accessors->IsAccessorPair()) return false; |
335 Handle<Object> accessor( | 340 Handle<Object> accessor( |
336 access_mode == AccessMode::kLoad | 341 access_mode == AccessMode::kLoad |
337 ? Handle<AccessorPair>::cast(accessors)->getter() | 342 ? Handle<AccessorPair>::cast(accessors)->getter() |
338 : Handle<AccessorPair>::cast(accessors)->setter(), | 343 : Handle<AccessorPair>::cast(accessors)->setter(), |
339 isolate()); | 344 isolate()); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 PropertyDetails const details = | 482 PropertyDetails const details = |
478 transition_map->instance_descriptors()->GetDetails(number); | 483 transition_map->instance_descriptors()->GetDetails(number); |
479 // Don't bother optimizing stores to read-only properties. | 484 // Don't bother optimizing stores to read-only properties. |
480 if (details.IsReadOnly()) return false; | 485 if (details.IsReadOnly()) return false; |
481 // TODO(bmeurer): Handle transition to data constant? | 486 // TODO(bmeurer): Handle transition to data constant? |
482 if (details.type() != DATA) return false; | 487 if (details.type() != DATA) return false; |
483 int const index = details.field_index(); | 488 int const index = details.field_index(); |
484 Representation details_representation = details.representation(); | 489 Representation details_representation = details.representation(); |
485 FieldIndex field_index = FieldIndex::ForPropertyIndex( | 490 FieldIndex field_index = FieldIndex::ForPropertyIndex( |
486 *transition_map, index, details_representation.IsDouble()); | 491 *transition_map, index, details_representation.IsDouble()); |
487 Type* field_type = Type::Tagged(); | 492 Type* field_type = Type::NonInternal(); |
| 493 MaybeHandle<Map> field_map; |
488 MachineRepresentation field_representation = MachineRepresentation::kTagged; | 494 MachineRepresentation field_representation = MachineRepresentation::kTagged; |
489 if (details_representation.IsSmi()) { | 495 if (details_representation.IsSmi()) { |
490 field_type = type_cache_.kSmi; | 496 field_type = type_cache_.kSmi; |
491 field_representation = MachineRepresentation::kTaggedSigned; | 497 field_representation = MachineRepresentation::kTaggedSigned; |
492 } else if (details_representation.IsDouble()) { | 498 } else if (details_representation.IsDouble()) { |
493 field_type = type_cache_.kFloat64; | 499 field_type = type_cache_.kFloat64; |
494 field_representation = MachineRepresentation::kFloat64; | 500 field_representation = MachineRepresentation::kFloat64; |
495 } else if (details_representation.IsHeapObject()) { | 501 } else if (details_representation.IsHeapObject()) { |
496 // Extract the field type from the property details (make sure its | 502 // Extract the field type from the property details (make sure its |
497 // representation is TaggedPointer to reflect the heap object case). | 503 // representation is TaggedPointer to reflect the heap object case). |
498 field_representation = MachineRepresentation::kTaggedPointer; | 504 field_representation = MachineRepresentation::kTaggedPointer; |
499 field_type = | 505 Handle<FieldType> descriptors_field_type( |
500 transition_map->instance_descriptors()->GetFieldType(number)->Convert( | 506 transition_map->instance_descriptors()->GetFieldType(number), |
501 zone()); | 507 isolate()); |
502 if (field_type->Is(Type::None())) { | 508 if (descriptors_field_type->IsNone()) { |
503 // Store is not safe if the field type was cleared. | 509 // Store is not safe if the field type was cleared. |
504 return false; | 510 return false; |
505 } else if (!Type::Any()->Is(field_type)) { | 511 } else if (descriptors_field_type->IsClass()) { |
506 // Add proper code dependencies in case of stable field map(s). | 512 // Add proper code dependencies in case of stable field map(s). |
507 Handle<Map> field_owner_map(transition_map->FindFieldOwner(number), | 513 Handle<Map> field_owner_map(transition_map->FindFieldOwner(number), |
508 isolate()); | 514 isolate()); |
509 dependencies()->AssumeFieldType(field_owner_map); | 515 dependencies()->AssumeFieldType(field_owner_map); |
| 516 |
| 517 // Remember the field map, and try to infer a useful type. |
| 518 field_type = Type::For(descriptors_field_type->AsClass()); |
| 519 field_map = descriptors_field_type->AsClass(); |
510 } | 520 } |
511 } | 521 } |
512 dependencies()->AssumeMapNotDeprecated(transition_map); | 522 dependencies()->AssumeMapNotDeprecated(transition_map); |
513 *access_info = PropertyAccessInfo::DataField( | 523 *access_info = PropertyAccessInfo::DataField( |
514 MapList{map}, field_index, field_representation, field_type, holder, | 524 MapList{map}, field_index, field_representation, field_type, field_map, |
515 transition_map); | 525 holder, transition_map); |
516 return true; | 526 return true; |
517 } | 527 } |
518 return false; | 528 return false; |
519 } | 529 } |
520 | 530 |
521 | 531 |
522 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } | 532 Factory* AccessInfoFactory::factory() const { return isolate()->factory(); } |
523 | 533 |
524 } // namespace compiler | 534 } // namespace compiler |
525 } // namespace internal | 535 } // namespace internal |
526 } // namespace v8 | 536 } // namespace v8 |
OLD | NEW |