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 |