OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 return InnerAllocate(previous, IntPtrConstant(offset)); | 905 return InnerAllocate(previous, IntPtrConstant(offset)); |
906 } | 906 } |
907 | 907 |
908 Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) { | 908 Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) { |
909 return UintPtrLessThanOrEqual(size, | 909 return UintPtrLessThanOrEqual(size, |
910 IntPtrConstant(kMaxRegularHeapObjectSize)); | 910 IntPtrConstant(kMaxRegularHeapObjectSize)); |
911 } | 911 } |
912 | 912 |
913 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true, | 913 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true, |
914 Label* if_false) { | 914 Label* if_false) { |
915 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this), | 915 Label if_valueissmi(this), if_valueisnotsmi(this), |
916 if_valueisheapnumber(this), if_valueisother(this); | 916 if_valueisheapnumber(this, Label::kDeferred); |
917 | 917 |
918 // Fast check for Boolean {value}s (common case). | 918 // Rule out false {value}. |
919 GotoIf(WordEqual(value, BooleanConstant(true)), if_true); | |
920 GotoIf(WordEqual(value, BooleanConstant(false)), if_false); | 919 GotoIf(WordEqual(value, BooleanConstant(false)), if_false); |
921 | 920 |
922 // Check if {value} is a Smi or a HeapObject. | 921 // Check if {value} is a Smi or a HeapObject. |
923 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 922 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
924 | 923 |
925 Bind(&if_valueissmi); | 924 Bind(&if_valueissmi); |
926 { | 925 { |
927 // The {value} is a Smi, only need to check against zero. | 926 // The {value} is a Smi, only need to check against zero. |
928 BranchIfSmiEqual(value, SmiConstant(0), if_false, if_true); | 927 BranchIfSmiEqual(value, SmiConstant(0), if_false, if_true); |
929 } | 928 } |
930 | 929 |
931 Bind(&if_valueisnotsmi); | 930 Bind(&if_valueisnotsmi); |
932 { | 931 { |
| 932 // Check if {value} is the empty string. |
| 933 GotoIf(IsEmptyString(value), if_false); |
| 934 |
933 // The {value} is a HeapObject, load its map. | 935 // The {value} is a HeapObject, load its map. |
934 Node* value_map = LoadMap(value); | 936 Node* value_map = LoadMap(value); |
935 | 937 |
936 // Load the {value}s instance type. | 938 // Only null, undefined and document.all have the undetectable bit set, |
937 Node* value_instance_type = LoadMapInstanceType(value_map); | 939 // so we can return false immediately when that bit is set. |
| 940 Node* value_map_bitfield = LoadMapBitField(value_map); |
| 941 Node* value_map_undetectable = |
| 942 Word32And(value_map_bitfield, Int32Constant(1 << Map::kIsUndetectable)); |
938 | 943 |
939 // Dispatch based on the instance type; we distinguish all String instance | 944 // Check if the {value} is undetectable. |
940 // types, the HeapNumber type and everything else. | 945 GotoUnless(Word32Equal(value_map_undetectable, Int32Constant(0)), if_false); |
941 GotoIf(Word32Equal(value_instance_type, Int32Constant(HEAP_NUMBER_TYPE)), | |
942 &if_valueisheapnumber); | |
943 Branch(IsStringInstanceType(value_instance_type), &if_valueisstring, | |
944 &if_valueisother); | |
945 | 946 |
946 Bind(&if_valueisstring); | 947 // We still need to handle numbers specially, but all other {value}s |
947 { | 948 // that make it here yield true. |
948 // Load the string length field of the {value}. | 949 Branch(IsHeapNumberMap(value_map), &if_valueisheapnumber, if_true); |
949 Node* value_length = LoadObjectField(value, String::kLengthOffset); | |
950 | |
951 // Check if the {value} is the empty string. | |
952 BranchIfSmiEqual(value_length, SmiConstant(0), if_false, if_true); | |
953 } | |
954 | 950 |
955 Bind(&if_valueisheapnumber); | 951 Bind(&if_valueisheapnumber); |
956 { | 952 { |
957 // Load the floating point value of {value}. | 953 // Load the floating point value of {value}. |
958 Node* value_value = LoadObjectField(value, HeapNumber::kValueOffset, | 954 Node* value_value = LoadObjectField(value, HeapNumber::kValueOffset, |
959 MachineType::Float64()); | 955 MachineType::Float64()); |
960 | 956 |
961 // Check if the floating point {value} is neither 0.0, -0.0 nor NaN. | 957 // Check if the floating point {value} is neither 0.0, -0.0 nor NaN. |
962 Branch(Float64LessThan(Float64Constant(0.0), Float64Abs(value_value)), | 958 Branch(Float64LessThan(Float64Constant(0.0), Float64Abs(value_value)), |
963 if_true, if_false); | 959 if_true, if_false); |
964 } | 960 } |
965 | |
966 Bind(&if_valueisother); | |
967 { | |
968 // Load the bit field from the {value}s map. The {value} is now either | |
969 // Null or Undefined, which have the undetectable bit set (so we always | |
970 // return false for those), or a Symbol or Simd128Value, whose maps never | |
971 // have the undetectable bit set (so we always return true for those), or | |
972 // a JSReceiver, which may or may not have the undetectable bit set. | |
973 Node* value_map_bitfield = LoadMapBitField(value_map); | |
974 Node* value_map_undetectable = Word32And( | |
975 value_map_bitfield, Int32Constant(1 << Map::kIsUndetectable)); | |
976 | |
977 // Check if the {value} is undetectable. | |
978 Branch(Word32Equal(value_map_undetectable, Int32Constant(0)), if_true, | |
979 if_false); | |
980 } | |
981 } | 961 } |
982 } | 962 } |
983 | 963 |
984 Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) { | 964 Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) { |
985 Node* frame_pointer = LoadFramePointer(); | 965 Node* frame_pointer = LoadFramePointer(); |
986 return Load(rep, frame_pointer, IntPtrConstant(offset)); | 966 return Load(rep, frame_pointer, IntPtrConstant(offset)); |
987 } | 967 } |
988 | 968 |
989 Node* CodeStubAssembler::LoadFromParentFrame(int offset, MachineType rep) { | 969 Node* CodeStubAssembler::LoadFromParentFrame(int offset, MachineType rep) { |
990 Node* frame_pointer = LoadParentFramePointer(); | 970 Node* frame_pointer = LoadParentFramePointer(); |
(...skipping 7383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8374 formatted.c_str(), TENURED); | 8354 formatted.c_str(), TENURED); |
8375 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 8355 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
8376 HeapConstant(string)); | 8356 HeapConstant(string)); |
8377 } | 8357 } |
8378 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 8358 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
8379 #endif | 8359 #endif |
8380 } | 8360 } |
8381 | 8361 |
8382 } // namespace internal | 8362 } // namespace internal |
8383 } // namespace v8 | 8363 } // namespace v8 |
OLD | NEW |