Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 2290233002: [turbofan] Introduce MachineRepresentation to PropertyAccessInfo. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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.representation();
884 if (access_mode == AccessMode::kLoad && 885 if (access_mode == AccessMode::kLoad &&
885 access_info.holder().ToHandle(&holder)) { 886 access_info.holder().ToHandle(&holder)) {
886 receiver = jsgraph()->Constant(holder); 887 receiver = jsgraph()->Constant(holder);
887 } 888 }
888 Node* storage = receiver; 889 Node* storage = receiver;
889 if (!field_index.is_inobject()) { 890 if (!field_index.is_inobject()) {
890 storage = effect = graph()->NewNode( 891 storage = effect = graph()->NewNode(
891 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()), 892 simplified()->LoadField(AccessBuilder::ForJSObjectProperties()),
892 storage, effect, control); 893 storage, effect, control);
893 } 894 }
895 // TODO(mvstanton): note that for the field_access.machine_type we don't
896 // incorporate the MachineRepresentation information that we have. This is
897 // done below, only if numerous conditions are met on a case by case basis.
898 // Is this the correct albeit conservative choice?
894 FieldAccess field_access = { 899 FieldAccess field_access = {
895 kTaggedBase, field_index.offset(), name, 900 kTaggedBase, field_index.offset(), name,
896 field_type, MachineType::AnyTagged(), kFullWriteBarrier}; 901 field_type, MachineType::AnyTagged(), kFullWriteBarrier};
897 if (access_mode == AccessMode::kLoad) { 902 if (access_mode == AccessMode::kLoad) {
898 if (field_type->Is(Type::UntaggedFloat64())) { 903 if (rep == MachineRepresentation::kFloat64) {
899 // TODO(turbofan): We remove the representation axis from the type to
900 // avoid uninhabited representation types. This is a workaround until
901 // the {PropertyAccessInfo} is using {MachineRepresentation} instead.
902 field_access.type = Type::Union(
903 field_type, Type::Representation(Type::Number(), zone()), zone());
904 if (!field_index.is_inobject() || field_index.is_hidden_field() || 904 if (!field_index.is_inobject() || field_index.is_hidden_field() ||
905 !FLAG_unbox_double_fields) { 905 !FLAG_unbox_double_fields) {
906 storage = effect = graph()->NewNode( 906 storage = effect = graph()->NewNode(
907 simplified()->LoadField(field_access), storage, effect, control); 907 simplified()->LoadField(field_access), storage, effect, control);
908 field_access.offset = HeapNumber::kValueOffset; 908 field_access.offset = HeapNumber::kValueOffset;
909 field_access.name = MaybeHandle<Name>(); 909 field_access.name = MaybeHandle<Name>();
910 } 910 }
911 field_access.machine_type = MachineType::Float64(); 911 field_access.machine_type = MachineType::Float64();
912 } 912 }
913 value = effect = graph()->NewNode(simplified()->LoadField(field_access), 913 value = effect = graph()->NewNode(simplified()->LoadField(field_access),
914 storage, effect, control); 914 storage, effect, control);
915 } else { 915 } else {
916 DCHECK_EQ(AccessMode::kStore, access_mode); 916 DCHECK_EQ(AccessMode::kStore, access_mode);
917 if (field_type->Is(Type::UntaggedFloat64())) { 917 if (rep == MachineRepresentation::kFloat64) {
918 // TODO(turbofan): We remove the representation axis from the type to
919 // avoid uninhabited representation types. This is a workaround until
920 // the {PropertyAccessInfo} is using {MachineRepresentation} instead.
921 field_access.type = Type::Union(
922 field_type, Type::Representation(Type::Number(), zone()), zone());
923 value = effect = graph()->NewNode(simplified()->CheckNumber(), value, 918 value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
924 effect, control); 919 effect, control);
925 920
926 if (!field_index.is_inobject() || field_index.is_hidden_field() || 921 if (!field_index.is_inobject() || field_index.is_hidden_field() ||
927 !FLAG_unbox_double_fields) { 922 !FLAG_unbox_double_fields) {
928 if (access_info.HasTransitionMap()) { 923 if (access_info.HasTransitionMap()) {
929 // Allocate a MutableHeapNumber for the new property. 924 // Allocate a MutableHeapNumber for the new property.
930 effect = graph()->NewNode( 925 effect = graph()->NewNode(
931 common()->BeginRegion(RegionObservability::kNotObservable), 926 common()->BeginRegion(RegionObservability::kNotObservable),
932 effect); 927 effect);
933 Node* box = effect = graph()->NewNode( 928 Node* box = effect = graph()->NewNode(
934 simplified()->Allocate(NOT_TENURED), 929 simplified()->Allocate(NOT_TENURED),
935 jsgraph()->Constant(HeapNumber::kSize), effect, control); 930 jsgraph()->Constant(HeapNumber::kSize), effect, control);
936 effect = graph()->NewNode( 931 effect = graph()->NewNode(
937 simplified()->StoreField(AccessBuilder::ForMap()), box, 932 simplified()->StoreField(AccessBuilder::ForMap()), box,
938 jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), 933 jsgraph()->HeapConstant(factory()->mutable_heap_number_map()),
939 effect, control); 934 effect, control);
940 effect = graph()->NewNode( 935 effect = graph()->NewNode(
941 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), 936 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()),
942 box, value, effect, control); 937 box, value, effect, control);
943 value = effect = 938 value = effect =
944 graph()->NewNode(common()->FinishRegion(), box, effect); 939 graph()->NewNode(common()->FinishRegion(), box, effect);
945 940
941 // TODO(mvstanton): this looks like representation. Should we set
942 // {type}?
946 field_access.type = Type::TaggedPointer(); 943 field_access.type = Type::TaggedPointer();
944 field_access.machine_type = MachineType::TaggedPointer();
947 } else { 945 } else {
948 // We just store directly to the MutableHeapNumber. 946 // We just store directly to the MutableHeapNumber.
949 storage = effect = 947 storage = effect =
950 graph()->NewNode(simplified()->LoadField(field_access), storage, 948 graph()->NewNode(simplified()->LoadField(field_access), storage,
951 effect, control); 949 effect, control);
952 field_access.offset = HeapNumber::kValueOffset; 950 field_access.offset = HeapNumber::kValueOffset;
953 field_access.name = MaybeHandle<Name>(); 951 field_access.name = MaybeHandle<Name>();
954 field_access.machine_type = MachineType::Float64(); 952 field_access.machine_type = MachineType::Float64();
955 } 953 }
956 } else { 954 } else {
957 // Unboxed double field, we store directly to the field. 955 // Unboxed double field, we store directly to the field.
958 field_access.machine_type = MachineType::Float64(); 956 field_access.machine_type = MachineType::Float64();
959 } 957 }
960 } else if (field_type->Is(Type::TaggedSigned())) { 958 } else if (rep == MachineRepresentation::kTaggedSigned) {
961 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(), 959 value = effect = graph()->NewNode(simplified()->CheckTaggedSigned(),
962 value, effect, control); 960 value, effect, control);
963 } else if (field_type->Is(Type::TaggedPointer())) { 961 } else if (rep == MachineRepresentation::kTaggedPointer) {
964 // Ensure that {value} is a HeapObject. 962 // Ensure that {value} is a HeapObject.
965 value = effect = graph()->NewNode(simplified()->CheckTaggedPointer(), 963 value = effect = graph()->NewNode(simplified()->CheckTaggedPointer(),
966 value, effect, control); 964 value, effect, control);
967 if (field_type->NumClasses() == 1) { 965 if (field_type->NumClasses() == 1) {
968 // Emit a map check for the value. 966 // Emit a map check for the value.
969 Node* field_map = 967 Node* field_map =
970 jsgraph()->Constant(field_type->Classes().Current()); 968 jsgraph()->Constant(field_type->Classes().Current());
971 effect = graph()->NewNode(simplified()->CheckMaps(1), value, 969 effect = graph()->NewNode(simplified()->CheckMaps(1), value,
972 field_map, effect, control); 970 field_map, effect, control);
973 } else { 971 } else {
974 DCHECK_EQ(0, field_type->NumClasses()); 972 DCHECK_EQ(0, field_type->NumClasses());
975 } 973 }
976 } else { 974 } else {
977 DCHECK(field_type->Is(Type::Tagged())); 975 // DCHECK(field_type->Is(Type::Tagged()));
976 DCHECK(rep == MachineRepresentation::kTagged);
978 } 977 }
979 Handle<Map> transition_map; 978 Handle<Map> transition_map;
980 if (access_info.transition_map().ToHandle(&transition_map)) { 979 if (access_info.transition_map().ToHandle(&transition_map)) {
981 effect = graph()->NewNode( 980 effect = graph()->NewNode(
982 common()->BeginRegion(RegionObservability::kObservable), effect); 981 common()->BeginRegion(RegionObservability::kObservable), effect);
983 effect = graph()->NewNode( 982 effect = graph()->NewNode(
984 simplified()->StoreField(AccessBuilder::ForMap()), receiver, 983 simplified()->StoreField(AccessBuilder::ForMap()), receiver,
985 jsgraph()->Constant(transition_map), effect, control); 984 jsgraph()->Constant(transition_map), effect, control);
986 } 985 }
987 effect = graph()->NewNode(simplified()->StoreField(field_access), storage, 986 effect = graph()->NewNode(simplified()->StoreField(field_access), storage,
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 } 1160 }
1162 1161
1163 // Compute the element access. 1162 // Compute the element access.
1164 Type* element_type = Type::NonInternal(); 1163 Type* element_type = Type::NonInternal();
1165 MachineType element_machine_type = MachineType::AnyTagged(); 1164 MachineType element_machine_type = MachineType::AnyTagged();
1166 if (IsFastDoubleElementsKind(elements_kind)) { 1165 if (IsFastDoubleElementsKind(elements_kind)) {
1167 element_type = Type::Number(); 1166 element_type = Type::Number();
1168 element_machine_type = MachineType::Float64(); 1167 element_machine_type = MachineType::Float64();
1169 } else if (IsFastSmiElementsKind(elements_kind)) { 1168 } else if (IsFastSmiElementsKind(elements_kind)) {
1170 element_type = type_cache_.kSmi; 1169 element_type = type_cache_.kSmi;
1170 element_machine_type = MachineType::TaggedSigned();
1171 } 1171 }
1172 ElementAccess element_access = {kTaggedBase, FixedArray::kHeaderSize, 1172 ElementAccess element_access = {kTaggedBase, FixedArray::kHeaderSize,
1173 element_type, element_machine_type, 1173 element_type, element_machine_type,
1174 kFullWriteBarrier}; 1174 kFullWriteBarrier};
1175 1175
1176 // Access the actual element. 1176 // Access the actual element.
1177 if (access_mode == AccessMode::kLoad) { 1177 if (access_mode == AccessMode::kLoad) {
1178 // Compute the real element access type, which includes the hole in case 1178 // Compute the real element access type, which includes the hole in case
1179 // of holey backing stores. 1179 // of holey backing stores.
1180 if (elements_kind == FAST_HOLEY_ELEMENTS || 1180 if (elements_kind == FAST_HOLEY_ELEMENTS ||
1181 elements_kind == FAST_HOLEY_SMI_ELEMENTS) { 1181 elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
1182 element_access.type = 1182 element_access.type =
1183 Type::Union(element_type, Type::Hole(), graph()->zone()); 1183 Type::Union(element_type, Type::Hole(), graph()->zone());
1184 element_access.machine_type = MachineType::AnyTagged();
1184 } 1185 }
1185 // Perform the actual backing store access. 1186 // Perform the actual backing store access.
1186 value = effect = 1187 value = effect =
1187 graph()->NewNode(simplified()->LoadElement(element_access), elements, 1188 graph()->NewNode(simplified()->LoadElement(element_access), elements,
1188 index, effect, control); 1189 index, effect, control);
1189 // Handle loading from holey backing stores correctly, by either mapping 1190 // Handle loading from holey backing stores correctly, by either mapping
1190 // the hole to undefined if possible, or deoptimizing otherwise. 1191 // the hole to undefined if possible, or deoptimizing otherwise.
1191 if (elements_kind == FAST_HOLEY_ELEMENTS || 1192 if (elements_kind == FAST_HOLEY_ELEMENTS ||
1192 elements_kind == FAST_HOLEY_SMI_ELEMENTS) { 1193 elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
1193 // Check if we are allowed to turn the hole into undefined. 1194 // Check if we are allowed to turn the hole into undefined.
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 } 1487 }
1487 1488
1488 1489
1489 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1490 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1490 return jsgraph()->simplified(); 1491 return jsgraph()->simplified();
1491 } 1492 }
1492 1493
1493 } // namespace compiler 1494 } // namespace compiler
1494 } // namespace internal 1495 } // namespace internal
1495 } // namespace v8 1496 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698