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

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 8391045: Handlify the remaining CallStubCompiler functions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 bind(&done); 1587 bind(&done);
1588 } 1588 }
1589 1589
1590 1590
1591 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) { 1591 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
1592 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs. 1592 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
1593 call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 1593 call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
1594 } 1594 }
1595 1595
1596 1596
1597 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) {
1598 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
1599 Object* result;
1600 { MaybeObject* maybe_result = stub->TryGetCode();
1601 if (!maybe_result->ToObject(&result)) return maybe_result;
1602 }
1603 call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
1604 return result;
1605 }
1606
1607
1608 void MacroAssembler::TailCallStub(CodeStub* stub) { 1597 void MacroAssembler::TailCallStub(CodeStub* stub) {
1609 ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe()); 1598 ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
1610 jmp(stub->GetCode(), RelocInfo::CODE_TARGET); 1599 jmp(stub->GetCode(), RelocInfo::CODE_TARGET);
1611 } 1600 }
1612 1601
1613 1602
1614 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
1615 Object* result;
1616 { MaybeObject* maybe_result = stub->TryGetCode();
1617 if (!maybe_result->ToObject(&result)) return maybe_result;
1618 }
1619 jmp(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
1620 return result;
1621 }
1622
1623
1624 void MacroAssembler::StubReturn(int argc) { 1603 void MacroAssembler::StubReturn(int argc) {
1625 ASSERT(argc >= 1 && generating_stub()); 1604 ASSERT(argc >= 1 && generating_stub());
1626 ret((argc - 1) * kPointerSize); 1605 ret((argc - 1) * kPointerSize);
1627 } 1606 }
1628 1607
1629 1608
1630 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 1609 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
1631 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false; 1610 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
1632 return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(); 1611 return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe();
1633 } 1612 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 1646
1668 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { 1647 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
1669 const Runtime::Function* function = Runtime::FunctionForId(id); 1648 const Runtime::Function* function = Runtime::FunctionForId(id);
1670 Set(eax, Immediate(function->nargs)); 1649 Set(eax, Immediate(function->nargs));
1671 mov(ebx, Immediate(ExternalReference(function, isolate()))); 1650 mov(ebx, Immediate(ExternalReference(function, isolate())));
1672 CEntryStub ces(1, kSaveFPRegs); 1651 CEntryStub ces(1, kSaveFPRegs);
1673 CallStub(&ces); 1652 CallStub(&ces);
1674 } 1653 }
1675 1654
1676 1655
1677 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
1678 int num_arguments) {
1679 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
1680 }
1681
1682
1683 void MacroAssembler::CallRuntime(const Runtime::Function* f, 1656 void MacroAssembler::CallRuntime(const Runtime::Function* f,
1684 int num_arguments) { 1657 int num_arguments) {
1685 // If the expected number of arguments of the runtime function is 1658 // If the expected number of arguments of the runtime function is
1686 // constant, we check that the actual number of arguments match the 1659 // constant, we check that the actual number of arguments match the
1687 // expectation. 1660 // expectation.
1688 if (f->nargs >= 0 && f->nargs != num_arguments) { 1661 if (f->nargs >= 0 && f->nargs != num_arguments) {
1689 IllegalOperation(num_arguments); 1662 IllegalOperation(num_arguments);
1690 return; 1663 return;
1691 } 1664 }
1692 1665
1693 // TODO(1236192): Most runtime routines don't need the number of 1666 // TODO(1236192): Most runtime routines don't need the number of
1694 // arguments passed in because it is constant. At some point we 1667 // arguments passed in because it is constant. At some point we
1695 // should remove this need and make the runtime routine entry code 1668 // should remove this need and make the runtime routine entry code
1696 // smarter. 1669 // smarter.
1697 Set(eax, Immediate(num_arguments)); 1670 Set(eax, Immediate(num_arguments));
1698 mov(ebx, Immediate(ExternalReference(f, isolate()))); 1671 mov(ebx, Immediate(ExternalReference(f, isolate())));
1699 CEntryStub ces(1); 1672 CEntryStub ces(1);
1700 CallStub(&ces); 1673 CallStub(&ces);
1701 } 1674 }
1702 1675
1703 1676
1704 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f,
1705 int num_arguments) {
1706 if (f->nargs >= 0 && f->nargs != num_arguments) {
1707 IllegalOperation(num_arguments);
1708 // Since we did not call the stub, there was no allocation failure.
1709 // Return some non-failure object.
1710 return isolate()->heap()->undefined_value();
1711 }
1712
1713 // TODO(1236192): Most runtime routines don't need the number of
1714 // arguments passed in because it is constant. At some point we
1715 // should remove this need and make the runtime routine entry code
1716 // smarter.
1717 Set(eax, Immediate(num_arguments));
1718 mov(ebx, Immediate(ExternalReference(f, isolate())));
1719 CEntryStub ces(1);
1720 return TryCallStub(&ces);
1721 }
1722
1723
1724 void MacroAssembler::CallExternalReference(ExternalReference ref, 1677 void MacroAssembler::CallExternalReference(ExternalReference ref,
1725 int num_arguments) { 1678 int num_arguments) {
1726 mov(eax, Immediate(num_arguments)); 1679 mov(eax, Immediate(num_arguments));
1727 mov(ebx, Immediate(ref)); 1680 mov(ebx, Immediate(ref));
1728 1681
1729 CEntryStub stub(1); 1682 CEntryStub stub(1);
1730 CallStub(&stub); 1683 CallStub(&stub);
1731 } 1684 }
1732 1685
1733 1686
1734 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 1687 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
1735 int num_arguments, 1688 int num_arguments,
1736 int result_size) { 1689 int result_size) {
1737 // TODO(1236192): Most runtime routines don't need the number of 1690 // TODO(1236192): Most runtime routines don't need the number of
1738 // arguments passed in because it is constant. At some point we 1691 // arguments passed in because it is constant. At some point we
1739 // should remove this need and make the runtime routine entry code 1692 // should remove this need and make the runtime routine entry code
1740 // smarter. 1693 // smarter.
1741 Set(eax, Immediate(num_arguments)); 1694 Set(eax, Immediate(num_arguments));
1742 JumpToExternalReference(ext); 1695 JumpToExternalReference(ext);
1743 } 1696 }
1744 1697
1745 1698
1746 MaybeObject* MacroAssembler::TryTailCallExternalReference(
1747 const ExternalReference& ext, int num_arguments, int result_size) {
1748 // TODO(1236192): Most runtime routines don't need the number of
1749 // arguments passed in because it is constant. At some point we
1750 // should remove this need and make the runtime routine entry code
1751 // smarter.
1752 Set(eax, Immediate(num_arguments));
1753 return TryJumpToExternalReference(ext);
1754 }
1755
1756
1757 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 1699 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
1758 int num_arguments, 1700 int num_arguments,
1759 int result_size) { 1701 int result_size) {
1760 TailCallExternalReference(ExternalReference(fid, isolate()), 1702 TailCallExternalReference(ExternalReference(fid, isolate()),
1761 num_arguments, 1703 num_arguments,
1762 result_size); 1704 result_size);
1763 } 1705 }
1764 1706
1765 1707
1766 MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid,
1767 int num_arguments,
1768 int result_size) {
1769 return TryTailCallExternalReference(
1770 ExternalReference(fid, isolate()), num_arguments, result_size);
1771 }
1772
1773
1774 // If true, a Handle<T> returned by value from a function with cdecl calling 1708 // If true, a Handle<T> returned by value from a function with cdecl calling
1775 // convention will be returned directly as a value of location_ field in a 1709 // convention will be returned directly as a value of location_ field in a
1776 // register eax. 1710 // register eax.
1777 // If false, it is returned as a pointer to a preallocated by caller memory 1711 // If false, it is returned as a pointer to a preallocated by caller memory
1778 // region. Pointer to this region should be passed to a function as an 1712 // region. Pointer to this region should be passed to a function as an
1779 // implicit first argument. 1713 // implicit first argument.
1780 #if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__) 1714 #if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__)
1781 static const bool kReturnHandlesDirectly = true; 1715 static const bool kReturnHandlesDirectly = true;
1782 #else 1716 #else
1783 static const bool kReturnHandlesDirectly = false; 1717 static const bool kReturnHandlesDirectly = false;
(...skipping 28 matching lines...) Expand all
1812 1746
1813 lea(esi, Operand(esp, (argc + 1) * kPointerSize)); 1747 lea(esi, Operand(esp, (argc + 1) * kPointerSize));
1814 mov(Operand(esp, 0 * kPointerSize), esi); 1748 mov(Operand(esp, 0 * kPointerSize), esi);
1815 if (emit_debug_code()) { 1749 if (emit_debug_code()) {
1816 mov(Operand(esi, 0), Immediate(0)); 1750 mov(Operand(esi, 0), Immediate(0));
1817 } 1751 }
1818 } 1752 }
1819 } 1753 }
1820 1754
1821 1755
1822 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, 1756 void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
1823 int stack_space) { 1757 int stack_space) {
1824 ExternalReference next_address = 1758 ExternalReference next_address =
1825 ExternalReference::handle_scope_next_address(); 1759 ExternalReference::handle_scope_next_address();
1826 ExternalReference limit_address = 1760 ExternalReference limit_address =
1827 ExternalReference::handle_scope_limit_address(); 1761 ExternalReference::handle_scope_limit_address();
1828 ExternalReference level_address = 1762 ExternalReference level_address =
1829 ExternalReference::handle_scope_level_address(); 1763 ExternalReference::handle_scope_level_address();
1830 1764
1831 // Allocate HandleScope in callee-save registers. 1765 // Allocate HandleScope in callee-save registers.
1832 mov(ebx, Operand::StaticVariable(next_address)); 1766 mov(ebx, Operand::StaticVariable(next_address));
1833 mov(edi, Operand::StaticVariable(limit_address)); 1767 mov(edi, Operand::StaticVariable(limit_address));
1834 add(Operand::StaticVariable(level_address), Immediate(1)); 1768 add(Operand::StaticVariable(level_address), Immediate(1));
1835 1769
1836 // Call the api function! 1770 // Call the api function.
1837 call(function->address(), RelocInfo::RUNTIME_ENTRY); 1771 call(function_address, RelocInfo::RUNTIME_ENTRY);
1838 1772
1839 if (!kReturnHandlesDirectly) { 1773 if (!kReturnHandlesDirectly) {
1840 // PrepareCallApiFunction saved pointer to the output slot into 1774 // PrepareCallApiFunction saved pointer to the output slot into
1841 // callee-save register esi. 1775 // callee-save register esi.
1842 mov(eax, Operand(esi, 0)); 1776 mov(eax, Operand(esi, 0));
1843 } 1777 }
1844 1778
1845 Label empty_handle; 1779 Label empty_handle;
1846 Label prologue; 1780 Label prologue;
1847 Label promote_scheduled_exception; 1781 Label promote_scheduled_exception;
(...skipping 17 matching lines...) Expand all
1865 1799
1866 // Check if the function scheduled an exception. 1800 // Check if the function scheduled an exception.
1867 ExternalReference scheduled_exception_address = 1801 ExternalReference scheduled_exception_address =
1868 ExternalReference::scheduled_exception_address(isolate()); 1802 ExternalReference::scheduled_exception_address(isolate());
1869 cmp(Operand::StaticVariable(scheduled_exception_address), 1803 cmp(Operand::StaticVariable(scheduled_exception_address),
1870 Immediate(isolate()->factory()->the_hole_value())); 1804 Immediate(isolate()->factory()->the_hole_value()));
1871 j(not_equal, &promote_scheduled_exception); 1805 j(not_equal, &promote_scheduled_exception);
1872 LeaveApiExitFrame(); 1806 LeaveApiExitFrame();
1873 ret(stack_space * kPointerSize); 1807 ret(stack_space * kPointerSize);
1874 bind(&promote_scheduled_exception); 1808 bind(&promote_scheduled_exception);
1875 MaybeObject* result = 1809 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
1876 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); 1810
1877 if (result->IsFailure()) {
1878 return result;
1879 }
1880 bind(&empty_handle); 1811 bind(&empty_handle);
1881 // It was zero; the result is undefined. 1812 // It was zero; the result is undefined.
1882 mov(eax, isolate()->factory()->undefined_value()); 1813 mov(eax, isolate()->factory()->undefined_value());
1883 jmp(&prologue); 1814 jmp(&prologue);
1884 1815
1885 // HandleScope limit has changed. Delete allocated extensions. 1816 // HandleScope limit has changed. Delete allocated extensions.
1886 ExternalReference delete_extensions = 1817 ExternalReference delete_extensions =
1887 ExternalReference::delete_handle_scope_extensions(isolate()); 1818 ExternalReference::delete_handle_scope_extensions(isolate());
1888 bind(&delete_allocated_handles); 1819 bind(&delete_allocated_handles);
1889 mov(Operand::StaticVariable(limit_address), edi); 1820 mov(Operand::StaticVariable(limit_address), edi);
1890 mov(edi, eax); 1821 mov(edi, eax);
1891 mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address())); 1822 mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address()));
1892 mov(eax, Immediate(delete_extensions)); 1823 mov(eax, Immediate(delete_extensions));
1893 call(eax); 1824 call(eax);
1894 mov(eax, edi); 1825 mov(eax, edi);
1895 jmp(&leave_exit_frame); 1826 jmp(&leave_exit_frame);
1896
1897 return result;
1898 } 1827 }
1899 1828
1900 1829
1901 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 1830 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) {
1902 // Set the entry point and jump to the C entry runtime stub. 1831 // Set the entry point and jump to the C entry runtime stub.
1903 mov(ebx, Immediate(ext)); 1832 mov(ebx, Immediate(ext));
1904 CEntryStub ces(1); 1833 CEntryStub ces(1);
1905 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 1834 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
1906 } 1835 }
1907 1836
1908 1837
1909 MaybeObject* MacroAssembler::TryJumpToExternalReference(
1910 const ExternalReference& ext) {
1911 // Set the entry point and jump to the C entry runtime stub.
1912 mov(ebx, Immediate(ext));
1913 CEntryStub ces(1);
1914 return TryTailCallStub(&ces);
1915 }
1916
1917
1918 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { 1838 void MacroAssembler::SetCallKind(Register dst, CallKind call_kind) {
1919 // This macro takes the dst register to make the code more readable 1839 // This macro takes the dst register to make the code more readable
1920 // at the call sites. However, the dst register has to be ecx to 1840 // at the call sites. However, the dst register has to be ecx to
1921 // follow the calling convention which requires the call type to be 1841 // follow the calling convention which requires the call type to be
1922 // in ecx. 1842 // in ecx.
1923 ASSERT(dst.is(ecx)); 1843 ASSERT(dst.is(ecx));
1924 if (call_kind == CALL_AS_FUNCTION) { 1844 if (call_kind == CALL_AS_FUNCTION) {
1925 // Set to some non-zero smi by updating the least significant 1845 // Set to some non-zero smi by updating the least significant
1926 // byte. 1846 // byte.
1927 mov_b(dst, 1 << kSmiTagSize); 1847 mov_b(dst, 1 << kSmiTagSize);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2072 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 1992 mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2073 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 1993 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
2074 SmiUntag(ebx); 1994 SmiUntag(ebx);
2075 1995
2076 ParameterCount expected(ebx); 1996 ParameterCount expected(ebx);
2077 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 1997 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2078 expected, actual, flag, call_wrapper, call_kind); 1998 expected, actual, flag, call_wrapper, call_kind);
2079 } 1999 }
2080 2000
2081 2001
2082 void MacroAssembler::InvokeFunction(JSFunction* function, 2002 void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
2083 const ParameterCount& actual, 2003 const ParameterCount& actual,
2084 InvokeFlag flag, 2004 InvokeFlag flag,
2085 const CallWrapper& call_wrapper, 2005 const CallWrapper& call_wrapper,
2086 CallKind call_kind) { 2006 CallKind call_kind) {
2087 // You can't call a function without a valid frame. 2007 // You can't call a function without a valid frame.
2088 ASSERT(flag == JUMP_FUNCTION || has_frame()); 2008 ASSERT(flag == JUMP_FUNCTION || has_frame());
2089 2009
2090 // Get the function and setup the context. 2010 // Get the function and setup the context.
2091 mov(edi, Immediate(Handle<JSFunction>(function))); 2011 mov(edi, Immediate(function));
2092 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2012 mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2093 2013
2094 ParameterCount expected(function->shared()->formal_parameter_count()); 2014 ParameterCount expected(function->shared()->formal_parameter_count());
2095 // We call indirectly through the code field in the function to 2015 // We call indirectly through the code field in the function to
2096 // allow recompilation to take effect without changing any of the 2016 // allow recompilation to take effect without changing any of the
2097 // call sites. 2017 // call sites.
2098 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2018 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2099 expected, actual, flag, call_wrapper, call_kind); 2019 expected, actual, flag, call_wrapper, call_kind);
2100 } 2020 }
2101 2021
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
2727 cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); 2647 cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset));
2728 Check(less_equal, "Live Bytes Count overflow chunk size"); 2648 Check(less_equal, "Live Bytes Count overflow chunk size");
2729 } 2649 }
2730 2650
2731 bind(&done); 2651 bind(&done);
2732 } 2652 }
2733 2653
2734 } } // namespace v8::internal 2654 } } // namespace v8::internal
2735 2655
2736 #endif // V8_TARGET_ARCH_IA32 2656 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698