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