OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1633 bool do_restore) { | 1633 bool do_restore) { |
1634 // r0: result parameter for PerformGC, if any | 1634 // r0: result parameter for PerformGC, if any |
1635 // r4: number of arguments including receiver (C callee-saved) | 1635 // r4: number of arguments including receiver (C callee-saved) |
1636 // r5: pointer to builtin function (C callee-saved) | 1636 // r5: pointer to builtin function (C callee-saved) |
1637 | 1637 |
1638 if (do_gc) { | 1638 if (do_gc) { |
1639 __ Call(FUNCTION_ADDR(Runtime::PerformGC), runtime_entry); // passing r0 | 1639 __ Call(FUNCTION_ADDR(Runtime::PerformGC), runtime_entry); // passing r0 |
1640 } | 1640 } |
1641 | 1641 |
1642 // Call C built-in. | 1642 // Call C built-in. |
1643 // r0 = argc. | 1643 // r0 = argc, r1 = argv |
1644 __ mov(r0, Operand(r4)); | 1644 __ mov(r0, Operand(r4)); |
1645 // r1 = argv. | 1645 __ mov(r1, Operand(r6)); |
iposva
2008/09/23 07:51:28
Please add r6 to the contract with calling code ab
| |
1646 __ add(r1, fp, Operand(r4, LSL, kPointerSizeLog2)); | |
1647 __ add(r1, r1, Operand(ExitFrameConstants::kPPDisplacement - kPointerSize)); | |
1648 | 1646 |
1649 // TODO(1242173): To let the GC traverse the return address of the exit | 1647 // TODO(1242173): To let the GC traverse the return address of the exit |
1650 // frames, we need to know where the return address is. Right now, | 1648 // frames, we need to know where the return address is. Right now, |
1651 // we push it on the stack to be able to find it again, but we never | 1649 // we push it on the stack to be able to find it again, but we never |
1652 // restore from it in case of changes, which makes it impossible to | 1650 // restore from it in case of changes, which makes it impossible to |
1653 // support moving the C entry code stub. This should be fixed, but currently | 1651 // support moving the C entry code stub. This should be fixed, but currently |
1654 // this is OK because the CEntryStub gets generated so early in the V8 boot | 1652 // this is OK because the CEntryStub gets generated so early in the V8 boot |
1655 // sequence that it is not moving ever. | 1653 // sequence that it is not moving ever. |
1656 __ add(lr, pc, Operand(4)); // compute return address: (pc + 8) + 4 | 1654 __ add(lr, pc, Operand(4)); // compute return address: (pc + 8) + 4 |
1657 __ push(lr); | 1655 __ push(lr); |
1658 #if !defined(__arm__) | 1656 #if !defined(__arm__) |
1659 // Notify the simulator of the transition to C code. | 1657 // Notify the simulator of the transition to C code. |
1660 __ swi(assembler::arm::call_rt_r5); | 1658 __ swi(assembler::arm::call_rt_r5); |
1661 #else /* !defined(__arm__) */ | 1659 #else /* !defined(__arm__) */ |
1662 __ mov(pc, Operand(r5)); | 1660 __ mov(pc, Operand(r5)); |
1663 #endif /* !defined(__arm__) */ | 1661 #endif /* !defined(__arm__) */ |
1664 // result is in r0 or r0:r1 - do not destroy these registers! | 1662 // result is in r0 or r0:r1 - do not destroy these registers! |
1665 | 1663 |
1666 // check for failure result | 1664 // check for failure result |
1667 Label failure_returned; | 1665 Label failure_returned; |
1668 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 1666 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
1669 // Lower 2 bits of r2 are 0 iff r0 has failure tag. | 1667 // Lower 2 bits of r2 are 0 iff r0 has failure tag. |
1670 __ add(r2, r0, Operand(1)); | 1668 __ add(r2, r0, Operand(1)); |
1671 __ tst(r2, Operand(kFailureTagMask)); | 1669 __ tst(r2, Operand(kFailureTagMask)); |
1672 __ b(eq, &failure_returned); | 1670 __ b(eq, &failure_returned); |
1673 | 1671 |
1674 // clear top frame | |
1675 __ mov(r3, Operand(0)); | |
1676 __ mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); | |
1677 __ str(r3, MemOperand(ip)); | |
1678 | |
1679 // Restore the memory copy of the registers by digging them out from | 1672 // Restore the memory copy of the registers by digging them out from |
1680 // the stack. | 1673 // the stack. |
1681 if (do_restore) { | 1674 if (do_restore) { |
1682 // Ok to clobber r2 and r3. | 1675 // Ok to clobber r2 and r3. |
1683 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | 1676 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; |
1684 const int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; | 1677 const int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; |
1685 __ add(r3, fp, Operand(kOffset)); | 1678 __ add(r3, fp, Operand(kOffset)); |
1686 __ CopyRegistersFromStackToMemory(r3, r2, kJSCallerSaved); | 1679 __ CopyRegistersFromStackToMemory(r3, r2, kJSCallerSaved); |
1687 } | 1680 } |
1688 | 1681 |
1689 // Exit C frame and return | 1682 // Exit C frame and return |
1690 // r0:r1: result | 1683 // r0:r1: result |
1691 // sp: stack pointer | 1684 // sp: stack pointer |
1692 // fp: frame pointer | 1685 // fp: frame pointer |
1693 // pp: caller's parameter pointer pp (restored as C callee-saved) | 1686 // pp: caller's parameter pointer pp (restored as C callee-saved) |
1694 | 1687 __ LeaveExitFrame(); |
1695 // Restore current context from top and clear it in debug mode. | |
1696 __ mov(r3, Operand(Top::context_address())); | |
1697 __ ldr(cp, MemOperand(r3)); | |
1698 __ mov(sp, Operand(fp)); // respect ABI stack constraint | |
1699 __ ldm(ia, sp, fp.bit() | sp.bit() | pc.bit()); | |
1700 | 1688 |
1701 // check if we should retry or throw exception | 1689 // check if we should retry or throw exception |
1702 Label retry; | 1690 Label retry; |
1703 __ bind(&failure_returned); | 1691 __ bind(&failure_returned); |
1704 ASSERT(Failure::RETRY_AFTER_GC == 0); | 1692 ASSERT(Failure::RETRY_AFTER_GC == 0); |
1705 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 1693 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
1706 __ b(eq, &retry); | 1694 __ b(eq, &retry); |
1707 | 1695 |
1708 Label continue_exception; | 1696 Label continue_exception; |
1709 // If the returned failure is EXCEPTION then promote Top::pending_exception(). | 1697 // If the returned failure is EXCEPTION then promote Top::pending_exception(). |
(...skipping 27 matching lines...) Expand all Loading... | |
1737 // fp: frame pointer (restored after C call) | 1725 // fp: frame pointer (restored after C call) |
1738 // sp: stack pointer (restored as callee's pp after C call) | 1726 // sp: stack pointer (restored as callee's pp after C call) |
1739 // cp: current context (C callee-saved) | 1727 // cp: current context (C callee-saved) |
1740 // pp: caller's parameter pointer pp (C callee-saved) | 1728 // pp: caller's parameter pointer pp (C callee-saved) |
1741 | 1729 |
1742 // NOTE: Invocations of builtins may return failure objects | 1730 // NOTE: Invocations of builtins may return failure objects |
1743 // instead of a proper result. The builtin entry handles | 1731 // instead of a proper result. The builtin entry handles |
1744 // this by performing a garbage collection and retrying the | 1732 // this by performing a garbage collection and retrying the |
1745 // builtin once. | 1733 // builtin once. |
1746 | 1734 |
1747 // Enter C frame | 1735 StackFrame::Type frame_type = is_debug_break |
1748 // Compute parameter pointer before making changes and save it as ip register | 1736 ? StackFrame::EXIT_DEBUG |
1749 // so that it is restored as sp register on exit, thereby popping the args. | 1737 : StackFrame::EXIT; |
1750 // ip = sp + kPointerSize*args_len; | |
1751 __ add(ip, sp, Operand(r0, LSL, kPointerSizeLog2)); | |
1752 | 1738 |
1753 // push in reverse order: | 1739 // Enter the exit frame that transitions from JavaScript to C++. |
1754 // caller_fp, sp_on_exit, caller_pc | 1740 __ EnterExitFrame(frame_type); |
1755 __ stm(db_w, sp, fp.bit() | ip.bit() | lr.bit()); | |
1756 __ mov(fp, Operand(sp)); // setup new frame pointer | |
1757 | |
1758 // Store the current context in top. | |
1759 __ mov(ip, Operand(ExternalReference(Top::k_context_address))); | |
1760 __ str(cp, MemOperand(ip)); | |
1761 | |
1762 // remember top frame | |
1763 __ mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); | |
1764 __ str(fp, MemOperand(ip)); | |
1765 | |
1766 // Push debug marker. | |
1767 __ mov(ip, Operand(is_debug_break ? 1 : 0)); | |
1768 __ push(ip); | |
1769 | 1741 |
1770 if (is_debug_break) { | 1742 if (is_debug_break) { |
1771 // Save the state of all registers to the stack from the memory location. | 1743 // Save the state of all registers to the stack from the memory location. |
1772 // Use sp as base to push. | 1744 // Use sp as base to push. |
1773 __ CopyRegistersFromMemoryToStack(sp, kJSCallerSaved); | 1745 __ CopyRegistersFromMemoryToStack(sp, kJSCallerSaved); |
1774 } | 1746 } |
1775 | 1747 |
1776 // move number of arguments (argc) into callee-saved register | |
1777 __ mov(r4, Operand(r0)); | |
1778 | |
1779 // move pointer to builtin function into callee-saved register | |
1780 __ mov(r5, Operand(r1)); | |
1781 | |
1782 // r0: result parameter for PerformGC, if any (setup below) | |
1783 // r4: number of arguments | 1748 // r4: number of arguments |
1784 // r5: pointer to builtin function (C callee-saved) | 1749 // r5: pointer to builtin function (C callee-saved) |
1785 | 1750 |
1786 Label entry; | 1751 Label entry; |
1787 __ bind(&entry); | 1752 __ bind(&entry); |
1788 | 1753 |
1789 Label throw_out_of_memory_exception; | 1754 Label throw_out_of_memory_exception; |
1790 Label throw_normal_exception; | 1755 Label throw_normal_exception; |
1791 | 1756 |
1792 #ifdef DEBUG | 1757 #ifdef DEBUG |
(...skipping 2789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4582 bool is_eval) { | 4547 bool is_eval) { |
4583 Handle<Code> code = ArmCodeGenerator::MakeCode(fun, script, is_eval); | 4548 Handle<Code> code = ArmCodeGenerator::MakeCode(fun, script, is_eval); |
4584 if (!code.is_null()) { | 4549 if (!code.is_null()) { |
4585 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 4550 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
4586 } | 4551 } |
4587 return code; | 4552 return code; |
4588 } | 4553 } |
4589 | 4554 |
4590 | 4555 |
4591 } } // namespace v8::internal | 4556 } } // namespace v8::internal |
OLD | NEW |