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