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 "src/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
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-builder.h" | 9 #include "src/compiler/access-builder.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 return true; | 401 return true; |
402 } else if (details.type() == DATA) { | 402 } else if (details.type() == DATA) { |
403 int index = descriptors->GetFieldIndex(number); | 403 int index = descriptors->GetFieldIndex(number); |
404 Representation field_representation = details.representation(); | 404 Representation field_representation = details.representation(); |
405 FieldIndex field_index = FieldIndex::ForPropertyIndex( | 405 FieldIndex field_index = FieldIndex::ForPropertyIndex( |
406 *map, index, field_representation.IsDouble()); | 406 *map, index, field_representation.IsDouble()); |
407 Type* field_type = Type::Tagged(); | 407 Type* field_type = Type::Tagged(); |
408 if (field_representation.IsSmi()) { | 408 if (field_representation.IsSmi()) { |
409 field_type = type_cache_.kSmi; | 409 field_type = type_cache_.kSmi; |
410 } else if (field_representation.IsDouble()) { | 410 } else if (field_representation.IsDouble()) { |
411 if (access_mode == kStore) { | |
412 // TODO(bmeurer): Add support for storing to double fields. | |
413 return false; | |
414 } | |
415 field_type = type_cache_.kFloat64; | 411 field_type = type_cache_.kFloat64; |
416 } else if (field_representation.IsHeapObject()) { | 412 } else if (field_representation.IsHeapObject()) { |
417 // Extract the field type from the property details (make sure its | 413 // Extract the field type from the property details (make sure its |
418 // representation is TaggedPointer to reflect the heap object case). | 414 // representation is TaggedPointer to reflect the heap object case). |
419 field_type = Type::Intersect( | 415 field_type = Type::Intersect( |
420 Type::Convert<HeapType>( | 416 Type::Convert<HeapType>( |
421 handle(descriptors->GetFieldType(number), isolate()), | 417 handle(descriptors->GetFieldType(number), isolate()), |
422 graph()->zone()), | 418 graph()->zone()), |
423 Type::TaggedPointer(), graph()->zone()); | 419 Type::TaggedPointer(), graph()->zone()); |
424 if (field_type->Is(Type::None())) { | 420 if (field_type->Is(Type::None())) { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
674 this_receiver = jsgraph()->Constant(holder); | 670 this_receiver = jsgraph()->Constant(holder); |
675 } | 671 } |
676 Node* this_storage = this_receiver; | 672 Node* this_storage = this_receiver; |
677 if (!field_index.is_inobject()) { | 673 if (!field_index.is_inobject()) { |
678 this_storage = this_effect = graph()->NewNode( | 674 this_storage = this_effect = graph()->NewNode( |
679 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()), | 675 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()), |
680 this_storage, this_effect, this_control); | 676 this_storage, this_effect, this_control); |
681 } | 677 } |
682 FieldAccess field_access = {kTaggedBase, field_index.offset(), name, | 678 FieldAccess field_access = {kTaggedBase, field_index.offset(), name, |
683 field_type, kMachAnyTagged}; | 679 field_type, kMachAnyTagged}; |
680 if (field_type->Is(Type::UntaggedFloat64())) { | |
681 if (!field_index.is_inobject() || field_index.is_hidden_field() || | |
682 !FLAG_unbox_double_fields) { | |
683 this_storage = this_effect = | |
684 graph()->NewNode(simplified()->LoadField(field_access), | |
685 this_storage, this_effect, this_control); | |
686 field_access.offset = HeapNumber::kValueOffset; | |
687 field_access.name = MaybeHandle<Name>(); | |
Jarin
2015/10/30 10:05:12
I am confused, are we going to store into heap num
Benedikt Meurer
2015/10/30 10:07:19
Yes, when double field unboxing is disabled, we al
Jarin
2015/10/30 10:11:05
Ok, I will trust you that we will not store into a
| |
688 } | |
689 field_access.machine_type = kMachFloat64; | |
690 } | |
684 if (access_mode == kLoad) { | 691 if (access_mode == kLoad) { |
685 if (field_type->Is(Type::UntaggedFloat64())) { | |
686 if (!field_index.is_inobject() || field_index.is_hidden_field() || | |
687 !FLAG_unbox_double_fields) { | |
688 this_storage = this_effect = | |
689 graph()->NewNode(simplified()->LoadField(field_access), | |
690 this_storage, this_effect, this_control); | |
691 field_access.offset = HeapNumber::kValueOffset; | |
692 field_access.name = MaybeHandle<Name>(); | |
693 } | |
694 field_access.machine_type = kMachFloat64; | |
695 } | |
696 this_value = this_effect = | 692 this_value = this_effect = |
697 graph()->NewNode(simplified()->LoadField(field_access), | 693 graph()->NewNode(simplified()->LoadField(field_access), |
698 this_storage, this_effect, this_control); | 694 this_storage, this_effect, this_control); |
699 } else { | 695 } else { |
700 DCHECK_EQ(kStore, access_mode); | 696 DCHECK_EQ(kStore, access_mode); |
701 if (field_type->Is(Type::TaggedSigned())) { | 697 if (field_type->Is(Type::UntaggedFloat64())) { |
702 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); | 698 Node* check = |
699 graph()->NewNode(simplified()->ObjectIsNumber(), this_value); | |
700 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | |
701 check, this_control); | |
702 exit_controls.push_back( | |
703 graph()->NewNode(common()->IfFalse(), branch)); | |
704 this_control = graph()->NewNode(common()->IfTrue(), branch); | |
705 this_value = graph()->NewNode(common()->Guard(Type::Number()), | |
706 this_value, this_control); | |
707 } else if (field_type->Is(Type::TaggedSigned())) { | |
708 Node* check = | |
709 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); | |
703 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 710 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
704 check, this_control); | 711 check, this_control); |
705 exit_controls.push_back( | 712 exit_controls.push_back( |
706 graph()->NewNode(common()->IfFalse(), branch)); | 713 graph()->NewNode(common()->IfFalse(), branch)); |
707 this_control = graph()->NewNode(common()->IfTrue(), branch); | 714 this_control = graph()->NewNode(common()->IfTrue(), branch); |
708 } else if (field_type->Is(Type::TaggedPointer())) { | 715 } else if (field_type->Is(Type::TaggedPointer())) { |
709 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value); | 716 Node* check = |
717 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); | |
710 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 718 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
711 check, this_control); | 719 check, this_control); |
712 exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); | 720 exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); |
713 this_control = graph()->NewNode(common()->IfFalse(), branch); | 721 this_control = graph()->NewNode(common()->IfFalse(), branch); |
714 if (field_type->NumClasses() > 0) { | 722 if (field_type->NumClasses() > 0) { |
715 // Emit a (sequence of) map checks for the value. | 723 // Emit a (sequence of) map checks for the value. |
716 ZoneVector<Node*> this_controls(zone()); | 724 ZoneVector<Node*> this_controls(zone()); |
717 Node* value_map = this_effect = graph()->NewNode( | 725 Node* this_value_map = this_effect = graph()->NewNode( |
718 simplified()->LoadField(AccessBuilder::ForMap()), value, | 726 simplified()->LoadField(AccessBuilder::ForMap()), this_value, |
719 this_effect, this_control); | 727 this_effect, this_control); |
720 for (auto i = field_type->Classes(); !i.Done(); i.Advance()) { | 728 for (auto i = field_type->Classes(); !i.Done(); i.Advance()) { |
721 Handle<Map> field_map(i.Current()); | 729 Handle<Map> field_map(i.Current()); |
722 check = graph()->NewNode( | 730 check = graph()->NewNode( |
723 simplified()->ReferenceEqual(Type::Internal()), value_map, | 731 simplified()->ReferenceEqual(Type::Internal()), |
724 jsgraph()->Constant(field_map)); | 732 this_value_map, jsgraph()->Constant(field_map)); |
725 branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 733 branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
726 check, this_control); | 734 check, this_control); |
727 this_control = graph()->NewNode(common()->IfFalse(), branch); | 735 this_control = graph()->NewNode(common()->IfFalse(), branch); |
728 this_controls.push_back( | 736 this_controls.push_back( |
729 graph()->NewNode(common()->IfTrue(), branch)); | 737 graph()->NewNode(common()->IfTrue(), branch)); |
730 } | 738 } |
731 exit_controls.push_back(this_control); | 739 exit_controls.push_back(this_control); |
732 int const this_control_count = | 740 int const this_control_count = |
733 static_cast<int>(this_controls.size()); | 741 static_cast<int>(this_controls.size()); |
734 this_control = | 742 this_control = |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
930 } | 938 } |
931 | 939 |
932 | 940 |
933 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 941 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
934 return jsgraph()->simplified(); | 942 return jsgraph()->simplified(); |
935 } | 943 } |
936 | 944 |
937 } // namespace compiler | 945 } // namespace compiler |
938 } // namespace internal | 946 } // namespace internal |
939 } // namespace v8 | 947 } // namespace v8 |
OLD | NEW |