OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 | 1470 |
1471 | 1471 |
1472 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { | 1472 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { |
1473 CEntryStub stub(1, kDontSaveFPRegs); | 1473 CEntryStub stub(1, kDontSaveFPRegs); |
1474 stub.GetCode(isolate); | 1474 stub.GetCode(isolate); |
1475 CEntryStub stub_fp(1, kSaveFPRegs); | 1475 CEntryStub stub_fp(1, kSaveFPRegs); |
1476 stub_fp.GetCode(isolate); | 1476 stub_fp.GetCode(isolate); |
1477 } | 1477 } |
1478 | 1478 |
1479 | 1479 |
1480 void CEntryStub::GenerateCore(MacroAssembler* masm, | 1480 void CEntryStub::Generate(MacroAssembler* masm) { |
1481 Label* throw_normal, | 1481 // The Abort mechanism relies on CallRuntime, which in turn relies on |
1482 Label* throw_termination, | 1482 // CEntryStub, so until this stub has been generated, we have to use a |
1483 bool do_gc, | 1483 // fall-back Abort mechanism. |
1484 bool always_allocate) { | 1484 // |
1485 // x0 : Result parameter for PerformGC, if do_gc is true. | 1485 // Note that this stub must be generated before any use of Abort. |
| 1486 MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm); |
| 1487 |
| 1488 ASM_LOCATION("CEntryStub::Generate entry"); |
| 1489 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 1490 |
| 1491 // Register parameters: |
| 1492 // x0: argc (including receiver, untagged) |
| 1493 // x1: target |
| 1494 // |
| 1495 // The stack on entry holds the arguments and the receiver, with the receiver |
| 1496 // at the highest address: |
| 1497 // |
| 1498 // jssp]argc-1]: receiver |
| 1499 // jssp[argc-2]: arg[argc-2] |
| 1500 // ... ... |
| 1501 // jssp[1]: arg[1] |
| 1502 // jssp[0]: arg[0] |
| 1503 // |
| 1504 // The arguments are in reverse order, so that arg[argc-2] is actually the |
| 1505 // first argument to the target function and arg[0] is the last. |
| 1506 ASSERT(jssp.Is(__ StackPointer())); |
| 1507 const Register& argc_input = x0; |
| 1508 const Register& target_input = x1; |
| 1509 |
| 1510 // Calculate argv, argc and the target address, and store them in |
| 1511 // callee-saved registers so we can retry the call without having to reload |
| 1512 // these arguments. |
| 1513 // TODO(jbramley): If the first call attempt succeeds in the common case (as |
| 1514 // it should), then we might be better off putting these parameters directly |
| 1515 // into their argument registers, rather than using callee-saved registers and |
| 1516 // preserving them on the stack. |
| 1517 const Register& argv = x21; |
| 1518 const Register& argc = x22; |
| 1519 const Register& target = x23; |
| 1520 |
| 1521 // Derive argv from the stack pointer so that it points to the first argument |
| 1522 // (arg[argc-2]), or just below the receiver in case there are no arguments. |
| 1523 // - Adjust for the arg[] array. |
| 1524 Register temp_argv = x11; |
| 1525 __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2)); |
| 1526 // - Adjust for the receiver. |
| 1527 __ Sub(temp_argv, temp_argv, 1 * kPointerSize); |
| 1528 |
| 1529 // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved |
| 1530 // registers. |
| 1531 FrameScope scope(masm, StackFrame::MANUAL); |
| 1532 __ EnterExitFrame(save_doubles_, x10, 3); |
| 1533 ASSERT(csp.Is(__ StackPointer())); |
| 1534 |
| 1535 // Poke callee-saved registers into reserved space. |
| 1536 __ Poke(argv, 1 * kPointerSize); |
| 1537 __ Poke(argc, 2 * kPointerSize); |
| 1538 __ Poke(target, 3 * kPointerSize); |
| 1539 |
| 1540 // We normally only keep tagged values in callee-saved registers, as they |
| 1541 // could be pushed onto the stack by called stubs and functions, and on the |
| 1542 // stack they can confuse the GC. However, we're only calling C functions |
| 1543 // which can push arbitrary data onto the stack anyway, and so the GC won't |
| 1544 // examine that part of the stack. |
| 1545 __ Mov(argc, argc_input); |
| 1546 __ Mov(target, target_input); |
| 1547 __ Mov(argv, temp_argv); |
| 1548 |
1486 // x21 : argv | 1549 // x21 : argv |
1487 // x22 : argc | 1550 // x22 : argc |
1488 // x23 : target | 1551 // x23 : call target |
1489 // | 1552 // |
1490 // The stack (on entry) holds the arguments and the receiver, with the | 1553 // The stack (on entry) holds the arguments and the receiver, with the |
1491 // receiver at the highest address: | 1554 // receiver at the highest address: |
1492 // | 1555 // |
1493 // argv[8]: receiver | 1556 // argv[8]: receiver |
1494 // argv -> argv[0]: arg[argc-2] | 1557 // argv -> argv[0]: arg[argc-2] |
1495 // ... ... | 1558 // ... ... |
1496 // argv[...]: arg[1] | 1559 // argv[...]: arg[1] |
1497 // argv[...]: arg[0] | 1560 // argv[...]: arg[0] |
1498 // | 1561 // |
1499 // Immediately below (after) this is the exit frame, as constructed by | 1562 // Immediately below (after) this is the exit frame, as constructed by |
1500 // EnterExitFrame: | 1563 // EnterExitFrame: |
1501 // fp[8]: CallerPC (lr) | 1564 // fp[8]: CallerPC (lr) |
1502 // fp -> fp[0]: CallerFP (old fp) | 1565 // fp -> fp[0]: CallerFP (old fp) |
1503 // fp[-8]: Space reserved for SPOffset. | 1566 // fp[-8]: Space reserved for SPOffset. |
1504 // fp[-16]: CodeObject() | 1567 // fp[-16]: CodeObject() |
1505 // csp[...]: Saved doubles, if saved_doubles is true. | 1568 // csp[...]: Saved doubles, if saved_doubles is true. |
1506 // csp[32]: Alignment padding, if necessary. | 1569 // csp[32]: Alignment padding, if necessary. |
1507 // csp[24]: Preserved x23 (used for target). | 1570 // csp[24]: Preserved x23 (used for target). |
1508 // csp[16]: Preserved x22 (used for argc). | 1571 // csp[16]: Preserved x22 (used for argc). |
1509 // csp[8]: Preserved x21 (used for argv). | 1572 // csp[8]: Preserved x21 (used for argv). |
1510 // csp -> csp[0]: Space reserved for the return address. | 1573 // csp -> csp[0]: Space reserved for the return address. |
1511 // | 1574 // |
1512 // After a successful call, the exit frame, preserved registers (x21-x23) and | 1575 // After a successful call, the exit frame, preserved registers (x21-x23) and |
1513 // the arguments (including the receiver) are dropped or popped as | 1576 // the arguments (including the receiver) are dropped or popped as |
1514 // appropriate. The stub then returns. | 1577 // appropriate. The stub then returns. |
1515 // | 1578 // |
1516 // After an unsuccessful call, the exit frame and suchlike are left | 1579 // After an unsuccessful call, the exit frame and suchlike are left |
1517 // untouched, and the stub either throws an exception by jumping to one of | 1580 // untouched, and the stub either throws an exception by jumping to one of |
1518 // the provided throw_ labels, or it falls through. The failure details are | 1581 // the exception_returned label. |
1519 // passed through in x0. | 1582 |
1520 ASSERT(csp.Is(__ StackPointer())); | 1583 ASSERT(csp.Is(__ StackPointer())); |
1521 | 1584 |
1522 Isolate* isolate = masm->isolate(); | 1585 Isolate* isolate = masm->isolate(); |
1523 | 1586 |
1524 const Register& argv = x21; | |
1525 const Register& argc = x22; | |
1526 const Register& target = x23; | |
1527 | |
1528 if (do_gc) { | |
1529 // Call Runtime::PerformGC, passing x0 (the result parameter for | |
1530 // PerformGC) and x1 (the isolate). | |
1531 __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); | |
1532 __ CallCFunction( | |
1533 ExternalReference::perform_gc_function(isolate), 2, 0); | |
1534 } | |
1535 | |
1536 ExternalReference scope_depth = | |
1537 ExternalReference::heap_always_allocate_scope_depth(isolate); | |
1538 if (always_allocate) { | |
1539 __ Mov(x10, Operand(scope_depth)); | |
1540 __ Ldr(x11, MemOperand(x10)); | |
1541 __ Add(x11, x11, 1); | |
1542 __ Str(x11, MemOperand(x10)); | |
1543 } | |
1544 | |
1545 // Prepare AAPCS64 arguments to pass to the builtin. | 1587 // Prepare AAPCS64 arguments to pass to the builtin. |
1546 __ Mov(x0, argc); | 1588 __ Mov(x0, argc); |
1547 __ Mov(x1, argv); | 1589 __ Mov(x1, argv); |
1548 __ Mov(x2, ExternalReference::isolate_address(isolate)); | 1590 __ Mov(x2, ExternalReference::isolate_address(isolate)); |
1549 | 1591 |
1550 // Store the return address on the stack, in the space previously allocated | |
1551 // by EnterExitFrame. The return address is queried by | |
1552 // ExitFrame::GetStateForFramePointer. | |
1553 Label return_location; | 1592 Label return_location; |
1554 __ Adr(x12, &return_location); | 1593 __ Adr(x12, &return_location); |
1555 __ Poke(x12, 0); | 1594 __ Poke(x12, 0); |
| 1595 |
1556 if (__ emit_debug_code()) { | 1596 if (__ emit_debug_code()) { |
1557 // Verify that the slot below fp[kSPOffset]-8 points to the return location | 1597 // Verify that the slot below fp[kSPOffset]-8 points to the return location |
1558 // (currently in x12). | 1598 // (currently in x12). |
1559 UseScratchRegisterScope temps(masm); | 1599 UseScratchRegisterScope temps(masm); |
1560 Register temp = temps.AcquireX(); | 1600 Register temp = temps.AcquireX(); |
1561 __ Ldr(temp, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 1601 __ Ldr(temp, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
1562 __ Ldr(temp, MemOperand(temp, -static_cast<int64_t>(kXRegSize))); | 1602 __ Ldr(temp, MemOperand(temp, -static_cast<int64_t>(kXRegSize))); |
1563 __ Cmp(temp, x12); | 1603 __ Cmp(temp, x12); |
1564 __ Check(eq, kReturnAddressNotFoundInFrame); | 1604 __ Check(eq, kReturnAddressNotFoundInFrame); |
1565 } | 1605 } |
1566 | 1606 |
1567 // Call the builtin. | 1607 // Call the builtin. |
1568 __ Blr(target); | 1608 __ Blr(target); |
1569 __ Bind(&return_location); | 1609 __ Bind(&return_location); |
1570 const Register& result = x0; | |
1571 | |
1572 if (always_allocate) { | |
1573 __ Mov(x10, Operand(scope_depth)); | |
1574 __ Ldr(x11, MemOperand(x10)); | |
1575 __ Sub(x11, x11, 1); | |
1576 __ Str(x11, MemOperand(x10)); | |
1577 } | |
1578 | 1610 |
1579 // x0 result The return code from the call. | 1611 // x0 result The return code from the call. |
1580 // x21 argv | 1612 // x21 argv |
1581 // x22 argc | 1613 // x22 argc |
1582 // x23 target | 1614 // x23 target |
1583 // | 1615 const Register& result = x0; |
1584 // If all of the result bits matching kFailureTagMask are '1', the result is | 1616 |
1585 // a failure. Otherwise, it's an ordinary tagged object and the call was a | 1617 // Check result for exception sentinel. |
1586 // success. | 1618 Label exception_returned; |
1587 Label failure; | 1619 __ CompareRoot(result, Heap::kExceptionRootIndex); |
1588 __ And(x10, result, kFailureTagMask); | 1620 __ B(eq, &exception_returned); |
1589 __ Cmp(x10, kFailureTagMask); | |
1590 __ B(&failure, eq); | |
1591 | 1621 |
1592 // The call succeeded, so unwind the stack and return. | 1622 // The call succeeded, so unwind the stack and return. |
1593 | 1623 |
1594 // Restore callee-saved registers x21-x23. | 1624 // Restore callee-saved registers x21-x23. |
1595 __ Mov(x11, argc); | 1625 __ Mov(x11, argc); |
1596 | 1626 |
1597 __ Peek(argv, 1 * kPointerSize); | 1627 __ Peek(argv, 1 * kPointerSize); |
1598 __ Peek(argc, 2 * kPointerSize); | 1628 __ Peek(argc, 2 * kPointerSize); |
1599 __ Peek(target, 3 * kPointerSize); | 1629 __ Peek(target, 3 * kPointerSize); |
1600 | 1630 |
1601 __ LeaveExitFrame(save_doubles_, x10, true); | 1631 __ LeaveExitFrame(save_doubles_, x10, true); |
1602 ASSERT(jssp.Is(__ StackPointer())); | 1632 ASSERT(jssp.Is(__ StackPointer())); |
1603 // Pop or drop the remaining stack slots and return from the stub. | 1633 // Pop or drop the remaining stack slots and return from the stub. |
1604 // jssp[24]: Arguments array (of size argc), including receiver. | 1634 // jssp[24]: Arguments array (of size argc), including receiver. |
1605 // jssp[16]: Preserved x23 (used for target). | 1635 // jssp[16]: Preserved x23 (used for target). |
1606 // jssp[8]: Preserved x22 (used for argc). | 1636 // jssp[8]: Preserved x22 (used for argc). |
1607 // jssp[0]: Preserved x21 (used for argv). | 1637 // jssp[0]: Preserved x21 (used for argv). |
1608 __ Drop(x11); | 1638 __ Drop(x11); |
1609 __ Ret(); | 1639 __ Ret(); |
1610 | 1640 |
1611 // The stack pointer is still csp if we aren't returning, and the frame | 1641 // The stack pointer is still csp if we aren't returning, and the frame |
1612 // hasn't changed (except for the return address). | 1642 // hasn't changed (except for the return address). |
1613 __ SetStackPointer(csp); | 1643 __ SetStackPointer(csp); |
1614 | 1644 |
1615 __ Bind(&failure); | 1645 // Handling of exception. |
1616 // The call failed, so check if we need to throw an exception, and fall | 1646 __ Bind(&exception_returned); |
1617 // through (to retry) otherwise. | |
1618 | |
1619 Label retry; | |
1620 // x0 result The return code from the call, including the failure | |
1621 // code and details. | |
1622 // x21 argv | |
1623 // x22 argc | |
1624 // x23 target | |
1625 // Refer to the Failure class for details of the bit layout. | |
1626 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0); | |
1627 __ Tst(result, kFailureTypeTagMask << kFailureTagSize); | |
1628 __ B(eq, &retry); // RETRY_AFTER_GC | |
1629 | 1647 |
1630 // Retrieve the pending exception. | 1648 // Retrieve the pending exception. |
| 1649 ExternalReference pending_exception_address( |
| 1650 Isolate::kPendingExceptionAddress, isolate); |
1631 const Register& exception = result; | 1651 const Register& exception = result; |
1632 const Register& exception_address = x11; | 1652 const Register& exception_address = x11; |
1633 __ Mov(exception_address, | 1653 __ Mov(exception_address, Operand(pending_exception_address)); |
1634 Operand(ExternalReference(Isolate::kPendingExceptionAddress, | |
1635 isolate))); | |
1636 __ Ldr(exception, MemOperand(exception_address)); | 1654 __ Ldr(exception, MemOperand(exception_address)); |
1637 | 1655 |
1638 // Clear the pending exception. | 1656 // Clear the pending exception. |
1639 __ Mov(x10, Operand(isolate->factory()->the_hole_value())); | 1657 __ Mov(x10, Operand(isolate->factory()->the_hole_value())); |
1640 __ Str(x10, MemOperand(exception_address)); | 1658 __ Str(x10, MemOperand(exception_address)); |
1641 | 1659 |
1642 // x0 exception The exception descriptor. | 1660 // x0 exception The exception descriptor. |
1643 // x21 argv | 1661 // x21 argv |
1644 // x22 argc | 1662 // x22 argc |
1645 // x23 target | 1663 // x23 target |
1646 | 1664 |
1647 // Special handling of termination exceptions, which are uncatchable by | 1665 // Special handling of termination exceptions, which are uncatchable by |
1648 // JavaScript code. | 1666 // JavaScript code. |
| 1667 Label throw_termination_exception; |
1649 __ Cmp(exception, Operand(isolate->factory()->termination_exception())); | 1668 __ Cmp(exception, Operand(isolate->factory()->termination_exception())); |
1650 __ B(eq, throw_termination); | 1669 __ B(eq, &throw_termination_exception); |
1651 | |
1652 // Handle normal exception. | |
1653 __ B(throw_normal); | |
1654 | |
1655 __ Bind(&retry); | |
1656 // The result (x0) is passed through as the next PerformGC parameter. | |
1657 } | |
1658 | |
1659 | |
1660 void CEntryStub::Generate(MacroAssembler* masm) { | |
1661 // The Abort mechanism relies on CallRuntime, which in turn relies on | |
1662 // CEntryStub, so until this stub has been generated, we have to use a | |
1663 // fall-back Abort mechanism. | |
1664 // | |
1665 // Note that this stub must be generated before any use of Abort. | |
1666 MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm); | |
1667 | |
1668 ASM_LOCATION("CEntryStub::Generate entry"); | |
1669 ProfileEntryHookStub::MaybeCallEntryHook(masm); | |
1670 | |
1671 // Register parameters: | |
1672 // x0: argc (including receiver, untagged) | |
1673 // x1: target | |
1674 // | |
1675 // The stack on entry holds the arguments and the receiver, with the receiver | |
1676 // at the highest address: | |
1677 // | |
1678 // jssp]argc-1]: receiver | |
1679 // jssp[argc-2]: arg[argc-2] | |
1680 // ... ... | |
1681 // jssp[1]: arg[1] | |
1682 // jssp[0]: arg[0] | |
1683 // | |
1684 // The arguments are in reverse order, so that arg[argc-2] is actually the | |
1685 // first argument to the target function and arg[0] is the last. | |
1686 ASSERT(jssp.Is(__ StackPointer())); | |
1687 const Register& argc_input = x0; | |
1688 const Register& target_input = x1; | |
1689 | |
1690 // Calculate argv, argc and the target address, and store them in | |
1691 // callee-saved registers so we can retry the call without having to reload | |
1692 // these arguments. | |
1693 // TODO(jbramley): If the first call attempt succeeds in the common case (as | |
1694 // it should), then we might be better off putting these parameters directly | |
1695 // into their argument registers, rather than using callee-saved registers and | |
1696 // preserving them on the stack. | |
1697 const Register& argv = x21; | |
1698 const Register& argc = x22; | |
1699 const Register& target = x23; | |
1700 | |
1701 // Derive argv from the stack pointer so that it points to the first argument | |
1702 // (arg[argc-2]), or just below the receiver in case there are no arguments. | |
1703 // - Adjust for the arg[] array. | |
1704 Register temp_argv = x11; | |
1705 __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2)); | |
1706 // - Adjust for the receiver. | |
1707 __ Sub(temp_argv, temp_argv, 1 * kPointerSize); | |
1708 | |
1709 // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved | |
1710 // registers. | |
1711 FrameScope scope(masm, StackFrame::MANUAL); | |
1712 __ EnterExitFrame(save_doubles_, x10, 3); | |
1713 ASSERT(csp.Is(__ StackPointer())); | |
1714 | |
1715 // Poke callee-saved registers into reserved space. | |
1716 __ Poke(argv, 1 * kPointerSize); | |
1717 __ Poke(argc, 2 * kPointerSize); | |
1718 __ Poke(target, 3 * kPointerSize); | |
1719 | |
1720 // We normally only keep tagged values in callee-saved registers, as they | |
1721 // could be pushed onto the stack by called stubs and functions, and on the | |
1722 // stack they can confuse the GC. However, we're only calling C functions | |
1723 // which can push arbitrary data onto the stack anyway, and so the GC won't | |
1724 // examine that part of the stack. | |
1725 __ Mov(argc, argc_input); | |
1726 __ Mov(target, target_input); | |
1727 __ Mov(argv, temp_argv); | |
1728 | |
1729 Label throw_normal; | |
1730 Label throw_termination; | |
1731 | |
1732 // Call the runtime function. | |
1733 GenerateCore(masm, | |
1734 &throw_normal, | |
1735 &throw_termination, | |
1736 false, | |
1737 false); | |
1738 | |
1739 // If successful, the previous GenerateCore will have returned to the | |
1740 // calling code. Otherwise, we fall through into the following. | |
1741 | |
1742 // Do space-specific GC and retry runtime call. | |
1743 GenerateCore(masm, | |
1744 &throw_normal, | |
1745 &throw_termination, | |
1746 true, | |
1747 false); | |
1748 | |
1749 // Do full GC and retry runtime call one final time. | |
1750 __ Mov(x0, reinterpret_cast<uint64_t>(Failure::InternalError())); | |
1751 GenerateCore(masm, | |
1752 &throw_normal, | |
1753 &throw_termination, | |
1754 true, | |
1755 true); | |
1756 | |
1757 { FrameScope scope(masm, StackFrame::MANUAL); | |
1758 __ CallCFunction( | |
1759 ExternalReference::out_of_memory_function(masm->isolate()), 0); | |
1760 } | |
1761 | 1670 |
1762 // We didn't execute a return case, so the stack frame hasn't been updated | 1671 // We didn't execute a return case, so the stack frame hasn't been updated |
1763 // (except for the return address slot). However, we don't need to initialize | 1672 // (except for the return address slot). However, we don't need to initialize |
1764 // jssp because the throw method will immediately overwrite it when it | 1673 // jssp because the throw method will immediately overwrite it when it |
1765 // unwinds the stack. | 1674 // unwinds the stack. |
1766 __ SetStackPointer(jssp); | 1675 __ SetStackPointer(jssp); |
1767 | 1676 |
1768 // Throw exceptions. | 1677 ASM_LOCATION("Throw normal"); |
1769 // If we throw an exception, we can end up re-entering CEntryStub before we | 1678 __ Mov(argv, 0); |
1770 // pop the exit frame, so need to ensure that x21-x23 contain GC-safe values | 1679 __ Mov(argc, 0); |
1771 // here. | 1680 __ Mov(target, 0); |
| 1681 __ Throw(x0, x10, x11, x12, x13); |
1772 | 1682 |
1773 __ Bind(&throw_termination); | 1683 __ Bind(&throw_termination_exception); |
1774 ASM_LOCATION("Throw termination"); | 1684 ASM_LOCATION("Throw termination"); |
1775 __ Mov(argv, 0); | 1685 __ Mov(argv, 0); |
1776 __ Mov(argc, 0); | 1686 __ Mov(argc, 0); |
1777 __ Mov(target, 0); | 1687 __ Mov(target, 0); |
1778 __ ThrowUncatchable(x0, x10, x11, x12, x13); | 1688 __ ThrowUncatchable(x0, x10, x11, x12, x13); |
1779 | |
1780 __ Bind(&throw_normal); | |
1781 ASM_LOCATION("Throw normal"); | |
1782 __ Mov(argv, 0); | |
1783 __ Mov(argc, 0); | |
1784 __ Mov(target, 0); | |
1785 __ Throw(x0, x10, x11, x12, x13); | |
1786 } | 1689 } |
1787 | 1690 |
1788 | 1691 |
1789 // This is the entry point from C++. 5 arguments are provided in x0-x4. | 1692 // This is the entry point from C++. 5 arguments are provided in x0-x4. |
1790 // See use of the CALL_GENERATED_CODE macro for example in src/execution.cc. | 1693 // See use of the CALL_GENERATED_CODE macro for example in src/execution.cc. |
1791 // Input: | 1694 // Input: |
1792 // x0: code entry. | 1695 // x0: code entry. |
1793 // x1: function. | 1696 // x1: function. |
1794 // x2: receiver. | 1697 // x2: receiver. |
1795 // x3: argc. | 1698 // x3: argc. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1875 __ bind(&handler_entry); | 1778 __ bind(&handler_entry); |
1876 handler_offset_ = handler_entry.pos(); | 1779 handler_offset_ = handler_entry.pos(); |
1877 // Caught exception: Store result (exception) in the pending exception | 1780 // Caught exception: Store result (exception) in the pending exception |
1878 // field in the JSEnv and return a failure sentinel. Coming in here the | 1781 // field in the JSEnv and return a failure sentinel. Coming in here the |
1879 // fp will be invalid because the PushTryHandler below sets it to 0 to | 1782 // fp will be invalid because the PushTryHandler below sets it to 0 to |
1880 // signal the existence of the JSEntry frame. | 1783 // signal the existence of the JSEntry frame. |
1881 __ Mov(x10, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 1784 __ Mov(x10, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
1882 isolate))); | 1785 isolate))); |
1883 } | 1786 } |
1884 __ Str(code_entry, MemOperand(x10)); | 1787 __ Str(code_entry, MemOperand(x10)); |
1885 __ Mov(x0, Operand(reinterpret_cast<int64_t>(Failure::Exception()))); | 1788 __ LoadRoot(x0, Heap::kExceptionRootIndex); |
1886 __ B(&exit); | 1789 __ B(&exit); |
1887 | 1790 |
1888 // Invoke: Link this frame into the handler chain. There's only one | 1791 // Invoke: Link this frame into the handler chain. There's only one |
1889 // handler block in this code object, so its index is 0. | 1792 // handler block in this code object, so its index is 0. |
1890 __ Bind(&invoke); | 1793 __ Bind(&invoke); |
1891 __ PushTryHandler(StackHandler::JS_ENTRY, 0); | 1794 __ PushTryHandler(StackHandler::JS_ENTRY, 0); |
1892 // If an exception not caught by another handler occurs, this handler | 1795 // If an exception not caught by another handler occurs, this handler |
1893 // returns control to the code after the B(&invoke) above, which | 1796 // returns control to the code after the B(&invoke) above, which |
1894 // restores all callee-saved registers (including cp and fp) to their | 1797 // restores all callee-saved registers (including cp and fp) to their |
1895 // saved values before returning a failure to C. | 1798 // saved values before returning a failure to C. |
(...skipping 3628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5524 MemOperand(fp, 6 * kPointerSize), | 5427 MemOperand(fp, 6 * kPointerSize), |
5525 NULL); | 5428 NULL); |
5526 } | 5429 } |
5527 | 5430 |
5528 | 5431 |
5529 #undef __ | 5432 #undef __ |
5530 | 5433 |
5531 } } // namespace v8::internal | 5434 } } // namespace v8::internal |
5532 | 5435 |
5533 #endif // V8_TARGET_ARCH_ARM64 | 5436 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |