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/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 3, VectorSlotPair(), ConvertReceiverMode::kNotNullOrUndefined), | 874 3, VectorSlotPair(), ConvertReceiverMode::kNotNullOrUndefined), |
875 target, receiver, value, context, frame_state0, effect, control); | 875 target, receiver, value, context, frame_state0, effect, control); |
876 control = graph()->NewNode(common()->IfSuccess(), effect); | 876 control = graph()->NewNode(common()->IfSuccess(), effect); |
877 break; | 877 break; |
878 } | 878 } |
879 } | 879 } |
880 } else { | 880 } else { |
881 DCHECK(access_info.IsDataField()); | 881 DCHECK(access_info.IsDataField()); |
882 FieldIndex const field_index = access_info.field_index(); | 882 FieldIndex const field_index = access_info.field_index(); |
883 Type* const field_type = access_info.field_type(); | 883 Type* const field_type = access_info.field_type(); |
884 MachineRepresentation const rep = access_info.field_representation(); | 884 MachineRepresentation const field_representation = |
| 885 access_info.field_representation(); |
885 if (access_mode == AccessMode::kLoad && | 886 if (access_mode == AccessMode::kLoad && |
886 access_info.holder().ToHandle(&holder)) { | 887 access_info.holder().ToHandle(&holder)) { |
887 receiver = jsgraph()->Constant(holder); | 888 receiver = jsgraph()->Constant(holder); |
888 } | 889 } |
889 Node* storage = receiver; | 890 Node* storage = receiver; |
890 if (!field_index.is_inobject()) { | 891 if (!field_index.is_inobject()) { |
891 storage = effect = graph()->NewNode( | 892 storage = effect = graph()->NewNode( |
892 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()), | 893 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()), |
893 storage, effect, control); | 894 storage, effect, control); |
894 } | 895 } |
895 FieldAccess field_access = { | 896 FieldAccess field_access = { |
896 kTaggedBase, field_index.offset(), name, | 897 kTaggedBase, |
897 field_type, MachineType::AnyTagged(), kFullWriteBarrier}; | 898 field_index.offset(), |
| 899 name, |
| 900 field_type, |
| 901 MachineType::TypeForRepresentation(field_representation), |
| 902 kFullWriteBarrier}; |
898 if (access_mode == AccessMode::kLoad) { | 903 if (access_mode == AccessMode::kLoad) { |
899 if (rep == MachineRepresentation::kFloat64) { | 904 if (field_representation == MachineRepresentation::kFloat64) { |
900 if (!field_index.is_inobject() || field_index.is_hidden_field() || | 905 if (!field_index.is_inobject() || field_index.is_hidden_field() || |
901 !FLAG_unbox_double_fields) { | 906 !FLAG_unbox_double_fields) { |
902 storage = effect = graph()->NewNode( | 907 FieldAccess const storage_access = {kTaggedBase, |
903 simplified()->LoadField(field_access), storage, effect, control); | 908 field_index.offset(), |
| 909 name, |
| 910 Type::OtherInternal(), |
| 911 MachineType::TaggedPointer(), |
| 912 kPointerWriteBarrier}; |
| 913 storage = effect = |
| 914 graph()->NewNode(simplified()->LoadField(storage_access), storage, |
| 915 effect, control); |
904 field_access.offset = HeapNumber::kValueOffset; | 916 field_access.offset = HeapNumber::kValueOffset; |
905 field_access.name = MaybeHandle<Name>(); | 917 field_access.name = MaybeHandle<Name>(); |
906 } | 918 } |
907 field_access.machine_type = MachineType::Float64(); | |
908 } | 919 } |
909 // TODO(turbofan): Track the field_map (if any) on the {field_access} and | 920 // TODO(turbofan): Track the field_map (if any) on the {field_access} and |
910 // use it in LoadElimination to eliminate map checks. | 921 // use it in LoadElimination to eliminate map checks. |
911 value = effect = graph()->NewNode(simplified()->LoadField(field_access), | 922 value = effect = graph()->NewNode(simplified()->LoadField(field_access), |
912 storage, effect, control); | 923 storage, effect, control); |
913 } else { | 924 } else { |
914 DCHECK_EQ(AccessMode::kStore, access_mode); | 925 DCHECK_EQ(AccessMode::kStore, access_mode); |
915 if (rep == MachineRepresentation::kFloat64) { | 926 switch (field_representation) { |
916 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, | 927 case MachineRepresentation::kFloat64: { |
917 effect, control); | 928 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, |
| 929 effect, control); |
| 930 if (!field_index.is_inobject() || field_index.is_hidden_field() || |
| 931 !FLAG_unbox_double_fields) { |
| 932 if (access_info.HasTransitionMap()) { |
| 933 // Allocate a MutableHeapNumber for the new property. |
| 934 effect = graph()->NewNode( |
| 935 common()->BeginRegion(RegionObservability::kNotObservable), |
| 936 effect); |
| 937 Node* box = effect = graph()->NewNode( |
| 938 simplified()->Allocate(NOT_TENURED), |
| 939 jsgraph()->Constant(HeapNumber::kSize), effect, control); |
| 940 effect = graph()->NewNode( |
| 941 simplified()->StoreField(AccessBuilder::ForMap()), box, |
| 942 jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), |
| 943 effect, control); |
| 944 effect = graph()->NewNode( |
| 945 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), |
| 946 box, value, effect, control); |
| 947 value = effect = |
| 948 graph()->NewNode(common()->FinishRegion(), box, effect); |
918 | 949 |
919 if (!field_index.is_inobject() || field_index.is_hidden_field() || | 950 field_access.type = Type::TaggedPointer(); |
920 !FLAG_unbox_double_fields) { | 951 field_access.machine_type = MachineType::TaggedPointer(); |
921 if (access_info.HasTransitionMap()) { | 952 field_access.write_barrier_kind = kPointerWriteBarrier; |
922 // Allocate a MutableHeapNumber for the new property. | 953 } else { |
923 effect = graph()->NewNode( | 954 // We just store directly to the MutableHeapNumber. |
924 common()->BeginRegion(RegionObservability::kNotObservable), | 955 FieldAccess const storage_access = {kTaggedBase, |
925 effect); | 956 field_index.offset(), |
926 Node* box = effect = graph()->NewNode( | 957 name, |
927 simplified()->Allocate(NOT_TENURED), | 958 Type::OtherInternal(), |
928 jsgraph()->Constant(HeapNumber::kSize), effect, control); | 959 MachineType::TaggedPointer(), |
929 effect = graph()->NewNode( | 960 kPointerWriteBarrier}; |
930 simplified()->StoreField(AccessBuilder::ForMap()), box, | 961 storage = effect = |
931 jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), | 962 graph()->NewNode(simplified()->LoadField(storage_access), |
932 effect, control); | 963 storage, effect, control); |
933 effect = graph()->NewNode( | 964 field_access.offset = HeapNumber::kValueOffset; |
934 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), | 965 field_access.name = MaybeHandle<Name>(); |
935 box, value, effect, control); | 966 field_access.machine_type = MachineType::Float64(); |
936 value = effect = | 967 } |
937 graph()->NewNode(common()->FinishRegion(), box, effect); | |
938 | |
939 field_access.type = Type::TaggedPointer(); | |
940 field_access.machine_type = MachineType::TaggedPointer(); | |
941 } else { | |
942 // We just store directly to the MutableHeapNumber. | |
943 storage = effect = | |
944 graph()->NewNode(simplified()->LoadField(field_access), storage, | |
945 effect, control); | |
946 field_access.offset = HeapNumber::kValueOffset; | |
947 field_access.name = MaybeHandle<Name>(); | |
948 field_access.machine_type = MachineType::Float64(); | |
949 } | 968 } |
950 } else { | 969 break; |
951 // Unboxed double field, we store directly to the field. | |
952 field_access.machine_type = MachineType::Float64(); | |
953 } | 970 } |
954 } else if (rep == MachineRepresentation::kTaggedSigned) { | 971 case MachineRepresentation::kTaggedSigned: { |
955 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), | 972 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), |
956 value, effect, control); | 973 value, effect, control); |
957 } else if (rep == MachineRepresentation::kTaggedPointer) { | 974 field_access.write_barrier_kind = kNoWriteBarrier; |
958 // Ensure that {value} is a HeapObject. | 975 break; |
959 value = effect = graph()->NewNode(simplified()->CheckTaggedPointer(), | |
960 value, effect, control); | |
961 Handle<Map> field_map; | |
962 if (access_info.field_map().ToHandle(&field_map)) { | |
963 // Emit a map check for the value. | |
964 effect = graph()->NewNode(simplified()->CheckMaps(1), value, | |
965 jsgraph()->HeapConstant(field_map), effect, | |
966 control); | |
967 } | 976 } |
968 } else { | 977 case MachineRepresentation::kTaggedPointer: { |
969 DCHECK(rep == MachineRepresentation::kTagged); | 978 // Ensure that {value} is a HeapObject. |
| 979 value = effect = graph()->NewNode(simplified()->CheckTaggedPointer(), |
| 980 value, effect, control); |
| 981 Handle<Map> field_map; |
| 982 if (access_info.field_map().ToHandle(&field_map)) { |
| 983 // Emit a map check for the value. |
| 984 effect = graph()->NewNode(simplified()->CheckMaps(1), value, |
| 985 jsgraph()->HeapConstant(field_map), |
| 986 effect, control); |
| 987 } |
| 988 field_access.write_barrier_kind = kPointerWriteBarrier; |
| 989 break; |
| 990 } |
| 991 case MachineRepresentation::kTagged: |
| 992 break; |
| 993 case MachineRepresentation::kNone: |
| 994 case MachineRepresentation::kBit: |
| 995 case MachineRepresentation::kWord8: |
| 996 case MachineRepresentation::kWord16: |
| 997 case MachineRepresentation::kWord32: |
| 998 case MachineRepresentation::kWord64: |
| 999 case MachineRepresentation::kFloat32: |
| 1000 case MachineRepresentation::kSimd128: |
| 1001 UNREACHABLE(); |
| 1002 break; |
970 } | 1003 } |
971 Handle<Map> transition_map; | 1004 Handle<Map> transition_map; |
972 if (access_info.transition_map().ToHandle(&transition_map)) { | 1005 if (access_info.transition_map().ToHandle(&transition_map)) { |
973 effect = graph()->NewNode( | 1006 effect = graph()->NewNode( |
974 common()->BeginRegion(RegionObservability::kObservable), effect); | 1007 common()->BeginRegion(RegionObservability::kObservable), effect); |
975 effect = graph()->NewNode( | 1008 effect = graph()->NewNode( |
976 simplified()->StoreField(AccessBuilder::ForMap()), receiver, | 1009 simplified()->StoreField(AccessBuilder::ForMap()), receiver, |
977 jsgraph()->Constant(transition_map), effect, control); | 1010 jsgraph()->Constant(transition_map), effect, control); |
978 } | 1011 } |
979 effect = graph()->NewNode(simplified()->StoreField(field_access), storage, | 1012 effect = graph()->NewNode(simplified()->StoreField(field_access), storage, |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1480 } | 1513 } |
1481 | 1514 |
1482 | 1515 |
1483 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1516 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1484 return jsgraph()->simplified(); | 1517 return jsgraph()->simplified(); |
1485 } | 1518 } |
1486 | 1519 |
1487 } // namespace compiler | 1520 } // namespace compiler |
1488 } // namespace internal | 1521 } // namespace internal |
1489 } // namespace v8 | 1522 } // namespace v8 |
OLD | NEW |