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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/compiler-source-position-table.h" | 9 #include "src/compiler/compiler-source-position-table.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 | 915 |
916 Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) { | 916 Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) { |
917 Node* value = node->InputAt(0); | 917 Node* value = node->InputAt(0); |
918 return __ WordEqual(value, __ TrueConstant()); | 918 return __ WordEqual(value, __ TrueConstant()); |
919 } | 919 } |
920 | 920 |
921 Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) { | 921 Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) { |
922 Node* value = node->InputAt(0); | 922 Node* value = node->InputAt(0); |
923 | 923 |
924 auto if_smi = __ MakeDeferredLabel<1>(); | 924 auto if_smi = __ MakeDeferredLabel<1>(); |
925 auto if_not_oddball = __ MakeDeferredLabel<1>(); | 925 auto if_heapnumber = __ MakeDeferredLabel<1>(); |
926 auto if_not_string = __ MakeDeferredLabel<1>(); | 926 auto done = __ MakeLabel<6>(MachineRepresentation::kBit); |
927 auto if_not_heapnumber = __ MakeDeferredLabel<1>(); | |
928 auto done = __ MakeLabel<5>(MachineRepresentation::kBit); | |
929 | 927 |
930 Node* zero = __ Int32Constant(0); | 928 Node* zero = __ Int32Constant(0); |
931 Node* fzero = __ Float64Constant(0.0); | 929 Node* fzero = __ Float64Constant(0.0); |
932 | 930 |
| 931 // Check if {value} is false. |
| 932 __ GotoIf(__ WordEqual(value, __ FalseConstant()), &done, zero); |
| 933 |
933 // Check if {value} is a Smi. | 934 // Check if {value} is a Smi. |
934 Node* check_smi = ObjectIsSmi(value); | 935 Node* check_smi = ObjectIsSmi(value); |
935 __ GotoIf(check_smi, &if_smi); | 936 __ GotoIf(check_smi, &if_smi); |
936 | 937 |
937 // Load the map instance type of {value}. | 938 // Check if {value} is the empty string. |
| 939 __ GotoIf(__ WordEqual(value, __ EmptyStringConstant()), &done, zero); |
| 940 |
| 941 // Load the map of {value}. |
938 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); | 942 Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
939 Node* value_instance_type = | |
940 __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); | |
941 | 943 |
942 // Check if {value} is an Oddball. | 944 // Check if the {value} is undetectable and immediately return false. |
943 Node* check_oddball = | |
944 __ Word32Equal(value_instance_type, __ Int32Constant(ODDBALL_TYPE)); | |
945 | |
946 __ GotoUnless(check_oddball, &if_not_oddball); | |
947 // The only Oddball {value} that is trueish is true itself. | |
948 __ Goto(&done, __ WordEqual(value, __ TrueConstant())); | |
949 | |
950 __ Bind(&if_not_oddball); | |
951 // Check if {value} is a String. | |
952 Node* check_string = __ Int32LessThan(value_instance_type, | |
953 __ Int32Constant(FIRST_NONSTRING_TYPE)); | |
954 __ GotoUnless(check_string, &if_not_string); | |
955 // For String {value}, we need to check that the length is not zero. | |
956 Node* value_length = __ LoadField(AccessBuilder::ForStringLength(), value); | |
957 __ Goto(&done, __ Word32Equal( | |
958 __ WordEqual(value_length, __ IntPtrConstant(0)), zero)); | |
959 | |
960 __ Bind(&if_not_string); | |
961 // Check if {value} is a HeapNumber. | |
962 Node* check_heapnumber = | |
963 __ Word32Equal(value_instance_type, __ Int32Constant(HEAP_NUMBER_TYPE)); | |
964 __ GotoUnless(check_heapnumber, &if_not_heapnumber); | |
965 | |
966 // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or | |
967 // NaN. | |
968 // Load the raw value of {value}. | |
969 Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); | |
970 __ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value))); | |
971 | |
972 // The {value} is either a JSReceiver, a Symbol or some Simd128Value. In | |
973 // those cases we can just the undetectable bit on the map, which will only | |
974 // be set for certain JSReceivers, i.e. document.all. | |
975 __ Bind(&if_not_heapnumber); | |
976 | |
977 // Load the {value} map bit field. | |
978 Node* value_map_bitfield = | 945 Node* value_map_bitfield = |
979 __ LoadField(AccessBuilder::ForMapBitField(), value_map); | 946 __ LoadField(AccessBuilder::ForMapBitField(), value_map); |
980 __ Goto(&done, __ Word32Equal( | 947 __ GotoUnless( |
981 __ Word32And(value_map_bitfield, | 948 __ Word32Equal(__ Word32And(value_map_bitfield, |
982 __ Int32Constant(1 << Map::kIsUndetectable)), | 949 __ Int32Constant(1 << Map::kIsUndetectable)), |
983 zero)); | 950 zero), |
| 951 &done, zero); |
| 952 |
| 953 // Check if {value} is a HeapNumber. |
| 954 __ GotoIf(__ WordEqual(value_map, __ HeapNumberMapConstant()), |
| 955 &if_heapnumber); |
| 956 |
| 957 // All other values that reach here are true. |
| 958 __ Goto(&done, __ Int32Constant(1)); |
| 959 |
| 960 __ Bind(&if_heapnumber); |
| 961 { |
| 962 // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or |
| 963 // NaN. |
| 964 Node* value_value = |
| 965 __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
| 966 __ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value))); |
| 967 } |
984 | 968 |
985 __ Bind(&if_smi); | 969 __ Bind(&if_smi); |
986 // If {value} is a Smi, then we only need to check that it's not zero. | 970 { |
987 __ Goto(&done, | 971 // If {value} is a Smi, then we only need to check that it's not zero. |
988 __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)), zero)); | 972 __ Goto(&done, |
| 973 __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)), zero)); |
| 974 } |
989 | 975 |
990 __ Bind(&done); | 976 __ Bind(&done); |
991 return done.PhiAt(0); | 977 return done.PhiAt(0); |
992 } | 978 } |
993 | 979 |
994 Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) { | 980 Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) { |
995 Node* value = node->InputAt(0); | 981 Node* value = node->InputAt(0); |
996 | 982 |
997 auto if_not_smi = __ MakeDeferredLabel<1>(); | 983 auto if_not_smi = __ MakeDeferredLabel<1>(); |
998 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); | 984 auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
(...skipping 1791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2790 return isolate()->factory(); | 2776 return isolate()->factory(); |
2791 } | 2777 } |
2792 | 2778 |
2793 Isolate* EffectControlLinearizer::isolate() const { | 2779 Isolate* EffectControlLinearizer::isolate() const { |
2794 return jsgraph()->isolate(); | 2780 return jsgraph()->isolate(); |
2795 } | 2781 } |
2796 | 2782 |
2797 } // namespace compiler | 2783 } // namespace compiler |
2798 } // namespace internal | 2784 } // namespace internal |
2799 } // namespace v8 | 2785 } // namespace v8 |
OLD | NEW |