| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 Branch(condition, &ok, ¬_ok); | 67 Branch(condition, &ok, ¬_ok); |
| 68 BIND(¬_ok); | 68 BIND(¬_ok); |
| 69 if (message != nullptr) { | 69 if (message != nullptr) { |
| 70 char chars[1024]; | 70 char chars[1024]; |
| 71 Vector<char> buffer(chars); | 71 Vector<char> buffer(chars); |
| 72 if (file != nullptr) { | 72 if (file != nullptr) { |
| 73 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); | 73 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); |
| 74 } else { | 74 } else { |
| 75 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); | 75 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); |
| 76 } | 76 } |
| 77 CallRuntime(Runtime::kGlobalPrint, SmiConstant(0), | 77 CallRuntime( |
| 78 HeapConstant(factory()->InternalizeUtf8String(&(buffer[0])))); | 78 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), |
| 79 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); |
| 79 } | 80 } |
| 80 DebugBreak(); | 81 DebugBreak(); |
| 81 Goto(&ok); | 82 Goto(&ok); |
| 82 BIND(&ok); | 83 BIND(&ok); |
| 83 Comment("] Assert"); | 84 Comment("] Assert"); |
| 84 } | 85 } |
| 85 | 86 |
| 86 Node* CodeStubAssembler::Select(Node* condition, const NodeGenerator& true_body, | 87 Node* CodeStubAssembler::Select(Node* condition, const NodeGenerator& true_body, |
| 87 const NodeGenerator& false_body, | 88 const NodeGenerator& false_body, |
| 88 MachineRepresentation rep) { | 89 MachineRepresentation rep) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 Node* CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(Node* value) { | 191 Node* CodeStubAssembler::IntPtrRoundUpToPowerOfTwo32(Node* value) { |
| 191 Comment("IntPtrRoundUpToPowerOfTwo32"); | 192 Comment("IntPtrRoundUpToPowerOfTwo32"); |
| 192 CSA_ASSERT(this, UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u))); | 193 CSA_ASSERT(this, UintPtrLessThanOrEqual(value, IntPtrConstant(0x80000000u))); |
| 193 value = IntPtrSub(value, IntPtrConstant(1)); | 194 value = IntPtrSub(value, IntPtrConstant(1)); |
| 194 for (int i = 1; i <= 16; i *= 2) { | 195 for (int i = 1; i <= 16; i *= 2) { |
| 195 value = WordOr(value, WordShr(value, IntPtrConstant(i))); | 196 value = WordOr(value, WordShr(value, IntPtrConstant(i))); |
| 196 } | 197 } |
| 197 return IntPtrAdd(value, IntPtrConstant(1)); | 198 return IntPtrAdd(value, IntPtrConstant(1)); |
| 198 } | 199 } |
| 199 | 200 |
| 200 Node* CodeStubAssembler::MatchesParameterMode(Node* value, ParameterMode mode) { | |
| 201 return (mode == SMI_PARAMETERS) ? TaggedIsSmi(value) : Int32Constant(1); | |
| 202 } | |
| 203 | |
| 204 Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { | 201 Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { |
| 205 // value && !(value & (value - 1)) | 202 // value && !(value & (value - 1)) |
| 206 return WordEqual( | 203 return WordEqual( |
| 207 Select( | 204 Select( |
| 208 WordEqual(value, IntPtrConstant(0)), | 205 WordEqual(value, IntPtrConstant(0)), |
| 209 [=] { return IntPtrConstant(1); }, | 206 [=] { return IntPtrConstant(1); }, |
| 210 [=] { return WordAnd(value, IntPtrSub(value, IntPtrConstant(1))); }, | 207 [=] { return WordAnd(value, IntPtrSub(value, IntPtrConstant(1))); }, |
| 211 MachineType::PointerRepresentation()), | 208 MachineType::PointerRepresentation()), |
| 212 IntPtrConstant(0)); | 209 IntPtrConstant(0)); |
| 213 } | 210 } |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 void CodeStubAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) { | 665 void CodeStubAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) { |
| 669 CodeAssembler::Bind(label, debug_info); | 666 CodeAssembler::Bind(label, debug_info); |
| 670 } | 667 } |
| 671 #else | 668 #else |
| 672 void CodeStubAssembler::Bind(Label* label) { CodeAssembler::Bind(label); } | 669 void CodeStubAssembler::Bind(Label* label) { CodeAssembler::Bind(label); } |
| 673 #endif // DEBUG | 670 #endif // DEBUG |
| 674 | 671 |
| 675 void CodeStubAssembler::BranchIfPrototypesHaveNoElements( | 672 void CodeStubAssembler::BranchIfPrototypesHaveNoElements( |
| 676 Node* receiver_map, Label* definitely_no_elements, | 673 Node* receiver_map, Label* definitely_no_elements, |
| 677 Label* possibly_elements) { | 674 Label* possibly_elements) { |
| 678 CSA_SLOW_ASSERT(this, IsMap(receiver_map)); | |
| 679 VARIABLE(var_map, MachineRepresentation::kTagged, receiver_map); | 675 VARIABLE(var_map, MachineRepresentation::kTagged, receiver_map); |
| 680 Label loop_body(this, &var_map); | 676 Label loop_body(this, &var_map); |
| 681 Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | 677 Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex); |
| 682 Goto(&loop_body); | 678 Goto(&loop_body); |
| 683 | 679 |
| 684 BIND(&loop_body); | 680 BIND(&loop_body); |
| 685 { | 681 { |
| 686 Node* map = var_map.value(); | 682 Node* map = var_map.value(); |
| 687 Node* prototype = LoadMapPrototype(map); | 683 Node* prototype = LoadMapPrototype(map); |
| 688 GotoIf(WordEqual(prototype, NullConstant()), definitely_no_elements); | 684 GotoIf(WordEqual(prototype, NullConstant()), definitely_no_elements); |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 result.Bind( | 1205 result.Bind( |
| 1210 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); | 1206 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); |
| 1211 Goto(&loop); | 1207 Goto(&loop); |
| 1212 } | 1208 } |
| 1213 BIND(&done); | 1209 BIND(&done); |
| 1214 return result.value(); | 1210 return result.value(); |
| 1215 } | 1211 } |
| 1216 | 1212 |
| 1217 Node* CodeStubAssembler::LoadSharedFunctionInfoSpecialField( | 1213 Node* CodeStubAssembler::LoadSharedFunctionInfoSpecialField( |
| 1218 Node* shared, int offset, ParameterMode mode) { | 1214 Node* shared, int offset, ParameterMode mode) { |
| 1219 CSA_SLOW_ASSERT(this, HasInstanceType(shared, SHARED_FUNCTION_INFO_TYPE)); | |
| 1220 if (Is64()) { | 1215 if (Is64()) { |
| 1221 Node* result = LoadObjectField(shared, offset, MachineType::Int32()); | 1216 Node* result = LoadObjectField(shared, offset, MachineType::Int32()); |
| 1222 if (mode == SMI_PARAMETERS) { | 1217 if (mode == SMI_PARAMETERS) { |
| 1223 result = SmiTag(result); | 1218 result = SmiTag(result); |
| 1224 } else { | 1219 } else { |
| 1225 result = ChangeUint32ToWord(result); | 1220 result = ChangeUint32ToWord(result); |
| 1226 } | 1221 } |
| 1227 return result; | 1222 return result; |
| 1228 } else { | 1223 } else { |
| 1229 Node* result = LoadObjectField(shared, offset); | 1224 Node* result = LoadObjectField(shared, offset); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1354 return AllocateHeapNumberWithValue(value); | 1349 return AllocateHeapNumberWithValue(value); |
| 1355 default: | 1350 default: |
| 1356 UNREACHABLE(); | 1351 UNREACHABLE(); |
| 1357 return nullptr; | 1352 return nullptr; |
| 1358 } | 1353 } |
| 1359 } | 1354 } |
| 1360 | 1355 |
| 1361 Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement( | 1356 Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement( |
| 1362 Node* object, Node* index_node, int additional_offset, | 1357 Node* object, Node* index_node, int additional_offset, |
| 1363 ParameterMode parameter_mode) { | 1358 ParameterMode parameter_mode) { |
| 1364 CSA_SLOW_ASSERT(this, IsFixedArray(object)); | |
| 1365 CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode)); | |
| 1366 int32_t header_size = | 1359 int32_t header_size = |
| 1367 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; | 1360 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; |
| 1368 #if V8_TARGET_LITTLE_ENDIAN | 1361 #if V8_TARGET_LITTLE_ENDIAN |
| 1369 if (Is64()) { | 1362 if (Is64()) { |
| 1370 header_size += kPointerSize / 2; | 1363 header_size += kPointerSize / 2; |
| 1371 } | 1364 } |
| 1372 #endif | 1365 #endif |
| 1373 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, | 1366 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, |
| 1374 parameter_mode, header_size); | 1367 parameter_mode, header_size); |
| 1375 if (Is64()) { | 1368 if (Is64()) { |
| 1376 return Load(MachineType::Int32(), object, offset); | 1369 return Load(MachineType::Int32(), object, offset); |
| 1377 } else { | 1370 } else { |
| 1378 return SmiToWord32(Load(MachineType::AnyTagged(), object, offset)); | 1371 return SmiToWord32(Load(MachineType::AnyTagged(), object, offset)); |
| 1379 } | 1372 } |
| 1380 } | 1373 } |
| 1381 | 1374 |
| 1382 Node* CodeStubAssembler::LoadFixedDoubleArrayElement( | 1375 Node* CodeStubAssembler::LoadFixedDoubleArrayElement( |
| 1383 Node* object, Node* index_node, MachineType machine_type, | 1376 Node* object, Node* index_node, MachineType machine_type, |
| 1384 int additional_offset, ParameterMode parameter_mode, Label* if_hole) { | 1377 int additional_offset, ParameterMode parameter_mode, Label* if_hole) { |
| 1385 CSA_SLOW_ASSERT(this, IsFixedDoubleArray(object)); | |
| 1386 CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode)); | |
| 1387 CSA_ASSERT(this, IsFixedDoubleArray(object)); | 1378 CSA_ASSERT(this, IsFixedDoubleArray(object)); |
| 1388 int32_t header_size = | 1379 int32_t header_size = |
| 1389 FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag; | 1380 FixedDoubleArray::kHeaderSize + additional_offset - kHeapObjectTag; |
| 1390 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS, | 1381 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_DOUBLE_ELEMENTS, |
| 1391 parameter_mode, header_size); | 1382 parameter_mode, header_size); |
| 1392 return LoadDoubleWithHoleCheck(object, offset, if_hole, machine_type); | 1383 return LoadDoubleWithHoleCheck(object, offset, if_hole, machine_type); |
| 1393 } | 1384 } |
| 1394 | 1385 |
| 1395 Node* CodeStubAssembler::LoadDoubleWithHoleCheck(Node* base, Node* offset, | 1386 Node* CodeStubAssembler::LoadDoubleWithHoleCheck(Node* base, Node* offset, |
| 1396 Label* if_hole, | 1387 Label* if_hole, |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 } else { | 1535 } else { |
| 1545 return StoreObjectField(object, offset, LoadRoot(root_index)); | 1536 return StoreObjectField(object, offset, LoadRoot(root_index)); |
| 1546 } | 1537 } |
| 1547 } | 1538 } |
| 1548 | 1539 |
| 1549 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node, | 1540 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node, |
| 1550 Node* value, | 1541 Node* value, |
| 1551 WriteBarrierMode barrier_mode, | 1542 WriteBarrierMode barrier_mode, |
| 1552 int additional_offset, | 1543 int additional_offset, |
| 1553 ParameterMode parameter_mode) { | 1544 ParameterMode parameter_mode) { |
| 1554 CSA_SLOW_ASSERT(this, IsFixedArray(object)); | |
| 1555 CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode)); | |
| 1556 DCHECK(barrier_mode == SKIP_WRITE_BARRIER || | 1545 DCHECK(barrier_mode == SKIP_WRITE_BARRIER || |
| 1557 barrier_mode == UPDATE_WRITE_BARRIER); | 1546 barrier_mode == UPDATE_WRITE_BARRIER); |
| 1558 int header_size = | 1547 int header_size = |
| 1559 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; | 1548 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; |
| 1560 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, | 1549 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, |
| 1561 parameter_mode, header_size); | 1550 parameter_mode, header_size); |
| 1562 if (barrier_mode == SKIP_WRITE_BARRIER) { | 1551 if (barrier_mode == SKIP_WRITE_BARRIER) { |
| 1563 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, | 1552 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, |
| 1564 value); | 1553 value); |
| 1565 } else { | 1554 } else { |
| 1566 return Store(object, offset, value); | 1555 return Store(object, offset, value); |
| 1567 } | 1556 } |
| 1568 } | 1557 } |
| 1569 | 1558 |
| 1570 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( | 1559 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( |
| 1571 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { | 1560 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { |
| 1572 CSA_ASSERT(this, IsFixedDoubleArray(object)); | 1561 CSA_ASSERT(this, IsFixedDoubleArray(object)); |
| 1573 CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode)); | |
| 1574 Node* offset = | 1562 Node* offset = |
| 1575 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, | 1563 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, |
| 1576 FixedArray::kHeaderSize - kHeapObjectTag); | 1564 FixedArray::kHeaderSize - kHeapObjectTag); |
| 1577 MachineRepresentation rep = MachineRepresentation::kFloat64; | 1565 MachineRepresentation rep = MachineRepresentation::kFloat64; |
| 1578 return StoreNoWriteBarrier(rep, object, offset, value); | 1566 return StoreNoWriteBarrier(rep, object, offset, value); |
| 1579 } | 1567 } |
| 1580 | 1568 |
| 1581 void CodeStubAssembler::EnsureArrayLengthWritable(Node* map, Label* bailout) { | 1569 void CodeStubAssembler::EnsureArrayLengthWritable(Node* map, Label* bailout) { |
| 1582 // Check whether the length property is writable. The length property is the | 1570 // Check whether the length property is writable. The length property is the |
| 1583 // only default named property on arrays. It's nonconfigurable, hence is | 1571 // only default named property on arrays. It's nonconfigurable, hence is |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 kind, capacity, new_capacity, mode, | 1613 kind, capacity, new_capacity, mode, |
| 1626 bailout)); | 1614 bailout)); |
| 1627 Goto(&fits); | 1615 Goto(&fits); |
| 1628 BIND(&fits); | 1616 BIND(&fits); |
| 1629 } | 1617 } |
| 1630 | 1618 |
| 1631 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array, | 1619 Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array, |
| 1632 CodeStubArguments& args, | 1620 CodeStubArguments& args, |
| 1633 Variable& arg_index, | 1621 Variable& arg_index, |
| 1634 Label* bailout) { | 1622 Label* bailout) { |
| 1635 CSA_SLOW_ASSERT(this, IsJSArray(array)); | |
| 1636 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); | 1623 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); |
| 1637 Label pre_bailout(this); | 1624 Label pre_bailout(this); |
| 1638 Label success(this); | 1625 Label success(this); |
| 1639 VARIABLE(var_tagged_length, MachineRepresentation::kTagged); | 1626 VARIABLE(var_tagged_length, MachineRepresentation::kTagged); |
| 1640 ParameterMode mode = OptimalParameterMode(); | 1627 ParameterMode mode = OptimalParameterMode(); |
| 1641 VARIABLE(var_length, OptimalParameterRepresentation(), | 1628 VARIABLE(var_length, OptimalParameterRepresentation(), |
| 1642 TaggedToParameter(LoadJSArrayLength(array), mode)); | 1629 TaggedToParameter(LoadJSArrayLength(array), mode)); |
| 1643 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); | 1630 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); |
| 1644 | 1631 |
| 1645 // Resize the capacity of the fixed array if it doesn't fit. | 1632 // Resize the capacity of the fixed array if it doesn't fit. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 Float64SilenceNaN(double_value), mode); | 1683 Float64SilenceNaN(double_value), mode); |
| 1697 } else { | 1684 } else { |
| 1698 WriteBarrierMode barrier_mode = | 1685 WriteBarrierMode barrier_mode = |
| 1699 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; | 1686 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; |
| 1700 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode); | 1687 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode); |
| 1701 } | 1688 } |
| 1702 } | 1689 } |
| 1703 | 1690 |
| 1704 void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array, | 1691 void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array, |
| 1705 Node* value, Label* bailout) { | 1692 Node* value, Label* bailout) { |
| 1706 CSA_SLOW_ASSERT(this, IsJSArray(array)); | |
| 1707 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); | 1693 Comment("BuildAppendJSArray: %s", ElementsKindToString(kind)); |
| 1708 ParameterMode mode = OptimalParameterMode(); | 1694 ParameterMode mode = OptimalParameterMode(); |
| 1709 VARIABLE(var_length, OptimalParameterRepresentation(), | 1695 VARIABLE(var_length, OptimalParameterRepresentation(), |
| 1710 TaggedToParameter(LoadJSArrayLength(array), mode)); | 1696 TaggedToParameter(LoadJSArrayLength(array), mode)); |
| 1711 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); | 1697 VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); |
| 1712 | 1698 |
| 1713 // Resize the capacity of the fixed array if it doesn't fit. | 1699 // Resize the capacity of the fixed array if it doesn't fit. |
| 1714 Node* growth = IntPtrOrSmiConstant(1, mode); | 1700 Node* growth = IntPtrOrSmiConstant(1, mode); |
| 1715 PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(), | 1701 PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(), |
| 1716 &var_elements, growth, bailout); | 1702 &var_elements, growth, bailout); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, | 1742 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, |
| 1757 IntPtrConstant(String::kEmptyHashField), | 1743 IntPtrConstant(String::kEmptyHashField), |
| 1758 MachineType::PointerRepresentation()); | 1744 MachineType::PointerRepresentation()); |
| 1759 return result; | 1745 return result; |
| 1760 } | 1746 } |
| 1761 | 1747 |
| 1762 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, | 1748 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, |
| 1763 ParameterMode mode, | 1749 ParameterMode mode, |
| 1764 AllocationFlags flags) { | 1750 AllocationFlags flags) { |
| 1765 Comment("AllocateSeqOneByteString"); | 1751 Comment("AllocateSeqOneByteString"); |
| 1766 CSA_SLOW_ASSERT(this, IsFixedArray(context)); | |
| 1767 CSA_SLOW_ASSERT(this, MatchesParameterMode(length, mode)); | |
| 1768 VARIABLE(var_result, MachineRepresentation::kTagged); | 1752 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 1769 | 1753 |
| 1770 // Compute the SeqOneByteString size and check if it fits into new space. | 1754 // Compute the SeqOneByteString size and check if it fits into new space. |
| 1771 Label if_lengthiszero(this), if_sizeissmall(this), | 1755 Label if_lengthiszero(this), if_sizeissmall(this), |
| 1772 if_notsizeissmall(this, Label::kDeferred), if_join(this); | 1756 if_notsizeissmall(this, Label::kDeferred), if_join(this); |
| 1773 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero); | 1757 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero); |
| 1774 | 1758 |
| 1775 Node* raw_size = GetArrayAllocationSize( | 1759 Node* raw_size = GetArrayAllocationSize( |
| 1776 length, UINT8_ELEMENTS, mode, | 1760 length, UINT8_ELEMENTS, mode, |
| 1777 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); | 1761 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 // Initialize both used and unused parts of hash field slot at once. | 1812 // Initialize both used and unused parts of hash field slot at once. |
| 1829 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, | 1813 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, |
| 1830 IntPtrConstant(String::kEmptyHashField), | 1814 IntPtrConstant(String::kEmptyHashField), |
| 1831 MachineType::PointerRepresentation()); | 1815 MachineType::PointerRepresentation()); |
| 1832 return result; | 1816 return result; |
| 1833 } | 1817 } |
| 1834 | 1818 |
| 1835 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, | 1819 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, |
| 1836 ParameterMode mode, | 1820 ParameterMode mode, |
| 1837 AllocationFlags flags) { | 1821 AllocationFlags flags) { |
| 1838 CSA_SLOW_ASSERT(this, IsFixedArray(context)); | |
| 1839 CSA_SLOW_ASSERT(this, MatchesParameterMode(length, mode)); | |
| 1840 Comment("AllocateSeqTwoByteString"); | 1822 Comment("AllocateSeqTwoByteString"); |
| 1841 VARIABLE(var_result, MachineRepresentation::kTagged); | 1823 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 1842 | 1824 |
| 1843 // Compute the SeqTwoByteString size and check if it fits into new space. | 1825 // Compute the SeqTwoByteString size and check if it fits into new space. |
| 1844 Label if_lengthiszero(this), if_sizeissmall(this), | 1826 Label if_lengthiszero(this), if_sizeissmall(this), |
| 1845 if_notsizeissmall(this, Label::kDeferred), if_join(this); | 1827 if_notsizeissmall(this, Label::kDeferred), if_join(this); |
| 1846 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero); | 1828 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero); |
| 1847 | 1829 |
| 1848 Node* raw_size = GetArrayAllocationSize( | 1830 Node* raw_size = GetArrayAllocationSize( |
| 1849 length, UINT16_ELEMENTS, mode, | 1831 length, UINT16_ELEMENTS, mode, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1885 Goto(&if_join); | 1867 Goto(&if_join); |
| 1886 } | 1868 } |
| 1887 | 1869 |
| 1888 BIND(&if_join); | 1870 BIND(&if_join); |
| 1889 return var_result.value(); | 1871 return var_result.value(); |
| 1890 } | 1872 } |
| 1891 | 1873 |
| 1892 Node* CodeStubAssembler::AllocateSlicedString( | 1874 Node* CodeStubAssembler::AllocateSlicedString( |
| 1893 Heap::RootListIndex map_root_index, Node* length, Node* parent, | 1875 Heap::RootListIndex map_root_index, Node* length, Node* parent, |
| 1894 Node* offset) { | 1876 Node* offset) { |
| 1895 CSA_ASSERT(this, IsString(parent)); | |
| 1896 CSA_ASSERT(this, TaggedIsSmi(length)); | 1877 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 1897 CSA_ASSERT(this, TaggedIsSmi(offset)); | |
| 1898 Node* result = Allocate(SlicedString::kSize); | 1878 Node* result = Allocate(SlicedString::kSize); |
| 1899 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); | 1879 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |
| 1900 StoreMapNoWriteBarrier(result, map_root_index); | 1880 StoreMapNoWriteBarrier(result, map_root_index); |
| 1901 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, | 1881 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, |
| 1902 MachineRepresentation::kTagged); | 1882 MachineRepresentation::kTagged); |
| 1903 // Initialize both used and unused parts of hash field slot at once. | 1883 // Initialize both used and unused parts of hash field slot at once. |
| 1904 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldSlot, | 1884 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldSlot, |
| 1905 IntPtrConstant(String::kEmptyHashField), | 1885 IntPtrConstant(String::kEmptyHashField), |
| 1906 MachineType::PointerRepresentation()); | 1886 MachineType::PointerRepresentation()); |
| 1907 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, | 1887 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1920 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent, | 1900 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent, |
| 1921 Node* offset) { | 1901 Node* offset) { |
| 1922 return AllocateSlicedString(Heap::kSlicedStringMapRootIndex, length, parent, | 1902 return AllocateSlicedString(Heap::kSlicedStringMapRootIndex, length, parent, |
| 1923 offset); | 1903 offset); |
| 1924 } | 1904 } |
| 1925 | 1905 |
| 1926 Node* CodeStubAssembler::AllocateConsString(Heap::RootListIndex map_root_index, | 1906 Node* CodeStubAssembler::AllocateConsString(Heap::RootListIndex map_root_index, |
| 1927 Node* length, Node* first, | 1907 Node* length, Node* first, |
| 1928 Node* second, | 1908 Node* second, |
| 1929 AllocationFlags flags) { | 1909 AllocationFlags flags) { |
| 1930 CSA_ASSERT(this, IsString(first)); | |
| 1931 CSA_ASSERT(this, IsString(second)); | |
| 1932 CSA_ASSERT(this, TaggedIsSmi(length)); | 1910 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 1933 Node* result = Allocate(ConsString::kSize, flags); | 1911 Node* result = Allocate(ConsString::kSize, flags); |
| 1934 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); | 1912 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |
| 1935 StoreMapNoWriteBarrier(result, map_root_index); | 1913 StoreMapNoWriteBarrier(result, map_root_index); |
| 1936 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, | 1914 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, |
| 1937 MachineRepresentation::kTagged); | 1915 MachineRepresentation::kTagged); |
| 1938 // Initialize both used and unused parts of hash field slot at once. | 1916 // Initialize both used and unused parts of hash field slot at once. |
| 1939 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldSlot, | 1917 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldSlot, |
| 1940 IntPtrConstant(String::kEmptyHashField), | 1918 IntPtrConstant(String::kEmptyHashField), |
| 1941 MachineType::PointerRepresentation()); | 1919 MachineType::PointerRepresentation()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1961 | 1939 |
| 1962 Node* CodeStubAssembler::AllocateTwoByteConsString(Node* length, Node* first, | 1940 Node* CodeStubAssembler::AllocateTwoByteConsString(Node* length, Node* first, |
| 1963 Node* second, | 1941 Node* second, |
| 1964 AllocationFlags flags) { | 1942 AllocationFlags flags) { |
| 1965 return AllocateConsString(Heap::kConsStringMapRootIndex, length, first, | 1943 return AllocateConsString(Heap::kConsStringMapRootIndex, length, first, |
| 1966 second, flags); | 1944 second, flags); |
| 1967 } | 1945 } |
| 1968 | 1946 |
| 1969 Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left, | 1947 Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left, |
| 1970 Node* right, AllocationFlags flags) { | 1948 Node* right, AllocationFlags flags) { |
| 1971 CSA_ASSERT(this, IsFixedArray(context)); | |
| 1972 CSA_ASSERT(this, IsString(left)); | |
| 1973 CSA_ASSERT(this, IsString(right)); | |
| 1974 CSA_ASSERT(this, TaggedIsSmi(length)); | 1949 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 1975 // Added string can be a cons string. | 1950 // Added string can be a cons string. |
| 1976 Comment("Allocating ConsString"); | 1951 Comment("Allocating ConsString"); |
| 1977 Node* left_instance_type = LoadInstanceType(left); | 1952 Node* left_instance_type = LoadInstanceType(left); |
| 1978 Node* right_instance_type = LoadInstanceType(right); | 1953 Node* right_instance_type = LoadInstanceType(right); |
| 1979 | 1954 |
| 1980 // Compute intersection and difference of instance types. | 1955 // Compute intersection and difference of instance types. |
| 1981 Node* anded_instance_types = | 1956 Node* anded_instance_types = |
| 1982 Word32And(left_instance_type, right_instance_type); | 1957 Word32And(left_instance_type, right_instance_type); |
| 1983 Node* xored_instance_types = | 1958 Node* xored_instance_types = |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2019 result.Bind(AllocateTwoByteConsString(length, left, right, flags)); | 1994 result.Bind(AllocateTwoByteConsString(length, left, right, flags)); |
| 2020 Goto(&done); | 1995 Goto(&done); |
| 2021 | 1996 |
| 2022 BIND(&done); | 1997 BIND(&done); |
| 2023 | 1998 |
| 2024 return result.value(); | 1999 return result.value(); |
| 2025 } | 2000 } |
| 2026 | 2001 |
| 2027 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, | 2002 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, |
| 2028 Node* index, Node* input) { | 2003 Node* index, Node* input) { |
| 2029 CSA_ASSERT(this, IsFixedArray(context)); | |
| 2030 CSA_ASSERT(this, TaggedIsSmi(index)); | |
| 2031 CSA_ASSERT(this, TaggedIsSmi(length)); | |
| 2032 CSA_ASSERT(this, IsString(input)); | |
| 2033 | |
| 2034 #ifdef DEBUG | |
| 2035 Node* const max_length = | 2004 Node* const max_length = |
| 2036 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); | 2005 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); |
| 2037 CSA_ASSERT(this, SmiLessThanOrEqual(length, max_length)); | 2006 CSA_ASSERT(this, SmiLessThanOrEqual(length, max_length)); |
| 2038 #endif // DEBUG | 2007 USE(max_length); |
| 2039 | 2008 |
| 2040 // Allocate the JSRegExpResult. | 2009 // Allocate the JSRegExpResult. |
| 2041 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove | 2010 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove |
| 2042 // unneeded store of elements. | 2011 // unneeded store of elements. |
| 2043 Node* const result = Allocate(JSRegExpResult::kSize); | 2012 Node* const result = Allocate(JSRegExpResult::kSize); |
| 2044 | 2013 |
| 2045 // TODO(jgruber): Store map as Heap constant? | 2014 // TODO(jgruber): Store map as Heap constant? |
| 2046 Node* const native_context = LoadNativeContext(context); | 2015 Node* const native_context = LoadNativeContext(context); |
| 2047 Node* const map = | 2016 Node* const map = |
| 2048 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); | 2017 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 Node* size = TimesPointerSize(LoadMapInstanceSize(map)); | 2118 Node* size = TimesPointerSize(LoadMapInstanceSize(map)); |
| 2150 Node* object = AllocateInNewSpace(size, flags); | 2119 Node* object = AllocateInNewSpace(size, flags); |
| 2151 StoreMapNoWriteBarrier(object, map); | 2120 StoreMapNoWriteBarrier(object, map); |
| 2152 InitializeJSObjectFromMap(object, map, size, properties, elements); | 2121 InitializeJSObjectFromMap(object, map, size, properties, elements); |
| 2153 return object; | 2122 return object; |
| 2154 } | 2123 } |
| 2155 | 2124 |
| 2156 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, | 2125 void CodeStubAssembler::InitializeJSObjectFromMap(Node* object, Node* map, |
| 2157 Node* size, Node* properties, | 2126 Node* size, Node* properties, |
| 2158 Node* elements) { | 2127 Node* elements) { |
| 2159 CSA_SLOW_ASSERT(this, IsMap(map)); | |
| 2160 // This helper assumes that the object is in new-space, as guarded by the | 2128 // This helper assumes that the object is in new-space, as guarded by the |
| 2161 // check in AllocatedJSObjectFromMap. | 2129 // check in AllocatedJSObjectFromMap. |
| 2162 if (properties == nullptr) { | 2130 if (properties == nullptr) { |
| 2163 CSA_ASSERT(this, Word32BinaryNot(IsDictionaryMap((map)))); | 2131 CSA_ASSERT(this, Word32BinaryNot(IsDictionaryMap((map)))); |
| 2164 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, | 2132 StoreObjectFieldRoot(object, JSObject::kPropertiesOffset, |
| 2165 Heap::kEmptyFixedArrayRootIndex); | 2133 Heap::kEmptyFixedArrayRootIndex); |
| 2166 } else { | 2134 } else { |
| 2167 CSA_ASSERT(this, IsFixedArray(properties)); | |
| 2168 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, | 2135 StoreObjectFieldNoWriteBarrier(object, JSObject::kPropertiesOffset, |
| 2169 properties); | 2136 properties); |
| 2170 } | 2137 } |
| 2171 if (elements == nullptr) { | 2138 if (elements == nullptr) { |
| 2172 StoreObjectFieldRoot(object, JSObject::kElementsOffset, | 2139 StoreObjectFieldRoot(object, JSObject::kElementsOffset, |
| 2173 Heap::kEmptyFixedArrayRootIndex); | 2140 Heap::kEmptyFixedArrayRootIndex); |
| 2174 } else { | 2141 } else { |
| 2175 CSA_ASSERT(this, IsFixedArray(elements)); | |
| 2176 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements); | 2142 StoreObjectFieldNoWriteBarrier(object, JSObject::kElementsOffset, elements); |
| 2177 } | 2143 } |
| 2178 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize); | 2144 InitializeJSObjectBody(object, map, size, JSObject::kHeaderSize); |
| 2179 } | 2145 } |
| 2180 | 2146 |
| 2181 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map, | 2147 void CodeStubAssembler::InitializeJSObjectBody(Node* object, Node* map, |
| 2182 Node* size, int start_offset) { | 2148 Node* size, int start_offset) { |
| 2183 CSA_SLOW_ASSERT(this, IsMap(map)); | |
| 2184 // TODO(cbruni): activate in-object slack tracking machinery. | 2149 // TODO(cbruni): activate in-object slack tracking machinery. |
| 2185 Comment("InitializeJSObjectBody"); | 2150 Comment("InitializeJSObjectBody"); |
| 2186 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); | 2151 Node* filler = LoadRoot(Heap::kUndefinedValueRootIndex); |
| 2187 // Calculate the untagged field addresses. | 2152 // Calculate the untagged field addresses. |
| 2188 object = BitcastTaggedToWord(object); | 2153 object = BitcastTaggedToWord(object); |
| 2189 Node* start_address = | 2154 Node* start_address = |
| 2190 IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag)); | 2155 IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag)); |
| 2191 Node* end_address = | 2156 Node* end_address = |
| 2192 IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag)); | 2157 IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag)); |
| 2193 StoreFieldsNoWriteBarrier(start_address, end_address, filler); | 2158 StoreFieldsNoWriteBarrier(start_address, end_address, filler); |
| 2194 } | 2159 } |
| 2195 | 2160 |
| 2196 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, | 2161 void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, |
| 2197 Node* end_address, | 2162 Node* end_address, |
| 2198 Node* value) { | 2163 Node* value) { |
| 2199 Comment("StoreFieldsNoWriteBarrier"); | 2164 Comment("StoreFieldsNoWriteBarrier"); |
| 2200 CSA_ASSERT(this, WordIsWordAligned(start_address)); | 2165 CSA_ASSERT(this, WordIsWordAligned(start_address)); |
| 2201 CSA_ASSERT(this, WordIsWordAligned(end_address)); | 2166 CSA_ASSERT(this, WordIsWordAligned(end_address)); |
| 2202 BuildFastLoop(start_address, end_address, | 2167 BuildFastLoop(start_address, end_address, |
| 2203 [this, value](Node* current) { | 2168 [this, value](Node* current) { |
| 2204 StoreNoWriteBarrier(MachineRepresentation::kTagged, current, | 2169 StoreNoWriteBarrier(MachineRepresentation::kTagged, current, |
| 2205 value); | 2170 value); |
| 2206 }, | 2171 }, |
| 2207 kPointerSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); | 2172 kPointerSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); |
| 2208 } | 2173 } |
| 2209 | 2174 |
| 2210 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( | 2175 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( |
| 2211 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { | 2176 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { |
| 2212 Comment("begin allocation of JSArray without elements"); | 2177 Comment("begin allocation of JSArray without elements"); |
| 2213 CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); | |
| 2214 CSA_SLOW_ASSERT(this, IsMap(array_map)); | |
| 2215 int base_size = JSArray::kSize; | 2178 int base_size = JSArray::kSize; |
| 2216 if (allocation_site != nullptr) { | 2179 if (allocation_site != nullptr) { |
| 2217 base_size += AllocationMemento::kSize; | 2180 base_size += AllocationMemento::kSize; |
| 2218 } | 2181 } |
| 2219 | 2182 |
| 2220 Node* size = IntPtrConstant(base_size); | 2183 Node* size = IntPtrConstant(base_size); |
| 2221 Node* array = AllocateUninitializedJSArray(kind, array_map, length, | 2184 Node* array = AllocateUninitializedJSArray(kind, array_map, length, |
| 2222 allocation_site, size); | 2185 allocation_site, size); |
| 2223 return array; | 2186 return array; |
| 2224 } | 2187 } |
| 2225 | 2188 |
| 2226 std::pair<Node*, Node*> | 2189 std::pair<Node*, Node*> |
| 2227 CodeStubAssembler::AllocateUninitializedJSArrayWithElements( | 2190 CodeStubAssembler::AllocateUninitializedJSArrayWithElements( |
| 2228 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site, | 2191 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site, |
| 2229 Node* capacity, ParameterMode capacity_mode) { | 2192 Node* capacity, ParameterMode capacity_mode) { |
| 2230 Comment("begin allocation of JSArray with elements"); | 2193 Comment("begin allocation of JSArray with elements"); |
| 2231 CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); | |
| 2232 CSA_SLOW_ASSERT(this, IsMap(array_map)); | |
| 2233 int base_size = JSArray::kSize; | 2194 int base_size = JSArray::kSize; |
| 2234 | 2195 |
| 2235 if (allocation_site != nullptr) { | 2196 if (allocation_site != nullptr) { |
| 2236 base_size += AllocationMemento::kSize; | 2197 base_size += AllocationMemento::kSize; |
| 2237 } | 2198 } |
| 2238 | 2199 |
| 2239 int elements_offset = base_size; | 2200 int elements_offset = base_size; |
| 2240 | 2201 |
| 2241 // Compute space for elements | 2202 // Compute space for elements |
| 2242 base_size += FixedArray::kHeaderSize; | 2203 base_size += FixedArray::kHeaderSize; |
| 2243 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); | 2204 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); |
| 2244 | 2205 |
| 2245 Node* array = AllocateUninitializedJSArray(kind, array_map, length, | 2206 Node* array = AllocateUninitializedJSArray(kind, array_map, length, |
| 2246 allocation_site, size); | 2207 allocation_site, size); |
| 2247 | 2208 |
| 2248 Node* elements = InnerAllocate(array, elements_offset); | 2209 Node* elements = InnerAllocate(array, elements_offset); |
| 2249 StoreObjectFieldNoWriteBarrier(array, JSObject::kElementsOffset, elements); | 2210 StoreObjectFieldNoWriteBarrier(array, JSObject::kElementsOffset, elements); |
| 2250 | 2211 |
| 2251 return {array, elements}; | 2212 return {array, elements}; |
| 2252 } | 2213 } |
| 2253 | 2214 |
| 2254 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, | 2215 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, |
| 2255 Node* array_map, | 2216 Node* array_map, |
| 2256 Node* length, | 2217 Node* length, |
| 2257 Node* allocation_site, | 2218 Node* allocation_site, |
| 2258 Node* size_in_bytes) { | 2219 Node* size_in_bytes) { |
| 2259 CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); | |
| 2260 CSA_SLOW_ASSERT(this, IsMap(array_map)); | |
| 2261 | |
| 2262 // Allocate space for the JSArray and the elements FixedArray in one go. | 2220 // Allocate space for the JSArray and the elements FixedArray in one go. |
| 2263 Node* array = AllocateInNewSpace(size_in_bytes); | 2221 Node* array = AllocateInNewSpace(size_in_bytes); |
| 2264 | 2222 |
| 2265 Comment("write JSArray headers"); | 2223 Comment("write JSArray headers"); |
| 2266 StoreMapNoWriteBarrier(array, array_map); | 2224 StoreMapNoWriteBarrier(array, array_map); |
| 2267 | 2225 |
| 2226 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 2268 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); | 2227 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); |
| 2269 | 2228 |
| 2270 StoreObjectFieldRoot(array, JSArray::kPropertiesOffset, | 2229 StoreObjectFieldRoot(array, JSArray::kPropertiesOffset, |
| 2271 Heap::kEmptyFixedArrayRootIndex); | 2230 Heap::kEmptyFixedArrayRootIndex); |
| 2272 | 2231 |
| 2273 if (allocation_site != nullptr) { | 2232 if (allocation_site != nullptr) { |
| 2274 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); | 2233 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); |
| 2275 } | 2234 } |
| 2276 return array; | 2235 return array; |
| 2277 } | 2236 } |
| 2278 | 2237 |
| 2279 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, | 2238 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, |
| 2280 Node* capacity, Node* length, | 2239 Node* capacity, Node* length, |
| 2281 Node* allocation_site, | 2240 Node* allocation_site, |
| 2282 ParameterMode capacity_mode) { | 2241 ParameterMode capacity_mode) { |
| 2283 CSA_SLOW_ASSERT(this, IsMap(array_map)); | |
| 2284 CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); | |
| 2285 CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity, capacity_mode)); | |
| 2286 | |
| 2287 Node *array = nullptr, *elements = nullptr; | 2242 Node *array = nullptr, *elements = nullptr; |
| 2288 if (IsIntPtrOrSmiConstantZero(capacity)) { | 2243 if (IsIntPtrOrSmiConstantZero(capacity)) { |
| 2289 // Array is empty. Use the shared empty fixed array instead of allocating a | 2244 // Array is empty. Use the shared empty fixed array instead of allocating a |
| 2290 // new one. | 2245 // new one. |
| 2291 array = AllocateUninitializedJSArrayWithoutElements(kind, array_map, length, | 2246 array = AllocateUninitializedJSArrayWithoutElements(kind, array_map, length, |
| 2292 nullptr); | 2247 nullptr); |
| 2293 StoreObjectFieldRoot(array, JSArray::kElementsOffset, | 2248 StoreObjectFieldRoot(array, JSArray::kElementsOffset, |
| 2294 Heap::kEmptyFixedArrayRootIndex); | 2249 Heap::kEmptyFixedArrayRootIndex); |
| 2295 } else { | 2250 } else { |
| 2296 // Allocate both array and elements object, and initialize the JSArray. | 2251 // Allocate both array and elements object, and initialize the JSArray. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2310 Heap::kTheHoleValueRootIndex, capacity_mode); | 2265 Heap::kTheHoleValueRootIndex, capacity_mode); |
| 2311 } | 2266 } |
| 2312 | 2267 |
| 2313 return array; | 2268 return array; |
| 2314 } | 2269 } |
| 2315 | 2270 |
| 2316 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, | 2271 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, |
| 2317 Node* capacity_node, | 2272 Node* capacity_node, |
| 2318 ParameterMode mode, | 2273 ParameterMode mode, |
| 2319 AllocationFlags flags) { | 2274 AllocationFlags flags) { |
| 2320 CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity_node, mode)); | |
| 2321 CSA_ASSERT(this, IntPtrOrSmiGreaterThan(capacity_node, | 2275 CSA_ASSERT(this, IntPtrOrSmiGreaterThan(capacity_node, |
| 2322 IntPtrOrSmiConstant(0, mode), mode)); | 2276 IntPtrOrSmiConstant(0, mode), mode)); |
| 2323 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); | 2277 Node* total_size = GetFixedArrayAllocationSize(capacity_node, kind, mode); |
| 2324 | 2278 |
| 2325 // Allocate both array and elements object, and initialize the JSArray. | 2279 // Allocate both array and elements object, and initialize the JSArray. |
| 2326 Node* array = Allocate(total_size, flags); | 2280 Node* array = Allocate(total_size, flags); |
| 2327 Heap::RootListIndex map_index = IsFastDoubleElementsKind(kind) | 2281 Heap::RootListIndex map_index = IsFastDoubleElementsKind(kind) |
| 2328 ? Heap::kFixedDoubleArrayMapRootIndex | 2282 ? Heap::kFixedDoubleArrayMapRootIndex |
| 2329 : Heap::kFixedArrayMapRootIndex; | 2283 : Heap::kFixedArrayMapRootIndex; |
| 2330 DCHECK(Heap::RootIsImmortalImmovable(map_index)); | 2284 DCHECK(Heap::RootIsImmortalImmovable(map_index)); |
| 2331 StoreMapNoWriteBarrier(array, map_index); | 2285 StoreMapNoWriteBarrier(array, map_index); |
| 2332 StoreObjectFieldNoWriteBarrier(array, FixedArray::kLengthOffset, | 2286 StoreObjectFieldNoWriteBarrier(array, FixedArray::kLengthOffset, |
| 2333 ParameterToTagged(capacity_node, mode)); | 2287 ParameterToTagged(capacity_node, mode)); |
| 2334 return array; | 2288 return array; |
| 2335 } | 2289 } |
| 2336 | 2290 |
| 2337 void CodeStubAssembler::FillFixedArrayWithValue( | 2291 void CodeStubAssembler::FillFixedArrayWithValue( |
| 2338 ElementsKind kind, Node* array, Node* from_node, Node* to_node, | 2292 ElementsKind kind, Node* array, Node* from_node, Node* to_node, |
| 2339 Heap::RootListIndex value_root_index, ParameterMode mode) { | 2293 Heap::RootListIndex value_root_index, ParameterMode mode) { |
| 2340 CSA_SLOW_ASSERT(this, MatchesParameterMode(from_node, mode)); | |
| 2341 CSA_SLOW_ASSERT(this, MatchesParameterMode(to_node, mode)); | |
| 2342 CSA_SLOW_ASSERT(this, IsFixedArrayWithKind(array, kind)); | |
| 2343 bool is_double = IsFastDoubleElementsKind(kind); | 2294 bool is_double = IsFastDoubleElementsKind(kind); |
| 2344 DCHECK(value_root_index == Heap::kTheHoleValueRootIndex || | 2295 DCHECK(value_root_index == Heap::kTheHoleValueRootIndex || |
| 2345 value_root_index == Heap::kUndefinedValueRootIndex); | 2296 value_root_index == Heap::kUndefinedValueRootIndex); |
| 2346 DCHECK_IMPLIES(is_double, value_root_index == Heap::kTheHoleValueRootIndex); | 2297 DCHECK_IMPLIES(is_double, value_root_index == Heap::kTheHoleValueRootIndex); |
| 2347 STATIC_ASSERT(kHoleNanLower32 == kHoleNanUpper32); | 2298 STATIC_ASSERT(kHoleNanLower32 == kHoleNanUpper32); |
| 2348 Node* double_hole = | 2299 Node* double_hole = |
| 2349 Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32); | 2300 Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32); |
| 2350 Node* value = LoadRoot(value_root_index); | 2301 Node* value = LoadRoot(value_root_index); |
| 2351 | 2302 |
| 2352 BuildFastFixedArrayForEach( | 2303 BuildFastFixedArrayForEach( |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2376 value); | 2327 value); |
| 2377 } | 2328 } |
| 2378 }, | 2329 }, |
| 2379 mode); | 2330 mode); |
| 2380 } | 2331 } |
| 2381 | 2332 |
| 2382 void CodeStubAssembler::CopyFixedArrayElements( | 2333 void CodeStubAssembler::CopyFixedArrayElements( |
| 2383 ElementsKind from_kind, Node* from_array, ElementsKind to_kind, | 2334 ElementsKind from_kind, Node* from_array, ElementsKind to_kind, |
| 2384 Node* to_array, Node* element_count, Node* capacity, | 2335 Node* to_array, Node* element_count, Node* capacity, |
| 2385 WriteBarrierMode barrier_mode, ParameterMode mode) { | 2336 WriteBarrierMode barrier_mode, ParameterMode mode) { |
| 2386 CSA_SLOW_ASSERT(this, MatchesParameterMode(element_count, mode)); | |
| 2387 CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity, mode)); | |
| 2388 CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(from_array, from_kind)); | |
| 2389 CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(to_array, to_kind)); | |
| 2390 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); | 2337 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); |
| 2391 const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; | 2338 const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; |
| 2392 Comment("[ CopyFixedArrayElements"); | 2339 Comment("[ CopyFixedArrayElements"); |
| 2393 | 2340 |
| 2394 // Typed array elements are not supported. | 2341 // Typed array elements are not supported. |
| 2395 DCHECK(!IsFixedTypedArrayElementsKind(from_kind)); | 2342 DCHECK(!IsFixedTypedArrayElementsKind(from_kind)); |
| 2396 DCHECK(!IsFixedTypedArrayElementsKind(to_kind)); | 2343 DCHECK(!IsFixedTypedArrayElementsKind(to_kind)); |
| 2397 | 2344 |
| 2398 Label done(this); | 2345 Label done(this); |
| 2399 bool from_double_elements = IsFastDoubleElementsKind(from_kind); | 2346 bool from_double_elements = IsFastDoubleElementsKind(from_kind); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2516 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); | 2463 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); |
| 2517 Comment("] CopyFixedArrayElements"); | 2464 Comment("] CopyFixedArrayElements"); |
| 2518 } | 2465 } |
| 2519 | 2466 |
| 2520 void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string, | 2467 void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string, |
| 2521 Node* from_index, Node* to_index, | 2468 Node* from_index, Node* to_index, |
| 2522 Node* character_count, | 2469 Node* character_count, |
| 2523 String::Encoding from_encoding, | 2470 String::Encoding from_encoding, |
| 2524 String::Encoding to_encoding, | 2471 String::Encoding to_encoding, |
| 2525 ParameterMode mode) { | 2472 ParameterMode mode) { |
| 2526 // Cannot assert IsString(from_string) and IsString(to_string) here because | |
| 2527 // CSA::SubString can pass in faked sequential strings when handling external | |
| 2528 // subject strings. | |
| 2529 CSA_SLOW_ASSERT(this, MatchesParameterMode(character_count, mode)); | |
| 2530 CSA_SLOW_ASSERT(this, MatchesParameterMode(from_index, mode)); | |
| 2531 CSA_SLOW_ASSERT(this, MatchesParameterMode(to_index, mode)); | |
| 2532 bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING; | 2473 bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING; |
| 2533 bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING; | 2474 bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING; |
| 2534 DCHECK_IMPLIES(to_one_byte, from_one_byte); | 2475 DCHECK_IMPLIES(to_one_byte, from_one_byte); |
| 2535 Comment("CopyStringCharacters %s -> %s", | 2476 Comment("CopyStringCharacters %s -> %s", |
| 2536 from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", | 2477 from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", |
| 2537 to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING"); | 2478 to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING"); |
| 2538 | 2479 |
| 2539 ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; | 2480 ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; |
| 2540 ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; | 2481 ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; |
| 2541 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); | 2482 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 } | 2521 } |
| 2581 }, | 2522 }, |
| 2582 from_increment, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); | 2523 from_increment, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); |
| 2583 } | 2524 } |
| 2584 | 2525 |
| 2585 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, | 2526 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, |
| 2586 Node* offset, | 2527 Node* offset, |
| 2587 ElementsKind from_kind, | 2528 ElementsKind from_kind, |
| 2588 ElementsKind to_kind, | 2529 ElementsKind to_kind, |
| 2589 Label* if_hole) { | 2530 Label* if_hole) { |
| 2590 CSA_SLOW_ASSERT(this, IsFixedArrayWithKind(array, from_kind)); | |
| 2591 if (IsFastDoubleElementsKind(from_kind)) { | 2531 if (IsFastDoubleElementsKind(from_kind)) { |
| 2592 Node* value = | 2532 Node* value = |
| 2593 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64()); | 2533 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64()); |
| 2594 if (!IsFastDoubleElementsKind(to_kind)) { | 2534 if (!IsFastDoubleElementsKind(to_kind)) { |
| 2595 value = AllocateHeapNumberWithValue(value); | 2535 value = AllocateHeapNumberWithValue(value); |
| 2596 } | 2536 } |
| 2597 return value; | 2537 return value; |
| 2598 | 2538 |
| 2599 } else { | 2539 } else { |
| 2600 Node* value = Load(MachineType::AnyTagged(), array, offset); | 2540 Node* value = Load(MachineType::AnyTagged(), array, offset); |
| 2601 if (if_hole) { | 2541 if (if_hole) { |
| 2602 GotoIf(WordEqual(value, TheHoleConstant()), if_hole); | 2542 GotoIf(WordEqual(value, TheHoleConstant()), if_hole); |
| 2603 } | 2543 } |
| 2604 if (IsFastDoubleElementsKind(to_kind)) { | 2544 if (IsFastDoubleElementsKind(to_kind)) { |
| 2605 if (IsFastSmiElementsKind(from_kind)) { | 2545 if (IsFastSmiElementsKind(from_kind)) { |
| 2606 value = SmiToFloat64(value); | 2546 value = SmiToFloat64(value); |
| 2607 } else { | 2547 } else { |
| 2608 value = LoadHeapNumberValue(value); | 2548 value = LoadHeapNumberValue(value); |
| 2609 } | 2549 } |
| 2610 } | 2550 } |
| 2611 return value; | 2551 return value; |
| 2612 } | 2552 } |
| 2613 } | 2553 } |
| 2614 | 2554 |
| 2615 Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity, | 2555 Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity, |
| 2616 ParameterMode mode) { | 2556 ParameterMode mode) { |
| 2617 CSA_SLOW_ASSERT(this, MatchesParameterMode(old_capacity, mode)); | |
| 2618 Node* half_old_capacity = WordOrSmiShr(old_capacity, 1, mode); | 2557 Node* half_old_capacity = WordOrSmiShr(old_capacity, 1, mode); |
| 2619 Node* new_capacity = IntPtrOrSmiAdd(half_old_capacity, old_capacity, mode); | 2558 Node* new_capacity = IntPtrOrSmiAdd(half_old_capacity, old_capacity, mode); |
| 2620 Node* padding = IntPtrOrSmiConstant(16, mode); | 2559 Node* padding = IntPtrOrSmiConstant(16, mode); |
| 2621 return IntPtrOrSmiAdd(new_capacity, padding, mode); | 2560 return IntPtrOrSmiAdd(new_capacity, padding, mode); |
| 2622 } | 2561 } |
| 2623 | 2562 |
| 2624 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, | 2563 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, |
| 2625 ElementsKind kind, Node* key, | 2564 ElementsKind kind, Node* key, |
| 2626 Label* bailout) { | 2565 Label* bailout) { |
| 2627 CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); | |
| 2628 CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(elements, kind)); | |
| 2629 CSA_SLOW_ASSERT(this, TaggedIsSmi(key)); | |
| 2630 Node* capacity = LoadFixedArrayBaseLength(elements); | 2566 Node* capacity = LoadFixedArrayBaseLength(elements); |
| 2631 | 2567 |
| 2632 ParameterMode mode = OptimalParameterMode(); | 2568 ParameterMode mode = OptimalParameterMode(); |
| 2633 capacity = TaggedToParameter(capacity, mode); | 2569 capacity = TaggedToParameter(capacity, mode); |
| 2634 key = TaggedToParameter(key, mode); | 2570 key = TaggedToParameter(key, mode); |
| 2635 | 2571 |
| 2636 return TryGrowElementsCapacity(object, elements, kind, key, capacity, mode, | 2572 return TryGrowElementsCapacity(object, elements, kind, key, capacity, mode, |
| 2637 bailout); | 2573 bailout); |
| 2638 } | 2574 } |
| 2639 | 2575 |
| 2640 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, | 2576 Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, |
| 2641 ElementsKind kind, Node* key, | 2577 ElementsKind kind, Node* key, |
| 2642 Node* capacity, | 2578 Node* capacity, |
| 2643 ParameterMode mode, | 2579 ParameterMode mode, |
| 2644 Label* bailout) { | 2580 Label* bailout) { |
| 2645 Comment("TryGrowElementsCapacity"); | 2581 Comment("TryGrowElementsCapacity"); |
| 2646 CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); | |
| 2647 CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(elements, kind)); | |
| 2648 CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity, mode)); | |
| 2649 CSA_SLOW_ASSERT(this, MatchesParameterMode(key, mode)); | |
| 2650 | 2582 |
| 2651 // If the gap growth is too big, fall back to the runtime. | 2583 // If the gap growth is too big, fall back to the runtime. |
| 2652 Node* max_gap = IntPtrOrSmiConstant(JSObject::kMaxGap, mode); | 2584 Node* max_gap = IntPtrOrSmiConstant(JSObject::kMaxGap, mode); |
| 2653 Node* max_capacity = IntPtrOrSmiAdd(capacity, max_gap, mode); | 2585 Node* max_capacity = IntPtrOrSmiAdd(capacity, max_gap, mode); |
| 2654 GotoIf(UintPtrOrSmiGreaterThanOrEqual(key, max_capacity, mode), bailout); | 2586 GotoIf(UintPtrOrSmiGreaterThanOrEqual(key, max_capacity, mode), bailout); |
| 2655 | 2587 |
| 2656 // Calculate the capacity of the new backing store. | 2588 // Calculate the capacity of the new backing store. |
| 2657 Node* new_capacity = CalculateNewElementsCapacity( | 2589 Node* new_capacity = CalculateNewElementsCapacity( |
| 2658 IntPtrOrSmiAdd(key, IntPtrOrSmiConstant(1, mode), mode), mode); | 2590 IntPtrOrSmiAdd(key, IntPtrOrSmiConstant(1, mode), mode), mode); |
| 2659 return GrowElementsCapacity(object, elements, kind, kind, capacity, | 2591 return GrowElementsCapacity(object, elements, kind, kind, capacity, |
| 2660 new_capacity, mode, bailout); | 2592 new_capacity, mode, bailout); |
| 2661 } | 2593 } |
| 2662 | 2594 |
| 2663 Node* CodeStubAssembler::GrowElementsCapacity( | 2595 Node* CodeStubAssembler::GrowElementsCapacity( |
| 2664 Node* object, Node* elements, ElementsKind from_kind, ElementsKind to_kind, | 2596 Node* object, Node* elements, ElementsKind from_kind, ElementsKind to_kind, |
| 2665 Node* capacity, Node* new_capacity, ParameterMode mode, Label* bailout) { | 2597 Node* capacity, Node* new_capacity, ParameterMode mode, Label* bailout) { |
| 2666 Comment("[ GrowElementsCapacity"); | 2598 Comment("[ GrowElementsCapacity"); |
| 2667 CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); | |
| 2668 CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(elements, from_kind)); | |
| 2669 CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity, mode)); | |
| 2670 CSA_SLOW_ASSERT(this, MatchesParameterMode(new_capacity, mode)); | |
| 2671 | |
| 2672 // If size of the allocation for the new capacity doesn't fit in a page | 2599 // If size of the allocation for the new capacity doesn't fit in a page |
| 2673 // that we can bump-pointer allocate from, fall back to the runtime. | 2600 // that we can bump-pointer allocate from, fall back to the runtime. |
| 2674 int max_size = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(to_kind); | 2601 int max_size = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(to_kind); |
| 2675 GotoIf(UintPtrOrSmiGreaterThanOrEqual( | 2602 GotoIf(UintPtrOrSmiGreaterThanOrEqual( |
| 2676 new_capacity, IntPtrOrSmiConstant(max_size, mode), mode), | 2603 new_capacity, IntPtrOrSmiConstant(max_size, mode), mode), |
| 2677 bailout); | 2604 bailout); |
| 2678 | 2605 |
| 2679 // Allocate the new backing store. | 2606 // Allocate the new backing store. |
| 2680 Node* new_elements = AllocateFixedArray(to_kind, new_capacity, mode); | 2607 Node* new_elements = AllocateFixedArray(to_kind, new_capacity, mode); |
| 2681 | 2608 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2997 // The {value} is a Smi, convert it to a String. | 2924 // The {value} is a Smi, convert it to a String. |
| 2998 Callable callable = CodeFactory::NumberToString(isolate()); | 2925 Callable callable = CodeFactory::NumberToString(isolate()); |
| 2999 var_value.Bind(CallStub(callable, context, value)); | 2926 var_value.Bind(CallStub(callable, context, value)); |
| 3000 Goto(&if_valueisstring); | 2927 Goto(&if_valueisstring); |
| 3001 } | 2928 } |
| 3002 BIND(&if_valueisstring); | 2929 BIND(&if_valueisstring); |
| 3003 return var_value.value(); | 2930 return var_value.value(); |
| 3004 } | 2931 } |
| 3005 | 2932 |
| 3006 Node* CodeStubAssembler::ChangeNumberToFloat64(Node* value) { | 2933 Node* CodeStubAssembler::ChangeNumberToFloat64(Node* value) { |
| 3007 CSA_SLOW_ASSERT(this, IsNumber(value)); | |
| 3008 VARIABLE(result, MachineRepresentation::kFloat64); | 2934 VARIABLE(result, MachineRepresentation::kFloat64); |
| 3009 Label smi(this); | 2935 Label smi(this); |
| 3010 Label done(this, &result); | 2936 Label done(this, &result); |
| 3011 GotoIf(TaggedIsSmi(value), &smi); | 2937 GotoIf(TaggedIsSmi(value), &smi); |
| 3012 result.Bind( | 2938 result.Bind( |
| 3013 LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64())); | 2939 LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64())); |
| 3014 Goto(&done); | 2940 Goto(&done); |
| 3015 | 2941 |
| 3016 BIND(&smi); | 2942 BIND(&smi); |
| 3017 { | 2943 { |
| 3018 result.Bind(SmiToFloat64(value)); | 2944 result.Bind(SmiToFloat64(value)); |
| 3019 Goto(&done); | 2945 Goto(&done); |
| 3020 } | 2946 } |
| 3021 | 2947 |
| 3022 BIND(&done); | 2948 BIND(&done); |
| 3023 return result.value(); | 2949 return result.value(); |
| 3024 } | 2950 } |
| 3025 | 2951 |
| 3026 Node* CodeStubAssembler::ChangeNumberToIntPtr(Node* value) { | 2952 Node* CodeStubAssembler::ChangeNumberToIntPtr(Node* value) { |
| 3027 CSA_SLOW_ASSERT(this, IsNumber(value)); | |
| 3028 VARIABLE(result, MachineType::PointerRepresentation()); | 2953 VARIABLE(result, MachineType::PointerRepresentation()); |
| 3029 Label smi(this), done(this, &result); | 2954 Label smi(this), done(this, &result); |
| 3030 GotoIf(TaggedIsSmi(value), &smi); | 2955 GotoIf(TaggedIsSmi(value), &smi); |
| 3031 | 2956 |
| 3032 CSA_ASSERT(this, IsHeapNumber(value)); | 2957 CSA_ASSERT(this, IsHeapNumber(value)); |
| 3033 result.Bind(ChangeFloat64ToUintPtr(LoadHeapNumberValue(value))); | 2958 result.Bind(ChangeFloat64ToUintPtr(LoadHeapNumberValue(value))); |
| 3034 Goto(&done); | 2959 Goto(&done); |
| 3035 | 2960 |
| 3036 BIND(&smi); | 2961 BIND(&smi); |
| 3037 result.Bind(SmiToWord(value)); | 2962 result.Bind(SmiToWord(value)); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3159 | 3084 |
| 3160 BIND(&out); | 3085 BIND(&out); |
| 3161 return var_value_map.value(); | 3086 return var_value_map.value(); |
| 3162 } | 3087 } |
| 3163 | 3088 |
| 3164 Node* CodeStubAssembler::InstanceTypeEqual(Node* instance_type, int type) { | 3089 Node* CodeStubAssembler::InstanceTypeEqual(Node* instance_type, int type) { |
| 3165 return Word32Equal(instance_type, Int32Constant(type)); | 3090 return Word32Equal(instance_type, Int32Constant(type)); |
| 3166 } | 3091 } |
| 3167 | 3092 |
| 3168 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { | 3093 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
| 3169 CSA_SLOW_ASSERT(this, IsMap(map)); | |
| 3170 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 3094 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
| 3171 uint32_t mask = | 3095 uint32_t mask = |
| 3172 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; | 3096 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
| 3173 USE(mask); | 3097 USE(mask); |
| 3174 // Interceptors or access checks imply special receiver. | 3098 // Interceptors or access checks imply special receiver. |
| 3175 CSA_ASSERT(this, | 3099 CSA_ASSERT(this, |
| 3176 SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, | 3100 SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, |
| 3177 Int32Constant(1), MachineRepresentation::kWord32)); | 3101 Int32Constant(1), MachineRepresentation::kWord32)); |
| 3178 return is_special; | 3102 return is_special; |
| 3179 } | 3103 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3286 | 3210 |
| 3287 Node* CodeStubAssembler::IsJSObject(Node* object) { | 3211 Node* CodeStubAssembler::IsJSObject(Node* object) { |
| 3288 return IsJSObjectMap(LoadMap(object)); | 3212 return IsJSObjectMap(LoadMap(object)); |
| 3289 } | 3213 } |
| 3290 | 3214 |
| 3291 Node* CodeStubAssembler::IsJSGlobalProxy(Node* object) { | 3215 Node* CodeStubAssembler::IsJSGlobalProxy(Node* object) { |
| 3292 return Word32Equal(LoadInstanceType(object), | 3216 return Word32Equal(LoadInstanceType(object), |
| 3293 Int32Constant(JS_GLOBAL_PROXY_TYPE)); | 3217 Int32Constant(JS_GLOBAL_PROXY_TYPE)); |
| 3294 } | 3218 } |
| 3295 | 3219 |
| 3296 Node* CodeStubAssembler::IsMap(Node* map) { return IsMetaMap(LoadMap(map)); } | 3220 Node* CodeStubAssembler::IsMap(Node* map) { |
| 3221 return HasInstanceType(map, MAP_TYPE); |
| 3222 } |
| 3297 | 3223 |
| 3298 Node* CodeStubAssembler::IsJSValueInstanceType(Node* instance_type) { | 3224 Node* CodeStubAssembler::IsJSValueInstanceType(Node* instance_type) { |
| 3299 return Word32Equal(instance_type, Int32Constant(JS_VALUE_TYPE)); | 3225 return Word32Equal(instance_type, Int32Constant(JS_VALUE_TYPE)); |
| 3300 } | 3226 } |
| 3301 | 3227 |
| 3302 Node* CodeStubAssembler::IsJSValue(Node* object) { | 3228 Node* CodeStubAssembler::IsJSValue(Node* object) { |
| 3303 return IsJSValueMap(LoadMap(object)); | 3229 return IsJSValueMap(LoadMap(object)); |
| 3304 } | 3230 } |
| 3305 | 3231 |
| 3306 Node* CodeStubAssembler::IsJSValueMap(Node* map) { | 3232 Node* CodeStubAssembler::IsJSValueMap(Node* map) { |
| 3307 return IsJSValueInstanceType(LoadMapInstanceType(map)); | 3233 return IsJSValueInstanceType(LoadMapInstanceType(map)); |
| 3308 } | 3234 } |
| 3309 | 3235 |
| 3310 Node* CodeStubAssembler::IsJSArrayInstanceType(Node* instance_type) { | 3236 Node* CodeStubAssembler::IsJSArrayInstanceType(Node* instance_type) { |
| 3311 return Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); | 3237 return Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); |
| 3312 } | 3238 } |
| 3313 | 3239 |
| 3314 Node* CodeStubAssembler::IsJSArray(Node* object) { | 3240 Node* CodeStubAssembler::IsJSArray(Node* object) { |
| 3315 return IsJSArrayMap(LoadMap(object)); | 3241 return IsJSArrayMap(LoadMap(object)); |
| 3316 } | 3242 } |
| 3317 | 3243 |
| 3318 Node* CodeStubAssembler::IsJSArrayMap(Node* map) { | 3244 Node* CodeStubAssembler::IsJSArrayMap(Node* map) { |
| 3319 return IsJSArrayInstanceType(LoadMapInstanceType(map)); | 3245 return IsJSArrayInstanceType(LoadMapInstanceType(map)); |
| 3320 } | 3246 } |
| 3321 | 3247 |
| 3322 Node* CodeStubAssembler::IsFixedArray(Node* object) { | |
| 3323 return HasInstanceType(object, FIXED_ARRAY_TYPE); | |
| 3324 } | |
| 3325 | |
| 3326 // This complicated check is due to elements oddities. If a smi array is empty | |
| 3327 // after Array.p.shift, it is replaced by the empty array constant. If it is | |
| 3328 // later filled with a double element, we try to grow it but pass in a double | |
| 3329 // elements kind. Usually this would cause a size mismatch (since the source | |
| 3330 // fixed array has FAST_HOLEY_ELEMENTS and destination has | |
| 3331 // FAST_HOLEY_DOUBLE_ELEMENTS), but we don't have to worry about it when the | |
| 3332 // source array is empty. | |
| 3333 // TODO(jgruber): It might we worth creating an empty_double_array constant to | |
| 3334 // simplify this case. | |
| 3335 Node* CodeStubAssembler::IsFixedArrayWithKindOrEmpty(Node* object, | |
| 3336 ElementsKind kind) { | |
| 3337 Label out(this); | |
| 3338 VARIABLE(var_result, MachineRepresentation::kWord32, Int32Constant(1)); | |
| 3339 | |
| 3340 GotoIf(IsFixedArrayWithKind(object, kind), &out); | |
| 3341 | |
| 3342 Node* const length = LoadFixedArrayBaseLength(object); | |
| 3343 GotoIf(SmiEqual(length, SmiConstant(0)), &out); | |
| 3344 | |
| 3345 var_result.Bind(Int32Constant(0)); | |
| 3346 Goto(&out); | |
| 3347 | |
| 3348 BIND(&out); | |
| 3349 return var_result.value(); | |
| 3350 } | |
| 3351 | |
| 3352 Node* CodeStubAssembler::IsFixedArrayWithKind(Node* object, ElementsKind kind) { | |
| 3353 if (IsFastDoubleElementsKind(kind)) { | |
| 3354 return IsFixedDoubleArray(object); | |
| 3355 } else { | |
| 3356 DCHECK(IsFastSmiOrObjectElementsKind(kind)); | |
| 3357 return IsFixedArray(object); | |
| 3358 } | |
| 3359 } | |
| 3360 | |
| 3361 Node* CodeStubAssembler::IsWeakCell(Node* object) { | 3248 Node* CodeStubAssembler::IsWeakCell(Node* object) { |
| 3362 return IsWeakCellMap(LoadMap(object)); | 3249 return IsWeakCellMap(LoadMap(object)); |
| 3363 } | 3250 } |
| 3364 | 3251 |
| 3365 Node* CodeStubAssembler::IsBoolean(Node* object) { | 3252 Node* CodeStubAssembler::IsBoolean(Node* object) { |
| 3366 return IsBooleanMap(LoadMap(object)); | 3253 return IsBooleanMap(LoadMap(object)); |
| 3367 } | 3254 } |
| 3368 | 3255 |
| 3369 Node* CodeStubAssembler::IsPropertyCell(Node* object) { | 3256 Node* CodeStubAssembler::IsPropertyCell(Node* object) { |
| 3370 return IsPropertyCellMap(LoadMap(object)); | 3257 return IsPropertyCellMap(LoadMap(object)); |
| 3371 } | 3258 } |
| 3372 | 3259 |
| 3373 Node* CodeStubAssembler::IsAccessorInfo(Node* object) { | 3260 Node* CodeStubAssembler::IsAccessorInfo(Node* object) { |
| 3374 return IsAccessorInfoMap(LoadMap(object)); | 3261 return IsAccessorInfoMap(LoadMap(object)); |
| 3375 } | 3262 } |
| 3376 | 3263 |
| 3377 Node* CodeStubAssembler::IsAccessorPair(Node* object) { | 3264 Node* CodeStubAssembler::IsAccessorPair(Node* object) { |
| 3378 return IsAccessorPairMap(LoadMap(object)); | 3265 return IsAccessorPairMap(LoadMap(object)); |
| 3379 } | 3266 } |
| 3380 | 3267 |
| 3381 Node* CodeStubAssembler::IsAnyHeapNumber(Node* object) { | |
| 3382 return Word32Or(IsMutableHeapNumber(object), IsHeapNumber(object)); | |
| 3383 } | |
| 3384 | |
| 3385 Node* CodeStubAssembler::IsMutableHeapNumber(Node* object) { | |
| 3386 return IsMutableHeapNumberMap(LoadMap(object)); | |
| 3387 } | |
| 3388 | |
| 3389 Node* CodeStubAssembler::IsHeapNumber(Node* object) { | 3268 Node* CodeStubAssembler::IsHeapNumber(Node* object) { |
| 3390 return IsHeapNumberMap(LoadMap(object)); | 3269 return IsHeapNumberMap(LoadMap(object)); |
| 3391 } | 3270 } |
| 3392 | 3271 |
| 3393 Node* CodeStubAssembler::IsFeedbackVector(Node* object) { | 3272 Node* CodeStubAssembler::IsFeedbackVector(Node* object) { |
| 3394 return IsFeedbackVectorMap(LoadMap(object)); | 3273 return IsFeedbackVectorMap(LoadMap(object)); |
| 3395 } | 3274 } |
| 3396 | 3275 |
| 3397 Node* CodeStubAssembler::IsName(Node* object) { | 3276 Node* CodeStubAssembler::IsName(Node* object) { |
| 3398 return Int32LessThanOrEqual(LoadInstanceType(object), | 3277 return Int32LessThanOrEqual(LoadInstanceType(object), |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3510 [=] { return TaggedIsPositiveSmi(number); }, | 3389 [=] { return TaggedIsPositiveSmi(number); }, |
| 3511 [=] { | 3390 [=] { |
| 3512 Node* v = LoadHeapNumberValue(number); | 3391 Node* v = LoadHeapNumberValue(number); |
| 3513 return Float64GreaterThanOrEqual(v, float_zero); | 3392 return Float64GreaterThanOrEqual(v, float_zero); |
| 3514 }, | 3393 }, |
| 3515 MachineRepresentation::kWord32); | 3394 MachineRepresentation::kWord32); |
| 3516 } | 3395 } |
| 3517 | 3396 |
| 3518 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index, | 3397 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index, |
| 3519 ParameterMode parameter_mode) { | 3398 ParameterMode parameter_mode) { |
| 3520 CSA_ASSERT(this, MatchesParameterMode(index, parameter_mode)); | 3399 if (parameter_mode == SMI_PARAMETERS) CSA_ASSERT(this, TaggedIsSmi(index)); |
| 3521 CSA_ASSERT(this, IsString(string)); | 3400 CSA_ASSERT(this, IsString(string)); |
| 3522 | 3401 |
| 3523 // Translate the {index} into a Word. | 3402 // Translate the {index} into a Word. |
| 3524 Node* const int_index = ParameterToWord(index, parameter_mode); | 3403 Node* const int_index = ParameterToWord(index, parameter_mode); |
| 3525 CSA_ASSERT(this, IntPtrGreaterThanOrEqual(int_index, IntPtrConstant(0))); | 3404 CSA_ASSERT(this, IntPtrGreaterThanOrEqual(int_index, IntPtrConstant(0))); |
| 3526 | 3405 |
| 3527 VARIABLE(var_result, MachineRepresentation::kWord32); | 3406 VARIABLE(var_result, MachineRepresentation::kWord32); |
| 3528 | 3407 |
| 3529 Label out(this, &var_result), runtime_generic(this), runtime_external(this); | 3408 Label out(this, &var_result), runtime_generic(this), runtime_external(this); |
| 3530 | 3409 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3622 // Allocate a new SeqTwoByteString for {code}. | 3501 // Allocate a new SeqTwoByteString for {code}. |
| 3623 Node* result = AllocateSeqTwoByteString(1); | 3502 Node* result = AllocateSeqTwoByteString(1); |
| 3624 StoreNoWriteBarrier( | 3503 StoreNoWriteBarrier( |
| 3625 MachineRepresentation::kWord16, result, | 3504 MachineRepresentation::kWord16, result, |
| 3626 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code); | 3505 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code); |
| 3627 var_result.Bind(result); | 3506 var_result.Bind(result); |
| 3628 Goto(&if_done); | 3507 Goto(&if_done); |
| 3629 } | 3508 } |
| 3630 | 3509 |
| 3631 BIND(&if_done); | 3510 BIND(&if_done); |
| 3632 CSA_ASSERT(this, IsString(var_result.value())); | |
| 3633 return var_result.value(); | 3511 return var_result.value(); |
| 3634 } | 3512 } |
| 3635 | 3513 |
| 3636 // A wrapper around CopyStringCharacters which determines the correct string | 3514 // A wrapper around CopyStringCharacters which determines the correct string |
| 3637 // encoding, allocates a corresponding sequential string, and then copies the | 3515 // encoding, allocates a corresponding sequential string, and then copies the |
| 3638 // given character range using CopyStringCharacters. | 3516 // given character range using CopyStringCharacters. |
| 3639 // |from_string| must be a sequential string. |from_index| and | 3517 // |from_string| must be a sequential string. |from_index| and |
| 3640 // |character_count| must be Smis s.t. | 3518 // |character_count| must be Smis s.t. |
| 3641 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. | 3519 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. |
| 3642 Node* CodeStubAssembler::AllocAndCopyStringCharacters(Node* context, Node* from, | 3520 Node* CodeStubAssembler::AllocAndCopyStringCharacters(Node* context, Node* from, |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3825 | 3703 |
| 3826 // Fall back to a runtime call. | 3704 // Fall back to a runtime call. |
| 3827 BIND(&runtime); | 3705 BIND(&runtime); |
| 3828 { | 3706 { |
| 3829 var_result.Bind( | 3707 var_result.Bind( |
| 3830 CallRuntime(Runtime::kSubString, context, string, from, to)); | 3708 CallRuntime(Runtime::kSubString, context, string, from, to)); |
| 3831 Goto(&end); | 3709 Goto(&end); |
| 3832 } | 3710 } |
| 3833 | 3711 |
| 3834 BIND(&end); | 3712 BIND(&end); |
| 3835 CSA_ASSERT(this, IsString(var_result.value())); | |
| 3836 return var_result.value(); | 3713 return var_result.value(); |
| 3837 } | 3714 } |
| 3838 | 3715 |
| 3839 ToDirectStringAssembler::ToDirectStringAssembler( | 3716 ToDirectStringAssembler::ToDirectStringAssembler( |
| 3840 compiler::CodeAssemblerState* state, Node* string, Flags flags) | 3717 compiler::CodeAssemblerState* state, Node* string, Flags flags) |
| 3841 : CodeStubAssembler(state), | 3718 : CodeStubAssembler(state), |
| 3842 var_string_(this, MachineRepresentation::kTagged, string), | 3719 var_string_(this, MachineRepresentation::kTagged, string), |
| 3843 var_instance_type_(this, MachineRepresentation::kWord32), | 3720 var_instance_type_(this, MachineRepresentation::kWord32), |
| 3844 var_offset_(this, MachineType::PointerRepresentation()), | 3721 var_offset_(this, MachineType::PointerRepresentation()), |
| 3845 var_is_external_(this, MachineRepresentation::kWord32), | 3722 var_is_external_(this, MachineRepresentation::kWord32), |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3973 kHeapObjectTag)); | 3850 kHeapObjectTag)); |
| 3974 } | 3851 } |
| 3975 var_result.Bind(result); | 3852 var_result.Bind(result); |
| 3976 Goto(&out); | 3853 Goto(&out); |
| 3977 } | 3854 } |
| 3978 | 3855 |
| 3979 BIND(&out); | 3856 BIND(&out); |
| 3980 return var_result.value(); | 3857 return var_result.value(); |
| 3981 } | 3858 } |
| 3982 | 3859 |
| 3860 Node* CodeStubAssembler::TryDerefExternalString(Node* const string, |
| 3861 Node* const instance_type, |
| 3862 Label* if_bailout) { |
| 3863 Label out(this); |
| 3864 |
| 3865 CSA_ASSERT(this, IsExternalStringInstanceType(instance_type)); |
| 3866 GotoIf(IsShortExternalStringInstanceType(instance_type), if_bailout); |
| 3867 |
| 3868 // Move the pointer so that offset-wise, it looks like a sequential string. |
| 3869 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); |
| 3870 |
| 3871 Node* resource_data = LoadObjectField( |
| 3872 string, ExternalString::kResourceDataOffset, MachineType::Pointer()); |
| 3873 Node* const fake_sequential_string = |
| 3874 IntPtrSub(resource_data, |
| 3875 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
| 3876 |
| 3877 return fake_sequential_string; |
| 3878 } |
| 3879 |
| 3983 void CodeStubAssembler::MaybeDerefIndirectString(Variable* var_string, | 3880 void CodeStubAssembler::MaybeDerefIndirectString(Variable* var_string, |
| 3984 Node* instance_type, | 3881 Node* instance_type, |
| 3985 Variable* var_did_something) { | 3882 Variable* var_did_something) { |
| 3986 Label deref(this), done(this, var_did_something); | 3883 Label deref(this), done(this, var_did_something); |
| 3987 Node* representation = | 3884 Node* representation = |
| 3988 Word32And(instance_type, Int32Constant(kStringRepresentationMask)); | 3885 Word32And(instance_type, Int32Constant(kStringRepresentationMask)); |
| 3989 GotoIf(Word32Equal(representation, Int32Constant(kThinStringTag)), &deref); | 3886 GotoIf(Word32Equal(representation, Int32Constant(kThinStringTag)), &deref); |
| 3990 GotoIf(Word32NotEqual(representation, Int32Constant(kConsStringTag)), &done); | 3887 GotoIf(Word32NotEqual(representation, Int32Constant(kConsStringTag)), &done); |
| 3991 // Cons string. | 3888 // Cons string. |
| 3992 Node* rhs = LoadObjectField(var_string->value(), ConsString::kSecondOffset); | 3889 Node* rhs = LoadObjectField(var_string->value(), ConsString::kSecondOffset); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4178 Node* value = AllocateSeqTwoByteString(2); | 4075 Node* value = AllocateSeqTwoByteString(2); |
| 4179 StoreNoWriteBarrier( | 4076 StoreNoWriteBarrier( |
| 4180 MachineRepresentation::kWord32, value, | 4077 MachineRepresentation::kWord32, value, |
| 4181 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), | 4078 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), |
| 4182 codepoint); | 4079 codepoint); |
| 4183 var_result.Bind(value); | 4080 var_result.Bind(value); |
| 4184 Goto(&return_result); | 4081 Goto(&return_result); |
| 4185 } | 4082 } |
| 4186 | 4083 |
| 4187 BIND(&return_result); | 4084 BIND(&return_result); |
| 4188 CSA_ASSERT(this, IsString(var_result.value())); | |
| 4189 return var_result.value(); | 4085 return var_result.value(); |
| 4190 } | 4086 } |
| 4191 | 4087 |
| 4192 Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) { | 4088 Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) { |
| 4193 CSA_SLOW_ASSERT(this, IsString(input)); | |
| 4194 Label runtime(this, Label::kDeferred); | 4089 Label runtime(this, Label::kDeferred); |
| 4195 Label end(this); | 4090 Label end(this); |
| 4196 | 4091 |
| 4197 VARIABLE(var_result, MachineRepresentation::kTagged); | 4092 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 4198 | 4093 |
| 4199 // Check if string has a cached array index. | 4094 // Check if string has a cached array index. |
| 4200 Node* hash = LoadNameHashField(input); | 4095 Node* hash = LoadNameHashField(input); |
| 4201 Node* bit = | 4096 Node* bit = |
| 4202 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask)); | 4097 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask)); |
| 4203 GotoIf(Word32NotEqual(bit, Int32Constant(0)), &runtime); | 4098 GotoIf(Word32NotEqual(bit, Int32Constant(0)), &runtime); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4238 GotoIfNot(IsHeapNumberMap(map), &runtime); | 4133 GotoIfNot(IsHeapNumberMap(map), &runtime); |
| 4239 | 4134 |
| 4240 // Make a hash from the two 32-bit values of the double. | 4135 // Make a hash from the two 32-bit values of the double. |
| 4241 Node* low = | 4136 Node* low = |
| 4242 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); | 4137 LoadObjectField(argument, HeapNumber::kValueOffset, MachineType::Int32()); |
| 4243 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, | 4138 Node* high = LoadObjectField(argument, HeapNumber::kValueOffset + kIntSize, |
| 4244 MachineType::Int32()); | 4139 MachineType::Int32()); |
| 4245 Node* hash = Word32Xor(low, high); | 4140 Node* hash = Word32Xor(low, high); |
| 4246 hash = ChangeInt32ToIntPtr(hash); | 4141 hash = ChangeInt32ToIntPtr(hash); |
| 4247 hash = WordShl(hash, one); | 4142 hash = WordShl(hash, one); |
| 4248 Node* index = WordAnd(hash, WordSar(mask, SmiShiftBitsConstant())); | 4143 Node* index = WordAnd(hash, SmiUntag(BitcastWordToTagged(mask))); |
| 4249 | 4144 |
| 4250 // Cache entry's key must be a heap number | 4145 // Cache entry's key must be a heap number |
| 4251 Node* number_key = LoadFixedArrayElement(number_string_cache, index); | 4146 Node* number_key = LoadFixedArrayElement(number_string_cache, index); |
| 4252 GotoIf(TaggedIsSmi(number_key), &runtime); | 4147 GotoIf(TaggedIsSmi(number_key), &runtime); |
| 4253 map = LoadMap(number_key); | 4148 map = LoadMap(number_key); |
| 4254 GotoIfNot(IsHeapNumberMap(map), &runtime); | 4149 GotoIfNot(IsHeapNumberMap(map), &runtime); |
| 4255 | 4150 |
| 4256 // Cache entry's key must match the heap number value we're looking for. | 4151 // Cache entry's key must match the heap number value we're looking for. |
| 4257 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, | 4152 Node* low_compare = LoadObjectField(number_key, HeapNumber::kValueOffset, |
| 4258 MachineType::Int32()); | 4153 MachineType::Int32()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4283 GotoIf(WordNotEqual(smi_key, argument), &runtime); | 4178 GotoIf(WordNotEqual(smi_key, argument), &runtime); |
| 4284 | 4179 |
| 4285 // Smi match, return value from cache entry. | 4180 // Smi match, return value from cache entry. |
| 4286 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); | 4181 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
| 4287 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, | 4182 result.Bind(LoadFixedArrayElement(number_string_cache, smi_index, |
| 4288 kPointerSize, SMI_PARAMETERS)); | 4183 kPointerSize, SMI_PARAMETERS)); |
| 4289 Goto(&done); | 4184 Goto(&done); |
| 4290 } | 4185 } |
| 4291 | 4186 |
| 4292 BIND(&done); | 4187 BIND(&done); |
| 4293 CSA_ASSERT(this, IsString(result.value())); | |
| 4294 return result.value(); | 4188 return result.value(); |
| 4295 } | 4189 } |
| 4296 | 4190 |
| 4297 Node* CodeStubAssembler::ToName(Node* context, Node* value) { | 4191 Node* CodeStubAssembler::ToName(Node* context, Node* value) { |
| 4298 Label end(this); | 4192 Label end(this); |
| 4299 VARIABLE(var_result, MachineRepresentation::kTagged); | 4193 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 4300 | 4194 |
| 4301 Label is_number(this); | 4195 Label is_number(this); |
| 4302 GotoIf(TaggedIsSmi(value), &is_number); | 4196 GotoIf(TaggedIsSmi(value), &is_number); |
| 4303 | 4197 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4330 Goto(&end); | 4224 Goto(&end); |
| 4331 | 4225 |
| 4332 BIND(¬_oddball); | 4226 BIND(¬_oddball); |
| 4333 { | 4227 { |
| 4334 var_result.Bind(CallRuntime(Runtime::kToName, context, value)); | 4228 var_result.Bind(CallRuntime(Runtime::kToName, context, value)); |
| 4335 Goto(&end); | 4229 Goto(&end); |
| 4336 } | 4230 } |
| 4337 } | 4231 } |
| 4338 | 4232 |
| 4339 BIND(&end); | 4233 BIND(&end); |
| 4340 CSA_ASSERT(this, IsName(var_result.value())); | |
| 4341 return var_result.value(); | 4234 return var_result.value(); |
| 4342 } | 4235 } |
| 4343 | 4236 |
| 4344 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { | 4237 Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) { |
| 4345 // Assert input is a HeapObject (not smi or heap number) | 4238 // Assert input is a HeapObject (not smi or heap number) |
| 4346 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(input))); | 4239 CSA_ASSERT(this, Word32BinaryNot(TaggedIsSmi(input))); |
| 4347 CSA_ASSERT(this, Word32BinaryNot(IsHeapNumberMap(LoadMap(input)))); | 4240 CSA_ASSERT(this, Word32BinaryNot(IsHeapNumberMap(LoadMap(input)))); |
| 4348 | 4241 |
| 4349 // We might need to loop once here due to ToPrimitive conversions. | 4242 // We might need to loop once here due to ToPrimitive conversions. |
| 4350 VARIABLE(var_input, MachineRepresentation::kTagged, input); | 4243 VARIABLE(var_input, MachineRepresentation::kTagged, input); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4419 // Note: We cannot tail call to the runtime here, as js-to-wasm | 4312 // Note: We cannot tail call to the runtime here, as js-to-wasm |
| 4420 // trampolines also use this code currently, and they declare all | 4313 // trampolines also use this code currently, and they declare all |
| 4421 // outgoing parameters as untagged, while we would push a tagged | 4314 // outgoing parameters as untagged, while we would push a tagged |
| 4422 // object here. | 4315 // object here. |
| 4423 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input)); | 4316 var_result.Bind(CallRuntime(Runtime::kToNumber, context, input)); |
| 4424 Goto(&end); | 4317 Goto(&end); |
| 4425 } | 4318 } |
| 4426 } | 4319 } |
| 4427 | 4320 |
| 4428 BIND(&end); | 4321 BIND(&end); |
| 4429 CSA_ASSERT(this, IsNumber(var_result.value())); | |
| 4430 return var_result.value(); | 4322 return var_result.value(); |
| 4431 } | 4323 } |
| 4432 | 4324 |
| 4433 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) { | 4325 Node* CodeStubAssembler::ToNumber(Node* context, Node* input) { |
| 4434 VARIABLE(var_result, MachineRepresentation::kTagged); | 4326 VARIABLE(var_result, MachineRepresentation::kTagged); |
| 4435 Label end(this); | 4327 Label end(this); |
| 4436 | 4328 |
| 4437 Label not_smi(this, Label::kDeferred); | 4329 Label not_smi(this, Label::kDeferred); |
| 4438 GotoIfNot(TaggedIsSmi(input), ¬_smi); | 4330 GotoIfNot(TaggedIsSmi(input), ¬_smi); |
| 4439 var_result.Bind(input); | 4331 var_result.Bind(input); |
| 4440 Goto(&end); | 4332 Goto(&end); |
| 4441 | 4333 |
| 4442 BIND(¬_smi); | 4334 BIND(¬_smi); |
| 4443 { | 4335 { |
| 4444 Label not_heap_number(this, Label::kDeferred); | 4336 Label not_heap_number(this, Label::kDeferred); |
| 4445 Node* input_map = LoadMap(input); | 4337 Node* input_map = LoadMap(input); |
| 4446 GotoIfNot(IsHeapNumberMap(input_map), ¬_heap_number); | 4338 GotoIfNot(IsHeapNumberMap(input_map), ¬_heap_number); |
| 4447 | 4339 |
| 4448 var_result.Bind(input); | 4340 var_result.Bind(input); |
| 4449 Goto(&end); | 4341 Goto(&end); |
| 4450 | 4342 |
| 4451 BIND(¬_heap_number); | 4343 BIND(¬_heap_number); |
| 4452 { | 4344 { |
| 4453 var_result.Bind(NonNumberToNumber(context, input)); | 4345 var_result.Bind(NonNumberToNumber(context, input)); |
| 4454 Goto(&end); | 4346 Goto(&end); |
| 4455 } | 4347 } |
| 4456 } | 4348 } |
| 4457 | 4349 |
| 4458 BIND(&end); | 4350 BIND(&end); |
| 4459 CSA_ASSERT(this, IsNumber(var_result.value())); | |
| 4460 return var_result.value(); | 4351 return var_result.value(); |
| 4461 } | 4352 } |
| 4462 | 4353 |
| 4463 // ES#sec-touint32 | 4354 // ES#sec-touint32 |
| 4464 Node* CodeStubAssembler::ToUint32(Node* context, Node* input) { | 4355 Node* CodeStubAssembler::ToUint32(Node* context, Node* input) { |
| 4465 Node* const float_zero = Float64Constant(0.0); | 4356 Node* const float_zero = Float64Constant(0.0); |
| 4466 Node* const float_two_32 = Float64Constant(static_cast<double>(1ULL << 32)); | 4357 Node* const float_two_32 = Float64Constant(static_cast<double>(1ULL << 32)); |
| 4467 | 4358 |
| 4468 Label out(this); | 4359 Label out(this); |
| 4469 | 4360 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4552 } | 4443 } |
| 4553 | 4444 |
| 4554 BIND(&return_zero); | 4445 BIND(&return_zero); |
| 4555 { | 4446 { |
| 4556 var_result.Bind(SmiConstant(Smi::kZero)); | 4447 var_result.Bind(SmiConstant(Smi::kZero)); |
| 4557 Goto(&out); | 4448 Goto(&out); |
| 4558 } | 4449 } |
| 4559 } | 4450 } |
| 4560 | 4451 |
| 4561 BIND(&out); | 4452 BIND(&out); |
| 4562 CSA_ASSERT(this, IsNumber(var_result.value())); | |
| 4563 return var_result.value(); | 4453 return var_result.value(); |
| 4564 } | 4454 } |
| 4565 | 4455 |
| 4566 Node* CodeStubAssembler::ToString(Node* context, Node* input) { | 4456 Node* CodeStubAssembler::ToString(Node* context, Node* input) { |
| 4567 Label is_number(this); | 4457 Label is_number(this); |
| 4568 Label runtime(this, Label::kDeferred); | 4458 Label runtime(this, Label::kDeferred); |
| 4569 VARIABLE(result, MachineRepresentation::kTagged); | 4459 VARIABLE(result, MachineRepresentation::kTagged); |
| 4570 Label done(this, &result); | 4460 Label done(this, &result); |
| 4571 | 4461 |
| 4572 GotoIf(TaggedIsSmi(input), &is_number); | 4462 GotoIf(TaggedIsSmi(input), &is_number); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4661 Goto(&negative_check); | 4551 Goto(&negative_check); |
| 4662 | 4552 |
| 4663 BIND(&negative_check); | 4553 BIND(&negative_check); |
| 4664 Branch(SmiLessThan(result.value(), SmiConstant(0)), range_error, &done); | 4554 Branch(SmiLessThan(result.value(), SmiConstant(0)), range_error, &done); |
| 4665 | 4555 |
| 4666 BIND(&return_zero); | 4556 BIND(&return_zero); |
| 4667 result.Bind(SmiConstant(0)); | 4557 result.Bind(SmiConstant(0)); |
| 4668 Goto(&done); | 4558 Goto(&done); |
| 4669 | 4559 |
| 4670 BIND(&done); | 4560 BIND(&done); |
| 4671 CSA_SLOW_ASSERT(this, TaggedIsSmi(result.value())); | |
| 4672 return result.value(); | 4561 return result.value(); |
| 4673 } | 4562 } |
| 4674 | 4563 |
| 4675 Node* CodeStubAssembler::ToSmiLength(Node* input, Node* const context, | 4564 Node* CodeStubAssembler::ToSmiLength(Node* input, Node* const context, |
| 4676 Label* range_error) { | 4565 Label* range_error) { |
| 4677 VARIABLE(result, MachineRepresentation::kTagged, input); | 4566 VARIABLE(result, MachineRepresentation::kTagged, input); |
| 4678 Label to_integer(this), negative_check(this), return_zero(this), done(this); | 4567 Label to_integer(this), negative_check(this), return_zero(this), done(this); |
| 4679 Branch(TaggedIsSmi(result.value()), &negative_check, &to_integer); | 4568 Branch(TaggedIsSmi(result.value()), &negative_check, &to_integer); |
| 4680 | 4569 |
| 4681 BIND(&to_integer); | 4570 BIND(&to_integer); |
| 4682 result.Bind(ToInteger(context, result.value(), | 4571 result.Bind(ToInteger(context, result.value(), |
| 4683 CodeStubAssembler::kTruncateMinusZero)); | 4572 CodeStubAssembler::kTruncateMinusZero)); |
| 4684 GotoIfNot(TaggedIsSmi(result.value()), range_error); | 4573 GotoIfNot(TaggedIsSmi(result.value()), range_error); |
| 4685 CSA_ASSERT(this, TaggedIsSmi(result.value())); | 4574 CSA_ASSERT(this, TaggedIsSmi(result.value())); |
| 4686 Goto(&negative_check); | 4575 Goto(&negative_check); |
| 4687 | 4576 |
| 4688 BIND(&negative_check); | 4577 BIND(&negative_check); |
| 4689 Branch(SmiLessThan(result.value(), SmiConstant(0)), &return_zero, &done); | 4578 Branch(SmiLessThan(result.value(), SmiConstant(0)), &return_zero, &done); |
| 4690 | 4579 |
| 4691 BIND(&return_zero); | 4580 BIND(&return_zero); |
| 4692 result.Bind(SmiConstant(0)); | 4581 result.Bind(SmiConstant(0)); |
| 4693 Goto(&done); | 4582 Goto(&done); |
| 4694 | 4583 |
| 4695 BIND(&done); | 4584 BIND(&done); |
| 4696 CSA_SLOW_ASSERT(this, TaggedIsSmi(result.value())); | |
| 4697 return result.value(); | 4585 return result.value(); |
| 4698 } | 4586 } |
| 4699 | 4587 |
| 4700 Node* CodeStubAssembler::ToLength_Inline(Node* const context, | 4588 Node* CodeStubAssembler::ToLength_Inline(Node* const context, |
| 4701 Node* const input) { | 4589 Node* const input) { |
| 4702 Node* const smi_zero = SmiConstant(0); | 4590 Node* const smi_zero = SmiConstant(0); |
| 4703 return Select( | 4591 return Select( |
| 4704 TaggedIsSmi(input), [=] { return SmiMax(input, smi_zero); }, | 4592 TaggedIsSmi(input), [=] { return SmiMax(input, smi_zero); }, |
| 4705 [=] { return CallBuiltin(Builtins::kToLength, context, input); }, | 4593 [=] { return CallBuiltin(Builtins::kToLength, context, input); }, |
| 4706 MachineRepresentation::kTagged); | 4594 MachineRepresentation::kTagged); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4756 var_arg.Bind(CallStub(callable, context, arg)); | 4644 var_arg.Bind(CallStub(callable, context, arg)); |
| 4757 Goto(&loop); | 4645 Goto(&loop); |
| 4758 } | 4646 } |
| 4759 | 4647 |
| 4760 BIND(&return_zero); | 4648 BIND(&return_zero); |
| 4761 var_arg.Bind(SmiConstant(Smi::kZero)); | 4649 var_arg.Bind(SmiConstant(Smi::kZero)); |
| 4762 Goto(&out); | 4650 Goto(&out); |
| 4763 } | 4651 } |
| 4764 | 4652 |
| 4765 BIND(&out); | 4653 BIND(&out); |
| 4766 CSA_SLOW_ASSERT(this, IsNumber(var_arg.value())); | |
| 4767 return var_arg.value(); | 4654 return var_arg.value(); |
| 4768 } | 4655 } |
| 4769 | 4656 |
| 4770 Node* CodeStubAssembler::DecodeWord32(Node* word32, uint32_t shift, | 4657 Node* CodeStubAssembler::DecodeWord32(Node* word32, uint32_t shift, |
| 4771 uint32_t mask) { | 4658 uint32_t mask) { |
| 4772 return Word32Shr(Word32And(word32, Int32Constant(mask)), | 4659 return Word32Shr(Word32And(word32, Int32Constant(mask)), |
| 4773 static_cast<int>(shift)); | 4660 static_cast<int>(shift)); |
| 4774 } | 4661 } |
| 4775 | 4662 |
| 4776 Node* CodeStubAssembler::DecodeWord(Node* word, uint32_t shift, uint32_t mask) { | 4663 Node* CodeStubAssembler::DecodeWord(Node* word, uint32_t shift, uint32_t mask) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4873 BIND(&if_hascachedindex); | 4760 BIND(&if_hascachedindex); |
| 4874 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); | 4761 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); |
| 4875 Goto(if_keyisindex); | 4762 Goto(if_keyisindex); |
| 4876 } | 4763 } |
| 4877 | 4764 |
| 4878 void CodeStubAssembler::TryInternalizeString( | 4765 void CodeStubAssembler::TryInternalizeString( |
| 4879 Node* string, Label* if_index, Variable* var_index, Label* if_internalized, | 4766 Node* string, Label* if_index, Variable* var_index, Label* if_internalized, |
| 4880 Variable* var_internalized, Label* if_not_internalized, Label* if_bailout) { | 4767 Variable* var_internalized, Label* if_not_internalized, Label* if_bailout) { |
| 4881 DCHECK(var_index->rep() == MachineType::PointerRepresentation()); | 4768 DCHECK(var_index->rep() == MachineType::PointerRepresentation()); |
| 4882 DCHECK(var_internalized->rep() == MachineRepresentation::kTagged); | 4769 DCHECK(var_internalized->rep() == MachineRepresentation::kTagged); |
| 4883 CSA_SLOW_ASSERT(this, IsString(string)); | |
| 4884 Node* function = ExternalConstant( | 4770 Node* function = ExternalConstant( |
| 4885 ExternalReference::try_internalize_string_function(isolate())); | 4771 ExternalReference::try_internalize_string_function(isolate())); |
| 4886 Node* result = CallCFunction1(MachineType::AnyTagged(), | 4772 Node* result = CallCFunction1(MachineType::AnyTagged(), |
| 4887 MachineType::AnyTagged(), function, string); | 4773 MachineType::AnyTagged(), function, string); |
| 4888 Label internalized(this); | 4774 Label internalized(this); |
| 4889 GotoIf(TaggedIsNotSmi(result), &internalized); | 4775 GotoIf(TaggedIsNotSmi(result), &internalized); |
| 4890 Node* word_result = SmiUntag(result); | 4776 Node* word_result = SmiUntag(result); |
| 4891 GotoIf(WordEqual(word_result, IntPtrConstant(ResultSentinel::kNotFound)), | 4777 GotoIf(WordEqual(word_result, IntPtrConstant(ResultSentinel::kNotFound)), |
| 4892 if_not_internalized); | 4778 if_not_internalized); |
| 4893 GotoIf(WordEqual(word_result, IntPtrConstant(ResultSentinel::kUnsupported)), | 4779 GotoIf(WordEqual(word_result, IntPtrConstant(ResultSentinel::kUnsupported)), |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5121 void CodeStubAssembler::InsertEntry(Node* dictionary, Node* key, Node* value, | 5007 void CodeStubAssembler::InsertEntry(Node* dictionary, Node* key, Node* value, |
| 5122 Node* index, Node* enum_index) { | 5008 Node* index, Node* enum_index) { |
| 5123 UNREACHABLE(); // Use specializations instead. | 5009 UNREACHABLE(); // Use specializations instead. |
| 5124 } | 5010 } |
| 5125 | 5011 |
| 5126 template <> | 5012 template <> |
| 5127 void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary, | 5013 void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary, |
| 5128 Node* name, Node* value, | 5014 Node* name, Node* value, |
| 5129 Node* index, | 5015 Node* index, |
| 5130 Node* enum_index) { | 5016 Node* enum_index) { |
| 5131 CSA_SLOW_ASSERT(this, IsDictionary(dictionary)); | |
| 5132 | |
| 5133 // Store name and value. | 5017 // Store name and value. |
| 5134 StoreFixedArrayElement(dictionary, index, name); | 5018 StoreFixedArrayElement(dictionary, index, name); |
| 5135 StoreValueByKeyIndex<NameDictionary>(dictionary, index, value); | 5019 StoreValueByKeyIndex<NameDictionary>(dictionary, index, value); |
| 5136 | 5020 |
| 5137 // Prepare details of the new property. | 5021 // Prepare details of the new property. |
| 5138 const int kInitialIndex = 0; | 5022 const int kInitialIndex = 0; |
| 5139 PropertyDetails d(kData, NONE, kInitialIndex, PropertyCellType::kNoCell); | 5023 PropertyDetails d(kData, NONE, kInitialIndex, PropertyCellType::kNoCell); |
| 5140 enum_index = | 5024 enum_index = |
| 5141 SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); | 5025 SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift); |
| 5142 STATIC_ASSERT(kInitialIndex == 0); | 5026 STATIC_ASSERT(kInitialIndex == 0); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5164 void CodeStubAssembler::InsertEntry<GlobalDictionary>(Node* dictionary, | 5048 void CodeStubAssembler::InsertEntry<GlobalDictionary>(Node* dictionary, |
| 5165 Node* key, Node* value, | 5049 Node* key, Node* value, |
| 5166 Node* index, | 5050 Node* index, |
| 5167 Node* enum_index) { | 5051 Node* enum_index) { |
| 5168 UNIMPLEMENTED(); | 5052 UNIMPLEMENTED(); |
| 5169 } | 5053 } |
| 5170 | 5054 |
| 5171 template <class Dictionary> | 5055 template <class Dictionary> |
| 5172 void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value, | 5056 void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value, |
| 5173 Label* bailout) { | 5057 Label* bailout) { |
| 5174 CSA_SLOW_ASSERT(this, IsDictionary(dictionary)); | |
| 5175 Node* capacity = GetCapacity<Dictionary>(dictionary); | 5058 Node* capacity = GetCapacity<Dictionary>(dictionary); |
| 5176 Node* nof = GetNumberOfElements<Dictionary>(dictionary); | 5059 Node* nof = GetNumberOfElements<Dictionary>(dictionary); |
| 5177 Node* new_nof = SmiAdd(nof, SmiConstant(1)); | 5060 Node* new_nof = SmiAdd(nof, SmiConstant(1)); |
| 5178 // Require 33% to still be free after adding additional_elements. | 5061 // Require 33% to still be free after adding additional_elements. |
| 5179 // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi! | 5062 // Computing "x + (x >> 1)" on a Smi x does not return a valid Smi! |
| 5180 // But that's OK here because it's only used for a comparison. | 5063 // But that's OK here because it's only used for a comparison. |
| 5181 Node* required_capacity_pseudo_smi = SmiAdd(new_nof, SmiShr(new_nof, 1)); | 5064 Node* required_capacity_pseudo_smi = SmiAdd(new_nof, SmiShr(new_nof, 1)); |
| 5182 GotoIf(SmiBelow(capacity, required_capacity_pseudo_smi), bailout); | 5065 GotoIf(SmiBelow(capacity, required_capacity_pseudo_smi), bailout); |
| 5183 // Require rehashing if more than 50% of free elements are deleted elements. | 5066 // Require rehashing if more than 50% of free elements are deleted elements. |
| 5184 Node* deleted = GetNumberOfDeletedElements<Dictionary>(dictionary); | 5067 Node* deleted = GetNumberOfDeletedElements<Dictionary>(dictionary); |
| (...skipping 1694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6879 Goto(&end); | 6762 Goto(&end); |
| 6880 } | 6763 } |
| 6881 | 6764 |
| 6882 BIND(&end); | 6765 BIND(&end); |
| 6883 } | 6766 } |
| 6884 | 6767 |
| 6885 Node* CodeStubAssembler::BuildFastLoop( | 6768 Node* CodeStubAssembler::BuildFastLoop( |
| 6886 const CodeStubAssembler::VariableList& vars, Node* start_index, | 6769 const CodeStubAssembler::VariableList& vars, Node* start_index, |
| 6887 Node* end_index, const FastLoopBody& body, int increment, | 6770 Node* end_index, const FastLoopBody& body, int increment, |
| 6888 ParameterMode parameter_mode, IndexAdvanceMode advance_mode) { | 6771 ParameterMode parameter_mode, IndexAdvanceMode advance_mode) { |
| 6889 CSA_SLOW_ASSERT(this, MatchesParameterMode(start_index, parameter_mode)); | |
| 6890 CSA_SLOW_ASSERT(this, MatchesParameterMode(end_index, parameter_mode)); | |
| 6891 MachineRepresentation index_rep = (parameter_mode == INTPTR_PARAMETERS) | 6772 MachineRepresentation index_rep = (parameter_mode == INTPTR_PARAMETERS) |
| 6892 ? MachineType::PointerRepresentation() | 6773 ? MachineType::PointerRepresentation() |
| 6893 : MachineRepresentation::kTaggedSigned; | 6774 : MachineRepresentation::kTaggedSigned; |
| 6894 VARIABLE(var, index_rep, start_index); | 6775 VARIABLE(var, index_rep, start_index); |
| 6895 VariableList vars_copy(vars, zone()); | 6776 VariableList vars_copy(vars, zone()); |
| 6896 vars_copy.Add(&var, zone()); | 6777 vars_copy.Add(&var, zone()); |
| 6897 Label loop(this, vars_copy); | 6778 Label loop(this, vars_copy); |
| 6898 Label after_loop(this); | 6779 Label after_loop(this); |
| 6899 // Introduce an explicit second check of the termination condition before the | 6780 // Introduce an explicit second check of the termination condition before the |
| 6900 // loop that helps turbofan generate better code. If there's only a single | 6781 // loop that helps turbofan generate better code. If there's only a single |
| (...skipping 17 matching lines...) Expand all Loading... |
| 6918 BIND(&after_loop); | 6799 BIND(&after_loop); |
| 6919 return var.value(); | 6800 return var.value(); |
| 6920 } | 6801 } |
| 6921 | 6802 |
| 6922 void CodeStubAssembler::BuildFastFixedArrayForEach( | 6803 void CodeStubAssembler::BuildFastFixedArrayForEach( |
| 6923 const CodeStubAssembler::VariableList& vars, Node* fixed_array, | 6804 const CodeStubAssembler::VariableList& vars, Node* fixed_array, |
| 6924 ElementsKind kind, Node* first_element_inclusive, | 6805 ElementsKind kind, Node* first_element_inclusive, |
| 6925 Node* last_element_exclusive, const FastFixedArrayForEachBody& body, | 6806 Node* last_element_exclusive, const FastFixedArrayForEachBody& body, |
| 6926 ParameterMode mode, ForEachDirection direction) { | 6807 ParameterMode mode, ForEachDirection direction) { |
| 6927 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); | 6808 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); |
| 6928 CSA_SLOW_ASSERT(this, MatchesParameterMode(first_element_inclusive, mode)); | |
| 6929 CSA_SLOW_ASSERT(this, MatchesParameterMode(last_element_exclusive, mode)); | |
| 6930 CSA_SLOW_ASSERT(this, IsFixedArrayWithKind(fixed_array, kind)); | |
| 6931 int32_t first_val; | 6809 int32_t first_val; |
| 6932 bool constant_first = ToInt32Constant(first_element_inclusive, first_val); | 6810 bool constant_first = ToInt32Constant(first_element_inclusive, first_val); |
| 6933 int32_t last_val; | 6811 int32_t last_val; |
| 6934 bool constent_last = ToInt32Constant(last_element_exclusive, last_val); | 6812 bool constent_last = ToInt32Constant(last_element_exclusive, last_val); |
| 6935 if (constant_first && constent_last) { | 6813 if (constant_first && constent_last) { |
| 6936 int delta = last_val - first_val; | 6814 int delta = last_val - first_val; |
| 6937 DCHECK(delta >= 0); | 6815 DCHECK(delta >= 0); |
| 6938 if (delta <= kElementLoopUnrollThreshold) { | 6816 if (delta <= kElementLoopUnrollThreshold) { |
| 6939 if (direction == ForEachDirection::kForward) { | 6817 if (direction == ForEachDirection::kForward) { |
| 6940 for (int i = first_val; i < last_val; ++i) { | 6818 for (int i = first_val; i < last_val; ++i) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6981 (kMaxRegularHeapObjectSize - base_size) / kPointerSize; | 6859 (kMaxRegularHeapObjectSize - base_size) / kPointerSize; |
| 6982 GotoIf(IntPtrOrSmiGreaterThan( | 6860 GotoIf(IntPtrOrSmiGreaterThan( |
| 6983 element_count, IntPtrOrSmiConstant(max_newspace_parameters, mode), | 6861 element_count, IntPtrOrSmiConstant(max_newspace_parameters, mode), |
| 6984 mode), | 6862 mode), |
| 6985 doesnt_fit); | 6863 doesnt_fit); |
| 6986 } | 6864 } |
| 6987 | 6865 |
| 6988 void CodeStubAssembler::InitializeFieldsWithRoot( | 6866 void CodeStubAssembler::InitializeFieldsWithRoot( |
| 6989 Node* object, Node* start_offset, Node* end_offset, | 6867 Node* object, Node* start_offset, Node* end_offset, |
| 6990 Heap::RootListIndex root_index) { | 6868 Heap::RootListIndex root_index) { |
| 6991 CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); | |
| 6992 start_offset = IntPtrAdd(start_offset, IntPtrConstant(-kHeapObjectTag)); | 6869 start_offset = IntPtrAdd(start_offset, IntPtrConstant(-kHeapObjectTag)); |
| 6993 end_offset = IntPtrAdd(end_offset, IntPtrConstant(-kHeapObjectTag)); | 6870 end_offset = IntPtrAdd(end_offset, IntPtrConstant(-kHeapObjectTag)); |
| 6994 Node* root_value = LoadRoot(root_index); | 6871 Node* root_value = LoadRoot(root_index); |
| 6995 BuildFastLoop(end_offset, start_offset, | 6872 BuildFastLoop(end_offset, start_offset, |
| 6996 [this, object, root_value](Node* current) { | 6873 [this, object, root_value](Node* current) { |
| 6997 StoreNoWriteBarrier(MachineRepresentation::kTagged, object, | 6874 StoreNoWriteBarrier(MachineRepresentation::kTagged, object, |
| 6998 current, root_value); | 6875 current, root_value); |
| 6999 }, | 6876 }, |
| 7000 -kPointerSize, INTPTR_PARAMETERS, | 6877 -kPointerSize, INTPTR_PARAMETERS, |
| 7001 CodeStubAssembler::IndexAdvanceMode::kPre); | 6878 CodeStubAssembler::IndexAdvanceMode::kPre); |
| 7002 } | 6879 } |
| 7003 | 6880 |
| 7004 void CodeStubAssembler::BranchIfNumericRelationalComparison( | 6881 void CodeStubAssembler::BranchIfNumericRelationalComparison( |
| 7005 RelationalComparisonMode mode, Node* lhs, Node* rhs, Label* if_true, | 6882 RelationalComparisonMode mode, Node* lhs, Node* rhs, Label* if_true, |
| 7006 Label* if_false) { | 6883 Label* if_false) { |
| 7007 CSA_SLOW_ASSERT(this, IsNumber(lhs)); | |
| 7008 CSA_SLOW_ASSERT(this, IsNumber(rhs)); | |
| 7009 | |
| 7010 Label end(this); | 6884 Label end(this); |
| 7011 VARIABLE(result, MachineRepresentation::kTagged); | 6885 VARIABLE(result, MachineRepresentation::kTagged); |
| 7012 | 6886 |
| 7013 // Shared entry for floating point comparison. | 6887 // Shared entry for floating point comparison. |
| 7014 Label do_fcmp(this); | 6888 Label do_fcmp(this); |
| 7015 VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64); | 6889 VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64); |
| 7016 VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64); | 6890 VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64); |
| 7017 | 6891 |
| 7018 // Check if the {lhs} is a Smi or a HeapObject. | 6892 // Check if the {lhs} is a Smi or a HeapObject. |
| 7019 Label if_lhsissmi(this), if_lhsisnotsmi(this); | 6893 Label if_lhsissmi(this), if_lhsisnotsmi(this); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7112 Label* if_false) { | 6986 Label* if_false) { |
| 7113 Label if_true(this); | 6987 Label if_true(this); |
| 7114 BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false); | 6988 BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false); |
| 7115 BIND(&if_true); | 6989 BIND(&if_true); |
| 7116 } | 6990 } |
| 7117 | 6991 |
| 7118 Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode, | 6992 Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode, |
| 7119 Node* lhs, Node* rhs, | 6993 Node* lhs, Node* rhs, |
| 7120 Node* context, | 6994 Node* context, |
| 7121 Variable* var_type_feedback) { | 6995 Variable* var_type_feedback) { |
| 7122 CSA_SLOW_ASSERT(this, IsNumber(lhs)); | |
| 7123 CSA_SLOW_ASSERT(this, IsNumber(rhs)); | |
| 7124 | |
| 7125 Label return_true(this), return_false(this), end(this); | 6996 Label return_true(this), return_false(this), end(this); |
| 7126 VARIABLE(result, MachineRepresentation::kTagged); | 6997 VARIABLE(result, MachineRepresentation::kTagged); |
| 7127 | 6998 |
| 7128 // Shared entry for floating point comparison. | 6999 // Shared entry for floating point comparison. |
| 7129 Label do_fcmp(this); | 7000 Label do_fcmp(this); |
| 7130 VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64); | 7001 VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64); |
| 7131 VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64); | 7002 VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64); |
| 7132 | 7003 |
| 7133 // We might need to loop several times due to ToPrimitive and/or ToNumber | 7004 // We might need to loop several times due to ToPrimitive and/or ToNumber |
| 7134 // conversions. | 7005 // conversions. |
| (...skipping 2099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9234 Load(MachineType::Uint8(), | 9105 Load(MachineType::Uint8(), |
| 9235 ExternalConstant( | 9106 ExternalConstant( |
| 9236 ExternalReference::promise_hook_or_debug_is_active_address( | 9107 ExternalReference::promise_hook_or_debug_is_active_address( |
| 9237 isolate()))); | 9108 isolate()))); |
| 9238 return Word32NotEqual(promise_hook_or_debug_is_active, Int32Constant(0)); | 9109 return Word32NotEqual(promise_hook_or_debug_is_active, Int32Constant(0)); |
| 9239 } | 9110 } |
| 9240 | 9111 |
| 9241 Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map, | 9112 Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map, |
| 9242 Node* shared_info, | 9113 Node* shared_info, |
| 9243 Node* context) { | 9114 Node* context) { |
| 9244 CSA_SLOW_ASSERT(this, IsMap(map)); | |
| 9245 | |
| 9246 Node* const code = BitcastTaggedToWord( | 9115 Node* const code = BitcastTaggedToWord( |
| 9247 LoadObjectField(shared_info, SharedFunctionInfo::kCodeOffset)); | 9116 LoadObjectField(shared_info, SharedFunctionInfo::kCodeOffset)); |
| 9248 Node* const code_entry = | 9117 Node* const code_entry = |
| 9249 IntPtrAdd(code, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); | 9118 IntPtrAdd(code, IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); |
| 9250 | 9119 |
| 9251 Node* const fun = Allocate(JSFunction::kSize); | 9120 Node* const fun = Allocate(JSFunction::kSize); |
| 9252 StoreMapNoWriteBarrier(fun, map); | 9121 StoreMapNoWriteBarrier(fun, map); |
| 9253 StoreObjectFieldRoot(fun, JSObject::kPropertiesOffset, | 9122 StoreObjectFieldRoot(fun, JSObject::kPropertiesOffset, |
| 9254 Heap::kEmptyFixedArrayRootIndex); | 9123 Heap::kEmptyFixedArrayRootIndex); |
| 9255 StoreObjectFieldRoot(fun, JSObject::kElementsOffset, | 9124 StoreObjectFieldRoot(fun, JSObject::kElementsOffset, |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9322 formatted.c_str(), TENURED); | 9191 formatted.c_str(), TENURED); |
| 9323 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), | 9192 CallRuntime(Runtime::kGlobalPrint, NoContextConstant(), |
| 9324 HeapConstant(string)); | 9193 HeapConstant(string)); |
| 9325 } | 9194 } |
| 9326 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); | 9195 CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value); |
| 9327 #endif | 9196 #endif |
| 9328 } | 9197 } |
| 9329 | 9198 |
| 9330 } // namespace internal | 9199 } // namespace internal |
| 9331 } // namespace v8 | 9200 } // namespace v8 |
| OLD | NEW |