OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 return LoadAndUntagToWord32Root(Heap::kHashSeedRootIndex); | 119 return LoadAndUntagToWord32Root(Heap::kHashSeedRootIndex); |
120 } | 120 } |
121 | 121 |
122 Node* CodeStubAssembler::StaleRegisterConstant() { | 122 Node* CodeStubAssembler::StaleRegisterConstant() { |
123 return LoadRoot(Heap::kStaleRegisterRootIndex); | 123 return LoadRoot(Heap::kStaleRegisterRootIndex); |
124 } | 124 } |
125 | 125 |
126 Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) { | 126 Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) { |
127 if (mode == SMI_PARAMETERS) { | 127 if (mode == SMI_PARAMETERS) { |
128 return SmiConstant(Smi::FromInt(value)); | 128 return SmiConstant(Smi::FromInt(value)); |
| 129 } else if (mode == INTPTR_PARAMETERS) { |
| 130 return IntPtrConstant(value); |
129 } else { | 131 } else { |
130 DCHECK(mode == INTEGER_PARAMETERS || mode == INTPTR_PARAMETERS); | 132 DCHECK_EQ(INTEGER_PARAMETERS, mode); |
131 return IntPtrConstant(value); | 133 return Int32Constant(value); |
132 } | 134 } |
133 } | 135 } |
134 | 136 |
135 Node* CodeStubAssembler::IntPtrAddFoldConstants(Node* left, Node* right) { | 137 Node* CodeStubAssembler::IntPtrAddFoldConstants(Node* left, Node* right) { |
136 int32_t left_constant; | 138 int32_t left_constant; |
137 bool is_left_constant = ToInt32Constant(left, left_constant); | 139 bool is_left_constant = ToInt32Constant(left, left_constant); |
138 int32_t right_constant; | 140 int32_t right_constant; |
139 bool is_right_constant = ToInt32Constant(right, right_constant); | 141 bool is_right_constant = ToInt32Constant(right, right_constant); |
140 if (is_left_constant) { | 142 if (is_left_constant) { |
141 if (is_right_constant) { | 143 if (is_right_constant) { |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 | 721 |
720 void CodeStubAssembler::BranchIfFastJSArray( | 722 void CodeStubAssembler::BranchIfFastJSArray( |
721 Node* object, Node* context, CodeStubAssembler::FastJSArrayAccessMode mode, | 723 Node* object, Node* context, CodeStubAssembler::FastJSArrayAccessMode mode, |
722 Label* if_true, Label* if_false) { | 724 Label* if_true, Label* if_false) { |
723 // Bailout if receiver is a Smi. | 725 // Bailout if receiver is a Smi. |
724 GotoIf(TaggedIsSmi(object), if_false); | 726 GotoIf(TaggedIsSmi(object), if_false); |
725 | 727 |
726 Node* map = LoadMap(object); | 728 Node* map = LoadMap(object); |
727 | 729 |
728 // Bailout if instance type is not JS_ARRAY_TYPE. | 730 // Bailout if instance type is not JS_ARRAY_TYPE. |
729 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), | 731 GotoIf(Word32NotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), |
730 if_false); | 732 if_false); |
731 | 733 |
732 Node* elements_kind = LoadMapElementsKind(map); | 734 Node* elements_kind = LoadMapElementsKind(map); |
733 | 735 |
734 // Bailout if receiver has slow elements. | 736 // Bailout if receiver has slow elements. |
735 GotoUnless(IsFastElementsKind(elements_kind), if_false); | 737 GotoUnless(IsFastElementsKind(elements_kind), if_false); |
736 | 738 |
737 // Check prototype chain if receiver does not have packed elements. | 739 // Check prototype chain if receiver does not have packed elements. |
738 if (mode == FastJSArrayAccessMode::INBOUNDS_READ) { | 740 if (mode == FastJSArrayAccessMode::INBOUNDS_READ) { |
739 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); | 741 GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true); |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 } | 1456 } |
1455 | 1457 |
1456 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, | 1458 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context, |
1457 Node* array, | 1459 Node* array, |
1458 CodeStubArguments& args, | 1460 CodeStubArguments& args, |
1459 Variable& arg_index, | 1461 Variable& arg_index, |
1460 Label* bailout) { | 1462 Label* bailout) { |
1461 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); | 1463 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); |
1462 Label pre_bailout(this); | 1464 Label pre_bailout(this); |
1463 Label success(this); | 1465 Label success(this); |
1464 Variable elements(this, MachineRepresentation::kTagged); | 1466 Variable var_elements(this, MachineRepresentation::kTagged); |
| 1467 Variable var_tagged_length(this, MachineRepresentation::kTagged); |
1465 ParameterMode mode = OptimalParameterMode(); | 1468 ParameterMode mode = OptimalParameterMode(); |
1466 Variable length(this, OptimalParameterRepresentation()); | 1469 Variable var_length(this, OptimalParameterRepresentation()); |
1467 length.Bind(UntagParameter(LoadJSArrayLength(array), mode)); | 1470 var_length.Bind(TaggedToParameter(LoadJSArrayLength(array), mode)); |
1468 elements.Bind(LoadElements(array)); | 1471 var_elements.Bind(LoadElements(array)); |
1469 Node* capacity = | 1472 Node* capacity = |
1470 UntagParameter(LoadFixedArrayBaseLength(elements.value()), mode); | 1473 TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode); |
1471 | 1474 |
1472 // Resize the capacity of the fixed array if it doesn't fit. | 1475 // Resize the capacity of the fixed array if it doesn't fit. |
1473 Label fits(this, &elements); | 1476 Label fits(this, &var_elements); |
1474 Node* first = arg_index.value(); | 1477 Node* first = arg_index.value(); |
1475 Node* growth = IntPtrSubFoldConstants(args.GetLength(), first); | 1478 Node* growth = IntPtrSubFoldConstants(args.GetLength(), first); |
1476 Node* new_length = IntPtrAdd( | 1479 Node* new_length = |
1477 mode == INTPTR_PARAMETERS ? growth : SmiTag(growth), length.value()); | 1480 IntPtrOrSmiAdd(WordToParameter(growth, mode), var_length.value(), mode); |
1478 GotoUnless(IntPtrGreaterThanOrEqual(new_length, capacity), &fits); | 1481 GotoUnless(IntPtrOrSmiGreaterThanOrEqual(new_length, capacity, mode), &fits); |
1479 Node* new_capacity = CalculateNewElementsCapacity( | 1482 Node* new_capacity = CalculateNewElementsCapacity( |
1480 IntPtrAdd(new_length, IntPtrOrSmiConstant(1, mode)), mode); | 1483 IntPtrOrSmiAdd(new_length, IntPtrOrSmiConstant(1, mode), mode), mode); |
1481 elements.Bind(GrowElementsCapacity(array, elements.value(), kind, kind, | 1484 var_elements.Bind(GrowElementsCapacity(array, var_elements.value(), kind, |
1482 capacity, new_capacity, mode, | 1485 kind, capacity, new_capacity, mode, |
1483 &pre_bailout)); | 1486 &pre_bailout)); |
1484 Goto(&fits); | 1487 Goto(&fits); |
1485 Bind(&fits); | 1488 Bind(&fits); |
| 1489 Node* elements = var_elements.value(); |
1486 | 1490 |
1487 // Push each argument onto the end of the array now that there is enough | 1491 // Push each argument onto the end of the array now that there is enough |
1488 // capacity. | 1492 // capacity. |
1489 CodeStubAssembler::VariableList push_vars({&length, &elements}, zone()); | 1493 CodeStubAssembler::VariableList push_vars({&var_length}, zone()); |
1490 args.ForEach( | 1494 args.ForEach( |
1491 push_vars, | 1495 push_vars, |
1492 [this, kind, mode, &length, &elements, &pre_bailout](Node* arg) { | 1496 [this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) { |
1493 if (IsFastSmiElementsKind(kind)) { | 1497 if (IsFastSmiElementsKind(kind)) { |
1494 GotoIf(TaggedIsNotSmi(arg), &pre_bailout); | 1498 GotoIf(TaggedIsNotSmi(arg), &pre_bailout); |
1495 } else if (IsFastDoubleElementsKind(kind)) { | 1499 } else if (IsFastDoubleElementsKind(kind)) { |
1496 GotoIfNotNumber(arg, &pre_bailout); | 1500 GotoIfNotNumber(arg, &pre_bailout); |
1497 } | 1501 } |
1498 if (IsFastDoubleElementsKind(kind)) { | 1502 if (IsFastDoubleElementsKind(kind)) { |
1499 Node* double_value = ChangeNumberToFloat64(arg); | 1503 Node* double_value = ChangeNumberToFloat64(arg); |
1500 StoreFixedDoubleArrayElement(elements.value(), length.value(), | 1504 StoreFixedDoubleArrayElement(elements, var_length.value(), |
1501 Float64SilenceNaN(double_value), mode); | 1505 Float64SilenceNaN(double_value), mode); |
1502 } else { | 1506 } else { |
1503 WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind) | 1507 WriteBarrierMode barrier_mode = IsFastSmiElementsKind(kind) |
1504 ? SKIP_WRITE_BARRIER | 1508 ? SKIP_WRITE_BARRIER |
1505 : UPDATE_WRITE_BARRIER; | 1509 : UPDATE_WRITE_BARRIER; |
1506 StoreFixedArrayElement(elements.value(), length.value(), arg, | 1510 StoreFixedArrayElement(elements, var_length.value(), arg, |
1507 barrier_mode, 0, mode); | 1511 barrier_mode, 0, mode); |
1508 } | 1512 } |
1509 Increment(length, 1, mode); | 1513 Increment(var_length, 1, mode); |
1510 }, | 1514 }, |
1511 first, nullptr); | 1515 first, nullptr); |
1512 length.Bind(TagParameter(length.value(), mode)); | 1516 { |
1513 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value()); | 1517 Node* length = ParameterToTagged(var_length.value(), mode); |
1514 Goto(&success); | 1518 var_tagged_length.Bind(length); |
| 1519 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); |
| 1520 Goto(&success); |
| 1521 } |
1515 | 1522 |
1516 Bind(&pre_bailout); | 1523 Bind(&pre_bailout); |
1517 length.Bind(TagParameter(length.value(), mode)); | 1524 { |
1518 Node* diff = SmiSub(length.value(), LoadJSArrayLength(array)); | 1525 Node* length = ParameterToTagged(var_length.value(), mode); |
1519 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length.value()); | 1526 var_tagged_length.Bind(length); |
1520 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff))); | 1527 Node* diff = SmiSub(length, LoadJSArrayLength(array)); |
1521 Goto(bailout); | 1528 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); |
| 1529 arg_index.Bind(IntPtrAdd(arg_index.value(), SmiUntag(diff))); |
| 1530 Goto(bailout); |
| 1531 } |
1522 | 1532 |
1523 Bind(&success); | 1533 Bind(&success); |
1524 return length.value(); | 1534 return var_tagged_length.value(); |
1525 } | 1535 } |
1526 | 1536 |
1527 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { | 1537 Node* CodeStubAssembler::AllocateHeapNumber(MutableMode mode) { |
1528 Node* result = Allocate(HeapNumber::kSize, kNone); | 1538 Node* result = Allocate(HeapNumber::kSize, kNone); |
1529 Heap::RootListIndex heap_map_index = | 1539 Heap::RootListIndex heap_map_index = |
1530 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex | 1540 mode == IMMUTABLE ? Heap::kHeapNumberMapRootIndex |
1531 : Heap::kMutableHeapNumberMapRootIndex; | 1541 : Heap::kMutableHeapNumberMapRootIndex; |
1532 StoreMapNoWriteBarrier(result, heap_map_index); | 1542 StoreMapNoWriteBarrier(result, heap_map_index); |
1533 return result; | 1543 return result; |
1534 } | 1544 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), | 1581 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), |
1572 &if_sizeissmall, &if_notsizeissmall); | 1582 &if_sizeissmall, &if_notsizeissmall); |
1573 | 1583 |
1574 Bind(&if_sizeissmall); | 1584 Bind(&if_sizeissmall); |
1575 { | 1585 { |
1576 // Just allocate the SeqOneByteString in new space. | 1586 // Just allocate the SeqOneByteString in new space. |
1577 Node* result = Allocate(size, flags); | 1587 Node* result = Allocate(size, flags); |
1578 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); | 1588 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); |
1579 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); | 1589 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); |
1580 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, | 1590 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, |
1581 TagParameter(length, mode)); | 1591 ParameterToTagged(length, mode)); |
1582 // Initialize both used and unused parts of hash field slot at once. | 1592 // Initialize both used and unused parts of hash field slot at once. |
1583 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, | 1593 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, |
1584 IntPtrConstant(String::kEmptyHashField), | 1594 IntPtrConstant(String::kEmptyHashField), |
1585 MachineType::PointerRepresentation()); | 1595 MachineType::PointerRepresentation()); |
1586 var_result.Bind(result); | 1596 var_result.Bind(result); |
1587 Goto(&if_join); | 1597 Goto(&if_join); |
1588 } | 1598 } |
1589 | 1599 |
1590 Bind(&if_notsizeissmall); | 1600 Bind(&if_notsizeissmall); |
1591 { | 1601 { |
1592 // We might need to allocate in large object space, go to the runtime. | 1602 // We might need to allocate in large object space, go to the runtime. |
1593 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, | 1603 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, |
1594 TagParameter(length, mode)); | 1604 ParameterToTagged(length, mode)); |
1595 var_result.Bind(result); | 1605 var_result.Bind(result); |
1596 Goto(&if_join); | 1606 Goto(&if_join); |
1597 } | 1607 } |
1598 | 1608 |
1599 Bind(&if_join); | 1609 Bind(&if_join); |
1600 return var_result.value(); | 1610 return var_result.value(); |
1601 } | 1611 } |
1602 | 1612 |
1603 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, | 1613 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, |
1604 AllocationFlags flags) { | 1614 AllocationFlags flags) { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1869 SmiTag(capacity), SKIP_WRITE_BARRIER); | 1879 SmiTag(capacity), SKIP_WRITE_BARRIER); |
1870 // Initialize Dictionary fields. | 1880 // Initialize Dictionary fields. |
1871 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); | 1881 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); |
1872 StoreFixedArrayElement(result, NameDictionary::kMaxNumberKeyIndex, filler, | 1882 StoreFixedArrayElement(result, NameDictionary::kMaxNumberKeyIndex, filler, |
1873 SKIP_WRITE_BARRIER); | 1883 SKIP_WRITE_BARRIER); |
1874 StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex, | 1884 StoreFixedArrayElement(result, NameDictionary::kNextEnumerationIndexIndex, |
1875 SmiConstant(PropertyDetails::kInitialIndex), | 1885 SmiConstant(PropertyDetails::kInitialIndex), |
1876 SKIP_WRITE_BARRIER); | 1886 SKIP_WRITE_BARRIER); |
1877 | 1887 |
1878 // Initialize NameDictionary elements. | 1888 // Initialize NameDictionary elements. |
1879 result = BitcastTaggedToWord(result); | 1889 Node* result_word = BitcastTaggedToWord(result); |
1880 Node* start_address = IntPtrAdd( | 1890 Node* start_address = IntPtrAdd( |
1881 result, IntPtrConstant(NameDictionary::OffsetOfElementAt( | 1891 result_word, IntPtrConstant(NameDictionary::OffsetOfElementAt( |
1882 NameDictionary::kElementsStartIndex) - | 1892 NameDictionary::kElementsStartIndex) - |
1883 kHeapObjectTag)); | 1893 kHeapObjectTag)); |
1884 Node* end_address = IntPtrAdd( | 1894 Node* end_address = IntPtrAdd( |
1885 result, | 1895 result_word, |
1886 IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); | 1896 IntPtrSubFoldConstants(store_size, IntPtrConstant(kHeapObjectTag))); |
1887 StoreFieldsNoWriteBarrier(start_address, end_address, filler); | 1897 StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
1888 return result; | 1898 return result; |
1889 } | 1899 } |
1890 | 1900 |
1891 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, | 1901 Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties, |
1892 Node* elements) { | 1902 Node* elements) { |
1893 CSA_ASSERT(this, IsMap(map)); | 1903 CSA_ASSERT(this, IsMap(map)); |
1894 Node* size = | 1904 Node* size = |
1895 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); | 1905 IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize)); |
(...skipping 25 matching lines...) Expand all Loading... |
1921 } | 1931 } |
1922 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize); | 1932 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize); |
1923 } | 1933 } |
1924 | 1934 |
1925 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map, | 1935 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map, |
1926 Node* size, int start_offset) { | 1936 Node* size, int start_offset) { |
1927 // TODO(cbruni): activate in-object slack tracking machinery. | 1937 // TODO(cbruni): activate in-object slack tracking machinery. |
1928 Comment("InitializeJSObjectBody"); | 1938 Comment("InitializeJSObjectBody"); |
1929 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); | 1939 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); |
1930 // Calculate the untagged field addresses. | 1940 // Calculate the untagged field addresses. |
| 1941 object = BitcastTaggedToWord(object); |
1931 Node* start_address = | 1942 Node* start_address = |
1932 IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag)); | 1943 IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag)); |
1933 Node* end_address = | 1944 Node* end_address = |
1934 IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag)); | 1945 IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag)); |
1935 StoreFieldsNoWriteBarrier(start_address, end_address, filler); | 1946 StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
1936 } | 1947 } |
1937 | 1948 |
1938 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, | 1949 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, |
1939 Node* end_address, | 1950 Node* end_address, |
1940 Node* value) { | 1951 Node* value) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2019 Node *array, *elements; | 2030 Node *array, *elements; |
2020 std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( | 2031 std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( |
2021 kind, array_map, length, allocation_site, capacity, capacity_mode); | 2032 kind, array_map, length, allocation_site, capacity, capacity_mode); |
2022 // Setup elements object. | 2033 // Setup elements object. |
2023 Heap::RootListIndex elements_map_index = | 2034 Heap::RootListIndex elements_map_index = |
2024 IsFastDoubleElementsKind(kind) ? Heap::kFixedDoubleArrayMapRootIndex | 2035 IsFastDoubleElementsKind(kind) ? Heap::kFixedDoubleArrayMapRootIndex |
2025 : Heap::kFixedArrayMapRootIndex; | 2036 : Heap::kFixedArrayMapRootIndex; |
2026 DCHECK(Heap::RootIsImmortalImmovable(elements_map_index)); | 2037 DCHECK(Heap::RootIsImmortalImmovable(elements_map_index)); |
2027 StoreMapNoWriteBarrier(elements, elements_map_index); | 2038 StoreMapNoWriteBarrier(elements, elements_map_index); |
2028 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, | 2039 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, |
2029 TagParameter(capacity, capacity_mode)); | 2040 ParameterToTagged(capacity, capacity_mode)); |
2030 | 2041 |
2031 // Fill in the elements with holes. | 2042 // Fill in the elements with holes. |
2032 FillFixedArrayWithValue(kind, elements, IntPtrOrSmiConstant(0, capacity_mode), | 2043 FillFixedArrayWithValue(kind, elements, IntPtrOrSmiConstant(0, capacity_mode), |
2033 capacity, Heap::kTheHoleValueRootIndex, | 2044 capacity, Heap::kTheHoleValueRootIndex, |
2034 capacity_mode); | 2045 capacity_mode); |
2035 | 2046 |
2036 return array; | 2047 return array; |
2037 } | 2048 } |
2038 | 2049 |
2039 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, | 2050 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, |
2040 Node* capacity_node, | 2051 Node* capacity_node, |
2041 ParameterMode mode, | 2052 ParameterMode mode, |
2042 AllocationFlags flags) { | 2053 AllocationFlags flags) { |
2043 CSA_ASSERT(this, IntPtrOrSmiGreaterThan(capacity_node, | 2054 CSA_ASSERT(this, IntPtrOrSmiGreaterThan(capacity_node, |
2044 IntPtrOrSmiConstant(0, mode), mode)); | 2055 IntPtrOrSmiConstant(0, mode), mode)); |
2045 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); | 2056 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); |
2046 | 2057 |
2047 // Allocate both array and elements object, and initialize the JSArray. | 2058 // Allocate both array and elements object, and initialize the JSArray. |
2048 Node* array = Allocate(total_size, flags); | 2059 Node* array = Allocate(total_size, flags); |
2049 Heap::RootListIndex map_index = IsFastDoubleElementsKind(kind) | 2060 Heap::RootListIndex map_index = IsFastDoubleElementsKind(kind) |
2050 ? Heap::kFixedDoubleArrayMapRootIndex | 2061 ? Heap::kFixedDoubleArrayMapRootIndex |
2051 : Heap::kFixedArrayMapRootIndex; | 2062 : Heap::kFixedArrayMapRootIndex; |
2052 DCHECK(Heap::RootIsImmortalImmovable(map_index)); | 2063 DCHECK(Heap::RootIsImmortalImmovable(map_index)); |
2053 StoreMapNoWriteBarrier(array, map_index); | 2064 StoreMapNoWriteBarrier(array, map_index); |
2054 StoreObjectFieldNoWriteBarrier(array, FixedArray::kLengthOffset, | 2065 StoreObjectFieldNoWriteBarrier(array, FixedArray::kLengthOffset, |
2055 TagParameter(capacity_node, mode)); | 2066 ParameterToTagged(capacity_node, mode)); |
2056 return array; | 2067 return array; |
2057 } | 2068 } |
2058 | 2069 |
2059 void CodeStubAssembler::FillFixedArrayWithValue( | 2070 void CodeStubAssembler::FillFixedArrayWithValue( |
2060 ElementsKind kind, Node* array, Node* from_node, Node* to_node, | 2071 ElementsKind kind, Node* array, Node* from_node, Node* to_node, |
2061 Heap::RootListIndex value_root_index, ParameterMode mode) { | 2072 Heap::RootListIndex value_root_index, ParameterMode mode) { |
2062 bool is_double = IsFastDoubleElementsKind(kind); | 2073 bool is_double = IsFastDoubleElementsKind(kind); |
2063 DCHECK(value_root_index == Heap::kTheHoleValueRootIndex || | 2074 DCHECK(value_root_index == Heap::kTheHoleValueRootIndex || |
2064 value_root_index == Heap::kUndefinedValueRootIndex); | 2075 value_root_index == Heap::kUndefinedValueRootIndex); |
2065 DCHECK_IMPLIES(is_double, value_root_index == Heap::kTheHoleValueRootIndex); | 2076 DCHECK_IMPLIES(is_double, value_root_index == Heap::kTheHoleValueRootIndex); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2337 return unconditioned_result; | 2348 return unconditioned_result; |
2338 } | 2349 } |
2339 } | 2350 } |
2340 | 2351 |
2341 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, | 2352 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, |
2342 ElementsKind kind, Node* key, | 2353 ElementsKind kind, Node* key, |
2343 Label* bailout) { | 2354 Label* bailout) { |
2344 Node* capacity = LoadFixedArrayBaseLength(elements); | 2355 Node* capacity = LoadFixedArrayBaseLength(elements); |
2345 | 2356 |
2346 ParameterMode mode = OptimalParameterMode(); | 2357 ParameterMode mode = OptimalParameterMode(); |
2347 capacity = UntagParameter(capacity, mode); | 2358 capacity = TaggedToParameter(capacity, mode); |
2348 key = UntagParameter(key, mode); | 2359 key = TaggedToParameter(key, mode); |
2349 | 2360 |
2350 return TryGrowElementsCapacity(object, elements, kind, key, capacity, mode, | 2361 return TryGrowElementsCapacity(object, elements, kind, key, capacity, mode, |
2351 bailout); | 2362 bailout); |
2352 } | 2363 } |
2353 | 2364 |
2354 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, | 2365 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, |
2355 ElementsKind kind, Node* key, | 2366 ElementsKind kind, Node* key, |
2356 Node* capacity, | 2367 Node* capacity, |
2357 ParameterMode mode, | 2368 ParameterMode mode, |
2358 Label* bailout) { | 2369 Label* bailout) { |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2714 Variable result(this, MachineRepresentation::kFloat64); | 2725 Variable result(this, MachineRepresentation::kFloat64); |
2715 Label smi(this); | 2726 Label smi(this); |
2716 Label done(this, &result); | 2727 Label done(this, &result); |
2717 GotoIf(TaggedIsSmi(value), &smi); | 2728 GotoIf(TaggedIsSmi(value), &smi); |
2718 result.Bind( | 2729 result.Bind( |
2719 LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64())); | 2730 LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64())); |
2720 Goto(&done); | 2731 Goto(&done); |
2721 | 2732 |
2722 Bind(&smi); | 2733 Bind(&smi); |
2723 { | 2734 { |
2724 result.Bind(ChangeInt32ToFloat64(SmiUntag(value))); | 2735 result.Bind(SmiToFloat64(value)); |
2725 Goto(&done); | 2736 Goto(&done); |
2726 } | 2737 } |
2727 | 2738 |
2728 Bind(&done); | 2739 Bind(&done); |
2729 return result.value(); | 2740 return result.value(); |
2730 } | 2741 } |
2731 | 2742 |
2732 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, | 2743 Node* CodeStubAssembler::ToThisValue(Node* context, Node* value, |
2733 PrimitiveType primitive_type, | 2744 PrimitiveType primitive_type, |
2734 char const* method_name) { | 2745 char const* method_name) { |
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3554 | 3565 |
3555 Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string, | 3566 Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string, |
3556 Node* needle_char, Node* from) { | 3567 Node* needle_char, Node* from) { |
3557 CSA_ASSERT(this, IsString(string)); | 3568 CSA_ASSERT(this, IsString(string)); |
3558 Variable var_result(this, MachineRepresentation::kTagged); | 3569 Variable var_result(this, MachineRepresentation::kTagged); |
3559 | 3570 |
3560 Label out(this), runtime(this, Label::kDeferred); | 3571 Label out(this), runtime(this, Label::kDeferred); |
3561 | 3572 |
3562 // Let runtime handle non-one-byte {needle_char}. | 3573 // Let runtime handle non-one-byte {needle_char}. |
3563 | 3574 |
3564 Node* const one_byte_char_mask = IntPtrConstant(0xFF); | 3575 Node* const one_byte_char_mask = Int32Constant(0xFF); |
3565 GotoUnless(WordEqual(WordAnd(needle_char, one_byte_char_mask), needle_char), | 3576 GotoUnless( |
3566 &runtime); | 3577 Word32Equal(Word32And(needle_char, one_byte_char_mask), needle_char), |
| 3578 &runtime); |
3567 | 3579 |
3568 // TODO(jgruber): Handle external and two-byte strings. | 3580 // TODO(jgruber): Handle external and two-byte strings. |
3569 | 3581 |
3570 Node* const one_byte_seq_mask = Int32Constant( | 3582 Node* const one_byte_seq_mask = Int32Constant( |
3571 kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask); | 3583 kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask); |
3572 Node* const expected_masked = Int32Constant(kOneByteStringTag); | 3584 Node* const expected_masked = Int32Constant(kOneByteStringTag); |
3573 | 3585 |
3574 Node* const string_instance_type = LoadInstanceType(string); | 3586 Node* const string_instance_type = LoadInstanceType(string); |
3575 GotoUnless(Word32Equal(Word32And(string_instance_type, one_byte_seq_mask), | 3587 GotoUnless(Word32Equal(Word32And(string_instance_type, one_byte_seq_mask), |
3576 expected_masked), | 3588 expected_masked), |
3577 &runtime); | 3589 &runtime); |
3578 | 3590 |
3579 // If we reach this, {string} is a non-indirect, non-external one-byte string. | 3591 // If we reach this, {string} is a non-indirect, non-external one-byte string. |
3580 | 3592 |
3581 Node* const length = LoadStringLength(string); | 3593 Node* const length = LoadStringLength(string); |
3582 Node* const search_range_length = SmiUntag(SmiSub(length, from)); | 3594 Node* const search_range_length = SmiUntag(SmiSub(length, from)); |
3583 | 3595 |
3584 const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag; | 3596 const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag; |
3585 Node* const begin = IntPtrConstant(offset); | 3597 Node* const begin = IntPtrConstant(offset); |
3586 Node* const cursor = IntPtrAdd(begin, SmiUntag(from)); | 3598 Node* const cursor = IntPtrAdd(begin, SmiUntag(from)); |
3587 Node* const end = IntPtrAdd(cursor, search_range_length); | 3599 Node* const end = IntPtrAdd(cursor, search_range_length); |
3588 | 3600 |
3589 var_result.Bind(SmiConstant(Smi::FromInt(-1))); | 3601 var_result.Bind(SmiConstant(Smi::FromInt(-1))); |
3590 | 3602 |
3591 BuildFastLoop( | 3603 BuildFastLoop( |
3592 MachineType::PointerRepresentation(), cursor, end, | 3604 MachineType::PointerRepresentation(), cursor, end, |
3593 [this, string, needle_char, begin, &var_result, &out](Node* cursor) { | 3605 [this, string, needle_char, begin, &var_result, &out](Node* cursor) { |
3594 Label next(this); | 3606 Label next(this); |
3595 Node* value = Load(MachineType::Uint8(), string, cursor); | 3607 Node* value = Load(MachineType::Uint8(), string, cursor); |
3596 GotoUnless(WordEqual(value, needle_char), &next); | 3608 GotoUnless(Word32Equal(value, needle_char), &next); |
3597 | 3609 |
3598 // Found a match. | 3610 // Found a match. |
3599 Node* index = SmiTag(IntPtrSub(cursor, begin)); | 3611 Node* index = SmiTag(IntPtrSub(cursor, begin)); |
3600 var_result.Bind(index); | 3612 var_result.Bind(index); |
3601 Goto(&out); | 3613 Goto(&out); |
3602 | 3614 |
3603 Bind(&next); | 3615 Bind(&next); |
3604 }, | 3616 }, |
3605 1, IndexAdvanceMode::kPost); | 3617 1, IndexAdvanceMode::kPost); |
3606 Goto(&out); | 3618 Goto(&out); |
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4245 } | 4257 } |
4246 } | 4258 } |
4247 | 4259 |
4248 void CodeStubAssembler::Increment(Variable& variable, int value, | 4260 void CodeStubAssembler::Increment(Variable& variable, int value, |
4249 ParameterMode mode) { | 4261 ParameterMode mode) { |
4250 DCHECK_IMPLIES(mode == INTPTR_PARAMETERS, | 4262 DCHECK_IMPLIES(mode == INTPTR_PARAMETERS, |
4251 variable.rep() == MachineType::PointerRepresentation()); | 4263 variable.rep() == MachineType::PointerRepresentation()); |
4252 DCHECK_IMPLIES(mode == SMI_PARAMETERS, | 4264 DCHECK_IMPLIES(mode == SMI_PARAMETERS, |
4253 variable.rep() == MachineRepresentation::kTagged || | 4265 variable.rep() == MachineRepresentation::kTagged || |
4254 variable.rep() == MachineRepresentation::kTaggedSigned); | 4266 variable.rep() == MachineRepresentation::kTaggedSigned); |
4255 variable.Bind(IntPtrAdd(variable.value(), IntPtrOrSmiConstant(value, mode))); | 4267 variable.Bind( |
| 4268 IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode)); |
4256 } | 4269 } |
4257 | 4270 |
4258 void CodeStubAssembler::Use(Label* label) { | 4271 void CodeStubAssembler::Use(Label* label) { |
4259 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); | 4272 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); |
4260 } | 4273 } |
4261 | 4274 |
4262 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, | 4275 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
4263 Variable* var_index, Label* if_keyisunique, | 4276 Variable* var_index, Label* if_keyisunique, |
4264 Label* if_bailout) { | 4277 Label* if_bailout) { |
4265 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); | 4278 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); |
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5473 | 5486 |
5474 Bind(&done); | 5487 Bind(&done); |
5475 return var_intptr_key.value(); | 5488 return var_intptr_key.value(); |
5476 } | 5489 } |
5477 | 5490 |
5478 void CodeStubAssembler::ExtendPropertiesBackingStore(Node* object) { | 5491 void CodeStubAssembler::ExtendPropertiesBackingStore(Node* object) { |
5479 Node* properties = LoadProperties(object); | 5492 Node* properties = LoadProperties(object); |
5480 Node* length = LoadFixedArrayBaseLength(properties); | 5493 Node* length = LoadFixedArrayBaseLength(properties); |
5481 | 5494 |
5482 ParameterMode mode = OptimalParameterMode(); | 5495 ParameterMode mode = OptimalParameterMode(); |
5483 length = UntagParameter(length, mode); | 5496 length = TaggedToParameter(length, mode); |
5484 | 5497 |
5485 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 5498 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
5486 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); | 5499 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); |
5487 | 5500 |
5488 // Grow properties array. | 5501 // Grow properties array. |
5489 ElementsKind kind = FAST_ELEMENTS; | 5502 ElementsKind kind = FAST_ELEMENTS; |
5490 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < | 5503 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < |
5491 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); | 5504 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); |
5492 // The size of a new properties backing store is guaranteed to be small | 5505 // The size of a new properties backing store is guaranteed to be small |
5493 // enough that the new backing store will be allocated in new space. | 5506 // enough that the new backing store will be allocated in new space. |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5860 | 5873 |
5861 value = PrepareValueForWriteToTypedArray(value, elements_kind, bailout); | 5874 value = PrepareValueForWriteToTypedArray(value, elements_kind, bailout); |
5862 | 5875 |
5863 // There must be no allocations between the buffer load and | 5876 // There must be no allocations between the buffer load and |
5864 // and the actual store to backing store, because GC may decide that | 5877 // and the actual store to backing store, because GC may decide that |
5865 // the buffer is not alive or move the elements. | 5878 // the buffer is not alive or move the elements. |
5866 // TODO(ishell): introduce DisallowHeapAllocationCode scope here. | 5879 // TODO(ishell): introduce DisallowHeapAllocationCode scope here. |
5867 | 5880 |
5868 // Check if buffer has been neutered. | 5881 // Check if buffer has been neutered. |
5869 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); | 5882 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); |
5870 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, | 5883 GotoIf(IsDetachedBuffer(buffer), bailout); |
5871 MachineType::Uint32()); | |
5872 Node* neutered_bit = | |
5873 Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask)); | |
5874 GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), bailout); | |
5875 | 5884 |
5876 // Bounds check. | 5885 // Bounds check. |
5877 Node* length = UntagParameter( | 5886 Node* length = TaggedToParameter( |
5878 LoadObjectField(object, JSTypedArray::kLengthOffset), parameter_mode); | 5887 LoadObjectField(object, JSTypedArray::kLengthOffset), parameter_mode); |
5879 | 5888 |
5880 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 5889 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
5881 // Skip the store if we write beyond the length. | 5890 // Skip the store if we write beyond the length. |
5882 GotoUnless(IntPtrLessThan(key, length), &done); | 5891 GotoUnless(IntPtrLessThan(key, length), &done); |
5883 // ... but bailout if the key is negative. | 5892 // ... but bailout if the key is negative. |
5884 } else { | 5893 } else { |
5885 DCHECK_EQ(STANDARD_STORE, store_mode); | 5894 DCHECK_EQ(STANDARD_STORE, store_mode); |
5886 } | 5895 } |
5887 GotoUnless(UintPtrLessThan(key, length), bailout); | 5896 GotoUnless(UintPtrLessThan(key, length), bailout); |
5888 | 5897 |
5889 // Backing store = external_pointer + base_pointer. | 5898 // Backing store = external_pointer + base_pointer. |
5890 Node* external_pointer = | 5899 Node* external_pointer = |
5891 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, | 5900 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, |
5892 MachineType::Pointer()); | 5901 MachineType::Pointer()); |
5893 Node* base_pointer = | 5902 Node* base_pointer = |
5894 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); | 5903 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); |
5895 Node* backing_store = IntPtrAdd(external_pointer, base_pointer); | 5904 Node* backing_store = |
| 5905 IntPtrAdd(external_pointer, BitcastTaggedToWord(base_pointer)); |
5896 StoreElement(backing_store, elements_kind, key, value, parameter_mode); | 5906 StoreElement(backing_store, elements_kind, key, value, parameter_mode); |
5897 Goto(&done); | 5907 Goto(&done); |
5898 | 5908 |
5899 Bind(&done); | 5909 Bind(&done); |
5900 return; | 5910 return; |
5901 } | 5911 } |
5902 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || | 5912 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || |
5903 IsFastDoubleElementsKind(elements_kind)); | 5913 IsFastDoubleElementsKind(elements_kind)); |
5904 | 5914 |
5905 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset) | 5915 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset) |
5906 : LoadFixedArrayBaseLength(elements); | 5916 : LoadFixedArrayBaseLength(elements); |
5907 length = UntagParameter(length, parameter_mode); | 5917 length = TaggedToParameter(length, parameter_mode); |
5908 | 5918 |
5909 // In case value is stored into a fast smi array, assure that the value is | 5919 // In case value is stored into a fast smi array, assure that the value is |
5910 // a smi before manipulating the backing store. Otherwise the backing store | 5920 // a smi before manipulating the backing store. Otherwise the backing store |
5911 // may be left in an invalid state. | 5921 // may be left in an invalid state. |
5912 if (IsFastSmiElementsKind(elements_kind)) { | 5922 if (IsFastSmiElementsKind(elements_kind)) { |
5913 GotoUnless(TaggedIsSmi(value), bailout); | 5923 GotoUnless(TaggedIsSmi(value), bailout); |
5914 } else if (IsFastDoubleElementsKind(elements_kind)) { | 5924 } else if (IsFastDoubleElementsKind(elements_kind)) { |
5915 value = TryTaggedToFloat64(value, bailout); | 5925 value = TryTaggedToFloat64(value, bailout); |
5916 } | 5926 } |
5917 | 5927 |
(...skipping 24 matching lines...) Expand all Loading... |
5942 if (IsHoleyElementsKind(kind)) { | 5952 if (IsHoleyElementsKind(kind)) { |
5943 condition = UintPtrGreaterThanOrEqual(key, length); | 5953 condition = UintPtrGreaterThanOrEqual(key, length); |
5944 } else { | 5954 } else { |
5945 condition = WordEqual(key, length); | 5955 condition = WordEqual(key, length); |
5946 } | 5956 } |
5947 Branch(condition, &grow_case, &no_grow_case); | 5957 Branch(condition, &grow_case, &no_grow_case); |
5948 | 5958 |
5949 Bind(&grow_case); | 5959 Bind(&grow_case); |
5950 { | 5960 { |
5951 Node* current_capacity = | 5961 Node* current_capacity = |
5952 UntagParameter(LoadFixedArrayBaseLength(elements), mode); | 5962 TaggedToParameter(LoadFixedArrayBaseLength(elements), mode); |
5953 | 5963 |
5954 checked_elements.Bind(elements); | 5964 checked_elements.Bind(elements); |
5955 | 5965 |
5956 Label fits_capacity(this); | 5966 Label fits_capacity(this); |
5957 GotoIf(UintPtrLessThan(key, current_capacity), &fits_capacity); | 5967 GotoIf(UintPtrLessThan(key, current_capacity), &fits_capacity); |
5958 { | 5968 { |
5959 Node* new_elements = TryGrowElementsCapacity( | 5969 Node* new_elements = TryGrowElementsCapacity( |
5960 object, elements, kind, key, current_capacity, mode, bailout); | 5970 object, elements, kind, key, current_capacity, mode, bailout); |
5961 | 5971 |
5962 checked_elements.Bind(new_elements); | 5972 checked_elements.Bind(new_elements); |
5963 Goto(&fits_capacity); | 5973 Goto(&fits_capacity); |
5964 } | 5974 } |
5965 Bind(&fits_capacity); | 5975 Bind(&fits_capacity); |
5966 | 5976 |
5967 if (is_js_array) { | 5977 if (is_js_array) { |
5968 Node* new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode)); | 5978 Node* new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode)); |
5969 StoreObjectFieldNoWriteBarrier(object, JSArray::kLengthOffset, | 5979 StoreObjectFieldNoWriteBarrier(object, JSArray::kLengthOffset, |
5970 TagParameter(new_length, mode)); | 5980 ParameterToTagged(new_length, mode)); |
5971 } | 5981 } |
5972 Goto(&done); | 5982 Goto(&done); |
5973 } | 5983 } |
5974 | 5984 |
5975 Bind(&no_grow_case); | 5985 Bind(&no_grow_case); |
5976 { | 5986 { |
5977 GotoUnless(UintPtrLessThan(key, length), bailout); | 5987 GotoUnless(UintPtrLessThan(key, length), bailout); |
5978 checked_elements.Bind(elements); | 5988 checked_elements.Bind(elements); |
5979 Goto(&done); | 5989 Goto(&done); |
5980 } | 5990 } |
5981 | 5991 |
5982 Bind(&done); | 5992 Bind(&done); |
5983 return checked_elements.value(); | 5993 return checked_elements.value(); |
5984 } | 5994 } |
5985 | 5995 |
5986 Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements, | 5996 Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements, |
5987 ElementsKind kind, Node* length, | 5997 ElementsKind kind, Node* length, |
5988 ParameterMode mode, | 5998 ParameterMode mode, |
5989 Label* bailout) { | 5999 Label* bailout) { |
5990 Variable new_elements_var(this, MachineRepresentation::kTagged); | 6000 Variable new_elements_var(this, MachineRepresentation::kTagged); |
5991 Label done(this); | 6001 Label done(this); |
5992 | 6002 |
5993 new_elements_var.Bind(elements); | 6003 new_elements_var.Bind(elements); |
5994 GotoUnless( | 6004 GotoUnless( |
5995 WordEqual(LoadMap(elements), LoadRoot(Heap::kFixedCOWArrayMapRootIndex)), | 6005 WordEqual(LoadMap(elements), LoadRoot(Heap::kFixedCOWArrayMapRootIndex)), |
5996 &done); | 6006 &done); |
5997 { | 6007 { |
5998 Node* capacity = UntagParameter(LoadFixedArrayBaseLength(elements), mode); | 6008 Node* capacity = |
| 6009 TaggedToParameter(LoadFixedArrayBaseLength(elements), mode); |
5999 Node* new_elements = GrowElementsCapacity(object, elements, kind, kind, | 6010 Node* new_elements = GrowElementsCapacity(object, elements, kind, kind, |
6000 length, capacity, mode, bailout); | 6011 length, capacity, mode, bailout); |
6001 | 6012 |
6002 new_elements_var.Bind(new_elements); | 6013 new_elements_var.Bind(new_elements); |
6003 Goto(&done); | 6014 Goto(&done); |
6004 } | 6015 } |
6005 | 6016 |
6006 Bind(&done); | 6017 Bind(&done); |
6007 return new_elements_var.value(); | 6018 return new_elements_var.value(); |
6008 } | 6019 } |
(...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7544 } | 7555 } |
7545 | 7556 |
7546 Bind(&end); | 7557 Bind(&end); |
7547 return result.value(); | 7558 return result.value(); |
7548 } | 7559 } |
7549 | 7560 |
7550 // ECMA#sec-samevalue | 7561 // ECMA#sec-samevalue |
7551 // This algorithm differs from the Strict Equality Comparison Algorithm in its | 7562 // This algorithm differs from the Strict Equality Comparison Algorithm in its |
7552 // treatment of signed zeroes and NaNs. | 7563 // treatment of signed zeroes and NaNs. |
7553 Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) { | 7564 Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) { |
7554 Variable var_result(this, MachineType::PointerRepresentation()); | 7565 Variable var_result(this, MachineRepresentation::kWord32); |
7555 Label strict_equal(this), out(this); | 7566 Label strict_equal(this), out(this); |
7556 | 7567 |
7557 Node* const int_false = IntPtrConstant(0); | 7568 Node* const int_false = Int32Constant(0); |
7558 Node* const int_true = IntPtrConstant(1); | 7569 Node* const int_true = Int32Constant(1); |
7559 | 7570 |
7560 Label if_equal(this), if_notequal(this); | 7571 Label if_equal(this), if_notequal(this); |
7561 Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal); | 7572 Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal); |
7562 | 7573 |
7563 Bind(&if_equal); | 7574 Bind(&if_equal); |
7564 { | 7575 { |
7565 // This covers the case when {lhs} == {rhs}. We can simply return true | 7576 // This covers the case when {lhs} == {rhs}. We can simply return true |
7566 // because SameValue considers two NaNs to be equal. | 7577 // because SameValue considers two NaNs to be equal. |
7567 | 7578 |
7568 var_result.Bind(int_true); | 7579 var_result.Bind(int_true); |
(...skipping 10 matching lines...) Expand all Loading... |
7579 | 7590 |
7580 Label if_lhsisnan(this), if_lhsnotnan(this); | 7591 Label if_lhsisnan(this), if_lhsnotnan(this); |
7581 BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan); | 7592 BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan); |
7582 | 7593 |
7583 Bind(&if_lhsisnan); | 7594 Bind(&if_lhsisnan); |
7584 { | 7595 { |
7585 // Return true iff {rhs} is NaN. | 7596 // Return true iff {rhs} is NaN. |
7586 | 7597 |
7587 Node* const result = | 7598 Node* const result = |
7588 SelectConstant(Float64Equal(rhs_float, rhs_float), int_false, | 7599 SelectConstant(Float64Equal(rhs_float, rhs_float), int_false, |
7589 int_true, MachineType::PointerRepresentation()); | 7600 int_true, MachineRepresentation::kWord32); |
7590 var_result.Bind(result); | 7601 var_result.Bind(result); |
7591 Goto(&out); | 7602 Goto(&out); |
7592 } | 7603 } |
7593 | 7604 |
7594 Bind(&if_lhsnotnan); | 7605 Bind(&if_lhsnotnan); |
7595 { | 7606 { |
7596 Label if_floatisequal(this), if_floatnotequal(this); | 7607 Label if_floatisequal(this), if_floatnotequal(this); |
7597 Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal, | 7608 Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal, |
7598 &if_floatnotequal); | 7609 &if_floatnotequal); |
7599 | 7610 |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7848 Node* one = SmiConstant(Smi::FromInt(1)); | 7859 Node* one = SmiConstant(Smi::FromInt(1)); |
7849 Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(value), | 7860 Node* pair = IntPtrAddWithOverflow(BitcastTaggedToWord(value), |
7850 BitcastTaggedToWord(one)); | 7861 BitcastTaggedToWord(one)); |
7851 Node* overflow = Projection(1, pair); | 7862 Node* overflow = Projection(1, pair); |
7852 | 7863 |
7853 // Check if the Smi addition overflowed. | 7864 // Check if the Smi addition overflowed. |
7854 Label if_overflow(this), if_notoverflow(this); | 7865 Label if_overflow(this), if_notoverflow(this); |
7855 Branch(overflow, &if_overflow, &if_notoverflow); | 7866 Branch(overflow, &if_overflow, &if_notoverflow); |
7856 | 7867 |
7857 Bind(&if_notoverflow); | 7868 Bind(&if_notoverflow); |
7858 var_result.Bind(Projection(0, pair)); | 7869 var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair))); |
7859 Goto(&end); | 7870 Goto(&end); |
7860 | 7871 |
7861 Bind(&if_overflow); | 7872 Bind(&if_overflow); |
7862 { | 7873 { |
7863 var_finc_value.Bind(SmiToFloat64(value)); | 7874 var_finc_value.Bind(SmiToFloat64(value)); |
7864 Goto(&do_finc); | 7875 Goto(&do_finc); |
7865 } | 7876 } |
7866 } | 7877 } |
7867 | 7878 |
7868 Bind(&if_isnotsmi); | 7879 Bind(&if_isnotsmi); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8032 GotoUnless(WordEqual(prototype, object_prototype), &if_isslow); | 8043 GotoUnless(WordEqual(prototype, object_prototype), &if_isslow); |
8033 | 8044 |
8034 map = LoadMap(prototype); | 8045 map = LoadMap(prototype); |
8035 prototype = LoadMapPrototype(map); | 8046 prototype = LoadMapPrototype(map); |
8036 Branch(IsNull(prototype), &if_ispacked, &if_isslow); | 8047 Branch(IsNull(prototype), &if_ispacked, &if_isslow); |
8037 } | 8048 } |
8038 Bind(&if_ispacked); | 8049 Bind(&if_ispacked); |
8039 { | 8050 { |
8040 Node* map_index = | 8051 Node* map_index = |
8041 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | 8052 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), |
8042 LoadMapElementsKind(array_map)); | 8053 ChangeUint32ToWord(LoadMapElementsKind(array_map))); |
8043 CSA_ASSERT(this, IntPtrGreaterThanOrEqual( | 8054 CSA_ASSERT(this, IntPtrGreaterThanOrEqual( |
8044 map_index, IntPtrConstant(kBaseMapIndex + | 8055 map_index, IntPtrConstant(kBaseMapIndex + |
8045 kFastIteratorOffset))); | 8056 kFastIteratorOffset))); |
8046 CSA_ASSERT(this, IntPtrLessThan(map_index, | 8057 CSA_ASSERT(this, IntPtrLessThan(map_index, |
8047 IntPtrConstant(kBaseMapIndex + | 8058 IntPtrConstant(kBaseMapIndex + |
8048 kSlowIteratorOffset))); | 8059 kSlowIteratorOffset))); |
8049 | 8060 |
8050 var_map_index.Bind(map_index); | 8061 var_map_index.Bind(map_index); |
8051 var_array_map.Bind(array_map); | 8062 var_array_map.Bind(array_map); |
8052 Goto(&allocate_iterator); | 8063 Goto(&allocate_iterator); |
8053 } | 8064 } |
8054 } | 8065 } |
8055 | 8066 |
8056 Bind(&if_isslow); | 8067 Bind(&if_isslow); |
8057 { | 8068 { |
8058 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), | 8069 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), |
8059 IntPtrConstant(kSlowIteratorOffset)); | 8070 IntPtrConstant(kSlowIteratorOffset)); |
8060 var_map_index.Bind(map_index); | 8071 var_map_index.Bind(map_index); |
8061 var_array_map.Bind(UndefinedConstant()); | 8072 var_array_map.Bind(UndefinedConstant()); |
8062 Goto(&allocate_iterator); | 8073 Goto(&allocate_iterator); |
8063 } | 8074 } |
8064 } | 8075 } |
8065 | 8076 |
8066 Bind(&if_istypedarray); | 8077 Bind(&if_istypedarray); |
8067 { | 8078 { |
8068 Node* map_index = | 8079 Node* map_index = |
8069 IntPtrAdd(IntPtrConstant(kBaseMapIndex - UINT8_ELEMENTS), | 8080 IntPtrAdd(IntPtrConstant(kBaseMapIndex - UINT8_ELEMENTS), |
8070 LoadMapElementsKind(array_map)); | 8081 ChangeUint32ToWord(LoadMapElementsKind(array_map))); |
8071 CSA_ASSERT( | 8082 CSA_ASSERT( |
8072 this, IntPtrLessThan(map_index, IntPtrConstant(kBaseMapIndex + | 8083 this, IntPtrLessThan(map_index, IntPtrConstant(kBaseMapIndex + |
8073 kFastIteratorOffset))); | 8084 kFastIteratorOffset))); |
8074 CSA_ASSERT(this, IntPtrGreaterThanOrEqual(map_index, | 8085 CSA_ASSERT(this, IntPtrGreaterThanOrEqual(map_index, |
8075 IntPtrConstant(kBaseMapIndex))); | 8086 IntPtrConstant(kBaseMapIndex))); |
8076 var_map_index.Bind(map_index); | 8087 var_map_index.Bind(map_index); |
8077 var_array_map.Bind(UndefinedConstant()); | 8088 var_array_map.Bind(UndefinedConstant()); |
8078 Goto(&allocate_iterator); | 8089 Goto(&allocate_iterator); |
8079 } | 8090 } |
8080 } | 8091 } |
(...skipping 26 matching lines...) Expand all Loading... |
8107 StoreObjectFieldNoWriteBarrier( | 8118 StoreObjectFieldNoWriteBarrier( |
8108 iterator, JSArrayIterator::kIteratedObjectMapOffset, array_map); | 8119 iterator, JSArrayIterator::kIteratedObjectMapOffset, array_map); |
8109 return iterator; | 8120 return iterator; |
8110 } | 8121 } |
8111 | 8122 |
8112 Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) { | 8123 Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) { |
8113 CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE)); | 8124 CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE)); |
8114 | 8125 |
8115 Node* buffer_bit_field = LoadObjectField( | 8126 Node* buffer_bit_field = LoadObjectField( |
8116 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8127 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8117 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8128 return IsSetWord32<JSArrayBuffer::WasNeutered>(buffer_bit_field); |
8118 | |
8119 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | |
8120 Int32Constant(0)); | |
8121 } | 8129 } |
8122 | 8130 |
8123 CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler, Node* argc, | 8131 CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler, Node* argc) |
8124 CodeStubAssembler::ParameterMode mode) | |
8125 : assembler_(assembler), | 8132 : assembler_(assembler), |
8126 argc_(argc), | 8133 argc_(argc), |
8127 arguments_(nullptr), | 8134 arguments_(nullptr), |
8128 fp_(assembler->LoadFramePointer()) { | 8135 fp_(assembler->LoadFramePointer()) { |
| 8136 argc_ = assembler->ChangeUint32ToWord(argc_); |
8129 Node* offset = assembler->ElementOffsetFromIndex( | 8137 Node* offset = assembler->ElementOffsetFromIndex( |
8130 argc_, FAST_ELEMENTS, mode, | 8138 argc_, FAST_ELEMENTS, CodeStubAssembler::INTPTR_PARAMETERS, |
8131 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); | 8139 (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kPointerSize); |
8132 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); | 8140 arguments_ = assembler_->IntPtrAddFoldConstants(fp_, offset); |
8133 if (mode == CodeStubAssembler::INTEGER_PARAMETERS) { | |
8134 argc_ = assembler->ChangeInt32ToIntPtr(argc_); | |
8135 } else if (mode == CodeStubAssembler::SMI_PARAMETERS) { | |
8136 argc_ = assembler->SmiUntag(argc_); | |
8137 } | |
8138 } | 8141 } |
8139 | 8142 |
8140 Node* CodeStubArguments::GetReceiver() const { | 8143 Node* CodeStubArguments::GetReceiver() const { |
8141 return assembler_->Load(MachineType::AnyTagged(), arguments_, | 8144 return assembler_->Load(MachineType::AnyTagged(), arguments_, |
8142 assembler_->IntPtrConstant(kPointerSize)); | 8145 assembler_->IntPtrConstant(kPointerSize)); |
8143 } | 8146 } |
8144 | 8147 |
8145 Node* CodeStubArguments::AtIndex(Node* index, | 8148 Node* CodeStubArguments::AtIndex(Node* index, |
8146 CodeStubAssembler::ParameterMode mode) const { | 8149 CodeStubAssembler::ParameterMode mode) const { |
8147 typedef compiler::Node Node; | 8150 typedef compiler::Node Node; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8204 | 8207 |
8205 // Check prototype chain if receiver does not have packed elements. | 8208 // Check prototype chain if receiver does not have packed elements. |
8206 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); | 8209 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); |
8207 return Word32Equal(holey_elements, Int32Constant(1)); | 8210 return Word32Equal(holey_elements, Int32Constant(1)); |
8208 } | 8211 } |
8209 | 8212 |
8210 Node* CodeStubAssembler::IsDebugActive() { | 8213 Node* CodeStubAssembler::IsDebugActive() { |
8211 Node* is_debug_active = Load( | 8214 Node* is_debug_active = Load( |
8212 MachineType::Uint8(), | 8215 MachineType::Uint8(), |
8213 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); | 8216 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); |
8214 return WordNotEqual(is_debug_active, Int32Constant(0)); | 8217 return Word32NotEqual(is_debug_active, Int32Constant(0)); |
8215 } | 8218 } |
8216 | 8219 |
8217 Node* CodeStubAssembler::IsPromiseHookEnabled() { | 8220 Node* CodeStubAssembler::IsPromiseHookEnabled() { |
8218 Node* const is_promisehook_enabled = | 8221 Node* const is_promisehook_enabled = |
8219 Load(MachineType::Uint8(), | 8222 Load(MachineType::Uint8(), |
8220 ExternalConstant( | 8223 ExternalConstant( |
8221 ExternalReference::is_promisehook_enabled_address(isolate()))); | 8224 ExternalReference::is_promisehook_enabled_address(isolate()))); |
8222 return WordNotEqual(is_promisehook_enabled, Int32Constant(0)); | 8225 return Word32NotEqual(is_promisehook_enabled, Int32Constant(0)); |
8223 } | 8226 } |
8224 | 8227 |
8225 Node* CodeStubAssembler::AllocateJSPromise(Node* context) { | 8228 Node* CodeStubAssembler::AllocateJSPromise(Node* context) { |
8226 Node* const native_context = LoadNativeContext(context); | 8229 Node* const native_context = LoadNativeContext(context); |
8227 Node* const promise_fun = | 8230 Node* const promise_fun = |
8228 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); | 8231 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); |
8229 Node* const initial_map = | 8232 Node* const initial_map = |
8230 LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset); | 8233 LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset); |
8231 Node* const instance = AllocateJSObjectFromMap(initial_map); | 8234 Node* const instance = AllocateJSObjectFromMap(initial_map); |
8232 | 8235 |
(...skipping 29 matching lines...) Expand all Loading... |
8262 Heap::kUndefinedValueRootIndex); | 8265 Heap::kUndefinedValueRootIndex); |
8263 StoreObjectFieldRoot(result, PromiseReactionJobInfo::kDebugNameOffset, | 8266 StoreObjectFieldRoot(result, PromiseReactionJobInfo::kDebugNameOffset, |
8264 Heap::kUndefinedValueRootIndex); | 8267 Heap::kUndefinedValueRootIndex); |
8265 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, | 8268 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, |
8266 context); | 8269 context); |
8267 return result; | 8270 return result; |
8268 } | 8271 } |
8269 | 8272 |
8270 } // namespace internal | 8273 } // namespace internal |
8271 } // namespace v8 | 8274 } // namespace v8 |
OLD | NEW |