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