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 |