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 | 4 |
5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 | 829 |
830 Bind(&if_valueisheapnumber); | 830 Bind(&if_valueisheapnumber); |
831 { | 831 { |
832 // Load the floating point value of {value}. | 832 // Load the floating point value of {value}. |
833 Node* value_value = LoadObjectField(value, HeapNumber::kValueOffset, | 833 Node* value_value = LoadObjectField(value, HeapNumber::kValueOffset, |
834 MachineType::Float64()); | 834 MachineType::Float64()); |
835 | 835 |
836 // Check if the floating point {value} is neither 0.0, -0.0 nor NaN. | 836 // Check if the floating point {value} is neither 0.0, -0.0 nor NaN. |
837 Node* zero = Float64Constant(0.0); | 837 Node* zero = Float64Constant(0.0); |
838 GotoIf(Float64LessThan(zero, value_value), if_true); | 838 GotoIf(Float64LessThan(zero, value_value), if_true); |
839 BranchIfFloat64LessThan(value_value, zero, if_true, if_false); | 839 Branch(Float64LessThan(value_value, zero), if_true, if_false); |
840 } | 840 } |
841 | 841 |
842 Bind(&if_valueisother); | 842 Bind(&if_valueisother); |
843 { | 843 { |
844 // Load the bit field from the {value}s map. The {value} is now either | 844 // Load the bit field from the {value}s map. The {value} is now either |
845 // Null or Undefined, which have the undetectable bit set (so we always | 845 // Null or Undefined, which have the undetectable bit set (so we always |
846 // return false for those), or a Symbol or Simd128Value, whose maps never | 846 // return false for those), or a Symbol or Simd128Value, whose maps never |
847 // have the undetectable bit set (so we always return true for those), or | 847 // have the undetectable bit set (so we always return true for those), or |
848 // a JSReceiver, which may or may not have the undetectable bit set. | 848 // a JSReceiver, which may or may not have the undetectable bit set. |
849 Node* value_map_bitfield = LoadMapBitField(value_map); | 849 Node* value_map_bitfield = LoadMapBitField(value_map); |
850 Node* value_map_undetectable = Word32And( | 850 Node* value_map_undetectable = Word32And( |
851 value_map_bitfield, Int32Constant(1 << Map::kIsUndetectable)); | 851 value_map_bitfield, Int32Constant(1 << Map::kIsUndetectable)); |
852 | 852 |
853 // Check if the {value} is undetectable. | 853 // Check if the {value} is undetectable. |
854 BranchIfWord32Equal(value_map_undetectable, Int32Constant(0), if_true, | 854 Branch(Word32Equal(value_map_undetectable, Int32Constant(0)), if_true, |
855 if_false); | 855 if_false); |
856 } | 856 } |
857 } | 857 } |
858 } | 858 } |
859 | 859 |
860 compiler::Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) { | 860 compiler::Node* CodeStubAssembler::LoadFromFrame(int offset, MachineType rep) { |
861 Node* frame_pointer = LoadFramePointer(); | 861 Node* frame_pointer = LoadFramePointer(); |
862 return Load(rep, frame_pointer, IntPtrConstant(offset)); | 862 return Load(rep, frame_pointer, IntPtrConstant(offset)); |
863 } | 863 } |
864 | 864 |
865 compiler::Node* CodeStubAssembler::LoadFromParentFrame(int offset, | 865 compiler::Node* CodeStubAssembler::LoadFromParentFrame(int offset, |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2173 Node* value32 = RoundFloat64ToInt32(value); | 2173 Node* value32 = RoundFloat64ToInt32(value); |
2174 Node* value64 = ChangeInt32ToFloat64(value32); | 2174 Node* value64 = ChangeInt32ToFloat64(value32); |
2175 | 2175 |
2176 Label if_valueisint32(this), if_valueisheapnumber(this), if_join(this); | 2176 Label if_valueisint32(this), if_valueisheapnumber(this), if_join(this); |
2177 | 2177 |
2178 Label if_valueisequal(this), if_valueisnotequal(this); | 2178 Label if_valueisequal(this), if_valueisnotequal(this); |
2179 Branch(Float64Equal(value, value64), &if_valueisequal, &if_valueisnotequal); | 2179 Branch(Float64Equal(value, value64), &if_valueisequal, &if_valueisnotequal); |
2180 Bind(&if_valueisequal); | 2180 Bind(&if_valueisequal); |
2181 { | 2181 { |
2182 GotoUnless(Word32Equal(value32, Int32Constant(0)), &if_valueisint32); | 2182 GotoUnless(Word32Equal(value32, Int32Constant(0)), &if_valueisint32); |
2183 BranchIfInt32LessThan(Float64ExtractHighWord32(value), Int32Constant(0), | 2183 Branch(Int32LessThan(Float64ExtractHighWord32(value), Int32Constant(0)), |
2184 &if_valueisheapnumber, &if_valueisint32); | 2184 &if_valueisheapnumber, &if_valueisint32); |
2185 } | 2185 } |
2186 Bind(&if_valueisnotequal); | 2186 Bind(&if_valueisnotequal); |
2187 Goto(&if_valueisheapnumber); | 2187 Goto(&if_valueisheapnumber); |
2188 | 2188 |
2189 Variable var_result(this, MachineRepresentation::kTagged); | 2189 Variable var_result(this, MachineRepresentation::kTagged); |
2190 Bind(&if_valueisint32); | 2190 Bind(&if_valueisint32); |
2191 { | 2191 { |
2192 if (Is64()) { | 2192 if (Is64()) { |
2193 Node* result = SmiTag(ChangeInt32ToInt64(value32)); | 2193 Node* result = SmiTag(ChangeInt32ToInt64(value32)); |
2194 var_result.Bind(result); | 2194 var_result.Bind(result); |
(...skipping 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3663 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); | 3663 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); |
3664 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); | 3664 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); |
3665 // Finally, check if |key| is internalized. | 3665 // Finally, check if |key| is internalized. |
3666 STATIC_ASSERT(kNotInternalizedTag != 0); | 3666 STATIC_ASSERT(kNotInternalizedTag != 0); |
3667 Node* not_internalized = | 3667 Node* not_internalized = |
3668 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); | 3668 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); |
3669 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); | 3669 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); |
3670 Goto(if_keyisunique); | 3670 Goto(if_keyisunique); |
3671 | 3671 |
3672 Bind(&if_hascachedindex); | 3672 Bind(&if_hascachedindex); |
3673 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); | 3673 var_index->Bind(BitFieldDecodeWord<Name::ArrayIndexValueBits>(hash)); |
3674 Goto(if_keyisindex); | 3674 Goto(if_keyisindex); |
3675 } | 3675 } |
3676 | 3676 |
3677 template <typename Dictionary> | 3677 template <typename Dictionary> |
3678 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { | 3678 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { |
3679 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); | 3679 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); |
3680 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + | 3680 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + |
3681 field_index)); | 3681 field_index)); |
3682 } | 3682 } |
3683 | 3683 |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3987 Node* field_index = | 3987 Node* field_index = |
3988 BitFieldDecodeWord<PropertyDetails::FieldIndexField>(details); | 3988 BitFieldDecodeWord<PropertyDetails::FieldIndexField>(details); |
3989 Node* representation = | 3989 Node* representation = |
3990 BitFieldDecode<PropertyDetails::RepresentationField>(details); | 3990 BitFieldDecode<PropertyDetails::RepresentationField>(details); |
3991 | 3991 |
3992 Node* inobject_properties = LoadMapInobjectProperties(map); | 3992 Node* inobject_properties = LoadMapInobjectProperties(map); |
3993 | 3993 |
3994 Label if_inobject(this), if_backing_store(this); | 3994 Label if_inobject(this), if_backing_store(this); |
3995 Variable var_double_value(this, MachineRepresentation::kFloat64); | 3995 Variable var_double_value(this, MachineRepresentation::kFloat64); |
3996 Label rebox_double(this, &var_double_value); | 3996 Label rebox_double(this, &var_double_value); |
3997 BranchIfUintPtrLessThan(field_index, inobject_properties, &if_inobject, | 3997 Branch(UintPtrLessThan(field_index, inobject_properties), &if_inobject, |
3998 &if_backing_store); | 3998 &if_backing_store); |
3999 Bind(&if_inobject); | 3999 Bind(&if_inobject); |
4000 { | 4000 { |
4001 Comment("if_inobject"); | 4001 Comment("if_inobject"); |
4002 Node* field_offset = | 4002 Node* field_offset = |
4003 IntPtrMul(IntPtrSub(LoadMapInstanceSize(map), | 4003 IntPtrMul(IntPtrSub(LoadMapInstanceSize(map), |
4004 IntPtrSub(inobject_properties, field_index)), | 4004 IntPtrSub(inobject_properties, field_index)), |
4005 IntPtrConstant(kPointerSize)); | 4005 IntPtrConstant(kPointerSize)); |
4006 | 4006 |
4007 Label if_double(this), if_tagged(this); | 4007 Label if_double(this), if_tagged(this); |
4008 BranchIfWord32NotEqual(representation, | 4008 Branch(Word32NotEqual(representation, |
4009 Int32Constant(Representation::kDouble), &if_tagged, | 4009 Int32Constant(Representation::kDouble)), |
4010 &if_double); | 4010 &if_tagged, &if_double); |
4011 Bind(&if_tagged); | 4011 Bind(&if_tagged); |
4012 { | 4012 { |
4013 var_value->Bind(LoadObjectField(object, field_offset)); | 4013 var_value->Bind(LoadObjectField(object, field_offset)); |
4014 Goto(&done); | 4014 Goto(&done); |
4015 } | 4015 } |
4016 Bind(&if_double); | 4016 Bind(&if_double); |
4017 { | 4017 { |
4018 if (FLAG_unbox_double_fields) { | 4018 if (FLAG_unbox_double_fields) { |
4019 var_double_value.Bind( | 4019 var_double_value.Bind( |
4020 LoadObjectField(object, field_offset, MachineType::Float64())); | 4020 LoadObjectField(object, field_offset, MachineType::Float64())); |
4021 } else { | 4021 } else { |
4022 Node* mutable_heap_number = LoadObjectField(object, field_offset); | 4022 Node* mutable_heap_number = LoadObjectField(object, field_offset); |
4023 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); | 4023 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); |
4024 } | 4024 } |
4025 Goto(&rebox_double); | 4025 Goto(&rebox_double); |
4026 } | 4026 } |
4027 } | 4027 } |
4028 Bind(&if_backing_store); | 4028 Bind(&if_backing_store); |
4029 { | 4029 { |
4030 Comment("if_backing_store"); | 4030 Comment("if_backing_store"); |
4031 Node* properties = LoadProperties(object); | 4031 Node* properties = LoadProperties(object); |
4032 field_index = IntPtrSub(field_index, inobject_properties); | 4032 field_index = IntPtrSub(field_index, inobject_properties); |
4033 Node* value = LoadFixedArrayElement(properties, field_index); | 4033 Node* value = LoadFixedArrayElement(properties, field_index); |
4034 | 4034 |
4035 Label if_double(this), if_tagged(this); | 4035 Label if_double(this), if_tagged(this); |
4036 BranchIfWord32NotEqual(representation, | 4036 Branch(Word32NotEqual(representation, |
4037 Int32Constant(Representation::kDouble), &if_tagged, | 4037 Int32Constant(Representation::kDouble)), |
4038 &if_double); | 4038 &if_tagged, &if_double); |
4039 Bind(&if_tagged); | 4039 Bind(&if_tagged); |
4040 { | 4040 { |
4041 var_value->Bind(value); | 4041 var_value->Bind(value); |
4042 Goto(&done); | 4042 Goto(&done); |
4043 } | 4043 } |
4044 Bind(&if_double); | 4044 Bind(&if_double); |
4045 { | 4045 { |
4046 var_double_value.Bind(LoadHeapNumberValue(value)); | 4046 var_double_value.Bind(LoadHeapNumberValue(value)); |
4047 Goto(&rebox_double); | 4047 Goto(&rebox_double); |
4048 } | 4048 } |
(...skipping 2143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6192 // These variables are updated in the loop below. | 6192 // These variables are updated in the loop below. |
6193 Variable* loop_vars[2] = {¤t_js_object, ¤t_map}; | 6193 Variable* loop_vars[2] = {¤t_js_object, ¤t_map}; |
6194 Label loop(this, 2, loop_vars), next(this); | 6194 Label loop(this, 2, loop_vars), next(this); |
6195 | 6195 |
6196 // Check if the enum length field is properly initialized, indicating that | 6196 // Check if the enum length field is properly initialized, indicating that |
6197 // there is an enum cache. | 6197 // there is an enum cache. |
6198 { | 6198 { |
6199 Node* invalid_enum_cache_sentinel = | 6199 Node* invalid_enum_cache_sentinel = |
6200 SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel)); | 6200 SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel)); |
6201 Node* enum_length = EnumLength(current_map.value()); | 6201 Node* enum_length = EnumLength(current_map.value()); |
6202 BranchIfWordEqual(enum_length, invalid_enum_cache_sentinel, use_runtime, | 6202 Branch(WordEqual(enum_length, invalid_enum_cache_sentinel), use_runtime, |
6203 &loop); | 6203 &loop); |
6204 } | 6204 } |
6205 | 6205 |
6206 // Check that there are no elements. |current_js_object| contains | 6206 // Check that there are no elements. |current_js_object| contains |
6207 // the current JS object we've reached through the prototype chain. | 6207 // the current JS object we've reached through the prototype chain. |
6208 Bind(&loop); | 6208 Bind(&loop); |
6209 { | 6209 { |
6210 Label if_elements(this), if_no_elements(this); | 6210 Label if_elements(this), if_no_elements(this); |
6211 Node* elements = LoadElements(current_js_object.value()); | 6211 Node* elements = LoadElements(current_js_object.value()); |
6212 Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | 6212 Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex); |
6213 // Check that there are no elements. | 6213 // Check that there are no elements. |
6214 BranchIfWordEqual(elements, empty_fixed_array, &if_no_elements, | 6214 Branch(WordEqual(elements, empty_fixed_array), &if_no_elements, |
6215 &if_elements); | 6215 &if_elements); |
6216 Bind(&if_elements); | 6216 Bind(&if_elements); |
6217 { | 6217 { |
6218 // Second chance, the object may be using the empty slow element | 6218 // Second chance, the object may be using the empty slow element |
6219 // dictionary. | 6219 // dictionary. |
6220 Node* slow_empty_dictionary = | 6220 Node* slow_empty_dictionary = |
6221 LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex); | 6221 LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex); |
6222 BranchIfWordNotEqual(elements, slow_empty_dictionary, use_runtime, | 6222 Branch(WordNotEqual(elements, slow_empty_dictionary), use_runtime, |
6223 &if_no_elements); | 6223 &if_no_elements); |
6224 } | 6224 } |
6225 | 6225 |
6226 Bind(&if_no_elements); | 6226 Bind(&if_no_elements); |
6227 { | 6227 { |
6228 // Update map prototype. | 6228 // Update map prototype. |
6229 current_js_object.Bind(LoadMapPrototype(current_map.value())); | 6229 current_js_object.Bind(LoadMapPrototype(current_map.value())); |
6230 BranchIfWordEqual(current_js_object.value(), NullConstant(), use_cache, | 6230 Branch(WordEqual(current_js_object.value(), NullConstant()), use_cache, |
6231 &next); | 6231 &next); |
6232 } | 6232 } |
6233 } | 6233 } |
6234 | 6234 |
6235 Bind(&next); | 6235 Bind(&next); |
6236 { | 6236 { |
6237 // For all objects but the receiver, check that the cache is empty. | 6237 // For all objects but the receiver, check that the cache is empty. |
6238 current_map.Bind(LoadMap(current_js_object.value())); | 6238 current_map.Bind(LoadMap(current_js_object.value())); |
6239 Node* enum_length = EnumLength(current_map.value()); | 6239 Node* enum_length = EnumLength(current_map.value()); |
6240 Node* zero_constant = SmiConstant(Smi::kZero); | 6240 Node* zero_constant = SmiConstant(Smi::kZero); |
6241 BranchIf(WordEqual(enum_length, zero_constant), &loop, use_runtime); | 6241 Branch(WordEqual(enum_length, zero_constant), &loop, use_runtime); |
6242 } | 6242 } |
6243 } | 6243 } |
6244 | 6244 |
6245 Node* CodeStubAssembler::CreateAllocationSiteInFeedbackVector( | 6245 Node* CodeStubAssembler::CreateAllocationSiteInFeedbackVector( |
6246 Node* feedback_vector, Node* slot) { | 6246 Node* feedback_vector, Node* slot) { |
6247 Node* size = IntPtrConstant(AllocationSite::kSize); | 6247 Node* size = IntPtrConstant(AllocationSite::kSize); |
6248 Node* site = Allocate(size, CodeStubAssembler::kPretenured); | 6248 Node* site = Allocate(size, CodeStubAssembler::kPretenured); |
6249 | 6249 |
6250 // Store the map | 6250 // Store the map |
6251 StoreObjectFieldRoot(site, AllocationSite::kMapOffset, | 6251 StoreObjectFieldRoot(site, AllocationSite::kMapOffset, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6314 var.Bind(start_index); | 6314 var.Bind(start_index); |
6315 Label loop(this, &var); | 6315 Label loop(this, &var); |
6316 Label after_loop(this); | 6316 Label after_loop(this); |
6317 // Introduce an explicit second check of the termination condition before the | 6317 // Introduce an explicit second check of the termination condition before the |
6318 // loop that helps turbofan generate better code. If there's only a single | 6318 // loop that helps turbofan generate better code. If there's only a single |
6319 // check, then the CodeStubAssembler forces it to be at the beginning of the | 6319 // check, then the CodeStubAssembler forces it to be at the beginning of the |
6320 // loop requiring a backwards branch at the end of the loop (it's not possible | 6320 // loop requiring a backwards branch at the end of the loop (it's not possible |
6321 // to force the loop header check at the end of the loop and branch forward to | 6321 // to force the loop header check at the end of the loop and branch forward to |
6322 // it from the pre-header). The extra branch is slower in the case that the | 6322 // it from the pre-header). The extra branch is slower in the case that the |
6323 // loop actually iterates. | 6323 // loop actually iterates. |
6324 BranchIf(WordEqual(var.value(), end_index), &after_loop, &loop); | 6324 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); |
6325 Bind(&loop); | 6325 Bind(&loop); |
6326 { | 6326 { |
6327 if (mode == IndexAdvanceMode::kPre) { | 6327 if (mode == IndexAdvanceMode::kPre) { |
6328 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 6328 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); |
6329 } | 6329 } |
6330 body(this, var.value()); | 6330 body(this, var.value()); |
6331 if (mode == IndexAdvanceMode::kPost) { | 6331 if (mode == IndexAdvanceMode::kPost) { |
6332 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); | 6332 var.Bind(IntPtrAdd(var.value(), IntPtrConstant(increment))); |
6333 } | 6333 } |
6334 BranchIf(WordNotEqual(var.value(), end_index), &loop, &after_loop); | 6334 Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop); |
6335 } | 6335 } |
6336 Bind(&after_loop); | 6336 Bind(&after_loop); |
6337 } | 6337 } |
6338 | 6338 |
6339 void CodeStubAssembler::BuildFastFixedArrayForEach( | 6339 void CodeStubAssembler::BuildFastFixedArrayForEach( |
6340 compiler::Node* fixed_array, ElementsKind kind, | 6340 compiler::Node* fixed_array, ElementsKind kind, |
6341 compiler::Node* first_element_inclusive, | 6341 compiler::Node* first_element_inclusive, |
6342 compiler::Node* last_element_exclusive, | 6342 compiler::Node* last_element_exclusive, |
6343 std::function<void(CodeStubAssembler* assembler, | 6343 std::function<void(CodeStubAssembler* assembler, |
6344 compiler::Node* fixed_array, compiler::Node* offset)> | 6344 compiler::Node* fixed_array, compiler::Node* offset)> |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6477 | 6477 |
6478 Bind(&do_fcmp); | 6478 Bind(&do_fcmp); |
6479 { | 6479 { |
6480 // Load the {lhs} and {rhs} floating point values. | 6480 // Load the {lhs} and {rhs} floating point values. |
6481 Node* lhs = var_fcmp_lhs.value(); | 6481 Node* lhs = var_fcmp_lhs.value(); |
6482 Node* rhs = var_fcmp_rhs.value(); | 6482 Node* rhs = var_fcmp_rhs.value(); |
6483 | 6483 |
6484 // Perform a fast floating point comparison. | 6484 // Perform a fast floating point comparison. |
6485 switch (mode) { | 6485 switch (mode) { |
6486 case kLessThan: | 6486 case kLessThan: |
6487 BranchIfFloat64LessThan(lhs, rhs, if_true, if_false); | 6487 Branch(Float64LessThan(lhs, rhs), if_true, if_false); |
6488 break; | 6488 break; |
6489 case kLessThanOrEqual: | 6489 case kLessThanOrEqual: |
6490 BranchIfFloat64LessThanOrEqual(lhs, rhs, if_true, if_false); | 6490 Branch(Float64LessThanOrEqual(lhs, rhs), if_true, if_false); |
6491 break; | 6491 break; |
6492 case kGreaterThan: | 6492 case kGreaterThan: |
6493 BranchIfFloat64GreaterThan(lhs, rhs, if_true, if_false); | 6493 Branch(Float64GreaterThan(lhs, rhs), if_true, if_false); |
6494 break; | 6494 break; |
6495 case kGreaterThanOrEqual: | 6495 case kGreaterThanOrEqual: |
6496 BranchIfFloat64GreaterThanOrEqual(lhs, rhs, if_true, if_false); | 6496 Branch(Float64GreaterThanOrEqual(lhs, rhs), if_true, if_false); |
6497 break; | 6497 break; |
6498 } | 6498 } |
6499 } | 6499 } |
6500 } | 6500 } |
6501 | 6501 |
6502 void CodeStubAssembler::GotoUnlessNumberLessThan(compiler::Node* lhs, | 6502 void CodeStubAssembler::GotoUnlessNumberLessThan(compiler::Node* lhs, |
6503 compiler::Node* rhs, | 6503 compiler::Node* rhs, |
6504 Label* if_false) { | 6504 Label* if_false) { |
6505 Label if_true(this); | 6505 Label if_true(this); |
6506 BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false); | 6506 BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false); |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6792 | 6792 |
6793 Bind(&do_fcmp); | 6793 Bind(&do_fcmp); |
6794 { | 6794 { |
6795 // Load the {lhs} and {rhs} floating point values. | 6795 // Load the {lhs} and {rhs} floating point values. |
6796 Node* lhs = var_fcmp_lhs.value(); | 6796 Node* lhs = var_fcmp_lhs.value(); |
6797 Node* rhs = var_fcmp_rhs.value(); | 6797 Node* rhs = var_fcmp_rhs.value(); |
6798 | 6798 |
6799 // Perform a fast floating point comparison. | 6799 // Perform a fast floating point comparison. |
6800 switch (mode) { | 6800 switch (mode) { |
6801 case kLessThan: | 6801 case kLessThan: |
6802 BranchIfFloat64LessThan(lhs, rhs, &return_true, &return_false); | 6802 Branch(Float64LessThan(lhs, rhs), &return_true, &return_false); |
6803 break; | 6803 break; |
6804 case kLessThanOrEqual: | 6804 case kLessThanOrEqual: |
6805 BranchIfFloat64LessThanOrEqual(lhs, rhs, &return_true, &return_false); | 6805 Branch(Float64LessThanOrEqual(lhs, rhs), &return_true, &return_false); |
6806 break; | 6806 break; |
6807 case kGreaterThan: | 6807 case kGreaterThan: |
6808 BranchIfFloat64GreaterThan(lhs, rhs, &return_true, &return_false); | 6808 Branch(Float64GreaterThan(lhs, rhs), &return_true, &return_false); |
6809 break; | 6809 break; |
6810 case kGreaterThanOrEqual: | 6810 case kGreaterThanOrEqual: |
6811 BranchIfFloat64GreaterThanOrEqual(lhs, rhs, &return_true, | 6811 Branch(Float64GreaterThanOrEqual(lhs, rhs), &return_true, |
6812 &return_false); | 6812 &return_false); |
6813 break; | 6813 break; |
6814 } | 6814 } |
6815 } | 6815 } |
6816 | 6816 |
6817 Bind(&return_true); | 6817 Bind(&return_true); |
6818 { | 6818 { |
6819 result.Bind(BooleanConstant(true)); | 6819 result.Bind(BooleanConstant(true)); |
6820 Goto(&end); | 6820 Goto(&end); |
6821 } | 6821 } |
6822 | 6822 |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7216 Goto(&loop); | 7216 Goto(&loop); |
7217 } | 7217 } |
7218 } | 7218 } |
7219 | 7219 |
7220 Bind(&if_lhsisnotboolean); | 7220 Bind(&if_lhsisnotboolean); |
7221 { | 7221 { |
7222 // The {lhs} is either Null or Undefined; check if the {rhs} is | 7222 // The {lhs} is either Null or Undefined; check if the {rhs} is |
7223 // undetectable (i.e. either also Null or Undefined or some | 7223 // undetectable (i.e. either also Null or Undefined or some |
7224 // undetectable JSReceiver). | 7224 // undetectable JSReceiver). |
7225 Node* rhs_bitfield = LoadMapBitField(rhs_map); | 7225 Node* rhs_bitfield = LoadMapBitField(rhs_map); |
7226 BranchIfWord32Equal( | 7226 Branch(Word32Equal( |
7227 Word32And(rhs_bitfield, | 7227 Word32And(rhs_bitfield, |
7228 Int32Constant(1 << Map::kIsUndetectable)), | 7228 Int32Constant(1 << Map::kIsUndetectable)), |
7229 Int32Constant(0), &if_notequal, &if_equal); | 7229 Int32Constant(0)), |
| 7230 &if_notequal, &if_equal); |
7230 } | 7231 } |
7231 } | 7232 } |
7232 | 7233 |
7233 Bind(&if_lhsissymbol); | 7234 Bind(&if_lhsissymbol); |
7234 { | 7235 { |
7235 // Check if the {rhs} is a JSReceiver. | 7236 // Check if the {rhs} is a JSReceiver. |
7236 Label if_rhsisreceiver(this), if_rhsisnotreceiver(this); | 7237 Label if_rhsisreceiver(this), if_rhsisnotreceiver(this); |
7237 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); | 7238 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
7238 Branch(IsJSReceiverInstanceType(rhs_instance_type), | 7239 Branch(IsJSReceiverInstanceType(rhs_instance_type), |
7239 &if_rhsisreceiver, &if_rhsisnotreceiver); | 7240 &if_rhsisreceiver, &if_rhsisnotreceiver); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7314 } | 7315 } |
7315 | 7316 |
7316 Bind(&if_rhsisnotreceiver); | 7317 Bind(&if_rhsisnotreceiver); |
7317 { | 7318 { |
7318 // Check if {rhs} is Null or Undefined (an undetectable check | 7319 // Check if {rhs} is Null or Undefined (an undetectable check |
7319 // is sufficient here, since we already know that {rhs} is not | 7320 // is sufficient here, since we already know that {rhs} is not |
7320 // a JSReceiver). | 7321 // a JSReceiver). |
7321 Label if_rhsisundetectable(this), | 7322 Label if_rhsisundetectable(this), |
7322 if_rhsisnotundetectable(this, Label::kDeferred); | 7323 if_rhsisnotundetectable(this, Label::kDeferred); |
7323 Node* rhs_bitfield = LoadMapBitField(rhs_map); | 7324 Node* rhs_bitfield = LoadMapBitField(rhs_map); |
7324 BranchIfWord32Equal( | 7325 Branch(Word32Equal( |
7325 Word32And(rhs_bitfield, | 7326 Word32And(rhs_bitfield, |
7326 Int32Constant(1 << Map::kIsUndetectable)), | 7327 Int32Constant(1 << Map::kIsUndetectable)), |
7327 Int32Constant(0), &if_rhsisnotundetectable, | 7328 Int32Constant(0)), |
7328 &if_rhsisundetectable); | 7329 &if_rhsisnotundetectable, &if_rhsisundetectable); |
7329 | 7330 |
7330 Bind(&if_rhsisundetectable); | 7331 Bind(&if_rhsisundetectable); |
7331 { | 7332 { |
7332 // Check if {lhs} is an undetectable JSReceiver. | 7333 // Check if {lhs} is an undetectable JSReceiver. |
7333 Node* lhs_bitfield = LoadMapBitField(lhs_map); | 7334 Node* lhs_bitfield = LoadMapBitField(lhs_map); |
7334 BranchIfWord32Equal( | 7335 Branch(Word32Equal( |
7335 Word32And(lhs_bitfield, | 7336 Word32And(lhs_bitfield, |
7336 Int32Constant(1 << Map::kIsUndetectable)), | 7337 Int32Constant(1 << Map::kIsUndetectable)), |
7337 Int32Constant(0), &if_notequal, &if_equal); | 7338 Int32Constant(0)), |
| 7339 &if_notequal, &if_equal); |
7338 } | 7340 } |
7339 | 7341 |
7340 Bind(&if_rhsisnotundetectable); | 7342 Bind(&if_rhsisnotundetectable); |
7341 { | 7343 { |
7342 // The {rhs} is some Primitive different from Null and | 7344 // The {rhs} is some Primitive different from Null and |
7343 // Undefined, need to convert {lhs} to Primitive first. | 7345 // Undefined, need to convert {lhs} to Primitive first. |
7344 Callable callable = | 7346 Callable callable = |
7345 CodeFactory::NonPrimitiveToPrimitive(isolate()); | 7347 CodeFactory::NonPrimitiveToPrimitive(isolate()); |
7346 var_lhs.Bind(CallStub(callable, context, lhs)); | 7348 var_lhs.Bind(CallStub(callable, context, lhs)); |
7347 Goto(&loop); | 7349 Goto(&loop); |
(...skipping 12 matching lines...) Expand all Loading... |
7360 } | 7362 } |
7361 } | 7363 } |
7362 | 7364 |
7363 Bind(&do_fcmp); | 7365 Bind(&do_fcmp); |
7364 { | 7366 { |
7365 // Load the {lhs} and {rhs} floating point values. | 7367 // Load the {lhs} and {rhs} floating point values. |
7366 Node* lhs = var_fcmp_lhs.value(); | 7368 Node* lhs = var_fcmp_lhs.value(); |
7367 Node* rhs = var_fcmp_rhs.value(); | 7369 Node* rhs = var_fcmp_rhs.value(); |
7368 | 7370 |
7369 // Perform a fast floating point comparison. | 7371 // Perform a fast floating point comparison. |
7370 BranchIfFloat64Equal(lhs, rhs, &if_equal, &if_notequal); | 7372 Branch(Float64Equal(lhs, rhs), &if_equal, &if_notequal); |
7371 } | 7373 } |
7372 | 7374 |
7373 Bind(&if_equal); | 7375 Bind(&if_equal); |
7374 { | 7376 { |
7375 result.Bind(BooleanConstant(mode == kDontNegateResult)); | 7377 result.Bind(BooleanConstant(mode == kDontNegateResult)); |
7376 Goto(&end); | 7378 Goto(&end); |
7377 } | 7379 } |
7378 | 7380 |
7379 Bind(&if_notequal); | 7381 Bind(&if_notequal); |
7380 { | 7382 { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7480 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 7482 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
7481 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 7483 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
7482 | 7484 |
7483 Bind(&if_rhsissmi); | 7485 Bind(&if_rhsissmi); |
7484 { | 7486 { |
7485 // Convert {lhs} and {rhs} to floating point values. | 7487 // Convert {lhs} and {rhs} to floating point values. |
7486 Node* lhs_value = LoadHeapNumberValue(lhs); | 7488 Node* lhs_value = LoadHeapNumberValue(lhs); |
7487 Node* rhs_value = SmiToFloat64(rhs); | 7489 Node* rhs_value = SmiToFloat64(rhs); |
7488 | 7490 |
7489 // Perform a floating point comparison of {lhs} and {rhs}. | 7491 // Perform a floating point comparison of {lhs} and {rhs}. |
7490 BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal, &if_notequal); | 7492 Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal); |
7491 } | 7493 } |
7492 | 7494 |
7493 Bind(&if_rhsisnotsmi); | 7495 Bind(&if_rhsisnotsmi); |
7494 { | 7496 { |
7495 // Load the map of {rhs}. | 7497 // Load the map of {rhs}. |
7496 Node* rhs_map = LoadMap(rhs); | 7498 Node* rhs_map = LoadMap(rhs); |
7497 | 7499 |
7498 // Check if {rhs} is also a HeapNumber. | 7500 // Check if {rhs} is also a HeapNumber. |
7499 Label if_rhsisnumber(this), if_rhsisnotnumber(this); | 7501 Label if_rhsisnumber(this), if_rhsisnotnumber(this); |
7500 Branch(WordEqual(rhs_map, number_map), &if_rhsisnumber, | 7502 Branch(WordEqual(rhs_map, number_map), &if_rhsisnumber, |
7501 &if_rhsisnotnumber); | 7503 &if_rhsisnotnumber); |
7502 | 7504 |
7503 Bind(&if_rhsisnumber); | 7505 Bind(&if_rhsisnumber); |
7504 { | 7506 { |
7505 // Convert {lhs} and {rhs} to floating point values. | 7507 // Convert {lhs} and {rhs} to floating point values. |
7506 Node* lhs_value = LoadHeapNumberValue(lhs); | 7508 Node* lhs_value = LoadHeapNumberValue(lhs); |
7507 Node* rhs_value = LoadHeapNumberValue(rhs); | 7509 Node* rhs_value = LoadHeapNumberValue(rhs); |
7508 | 7510 |
7509 // Perform a floating point comparison of {lhs} and {rhs}. | 7511 // Perform a floating point comparison of {lhs} and {rhs}. |
7510 BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal, &if_notequal); | 7512 Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal); |
7511 } | 7513 } |
7512 | 7514 |
7513 Bind(&if_rhsisnotnumber); | 7515 Bind(&if_rhsisnotnumber); |
7514 Goto(&if_notequal); | 7516 Goto(&if_notequal); |
7515 } | 7517 } |
7516 } | 7518 } |
7517 | 7519 |
7518 Bind(&if_lhsisnotnumber); | 7520 Bind(&if_lhsisnotnumber); |
7519 { | 7521 { |
7520 // Check if {rhs} is a Smi or a HeapObject. | 7522 // Check if {rhs} is a Smi or a HeapObject. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7606 Branch(WordEqual(rhs_map, number_map), &if_rhsisnumber, | 7608 Branch(WordEqual(rhs_map, number_map), &if_rhsisnumber, |
7607 &if_rhsisnotnumber); | 7609 &if_rhsisnotnumber); |
7608 | 7610 |
7609 Bind(&if_rhsisnumber); | 7611 Bind(&if_rhsisnumber); |
7610 { | 7612 { |
7611 // Convert {lhs} and {rhs} to floating point values. | 7613 // Convert {lhs} and {rhs} to floating point values. |
7612 Node* lhs_value = SmiToFloat64(lhs); | 7614 Node* lhs_value = SmiToFloat64(lhs); |
7613 Node* rhs_value = LoadHeapNumberValue(rhs); | 7615 Node* rhs_value = LoadHeapNumberValue(rhs); |
7614 | 7616 |
7615 // Perform a floating point comparison of {lhs} and {rhs}. | 7617 // Perform a floating point comparison of {lhs} and {rhs}. |
7616 BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal, &if_notequal); | 7618 Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal); |
7617 } | 7619 } |
7618 | 7620 |
7619 Bind(&if_rhsisnotnumber); | 7621 Bind(&if_rhsisnotnumber); |
7620 Goto(&if_notequal); | 7622 Goto(&if_notequal); |
7621 } | 7623 } |
7622 } | 7624 } |
7623 } | 7625 } |
7624 | 7626 |
7625 Bind(&if_equal); | 7627 Bind(&if_equal); |
7626 { | 7628 { |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8068 Node* buffer_bit_field = LoadObjectField( | 8070 Node* buffer_bit_field = LoadObjectField( |
8069 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8071 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8070 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8072 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
8071 | 8073 |
8072 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8074 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
8073 Int32Constant(0)); | 8075 Int32Constant(0)); |
8074 } | 8076 } |
8075 | 8077 |
8076 } // namespace internal | 8078 } // namespace internal |
8077 } // namespace v8 | 8079 } // namespace v8 |
OLD | NEW |