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