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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 if (Is64()) { | 284 if (Is64()) { |
285 result = TruncateInt64ToInt32(result); | 285 result = TruncateInt64ToInt32(result); |
286 } | 286 } |
287 return result; | 287 return result; |
288 } | 288 } |
289 | 289 |
290 Node* CodeStubAssembler::SmiToFloat64(Node* value) { | 290 Node* CodeStubAssembler::SmiToFloat64(Node* value) { |
291 return ChangeInt32ToFloat64(SmiToWord32(value)); | 291 return ChangeInt32ToFloat64(SmiToWord32(value)); |
292 } | 292 } |
293 | 293 |
294 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { return IntPtrAdd(a, b); } | 294 Node* CodeStubAssembler::SmiAdd(Node* a, Node* b) { |
| 295 return BitcastWordToTaggedSigned( |
| 296 IntPtrAdd(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); |
| 297 } |
295 | 298 |
296 Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) { | 299 Node* CodeStubAssembler::SmiAddWithOverflow(Node* a, Node* b) { |
297 return IntPtrAddWithOverflow(a, b); | 300 return IntPtrAddWithOverflow(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
298 } | 301 } |
299 | 302 |
300 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); } | 303 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { |
| 304 return BitcastWordToTaggedSigned( |
| 305 IntPtrSub(BitcastTaggedToWord(a), BitcastTaggedToWord(b))); |
| 306 } |
301 | 307 |
302 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) { | 308 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) { |
303 return IntPtrSubWithOverflow(a, b); | 309 return IntPtrSubWithOverflow(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
304 } | 310 } |
305 | 311 |
306 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); } | 312 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { |
| 313 return WordEqual(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
| 314 } |
307 | 315 |
308 Node* CodeStubAssembler::SmiAbove(Node* a, Node* b) { | 316 Node* CodeStubAssembler::SmiAbove(Node* a, Node* b) { |
309 return UintPtrGreaterThan(a, b); | 317 return UintPtrGreaterThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
310 } | 318 } |
311 | 319 |
312 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) { | 320 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) { |
313 return UintPtrGreaterThanOrEqual(a, b); | 321 return UintPtrGreaterThanOrEqual(BitcastTaggedToWord(a), |
| 322 BitcastTaggedToWord(b)); |
314 } | 323 } |
315 | 324 |
316 Node* CodeStubAssembler::SmiBelow(Node* a, Node* b) { | 325 Node* CodeStubAssembler::SmiBelow(Node* a, Node* b) { |
317 return UintPtrLessThan(a, b); | 326 return UintPtrLessThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
318 } | 327 } |
319 | 328 |
320 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { | 329 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { |
321 return IntPtrLessThan(a, b); | 330 return IntPtrLessThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
322 } | 331 } |
323 | 332 |
324 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { | 333 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { |
325 return IntPtrLessThanOrEqual(a, b); | 334 return IntPtrLessThanOrEqual(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
326 } | 335 } |
327 | 336 |
328 Node* CodeStubAssembler::SmiMax(Node* a, Node* b) { | 337 Node* CodeStubAssembler::SmiMax(Node* a, Node* b) { |
329 return Select(SmiLessThan(a, b), b, a); | 338 return Select(SmiLessThan(a, b), b, a); |
330 } | 339 } |
331 | 340 |
332 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { | 341 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { |
333 return Select(SmiLessThan(a, b), a, b); | 342 return Select(SmiLessThan(a, b), a, b); |
334 } | 343 } |
335 | 344 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); | 459 Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
451 Node* result = ChangeFloat64ToTagged(value); | 460 Node* result = ChangeFloat64ToTagged(value); |
452 var_result.Bind(result); | 461 var_result.Bind(result); |
453 Goto(&return_result); | 462 Goto(&return_result); |
454 } | 463 } |
455 | 464 |
456 Bind(&return_result); | 465 Bind(&return_result); |
457 return var_result.value(); | 466 return var_result.value(); |
458 } | 467 } |
459 | 468 |
460 Node* CodeStubAssembler::WordIsSmi(Node* a) { | 469 Node* CodeStubAssembler::TaggedIsSmi(Node* a) { |
461 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0)); | 470 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), |
| 471 IntPtrConstant(0)); |
462 } | 472 } |
463 | 473 |
464 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { | 474 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { |
465 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), | 475 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), |
466 IntPtrConstant(0)); | 476 IntPtrConstant(0)); |
467 } | 477 } |
468 | 478 |
469 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map, | 479 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map, |
470 Node* rhs, Node* rhs_map, | 480 Node* rhs, Node* rhs_map, |
471 Label* if_equal, | 481 Label* if_equal, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 GotoIf(WordNotEqual(LoadElements(prototype), empty_elements), | 572 GotoIf(WordNotEqual(LoadElements(prototype), empty_elements), |
563 possibly_elements); | 573 possibly_elements); |
564 var_map.Bind(prototype_map); | 574 var_map.Bind(prototype_map); |
565 Goto(&loop_body); | 575 Goto(&loop_body); |
566 } | 576 } |
567 } | 577 } |
568 | 578 |
569 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, | 579 void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context, |
570 Label* if_true, Label* if_false) { | 580 Label* if_true, Label* if_false) { |
571 // Bailout if receiver is a Smi. | 581 // Bailout if receiver is a Smi. |
572 GotoIf(WordIsSmi(object), if_false); | 582 GotoIf(TaggedIsSmi(object), if_false); |
573 | 583 |
574 Node* map = LoadMap(object); | 584 Node* map = LoadMap(object); |
575 | 585 |
576 // Bailout if instance type is not JS_ARRAY_TYPE. | 586 // Bailout if instance type is not JS_ARRAY_TYPE. |
577 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), | 587 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), |
578 if_false); | 588 if_false); |
579 | 589 |
580 Node* bit_field2 = LoadMapBitField2(map); | 590 Node* bit_field2 = LoadMapBitField2(map); |
581 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2); | 591 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2); |
582 | 592 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true, | 739 void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true, |
730 Label* if_false) { | 740 Label* if_false) { |
731 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this), | 741 Label if_valueissmi(this), if_valueisnotsmi(this), if_valueisstring(this), |
732 if_valueisheapnumber(this), if_valueisother(this); | 742 if_valueisheapnumber(this), if_valueisother(this); |
733 | 743 |
734 // Fast check for Boolean {value}s (common case). | 744 // Fast check for Boolean {value}s (common case). |
735 GotoIf(WordEqual(value, BooleanConstant(true)), if_true); | 745 GotoIf(WordEqual(value, BooleanConstant(true)), if_true); |
736 GotoIf(WordEqual(value, BooleanConstant(false)), if_false); | 746 GotoIf(WordEqual(value, BooleanConstant(false)), if_false); |
737 | 747 |
738 // Check if {value} is a Smi or a HeapObject. | 748 // Check if {value} is a Smi or a HeapObject. |
739 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 749 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
740 | 750 |
741 Bind(&if_valueissmi); | 751 Bind(&if_valueissmi); |
742 { | 752 { |
743 // The {value} is a Smi, only need to check against zero. | 753 // The {value} is a Smi, only need to check against zero. |
744 BranchIfSmiEqual(value, SmiConstant(0), if_false, if_true); | 754 BranchIfSmiEqual(value, SmiConstant(0), if_false, if_true); |
745 } | 755 } |
746 | 756 |
747 Bind(&if_valueisnotsmi); | 757 Bind(&if_valueisnotsmi); |
748 { | 758 { |
749 // The {value} is a HeapObject, load its map. | 759 // The {value} is a HeapObject, load its map. |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 } | 981 } |
972 | 982 |
973 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { | 983 Node* CodeStubAssembler::LoadMapConstructor(Node* map) { |
974 Variable result(this, MachineRepresentation::kTagged); | 984 Variable result(this, MachineRepresentation::kTagged); |
975 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); | 985 result.Bind(LoadObjectField(map, Map::kConstructorOrBackPointerOffset)); |
976 | 986 |
977 Label done(this), loop(this, &result); | 987 Label done(this), loop(this, &result); |
978 Goto(&loop); | 988 Goto(&loop); |
979 Bind(&loop); | 989 Bind(&loop); |
980 { | 990 { |
981 GotoIf(WordIsSmi(result.value()), &done); | 991 GotoIf(TaggedIsSmi(result.value()), &done); |
982 Node* is_map_type = | 992 Node* is_map_type = |
983 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); | 993 Word32Equal(LoadInstanceType(result.value()), Int32Constant(MAP_TYPE)); |
984 GotoUnless(is_map_type, &done); | 994 GotoUnless(is_map_type, &done); |
985 result.Bind( | 995 result.Bind( |
986 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); | 996 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); |
987 Goto(&loop); | 997 Goto(&loop); |
988 } | 998 } |
989 Bind(&done); | 999 Bind(&done); |
990 return result.value(); | 1000 return result.value(); |
991 } | 1001 } |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 | 1421 |
1412 int elements_offset = base_size; | 1422 int elements_offset = base_size; |
1413 | 1423 |
1414 // Compute space for elements | 1424 // Compute space for elements |
1415 base_size += FixedArray::kHeaderSize; | 1425 base_size += FixedArray::kHeaderSize; |
1416 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); | 1426 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); |
1417 | 1427 |
1418 Node* array = AllocateUninitializedJSArray(kind, array_map, length, | 1428 Node* array = AllocateUninitializedJSArray(kind, array_map, length, |
1419 allocation_site, size); | 1429 allocation_site, size); |
1420 | 1430 |
1421 Node* elements = InnerAllocate(array, elements_offset); | 1431 // The bitcast here is safe because InnerAllocate doesn't actually allocate. |
| 1432 Node* elements = InnerAllocate(BitcastTaggedToWord(array), elements_offset); |
1422 StoreObjectField(array, JSObject::kElementsOffset, elements); | 1433 StoreObjectField(array, JSObject::kElementsOffset, elements); |
1423 | 1434 |
1424 return {array, elements}; | 1435 return {array, elements}; |
1425 } | 1436 } |
1426 | 1437 |
1427 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, | 1438 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, |
1428 Node* array_map, | 1439 Node* array_map, |
1429 Node* length, | 1440 Node* length, |
1430 Node* allocation_site, | 1441 Node* allocation_site, |
1431 Node* size_in_bytes) { | 1442 Node* size_in_bytes) { |
(...skipping 25 matching lines...) Expand all Loading... |
1457 kind, array_map, length, allocation_site, capacity, capacity_mode); | 1468 kind, array_map, length, allocation_site, capacity, capacity_mode); |
1458 // Setup elements object. | 1469 // Setup elements object. |
1459 Heap* heap = isolate()->heap(); | 1470 Heap* heap = isolate()->heap(); |
1460 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() | 1471 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() |
1461 : heap->fixed_array_map()); | 1472 : heap->fixed_array_map()); |
1462 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); | 1473 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); |
1463 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, | 1474 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, |
1464 TagParameter(capacity, capacity_mode)); | 1475 TagParameter(capacity, capacity_mode)); |
1465 | 1476 |
1466 // Fill in the elements with holes. | 1477 // Fill in the elements with holes. |
1467 FillFixedArrayWithValue(kind, elements, IntPtrConstant(0), capacity, | 1478 FillFixedArrayWithValue( |
1468 Heap::kTheHoleValueRootIndex, capacity_mode); | 1479 kind, elements, capacity_mode == SMI_PARAMETERS ? SmiConstant(Smi::kZero) |
| 1480 : IntPtrConstant(0), |
| 1481 capacity, Heap::kTheHoleValueRootIndex, capacity_mode); |
1469 | 1482 |
1470 return array; | 1483 return array; |
1471 } | 1484 } |
1472 | 1485 |
1473 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, | 1486 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, |
1474 Node* capacity_node, | 1487 Node* capacity_node, |
1475 ParameterMode mode, | 1488 ParameterMode mode, |
1476 AllocationFlags flags) { | 1489 AllocationFlags flags) { |
1477 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); | 1490 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); |
1478 | 1491 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1626 | 1639 |
1627 Node* value = LoadElementAndPrepareForStore( | 1640 Node* value = LoadElementAndPrepareForStore( |
1628 from_array, var_from_offset.value(), from_kind, to_kind, if_hole); | 1641 from_array, var_from_offset.value(), from_kind, to_kind, if_hole); |
1629 | 1642 |
1630 if (needs_write_barrier) { | 1643 if (needs_write_barrier) { |
1631 Store(MachineRepresentation::kTagged, to_array, to_offset, value); | 1644 Store(MachineRepresentation::kTagged, to_array, to_offset, value); |
1632 } else if (to_double_elements) { | 1645 } else if (to_double_elements) { |
1633 StoreNoWriteBarrier(MachineRepresentation::kFloat64, to_array, to_offset, | 1646 StoreNoWriteBarrier(MachineRepresentation::kFloat64, to_array, to_offset, |
1634 value); | 1647 value); |
1635 } else { | 1648 } else { |
1636 StoreNoWriteBarrier(MachineType::PointerRepresentation(), to_array, | 1649 StoreNoWriteBarrier(MachineRepresentation::kTagged, to_array, to_offset, |
1637 to_offset, value); | 1650 value); |
1638 } | 1651 } |
1639 Goto(&next_iter); | 1652 Goto(&next_iter); |
1640 | 1653 |
1641 if (if_hole == &store_double_hole) { | 1654 if (if_hole == &store_double_hole) { |
1642 Bind(&store_double_hole); | 1655 Bind(&store_double_hole); |
1643 // Don't use doubles to store the hole double, since manipulating the | 1656 // Don't use doubles to store the hole double, since manipulating the |
1644 // signaling NaN used for the hole in C++, e.g. with bit_cast, will | 1657 // signaling NaN used for the hole in C++, e.g. with bit_cast, will |
1645 // change its value on ia32 (the x87 stack is used to return values | 1658 // change its value on ia32 (the x87 stack is used to return values |
1646 // and stores to the stack silently clear the signalling bit). | 1659 // and stores to the stack silently clear the signalling bit). |
1647 // | 1660 // |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 Label* if_hole) { | 1759 Label* if_hole) { |
1747 if (IsFastDoubleElementsKind(from_kind)) { | 1760 if (IsFastDoubleElementsKind(from_kind)) { |
1748 Node* value = | 1761 Node* value = |
1749 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64()); | 1762 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64()); |
1750 if (!IsFastDoubleElementsKind(to_kind)) { | 1763 if (!IsFastDoubleElementsKind(to_kind)) { |
1751 value = AllocateHeapNumberWithValue(value); | 1764 value = AllocateHeapNumberWithValue(value); |
1752 } | 1765 } |
1753 return value; | 1766 return value; |
1754 | 1767 |
1755 } else { | 1768 } else { |
1756 Node* value = Load(MachineType::Pointer(), array, offset); | 1769 Node* value = Load(MachineType::AnyTagged(), array, offset); |
1757 if (if_hole) { | 1770 if (if_hole) { |
1758 GotoIf(WordEqual(value, TheHoleConstant()), if_hole); | 1771 GotoIf(WordEqual(value, TheHoleConstant()), if_hole); |
1759 } | 1772 } |
1760 if (IsFastDoubleElementsKind(to_kind)) { | 1773 if (IsFastDoubleElementsKind(to_kind)) { |
1761 if (IsFastSmiElementsKind(from_kind)) { | 1774 if (IsFastSmiElementsKind(from_kind)) { |
1762 value = SmiToFloat64(value); | 1775 value = SmiToFloat64(value); |
1763 } else { | 1776 } else { |
1764 value = LoadHeapNumberValue(value); | 1777 value = LoadHeapNumberValue(value); |
1765 } | 1778 } |
1766 } | 1779 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 StoreObjectFieldNoWriteBarrier( | 1863 StoreObjectFieldNoWriteBarrier( |
1851 base_allocation, AllocationMemento::kMapOffset + base_allocation_size, | 1864 base_allocation, AllocationMemento::kMapOffset + base_allocation_size, |
1852 HeapConstant(Handle<Map>(isolate()->heap()->allocation_memento_map()))); | 1865 HeapConstant(Handle<Map>(isolate()->heap()->allocation_memento_map()))); |
1853 StoreObjectFieldNoWriteBarrier( | 1866 StoreObjectFieldNoWriteBarrier( |
1854 base_allocation, | 1867 base_allocation, |
1855 AllocationMemento::kAllocationSiteOffset + base_allocation_size, | 1868 AllocationMemento::kAllocationSiteOffset + base_allocation_size, |
1856 allocation_site); | 1869 allocation_site); |
1857 if (FLAG_allocation_site_pretenuring) { | 1870 if (FLAG_allocation_site_pretenuring) { |
1858 Node* count = LoadObjectField(allocation_site, | 1871 Node* count = LoadObjectField(allocation_site, |
1859 AllocationSite::kPretenureCreateCountOffset); | 1872 AllocationSite::kPretenureCreateCountOffset); |
1860 Node* incremented_count = IntPtrAdd(count, SmiConstant(Smi::FromInt(1))); | 1873 Node* incremented_count = SmiAdd(count, SmiConstant(Smi::FromInt(1))); |
1861 StoreObjectFieldNoWriteBarrier(allocation_site, | 1874 StoreObjectFieldNoWriteBarrier(allocation_site, |
1862 AllocationSite::kPretenureCreateCountOffset, | 1875 AllocationSite::kPretenureCreateCountOffset, |
1863 incremented_count); | 1876 incremented_count); |
1864 } | 1877 } |
1865 } | 1878 } |
1866 | 1879 |
1867 Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { | 1880 Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { |
1868 // We might need to loop once due to ToNumber conversion. | 1881 // We might need to loop once due to ToNumber conversion. |
1869 Variable var_value(this, MachineRepresentation::kTagged), | 1882 Variable var_value(this, MachineRepresentation::kTagged), |
1870 var_result(this, MachineRepresentation::kFloat64); | 1883 var_result(this, MachineRepresentation::kFloat64); |
1871 Label loop(this, &var_value), done_loop(this, &var_result); | 1884 Label loop(this, &var_value), done_loop(this, &var_result); |
1872 var_value.Bind(value); | 1885 var_value.Bind(value); |
1873 Goto(&loop); | 1886 Goto(&loop); |
1874 Bind(&loop); | 1887 Bind(&loop); |
1875 { | 1888 { |
1876 // Load the current {value}. | 1889 // Load the current {value}. |
1877 value = var_value.value(); | 1890 value = var_value.value(); |
1878 | 1891 |
1879 // Check if the {value} is a Smi or a HeapObject. | 1892 // Check if the {value} is a Smi or a HeapObject. |
1880 Label if_valueissmi(this), if_valueisnotsmi(this); | 1893 Label if_valueissmi(this), if_valueisnotsmi(this); |
1881 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 1894 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
1882 | 1895 |
1883 Bind(&if_valueissmi); | 1896 Bind(&if_valueissmi); |
1884 { | 1897 { |
1885 // Convert the Smi {value}. | 1898 // Convert the Smi {value}. |
1886 var_result.Bind(SmiToFloat64(value)); | 1899 var_result.Bind(SmiToFloat64(value)); |
1887 Goto(&done_loop); | 1900 Goto(&done_loop); |
1888 } | 1901 } |
1889 | 1902 |
1890 Bind(&if_valueisnotsmi); | 1903 Bind(&if_valueisnotsmi); |
1891 { | 1904 { |
(...skipping 30 matching lines...) Expand all Loading... |
1922 Label loop(this, &var_value), done_loop(this, &var_result); | 1935 Label loop(this, &var_value), done_loop(this, &var_result); |
1923 var_value.Bind(value); | 1936 var_value.Bind(value); |
1924 Goto(&loop); | 1937 Goto(&loop); |
1925 Bind(&loop); | 1938 Bind(&loop); |
1926 { | 1939 { |
1927 // Load the current {value}. | 1940 // Load the current {value}. |
1928 value = var_value.value(); | 1941 value = var_value.value(); |
1929 | 1942 |
1930 // Check if the {value} is a Smi or a HeapObject. | 1943 // Check if the {value} is a Smi or a HeapObject. |
1931 Label if_valueissmi(this), if_valueisnotsmi(this); | 1944 Label if_valueissmi(this), if_valueisnotsmi(this); |
1932 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 1945 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
1933 | 1946 |
1934 Bind(&if_valueissmi); | 1947 Bind(&if_valueissmi); |
1935 { | 1948 { |
1936 // Convert the Smi {value}. | 1949 // Convert the Smi {value}. |
1937 var_result.Bind(SmiToWord32(value)); | 1950 var_result.Bind(SmiToWord32(value)); |
1938 Goto(&done_loop); | 1951 Goto(&done_loop); |
1939 } | 1952 } |
1940 | 1953 |
1941 Bind(&if_valueisnotsmi); | 1954 Bind(&if_valueisnotsmi); |
1942 { | 1955 { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2084 } | 2097 } |
2085 | 2098 |
2086 Node* CodeStubAssembler::ToThisString(Node* context, Node* value, | 2099 Node* CodeStubAssembler::ToThisString(Node* context, Node* value, |
2087 char const* method_name) { | 2100 char const* method_name) { |
2088 Variable var_value(this, MachineRepresentation::kTagged); | 2101 Variable var_value(this, MachineRepresentation::kTagged); |
2089 var_value.Bind(value); | 2102 var_value.Bind(value); |
2090 | 2103 |
2091 // Check if the {value} is a Smi or a HeapObject. | 2104 // Check if the {value} is a Smi or a HeapObject. |
2092 Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this), | 2105 Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this), |
2093 if_valueisstring(this); | 2106 if_valueisstring(this); |
2094 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 2107 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
2095 Bind(&if_valueisnotsmi); | 2108 Bind(&if_valueisnotsmi); |
2096 { | 2109 { |
2097 // Load the instance type of the {value}. | 2110 // Load the instance type of the {value}. |
2098 Node* value_instance_type = LoadInstanceType(value); | 2111 Node* value_instance_type = LoadInstanceType(value); |
2099 | 2112 |
2100 // Check if the {value} is already String. | 2113 // Check if the {value} is already String. |
2101 Label if_valueisnotstring(this, Label::kDeferred); | 2114 Label if_valueisnotstring(this, Label::kDeferred); |
2102 Branch(IsStringInstanceType(value_instance_type), &if_valueisstring, | 2115 Branch(IsStringInstanceType(value_instance_type), &if_valueisstring, |
2103 &if_valueisnotstring); | 2116 &if_valueisnotstring); |
2104 Bind(&if_valueisnotstring); | 2117 Bind(&if_valueisnotstring); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2152 Label loop(this, &var_value), done_loop(this), | 2165 Label loop(this, &var_value), done_loop(this), |
2153 done_throw(this, Label::kDeferred); | 2166 done_throw(this, Label::kDeferred); |
2154 var_value.Bind(value); | 2167 var_value.Bind(value); |
2155 Goto(&loop); | 2168 Goto(&loop); |
2156 Bind(&loop); | 2169 Bind(&loop); |
2157 { | 2170 { |
2158 // Load the current {value}. | 2171 // Load the current {value}. |
2159 value = var_value.value(); | 2172 value = var_value.value(); |
2160 | 2173 |
2161 // Check if the {value} is a Smi or a HeapObject. | 2174 // Check if the {value} is a Smi or a HeapObject. |
2162 GotoIf(WordIsSmi(value), (primitive_type == PrimitiveType::kNumber) | 2175 GotoIf(TaggedIsSmi(value), (primitive_type == PrimitiveType::kNumber) |
2163 ? &done_loop | 2176 ? &done_loop |
2164 : &done_throw); | 2177 : &done_throw); |
2165 | 2178 |
2166 // Load the mape of the {value}. | 2179 // Load the mape of the {value}. |
2167 Node* value_map = LoadMap(value); | 2180 Node* value_map = LoadMap(value); |
2168 | 2181 |
2169 // Load the instance type of the {value}. | 2182 // Load the instance type of the {value}. |
2170 Node* value_instance_type = LoadMapInstanceType(value_map); | 2183 Node* value_instance_type = LoadMapInstanceType(value_map); |
2171 | 2184 |
2172 // Check if {value} is a JSValue. | 2185 // Check if {value} is a JSValue. |
2173 Label if_valueisvalue(this, Label::kDeferred), if_valueisnotvalue(this); | 2186 Label if_valueisvalue(this, Label::kDeferred), if_valueisnotvalue(this); |
2174 Branch(Word32Equal(value_instance_type, Int32Constant(JS_VALUE_TYPE)), | 2187 Branch(Word32Equal(value_instance_type, Int32Constant(JS_VALUE_TYPE)), |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 Bind(&done_loop); | 2229 Bind(&done_loop); |
2217 return var_value.value(); | 2230 return var_value.value(); |
2218 } | 2231 } |
2219 | 2232 |
2220 Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value, | 2233 Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value, |
2221 InstanceType instance_type, | 2234 InstanceType instance_type, |
2222 char const* method_name) { | 2235 char const* method_name) { |
2223 Label out(this), throw_exception(this, Label::kDeferred); | 2236 Label out(this), throw_exception(this, Label::kDeferred); |
2224 Variable var_value_map(this, MachineRepresentation::kTagged); | 2237 Variable var_value_map(this, MachineRepresentation::kTagged); |
2225 | 2238 |
2226 GotoIf(WordIsSmi(value), &throw_exception); | 2239 GotoIf(TaggedIsSmi(value), &throw_exception); |
2227 | 2240 |
2228 // Load the instance type of the {value}. | 2241 // Load the instance type of the {value}. |
2229 var_value_map.Bind(LoadMap(value)); | 2242 var_value_map.Bind(LoadMap(value)); |
2230 Node* const value_instance_type = LoadMapInstanceType(var_value_map.value()); | 2243 Node* const value_instance_type = LoadMapInstanceType(var_value_map.value()); |
2231 | 2244 |
2232 Branch(Word32Equal(value_instance_type, Int32Constant(instance_type)), &out, | 2245 Branch(Word32Equal(value_instance_type, Int32Constant(instance_type)), &out, |
2233 &throw_exception); | 2246 &throw_exception); |
2234 | 2247 |
2235 // The {value} is not a compatible receiver for this method. | 2248 // The {value} is not a compatible receiver for this method. |
2236 Bind(&throw_exception); | 2249 Bind(&throw_exception); |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2547 Variable var_from(this, MachineRepresentation::kTagged); // Smi. | 2560 Variable var_from(this, MachineRepresentation::kTagged); // Smi. |
2548 Variable var_string(this, MachineRepresentation::kTagged); // String. | 2561 Variable var_string(this, MachineRepresentation::kTagged); // String. |
2549 | 2562 |
2550 var_instance_type.Bind(Int32Constant(0)); | 2563 var_instance_type.Bind(Int32Constant(0)); |
2551 var_string.Bind(string); | 2564 var_string.Bind(string); |
2552 var_from.Bind(from); | 2565 var_from.Bind(from); |
2553 | 2566 |
2554 // Make sure first argument is a string. | 2567 // Make sure first argument is a string. |
2555 | 2568 |
2556 // Bailout if receiver is a Smi. | 2569 // Bailout if receiver is a Smi. |
2557 GotoIf(WordIsSmi(string), &runtime); | 2570 GotoIf(TaggedIsSmi(string), &runtime); |
2558 | 2571 |
2559 // Load the instance type of the {string}. | 2572 // Load the instance type of the {string}. |
2560 Node* const instance_type = LoadInstanceType(string); | 2573 Node* const instance_type = LoadInstanceType(string); |
2561 var_instance_type.Bind(instance_type); | 2574 var_instance_type.Bind(instance_type); |
2562 | 2575 |
2563 // Check if {string} is a String. | 2576 // Check if {string} is a String. |
2564 GotoUnless(IsStringInstanceType(instance_type), &runtime); | 2577 GotoUnless(IsStringInstanceType(instance_type), &runtime); |
2565 | 2578 |
2566 // Make sure that both from and to are non-negative smis. | 2579 // Make sure that both from and to are non-negative smis. |
2567 | 2580 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2845 | 2858 |
2846 // Load the number string cache. | 2859 // Load the number string cache. |
2847 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); | 2860 Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex); |
2848 | 2861 |
2849 // Make the hash mask from the length of the number string cache. It | 2862 // Make the hash mask from the length of the number string cache. It |
2850 // contains two elements (number and string) for each cache entry. | 2863 // contains two elements (number and string) for each cache entry. |
2851 Node* mask = LoadFixedArrayBaseLength(number_string_cache); | 2864 Node* mask = LoadFixedArrayBaseLength(number_string_cache); |
2852 Node* one = IntPtrConstant(1); | 2865 Node* one = IntPtrConstant(1); |
2853 mask = IntPtrSub(mask, one); | 2866 mask = IntPtrSub(mask, one); |
2854 | 2867 |
2855 GotoIf(WordIsSmi(argument), &smi); | 2868 GotoIf(TaggedIsSmi(argument), &smi); |
2856 | 2869 |
2857 // Argument isn't smi, check to see if it's a heap-number. | 2870 // Argument isn't smi, check to see if it's a heap-number. |
2858 Node* map = LoadMap(argument); | 2871 Node* map = LoadMap(argument); |
2859 GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); | 2872 GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); |
2860 | 2873 |
2861 // Make a hash from the two 32-bit values of the double. | 2874 // Make a hash from the two 32-bit values of the double. |
2862 Node* low = | 2875 Node* low = |
2863 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); | 2876 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); |
2864 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, | 2877 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, |
2865 MachineType::Int32()); | 2878 MachineType::Int32()); |
2866 Node* hash = Word32Xor(low, high); | 2879 Node* hash = Word32Xor(low, high); |
2867 if (Is64()) hash = ChangeInt32ToInt64(hash); | 2880 if (Is64()) hash = ChangeInt32ToInt64(hash); |
2868 hash = WordShl(hash, one); | 2881 hash = WordShl(hash, one); |
2869 Node* index = WordAnd(hash, SmiToWord(mask)); | 2882 Node* index = WordAnd(hash, SmiToWord(mask)); |
2870 | 2883 |
2871 // Cache entry's key must be a heap number | 2884 // Cache entry's key must be a heap number |
2872 Node* number_key = | 2885 Node* number_key = |
2873 LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS); | 2886 LoadFixedArrayElement(number_string_cache, index, 0, INTPTR_PARAMETERS); |
2874 GotoIf(WordIsSmi(number_key), &runtime); | 2887 GotoIf(TaggedIsSmi(number_key), &runtime); |
2875 map = LoadMap(number_key); | 2888 map = LoadMap(number_key); |
2876 GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); | 2889 GotoUnless(WordEqual(map, HeapNumberMapConstant()), &runtime); |
2877 | 2890 |
2878 // Cache entry's key must match the heap number value we're looking for. | 2891 // Cache entry's key must match the heap number value we're looking for. |
2879 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, | 2892 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, |
2880 MachineType::Int32()); | 2893 MachineType::Int32()); |
2881 Node* high_compare = LoadObjectField( | 2894 Node* high_compare = LoadObjectField( |
2882 number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32()); | 2895 number_key, HeapNumber::kValueOffset + kIntSize, MachineType::Int32()); |
2883 GotoUnless(WordEqual(low, low_compare), &runtime); | 2896 GotoUnless(WordEqual(low, low_compare), &runtime); |
2884 GotoUnless(WordEqual(high, high_compare), &runtime); | 2897 GotoUnless(WordEqual(high, high_compare), &runtime); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2916 } | 2929 } |
2917 | 2930 |
2918 Node* CodeStubAssembler::ToName(Node* context, Node* value) { | 2931 Node* CodeStubAssembler::ToName(Node* context, Node* value) { |
2919 typedef CodeStubAssembler::Label Label; | 2932 typedef CodeStubAssembler::Label Label; |
2920 typedef CodeStubAssembler::Variable Variable; | 2933 typedef CodeStubAssembler::Variable Variable; |
2921 | 2934 |
2922 Label end(this); | 2935 Label end(this); |
2923 Variable var_result(this, MachineRepresentation::kTagged); | 2936 Variable var_result(this, MachineRepresentation::kTagged); |
2924 | 2937 |
2925 Label is_number(this); | 2938 Label is_number(this); |
2926 GotoIf(WordIsSmi(value), &is_number); | 2939 GotoIf(TaggedIsSmi(value), &is_number); |
2927 | 2940 |
2928 Label not_name(this); | 2941 Label not_name(this); |
2929 Node* value_instance_type = LoadInstanceType(value); | 2942 Node* value_instance_type = LoadInstanceType(value); |
2930 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); | 2943 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); |
2931 GotoIf(Int32GreaterThan(value_instance_type, Int32Constant(LAST_NAME_TYPE)), | 2944 GotoIf(Int32GreaterThan(value_instance_type, Int32Constant(LAST_NAME_TYPE)), |
2932 ¬_name); | 2945 ¬_name); |
2933 | 2946 |
2934 var_result.Bind(value); | 2947 var_result.Bind(value); |
2935 Goto(&end); | 2948 Goto(&end); |
2936 | 2949 |
(...skipping 22 matching lines...) Expand all Loading... |
2959 Goto(&end); | 2972 Goto(&end); |
2960 } | 2973 } |
2961 } | 2974 } |
2962 | 2975 |
2963 Bind(&end); | 2976 Bind(&end); |
2964 return var_result.value(); | 2977 return var_result.value(); |
2965 } | 2978 } |
2966 | 2979 |
2967 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { | 2980 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { |
2968 // Assert input is a HeapObject (not smi or heap number) | 2981 // Assert input is a HeapObject (not smi or heap number) |
2969 Assert(Word32BinaryNot(WordIsSmi(input))); | 2982 Assert(Word32BinaryNot(TaggedIsSmi(input))); |
2970 Assert(Word32NotEqual(LoadMap(input), HeapNumberMapConstant())); | 2983 Assert(Word32NotEqual(LoadMap(input), HeapNumberMapConstant())); |
2971 | 2984 |
2972 // We might need to loop once here due to ToPrimitive conversions. | 2985 // We might need to loop once here due to ToPrimitive conversions. |
2973 Variable var_input(this, MachineRepresentation::kTagged); | 2986 Variable var_input(this, MachineRepresentation::kTagged); |
2974 Variable var_result(this, MachineRepresentation::kTagged); | 2987 Variable var_result(this, MachineRepresentation::kTagged); |
2975 Label loop(this, &var_input); | 2988 Label loop(this, &var_input); |
2976 Label end(this); | 2989 Label end(this); |
2977 var_input.Bind(input); | 2990 var_input.Bind(input); |
2978 Goto(&loop); | 2991 Goto(&loop); |
2979 Bind(&loop); | 2992 Bind(&loop); |
(...skipping 29 matching lines...) Expand all Loading... |
3009 Bind(&if_inputisreceiver); | 3022 Bind(&if_inputisreceiver); |
3010 { | 3023 { |
3011 // The {input} is a JSReceiver, we need to convert it to a Primitive first | 3024 // The {input} is a JSReceiver, we need to convert it to a Primitive first |
3012 // using the ToPrimitive type conversion, preferably yielding a Number. | 3025 // using the ToPrimitive type conversion, preferably yielding a Number. |
3013 Callable callable = CodeFactory::NonPrimitiveToPrimitive( | 3026 Callable callable = CodeFactory::NonPrimitiveToPrimitive( |
3014 isolate(), ToPrimitiveHint::kNumber); | 3027 isolate(), ToPrimitiveHint::kNumber); |
3015 Node* result = CallStub(callable, context, input); | 3028 Node* result = CallStub(callable, context, input); |
3016 | 3029 |
3017 // Check if the {result} is already a Number. | 3030 // Check if the {result} is already a Number. |
3018 Label if_resultisnumber(this), if_resultisnotnumber(this); | 3031 Label if_resultisnumber(this), if_resultisnotnumber(this); |
3019 GotoIf(WordIsSmi(result), &if_resultisnumber); | 3032 GotoIf(TaggedIsSmi(result), &if_resultisnumber); |
3020 Node* result_map = LoadMap(result); | 3033 Node* result_map = LoadMap(result); |
3021 Branch(WordEqual(result_map, HeapNumberMapConstant()), &if_resultisnumber, | 3034 Branch(WordEqual(result_map, HeapNumberMapConstant()), &if_resultisnumber, |
3022 &if_resultisnotnumber); | 3035 &if_resultisnotnumber); |
3023 | 3036 |
3024 Bind(&if_resultisnumber); | 3037 Bind(&if_resultisnumber); |
3025 { | 3038 { |
3026 // The ToPrimitive conversion already gave us a Number, so we're done. | 3039 // The ToPrimitive conversion already gave us a Number, so we're done. |
3027 var_result.Bind(result); | 3040 var_result.Bind(result); |
3028 Goto(&end); | 3041 Goto(&end); |
3029 } | 3042 } |
(...skipping 21 matching lines...) Expand all Loading... |
3051 | 3064 |
3052 Bind(&end); | 3065 Bind(&end); |
3053 return var_result.value(); | 3066 return var_result.value(); |
3054 } | 3067 } |
3055 | 3068 |
3056 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) { | 3069 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) { |
3057 Variable var_result(this, MachineRepresentation::kTagged); | 3070 Variable var_result(this, MachineRepresentation::kTagged); |
3058 Label end(this); | 3071 Label end(this); |
3059 | 3072 |
3060 Label not_smi(this, Label::kDeferred); | 3073 Label not_smi(this, Label::kDeferred); |
3061 GotoUnless(WordIsSmi(input), ¬_smi); | 3074 GotoUnless(TaggedIsSmi(input), ¬_smi); |
3062 var_result.Bind(input); | 3075 var_result.Bind(input); |
3063 Goto(&end); | 3076 Goto(&end); |
3064 | 3077 |
3065 Bind(¬_smi); | 3078 Bind(¬_smi); |
3066 { | 3079 { |
3067 Label not_heap_number(this, Label::kDeferred); | 3080 Label not_heap_number(this, Label::kDeferred); |
3068 Node* input_map = LoadMap(input); | 3081 Node* input_map = LoadMap(input); |
3069 GotoIf(Word32NotEqual(input_map, HeapNumberMapConstant()), | 3082 GotoIf(Word32NotEqual(input_map, HeapNumberMapConstant()), |
3070 ¬_heap_number); | 3083 ¬_heap_number); |
3071 | 3084 |
(...skipping 20 matching lines...) Expand all Loading... |
3092 Goto(&loop); | 3105 Goto(&loop); |
3093 Bind(&loop); | 3106 Bind(&loop); |
3094 { | 3107 { |
3095 // Shared entry points. | 3108 // Shared entry points. |
3096 Label return_zero(this, Label::kDeferred); | 3109 Label return_zero(this, Label::kDeferred); |
3097 | 3110 |
3098 // Load the current {arg} value. | 3111 // Load the current {arg} value. |
3099 Node* arg = var_arg.value(); | 3112 Node* arg = var_arg.value(); |
3100 | 3113 |
3101 // Check if {arg} is a Smi. | 3114 // Check if {arg} is a Smi. |
3102 GotoIf(WordIsSmi(arg), &out); | 3115 GotoIf(TaggedIsSmi(arg), &out); |
3103 | 3116 |
3104 // Check if {arg} is a HeapNumber. | 3117 // Check if {arg} is a HeapNumber. |
3105 Label if_argisheapnumber(this), | 3118 Label if_argisheapnumber(this), |
3106 if_argisnotheapnumber(this, Label::kDeferred); | 3119 if_argisnotheapnumber(this, Label::kDeferred); |
3107 Branch(WordEqual(LoadMap(arg), HeapNumberMapConstant()), | 3120 Branch(WordEqual(LoadMap(arg), HeapNumberMapConstant()), |
3108 &if_argisheapnumber, &if_argisnotheapnumber); | 3121 &if_argisheapnumber, &if_argisnotheapnumber); |
3109 | 3122 |
3110 Bind(&if_argisheapnumber); | 3123 Bind(&if_argisheapnumber); |
3111 { | 3124 { |
3112 // Load the floating-point value of {arg}. | 3125 // Load the floating-point value of {arg}. |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3355 Node* count = var_count.value(); | 3368 Node* count = var_count.value(); |
3356 Node* entry = var_entry->value(); | 3369 Node* entry = var_entry->value(); |
3357 | 3370 |
3358 Node* index = EntryToIndex<Dictionary>(entry); | 3371 Node* index = EntryToIndex<Dictionary>(entry); |
3359 Node* current = | 3372 Node* current = |
3360 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); | 3373 LoadFixedArrayElement(dictionary, index, 0, INTPTR_PARAMETERS); |
3361 GotoIf(WordEqual(current, undefined), if_not_found); | 3374 GotoIf(WordEqual(current, undefined), if_not_found); |
3362 Label next_probe(this); | 3375 Label next_probe(this); |
3363 { | 3376 { |
3364 Label if_currentissmi(this), if_currentisnotsmi(this); | 3377 Label if_currentissmi(this), if_currentisnotsmi(this); |
3365 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); | 3378 Branch(TaggedIsSmi(current), &if_currentissmi, &if_currentisnotsmi); |
3366 Bind(&if_currentissmi); | 3379 Bind(&if_currentissmi); |
3367 { | 3380 { |
3368 Node* current_value = SmiUntag(current); | 3381 Node* current_value = SmiUntag(current); |
3369 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); | 3382 Branch(WordEqual(current_value, intptr_index), if_found, &next_probe); |
3370 } | 3383 } |
3371 Bind(&if_currentisnotsmi); | 3384 Bind(&if_currentisnotsmi); |
3372 { | 3385 { |
3373 GotoIf(WordEqual(current, the_hole), &next_probe); | 3386 GotoIf(WordEqual(current, the_hole), &next_probe); |
3374 // Current must be the Number. | 3387 // Current must be the Number. |
3375 Node* current_value = LoadHeapNumberValue(current); | 3388 Node* current_value = LoadHeapNumberValue(current); |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3872 Node*, Node*, Label*, Variable*, Label*); | 3885 Node*, Node*, Label*, Variable*, Label*); |
3873 template void CodeStubAssembler::NumberDictionaryLookup< | 3886 template void CodeStubAssembler::NumberDictionaryLookup< |
3874 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); | 3887 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); |
3875 | 3888 |
3876 void CodeStubAssembler::TryPrototypeChainLookup( | 3889 void CodeStubAssembler::TryPrototypeChainLookup( |
3877 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder, | 3890 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder, |
3878 LookupInHolder& lookup_element_in_holder, Label* if_end, | 3891 LookupInHolder& lookup_element_in_holder, Label* if_end, |
3879 Label* if_bailout) { | 3892 Label* if_bailout) { |
3880 // Ensure receiver is JSReceiver, otherwise bailout. | 3893 // Ensure receiver is JSReceiver, otherwise bailout. |
3881 Label if_objectisnotsmi(this); | 3894 Label if_objectisnotsmi(this); |
3882 Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi); | 3895 Branch(TaggedIsSmi(receiver), if_bailout, &if_objectisnotsmi); |
3883 Bind(&if_objectisnotsmi); | 3896 Bind(&if_objectisnotsmi); |
3884 | 3897 |
3885 Node* map = LoadMap(receiver); | 3898 Node* map = LoadMap(receiver); |
3886 Node* instance_type = LoadMapInstanceType(map); | 3899 Node* instance_type = LoadMapInstanceType(map); |
3887 { | 3900 { |
3888 Label if_objectisreceiver(this); | 3901 Label if_objectisreceiver(this); |
3889 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | 3902 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
3890 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); | 3903 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); |
3891 Branch( | 3904 Branch( |
3892 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), | 3905 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3982 } | 3995 } |
3983 } | 3996 } |
3984 | 3997 |
3985 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, | 3998 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
3986 Node* object) { | 3999 Node* object) { |
3987 Variable var_result(this, MachineRepresentation::kTagged); | 4000 Variable var_result(this, MachineRepresentation::kTagged); |
3988 Label return_false(this), return_true(this), | 4001 Label return_false(this), return_true(this), |
3989 return_runtime(this, Label::kDeferred), return_result(this); | 4002 return_runtime(this, Label::kDeferred), return_result(this); |
3990 | 4003 |
3991 // Goto runtime if {object} is a Smi. | 4004 // Goto runtime if {object} is a Smi. |
3992 GotoIf(WordIsSmi(object), &return_runtime); | 4005 GotoIf(TaggedIsSmi(object), &return_runtime); |
3993 | 4006 |
3994 // Load map of {object}. | 4007 // Load map of {object}. |
3995 Node* object_map = LoadMap(object); | 4008 Node* object_map = LoadMap(object); |
3996 | 4009 |
3997 // Lookup the {callable} and {object} map in the global instanceof cache. | 4010 // Lookup the {callable} and {object} map in the global instanceof cache. |
3998 // Note: This is safe because we clear the global instanceof cache whenever | 4011 // Note: This is safe because we clear the global instanceof cache whenever |
3999 // we change the prototype of any object. | 4012 // we change the prototype of any object. |
4000 Node* instanceof_cache_function = | 4013 Node* instanceof_cache_function = |
4001 LoadRoot(Heap::kInstanceofCacheFunctionRootIndex); | 4014 LoadRoot(Heap::kInstanceofCacheFunctionRootIndex); |
4002 Node* instanceof_cache_map = LoadRoot(Heap::kInstanceofCacheMapRootIndex); | 4015 Node* instanceof_cache_map = LoadRoot(Heap::kInstanceofCacheMapRootIndex); |
4003 { | 4016 { |
4004 Label instanceof_cache_miss(this); | 4017 Label instanceof_cache_miss(this); |
4005 GotoUnless(WordEqual(instanceof_cache_function, callable), | 4018 GotoUnless(WordEqual(instanceof_cache_function, callable), |
4006 &instanceof_cache_miss); | 4019 &instanceof_cache_miss); |
4007 GotoUnless(WordEqual(instanceof_cache_map, object_map), | 4020 GotoUnless(WordEqual(instanceof_cache_map, object_map), |
4008 &instanceof_cache_miss); | 4021 &instanceof_cache_miss); |
4009 var_result.Bind(LoadRoot(Heap::kInstanceofCacheAnswerRootIndex)); | 4022 var_result.Bind(LoadRoot(Heap::kInstanceofCacheAnswerRootIndex)); |
4010 Goto(&return_result); | 4023 Goto(&return_result); |
4011 Bind(&instanceof_cache_miss); | 4024 Bind(&instanceof_cache_miss); |
4012 } | 4025 } |
4013 | 4026 |
4014 // Goto runtime if {callable} is a Smi. | 4027 // Goto runtime if {callable} is a Smi. |
4015 GotoIf(WordIsSmi(callable), &return_runtime); | 4028 GotoIf(TaggedIsSmi(callable), &return_runtime); |
4016 | 4029 |
4017 // Load map of {callable}. | 4030 // Load map of {callable}. |
4018 Node* callable_map = LoadMap(callable); | 4031 Node* callable_map = LoadMap(callable); |
4019 | 4032 |
4020 // Goto runtime if {callable} is not a JSFunction. | 4033 // Goto runtime if {callable} is not a JSFunction. |
4021 Node* callable_instance_type = LoadMapInstanceType(callable_map); | 4034 Node* callable_instance_type = LoadMapInstanceType(callable_map); |
4022 GotoUnless( | 4035 GotoUnless( |
4023 Word32Equal(callable_instance_type, Int32Constant(JS_FUNCTION_TYPE)), | 4036 Word32Equal(callable_instance_type, Int32Constant(JS_FUNCTION_TYPE)), |
4024 &return_runtime); | 4037 &return_runtime); |
4025 | 4038 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4124 int base_size) { | 4137 int base_size) { |
4125 int element_size_shift = ElementsKindToShiftSize(kind); | 4138 int element_size_shift = ElementsKindToShiftSize(kind); |
4126 int element_size = 1 << element_size_shift; | 4139 int element_size = 1 << element_size_shift; |
4127 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; | 4140 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; |
4128 intptr_t index = 0; | 4141 intptr_t index = 0; |
4129 bool constant_index = false; | 4142 bool constant_index = false; |
4130 if (mode == SMI_PARAMETERS) { | 4143 if (mode == SMI_PARAMETERS) { |
4131 element_size_shift -= kSmiShiftBits; | 4144 element_size_shift -= kSmiShiftBits; |
4132 constant_index = ToIntPtrConstant(index_node, index); | 4145 constant_index = ToIntPtrConstant(index_node, index); |
4133 index = index >> kSmiShiftBits; | 4146 index = index >> kSmiShiftBits; |
| 4147 index_node = BitcastTaggedToWord(index_node); |
4134 } else if (mode == INTEGER_PARAMETERS) { | 4148 } else if (mode == INTEGER_PARAMETERS) { |
4135 int32_t temp = 0; | 4149 int32_t temp = 0; |
4136 constant_index = ToInt32Constant(index_node, temp); | 4150 constant_index = ToInt32Constant(index_node, temp); |
4137 index = static_cast<intptr_t>(temp); | 4151 index = static_cast<intptr_t>(temp); |
4138 } else { | 4152 } else { |
4139 DCHECK(mode == INTPTR_PARAMETERS); | 4153 DCHECK(mode == INTPTR_PARAMETERS); |
4140 constant_index = ToIntPtrConstant(index_node, index); | 4154 constant_index = ToIntPtrConstant(index_node, index); |
4141 } | 4155 } |
4142 if (constant_index) { | 4156 if (constant_index) { |
4143 return IntPtrConstant(base_size + element_size * index); | 4157 return IntPtrConstant(base_size + element_size * index); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4178 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, | 4192 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, |
4179 SKIP_WRITE_BARRIER); | 4193 SKIP_WRITE_BARRIER); |
4180 } | 4194 } |
4181 | 4195 |
4182 compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) { | 4196 compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) { |
4183 Variable var_receiver_map(this, MachineRepresentation::kTagged); | 4197 Variable var_receiver_map(this, MachineRepresentation::kTagged); |
4184 // TODO(ishell): defer blocks when it works. | 4198 // TODO(ishell): defer blocks when it works. |
4185 Label load_smi_map(this /*, Label::kDeferred*/), load_receiver_map(this), | 4199 Label load_smi_map(this /*, Label::kDeferred*/), load_receiver_map(this), |
4186 if_result(this); | 4200 if_result(this); |
4187 | 4201 |
4188 Branch(WordIsSmi(receiver), &load_smi_map, &load_receiver_map); | 4202 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map); |
4189 Bind(&load_smi_map); | 4203 Bind(&load_smi_map); |
4190 { | 4204 { |
4191 var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex)); | 4205 var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex)); |
4192 Goto(&if_result); | 4206 Goto(&if_result); |
4193 } | 4207 } |
4194 Bind(&load_receiver_map); | 4208 Bind(&load_receiver_map); |
4195 { | 4209 { |
4196 var_receiver_map.Bind(LoadMap(receiver)); | 4210 var_receiver_map.Bind(LoadMap(receiver)); |
4197 Goto(&if_result); | 4211 Goto(&if_result); |
4198 } | 4212 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4360 | 4374 |
4361 void CodeStubAssembler::TryProbeStubCache( | 4375 void CodeStubAssembler::TryProbeStubCache( |
4362 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, | 4376 StubCache* stub_cache, compiler::Node* receiver, compiler::Node* name, |
4363 Label* if_handler, Variable* var_handler, Label* if_miss) { | 4377 Label* if_handler, Variable* var_handler, Label* if_miss) { |
4364 Label try_secondary(this), miss(this); | 4378 Label try_secondary(this), miss(this); |
4365 | 4379 |
4366 Counters* counters = isolate()->counters(); | 4380 Counters* counters = isolate()->counters(); |
4367 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); | 4381 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); |
4368 | 4382 |
4369 // Check that the {receiver} isn't a smi. | 4383 // Check that the {receiver} isn't a smi. |
4370 GotoIf(WordIsSmi(receiver), &miss); | 4384 GotoIf(TaggedIsSmi(receiver), &miss); |
4371 | 4385 |
4372 Node* receiver_map = LoadMap(receiver); | 4386 Node* receiver_map = LoadMap(receiver); |
4373 | 4387 |
4374 // Probe the primary table. | 4388 // Probe the primary table. |
4375 Node* primary_offset = StubCachePrimaryOffset(name, receiver_map); | 4389 Node* primary_offset = StubCachePrimaryOffset(name, receiver_map); |
4376 TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, | 4390 TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, |
4377 receiver_map, if_handler, var_handler, &try_secondary); | 4391 receiver_map, if_handler, var_handler, &try_secondary); |
4378 | 4392 |
4379 Bind(&try_secondary); | 4393 Bind(&try_secondary); |
4380 { | 4394 { |
4381 // Probe the secondary table. | 4395 // Probe the secondary table. |
4382 Node* secondary_offset = StubCacheSecondaryOffset(name, primary_offset); | 4396 Node* secondary_offset = StubCacheSecondaryOffset(name, primary_offset); |
4383 TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name, | 4397 TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name, |
4384 receiver_map, if_handler, var_handler, &miss); | 4398 receiver_map, if_handler, var_handler, &miss); |
4385 } | 4399 } |
4386 | 4400 |
4387 Bind(&miss); | 4401 Bind(&miss); |
4388 { | 4402 { |
4389 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); | 4403 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); |
4390 Goto(if_miss); | 4404 Goto(if_miss); |
4391 } | 4405 } |
4392 } | 4406 } |
4393 | 4407 |
4394 Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) { | 4408 Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) { |
4395 Variable var_intptr_key(this, MachineType::PointerRepresentation()); | 4409 Variable var_intptr_key(this, MachineType::PointerRepresentation()); |
4396 Label done(this, &var_intptr_key), key_is_smi(this); | 4410 Label done(this, &var_intptr_key), key_is_smi(this); |
4397 GotoIf(WordIsSmi(key), &key_is_smi); | 4411 GotoIf(TaggedIsSmi(key), &key_is_smi); |
4398 // Try to convert a heap number to a Smi. | 4412 // Try to convert a heap number to a Smi. |
4399 GotoUnless(WordEqual(LoadMap(key), HeapNumberMapConstant()), miss); | 4413 GotoUnless(WordEqual(LoadMap(key), HeapNumberMapConstant()), miss); |
4400 { | 4414 { |
4401 Node* value = LoadHeapNumberValue(key); | 4415 Node* value = LoadHeapNumberValue(key); |
4402 Node* int_value = RoundFloat64ToInt32(value); | 4416 Node* int_value = RoundFloat64ToInt32(value); |
4403 GotoUnless(Float64Equal(value, ChangeInt32ToFloat64(int_value)), miss); | 4417 GotoUnless(Float64Equal(value, ChangeInt32ToFloat64(int_value)), miss); |
4404 var_intptr_key.Bind(ChangeInt32ToIntPtr(int_value)); | 4418 var_intptr_key.Bind(ChangeInt32ToIntPtr(int_value)); |
4405 Goto(&done); | 4419 Goto(&done); |
4406 } | 4420 } |
4407 | 4421 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4634 Goto(rebox_double); | 4648 Goto(rebox_double); |
4635 } | 4649 } |
4636 } | 4650 } |
4637 } | 4651 } |
4638 | 4652 |
4639 void CodeStubAssembler::HandleLoadICHandlerCase( | 4653 void CodeStubAssembler::HandleLoadICHandlerCase( |
4640 const LoadICParameters* p, Node* handler, Label* miss, | 4654 const LoadICParameters* p, Node* handler, Label* miss, |
4641 ElementSupport support_elements) { | 4655 ElementSupport support_elements) { |
4642 Comment("have_handler"); | 4656 Comment("have_handler"); |
4643 Label call_handler(this); | 4657 Label call_handler(this); |
4644 GotoUnless(WordIsSmi(handler), &call_handler); | 4658 GotoUnless(TaggedIsSmi(handler), &call_handler); |
4645 | 4659 |
4646 // |handler| is a Smi, encoding what to do. See handler-configuration.h | 4660 // |handler| is a Smi, encoding what to do. See handler-configuration.h |
4647 // for the encoding format. | 4661 // for the encoding format. |
4648 { | 4662 { |
4649 Variable var_double_value(this, MachineRepresentation::kFloat64); | 4663 Variable var_double_value(this, MachineRepresentation::kFloat64); |
4650 Label rebox_double(this, &var_double_value); | 4664 Label rebox_double(this, &var_double_value); |
4651 | 4665 |
4652 Node* handler_word = SmiUntag(handler); | 4666 Node* handler_word = SmiUntag(handler); |
4653 if (support_elements == kSupportElements) { | 4667 if (support_elements == kSupportElements) { |
4654 Label property(this); | 4668 Label property(this); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4859 | 4873 |
4860 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { | 4874 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
4861 Variable var_index(this, MachineType::PointerRepresentation()); | 4875 Variable var_index(this, MachineType::PointerRepresentation()); |
4862 Variable var_details(this, MachineRepresentation::kWord32); | 4876 Variable var_details(this, MachineRepresentation::kWord32); |
4863 Variable var_value(this, MachineRepresentation::kTagged); | 4877 Variable var_value(this, MachineRepresentation::kTagged); |
4864 Label if_index(this), if_unique_name(this), if_element_hole(this), | 4878 Label if_index(this), if_unique_name(this), if_element_hole(this), |
4865 if_oob(this), slow(this), stub_cache_miss(this), | 4879 if_oob(this), slow(this), stub_cache_miss(this), |
4866 if_property_dictionary(this), if_found_on_receiver(this); | 4880 if_property_dictionary(this), if_found_on_receiver(this); |
4867 | 4881 |
4868 Node* receiver = p->receiver; | 4882 Node* receiver = p->receiver; |
4869 GotoIf(WordIsSmi(receiver), &slow); | 4883 GotoIf(TaggedIsSmi(receiver), &slow); |
4870 Node* receiver_map = LoadMap(receiver); | 4884 Node* receiver_map = LoadMap(receiver); |
4871 Node* instance_type = LoadMapInstanceType(receiver_map); | 4885 Node* instance_type = LoadMapInstanceType(receiver_map); |
4872 // Receivers requiring non-standard element accesses (interceptors, access | 4886 // Receivers requiring non-standard element accesses (interceptors, access |
4873 // checks, strings and string wrappers, proxies) are handled in the runtime. | 4887 // checks, strings and string wrappers, proxies) are handled in the runtime. |
4874 GotoIf(Int32LessThanOrEqual(instance_type, | 4888 GotoIf(Int32LessThanOrEqual(instance_type, |
4875 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), | 4889 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
4876 &slow); | 4890 &slow); |
4877 | 4891 |
4878 Node* key = p->name; | 4892 Node* key = p->name; |
4879 TryToName(key, &if_index, &var_index, &if_unique_name, &slow); | 4893 TryToName(key, &if_index, &var_index, &if_unique_name, &slow); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5130 | 5144 |
5131 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); | 5145 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); |
5132 } | 5146 } |
5133 | 5147 |
5134 Node* CodeStubAssembler::PrepareValueForWrite(Node* value, | 5148 Node* CodeStubAssembler::PrepareValueForWrite(Node* value, |
5135 Representation representation, | 5149 Representation representation, |
5136 Label* bailout) { | 5150 Label* bailout) { |
5137 if (representation.IsDouble()) { | 5151 if (representation.IsDouble()) { |
5138 Variable var_value(this, MachineRepresentation::kFloat64); | 5152 Variable var_value(this, MachineRepresentation::kFloat64); |
5139 Label if_smi(this), if_heap_object(this), done(this); | 5153 Label if_smi(this), if_heap_object(this), done(this); |
5140 Branch(WordIsSmi(value), &if_smi, &if_heap_object); | 5154 Branch(TaggedIsSmi(value), &if_smi, &if_heap_object); |
5141 Bind(&if_smi); | 5155 Bind(&if_smi); |
5142 { | 5156 { |
5143 var_value.Bind(SmiToFloat64(value)); | 5157 var_value.Bind(SmiToFloat64(value)); |
5144 Goto(&done); | 5158 Goto(&done); |
5145 } | 5159 } |
5146 Bind(&if_heap_object); | 5160 Bind(&if_heap_object); |
5147 { | 5161 { |
5148 GotoUnless( | 5162 GotoUnless( |
5149 Word32Equal(LoadInstanceType(value), Int32Constant(HEAP_NUMBER_TYPE)), | 5163 Word32Equal(LoadInstanceType(value), Int32Constant(HEAP_NUMBER_TYPE)), |
5150 bailout); | 5164 bailout); |
5151 var_value.Bind(LoadHeapNumberValue(value)); | 5165 var_value.Bind(LoadHeapNumberValue(value)); |
5152 Goto(&done); | 5166 Goto(&done); |
5153 } | 5167 } |
5154 Bind(&done); | 5168 Bind(&done); |
5155 value = var_value.value(); | 5169 value = var_value.value(); |
5156 } else if (representation.IsHeapObject()) { | 5170 } else if (representation.IsHeapObject()) { |
5157 // Field type is checked by the handler, here we only check if the value | 5171 // Field type is checked by the handler, here we only check if the value |
5158 // is a heap object. | 5172 // is a heap object. |
5159 GotoIf(WordIsSmi(value), bailout); | 5173 GotoIf(TaggedIsSmi(value), bailout); |
5160 } else if (representation.IsSmi()) { | 5174 } else if (representation.IsSmi()) { |
5161 GotoUnless(WordIsSmi(value), bailout); | 5175 GotoUnless(TaggedIsSmi(value), bailout); |
5162 } else { | 5176 } else { |
5163 DCHECK(representation.IsTagged()); | 5177 DCHECK(representation.IsTagged()); |
5164 } | 5178 } |
5165 return value; | 5179 return value; |
5166 } | 5180 } |
5167 | 5181 |
5168 void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index, | 5182 void CodeStubAssembler::StoreNamedField(Node* object, FieldIndex index, |
5169 Representation representation, | 5183 Representation representation, |
5170 Node* value, bool transition_to_field) { | 5184 Node* value, bool transition_to_field) { |
5171 DCHECK_EQ(index.is_double(), representation.IsDouble()); | 5185 DCHECK_EQ(index.is_double(), representation.IsDouble()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5233 // to the runtime if the unmapped arguments array is not a fixed array or if | 5247 // to the runtime if the unmapped arguments array is not a fixed array or if |
5234 // key >= unmapped_arguments_array.length. | 5248 // key >= unmapped_arguments_array.length. |
5235 // | 5249 // |
5236 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value | 5250 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value |
5237 // in the unmapped arguments array, as described above. Otherwise, t is a Smi | 5251 // in the unmapped arguments array, as described above. Otherwise, t is a Smi |
5238 // index into the context array given at elements[0]. Return the value at | 5252 // index into the context array given at elements[0]. Return the value at |
5239 // context[t]. | 5253 // context[t]. |
5240 | 5254 |
5241 bool is_load = value == nullptr; | 5255 bool is_load = value == nullptr; |
5242 | 5256 |
5243 GotoUnless(WordIsSmi(key), bailout); | 5257 GotoUnless(TaggedIsSmi(key), bailout); |
5244 key = SmiUntag(key); | 5258 key = SmiUntag(key); |
5245 GotoIf(IntPtrLessThan(key, IntPtrConstant(0)), bailout); | 5259 GotoIf(IntPtrLessThan(key, IntPtrConstant(0)), bailout); |
5246 | 5260 |
5247 Node* elements = LoadElements(receiver); | 5261 Node* elements = LoadElements(receiver); |
5248 Node* elements_length = LoadAndUntagFixedArrayBaseLength(elements); | 5262 Node* elements_length = LoadAndUntagFixedArrayBaseLength(elements); |
5249 | 5263 |
5250 Variable var_result(this, MachineRepresentation::kTagged); | 5264 Variable var_result(this, MachineRepresentation::kTagged); |
5251 if (!is_load) { | 5265 if (!is_load) { |
5252 var_result.Bind(value); | 5266 var_result.Bind(value); |
5253 } | 5267 } |
5254 Label if_mapped(this), if_unmapped(this), end(this, &var_result); | 5268 Label if_mapped(this), if_unmapped(this), end(this, &var_result); |
5255 Node* intptr_two = IntPtrConstant(2); | 5269 Node* intptr_two = IntPtrConstant(2); |
5256 Node* adjusted_length = IntPtrSub(elements_length, intptr_two); | 5270 Node* adjusted_length = IntPtrSub(elements_length, intptr_two); |
5257 | 5271 |
5258 GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped); | 5272 GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped); |
5259 | 5273 |
5260 Node* mapped_index = LoadFixedArrayElement( | 5274 Node* mapped_index = LoadFixedArrayElement( |
5261 elements, IntPtrAdd(key, intptr_two), 0, INTPTR_PARAMETERS); | 5275 elements, IntPtrAdd(key, intptr_two), 0, INTPTR_PARAMETERS); |
5262 Branch(WordEqual(mapped_index, TheHoleConstant()), &if_unmapped, &if_mapped); | 5276 Branch(WordEqual(mapped_index, TheHoleConstant()), &if_unmapped, &if_mapped); |
5263 | 5277 |
5264 Bind(&if_mapped); | 5278 Bind(&if_mapped); |
5265 { | 5279 { |
5266 Assert(WordIsSmi(mapped_index)); | 5280 Assert(TaggedIsSmi(mapped_index)); |
5267 mapped_index = SmiUntag(mapped_index); | 5281 mapped_index = SmiUntag(mapped_index); |
5268 Node* the_context = LoadFixedArrayElement(elements, IntPtrConstant(0), 0, | 5282 Node* the_context = LoadFixedArrayElement(elements, IntPtrConstant(0), 0, |
5269 INTPTR_PARAMETERS); | 5283 INTPTR_PARAMETERS); |
5270 // Assert that we can use LoadFixedArrayElement/StoreFixedArrayElement | 5284 // Assert that we can use LoadFixedArrayElement/StoreFixedArrayElement |
5271 // methods for accessing Context. | 5285 // methods for accessing Context. |
5272 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); | 5286 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); |
5273 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, | 5287 DCHECK_EQ(Context::SlotOffset(0) + kHeapObjectTag, |
5274 FixedArray::OffsetOfElementAt(0)); | 5288 FixedArray::OffsetOfElementAt(0)); |
5275 if (is_load) { | 5289 if (is_load) { |
5276 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, | 5290 Node* result = LoadFixedArrayElement(the_context, mapped_index, 0, |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5465 IsFastDoubleElementsKind(elements_kind)); | 5479 IsFastDoubleElementsKind(elements_kind)); |
5466 | 5480 |
5467 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset) | 5481 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset) |
5468 : LoadFixedArrayBaseLength(elements); | 5482 : LoadFixedArrayBaseLength(elements); |
5469 length = UntagParameter(length, parameter_mode); | 5483 length = UntagParameter(length, parameter_mode); |
5470 | 5484 |
5471 // In case value is stored into a fast smi array, assure that the value is | 5485 // In case value is stored into a fast smi array, assure that the value is |
5472 // a smi before manipulating the backing store. Otherwise the backing store | 5486 // a smi before manipulating the backing store. Otherwise the backing store |
5473 // may be left in an invalid state. | 5487 // may be left in an invalid state. |
5474 if (IsFastSmiElementsKind(elements_kind)) { | 5488 if (IsFastSmiElementsKind(elements_kind)) { |
5475 GotoUnless(WordIsSmi(value), bailout); | 5489 GotoUnless(TaggedIsSmi(value), bailout); |
5476 } else if (IsFastDoubleElementsKind(elements_kind)) { | 5490 } else if (IsFastDoubleElementsKind(elements_kind)) { |
5477 value = PrepareValueForWrite(value, Representation::Double(), bailout); | 5491 value = PrepareValueForWrite(value, Representation::Double(), bailout); |
5478 } | 5492 } |
5479 | 5493 |
5480 if (IsGrowStoreMode(store_mode)) { | 5494 if (IsGrowStoreMode(store_mode)) { |
5481 elements = CheckForCapacityGrow(object, elements, elements_kind, length, | 5495 elements = CheckForCapacityGrow(object, elements, elements_kind, length, |
5482 key, parameter_mode, is_jsarray, bailout); | 5496 key, parameter_mode, is_jsarray, bailout); |
5483 } else { | 5497 } else { |
5484 GotoUnless(UintPtrLessThan(key, length), bailout); | 5498 GotoUnless(UintPtrLessThan(key, length), bailout); |
5485 | 5499 |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5907 var_rhs.Bind(rhs); | 5921 var_rhs.Bind(rhs); |
5908 Goto(&loop); | 5922 Goto(&loop); |
5909 Bind(&loop); | 5923 Bind(&loop); |
5910 { | 5924 { |
5911 // Load the current {lhs} and {rhs} values. | 5925 // Load the current {lhs} and {rhs} values. |
5912 lhs = var_lhs.value(); | 5926 lhs = var_lhs.value(); |
5913 rhs = var_rhs.value(); | 5927 rhs = var_rhs.value(); |
5914 | 5928 |
5915 // Check if the {lhs} is a Smi or a HeapObject. | 5929 // Check if the {lhs} is a Smi or a HeapObject. |
5916 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 5930 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
5917 Branch(WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 5931 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
5918 | 5932 |
5919 Bind(&if_lhsissmi); | 5933 Bind(&if_lhsissmi); |
5920 { | 5934 { |
5921 // Check if {rhs} is a Smi or a HeapObject. | 5935 // Check if {rhs} is a Smi or a HeapObject. |
5922 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 5936 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
5923 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 5937 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
5924 | 5938 |
5925 Bind(&if_rhsissmi); | 5939 Bind(&if_rhsissmi); |
5926 { | 5940 { |
5927 // Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison. | 5941 // Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison. |
5928 switch (mode) { | 5942 switch (mode) { |
5929 case kLessThan: | 5943 case kLessThan: |
5930 BranchIfSmiLessThan(lhs, rhs, &return_true, &return_false); | 5944 BranchIfSmiLessThan(lhs, rhs, &return_true, &return_false); |
5931 break; | 5945 break; |
5932 case kLessThanOrEqual: | 5946 case kLessThanOrEqual: |
5933 BranchIfSmiLessThanOrEqual(lhs, rhs, &return_true, &return_false); | 5947 BranchIfSmiLessThanOrEqual(lhs, rhs, &return_true, &return_false); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5975 Bind(&if_lhsisnotsmi); | 5989 Bind(&if_lhsisnotsmi); |
5976 { | 5990 { |
5977 // Load the HeapNumber map for later comparisons. | 5991 // Load the HeapNumber map for later comparisons. |
5978 Node* number_map = HeapNumberMapConstant(); | 5992 Node* number_map = HeapNumberMapConstant(); |
5979 | 5993 |
5980 // Load the map of {lhs}. | 5994 // Load the map of {lhs}. |
5981 Node* lhs_map = LoadMap(lhs); | 5995 Node* lhs_map = LoadMap(lhs); |
5982 | 5996 |
5983 // Check if {rhs} is a Smi or a HeapObject. | 5997 // Check if {rhs} is a Smi or a HeapObject. |
5984 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 5998 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
5985 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 5999 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
5986 | 6000 |
5987 Bind(&if_rhsissmi); | 6001 Bind(&if_rhsissmi); |
5988 { | 6002 { |
5989 // Check if the {lhs} is a HeapNumber. | 6003 // Check if the {lhs} is a HeapNumber. |
5990 Label if_lhsisnumber(this), if_lhsisnotnumber(this, Label::kDeferred); | 6004 Label if_lhsisnumber(this), if_lhsisnotnumber(this, Label::kDeferred); |
5991 Branch(WordEqual(lhs_map, number_map), &if_lhsisnumber, | 6005 Branch(WordEqual(lhs_map, number_map), &if_lhsisnumber, |
5992 &if_lhsisnotnumber); | 6006 &if_lhsisnotnumber); |
5993 | 6007 |
5994 Bind(&if_lhsisnumber); | 6008 Bind(&if_lhsisnumber); |
5995 { | 6009 { |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6216 // for NaN values because they are not considered equal, even if both the | 6230 // for NaN values because they are not considered equal, even if both the |
6217 // left and the right hand side reference exactly the same value. | 6231 // left and the right hand side reference exactly the same value. |
6218 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it | 6232 // TODO(bmeurer): This seems to violate the SIMD.js specification, but it |
6219 // seems to be what is tested in the current SIMD.js testsuite. | 6233 // seems to be what is tested in the current SIMD.js testsuite. |
6220 | 6234 |
6221 typedef CodeStubAssembler::Label Label; | 6235 typedef CodeStubAssembler::Label Label; |
6222 typedef compiler::Node Node; | 6236 typedef compiler::Node Node; |
6223 | 6237 |
6224 // Check if {value} is a Smi or a HeapObject. | 6238 // Check if {value} is a Smi or a HeapObject. |
6225 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); | 6239 Label if_valueissmi(assembler), if_valueisnotsmi(assembler); |
6226 assembler->Branch(assembler->WordIsSmi(value), &if_valueissmi, | 6240 assembler->Branch(assembler->TaggedIsSmi(value), &if_valueissmi, |
6227 &if_valueisnotsmi); | 6241 &if_valueisnotsmi); |
6228 | 6242 |
6229 assembler->Bind(&if_valueisnotsmi); | 6243 assembler->Bind(&if_valueisnotsmi); |
6230 { | 6244 { |
6231 // Load the map of {value}. | 6245 // Load the map of {value}. |
6232 Node* value_map = assembler->LoadMap(value); | 6246 Node* value_map = assembler->LoadMap(value); |
6233 | 6247 |
6234 // Check if {value} (and therefore {rhs}) is a HeapNumber. | 6248 // Check if {value} (and therefore {rhs}) is a HeapNumber. |
6235 Label if_valueisnumber(assembler), if_valueisnotnumber(assembler); | 6249 Label if_valueisnumber(assembler), if_valueisnotnumber(assembler); |
6236 assembler->Branch(assembler->IsHeapNumberMap(value_map), &if_valueisnumber, | 6250 assembler->Branch(assembler->IsHeapNumberMap(value_map), &if_valueisnumber, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6305 { | 6319 { |
6306 // The {lhs} and {rhs} reference the exact same value, yet we need special | 6320 // The {lhs} and {rhs} reference the exact same value, yet we need special |
6307 // treatment for HeapNumber, as NaN is not equal to NaN. | 6321 // treatment for HeapNumber, as NaN is not equal to NaN. |
6308 GenerateEqual_Same(this, lhs, &if_equal, &if_notequal); | 6322 GenerateEqual_Same(this, lhs, &if_equal, &if_notequal); |
6309 } | 6323 } |
6310 | 6324 |
6311 Bind(&if_notsame); | 6325 Bind(&if_notsame); |
6312 { | 6326 { |
6313 // Check if {lhs} is a Smi or a HeapObject. | 6327 // Check if {lhs} is a Smi or a HeapObject. |
6314 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 6328 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
6315 Branch(WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 6329 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
6316 | 6330 |
6317 Bind(&if_lhsissmi); | 6331 Bind(&if_lhsissmi); |
6318 { | 6332 { |
6319 // Check if {rhs} is a Smi or a HeapObject. | 6333 // Check if {rhs} is a Smi or a HeapObject. |
6320 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 6334 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
6321 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 6335 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
6322 | 6336 |
6323 Bind(&if_rhsissmi); | 6337 Bind(&if_rhsissmi); |
6324 // We have already checked for {lhs} and {rhs} being the same value, so | 6338 // We have already checked for {lhs} and {rhs} being the same value, so |
6325 // if both are Smis when we get here they must not be equal. | 6339 // if both are Smis when we get here they must not be equal. |
6326 Goto(&if_notequal); | 6340 Goto(&if_notequal); |
6327 | 6341 |
6328 Bind(&if_rhsisnotsmi); | 6342 Bind(&if_rhsisnotsmi); |
6329 { | 6343 { |
6330 // Load the map of {rhs}. | 6344 // Load the map of {rhs}. |
6331 Node* rhs_map = LoadMap(rhs); | 6345 Node* rhs_map = LoadMap(rhs); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6401 } | 6415 } |
6402 } | 6416 } |
6403 } | 6417 } |
6404 } | 6418 } |
6405 } | 6419 } |
6406 | 6420 |
6407 Bind(&if_lhsisnotsmi); | 6421 Bind(&if_lhsisnotsmi); |
6408 { | 6422 { |
6409 // Check if {rhs} is a Smi or a HeapObject. | 6423 // Check if {rhs} is a Smi or a HeapObject. |
6410 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 6424 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
6411 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 6425 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
6412 | 6426 |
6413 Bind(&if_rhsissmi); | 6427 Bind(&if_rhsissmi); |
6414 { | 6428 { |
6415 // The {lhs} is a HeapObject and the {rhs} is a Smi; swapping {lhs} | 6429 // The {lhs} is a HeapObject and the {rhs} is a Smi; swapping {lhs} |
6416 // and {rhs} is not observable and doesn't matter for the result, so | 6430 // and {rhs} is not observable and doesn't matter for the result, so |
6417 // we can just swap them and use the Smi handling above (for {lhs} | 6431 // we can just swap them and use the Smi handling above (for {lhs} |
6418 // being a Smi). | 6432 // being a Smi). |
6419 var_lhs.Bind(rhs); | 6433 var_lhs.Bind(rhs); |
6420 var_rhs.Bind(lhs); | 6434 var_rhs.Bind(lhs); |
6421 Goto(&loop); | 6435 Goto(&loop); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6832 } | 6846 } |
6833 | 6847 |
6834 Bind(&if_notsame); | 6848 Bind(&if_notsame); |
6835 { | 6849 { |
6836 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber, | 6850 // The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber, |
6837 // String and Simd128Value they can still be considered equal. | 6851 // String and Simd128Value they can still be considered equal. |
6838 Node* number_map = HeapNumberMapConstant(); | 6852 Node* number_map = HeapNumberMapConstant(); |
6839 | 6853 |
6840 // Check if {lhs} is a Smi or a HeapObject. | 6854 // Check if {lhs} is a Smi or a HeapObject. |
6841 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 6855 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
6842 Branch(WordIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); | 6856 Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi); |
6843 | 6857 |
6844 Bind(&if_lhsisnotsmi); | 6858 Bind(&if_lhsisnotsmi); |
6845 { | 6859 { |
6846 // Load the map of {lhs}. | 6860 // Load the map of {lhs}. |
6847 Node* lhs_map = LoadMap(lhs); | 6861 Node* lhs_map = LoadMap(lhs); |
6848 | 6862 |
6849 // Check if {lhs} is a HeapNumber. | 6863 // Check if {lhs} is a HeapNumber. |
6850 Label if_lhsisnumber(this), if_lhsisnotnumber(this); | 6864 Label if_lhsisnumber(this), if_lhsisnotnumber(this); |
6851 Branch(WordEqual(lhs_map, number_map), &if_lhsisnumber, | 6865 Branch(WordEqual(lhs_map, number_map), &if_lhsisnumber, |
6852 &if_lhsisnotnumber); | 6866 &if_lhsisnotnumber); |
6853 | 6867 |
6854 Bind(&if_lhsisnumber); | 6868 Bind(&if_lhsisnumber); |
6855 { | 6869 { |
6856 // Check if {rhs} is a Smi or a HeapObject. | 6870 // Check if {rhs} is a Smi or a HeapObject. |
6857 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 6871 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
6858 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 6872 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
6859 | 6873 |
6860 Bind(&if_rhsissmi); | 6874 Bind(&if_rhsissmi); |
6861 { | 6875 { |
6862 // Convert {lhs} and {rhs} to floating point values. | 6876 // Convert {lhs} and {rhs} to floating point values. |
6863 Node* lhs_value = LoadHeapNumberValue(lhs); | 6877 Node* lhs_value = LoadHeapNumberValue(lhs); |
6864 Node* rhs_value = SmiToFloat64(rhs); | 6878 Node* rhs_value = SmiToFloat64(rhs); |
6865 | 6879 |
6866 // Perform a floating point comparison of {lhs} and {rhs}. | 6880 // Perform a floating point comparison of {lhs} and {rhs}. |
6867 BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal, &if_notequal); | 6881 BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal, &if_notequal); |
6868 } | 6882 } |
(...skipping 20 matching lines...) Expand all Loading... |
6889 | 6903 |
6890 Bind(&if_rhsisnotnumber); | 6904 Bind(&if_rhsisnotnumber); |
6891 Goto(&if_notequal); | 6905 Goto(&if_notequal); |
6892 } | 6906 } |
6893 } | 6907 } |
6894 | 6908 |
6895 Bind(&if_lhsisnotnumber); | 6909 Bind(&if_lhsisnotnumber); |
6896 { | 6910 { |
6897 // Check if {rhs} is a Smi or a HeapObject. | 6911 // Check if {rhs} is a Smi or a HeapObject. |
6898 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 6912 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
6899 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 6913 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
6900 | 6914 |
6901 Bind(&if_rhsissmi); | 6915 Bind(&if_rhsissmi); |
6902 Goto(&if_notequal); | 6916 Goto(&if_notequal); |
6903 | 6917 |
6904 Bind(&if_rhsisnotsmi); | 6918 Bind(&if_rhsisnotsmi); |
6905 { | 6919 { |
6906 // Load the instance type of {lhs}. | 6920 // Load the instance type of {lhs}. |
6907 Node* lhs_instance_type = LoadMapInstanceType(lhs_map); | 6921 Node* lhs_instance_type = LoadMapInstanceType(lhs_map); |
6908 | 6922 |
6909 // Check if {lhs} is a String. | 6923 // Check if {lhs} is a String. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6961 } | 6975 } |
6962 | 6976 |
6963 Bind(&if_lhsissmi); | 6977 Bind(&if_lhsissmi); |
6964 { | 6978 { |
6965 // We already know that {lhs} and {rhs} are not reference equal, and {lhs} | 6979 // We already know that {lhs} and {rhs} are not reference equal, and {lhs} |
6966 // is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a | 6980 // is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a |
6967 // HeapNumber with an equal floating point value. | 6981 // HeapNumber with an equal floating point value. |
6968 | 6982 |
6969 // Check if {rhs} is a Smi or a HeapObject. | 6983 // Check if {rhs} is a Smi or a HeapObject. |
6970 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 6984 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
6971 Branch(WordIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 6985 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
6972 | 6986 |
6973 Bind(&if_rhsissmi); | 6987 Bind(&if_rhsissmi); |
6974 Goto(&if_notequal); | 6988 Goto(&if_notequal); |
6975 | 6989 |
6976 Bind(&if_rhsisnotsmi); | 6990 Bind(&if_rhsisnotsmi); |
6977 { | 6991 { |
6978 // Load the map of the {rhs}. | 6992 // Load the map of the {rhs}. |
6979 Node* rhs_map = LoadMap(rhs); | 6993 Node* rhs_map = LoadMap(rhs); |
6980 | 6994 |
6981 // The {rhs} could be a HeapNumber with the same value as {lhs}. | 6995 // The {rhs} could be a HeapNumber with the same value as {lhs}. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7100 } | 7114 } |
7101 | 7115 |
7102 compiler::Node* CodeStubAssembler::Typeof(compiler::Node* value, | 7116 compiler::Node* CodeStubAssembler::Typeof(compiler::Node* value, |
7103 compiler::Node* context) { | 7117 compiler::Node* context) { |
7104 Variable result_var(this, MachineRepresentation::kTagged); | 7118 Variable result_var(this, MachineRepresentation::kTagged); |
7105 | 7119 |
7106 Label return_number(this, Label::kDeferred), if_oddball(this), | 7120 Label return_number(this, Label::kDeferred), if_oddball(this), |
7107 return_function(this), return_undefined(this), return_object(this), | 7121 return_function(this), return_undefined(this), return_object(this), |
7108 return_string(this), return_result(this); | 7122 return_string(this), return_result(this); |
7109 | 7123 |
7110 GotoIf(WordIsSmi(value), &return_number); | 7124 GotoIf(TaggedIsSmi(value), &return_number); |
7111 | 7125 |
7112 Node* map = LoadMap(value); | 7126 Node* map = LoadMap(value); |
7113 | 7127 |
7114 GotoIf(IsHeapNumberMap(map), &return_number); | 7128 GotoIf(IsHeapNumberMap(map), &return_number); |
7115 | 7129 |
7116 Node* instance_type = LoadMapInstanceType(map); | 7130 Node* instance_type = LoadMapInstanceType(map); |
7117 | 7131 |
7118 GotoIf(Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE)), &if_oddball); | 7132 GotoIf(Word32Equal(instance_type, Int32Constant(ODDBALL_TYPE)), &if_oddball); |
7119 | 7133 |
7120 Node* callable_or_undetectable_mask = Word32And( | 7134 Node* callable_or_undetectable_mask = Word32And( |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7200 Variable result(this, MachineRepresentation::kTagged); | 7214 Variable result(this, MachineRepresentation::kTagged); |
7201 | 7215 |
7202 // Check if no one installed @@hasInstance somewhere. | 7216 // Check if no one installed @@hasInstance somewhere. |
7203 GotoUnless( | 7217 GotoUnless( |
7204 WordEqual(LoadObjectField(LoadRoot(Heap::kHasInstanceProtectorRootIndex), | 7218 WordEqual(LoadObjectField(LoadRoot(Heap::kHasInstanceProtectorRootIndex), |
7205 PropertyCell::kValueOffset), | 7219 PropertyCell::kValueOffset), |
7206 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), | 7220 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), |
7207 &return_runtime); | 7221 &return_runtime); |
7208 | 7222 |
7209 // Check if {callable} is a valid receiver. | 7223 // Check if {callable} is a valid receiver. |
7210 GotoIf(WordIsSmi(callable), &return_runtime); | 7224 GotoIf(TaggedIsSmi(callable), &return_runtime); |
7211 GotoIf(Word32Equal(Word32And(LoadMapBitField(LoadMap(callable)), | 7225 GotoIf(Word32Equal(Word32And(LoadMapBitField(LoadMap(callable)), |
7212 Int32Constant(1 << Map::kIsCallable)), | 7226 Int32Constant(1 << Map::kIsCallable)), |
7213 Int32Constant(0)), | 7227 Int32Constant(0)), |
7214 &return_runtime); | 7228 &return_runtime); |
7215 | 7229 |
7216 // Use the inline OrdinaryHasInstance directly. | 7230 // Use the inline OrdinaryHasInstance directly. |
7217 result.Bind(OrdinaryHasInstance(context, callable, object)); | 7231 result.Bind(OrdinaryHasInstance(context, callable, object)); |
7218 Goto(&end); | 7232 Goto(&end); |
7219 | 7233 |
7220 // TODO(bmeurer): Use GetPropertyStub here once available. | 7234 // TODO(bmeurer): Use GetPropertyStub here once available. |
7221 Bind(&return_runtime); | 7235 Bind(&return_runtime); |
7222 { | 7236 { |
7223 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); | 7237 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); |
7224 Goto(&end); | 7238 Goto(&end); |
7225 } | 7239 } |
7226 | 7240 |
7227 Bind(&end); | 7241 Bind(&end); |
7228 return result.value(); | 7242 return result.value(); |
7229 } | 7243 } |
7230 | 7244 |
7231 } // namespace internal | 7245 } // namespace internal |
7232 } // namespace v8 | 7246 } // namespace v8 |
OLD | NEW |