Chromium Code Reviews| 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 |