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