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