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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 6592064: Make the materialization of smi constants consistent between the two compiler... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 9 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 | src/full-codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 #ifdef DEBUG 332 #ifdef DEBUG
333 // Check that the size of the code used for returning is large enough 333 // Check that the size of the code used for returning is large enough
334 // for the debugger's requirements. 334 // for the debugger's requirements.
335 ASSERT(Assembler::kJSReturnSequenceInstructions <= 335 ASSERT(Assembler::kJSReturnSequenceInstructions <=
336 masm_->InstructionsGeneratedSince(&check_exit_codesize)); 336 masm_->InstructionsGeneratedSince(&check_exit_codesize));
337 #endif 337 #endif
338 } 338 }
339 } 339 }
340 340
341 341
342 FullCodeGenerator::ConstantOperand FullCodeGenerator::GetConstantOperand(
343 Token::Value op, Expression* left, Expression* right) {
344 ASSERT(ShouldInlineSmiCase(op));
345 if (op == Token::DIV || op == Token::MOD || op == Token::MUL) {
346 // We never generate inlined constant smi operations for these.
347 return kNoConstants;
348 } else if (right->IsSmiLiteral()) {
349 return kRightConstant;
350 } else if (left->IsSmiLiteral() && !Token::IsShiftOp(op)) {
351 // Don't inline shifts with constant left hand side.
352 return kLeftConstant;
353 } else {
354 return kNoConstants;
355 }
356 }
357
358
359 void FullCodeGenerator::EffectContext::Plug(Slot* slot) const { 342 void FullCodeGenerator::EffectContext::Plug(Slot* slot) const {
360 } 343 }
361 344
362 345
363 void FullCodeGenerator::AccumulatorValueContext::Plug(Slot* slot) const { 346 void FullCodeGenerator::AccumulatorValueContext::Plug(Slot* slot) const {
364 codegen()->Move(result_register(), slot); 347 codegen()->Move(result_register(), slot);
365 } 348 }
366 349
367 350
368 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const { 351 void FullCodeGenerator::StackValueContext::Plug(Slot* slot) const {
(...skipping 1258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1627 } 1610 }
1628 } 1611 }
1629 1612
1630 // For property compound assignments we need another deoptimization 1613 // For property compound assignments we need another deoptimization
1631 // point after the property load. 1614 // point after the property load.
1632 if (property != NULL) { 1615 if (property != NULL) {
1633 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG); 1616 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1634 } 1617 }
1635 1618
1636 Token::Value op = expr->binary_op(); 1619 Token::Value op = expr->binary_op();
1637 ConstantOperand constant = ShouldInlineSmiCase(op) 1620 __ push(r0); // Left operand goes on the stack.
1638 ? GetConstantOperand(op, expr->target(), expr->value()) 1621 VisitForAccumulatorValue(expr->value());
1639 : kNoConstants;
1640 ASSERT(constant == kRightConstant || constant == kNoConstants);
1641 if (constant == kNoConstants) {
1642 __ push(r0); // Left operand goes on the stack.
1643 VisitForAccumulatorValue(expr->value());
1644 }
1645 1622
1646 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1623 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1647 ? OVERWRITE_RIGHT 1624 ? OVERWRITE_RIGHT
1648 : NO_OVERWRITE; 1625 : NO_OVERWRITE;
1649 SetSourcePosition(expr->position() + 1); 1626 SetSourcePosition(expr->position() + 1);
1650 AccumulatorValueContext context(this); 1627 AccumulatorValueContext context(this);
1651 if (ShouldInlineSmiCase(op)) { 1628 if (ShouldInlineSmiCase(op)) {
1652 EmitInlineSmiBinaryOp(expr, 1629 EmitInlineSmiBinaryOp(expr,
1653 op, 1630 op,
1654 mode, 1631 mode,
1655 expr->target(), 1632 expr->target(),
1656 expr->value(), 1633 expr->value());
1657 constant);
1658 } else { 1634 } else {
1659 EmitBinaryOp(op, mode); 1635 EmitBinaryOp(op, mode);
1660 } 1636 }
1661 1637
1662 // Deoptimization point in case the binary operation may have side effects. 1638 // Deoptimization point in case the binary operation may have side effects.
1663 PrepareForBailout(expr->binary_operation(), TOS_REG); 1639 PrepareForBailout(expr->binary_operation(), TOS_REG);
1664 } else { 1640 } else {
1665 VisitForAccumulatorValue(expr->value()); 1641 VisitForAccumulatorValue(expr->value());
1666 } 1642 }
1667 1643
(...skipping 29 matching lines...) Expand all
1697 1673
1698 1674
1699 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1675 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1700 SetSourcePosition(prop->position()); 1676 SetSourcePosition(prop->position());
1701 // Call keyed load IC. It has arguments key and receiver in r0 and r1. 1677 // Call keyed load IC. It has arguments key and receiver in r0 and r1.
1702 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1678 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1703 EmitCallIC(ic, RelocInfo::CODE_TARGET); 1679 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1704 } 1680 }
1705 1681
1706 1682
1707 void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
1708 OverwriteMode mode,
1709 bool left_is_constant_smi,
1710 Smi* value) {
1711 Label call_stub, done;
1712 // Optimistically add smi value with unknown object. If result overflows or is
1713 // not a smi then we had either a smi overflow or added a smi with a tagged
1714 // pointer.
1715 __ mov(r1, Operand(value));
1716 __ add(r2, r0, r1, SetCC);
1717 __ b(vs, &call_stub);
1718 JumpPatchSite patch_site(masm_);
1719 patch_site.EmitJumpIfNotSmi(r2, &call_stub);
1720 __ mov(r0, r2);
1721 __ b(&done);
1722
1723 // Call the shared stub.
1724 __ bind(&call_stub);
1725 if (!left_is_constant_smi) {
1726 __ Swap(r0, r1, r2);
1727 }
1728 TypeRecordingBinaryOpStub stub(Token::ADD, mode);
1729 EmitCallIC(stub.GetCode(), &patch_site);
1730
1731 __ bind(&done);
1732 context()->Plug(r0);
1733 }
1734
1735
1736 void FullCodeGenerator::EmitConstantSmiSub(Expression* expr,
1737 OverwriteMode mode,
1738 bool left_is_constant_smi,
1739 Smi* value) {
1740 Label call_stub, done;
1741 // Optimistically subtract smi value and unknown object. If result overflows
1742 // or is not a smi then we had either a smi overflow or subtraction between a
1743 // smi and a tagged pointer.
1744 __ mov(r1, Operand(value));
1745 if (left_is_constant_smi) {
1746 __ sub(r2, r1, r0, SetCC);
1747 } else {
1748 __ sub(r2, r0, r1, SetCC);
1749 }
1750 __ b(vs, &call_stub);
1751 JumpPatchSite patch_site(masm_);
1752 patch_site.EmitJumpIfNotSmi(r2, &call_stub);
1753 __ mov(r0, r2);
1754 __ b(&done);
1755
1756 // Call the shared stub.
1757 __ bind(&call_stub);
1758 if (!left_is_constant_smi) {
1759 __ Swap(r0, r1, r2);
1760 }
1761 TypeRecordingBinaryOpStub stub(Token::SUB, mode);
1762 EmitCallIC(stub.GetCode(), &patch_site);
1763
1764 __ bind(&done);
1765 context()->Plug(r0);
1766 }
1767
1768
1769 void FullCodeGenerator::EmitConstantSmiShiftOp(Expression* expr,
1770 Token::Value op,
1771 OverwriteMode mode,
1772 Smi* value) {
1773 Label call_stub, smi_case, done;
1774 int shift_value = value->value() & 0x1f;
1775
1776 JumpPatchSite patch_site(masm_);
1777 patch_site.EmitJumpIfSmi(r0, &smi_case);
1778
1779 // Call stub.
1780 __ bind(&call_stub);
1781 __ mov(r1, r0);
1782 __ mov(r0, Operand(value));
1783 TypeRecordingBinaryOpStub stub(op, mode);
1784 EmitCallIC(stub.GetCode(), &patch_site);
1785 __ b(&done);
1786
1787 // Smi case.
1788 __ bind(&smi_case);
1789 switch (op) {
1790 case Token::SHL:
1791 if (shift_value != 0) {
1792 __ mov(r1, r0);
1793 if (shift_value > 1) {
1794 __ mov(r1, Operand(r1, LSL, shift_value - 1));
1795 }
1796 // Convert int result to smi, checking that it is in int range.
1797 __ SmiTag(r1, SetCC);
1798 __ b(vs, &call_stub);
1799 __ mov(r0, r1); // Put result back into r0.
1800 }
1801 break;
1802 case Token::SAR:
1803 if (shift_value != 0) {
1804 __ mov(r0, Operand(r0, ASR, shift_value));
1805 __ bic(r0, r0, Operand(kSmiTagMask));
1806 }
1807 break;
1808 case Token::SHR:
1809 // SHR must return a positive value. When shifting by 0 or 1 we need to
1810 // check that smi tagging the result will not create a negative value.
1811 if (shift_value < 2) {
1812 __ mov(r2, Operand(shift_value));
1813 __ SmiUntag(r1, r0);
1814 if (shift_value != 0) {
1815 __ mov(r1, Operand(r1, LSR, shift_value));
1816 }
1817 __ tst(r1, Operand(0xc0000000));
1818 __ b(ne, &call_stub);
1819 __ SmiTag(r0, r1); // result in r0.
1820 } else {
1821 __ SmiUntag(r0);
1822 __ mov(r0, Operand(r0, LSR, shift_value));
1823 __ SmiTag(r0);
1824 }
1825 break;
1826 default:
1827 UNREACHABLE();
1828 }
1829
1830 __ bind(&done);
1831 context()->Plug(r0);
1832 }
1833
1834
1835 void FullCodeGenerator::EmitConstantSmiBitOp(Expression* expr,
1836 Token::Value op,
1837 OverwriteMode mode,
1838 Smi* value) {
1839 Label smi_case, done;
1840
1841 JumpPatchSite patch_site(masm_);
1842 patch_site.EmitJumpIfSmi(r0, &smi_case);
1843
1844 // The order of the arguments does not matter for bit-ops with a
1845 // constant operand.
1846 __ mov(r1, Operand(value));
1847 TypeRecordingBinaryOpStub stub(op, mode);
1848 EmitCallIC(stub.GetCode(), &patch_site);
1849 __ jmp(&done);
1850
1851 // Smi case.
1852 __ bind(&smi_case);
1853 __ mov(r1, Operand(value));
1854 switch (op) {
1855 case Token::BIT_OR:
1856 __ orr(r0, r0, Operand(r1));
1857 break;
1858 case Token::BIT_XOR:
1859 __ eor(r0, r0, Operand(r1));
1860 break;
1861 case Token::BIT_AND:
1862 __ and_(r0, r0, Operand(r1));
1863 break;
1864 default:
1865 UNREACHABLE();
1866 }
1867
1868 __ bind(&done);
1869 context()->Plug(r0);
1870 }
1871
1872
1873 void FullCodeGenerator::EmitConstantSmiBinaryOp(Expression* expr,
1874 Token::Value op,
1875 OverwriteMode mode,
1876 bool left_is_constant_smi,
1877 Smi* value) {
1878 switch (op) {
1879 case Token::BIT_OR:
1880 case Token::BIT_XOR:
1881 case Token::BIT_AND:
1882 EmitConstantSmiBitOp(expr, op, mode, value);
1883 break;
1884 case Token::SHL:
1885 case Token::SAR:
1886 case Token::SHR:
1887 ASSERT(!left_is_constant_smi);
1888 EmitConstantSmiShiftOp(expr, op, mode, value);
1889 break;
1890 case Token::ADD:
1891 EmitConstantSmiAdd(expr, mode, left_is_constant_smi, value);
1892 break;
1893 case Token::SUB:
1894 EmitConstantSmiSub(expr, mode, left_is_constant_smi, value);
1895 break;
1896 default:
1897 UNREACHABLE();
1898 }
1899 }
1900
1901
1902 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, 1683 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1903 Token::Value op, 1684 Token::Value op,
1904 OverwriteMode mode, 1685 OverwriteMode mode,
1905 Expression* left_expr, 1686 Expression* left_expr,
1906 Expression* right_expr, 1687 Expression* right_expr) {
1907 ConstantOperand constant) {
1908 if (constant == kRightConstant) {
1909 Smi* value = Smi::cast(*right_expr->AsLiteral()->handle());
1910 EmitConstantSmiBinaryOp(expr, op, mode, false, value);
1911 return;
1912 } else if (constant == kLeftConstant) {
1913 Smi* value = Smi::cast(*left_expr->AsLiteral()->handle());
1914 EmitConstantSmiBinaryOp(expr, op, mode, true, value);
1915 return;
1916 }
1917
1918 Label done, smi_case, stub_call; 1688 Label done, smi_case, stub_call;
1919 1689
1920 Register scratch1 = r2; 1690 Register scratch1 = r2;
1921 Register scratch2 = r3; 1691 Register scratch2 = r3;
1922 1692
1923 // Get the arguments. 1693 // Get the arguments.
1924 Register left = r1; 1694 Register left = r1;
1925 Register right = r0; 1695 Register right = r0;
1926 __ pop(left); 1696 __ pop(left);
1927 1697
(...skipping 2251 matching lines...) Expand 10 before | Expand all | Expand 10 after
4179 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 3949 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4180 __ add(pc, r1, Operand(masm_->CodeObject())); 3950 __ add(pc, r1, Operand(masm_->CodeObject()));
4181 } 3951 }
4182 3952
4183 3953
4184 #undef __ 3954 #undef __
4185 3955
4186 } } // namespace v8::internal 3956 } } // namespace v8::internal
4187 3957
4188 #endif // V8_TARGET_ARCH_ARM 3958 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698