| 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 [=] { return IntPtrConstant(1); }, | 189 [=] { return IntPtrConstant(1); }, |
| 190 [=] { return WordAnd(value, IntPtrSub(value, IntPtrConstant(1))); }, | 190 [=] { return WordAnd(value, IntPtrSub(value, IntPtrConstant(1))); }, |
| 191 MachineType::PointerRepresentation()), | 191 MachineType::PointerRepresentation()), |
| 192 IntPtrConstant(0)); | 192 IntPtrConstant(0)); |
| 193 } | 193 } |
| 194 | 194 |
| 195 Node* CodeStubAssembler::Float64Round(Node* x) { | 195 Node* CodeStubAssembler::Float64Round(Node* x) { |
| 196 Node* one = Float64Constant(1.0); | 196 Node* one = Float64Constant(1.0); |
| 197 Node* one_half = Float64Constant(0.5); | 197 Node* one_half = Float64Constant(0.5); |
| 198 | 198 |
| 199 Variable var_x(this, MachineRepresentation::kFloat64); | |
| 200 Label return_x(this); | 199 Label return_x(this); |
| 201 | 200 |
| 202 // Round up {x} towards Infinity. | 201 // Round up {x} towards Infinity. |
| 203 var_x.Bind(Float64Ceil(x)); | 202 Variable var_x(this, MachineRepresentation::kFloat64, Float64Ceil(x)); |
| 204 | 203 |
| 205 GotoIf(Float64LessThanOrEqual(Float64Sub(var_x.value(), one_half), x), | 204 GotoIf(Float64LessThanOrEqual(Float64Sub(var_x.value(), one_half), x), |
| 206 &return_x); | 205 &return_x); |
| 207 var_x.Bind(Float64Sub(var_x.value(), one)); | 206 var_x.Bind(Float64Sub(var_x.value(), one)); |
| 208 Goto(&return_x); | 207 Goto(&return_x); |
| 209 | 208 |
| 210 Bind(&return_x); | 209 Bind(&return_x); |
| 211 return var_x.value(); | 210 return var_x.value(); |
| 212 } | 211 } |
| 213 | 212 |
| 214 Node* CodeStubAssembler::Float64Ceil(Node* x) { | 213 Node* CodeStubAssembler::Float64Ceil(Node* x) { |
| 215 if (IsFloat64RoundUpSupported()) { | 214 if (IsFloat64RoundUpSupported()) { |
| 216 return Float64RoundUp(x); | 215 return Float64RoundUp(x); |
| 217 } | 216 } |
| 218 | 217 |
| 219 Node* one = Float64Constant(1.0); | 218 Node* one = Float64Constant(1.0); |
| 220 Node* zero = Float64Constant(0.0); | 219 Node* zero = Float64Constant(0.0); |
| 221 Node* two_52 = Float64Constant(4503599627370496.0E0); | 220 Node* two_52 = Float64Constant(4503599627370496.0E0); |
| 222 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); | 221 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); |
| 223 | 222 |
| 224 Variable var_x(this, MachineRepresentation::kFloat64); | 223 Variable var_x(this, MachineRepresentation::kFloat64, x); |
| 225 Label return_x(this), return_minus_x(this); | 224 Label return_x(this), return_minus_x(this); |
| 226 var_x.Bind(x); | |
| 227 | 225 |
| 228 // Check if {x} is greater than zero. | 226 // Check if {x} is greater than zero. |
| 229 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); | 227 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); |
| 230 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, | 228 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, |
| 231 &if_xnotgreaterthanzero); | 229 &if_xnotgreaterthanzero); |
| 232 | 230 |
| 233 Bind(&if_xgreaterthanzero); | 231 Bind(&if_xgreaterthanzero); |
| 234 { | 232 { |
| 235 // Just return {x} unless it's in the range ]0,2^52[. | 233 // Just return {x} unless it's in the range ]0,2^52[. |
| 236 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x); | 234 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 267 Node* CodeStubAssembler::Float64Floor(Node* x) { | 265 Node* CodeStubAssembler::Float64Floor(Node* x) { |
| 268 if (IsFloat64RoundDownSupported()) { | 266 if (IsFloat64RoundDownSupported()) { |
| 269 return Float64RoundDown(x); | 267 return Float64RoundDown(x); |
| 270 } | 268 } |
| 271 | 269 |
| 272 Node* one = Float64Constant(1.0); | 270 Node* one = Float64Constant(1.0); |
| 273 Node* zero = Float64Constant(0.0); | 271 Node* zero = Float64Constant(0.0); |
| 274 Node* two_52 = Float64Constant(4503599627370496.0E0); | 272 Node* two_52 = Float64Constant(4503599627370496.0E0); |
| 275 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); | 273 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); |
| 276 | 274 |
| 277 Variable var_x(this, MachineRepresentation::kFloat64); | 275 Variable var_x(this, MachineRepresentation::kFloat64, x); |
| 278 Label return_x(this), return_minus_x(this); | 276 Label return_x(this), return_minus_x(this); |
| 279 var_x.Bind(x); | |
| 280 | 277 |
| 281 // Check if {x} is greater than zero. | 278 // Check if {x} is greater than zero. |
| 282 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); | 279 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); |
| 283 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, | 280 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, |
| 284 &if_xnotgreaterthanzero); | 281 &if_xnotgreaterthanzero); |
| 285 | 282 |
| 286 Bind(&if_xgreaterthanzero); | 283 Bind(&if_xgreaterthanzero); |
| 287 { | 284 { |
| 288 // Just return {x} unless it's in the range ]0,2^52[. | 285 // Just return {x} unless it's in the range ]0,2^52[. |
| 289 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x); | 286 GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 Node* CodeStubAssembler::Float64Trunc(Node* x) { | 348 Node* CodeStubAssembler::Float64Trunc(Node* x) { |
| 352 if (IsFloat64RoundTruncateSupported()) { | 349 if (IsFloat64RoundTruncateSupported()) { |
| 353 return Float64RoundTruncate(x); | 350 return Float64RoundTruncate(x); |
| 354 } | 351 } |
| 355 | 352 |
| 356 Node* one = Float64Constant(1.0); | 353 Node* one = Float64Constant(1.0); |
| 357 Node* zero = Float64Constant(0.0); | 354 Node* zero = Float64Constant(0.0); |
| 358 Node* two_52 = Float64Constant(4503599627370496.0E0); | 355 Node* two_52 = Float64Constant(4503599627370496.0E0); |
| 359 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); | 356 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); |
| 360 | 357 |
| 361 Variable var_x(this, MachineRepresentation::kFloat64); | 358 Variable var_x(this, MachineRepresentation::kFloat64, x); |
| 362 Label return_x(this), return_minus_x(this); | 359 Label return_x(this), return_minus_x(this); |
| 363 var_x.Bind(x); | |
| 364 | 360 |
| 365 // Check if {x} is greater than 0. | 361 // Check if {x} is greater than 0. |
| 366 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); | 362 Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); |
| 367 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, | 363 Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, |
| 368 &if_xnotgreaterthanzero); | 364 &if_xnotgreaterthanzero); |
| 369 | 365 |
| 370 Bind(&if_xgreaterthanzero); | 366 Bind(&if_xgreaterthanzero); |
| 371 { | 367 { |
| 372 if (IsFloat64RoundDownSupported()) { | 368 if (IsFloat64RoundDownSupported()) { |
| 373 var_x.Bind(Float64RoundDown(x)); | 369 var_x.Bind(Float64RoundDown(x)); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 } | 664 } |
| 669 } | 665 } |
| 670 | 666 |
| 671 Bind(&if_mapnotsame); | 667 Bind(&if_mapnotsame); |
| 672 Goto(if_notequal); | 668 Goto(if_notequal); |
| 673 } | 669 } |
| 674 | 670 |
| 675 void CodeStubAssembler::BranchIfPrototypesHaveNoElements( | 671 void CodeStubAssembler::BranchIfPrototypesHaveNoElements( |
| 676 Node* receiver_map, Label* definitely_no_elements, | 672 Node* receiver_map, Label* definitely_no_elements, |
| 677 Label* possibly_elements) { | 673 Label* possibly_elements) { |
| 678 Variable var_map(this, MachineRepresentation::kTagged); | 674 Variable var_map(this, MachineRepresentation::kTagged, receiver_map); |
| 679 var_map.Bind(receiver_map); | |
| 680 Label loop_body(this, &var_map); | 675 Label loop_body(this, &var_map); |
| 681 Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | 676 Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex); |
| 682 Goto(&loop_body); | 677 Goto(&loop_body); |
| 683 | 678 |
| 684 Bind(&loop_body); | 679 Bind(&loop_body); |
| 685 { | 680 { |
| 686 Node* map = var_map.value(); | 681 Node* map = var_map.value(); |
| 687 Node* prototype = LoadMapPrototype(map); | 682 Node* prototype = LoadMapPrototype(map); |
| 688 GotoIf(WordEqual(prototype, NullConstant()), definitely_no_elements); | 683 GotoIf(WordEqual(prototype, NullConstant()), definitely_no_elements); |
| 689 Node* prototype_map = LoadMap(prototype); | 684 Node* prototype_map = LoadMap(prototype); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 Bind(&merge_runtime); | 799 Bind(&merge_runtime); |
| 805 return result.value(); | 800 return result.value(); |
| 806 } | 801 } |
| 807 | 802 |
| 808 Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, | 803 Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, |
| 809 AllocationFlags flags, | 804 AllocationFlags flags, |
| 810 Node* top_address, | 805 Node* top_address, |
| 811 Node* limit_address) { | 806 Node* limit_address) { |
| 812 Node* top = Load(MachineType::Pointer(), top_address); | 807 Node* top = Load(MachineType::Pointer(), top_address); |
| 813 Node* limit = Load(MachineType::Pointer(), limit_address); | 808 Node* limit = Load(MachineType::Pointer(), limit_address); |
| 814 Variable adjusted_size(this, MachineType::PointerRepresentation()); | 809 Variable adjusted_size(this, MachineType::PointerRepresentation(), |
| 815 adjusted_size.Bind(size_in_bytes); | 810 size_in_bytes); |
| 816 if (flags & kDoubleAlignment) { | 811 if (flags & kDoubleAlignment) { |
| 817 // TODO(epertoso): Simd128 alignment. | 812 // TODO(epertoso): Simd128 alignment. |
| 818 Label aligned(this), not_aligned(this), merge(this, &adjusted_size); | 813 Label aligned(this), not_aligned(this), merge(this, &adjusted_size); |
| 819 Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), ¬_aligned, | 814 Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), ¬_aligned, |
| 820 &aligned); | 815 &aligned); |
| 821 | 816 |
| 822 Bind(¬_aligned); | 817 Bind(¬_aligned); |
| 823 Node* not_aligned_size = | 818 Node* not_aligned_size = |
| 824 IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); | 819 IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); |
| 825 adjusted_size.Bind(not_aligned_size); | 820 adjusted_size.Bind(not_aligned_size); |
| 826 Goto(&merge); | 821 Goto(&merge); |
| 827 | 822 |
| 828 Bind(&aligned); | 823 Bind(&aligned); |
| 829 Goto(&merge); | 824 Goto(&merge); |
| 830 | 825 |
| 831 Bind(&merge); | 826 Bind(&merge); |
| 832 } | 827 } |
| 833 | 828 |
| 834 Variable address(this, MachineRepresentation::kTagged); | 829 Variable address( |
| 835 address.Bind(AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit)); | 830 this, MachineRepresentation::kTagged, |
| 831 AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit)); |
| 836 | 832 |
| 837 Label needs_filler(this), doesnt_need_filler(this), | 833 Label needs_filler(this), doesnt_need_filler(this), |
| 838 merge_address(this, &address); | 834 merge_address(this, &address); |
| 839 Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler, | 835 Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler, |
| 840 &needs_filler); | 836 &needs_filler); |
| 841 | 837 |
| 842 Bind(&needs_filler); | 838 Bind(&needs_filler); |
| 843 // Store a filler and increase the address by kPointerSize. | 839 // Store a filler and increase the address by kPointerSize. |
| 844 // TODO(epertoso): this code assumes that we only align to kDoubleSize. Change | 840 // TODO(epertoso): this code assumes that we only align to kDoubleSize. Change |
| 845 // it when Simd128 alignment is supported. | 841 // it when Simd128 alignment is supported. |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); | 1165 STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); |
| 1170 CSA_ASSERT(this, Int32LessThanOrEqual(LoadMapInstanceType(map), | 1166 CSA_ASSERT(this, Int32LessThanOrEqual(LoadMapInstanceType(map), |
| 1171 Int32Constant(LAST_PRIMITIVE_TYPE))); | 1167 Int32Constant(LAST_PRIMITIVE_TYPE))); |
| 1172 return ChangeUint32ToWord(LoadObjectField( | 1168 return ChangeUint32ToWord(LoadObjectField( |
| 1173 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, | 1169 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset, |
| 1174 MachineType::Uint8())); | 1170 MachineType::Uint8())); |
| 1175 } | 1171 } |
| 1176 | 1172 |
| 1177 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { | 1173 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { |
| 1178 CSA_SLOW_ASSERT(this, IsMap(map)); | 1174 CSA_SLOW_ASSERT(this, IsMap(map)); |
| 1179 Variable result(this, MachineRepresentation::kTagged); | 1175 Variable result(this, MachineRepresentation::kTagged, |
| 1180 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); | 1176 LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); |
| 1181 | 1177 |
| 1182 Label done(this), loop(this, &result); | 1178 Label done(this), loop(this, &result); |
| 1183 Goto(&loop); | 1179 Goto(&loop); |
| 1184 Bind(&loop); | 1180 Bind(&loop); |
| 1185 { | 1181 { |
| 1186 GotoIf(TaggedIsSmi(result.value()), &done); | 1182 GotoIf(TaggedIsSmi(result.value()), &done); |
| 1187 Node* is_map_type = | 1183 Node* is_map_type = |
| 1188 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); | 1184 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); |
| 1189 GotoUnless(is_map_type, &done); | 1185 GotoUnless(is_map_type, &done); |
| 1190 result.Bind( | 1186 result.Bind( |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 } | 1472 } |
| 1477 | 1473 |
| 1478 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, | 1474 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, |
| 1479 Node* array, | 1475 Node* array, |
| 1480 CodeStubArguments& args, | 1476 CodeStubArguments& args, |
| 1481 Variable& arg_index, | 1477 Variable& arg_index, |
| 1482 Label* bailout) { | 1478 Label* bailout) { |
| 1483 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); | 1479 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); |
| 1484 Label pre_bailout(this); | 1480 Label pre_bailout(this); |
| 1485 Label success(this); | 1481 Label success(this); |
| 1486 Variable var_elements(this, MachineRepresentation::kTagged); | |
| 1487 Variable var_tagged_length(this, MachineRepresentation::kTagged); | 1482 Variable var_tagged_length(this, MachineRepresentation::kTagged); |
| 1488 ParameterMode mode = OptimalParameterMode(); | 1483 ParameterMode mode = OptimalParameterMode(); |
| 1489 Variable var_length(this, OptimalParameterRepresentation()); | 1484 Variable var_length(this, OptimalParameterRepresentation(), |
| 1490 var_length.Bind(TaggedToParameter(LoadJSArrayLength(array), mode)); | 1485 TaggedToParameter(LoadJSArrayLength(array), mode)); |
| 1491 var_elements.Bind(LoadElements(array)); | 1486 Variable var_elements(this, MachineRepresentation::kTagged, |
| 1487 LoadElements(array)); |
| 1492 Node* capacity = | 1488 Node* capacity = |
| 1493 TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode); | 1489 TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode); |
| 1494 | 1490 |
| 1495 // Resize the capacity of the fixed array if it doesn't fit. | 1491 // Resize the capacity of the fixed array if it doesn't fit. |
| 1496 Label fits(this, &var_elements); | 1492 Label fits(this, &var_elements); |
| 1497 Node* first = arg_index.value(); | 1493 Node* first = arg_index.value(); |
| 1498 Node* growth = IntPtrSub(args.GetLength(), first); | 1494 Node* growth = IntPtrSub(args.GetLength(), first); |
| 1499 Node* new_length = | 1495 Node* new_length = |
| 1500 IntPtrOrSmiAdd(WordToParameter(growth, mode), var_length.value(), mode); | 1496 IntPtrOrSmiAdd(WordToParameter(growth, mode), var_length.value(), mode); |
| 1501 GotoUnless(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits); | 1497 GotoUnless(IntPtrOrSmiGreaterThan(new_length, capacity, mode), &fits); |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2189 // consistent state. | 2185 // consistent state. |
| 2190 FillFixedArrayWithValue(to_kind, to_array, IntPtrOrSmiConstant(0, mode), | 2186 FillFixedArrayWithValue(to_kind, to_array, IntPtrOrSmiConstant(0, mode), |
| 2191 capacity, Heap::kTheHoleValueRootIndex, mode); | 2187 capacity, Heap::kTheHoleValueRootIndex, mode); |
| 2192 } else if (element_count != capacity) { | 2188 } else if (element_count != capacity) { |
| 2193 FillFixedArrayWithValue(to_kind, to_array, element_count, capacity, | 2189 FillFixedArrayWithValue(to_kind, to_array, element_count, capacity, |
| 2194 Heap::kTheHoleValueRootIndex, mode); | 2190 Heap::kTheHoleValueRootIndex, mode); |
| 2195 } | 2191 } |
| 2196 | 2192 |
| 2197 Node* limit_offset = ElementOffsetFromIndex( | 2193 Node* limit_offset = ElementOffsetFromIndex( |
| 2198 IntPtrOrSmiConstant(0, mode), from_kind, mode, first_element_offset); | 2194 IntPtrOrSmiConstant(0, mode), from_kind, mode, first_element_offset); |
| 2199 Variable var_from_offset(this, MachineType::PointerRepresentation()); | 2195 Variable var_from_offset(this, MachineType::PointerRepresentation(), |
| 2200 var_from_offset.Bind(ElementOffsetFromIndex(element_count, from_kind, mode, | 2196 ElementOffsetFromIndex(element_count, from_kind, |
| 2201 first_element_offset)); | 2197 mode, first_element_offset)); |
| 2202 // This second variable is used only when the element sizes of source and | 2198 // This second variable is used only when the element sizes of source and |
| 2203 // destination arrays do not match. | 2199 // destination arrays do not match. |
| 2204 Variable var_to_offset(this, MachineType::PointerRepresentation()); | 2200 Variable var_to_offset(this, MachineType::PointerRepresentation()); |
| 2205 if (element_size_matches) { | 2201 if (element_size_matches) { |
| 2206 var_to_offset.Bind(var_from_offset.value()); | 2202 var_to_offset.Bind(var_from_offset.value()); |
| 2207 } else { | 2203 } else { |
| 2208 var_to_offset.Bind(ElementOffsetFromIndex(element_count, to_kind, mode, | 2204 var_to_offset.Bind(ElementOffsetFromIndex(element_count, to_kind, mode, |
| 2209 first_element_offset)); | 2205 first_element_offset)); |
| 2210 } | 2206 } |
| 2211 | 2207 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2316 Node* limit_offset = IntPtrAdd(from_offset, byte_count); | 2312 Node* limit_offset = IntPtrAdd(from_offset, byte_count); |
| 2317 | 2313 |
| 2318 // Prepare the fast loop | 2314 // Prepare the fast loop |
| 2319 MachineType type = | 2315 MachineType type = |
| 2320 from_one_byte ? MachineType::Uint8() : MachineType::Uint16(); | 2316 from_one_byte ? MachineType::Uint8() : MachineType::Uint16(); |
| 2321 MachineRepresentation rep = to_one_byte ? MachineRepresentation::kWord8 | 2317 MachineRepresentation rep = to_one_byte ? MachineRepresentation::kWord8 |
| 2322 : MachineRepresentation::kWord16; | 2318 : MachineRepresentation::kWord16; |
| 2323 int from_increment = 1 << ElementsKindToShiftSize(from_kind); | 2319 int from_increment = 1 << ElementsKindToShiftSize(from_kind); |
| 2324 int to_increment = 1 << ElementsKindToShiftSize(to_kind); | 2320 int to_increment = 1 << ElementsKindToShiftSize(to_kind); |
| 2325 | 2321 |
| 2326 Variable current_to_offset(this, MachineType::PointerRepresentation()); | 2322 Variable current_to_offset(this, MachineType::PointerRepresentation(), |
| 2323 to_offset); |
| 2327 VariableList vars({¤t_to_offset}, zone()); | 2324 VariableList vars({¤t_to_offset}, zone()); |
| 2328 current_to_offset.Bind(to_offset); | |
| 2329 int to_index_constant = 0, from_index_constant = 0; | 2325 int to_index_constant = 0, from_index_constant = 0; |
| 2330 Smi* to_index_smi = nullptr; | 2326 Smi* to_index_smi = nullptr; |
| 2331 Smi* from_index_smi = nullptr; | 2327 Smi* from_index_smi = nullptr; |
| 2332 bool index_same = (from_encoding == to_encoding) && | 2328 bool index_same = (from_encoding == to_encoding) && |
| 2333 (from_index == to_index || | 2329 (from_index == to_index || |
| 2334 (ToInt32Constant(from_index, from_index_constant) && | 2330 (ToInt32Constant(from_index, from_index_constant) && |
| 2335 ToInt32Constant(to_index, to_index_constant) && | 2331 ToInt32Constant(to_index, to_index_constant) && |
| 2336 from_index_constant == to_index_constant) || | 2332 from_index_constant == to_index_constant) || |
| 2337 (ToSmiConstant(from_index, from_index_smi) && | 2333 (ToSmiConstant(from_index, from_index_smi) && |
| 2338 ToSmiConstant(to_index, to_index_smi) && | 2334 ToSmiConstant(to_index, to_index_smi) && |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2527 var_value.Bind(CallStub(callable, context, value)); | 2523 var_value.Bind(CallStub(callable, context, value)); |
| 2528 Goto(&loop); | 2524 Goto(&loop); |
| 2529 } | 2525 } |
| 2530 } | 2526 } |
| 2531 Bind(&done_loop); | 2527 Bind(&done_loop); |
| 2532 return var_result.value(); | 2528 return var_result.value(); |
| 2533 } | 2529 } |
| 2534 | 2530 |
| 2535 Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) { | 2531 Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) { |
| 2536 // We might need to loop once due to ToNumber conversion. | 2532 // We might need to loop once due to ToNumber conversion. |
| 2537 Variable var_value(this, MachineRepresentation::kTagged), | 2533 Variable var_value(this, MachineRepresentation::kTagged, value), |
| 2538 var_result(this, MachineRepresentation::kWord32); | 2534 var_result(this, MachineRepresentation::kWord32); |
| 2539 Label loop(this, &var_value), done_loop(this, &var_result); | 2535 Label loop(this, &var_value), done_loop(this, &var_result); |
| 2540 var_value.Bind(value); | |
| 2541 Goto(&loop); | 2536 Goto(&loop); |
| 2542 Bind(&loop); | 2537 Bind(&loop); |
| 2543 { | 2538 { |
| 2544 // Load the current {value}. | 2539 // Load the current {value}. |
| 2545 value = var_value.value(); | 2540 value = var_value.value(); |
| 2546 | 2541 |
| 2547 // Check if the {value} is a Smi or a HeapObject. | 2542 // Check if the {value} is a Smi or a HeapObject. |
| 2548 Label if_valueissmi(this), if_valueisnotsmi(this); | 2543 Label if_valueissmi(this), if_valueisnotsmi(this); |
| 2549 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 2544 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
| 2550 | 2545 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2695 var_result.Bind(AllocateHeapNumberWithValue(float64_value)); | 2690 var_result.Bind(AllocateHeapNumberWithValue(float64_value)); |
| 2696 } | 2691 } |
| 2697 Goto(&if_join); | 2692 Goto(&if_join); |
| 2698 | 2693 |
| 2699 Bind(&if_join); | 2694 Bind(&if_join); |
| 2700 return var_result.value(); | 2695 return var_result.value(); |
| 2701 } | 2696 } |
| 2702 | 2697 |
| 2703 Node* CodeStubAssembler::ToThisString(Node* context, Node* value, | 2698 Node* CodeStubAssembler::ToThisString(Node* context, Node* value, |
| 2704 char const* method_name) { | 2699 char const* method_name) { |
| 2705 Variable var_value(this, MachineRepresentation::kTagged); | 2700 Variable var_value(this, MachineRepresentation::kTagged, value); |
| 2706 var_value.Bind(value); | |
| 2707 | 2701 |
| 2708 // Check if the {value} is a Smi or a HeapObject. | 2702 // Check if the {value} is a Smi or a HeapObject. |
| 2709 Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this), | 2703 Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this), |
| 2710 if_valueisstring(this); | 2704 if_valueisstring(this); |
| 2711 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 2705 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
| 2712 Bind(&if_valueisnotsmi); | 2706 Bind(&if_valueisnotsmi); |
| 2713 { | 2707 { |
| 2714 // Load the instance type of the {value}. | 2708 // Load the instance type of the {value}. |
| 2715 Node* value_instance_type = LoadInstanceType(value); | 2709 Node* value_instance_type = LoadInstanceType(value); |
| 2716 | 2710 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 } | 2771 } |
| 2778 | 2772 |
| 2779 Bind(&done); | 2773 Bind(&done); |
| 2780 return result.value(); | 2774 return result.value(); |
| 2781 } | 2775 } |
| 2782 | 2776 |
| 2783 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, | 2777 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, |
| 2784 PrimitiveType primitive_type, | 2778 PrimitiveType primitive_type, |
| 2785 char const* method_name) { | 2779 char const* method_name) { |
| 2786 // We might need to loop once due to JSValue unboxing. | 2780 // We might need to loop once due to JSValue unboxing. |
| 2787 Variable var_value(this, MachineRepresentation::kTagged); | 2781 Variable var_value(this, MachineRepresentation::kTagged, value); |
| 2788 Label loop(this, &var_value), done_loop(this), | 2782 Label loop(this, &var_value), done_loop(this), |
| 2789 done_throw(this, Label::kDeferred); | 2783 done_throw(this, Label::kDeferred); |
| 2790 var_value.Bind(value); | |
| 2791 Goto(&loop); | 2784 Goto(&loop); |
| 2792 Bind(&loop); | 2785 Bind(&loop); |
| 2793 { | 2786 { |
| 2794 // Load the current {value}. | 2787 // Load the current {value}. |
| 2795 value = var_value.value(); | 2788 value = var_value.value(); |
| 2796 | 2789 |
| 2797 // Check if the {value} is a Smi or a HeapObject. | 2790 // Check if the {value} is a Smi or a HeapObject. |
| 2798 GotoIf(TaggedIsSmi(value), (primitive_type == PrimitiveType::kNumber) | 2791 GotoIf(TaggedIsSmi(value), (primitive_type == PrimitiveType::kNumber) |
| 2799 ? &done_loop | 2792 ? &done_loop |
| 2800 : &done_throw); | 2793 : &done_throw); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3018 return HasInstanceType(object, JS_FUNCTION_TYPE); | 3011 return HasInstanceType(object, JS_FUNCTION_TYPE); |
| 3019 } | 3012 } |
| 3020 | 3013 |
| 3021 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index, | 3014 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index, |
| 3022 ParameterMode parameter_mode) { | 3015 ParameterMode parameter_mode) { |
| 3023 CSA_ASSERT(this, IsString(string)); | 3016 CSA_ASSERT(this, IsString(string)); |
| 3024 // Translate the {index} into a Word. | 3017 // Translate the {index} into a Word. |
| 3025 index = ParameterToWord(index, parameter_mode); | 3018 index = ParameterToWord(index, parameter_mode); |
| 3026 | 3019 |
| 3027 // We may need to loop in case of cons, thin, or sliced strings. | 3020 // We may need to loop in case of cons, thin, or sliced strings. |
| 3028 Variable var_index(this, MachineType::PointerRepresentation()); | 3021 Variable var_index(this, MachineType::PointerRepresentation(), index); |
| 3022 Variable var_string(this, MachineRepresentation::kTagged, string); |
| 3029 Variable var_result(this, MachineRepresentation::kWord32); | 3023 Variable var_result(this, MachineRepresentation::kWord32); |
| 3030 Variable var_string(this, MachineRepresentation::kTagged); | |
| 3031 Variable* loop_vars[] = {&var_index, &var_string}; | 3024 Variable* loop_vars[] = {&var_index, &var_string}; |
| 3032 Label done_loop(this, &var_result), loop(this, 2, loop_vars); | 3025 Label done_loop(this, &var_result), loop(this, 2, loop_vars); |
| 3033 var_string.Bind(string); | |
| 3034 var_index.Bind(index); | |
| 3035 Goto(&loop); | 3026 Goto(&loop); |
| 3036 Bind(&loop); | 3027 Bind(&loop); |
| 3037 { | 3028 { |
| 3038 // Load the current {index}. | 3029 // Load the current {index}. |
| 3039 index = var_index.value(); | 3030 index = var_index.value(); |
| 3040 | 3031 |
| 3041 // Load the current {string}. | 3032 // Load the current {string}. |
| 3042 string = var_string.value(); | 3033 string = var_string.value(); |
| 3043 | 3034 |
| 3044 // Load the instance type of the {string}. | 3035 // Load the instance type of the {string}. |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3321 return var_result.value(); | 3312 return var_result.value(); |
| 3322 } | 3313 } |
| 3323 | 3314 |
| 3324 } // namespace | 3315 } // namespace |
| 3325 | 3316 |
| 3326 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, | 3317 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, |
| 3327 Node* to) { | 3318 Node* to) { |
| 3328 Label end(this); | 3319 Label end(this); |
| 3329 Label runtime(this); | 3320 Label runtime(this); |
| 3330 | 3321 |
| 3331 Variable var_instance_type(this, MachineRepresentation::kWord32); // Int32. | 3322 Node* const int_zero = Int32Constant(0); |
| 3332 Variable var_representation(this, MachineRepresentation::kWord32); // Int32. | |
| 3333 Variable var_result(this, MachineRepresentation::kTagged); // String. | |
| 3334 Variable var_from(this, MachineRepresentation::kTagged); // Smi. | |
| 3335 Variable var_string(this, MachineRepresentation::kTagged); // String. | |
| 3336 | 3323 |
| 3337 var_instance_type.Bind(Int32Constant(0)); | 3324 // Int32 variables. |
| 3338 var_representation.Bind(Int32Constant(0)); | 3325 Variable var_instance_type(this, MachineRepresentation::kWord32, int_zero); |
| 3339 var_string.Bind(string); | 3326 Variable var_representation(this, MachineRepresentation::kWord32, int_zero); |
| 3340 var_from.Bind(from); | 3327 |
| 3328 Variable var_from(this, MachineRepresentation::kTagged, from); // Smi. |
| 3329 Variable var_string(this, MachineRepresentation::kTagged, string); // String. |
| 3330 Variable var_result(this, MachineRepresentation::kTagged); // String. |
| 3341 | 3331 |
| 3342 // Make sure first argument is a string. | 3332 // Make sure first argument is a string. |
| 3343 | 3333 |
| 3344 // Bailout if receiver is a Smi. | 3334 // Bailout if receiver is a Smi. |
| 3345 GotoIf(TaggedIsSmi(string), &runtime); | 3335 GotoIf(TaggedIsSmi(string), &runtime); |
| 3346 | 3336 |
| 3347 // Load the instance type of the {string}. | 3337 // Load the instance type of the {string}. |
| 3348 Node* const instance_type = LoadInstanceType(string); | 3338 Node* const instance_type = LoadInstanceType(string); |
| 3349 var_instance_type.Bind(instance_type); | 3339 var_instance_type.Bind(instance_type); |
| 3350 | 3340 |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3590 Goto(&done); | 3580 Goto(&done); |
| 3591 | 3581 |
| 3592 Bind(&done); | 3582 Bind(&done); |
| 3593 } | 3583 } |
| 3594 | 3584 |
| 3595 void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left, | 3585 void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left, |
| 3596 Node* left_instance_type, | 3586 Node* left_instance_type, |
| 3597 Variable* var_right, | 3587 Variable* var_right, |
| 3598 Node* right_instance_type, | 3588 Node* right_instance_type, |
| 3599 Label* did_something) { | 3589 Label* did_something) { |
| 3600 Variable var_did_something(this, MachineType::PointerRepresentation()); | 3590 Variable var_did_something(this, MachineType::PointerRepresentation(), |
| 3601 var_did_something.Bind(IntPtrConstant(0)); | 3591 IntPtrConstant(0)); |
| 3602 MaybeDerefIndirectString(var_left, left_instance_type, &var_did_something); | 3592 MaybeDerefIndirectString(var_left, left_instance_type, &var_did_something); |
| 3603 MaybeDerefIndirectString(var_right, right_instance_type, &var_did_something); | 3593 MaybeDerefIndirectString(var_right, right_instance_type, &var_did_something); |
| 3604 | 3594 |
| 3605 GotoIf(WordNotEqual(var_did_something.value(), IntPtrConstant(0)), | 3595 GotoIf(WordNotEqual(var_did_something.value(), IntPtrConstant(0)), |
| 3606 did_something); | 3596 did_something); |
| 3607 // Fall through if neither string was an indirect string. | 3597 // Fall through if neither string was an indirect string. |
| 3608 } | 3598 } |
| 3609 | 3599 |
| 3610 Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right, | 3600 Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right, |
| 3611 AllocationFlags flags) { | 3601 AllocationFlags flags) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3629 Goto(&done_native); | 3619 Goto(&done_native); |
| 3630 | 3620 |
| 3631 Bind(&cons); | 3621 Bind(&cons); |
| 3632 { | 3622 { |
| 3633 CSA_ASSERT(this, TaggedIsSmi(left_length)); | 3623 CSA_ASSERT(this, TaggedIsSmi(left_length)); |
| 3634 CSA_ASSERT(this, TaggedIsSmi(right_length)); | 3624 CSA_ASSERT(this, TaggedIsSmi(right_length)); |
| 3635 Node* new_length = SmiAdd(left_length, right_length); | 3625 Node* new_length = SmiAdd(left_length, right_length); |
| 3636 GotoIf(SmiAboveOrEqual(new_length, SmiConstant(String::kMaxLength)), | 3626 GotoIf(SmiAboveOrEqual(new_length, SmiConstant(String::kMaxLength)), |
| 3637 &runtime); | 3627 &runtime); |
| 3638 | 3628 |
| 3639 Variable var_left(this, MachineRepresentation::kTagged); | 3629 Variable var_left(this, MachineRepresentation::kTagged, left); |
| 3640 Variable var_right(this, MachineRepresentation::kTagged); | 3630 Variable var_right(this, MachineRepresentation::kTagged, right); |
| 3641 Variable* input_vars[2] = {&var_left, &var_right}; | 3631 Variable* input_vars[2] = {&var_left, &var_right}; |
| 3642 Label non_cons(this, 2, input_vars); | 3632 Label non_cons(this, 2, input_vars); |
| 3643 Label slow(this, Label::kDeferred); | 3633 Label slow(this, Label::kDeferred); |
| 3644 var_left.Bind(left); | |
| 3645 var_right.Bind(right); | |
| 3646 GotoIf(SmiLessThan(new_length, SmiConstant(ConsString::kMinLength)), | 3634 GotoIf(SmiLessThan(new_length, SmiConstant(ConsString::kMinLength)), |
| 3647 &non_cons); | 3635 &non_cons); |
| 3648 | 3636 |
| 3649 result.Bind(NewConsString(context, new_length, var_left.value(), | 3637 result.Bind(NewConsString(context, new_length, var_left.value(), |
| 3650 var_right.value(), flags)); | 3638 var_right.value(), flags)); |
| 3651 Goto(&done_native); | 3639 Goto(&done_native); |
| 3652 | 3640 |
| 3653 Bind(&non_cons); | 3641 Bind(&non_cons); |
| 3654 | 3642 |
| 3655 Comment("Full string concatenate"); | 3643 Comment("Full string concatenate"); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3793 var_result.Bind(result); | 3781 var_result.Bind(result); |
| 3794 Goto(&out); | 3782 Goto(&out); |
| 3795 } | 3783 } |
| 3796 | 3784 |
| 3797 Bind(&out); | 3785 Bind(&out); |
| 3798 return var_result.value(); | 3786 return var_result.value(); |
| 3799 } | 3787 } |
| 3800 | 3788 |
| 3801 Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint, | 3789 Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint, |
| 3802 UnicodeEncoding encoding) { | 3790 UnicodeEncoding encoding) { |
| 3803 Variable var_result(this, MachineRepresentation::kTagged); | 3791 Variable var_result(this, MachineRepresentation::kTagged, |
| 3804 var_result.Bind(EmptyStringConstant()); | 3792 EmptyStringConstant()); |
| 3805 | 3793 |
| 3806 Label if_isword16(this), if_isword32(this), return_result(this); | 3794 Label if_isword16(this), if_isword32(this), return_result(this); |
| 3807 | 3795 |
| 3808 Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, | 3796 Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, |
| 3809 &if_isword32); | 3797 &if_isword32); |
| 3810 | 3798 |
| 3811 Bind(&if_isword16); | 3799 Bind(&if_isword16); |
| 3812 { | 3800 { |
| 3813 var_result.Bind(StringFromCharCode(codepoint)); | 3801 var_result.Bind(StringFromCharCode(codepoint)); |
| 3814 Goto(&return_result); | 3802 Goto(&return_result); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4000 Bind(&end); | 3988 Bind(&end); |
| 4001 return var_result.value(); | 3989 return var_result.value(); |
| 4002 } | 3990 } |
| 4003 | 3991 |
| 4004 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { | 3992 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { |
| 4005 // Assert input is a HeapObject (not smi or heap number) | 3993 // Assert input is a HeapObject (not smi or heap number) |
| 4006 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(input))); | 3994 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(input))); |
| 4007 CSA_ASSERT(this, Word32BinaryNot(IsHeapNumberMap(LoadMap(input)))); | 3995 CSA_ASSERT(this, Word32BinaryNot(IsHeapNumberMap(LoadMap(input)))); |
| 4008 | 3996 |
| 4009 // We might need to loop once here due to ToPrimitive conversions. | 3997 // We might need to loop once here due to ToPrimitive conversions. |
| 4010 Variable var_input(this, MachineRepresentation::kTagged); | 3998 Variable var_input(this, MachineRepresentation::kTagged, input); |
| 4011 Variable var_result(this, MachineRepresentation::kTagged); | 3999 Variable var_result(this, MachineRepresentation::kTagged); |
| 4012 Label loop(this, &var_input); | 4000 Label loop(this, &var_input); |
| 4013 Label end(this); | 4001 Label end(this); |
| 4014 var_input.Bind(input); | |
| 4015 Goto(&loop); | 4002 Goto(&loop); |
| 4016 Bind(&loop); | 4003 Bind(&loop); |
| 4017 { | 4004 { |
| 4018 // Load the current {input} value (known to be a HeapObject). | 4005 // Load the current {input} value (known to be a HeapObject). |
| 4019 Node* input = var_input.value(); | 4006 Node* input = var_input.value(); |
| 4020 | 4007 |
| 4021 // Dispatch on the {input} instance type. | 4008 // Dispatch on the {input} instance type. |
| 4022 Node* input_instance_type = LoadInstanceType(input); | 4009 Node* input_instance_type = LoadInstanceType(input); |
| 4023 Label if_inputisstring(this), if_inputisoddball(this), | 4010 Label if_inputisstring(this), if_inputisoddball(this), |
| 4024 if_inputisreceiver(this, Label::kDeferred), | 4011 if_inputisreceiver(this, Label::kDeferred), |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4118 Bind(&end); | 4105 Bind(&end); |
| 4119 return var_result.value(); | 4106 return var_result.value(); |
| 4120 } | 4107 } |
| 4121 | 4108 |
| 4122 Node* CodeStubAssembler::ToUint32(Node* context, Node* input) { | 4109 Node* CodeStubAssembler::ToUint32(Node* context, Node* input) { |
| 4123 Node* const float_zero = Float64Constant(0.0); | 4110 Node* const float_zero = Float64Constant(0.0); |
| 4124 Node* const float_two_32 = Float64Constant(static_cast<double>(1ULL << 32)); | 4111 Node* const float_two_32 = Float64Constant(static_cast<double>(1ULL << 32)); |
| 4125 | 4112 |
| 4126 Label out(this); | 4113 Label out(this); |
| 4127 | 4114 |
| 4128 Variable var_result(this, MachineRepresentation::kTagged); | 4115 Variable var_result(this, MachineRepresentation::kTagged, input); |
| 4129 var_result.Bind(input); | |
| 4130 | 4116 |
| 4131 // Early exit for positive smis. | 4117 // Early exit for positive smis. |
| 4132 { | 4118 { |
| 4133 // TODO(jgruber): This branch and the recheck below can be removed once we | 4119 // TODO(jgruber): This branch and the recheck below can be removed once we |
| 4134 // have a ToNumber with multiple exits. | 4120 // have a ToNumber with multiple exits. |
| 4135 Label next(this, Label::kDeferred); | 4121 Label next(this, Label::kDeferred); |
| 4136 Branch(TaggedIsPositiveSmi(input), &out, &next); | 4122 Branch(TaggedIsPositiveSmi(input), &out, &next); |
| 4137 Bind(&next); | 4123 Bind(&next); |
| 4138 } | 4124 } |
| 4139 | 4125 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4281 Goto(&done); | 4267 Goto(&done); |
| 4282 } | 4268 } |
| 4283 | 4269 |
| 4284 Bind(&done); | 4270 Bind(&done); |
| 4285 return result.value(); | 4271 return result.value(); |
| 4286 } | 4272 } |
| 4287 | 4273 |
| 4288 Node* CodeStubAssembler::ToInteger(Node* context, Node* input, | 4274 Node* CodeStubAssembler::ToInteger(Node* context, Node* input, |
| 4289 ToIntegerTruncationMode mode) { | 4275 ToIntegerTruncationMode mode) { |
| 4290 // We might need to loop once for ToNumber conversion. | 4276 // We might need to loop once for ToNumber conversion. |
| 4291 Variable var_arg(this, MachineRepresentation::kTagged); | 4277 Variable var_arg(this, MachineRepresentation::kTagged, input); |
| 4292 Label loop(this, &var_arg), out(this); | 4278 Label loop(this, &var_arg), out(this); |
| 4293 var_arg.Bind(input); | |
| 4294 Goto(&loop); | 4279 Goto(&loop); |
| 4295 Bind(&loop); | 4280 Bind(&loop); |
| 4296 { | 4281 { |
| 4297 // Shared entry points. | 4282 // Shared entry points. |
| 4298 Label return_zero(this, Label::kDeferred); | 4283 Label return_zero(this, Label::kDeferred); |
| 4299 | 4284 |
| 4300 // Load the current {arg} value. | 4285 // Load the current {arg} value. |
| 4301 Node* arg = var_arg.value(); | 4286 Node* arg = var_arg.value(); |
| 4302 | 4287 |
| 4303 // Check if {arg} is a Smi. | 4288 // Check if {arg} is a Smi. |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4549 entry = WordAnd(IntPtrAdd(entry, count), mask); | 4534 entry = WordAnd(IntPtrAdd(entry, count), mask); |
| 4550 } | 4535 } |
| 4551 if (mode == kFindInsertionIndex) { | 4536 if (mode == kFindInsertionIndex) { |
| 4552 // Appease the variable merging algorithm for "Goto(&loop)" below. | 4537 // Appease the variable merging algorithm for "Goto(&loop)" below. |
| 4553 var_name_index->Bind(IntPtrConstant(0)); | 4538 var_name_index->Bind(IntPtrConstant(0)); |
| 4554 } | 4539 } |
| 4555 | 4540 |
| 4556 Node* undefined = UndefinedConstant(); | 4541 Node* undefined = UndefinedConstant(); |
| 4557 Node* the_hole = mode == kFindExisting ? nullptr : TheHoleConstant(); | 4542 Node* the_hole = mode == kFindExisting ? nullptr : TheHoleConstant(); |
| 4558 | 4543 |
| 4559 Variable var_count(this, MachineType::PointerRepresentation()); | 4544 Variable var_count(this, MachineType::PointerRepresentation(), count); |
| 4560 Variable var_entry(this, MachineType::PointerRepresentation()); | 4545 Variable var_entry(this, MachineType::PointerRepresentation(), entry); |
| 4561 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; | 4546 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index}; |
| 4562 Label loop(this, 3, loop_vars); | 4547 Label loop(this, 3, loop_vars); |
| 4563 var_count.Bind(count); | |
| 4564 var_entry.Bind(entry); | |
| 4565 Goto(&loop); | 4548 Goto(&loop); |
| 4566 Bind(&loop); | 4549 Bind(&loop); |
| 4567 { | 4550 { |
| 4568 Node* entry = var_entry.value(); | 4551 Node* entry = var_entry.value(); |
| 4569 | 4552 |
| 4570 Node* index = EntryToIndex<Dictionary>(entry); | 4553 Node* index = EntryToIndex<Dictionary>(entry); |
| 4571 var_name_index->Bind(index); | 4554 var_name_index->Bind(index); |
| 4572 | 4555 |
| 4573 Node* current = LoadFixedArrayElement(dictionary, index); | 4556 Node* current = LoadFixedArrayElement(dictionary, index); |
| 4574 GotoIf(WordEqual(current, undefined), if_not_found); | 4557 GotoIf(WordEqual(current, undefined), if_not_found); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4630 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); | 4613 Node* hash = ChangeUint32ToWord(ComputeIntegerHash(intptr_index, int32_seed)); |
| 4631 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); | 4614 Node* key_as_float64 = RoundIntPtrToFloat64(intptr_index); |
| 4632 | 4615 |
| 4633 // See Dictionary::FirstProbe(). | 4616 // See Dictionary::FirstProbe(). |
| 4634 Node* count = IntPtrConstant(0); | 4617 Node* count = IntPtrConstant(0); |
| 4635 Node* entry = WordAnd(hash, mask); | 4618 Node* entry = WordAnd(hash, mask); |
| 4636 | 4619 |
| 4637 Node* undefined = UndefinedConstant(); | 4620 Node* undefined = UndefinedConstant(); |
| 4638 Node* the_hole = TheHoleConstant(); | 4621 Node* the_hole = TheHoleConstant(); |
| 4639 | 4622 |
| 4640 Variable var_count(this, MachineType::PointerRepresentation()); | 4623 Variable var_count(this, MachineType::PointerRepresentation(), count); |
| 4641 Variable* loop_vars[] = {&var_count, var_entry}; | 4624 Variable* loop_vars[] = {&var_count, var_entry}; |
| 4642 Label loop(this, 2, loop_vars); | 4625 Label loop(this, 2, loop_vars); |
| 4643 var_count.Bind(count); | |
| 4644 var_entry->Bind(entry); | 4626 var_entry->Bind(entry); |
| 4645 Goto(&loop); | 4627 Goto(&loop); |
| 4646 Bind(&loop); | 4628 Bind(&loop); |
| 4647 { | 4629 { |
| 4648 Node* entry = var_entry->value(); | 4630 Node* entry = var_entry->value(); |
| 4649 | 4631 |
| 4650 Node* index = EntryToIndex<Dictionary>(entry); | 4632 Node* index = EntryToIndex<Dictionary>(entry); |
| 4651 Node* current = LoadFixedArrayElement(dictionary, index); | 4633 Node* current = LoadFixedArrayElement(dictionary, index); |
| 4652 GotoIf(WordEqual(current, undefined), if_not_found); | 4634 GotoIf(WordEqual(current, undefined), if_not_found); |
| 4653 Label next_probe(this); | 4635 Label next_probe(this); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4707 Node* enum_index) { | 4689 Node* enum_index) { |
| 4708 // Store name and value. | 4690 // Store name and value. |
| 4709 StoreFixedArrayElement(dictionary, index, name); | 4691 StoreFixedArrayElement(dictionary, index, name); |
| 4710 const int kNameToValueOffset = | 4692 const int kNameToValueOffset = |
| 4711 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * | 4693 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * |
| 4712 kPointerSize; | 4694 kPointerSize; |
| 4713 StoreFixedArrayElement(dictionary, index, value, UPDATE_WRITE_BARRIER, | 4695 StoreFixedArrayElement(dictionary, index, value, UPDATE_WRITE_BARRIER, |
| 4714 kNameToValueOffset); | 4696 kNameToValueOffset); |
| 4715 | 4697 |
| 4716 // Prepare details of the new property. | 4698 // Prepare details of the new property. |
| 4717 Variable var_details(this, MachineRepresentation::kTaggedSigned); | |
| 4718 const int kInitialIndex = 0; | 4699 const int kInitialIndex = 0; |
| 4719 PropertyDetails d(kData, NONE, kInitialIndex, PropertyCellType::kNoCell); | 4700 PropertyDetails d(kData, NONE, kInitialIndex, PropertyCellType::kNoCell); |
| 4720 enum_index = | 4701 enum_index = |
| 4721 SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); | 4702 SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); |
| 4722 STATIC_ASSERT(kInitialIndex == 0); | 4703 STATIC_ASSERT(kInitialIndex == 0); |
| 4723 var_details.Bind(SmiOr(SmiConstant(d.AsSmi()), enum_index)); | 4704 Variable var_details(this, MachineRepresentation::kTaggedSigned, |
| 4705 SmiOr(SmiConstant(d.AsSmi()), enum_index)); |
| 4724 | 4706 |
| 4725 // Private names must be marked non-enumerable. | 4707 // Private names must be marked non-enumerable. |
| 4726 Label not_private(this, &var_details); | 4708 Label not_private(this, &var_details); |
| 4727 GotoUnless(IsSymbolMap(LoadMap(name)), ¬_private); | 4709 GotoUnless(IsSymbolMap(LoadMap(name)), ¬_private); |
| 4728 Node* flags = SmiToWord32(LoadObjectField(name, Symbol::kFlagsOffset)); | 4710 Node* flags = SmiToWord32(LoadObjectField(name, Symbol::kFlagsOffset)); |
| 4729 const int kPrivateMask = 1 << Symbol::kPrivateBit; | 4711 const int kPrivateMask = 1 << Symbol::kPrivateBit; |
| 4730 GotoUnless(IsSetWord32(flags, kPrivateMask), ¬_private); | 4712 GotoUnless(IsSetWord32(flags, kPrivateMask), ¬_private); |
| 4731 Node* dont_enum = | 4713 Node* dont_enum = |
| 4732 SmiShl(SmiConstant(DONT_ENUM), PropertyDetails::AttributesField::kShift); | 4714 SmiShl(SmiConstant(DONT_ENUM), PropertyDetails::AttributesField::kShift); |
| 4733 var_details.Bind(SmiOr(var_details.value(), dont_enum)); | 4715 var_details.Bind(SmiOr(var_details.value(), dont_enum)); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5066 | 5048 |
| 5067 Comment("] LoadPropertyFromGlobalDictionary"); | 5049 Comment("] LoadPropertyFromGlobalDictionary"); |
| 5068 } | 5050 } |
| 5069 | 5051 |
| 5070 // |value| is the property backing store's contents, which is either a value | 5052 // |value| is the property backing store's contents, which is either a value |
| 5071 // or an accessor pair, as specified by |details|. | 5053 // or an accessor pair, as specified by |details|. |
| 5072 // Returns either the original value, or the result of the getter call. | 5054 // Returns either the original value, or the result of the getter call. |
| 5073 Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details, | 5055 Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details, |
| 5074 Node* context, Node* receiver, | 5056 Node* context, Node* receiver, |
| 5075 Label* if_bailout) { | 5057 Label* if_bailout) { |
| 5076 Variable var_value(this, MachineRepresentation::kTagged); | 5058 Variable var_value(this, MachineRepresentation::kTagged, value); |
| 5077 var_value.Bind(value); | |
| 5078 Label done(this); | 5059 Label done(this); |
| 5079 | 5060 |
| 5080 Node* kind = DecodeWord32<PropertyDetails::KindField>(details); | 5061 Node* kind = DecodeWord32<PropertyDetails::KindField>(details); |
| 5081 GotoIf(Word32Equal(kind, Int32Constant(kData)), &done); | 5062 GotoIf(Word32Equal(kind, Int32Constant(kData)), &done); |
| 5082 | 5063 |
| 5083 // Accessor case. | 5064 // Accessor case. |
| 5084 { | 5065 { |
| 5085 Node* accessor_pair = value; | 5066 Node* accessor_pair = value; |
| 5086 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), | 5067 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), |
| 5087 Int32Constant(ACCESSOR_INFO_TYPE)), | 5068 Int32Constant(ACCESSOR_INFO_TYPE)), |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5297 | 5278 |
| 5298 Variable var_index(this, MachineType::PointerRepresentation()); | 5279 Variable var_index(this, MachineType::PointerRepresentation()); |
| 5299 Variable var_unique(this, MachineRepresentation::kTagged); | 5280 Variable var_unique(this, MachineRepresentation::kTagged); |
| 5300 | 5281 |
| 5301 Label if_keyisindex(this), if_iskeyunique(this); | 5282 Label if_keyisindex(this), if_iskeyunique(this); |
| 5302 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique, | 5283 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique, |
| 5303 if_bailout); | 5284 if_bailout); |
| 5304 | 5285 |
| 5305 Bind(&if_iskeyunique); | 5286 Bind(&if_iskeyunique); |
| 5306 { | 5287 { |
| 5307 Variable var_holder(this, MachineRepresentation::kTagged); | 5288 Variable var_holder(this, MachineRepresentation::kTagged, receiver); |
| 5308 Variable var_holder_map(this, MachineRepresentation::kTagged); | 5289 Variable var_holder_map(this, MachineRepresentation::kTagged, map); |
| 5309 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); | 5290 Variable var_holder_instance_type(this, MachineRepresentation::kWord32, |
| 5291 instance_type); |
| 5310 | 5292 |
| 5311 Variable* merged_variables[] = {&var_holder, &var_holder_map, | 5293 Variable* merged_variables[] = {&var_holder, &var_holder_map, |
| 5312 &var_holder_instance_type}; | 5294 &var_holder_instance_type}; |
| 5313 Label loop(this, arraysize(merged_variables), merged_variables); | 5295 Label loop(this, arraysize(merged_variables), merged_variables); |
| 5314 var_holder.Bind(receiver); | |
| 5315 var_holder_map.Bind(map); | |
| 5316 var_holder_instance_type.Bind(instance_type); | |
| 5317 Goto(&loop); | 5296 Goto(&loop); |
| 5318 Bind(&loop); | 5297 Bind(&loop); |
| 5319 { | 5298 { |
| 5320 Node* holder_map = var_holder_map.value(); | 5299 Node* holder_map = var_holder_map.value(); |
| 5321 Node* holder_instance_type = var_holder_instance_type.value(); | 5300 Node* holder_instance_type = var_holder_instance_type.value(); |
| 5322 | 5301 |
| 5323 Label next_proto(this); | 5302 Label next_proto(this); |
| 5324 lookup_property_in_holder(receiver, var_holder.value(), holder_map, | 5303 lookup_property_in_holder(receiver, var_holder.value(), holder_map, |
| 5325 holder_instance_type, var_unique.value(), | 5304 holder_instance_type, var_unique.value(), |
| 5326 &next_proto, if_bailout); | 5305 &next_proto, if_bailout); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5341 Node* instance_type = LoadMapInstanceType(map); | 5320 Node* instance_type = LoadMapInstanceType(map); |
| 5342 | 5321 |
| 5343 var_holder.Bind(proto); | 5322 var_holder.Bind(proto); |
| 5344 var_holder_map.Bind(map); | 5323 var_holder_map.Bind(map); |
| 5345 var_holder_instance_type.Bind(instance_type); | 5324 var_holder_instance_type.Bind(instance_type); |
| 5346 Goto(&loop); | 5325 Goto(&loop); |
| 5347 } | 5326 } |
| 5348 } | 5327 } |
| 5349 Bind(&if_keyisindex); | 5328 Bind(&if_keyisindex); |
| 5350 { | 5329 { |
| 5351 Variable var_holder(this, MachineRepresentation::kTagged); | 5330 Variable var_holder(this, MachineRepresentation::kTagged, receiver); |
| 5352 Variable var_holder_map(this, MachineRepresentation::kTagged); | 5331 Variable var_holder_map(this, MachineRepresentation::kTagged, map); |
| 5353 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); | 5332 Variable var_holder_instance_type(this, MachineRepresentation::kWord32, |
| 5333 instance_type); |
| 5354 | 5334 |
| 5355 Variable* merged_variables[] = {&var_holder, &var_holder_map, | 5335 Variable* merged_variables[] = {&var_holder, &var_holder_map, |
| 5356 &var_holder_instance_type}; | 5336 &var_holder_instance_type}; |
| 5357 Label loop(this, arraysize(merged_variables), merged_variables); | 5337 Label loop(this, arraysize(merged_variables), merged_variables); |
| 5358 var_holder.Bind(receiver); | |
| 5359 var_holder_map.Bind(map); | |
| 5360 var_holder_instance_type.Bind(instance_type); | |
| 5361 Goto(&loop); | 5338 Goto(&loop); |
| 5362 Bind(&loop); | 5339 Bind(&loop); |
| 5363 { | 5340 { |
| 5364 Label next_proto(this); | 5341 Label next_proto(this); |
| 5365 lookup_element_in_holder(receiver, var_holder.value(), | 5342 lookup_element_in_holder(receiver, var_holder.value(), |
| 5366 var_holder_map.value(), | 5343 var_holder_map.value(), |
| 5367 var_holder_instance_type.value(), | 5344 var_holder_instance_type.value(), |
| 5368 var_index.value(), &next_proto, if_bailout); | 5345 var_index.value(), &next_proto, if_bailout); |
| 5369 Bind(&next_proto); | 5346 Bind(&next_proto); |
| 5370 | 5347 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5433 Word32Equal(Word32And(callable_bitfield, | 5410 Word32Equal(Word32And(callable_bitfield, |
| 5434 Int32Constant((1 << Map::kHasNonInstancePrototype) | | 5411 Int32Constant((1 << Map::kHasNonInstancePrototype) | |
| 5435 (1 << Map::kIsConstructor))), | 5412 (1 << Map::kIsConstructor))), |
| 5436 Int32Constant(1 << Map::kIsConstructor)), | 5413 Int32Constant(1 << Map::kIsConstructor)), |
| 5437 &return_runtime); | 5414 &return_runtime); |
| 5438 | 5415 |
| 5439 // Get the "prototype" (or initial map) of the {callable}. | 5416 // Get the "prototype" (or initial map) of the {callable}. |
| 5440 Node* callable_prototype = | 5417 Node* callable_prototype = |
| 5441 LoadObjectField(callable, JSFunction::kPrototypeOrInitialMapOffset); | 5418 LoadObjectField(callable, JSFunction::kPrototypeOrInitialMapOffset); |
| 5442 { | 5419 { |
| 5443 Variable var_callable_prototype(this, MachineRepresentation::kTagged); | |
| 5444 Label callable_prototype_valid(this); | 5420 Label callable_prototype_valid(this); |
| 5445 var_callable_prototype.Bind(callable_prototype); | 5421 Variable var_callable_prototype(this, MachineRepresentation::kTagged, |
| 5422 callable_prototype); |
| 5446 | 5423 |
| 5447 // Resolve the "prototype" if the {callable} has an initial map. Afterwards | 5424 // Resolve the "prototype" if the {callable} has an initial map. Afterwards |
| 5448 // the {callable_prototype} will be either the JSReceiver prototype object | 5425 // the {callable_prototype} will be either the JSReceiver prototype object |
| 5449 // or the hole value, which means that no instances of the {callable} were | 5426 // or the hole value, which means that no instances of the {callable} were |
| 5450 // created so far and hence we should return false. | 5427 // created so far and hence we should return false. |
| 5451 Node* callable_prototype_instance_type = | 5428 Node* callable_prototype_instance_type = |
| 5452 LoadInstanceType(callable_prototype); | 5429 LoadInstanceType(callable_prototype); |
| 5453 GotoUnless( | 5430 GotoUnless( |
| 5454 Word32Equal(callable_prototype_instance_type, Int32Constant(MAP_TYPE)), | 5431 Word32Equal(callable_prototype_instance_type, Int32Constant(MAP_TYPE)), |
| 5455 &callable_prototype_valid); | 5432 &callable_prototype_valid); |
| 5456 var_callable_prototype.Bind( | 5433 var_callable_prototype.Bind( |
| 5457 LoadObjectField(callable_prototype, Map::kPrototypeOffset)); | 5434 LoadObjectField(callable_prototype, Map::kPrototypeOffset)); |
| 5458 Goto(&callable_prototype_valid); | 5435 Goto(&callable_prototype_valid); |
| 5459 Bind(&callable_prototype_valid); | 5436 Bind(&callable_prototype_valid); |
| 5460 callable_prototype = var_callable_prototype.value(); | 5437 callable_prototype = var_callable_prototype.value(); |
| 5461 } | 5438 } |
| 5462 | 5439 |
| 5463 // Update the global instanceof cache with the current {object} map and | 5440 // Update the global instanceof cache with the current {object} map and |
| 5464 // {callable}. The cached answer will be set when it is known below. | 5441 // {callable}. The cached answer will be set when it is known below. |
| 5465 StoreRoot(Heap::kInstanceofCacheFunctionRootIndex, callable); | 5442 StoreRoot(Heap::kInstanceofCacheFunctionRootIndex, callable); |
| 5466 StoreRoot(Heap::kInstanceofCacheMapRootIndex, object_map); | 5443 StoreRoot(Heap::kInstanceofCacheMapRootIndex, object_map); |
| 5467 | 5444 |
| 5468 // Loop through the prototype chain looking for the {callable} prototype. | 5445 // Loop through the prototype chain looking for the {callable} prototype. |
| 5469 Variable var_object_map(this, MachineRepresentation::kTagged); | 5446 Variable var_object_map(this, MachineRepresentation::kTagged, object_map); |
| 5470 var_object_map.Bind(object_map); | |
| 5471 Label loop(this, &var_object_map); | 5447 Label loop(this, &var_object_map); |
| 5472 Goto(&loop); | 5448 Goto(&loop); |
| 5473 Bind(&loop); | 5449 Bind(&loop); |
| 5474 { | 5450 { |
| 5475 Node* object_map = var_object_map.value(); | 5451 Node* object_map = var_object_map.value(); |
| 5476 | 5452 |
| 5477 // Check if the current {object} needs to be access checked. | 5453 // Check if the current {object} needs to be access checked. |
| 5478 Node* object_bitfield = LoadMapBitField(object_map); | 5454 Node* object_bitfield = LoadMapBitField(object_map); |
| 5479 GotoUnless( | 5455 GotoUnless( |
| 5480 Word32Equal(Word32And(object_bitfield, | 5456 Word32Equal(Word32And(object_bitfield, |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5773 StoreFixedDoubleArrayElement(elements, index, value, mode); | 5749 StoreFixedDoubleArrayElement(elements, index, value, mode); |
| 5774 } else { | 5750 } else { |
| 5775 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode); | 5751 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode); |
| 5776 } | 5752 } |
| 5777 } | 5753 } |
| 5778 | 5754 |
| 5779 Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) { | 5755 Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) { |
| 5780 Label done(this); | 5756 Label done(this); |
| 5781 Node* int32_zero = Int32Constant(0); | 5757 Node* int32_zero = Int32Constant(0); |
| 5782 Node* int32_255 = Int32Constant(255); | 5758 Node* int32_255 = Int32Constant(255); |
| 5783 Variable var_value(this, MachineRepresentation::kWord32); | 5759 Variable var_value(this, MachineRepresentation::kWord32, int32_value); |
| 5784 var_value.Bind(int32_value); | |
| 5785 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done); | 5760 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done); |
| 5786 var_value.Bind(int32_zero); | 5761 var_value.Bind(int32_zero); |
| 5787 GotoIf(Int32LessThan(int32_value, int32_zero), &done); | 5762 GotoIf(Int32LessThan(int32_value, int32_zero), &done); |
| 5788 var_value.Bind(int32_255); | 5763 var_value.Bind(int32_255); |
| 5789 Goto(&done); | 5764 Goto(&done); |
| 5790 Bind(&done); | 5765 Bind(&done); |
| 5791 return var_value.value(); | 5766 return var_value.value(); |
| 5792 } | 5767 } |
| 5793 | 5768 |
| 5794 Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) { | 5769 Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) { |
| 5795 Label done(this); | 5770 Label done(this); |
| 5796 Variable var_value(this, MachineRepresentation::kWord32); | 5771 Variable var_value(this, MachineRepresentation::kWord32, Int32Constant(0)); |
| 5797 var_value.Bind(Int32Constant(0)); | |
| 5798 GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done); | 5772 GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done); |
| 5799 var_value.Bind(Int32Constant(255)); | 5773 var_value.Bind(Int32Constant(255)); |
| 5800 GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done); | 5774 GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done); |
| 5801 { | 5775 { |
| 5802 Node* rounded_value = Float64RoundToEven(float64_value); | 5776 Node* rounded_value = Float64RoundToEven(float64_value); |
| 5803 var_value.Bind(TruncateFloat64ToWord32(rounded_value)); | 5777 var_value.Bind(TruncateFloat64ToWord32(rounded_value)); |
| 5804 Goto(&done); | 5778 Goto(&done); |
| 5805 } | 5779 } |
| 5806 Bind(&done); | 5780 Bind(&done); |
| 5807 return var_value.value(); | 5781 return var_value.value(); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6017 } | 5991 } |
| 6018 | 5992 |
| 6019 Bind(&done); | 5993 Bind(&done); |
| 6020 return checked_elements.value(); | 5994 return checked_elements.value(); |
| 6021 } | 5995 } |
| 6022 | 5996 |
| 6023 Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements, | 5997 Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements, |
| 6024 ElementsKind kind, Node* length, | 5998 ElementsKind kind, Node* length, |
| 6025 ParameterMode mode, | 5999 ParameterMode mode, |
| 6026 Label* bailout) { | 6000 Label* bailout) { |
| 6027 Variable new_elements_var(this, MachineRepresentation::kTagged); | 6001 Variable new_elements_var(this, MachineRepresentation::kTagged, elements); |
| 6028 Label done(this); | 6002 Label done(this); |
| 6029 | 6003 |
| 6030 new_elements_var.Bind(elements); | |
| 6031 GotoUnless( | 6004 GotoUnless( |
| 6032 WordEqual(LoadMap(elements), LoadRoot(Heap::kFixedCOWArrayMapRootIndex)), | 6005 WordEqual(LoadMap(elements), LoadRoot(Heap::kFixedCOWArrayMapRootIndex)), |
| 6033 &done); | 6006 &done); |
| 6034 { | 6007 { |
| 6035 Node* capacity = | 6008 Node* capacity = |
| 6036 TaggedToParameter(LoadFixedArrayBaseLength(elements), mode); | 6009 TaggedToParameter(LoadFixedArrayBaseLength(elements), mode); |
| 6037 Node* new_elements = GrowElementsCapacity(object, elements, kind, kind, | 6010 Node* new_elements = GrowElementsCapacity(object, elements, kind, kind, |
| 6038 length, capacity, mode, bailout); | 6011 length, capacity, mode, bailout); |
| 6039 | 6012 |
| 6040 new_elements_var.Bind(new_elements); | 6013 new_elements_var.Bind(new_elements); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6149 | 6122 |
| 6150 Node* CodeStubAssembler::EnumLength(Node* map) { | 6123 Node* CodeStubAssembler::EnumLength(Node* map) { |
| 6151 CSA_ASSERT(this, IsMap(map)); | 6124 CSA_ASSERT(this, IsMap(map)); |
| 6152 Node* bitfield_3 = LoadMapBitField3(map); | 6125 Node* bitfield_3 = LoadMapBitField3(map); |
| 6153 Node* enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(bitfield_3); | 6126 Node* enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(bitfield_3); |
| 6154 return SmiTag(enum_length); | 6127 return SmiTag(enum_length); |
| 6155 } | 6128 } |
| 6156 | 6129 |
| 6157 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, | 6130 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, |
| 6158 Label* use_runtime) { | 6131 Label* use_runtime) { |
| 6159 Variable current_js_object(this, MachineRepresentation::kTagged); | 6132 Variable current_js_object(this, MachineRepresentation::kTagged, receiver); |
| 6160 current_js_object.Bind(receiver); | |
| 6161 | 6133 |
| 6162 Variable current_map(this, MachineRepresentation::kTagged); | 6134 Variable current_map(this, MachineRepresentation::kTagged, |
| 6163 current_map.Bind(LoadMap(current_js_object.value())); | 6135 LoadMap(current_js_object.value())); |
| 6164 | 6136 |
| 6165 // These variables are updated in the loop below. | 6137 // These variables are updated in the loop below. |
| 6166 Variable* loop_vars[2] = {¤t_js_object, ¤t_map}; | 6138 Variable* loop_vars[2] = {¤t_js_object, ¤t_map}; |
| 6167 Label loop(this, 2, loop_vars), next(this); | 6139 Label loop(this, 2, loop_vars), next(this); |
| 6168 | 6140 |
| 6169 // Check if the enum length field is properly initialized, indicating that | 6141 // Check if the enum length field is properly initialized, indicating that |
| 6170 // there is an enum cache. | 6142 // there is an enum cache. |
| 6171 { | 6143 { |
| 6172 Node* invalid_enum_cache_sentinel = | 6144 Node* invalid_enum_cache_sentinel = |
| 6173 SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel)); | 6145 SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel)); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6275 // Store the WeakCell in the feedback vector. | 6247 // Store the WeakCell in the feedback vector. |
| 6276 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 0, | 6248 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 0, |
| 6277 CodeStubAssembler::SMI_PARAMETERS); | 6249 CodeStubAssembler::SMI_PARAMETERS); |
| 6278 return cell; | 6250 return cell; |
| 6279 } | 6251 } |
| 6280 | 6252 |
| 6281 void CodeStubAssembler::BuildFastLoop( | 6253 void CodeStubAssembler::BuildFastLoop( |
| 6282 const CodeStubAssembler::VariableList& vars, | 6254 const CodeStubAssembler::VariableList& vars, |
| 6283 MachineRepresentation index_rep, Node* start_index, Node* end_index, | 6255 MachineRepresentation index_rep, Node* start_index, Node* end_index, |
| 6284 const FastLoopBody& body, int increment, IndexAdvanceMode mode) { | 6256 const FastLoopBody& body, int increment, IndexAdvanceMode mode) { |
| 6285 Variable var(this, index_rep); | 6257 Variable var(this, index_rep, start_index); |
| 6286 VariableList vars_copy(vars, zone()); | 6258 VariableList vars_copy(vars, zone()); |
| 6287 vars_copy.Add(&var, zone()); | 6259 vars_copy.Add(&var, zone()); |
| 6288 var.Bind(start_index); | |
| 6289 Label loop(this, vars_copy); | 6260 Label loop(this, vars_copy); |
| 6290 Label after_loop(this); | 6261 Label after_loop(this); |
| 6291 // Introduce an explicit second check of the termination condition before the | 6262 // Introduce an explicit second check of the termination condition before the |
| 6292 // loop that helps turbofan generate better code. If there's only a single | 6263 // loop that helps turbofan generate better code. If there's only a single |
| 6293 // check, then the CodeStubAssembler forces it to be at the beginning of the | 6264 // check, then the CodeStubAssembler forces it to be at the beginning of the |
| 6294 // loop requiring a backwards branch at the end of the loop (it's not possible | 6265 // loop requiring a backwards branch at the end of the loop (it's not possible |
| 6295 // to force the loop header check at the end of the loop and branch forward to | 6266 // to force the loop header check at the end of the loop and branch forward to |
| 6296 // it from the pre-header). The extra branch is slower in the case that the | 6267 // it from the pre-header). The extra branch is slower in the case that the |
| 6297 // loop actually iterates. | 6268 // loop actually iterates. |
| 6298 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); | 6269 Branch(WordEqual(var.value(), end_index), &after_loop, &loop); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6492 Label return_true(this), return_false(this), end(this); | 6463 Label return_true(this), return_false(this), end(this); |
| 6493 Variable result(this, MachineRepresentation::kTagged); | 6464 Variable result(this, MachineRepresentation::kTagged); |
| 6494 | 6465 |
| 6495 // Shared entry for floating point comparison. | 6466 // Shared entry for floating point comparison. |
| 6496 Label do_fcmp(this); | 6467 Label do_fcmp(this); |
| 6497 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), | 6468 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), |
| 6498 var_fcmp_rhs(this, MachineRepresentation::kFloat64); | 6469 var_fcmp_rhs(this, MachineRepresentation::kFloat64); |
| 6499 | 6470 |
| 6500 // We might need to loop several times due to ToPrimitive and/or ToNumber | 6471 // We might need to loop several times due to ToPrimitive and/or ToNumber |
| 6501 // conversions. | 6472 // conversions. |
| 6502 Variable var_lhs(this, MachineRepresentation::kTagged), | 6473 Variable var_lhs(this, MachineRepresentation::kTagged, lhs), |
| 6503 var_rhs(this, MachineRepresentation::kTagged); | 6474 var_rhs(this, MachineRepresentation::kTagged, rhs); |
| 6504 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; | 6475 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; |
| 6505 Label loop(this, 2, loop_vars); | 6476 Label loop(this, 2, loop_vars); |
| 6506 var_lhs.Bind(lhs); | |
| 6507 var_rhs.Bind(rhs); | |
| 6508 Goto(&loop); | 6477 Goto(&loop); |
| 6509 Bind(&loop); | 6478 Bind(&loop); |
| 6510 { | 6479 { |
| 6511 // Load the current {lhs} and {rhs} values. | 6480 // Load the current {lhs} and {rhs} values. |
| 6512 lhs = var_lhs.value(); | 6481 lhs = var_lhs.value(); |
| 6513 rhs = var_rhs.value(); | 6482 rhs = var_rhs.value(); |
| 6514 | 6483 |
| 6515 // Check if the {lhs} is a Smi or a HeapObject. | 6484 // Check if the {lhs} is a Smi or a HeapObject. |
| 6516 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 6485 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
| 6517 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 6486 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6869 do_rhsstringtonumber(this, Label::kDeferred), end(this); | 6838 do_rhsstringtonumber(this, Label::kDeferred), end(this); |
| 6870 Variable result(this, MachineRepresentation::kTagged); | 6839 Variable result(this, MachineRepresentation::kTagged); |
| 6871 | 6840 |
| 6872 // Shared entry for floating point comparison. | 6841 // Shared entry for floating point comparison. |
| 6873 Label do_fcmp(this); | 6842 Label do_fcmp(this); |
| 6874 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), | 6843 Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64), |
| 6875 var_fcmp_rhs(this, MachineRepresentation::kFloat64); | 6844 var_fcmp_rhs(this, MachineRepresentation::kFloat64); |
| 6876 | 6845 |
| 6877 // We might need to loop several times due to ToPrimitive and/or ToNumber | 6846 // We might need to loop several times due to ToPrimitive and/or ToNumber |
| 6878 // conversions. | 6847 // conversions. |
| 6879 Variable var_lhs(this, MachineRepresentation::kTagged), | 6848 Variable var_lhs(this, MachineRepresentation::kTagged, lhs), |
| 6880 var_rhs(this, MachineRepresentation::kTagged); | 6849 var_rhs(this, MachineRepresentation::kTagged, rhs); |
| 6881 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; | 6850 Variable* loop_vars[2] = {&var_lhs, &var_rhs}; |
| 6882 Label loop(this, 2, loop_vars); | 6851 Label loop(this, 2, loop_vars); |
| 6883 var_lhs.Bind(lhs); | |
| 6884 var_rhs.Bind(rhs); | |
| 6885 Goto(&loop); | 6852 Goto(&loop); |
| 6886 Bind(&loop); | 6853 Bind(&loop); |
| 6887 { | 6854 { |
| 6888 // Load the current {lhs} and {rhs} values. | 6855 // Load the current {lhs} and {rhs} values. |
| 6889 lhs = var_lhs.value(); | 6856 lhs = var_lhs.value(); |
| 6890 rhs = var_rhs.value(); | 6857 rhs = var_rhs.value(); |
| 6891 | 6858 |
| 6892 // Check if {lhs} and {rhs} refer to the same object. | 6859 // Check if {lhs} and {rhs} refer to the same object. |
| 6893 Label if_same(this), if_notsame(this); | 6860 Label if_same(this), if_notsame(this); |
| 6894 Branch(WordEqual(lhs, rhs), &if_same, &if_notsame); | 6861 Branch(WordEqual(lhs, rhs), &if_same, &if_notsame); |
| (...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8393 deferred_on_reject); | 8360 deferred_on_reject); |
| 8394 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kDebugIdOffset, | 8361 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kDebugIdOffset, |
| 8395 SmiConstant(kDebugPromiseNoID)); | 8362 SmiConstant(kDebugPromiseNoID)); |
| 8396 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, | 8363 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, |
| 8397 context); | 8364 context); |
| 8398 return result; | 8365 return result; |
| 8399 } | 8366 } |
| 8400 | 8367 |
| 8401 } // namespace internal | 8368 } // namespace internal |
| 8402 } // namespace v8 | 8369 } // namespace v8 |
| OLD | NEW |