Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 246893010: MIPS: Return Object* instead of MaybeObject* from runtime calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1592 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 isolate->set_fp_stubs_generated(true); 1603 isolate->set_fp_stubs_generated(true);
1604 } 1604 }
1605 1605
1606 1606
1607 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 1607 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
1608 CEntryStub stub(1, kDontSaveFPRegs); 1608 CEntryStub stub(1, kDontSaveFPRegs);
1609 stub.GetCode(isolate); 1609 stub.GetCode(isolate);
1610 } 1610 }
1611 1611
1612 1612
1613 void CEntryStub::GenerateCore(MacroAssembler* masm, 1613 void CEntryStub::Generate(MacroAssembler* masm) {
1614 Label* throw_normal_exception, 1614 // Called from JavaScript; parameters are on stack as if calling JS function
1615 Label* throw_termination_exception, 1615 // s0: number of arguments including receiver
1616 bool do_gc, 1616 // s1: size of arguments excluding receiver
1617 bool always_allocate) { 1617 // s2: pointer to builtin function
1618 // v0: result parameter for PerformGC, if any 1618 // fp: frame pointer (restored after C call)
1619 // s0: number of arguments including receiver (C callee-saved) 1619 // sp: stack pointer (restored as callee's sp after C call)
1620 // s1: pointer to the first argument (C callee-saved) 1620 // cp: current context (C callee-saved)
1621 // s2: pointer to builtin function (C callee-saved) 1621
1622 ProfileEntryHookStub::MaybeCallEntryHook(masm);
1623
1624 // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
1625 // The reason for this is that these arguments would need to be saved anyway
1626 // so it's faster to set them up directly.
1627 // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
1628
1629 // Compute the argv pointer in a callee-saved register.
1630 __ Addu(s1, sp, s1);
1631
1632 // Enter the exit frame that transitions from JavaScript to C++.
1633 FrameScope scope(masm, StackFrame::MANUAL);
1634 __ EnterExitFrame(save_doubles_);
1635
1636 // s0: number of arguments including receiver (C callee-saved)
1637 // s1: pointer to first argument (C callee-saved)
1638 // s2: pointer to builtin function (C callee-saved)
1622 1639
1623 Isolate* isolate = masm->isolate(); 1640 Isolate* isolate = masm->isolate();
1624 1641
1625 if (do_gc) {
1626 // Move result passed in v0 into a0 to call PerformGC.
1627 __ mov(a0, v0);
1628 __ PrepareCallCFunction(2, 0, a1);
1629 __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
1630 __ CallCFunction(ExternalReference::perform_gc_function(isolate), 2, 0);
1631 }
1632
1633 ExternalReference scope_depth =
1634 ExternalReference::heap_always_allocate_scope_depth(isolate);
1635 if (always_allocate) {
1636 __ li(a0, Operand(scope_depth));
1637 __ lw(a1, MemOperand(a0));
1638 __ Addu(a1, a1, Operand(1));
1639 __ sw(a1, MemOperand(a0));
1640 }
1641
1642 // Prepare arguments for C routine. 1642 // Prepare arguments for C routine.
1643 // a0 = argc 1643 // a0 = argc
1644 __ mov(a0, s0); 1644 __ mov(a0, s0);
1645 // a1 = argv (set in the delay slot after find_ra below). 1645 // a1 = argv (set in the delay slot after find_ra below).
1646 1646
1647 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We 1647 // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
1648 // also need to reserve the 4 argument slots on the stack. 1648 // also need to reserve the 4 argument slots on the stack.
1649 1649
1650 __ AssertStackIsAligned(); 1650 __ AssertStackIsAligned();
1651 1651
(...skipping 25 matching lines...) Expand all
1677 // Call the C routine. 1677 // Call the C routine.
1678 masm->mov(t9, s2); // Function pointer to t9 to conform to ABI for PIC. 1678 masm->mov(t9, s2); // Function pointer to t9 to conform to ABI for PIC.
1679 masm->jalr(t9); 1679 masm->jalr(t9);
1680 // Set up sp in the delay slot. 1680 // Set up sp in the delay slot.
1681 masm->addiu(sp, sp, -kCArgsSlotsSize); 1681 masm->addiu(sp, sp, -kCArgsSlotsSize);
1682 // Make sure the stored 'ra' points to this position. 1682 // Make sure the stored 'ra' points to this position.
1683 ASSERT_EQ(kNumInstructionsToJump, 1683 ASSERT_EQ(kNumInstructionsToJump,
1684 masm->InstructionsGeneratedSince(&find_ra)); 1684 masm->InstructionsGeneratedSince(&find_ra));
1685 } 1685 }
1686 1686
1687 if (always_allocate) { 1687
1688 // It's okay to clobber a2 and a3 here. v0 & v1 contain result. 1688 // Runtime functions should not return 'the hole'. Allowing it to escape may
1689 __ li(a2, Operand(scope_depth)); 1689 // lead to crashes in the IC code later.
1690 __ lw(a3, MemOperand(a2)); 1690 if (FLAG_debug_code) {
1691 __ Subu(a3, a3, Operand(1)); 1691 Label okay;
1692 __ sw(a3, MemOperand(a2)); 1692 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
1693 __ Branch(&okay, ne, v0, Operand(t0));
1694 __ stop("The hole escaped");
1695 __ bind(&okay);
1693 } 1696 }
1694 1697
1695 // Check for failure result. 1698 // Check result for exception sentinel.
1696 Label failure_returned; 1699 Label exception_returned;
1697 STATIC_ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); 1700 __ LoadRoot(t0, Heap::kExceptionRootIndex);
1698 __ addiu(a2, v0, 1); 1701 __ Branch(&exception_returned, eq, t0, Operand(v0));
1699 __ andi(t0, a2, kFailureTagMask);
1700 __ Branch(USE_DELAY_SLOT, &failure_returned, eq, t0, Operand(zero_reg));
1701 // Restore stack (remove arg slots) in branch delay slot.
1702 __ addiu(sp, sp, kCArgsSlotsSize);
1703 1702
1703 ExternalReference pending_exception_address(
1704 Isolate::kPendingExceptionAddress, isolate);
1705
1706 // Check that there is no pending exception, otherwise we
1707 // should have returned the exception sentinel.
1708 if (FLAG_debug_code) {
1709 Label okay;
1710 __ li(a2, Operand(pending_exception_address));
1711 __ lw(a2, MemOperand(a2));
1712 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
1713 // Cannot use check here as it attempts to generate call into runtime.
1714 __ Branch(&okay, eq, t0, Operand(a2));
1715 __ stop("Unexpected pending exception");
1716 __ bind(&okay);
1717 }
1704 1718
1705 // Exit C frame and return. 1719 // Exit C frame and return.
1706 // v0:v1: result 1720 // v0:v1: result
1707 // sp: stack pointer 1721 // sp: stack pointer
1708 // fp: frame pointer 1722 // fp: frame pointer
1723 // s0: still holds argc (callee-saved).
1709 __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN); 1724 __ LeaveExitFrame(save_doubles_, s0, true, EMIT_RETURN);
1710 1725
1711 // Check if we should retry or throw exception. 1726 // Handling of exception.
1712 Label retry; 1727 __ bind(&exception_returned);
1713 __ bind(&failure_returned);
1714 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
1715 __ andi(t0, v0, ((1 << kFailureTypeTagSize) - 1) << kFailureTagSize);
1716 __ Branch(&retry, eq, t0, Operand(zero_reg));
1717 1728
1718 // Retrieve the pending exception. 1729 // Retrieve the pending exception.
1719 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, 1730 __ li(a2, Operand(pending_exception_address));
1720 isolate))); 1731 __ lw(v0, MemOperand(a2));
1721 __ lw(v0, MemOperand(t0));
1722 1732
1723 // Clear the pending exception. 1733 // Clear the pending exception.
1724 __ li(a3, Operand(isolate->factory()->the_hole_value())); 1734 __ li(a3, Operand(isolate->factory()->the_hole_value()));
1725 __ li(t0, Operand(ExternalReference(Isolate::kPendingExceptionAddress, 1735 __ sw(a3, MemOperand(a2));
1726 isolate)));
1727 __ sw(a3, MemOperand(t0));
1728 1736
1729 // Special handling of termination exceptions which are uncatchable 1737 // Special handling of termination exceptions which are uncatchable
1730 // by javascript code. 1738 // by javascript code.
1739 Label throw_termination_exception;
1731 __ LoadRoot(t0, Heap::kTerminationExceptionRootIndex); 1740 __ LoadRoot(t0, Heap::kTerminationExceptionRootIndex);
1732 __ Branch(throw_termination_exception, eq, v0, Operand(t0)); 1741 __ Branch(&throw_termination_exception, eq, v0, Operand(t0));
1733 1742
1734 // Handle normal exception. 1743 // Handle normal exception.
1735 __ jmp(throw_normal_exception); 1744 __ Throw(v0);
1736 1745
1737 __ bind(&retry); 1746 __ bind(&throw_termination_exception);
1738 // Last failure (v0) will be moved to (a0) for parameter when retrying. 1747 __ ThrowUncatchable(v0);
1739 } 1748 }
1740 1749
1741 1750
1742 void CEntryStub::Generate(MacroAssembler* masm) {
1743 // Called from JavaScript; parameters are on stack as if calling JS function
1744 // s0: number of arguments including receiver
1745 // s1: size of arguments excluding receiver
1746 // s2: pointer to builtin function
1747 // fp: frame pointer (restored after C call)
1748 // sp: stack pointer (restored as callee's sp after C call)
1749 // cp: current context (C callee-saved)
1750
1751 ProfileEntryHookStub::MaybeCallEntryHook(masm);
1752
1753 // NOTE: Invocations of builtins may return failure objects
1754 // instead of a proper result. The builtin entry handles
1755 // this by performing a garbage collection and retrying the
1756 // builtin once.
1757
1758 // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
1759 // The reason for this is that these arguments would need to be saved anyway
1760 // so it's faster to set them up directly.
1761 // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
1762
1763 // Compute the argv pointer in a callee-saved register.
1764 __ Addu(s1, sp, s1);
1765
1766 // Enter the exit frame that transitions from JavaScript to C++.
1767 FrameScope scope(masm, StackFrame::MANUAL);
1768 __ EnterExitFrame(save_doubles_);
1769
1770 // s0: number of arguments (C callee-saved)
1771 // s1: pointer to first argument (C callee-saved)
1772 // s2: pointer to builtin function (C callee-saved)
1773
1774 Label throw_normal_exception;
1775 Label throw_termination_exception;
1776
1777 // Call into the runtime system.
1778 GenerateCore(masm,
1779 &throw_normal_exception,
1780 &throw_termination_exception,
1781 false,
1782 false);
1783
1784 // Do space-specific GC and retry runtime call.
1785 GenerateCore(masm,
1786 &throw_normal_exception,
1787 &throw_termination_exception,
1788 true,
1789 false);
1790
1791 // Do full GC and retry runtime call one final time.
1792 Failure* failure = Failure::InternalError();
1793 __ li(v0, Operand(reinterpret_cast<int32_t>(failure)));
1794 GenerateCore(masm,
1795 &throw_normal_exception,
1796 &throw_termination_exception,
1797 true,
1798 true);
1799
1800 { FrameScope scope(masm, StackFrame::MANUAL);
1801 __ PrepareCallCFunction(0, v0);
1802 __ CallCFunction(
1803 ExternalReference::out_of_memory_function(masm->isolate()), 0);
1804 }
1805
1806 __ bind(&throw_termination_exception);
1807 __ ThrowUncatchable(v0);
1808
1809 __ bind(&throw_normal_exception);
1810 __ Throw(v0);
1811 }
1812
1813
1814 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { 1751 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
1815 Label invoke, handler_entry, exit; 1752 Label invoke, handler_entry, exit;
1816 Isolate* isolate = masm->isolate(); 1753 Isolate* isolate = masm->isolate();
1817 1754
1818 // Registers: 1755 // Registers:
1819 // a0: entry address 1756 // a0: entry address
1820 // a1: function 1757 // a1: function
1821 // a2: receiver 1758 // a2: receiver
1822 // a3: argc 1759 // a3: argc
1823 // 1760 //
(...skipping 3629 matching lines...) Expand 10 before | Expand all | Expand 10 after
5453 MemOperand(fp, 6 * kPointerSize), 5390 MemOperand(fp, 6 * kPointerSize),
5454 NULL); 5391 NULL);
5455 } 5392 }
5456 5393
5457 5394
5458 #undef __ 5395 #undef __
5459 5396
5460 } } // namespace v8::internal 5397 } } // namespace v8::internal
5461 5398
5462 #endif // V8_TARGET_ARCH_MIPS 5399 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698