| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1741 __ Cmp(x10, Isolate::kJSRegexpStaticOffsetsVectorSize - 2); | 1741 __ Cmp(x10, Isolate::kJSRegexpStaticOffsetsVectorSize - 2); |
| 1742 __ B(hi, &runtime); | 1742 __ B(hi, &runtime); |
| 1743 | 1743 |
| 1744 // Initialize offset for possibly sliced string. | 1744 // Initialize offset for possibly sliced string. |
| 1745 __ Mov(sliced_string_offset, 0); | 1745 __ Mov(sliced_string_offset, 0); |
| 1746 | 1746 |
| 1747 DCHECK(jssp.Is(__ StackPointer())); | 1747 DCHECK(jssp.Is(__ StackPointer())); |
| 1748 __ Peek(subject, kSubjectOffset); | 1748 __ Peek(subject, kSubjectOffset); |
| 1749 __ JumpIfSmi(subject, &runtime); | 1749 __ JumpIfSmi(subject, &runtime); |
| 1750 | 1750 |
| 1751 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); | |
| 1752 __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset)); | |
| 1753 | |
| 1754 __ Ldr(jsstring_length, FieldMemOperand(subject, String::kLengthOffset)); | 1751 __ Ldr(jsstring_length, FieldMemOperand(subject, String::kLengthOffset)); |
| 1755 | 1752 |
| 1756 // Handle subject string according to its encoding and representation: | 1753 // Handle subject string according to its encoding and representation: |
| 1757 // (1) Sequential string? If yes, go to (5). | 1754 // (1) Sequential string? If yes, go to (4). |
| 1758 // (2) Anything but sequential or cons? If yes, go to (6). | 1755 // (2) Sequential or cons? If not, go to (5). |
| 1759 // (3) Cons string. If the string is flat, replace subject with first string. | 1756 // (3) Cons string. If the string is flat, replace subject with first string |
| 1760 // Otherwise bailout. | 1757 // and go to (1). Otherwise bail out to runtime. |
| 1761 // (4) Is subject external? If yes, go to (7). | 1758 // (4) Sequential string. Load regexp code according to encoding. |
| 1762 // (5) Sequential string. Load regexp code according to encoding. | |
| 1763 // (E) Carry on. | 1759 // (E) Carry on. |
| 1764 /// [...] | 1760 /// [...] |
| 1765 | 1761 |
| 1766 // Deferred code at the end of the stub: | 1762 // Deferred code at the end of the stub: |
| 1767 // (6) Not a long external string? If yes, go to (8). | 1763 // (5) Long external string? If not, go to (7). |
| 1768 // (7) External string. Make it, offset-wise, look like a sequential string. | 1764 // (6) External string. Make it, offset-wise, look like a sequential string. |
| 1769 // Go to (5). | 1765 // Go to (4). |
| 1770 // (8) Short external string or not a string? If yes, bail out to runtime. | 1766 // (7) Short external string or not a string? If yes, bail out to runtime. |
| 1771 // (9) Sliced string. Replace subject with parent. Go to (4). | 1767 // (8) Sliced string. Replace subject with parent. Go to (1). |
| 1772 | 1768 |
| 1773 Label check_underlying; // (4) | 1769 Label check_underlying; // (1) |
| 1774 Label seq_string; // (5) | 1770 Label seq_string; // (4) |
| 1775 Label not_seq_nor_cons; // (6) | 1771 Label not_seq_nor_cons; // (5) |
| 1776 Label external_string; // (7) | 1772 Label external_string; // (6) |
| 1777 Label not_long_external; // (8) | 1773 Label not_long_external; // (7) |
| 1778 | 1774 |
| 1779 // (1) Sequential string? If yes, go to (5). | 1775 __ Bind(&check_underlying); |
| 1776 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); |
| 1777 __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset)); |
| 1778 |
| 1779 // (1) Sequential string? If yes, go to (4). |
| 1780 __ And(string_representation, | 1780 __ And(string_representation, |
| 1781 string_type, | 1781 string_type, |
| 1782 kIsNotStringMask | | 1782 kIsNotStringMask | |
| 1783 kStringRepresentationMask | | 1783 kStringRepresentationMask | |
| 1784 kShortExternalStringMask); | 1784 kShortExternalStringMask); |
| 1785 // We depend on the fact that Strings of type | 1785 // We depend on the fact that Strings of type |
| 1786 // SeqString and not ShortExternalString are defined | 1786 // SeqString and not ShortExternalString are defined |
| 1787 // by the following pattern: | 1787 // by the following pattern: |
| 1788 // string_type: 0XX0 XX00 | 1788 // string_type: 0XX0 XX00 |
| 1789 // ^ ^ ^^ | 1789 // ^ ^ ^^ |
| 1790 // | | || | 1790 // | | || |
| 1791 // | | is a SeqString | 1791 // | | is a SeqString |
| 1792 // | is not a short external String | 1792 // | is not a short external String |
| 1793 // is a String | 1793 // is a String |
| 1794 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); | 1794 STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); |
| 1795 STATIC_ASSERT(kShortExternalStringTag != 0); | 1795 STATIC_ASSERT(kShortExternalStringTag != 0); |
| 1796 __ Cbz(string_representation, &seq_string); // Go to (5). | 1796 __ Cbz(string_representation, &seq_string); // Go to (4). |
| 1797 | 1797 |
| 1798 // (2) Anything but sequential or cons? If yes, go to (6). | 1798 // (2) Sequential or cons? If not, go to (5). |
| 1799 STATIC_ASSERT(kConsStringTag < kExternalStringTag); | 1799 STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
| 1800 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); | 1800 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
| 1801 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); | 1801 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); |
| 1802 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); | 1802 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); |
| 1803 __ Cmp(string_representation, kExternalStringTag); | 1803 __ Cmp(string_representation, kExternalStringTag); |
| 1804 __ B(ge, ¬_seq_nor_cons); // Go to (6). | 1804 __ B(ge, ¬_seq_nor_cons); // Go to (5). |
| 1805 | 1805 |
| 1806 // (3) Cons string. Check that it's flat. | 1806 // (3) Cons string. Check that it's flat. |
| 1807 __ Ldr(x10, FieldMemOperand(subject, ConsString::kSecondOffset)); | 1807 __ Ldr(x10, FieldMemOperand(subject, ConsString::kSecondOffset)); |
| 1808 __ JumpIfNotRoot(x10, Heap::kempty_stringRootIndex, &runtime); | 1808 __ JumpIfNotRoot(x10, Heap::kempty_stringRootIndex, &runtime); |
| 1809 // Replace subject with first string. | 1809 // Replace subject with first string. |
| 1810 __ Ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); | 1810 __ Ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); |
| 1811 __ B(&check_underlying); |
| 1811 | 1812 |
| 1812 // (4) Is subject external? If yes, go to (7). | 1813 // (4) Sequential string. Load regexp code according to encoding. |
| 1813 __ Bind(&check_underlying); | |
| 1814 // Reload the string type. | |
| 1815 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); | |
| 1816 __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset)); | |
| 1817 STATIC_ASSERT(kSeqStringTag == 0); | |
| 1818 // The underlying external string is never a short external string. | |
| 1819 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength); | |
| 1820 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength); | |
| 1821 __ TestAndBranchIfAnySet(string_type.X(), | |
| 1822 kStringRepresentationMask, | |
| 1823 &external_string); // Go to (7). | |
| 1824 | |
| 1825 // (5) Sequential string. Load regexp code according to encoding. | |
| 1826 __ Bind(&seq_string); | 1814 __ Bind(&seq_string); |
| 1827 | 1815 |
| 1828 // Check that the third argument is a positive smi less than the subject | 1816 // Check that the third argument is a positive smi less than the subject |
| 1829 // string length. A negative value will be greater (unsigned comparison). | 1817 // string length. A negative value will be greater (unsigned comparison). |
| 1830 DCHECK(jssp.Is(__ StackPointer())); | 1818 DCHECK(jssp.Is(__ StackPointer())); |
| 1831 __ Peek(x10, kPreviousIndexOffset); | 1819 __ Peek(x10, kPreviousIndexOffset); |
| 1832 __ JumpIfNotSmi(x10, &runtime); | 1820 __ JumpIfNotSmi(x10, &runtime); |
| 1833 __ Cmp(jsstring_length, x10); | 1821 __ Cmp(jsstring_length, x10); |
| 1834 __ B(ls, &runtime); | 1822 __ B(ls, &runtime); |
| 1835 | 1823 |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2085 __ Bind(&failure); | 2073 __ Bind(&failure); |
| 2086 __ Mov(x0, Operand(isolate()->factory()->null_value())); | 2074 __ Mov(x0, Operand(isolate()->factory()->null_value())); |
| 2087 // Drop the 4 arguments of the stub from the stack. | 2075 // Drop the 4 arguments of the stub from the stack. |
| 2088 __ Drop(4); | 2076 __ Drop(4); |
| 2089 __ Ret(); | 2077 __ Ret(); |
| 2090 | 2078 |
| 2091 __ Bind(&runtime); | 2079 __ Bind(&runtime); |
| 2092 __ TailCallRuntime(Runtime::kRegExpExec); | 2080 __ TailCallRuntime(Runtime::kRegExpExec); |
| 2093 | 2081 |
| 2094 // Deferred code for string handling. | 2082 // Deferred code for string handling. |
| 2095 // (6) Not a long external string? If yes, go to (8). | 2083 // (5) Long external string? If not, go to (7). |
| 2096 __ Bind(¬_seq_nor_cons); | 2084 __ Bind(¬_seq_nor_cons); |
| 2097 // Compare flags are still set. | 2085 // Compare flags are still set. |
| 2098 __ B(ne, ¬_long_external); // Go to (8). | 2086 __ B(ne, ¬_long_external); // Go to (7). |
| 2099 | 2087 |
| 2100 // (7) External string. Make it, offset-wise, look like a sequential string. | 2088 // (6) External string. Make it, offset-wise, look like a sequential string. |
| 2101 __ Bind(&external_string); | 2089 __ Bind(&external_string); |
| 2102 if (masm->emit_debug_code()) { | 2090 if (masm->emit_debug_code()) { |
| 2103 // Assert that we do not have a cons or slice (indirect strings) here. | 2091 // Assert that we do not have a cons or slice (indirect strings) here. |
| 2104 // Sequential strings have already been ruled out. | 2092 // Sequential strings have already been ruled out. |
| 2105 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); | 2093 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); |
| 2106 __ Ldrb(x10, FieldMemOperand(x10, Map::kInstanceTypeOffset)); | 2094 __ Ldrb(x10, FieldMemOperand(x10, Map::kInstanceTypeOffset)); |
| 2107 __ Tst(x10, kIsIndirectStringMask); | 2095 __ Tst(x10, kIsIndirectStringMask); |
| 2108 __ Check(eq, kExternalStringExpectedButNotFound); | 2096 __ Check(eq, kExternalStringExpectedButNotFound); |
| 2109 __ And(x10, x10, kStringRepresentationMask); | 2097 __ And(x10, x10, kStringRepresentationMask); |
| 2110 __ Cmp(x10, 0); | 2098 __ Cmp(x10, 0); |
| 2111 __ Check(ne, kExternalStringExpectedButNotFound); | 2099 __ Check(ne, kExternalStringExpectedButNotFound); |
| 2112 } | 2100 } |
| 2113 __ Ldr(subject, | 2101 __ Ldr(subject, |
| 2114 FieldMemOperand(subject, ExternalString::kResourceDataOffset)); | 2102 FieldMemOperand(subject, ExternalString::kResourceDataOffset)); |
| 2115 // Move the pointer so that offset-wise, it looks like a sequential string. | 2103 // Move the pointer so that offset-wise, it looks like a sequential string. |
| 2116 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); | 2104 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); |
| 2117 __ Sub(subject, subject, SeqTwoByteString::kHeaderSize - kHeapObjectTag); | 2105 __ Sub(subject, subject, SeqTwoByteString::kHeaderSize - kHeapObjectTag); |
| 2118 __ B(&seq_string); // Go to (5). | 2106 __ B(&seq_string); // Go to (4). |
| 2119 | 2107 |
| 2120 // (8) If this is a short external string or not a string, bail out to | 2108 // (7) If this is a short external string or not a string, bail out to |
| 2121 // runtime. | 2109 // runtime. |
| 2122 __ Bind(¬_long_external); | 2110 __ Bind(¬_long_external); |
| 2123 STATIC_ASSERT(kShortExternalStringTag != 0); | 2111 STATIC_ASSERT(kShortExternalStringTag != 0); |
| 2124 __ TestAndBranchIfAnySet(string_representation, | 2112 __ TestAndBranchIfAnySet(string_representation, |
| 2125 kShortExternalStringMask | kIsNotStringMask, | 2113 kShortExternalStringMask | kIsNotStringMask, |
| 2126 &runtime); | 2114 &runtime); |
| 2127 | 2115 |
| 2128 // (9) Sliced string. Replace subject with parent. | 2116 // (8) Sliced string. Replace subject with parent. |
| 2129 __ Ldr(sliced_string_offset, | 2117 __ Ldr(sliced_string_offset, |
| 2130 UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2118 UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset)); |
| 2131 __ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2119 __ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
| 2132 __ B(&check_underlying); // Go to (4). | 2120 __ B(&check_underlying); // Go to (1). |
| 2133 #endif | 2121 #endif |
| 2134 } | 2122 } |
| 2135 | 2123 |
| 2136 | 2124 |
| 2137 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 2125 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, |
| 2138 Register argc, Register function, | 2126 Register argc, Register function, |
| 2139 Register feedback_vector, Register index, | 2127 Register feedback_vector, Register index, |
| 2140 Register new_target) { | 2128 Register new_target) { |
| 2141 FrameScope scope(masm, StackFrame::INTERNAL); | 2129 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2142 | 2130 |
| (...skipping 3796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5939 return_value_operand, NULL); | 5927 return_value_operand, NULL); |
| 5940 } | 5928 } |
| 5941 | 5929 |
| 5942 | 5930 |
| 5943 #undef __ | 5931 #undef __ |
| 5944 | 5932 |
| 5945 } // namespace internal | 5933 } // namespace internal |
| 5946 } // namespace v8 | 5934 } // namespace v8 |
| 5947 | 5935 |
| 5948 #endif // V8_TARGET_ARCH_ARM64 | 5936 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |