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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 Ldr(scratch2, MemOperand(scratch2)); | 1542 Ldr(scratch2, MemOperand(scratch2)); |
1543 Cmp(scratch1, scratch2); | 1543 Cmp(scratch1, scratch2); |
1544 B(gt, no_memento_found); | 1544 B(gt, no_memento_found); |
1545 | 1545 |
1546 Ldr(scratch1, MemOperand(scratch1, -AllocationMemento::kSize)); | 1546 Ldr(scratch1, MemOperand(scratch1, -AllocationMemento::kSize)); |
1547 Cmp(scratch1, | 1547 Cmp(scratch1, |
1548 Operand(isolate()->factory()->allocation_memento_map())); | 1548 Operand(isolate()->factory()->allocation_memento_map())); |
1549 } | 1549 } |
1550 | 1550 |
1551 | 1551 |
1552 void MacroAssembler::JumpToHandlerEntry(Register exception, | |
1553 Register object, | |
1554 Register state, | |
1555 Register scratch1, | |
1556 Register scratch2) { | |
1557 // Handler expects argument in x0. | |
1558 DCHECK(exception.Is(x0)); | |
1559 | |
1560 // Compute the handler entry address and jump to it. The handler table is | |
1561 // a fixed array of (smi-tagged) code offsets. | |
1562 Ldr(scratch1, FieldMemOperand(object, Code::kHandlerTableOffset)); | |
1563 Add(scratch1, scratch1, FixedArray::kHeaderSize - kHeapObjectTag); | |
1564 STATIC_ASSERT(StackHandler::kKindWidth < kPointerSizeLog2); | |
1565 Lsr(scratch2, state, StackHandler::kKindWidth); | |
1566 Ldr(scratch2, MemOperand(scratch1, scratch2, LSL, kPointerSizeLog2)); | |
1567 Add(scratch1, object, Code::kHeaderSize - kHeapObjectTag); | |
1568 Add(scratch1, scratch1, Operand::UntagSmi(scratch2)); | |
1569 Br(scratch1); | |
1570 } | |
1571 | |
1572 | |
1573 void MacroAssembler::InNewSpace(Register object, | 1552 void MacroAssembler::InNewSpace(Register object, |
1574 Condition cond, | 1553 Condition cond, |
1575 Label* branch) { | 1554 Label* branch) { |
1576 DCHECK(cond == eq || cond == ne); | 1555 DCHECK(cond == eq || cond == ne); |
1577 UseScratchRegisterScope temps(this); | 1556 UseScratchRegisterScope temps(this); |
1578 Register temp = temps.AcquireX(); | 1557 Register temp = temps.AcquireX(); |
1579 And(temp, object, ExternalReference::new_space_mask(isolate())); | 1558 And(temp, object, ExternalReference::new_space_mask(isolate())); |
1580 Cmp(temp, ExternalReference::new_space_start(isolate())); | 1559 Cmp(temp, ExternalReference::new_space_start(isolate())); |
1581 B(cond, branch); | 1560 B(cond, branch); |
1582 } | 1561 } |
1583 | 1562 |
1584 | 1563 |
1585 void MacroAssembler::Throw(Register value, | |
1586 Register scratch1, | |
1587 Register scratch2, | |
1588 Register scratch3, | |
1589 Register scratch4) { | |
1590 // Adjust this code if not the case. | |
1591 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | |
1592 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
1593 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | |
1594 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | |
1595 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | |
1596 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | |
1597 | |
1598 // The handler expects the exception in x0. | |
1599 DCHECK(value.Is(x0)); | |
1600 | |
1601 // Drop the stack pointer to the top of the top handler. | |
1602 DCHECK(jssp.Is(StackPointer())); | |
1603 Mov(scratch1, Operand(ExternalReference(Isolate::kHandlerAddress, | |
1604 isolate()))); | |
1605 Ldr(jssp, MemOperand(scratch1)); | |
1606 // Restore the next handler. | |
1607 Pop(scratch2); | |
1608 Str(scratch2, MemOperand(scratch1)); | |
1609 | |
1610 // Get the code object and state. Restore the context and frame pointer. | |
1611 Register object = scratch1; | |
1612 Register state = scratch2; | |
1613 Pop(object, state, cp, fp); | |
1614 | |
1615 // If the handler is a JS frame, restore the context to the frame. | |
1616 // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp | |
1617 // or cp. | |
1618 Label not_js_frame; | |
1619 Cbz(cp, ¬_js_frame); | |
1620 Str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
1621 Bind(¬_js_frame); | |
1622 | |
1623 JumpToHandlerEntry(value, object, state, scratch3, scratch4); | |
1624 } | |
1625 | |
1626 | |
1627 void MacroAssembler::ThrowUncatchable(Register value, | |
1628 Register scratch1, | |
1629 Register scratch2, | |
1630 Register scratch3, | |
1631 Register scratch4) { | |
1632 // Adjust this code if not the case. | |
1633 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | |
1634 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); | |
1635 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | |
1636 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | |
1637 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | |
1638 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | |
1639 | |
1640 // The handler expects the exception in x0. | |
1641 DCHECK(value.Is(x0)); | |
1642 | |
1643 // Drop the stack pointer to the top of the top stack handler. | |
1644 DCHECK(jssp.Is(StackPointer())); | |
1645 Mov(scratch1, Operand(ExternalReference(Isolate::kHandlerAddress, | |
1646 isolate()))); | |
1647 Ldr(jssp, MemOperand(scratch1)); | |
1648 | |
1649 // Unwind the handlers until the ENTRY handler is found. | |
1650 Label fetch_next, check_kind; | |
1651 B(&check_kind); | |
1652 Bind(&fetch_next); | |
1653 Peek(jssp, StackHandlerConstants::kNextOffset); | |
1654 | |
1655 Bind(&check_kind); | |
1656 STATIC_ASSERT(StackHandler::JS_ENTRY == 0); | |
1657 Peek(scratch2, StackHandlerConstants::kStateOffset); | |
1658 TestAndBranchIfAnySet(scratch2, StackHandler::KindField::kMask, &fetch_next); | |
1659 | |
1660 // Set the top handler address to next handler past the top ENTRY handler. | |
1661 Pop(scratch2); | |
1662 Str(scratch2, MemOperand(scratch1)); | |
1663 | |
1664 // Get the code object and state. Clear the context and frame pointer (0 was | |
1665 // saved in the handler). | |
1666 Register object = scratch1; | |
1667 Register state = scratch2; | |
1668 Pop(object, state, cp, fp); | |
1669 | |
1670 JumpToHandlerEntry(value, object, state, scratch3, scratch4); | |
1671 } | |
1672 | |
1673 | |
1674 void MacroAssembler::AssertSmi(Register object, BailoutReason reason) { | 1564 void MacroAssembler::AssertSmi(Register object, BailoutReason reason) { |
1675 if (emit_debug_code()) { | 1565 if (emit_debug_code()) { |
1676 STATIC_ASSERT(kSmiTag == 0); | 1566 STATIC_ASSERT(kSmiTag == 0); |
1677 Tst(object, kSmiTagMask); | 1567 Tst(object, kSmiTagMask); |
1678 Check(eq, reason); | 1568 Check(eq, reason); |
1679 } | 1569 } |
1680 } | 1570 } |
1681 | 1571 |
1682 | 1572 |
1683 void MacroAssembler::AssertNotSmi(Register object, BailoutReason reason) { | 1573 void MacroAssembler::AssertNotSmi(Register object, BailoutReason reason) { |
(...skipping 3591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5275 } | 5165 } |
5276 } | 5166 } |
5277 | 5167 |
5278 | 5168 |
5279 #undef __ | 5169 #undef __ |
5280 | 5170 |
5281 | 5171 |
5282 } } // namespace v8::internal | 5172 } } // namespace v8::internal |
5283 | 5173 |
5284 #endif // V8_TARGET_ARCH_ARM64 | 5174 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |