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 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 // and go to (1). Otherwise bail out to runtime. | 1435 // and go to (1). Otherwise bail out to runtime. |
1436 // (4) Sequential string. Load regexp code according to encoding. | 1436 // (4) Sequential string. Load regexp code according to encoding. |
1437 // (E) Carry on. | 1437 // (E) Carry on. |
1438 /// [...] | 1438 /// [...] |
1439 | 1439 |
1440 // Deferred code at the end of the stub: | 1440 // Deferred code at the end of the stub: |
1441 // (5) Long external string? If not, go to (7). | 1441 // (5) Long external string? If not, go to (7). |
1442 // (6) External string. Make it, offset-wise, look like a sequential string. | 1442 // (6) External string. Make it, offset-wise, look like a sequential string. |
1443 // Go to (4). | 1443 // Go to (4). |
1444 // (7) Short external string or not a string? If yes, bail out to runtime. | 1444 // (7) Short external string or not a string? If yes, bail out to runtime. |
1445 // (8) Sliced string. Replace subject with parent. Go to (1). | 1445 // (8) Sliced or thin string. Replace subject with parent. Go to (1). |
1446 | 1446 |
1447 Label check_underlying; // (1) | 1447 Label check_underlying; // (1) |
1448 Label seq_string; // (4) | 1448 Label seq_string; // (4) |
1449 Label not_seq_nor_cons; // (5) | 1449 Label not_seq_nor_cons; // (5) |
1450 Label external_string; // (6) | 1450 Label external_string; // (6) |
1451 Label not_long_external; // (7) | 1451 Label not_long_external; // (7) |
1452 | 1452 |
1453 __ Bind(&check_underlying); | 1453 __ Bind(&check_underlying); |
1454 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); | 1454 __ Ldr(x10, FieldMemOperand(subject, HeapObject::kMapOffset)); |
1455 __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset)); | 1455 __ Ldrb(string_type, FieldMemOperand(x10, Map::kInstanceTypeOffset)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 DCHECK(jssp.Is(__ StackPointer())); | 1496 DCHECK(jssp.Is(__ StackPointer())); |
1497 __ Peek(x10, kPreviousIndexOffset); | 1497 __ Peek(x10, kPreviousIndexOffset); |
1498 __ JumpIfNotSmi(x10, &runtime); | 1498 __ JumpIfNotSmi(x10, &runtime); |
1499 __ Cmp(jsstring_length, x10); | 1499 __ Cmp(jsstring_length, x10); |
1500 __ B(ls, &runtime); | 1500 __ B(ls, &runtime); |
1501 | 1501 |
1502 // Argument 2 (x1): We need to load argument 2 (the previous index) into x1 | 1502 // Argument 2 (x1): We need to load argument 2 (the previous index) into x1 |
1503 // before entering the exit frame. | 1503 // before entering the exit frame. |
1504 __ SmiUntag(x1, x10); | 1504 __ SmiUntag(x1, x10); |
1505 | 1505 |
1506 // The third bit determines the string encoding in string_type. | 1506 // The fourth bit determines the string encoding in string_type. |
1507 STATIC_ASSERT(kOneByteStringTag == 0x04); | 1507 STATIC_ASSERT(kOneByteStringTag == 0x08); |
1508 STATIC_ASSERT(kTwoByteStringTag == 0x00); | 1508 STATIC_ASSERT(kTwoByteStringTag == 0x00); |
1509 STATIC_ASSERT(kStringEncodingMask == 0x04); | 1509 STATIC_ASSERT(kStringEncodingMask == 0x08); |
1510 | 1510 |
1511 // Find the code object based on the assumptions above. | 1511 // Find the code object based on the assumptions above. |
1512 // kDataOneByteCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset | 1512 // kDataOneByteCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset |
1513 // of kPointerSize to reach the latter. | 1513 // of kPointerSize to reach the latter. |
1514 STATIC_ASSERT(JSRegExp::kDataOneByteCodeOffset + kPointerSize == | 1514 STATIC_ASSERT(JSRegExp::kDataOneByteCodeOffset + kPointerSize == |
1515 JSRegExp::kDataUC16CodeOffset); | 1515 JSRegExp::kDataUC16CodeOffset); |
1516 __ Mov(x10, kPointerSize); | 1516 __ Mov(x10, kPointerSize); |
1517 // We will need the encoding later: Latin1 = 0x04 | 1517 // We will need the encoding later: Latin1 = 0x08 |
1518 // UC16 = 0x00 | 1518 // UC16 = 0x00 |
1519 __ Ands(string_encoding, string_type, kStringEncodingMask); | 1519 __ Ands(string_encoding, string_type, kStringEncodingMask); |
1520 __ CzeroX(x10, ne); | 1520 __ CzeroX(x10, ne); |
1521 __ Add(x10, regexp_data, x10); | 1521 __ Add(x10, regexp_data, x10); |
1522 __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataOneByteCodeOffset)); | 1522 __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataOneByteCodeOffset)); |
1523 | 1523 |
1524 // (E) Carry on. String handling is done. | 1524 // (E) Carry on. String handling is done. |
1525 | 1525 |
1526 // Check that the irregexp code has been generated for the actual string | 1526 // Check that the irregexp code has been generated for the actual string |
1527 // encoding. If it has, the field contains a code object otherwise it contains | 1527 // encoding. If it has, the field contains a code object otherwise it contains |
(...skipping 27 matching lines...) Expand all Loading... |
1555 // Load start of the subject string. | 1555 // Load start of the subject string. |
1556 __ Add(start, subject, SeqString::kHeaderSize - kHeapObjectTag); | 1556 __ Add(start, subject, SeqString::kHeaderSize - kHeapObjectTag); |
1557 // Load the length from the original subject string from the previous stack | 1557 // Load the length from the original subject string from the previous stack |
1558 // frame. Therefore we have to use fp, which points exactly to two pointer | 1558 // frame. Therefore we have to use fp, which points exactly to two pointer |
1559 // sizes below the previous sp. (Because creating a new stack frame pushes | 1559 // sizes below the previous sp. (Because creating a new stack frame pushes |
1560 // the previous fp onto the stack and decrements sp by 2 * kPointerSize.) | 1560 // the previous fp onto the stack and decrements sp by 2 * kPointerSize.) |
1561 __ Ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); | 1561 __ Ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); |
1562 __ Ldr(length, UntagSmiFieldMemOperand(subject, String::kLengthOffset)); | 1562 __ Ldr(length, UntagSmiFieldMemOperand(subject, String::kLengthOffset)); |
1563 | 1563 |
1564 // Handle UC16 encoding, two bytes make one character. | 1564 // Handle UC16 encoding, two bytes make one character. |
1565 // string_encoding: if Latin1: 0x04 | 1565 // string_encoding: if Latin1: 0x08 |
1566 // if UC16: 0x00 | 1566 // if UC16: 0x00 |
1567 STATIC_ASSERT(kStringEncodingMask == 0x04); | 1567 STATIC_ASSERT(kStringEncodingMask == 0x08); |
1568 __ Ubfx(string_encoding, string_encoding, 2, 1); | 1568 __ Ubfx(string_encoding, string_encoding, 3, 1); |
1569 __ Eor(string_encoding, string_encoding, 1); | 1569 __ Eor(string_encoding, string_encoding, 1); |
1570 // string_encoding: if Latin1: 0 | 1570 // string_encoding: if Latin1: 0 |
1571 // if UC16: 1 | 1571 // if UC16: 1 |
1572 | 1572 |
1573 // Convert string positions from characters to bytes. | 1573 // Convert string positions from characters to bytes. |
1574 // Previous index is in x1. | 1574 // Previous index is in x1. |
1575 __ Lsl(previous_index_in_bytes, w1, string_encoding); | 1575 __ Lsl(previous_index_in_bytes, w1, string_encoding); |
1576 __ Lsl(length, length, string_encoding); | 1576 __ Lsl(length, length, string_encoding); |
1577 __ Lsl(sliced_string_offset, sliced_string_offset, string_encoding); | 1577 __ Lsl(sliced_string_offset, sliced_string_offset, string_encoding); |
1578 | 1578 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 __ B(&seq_string); // Go to (4). | 1771 __ B(&seq_string); // Go to (4). |
1772 | 1772 |
1773 // (7) If this is a short external string or not a string, bail out to | 1773 // (7) If this is a short external string or not a string, bail out to |
1774 // runtime. | 1774 // runtime. |
1775 __ Bind(¬_long_external); | 1775 __ Bind(¬_long_external); |
1776 STATIC_ASSERT(kShortExternalStringTag != 0); | 1776 STATIC_ASSERT(kShortExternalStringTag != 0); |
1777 __ TestAndBranchIfAnySet(string_representation, | 1777 __ TestAndBranchIfAnySet(string_representation, |
1778 kShortExternalStringMask | kIsNotStringMask, | 1778 kShortExternalStringMask | kIsNotStringMask, |
1779 &runtime); | 1779 &runtime); |
1780 | 1780 |
1781 // (8) Sliced string. Replace subject with parent. | 1781 // (8) Sliced or thin string. Replace subject with parent. |
| 1782 Label thin_string; |
| 1783 __ Cmp(string_representation, kThinStringTag); |
| 1784 __ B(eq, &thin_string); |
1782 __ Ldr(sliced_string_offset, | 1785 __ Ldr(sliced_string_offset, |
1783 UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset)); | 1786 UntagSmiFieldMemOperand(subject, SlicedString::kOffsetOffset)); |
1784 __ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 1787 __ Ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
1785 __ B(&check_underlying); // Go to (1). | 1788 __ B(&check_underlying); // Go to (1). |
| 1789 |
| 1790 __ bind(&thin_string); |
| 1791 __ Ldr(subject, FieldMemOperand(subject, ThinString::kActualOffset)); |
| 1792 __ B(&check_underlying); // Go to (1). |
1786 #endif | 1793 #endif |
1787 } | 1794 } |
1788 | 1795 |
1789 | 1796 |
1790 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 1797 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, |
1791 Register argc, Register function, | 1798 Register argc, Register function, |
1792 Register feedback_vector, Register index, | 1799 Register feedback_vector, Register index, |
1793 Register new_target) { | 1800 Register new_target) { |
1794 FrameScope scope(masm, StackFrame::INTERNAL); | 1801 FrameScope scope(masm, StackFrame::INTERNAL); |
1795 | 1802 |
(...skipping 2877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4673 kStackUnwindSpace, NULL, spill_offset, | 4680 kStackUnwindSpace, NULL, spill_offset, |
4674 return_value_operand, NULL); | 4681 return_value_operand, NULL); |
4675 } | 4682 } |
4676 | 4683 |
4677 #undef __ | 4684 #undef __ |
4678 | 4685 |
4679 } // namespace internal | 4686 } // namespace internal |
4680 } // namespace v8 | 4687 } // namespace v8 |
4681 | 4688 |
4682 #endif // V8_TARGET_ARCH_ARM64 | 4689 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |