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