OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 Comment cmnt(masm_, "[ function body"); | 314 Comment cmnt(masm_, "[ function body"); |
315 #ifdef DEBUG | 315 #ifdef DEBUG |
316 bool is_builtin = Bootstrapper::IsActive(); | 316 bool is_builtin = Bootstrapper::IsActive(); |
317 bool should_trace = | 317 bool should_trace = |
318 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls; | 318 is_builtin ? FLAG_trace_builtin_calls : FLAG_trace_calls; |
319 if (should_trace) { | 319 if (should_trace) { |
320 frame_->CallRuntime(Runtime::kDebugTrace, 0); | 320 frame_->CallRuntime(Runtime::kDebugTrace, 0); |
321 // Ignore the return value. | 321 // Ignore the return value. |
322 } | 322 } |
323 #endif | 323 #endif |
324 VisitStatementsAndSpill(info->function()->body()); | 324 VisitStatements(info->function()->body()); |
325 } | 325 } |
326 } | 326 } |
327 | 327 |
328 // Generate the return sequence if necessary. | 328 // Generate the return sequence if necessary. |
329 if (has_valid_frame() || function_return_.is_linked()) { | 329 if (has_valid_frame() || function_return_.is_linked()) { |
330 if (!function_return_.is_linked()) { | 330 if (!function_return_.is_linked()) { |
331 CodeForReturnPosition(info->function()); | 331 CodeForReturnPosition(info->function()); |
332 } | 332 } |
333 // exit | 333 // exit |
334 // r0: result | 334 // r0: result |
(...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 lo); | 1559 lo); |
1560 } | 1560 } |
1561 | 1561 |
1562 | 1562 |
1563 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { | 1563 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { |
1564 #ifdef DEBUG | 1564 #ifdef DEBUG |
1565 int original_height = frame_->height(); | 1565 int original_height = frame_->height(); |
1566 #endif | 1566 #endif |
1567 VirtualFrame::SpilledScope spilled_scope(frame_); | 1567 VirtualFrame::SpilledScope spilled_scope(frame_); |
1568 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { | 1568 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { |
1569 VisitAndSpill(statements->at(i)); | 1569 Visit(statements->at(i)); |
1570 } | 1570 } |
1571 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1571 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
1572 } | 1572 } |
1573 | 1573 |
1574 | 1574 |
1575 void CodeGenerator::VisitBlock(Block* node) { | 1575 void CodeGenerator::VisitBlock(Block* node) { |
1576 #ifdef DEBUG | 1576 #ifdef DEBUG |
1577 int original_height = frame_->height(); | 1577 int original_height = frame_->height(); |
1578 #endif | 1578 #endif |
1579 VirtualFrame::SpilledScope spilled_scope(frame_); | 1579 VirtualFrame::SpilledScope spilled_scope(frame_); |
1580 Comment cmnt(masm_, "[ Block"); | 1580 Comment cmnt(masm_, "[ Block"); |
1581 CodeForStatementPosition(node); | 1581 CodeForStatementPosition(node); |
1582 node->break_target()->SetExpectedHeight(); | 1582 node->break_target()->SetExpectedHeight(); |
1583 VisitStatementsAndSpill(node->statements()); | 1583 VisitStatements(node->statements()); |
1584 if (node->break_target()->is_linked()) { | 1584 if (node->break_target()->is_linked()) { |
1585 node->break_target()->Bind(); | 1585 node->break_target()->Bind(); |
1586 } | 1586 } |
1587 node->break_target()->Unuse(); | 1587 node->break_target()->Unuse(); |
1588 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 1588 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
1589 } | 1589 } |
1590 | 1590 |
1591 | 1591 |
1592 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 1592 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
1593 frame_->EmitPush(cp); | 1593 frame_->EmitPush(cp); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 CodeForStatementPosition(node); | 1688 CodeForStatementPosition(node); |
1689 // nothing to do | 1689 // nothing to do |
1690 ASSERT(frame_->height() == original_height); | 1690 ASSERT(frame_->height() == original_height); |
1691 } | 1691 } |
1692 | 1692 |
1693 | 1693 |
1694 void CodeGenerator::VisitIfStatement(IfStatement* node) { | 1694 void CodeGenerator::VisitIfStatement(IfStatement* node) { |
1695 #ifdef DEBUG | 1695 #ifdef DEBUG |
1696 int original_height = frame_->height(); | 1696 int original_height = frame_->height(); |
1697 #endif | 1697 #endif |
1698 VirtualFrame::SpilledScope spilled_scope(frame_); | |
1699 Comment cmnt(masm_, "[ IfStatement"); | 1698 Comment cmnt(masm_, "[ IfStatement"); |
1700 // Generate different code depending on which parts of the if statement | 1699 // Generate different code depending on which parts of the if statement |
1701 // are present or not. | 1700 // are present or not. |
1702 bool has_then_stm = node->HasThenStatement(); | 1701 bool has_then_stm = node->HasThenStatement(); |
1703 bool has_else_stm = node->HasElseStatement(); | 1702 bool has_else_stm = node->HasElseStatement(); |
1704 | 1703 |
1705 CodeForStatementPosition(node); | 1704 CodeForStatementPosition(node); |
1706 | 1705 |
1707 JumpTarget exit; | 1706 JumpTarget exit; |
1708 if (has_then_stm && has_else_stm) { | 1707 if (has_then_stm && has_else_stm) { |
1709 Comment cmnt(masm_, "[ IfThenElse"); | 1708 Comment cmnt(masm_, "[ IfThenElse"); |
1710 JumpTarget then; | 1709 JumpTarget then; |
1711 JumpTarget else_; | 1710 JumpTarget else_; |
1712 // if (cond) | 1711 // if (cond) |
1713 LoadConditionAndSpill(node->condition(), &then, &else_, true); | 1712 LoadCondition(node->condition(), &then, &else_, true); |
1714 if (frame_ != NULL) { | 1713 if (frame_ != NULL) { |
1715 Branch(false, &else_); | 1714 Branch(false, &else_); |
1716 } | 1715 } |
1717 // then | 1716 // then |
1718 if (frame_ != NULL || then.is_linked()) { | 1717 if (frame_ != NULL || then.is_linked()) { |
1719 then.Bind(); | 1718 then.Bind(); |
1720 VisitAndSpill(node->then_statement()); | 1719 Visit(node->then_statement()); |
1721 } | 1720 } |
1722 if (frame_ != NULL) { | 1721 if (frame_ != NULL) { |
1723 exit.Jump(); | 1722 exit.Jump(); |
1724 } | 1723 } |
1725 // else | 1724 // else |
1726 if (else_.is_linked()) { | 1725 if (else_.is_linked()) { |
1727 else_.Bind(); | 1726 else_.Bind(); |
1728 VisitAndSpill(node->else_statement()); | 1727 Visit(node->else_statement()); |
1729 } | 1728 } |
1730 | 1729 |
1731 } else if (has_then_stm) { | 1730 } else if (has_then_stm) { |
1732 Comment cmnt(masm_, "[ IfThen"); | 1731 Comment cmnt(masm_, "[ IfThen"); |
1733 ASSERT(!has_else_stm); | 1732 ASSERT(!has_else_stm); |
1734 JumpTarget then; | 1733 JumpTarget then; |
1735 // if (cond) | 1734 // if (cond) |
1736 LoadConditionAndSpill(node->condition(), &then, &exit, true); | 1735 LoadCondition(node->condition(), &then, &exit, true); |
1737 if (frame_ != NULL) { | 1736 if (frame_ != NULL) { |
1738 Branch(false, &exit); | 1737 Branch(false, &exit); |
1739 } | 1738 } |
1740 // then | 1739 // then |
1741 if (frame_ != NULL || then.is_linked()) { | 1740 if (frame_ != NULL || then.is_linked()) { |
1742 then.Bind(); | 1741 then.Bind(); |
1743 VisitAndSpill(node->then_statement()); | 1742 Visit(node->then_statement()); |
1744 } | 1743 } |
1745 | 1744 |
1746 } else if (has_else_stm) { | 1745 } else if (has_else_stm) { |
1747 Comment cmnt(masm_, "[ IfElse"); | 1746 Comment cmnt(masm_, "[ IfElse"); |
1748 ASSERT(!has_then_stm); | 1747 ASSERT(!has_then_stm); |
1749 JumpTarget else_; | 1748 JumpTarget else_; |
1750 // if (!cond) | 1749 // if (!cond) |
1751 LoadConditionAndSpill(node->condition(), &exit, &else_, true); | 1750 LoadCondition(node->condition(), &exit, &else_, true); |
1752 if (frame_ != NULL) { | 1751 if (frame_ != NULL) { |
1753 Branch(true, &exit); | 1752 Branch(true, &exit); |
1754 } | 1753 } |
1755 // else | 1754 // else |
1756 if (frame_ != NULL || else_.is_linked()) { | 1755 if (frame_ != NULL || else_.is_linked()) { |
1757 else_.Bind(); | 1756 else_.Bind(); |
1758 VisitAndSpill(node->else_statement()); | 1757 Visit(node->else_statement()); |
1759 } | 1758 } |
1760 | 1759 |
1761 } else { | 1760 } else { |
1762 Comment cmnt(masm_, "[ If"); | 1761 Comment cmnt(masm_, "[ If"); |
1763 ASSERT(!has_then_stm && !has_else_stm); | 1762 ASSERT(!has_then_stm && !has_else_stm); |
1764 // if (cond) | 1763 // if (cond) |
1765 LoadConditionAndSpill(node->condition(), &exit, &exit, false); | 1764 LoadCondition(node->condition(), &exit, &exit, false); |
1766 if (frame_ != NULL) { | 1765 if (frame_ != NULL) { |
1767 if (has_cc()) { | 1766 if (has_cc()) { |
1768 cc_reg_ = al; | 1767 cc_reg_ = al; |
1769 } else { | 1768 } else { |
1770 frame_->Drop(); | 1769 frame_->Drop(); |
1771 } | 1770 } |
1772 } | 1771 } |
1773 } | 1772 } |
1774 | 1773 |
1775 // end | 1774 // end |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1898 // the stack. | 1897 // the stack. |
1899 frame_->Drop(); | 1898 frame_->Drop(); |
1900 | 1899 |
1901 // Label the body so that fall through is enabled. | 1900 // Label the body so that fall through is enabled. |
1902 if (i > 0 && cases->at(i - 1)->is_default()) { | 1901 if (i > 0 && cases->at(i - 1)->is_default()) { |
1903 default_exit.Bind(); | 1902 default_exit.Bind(); |
1904 } else { | 1903 } else { |
1905 fall_through.Bind(); | 1904 fall_through.Bind(); |
1906 fall_through.Unuse(); | 1905 fall_through.Unuse(); |
1907 } | 1906 } |
1908 VisitStatementsAndSpill(clause->statements()); | 1907 VisitStatements(clause->statements()); |
1909 | 1908 |
1910 // If control flow can fall through from the body, jump to the next body | 1909 // If control flow can fall through from the body, jump to the next body |
1911 // or the end of the statement. | 1910 // or the end of the statement. |
1912 if (frame_ != NULL) { | 1911 if (frame_ != NULL) { |
1913 if (i < length - 1 && cases->at(i + 1)->is_default()) { | 1912 if (i < length - 1 && cases->at(i + 1)->is_default()) { |
1914 default_entry.Jump(); | 1913 default_entry.Jump(); |
1915 } else { | 1914 } else { |
1916 fall_through.Jump(); | 1915 fall_through.Jump(); |
1917 } | 1916 } |
1918 } | 1917 } |
1919 } | 1918 } |
1920 | 1919 |
1921 // The final "test" removes the switch value. | 1920 // The final "test" removes the switch value. |
1922 next_test.Bind(); | 1921 next_test.Bind(); |
1923 frame_->Drop(); | 1922 frame_->Drop(); |
1924 | 1923 |
1925 // If there is a default clause, compile it. | 1924 // If there is a default clause, compile it. |
1926 if (default_clause != NULL) { | 1925 if (default_clause != NULL) { |
1927 Comment cmnt(masm_, "[ Default clause"); | 1926 Comment cmnt(masm_, "[ Default clause"); |
1928 default_entry.Bind(); | 1927 default_entry.Bind(); |
1929 VisitStatementsAndSpill(default_clause->statements()); | 1928 VisitStatements(default_clause->statements()); |
1930 // If control flow can fall out of the default and there is a case after | 1929 // If control flow can fall out of the default and there is a case after |
1931 // it, jup to that case's body. | 1930 // it, jup to that case's body. |
1932 if (frame_ != NULL && default_exit.is_bound()) { | 1931 if (frame_ != NULL && default_exit.is_bound()) { |
1933 default_exit.Jump(); | 1932 default_exit.Jump(); |
1934 } | 1933 } |
1935 } | 1934 } |
1936 | 1935 |
1937 if (fall_through.is_linked()) { | 1936 if (fall_through.is_linked()) { |
1938 fall_through.Bind(); | 1937 fall_through.Bind(); |
1939 } | 1938 } |
(...skipping 29 matching lines...) Expand all Loading... |
1969 case ALWAYS_FALSE: | 1968 case ALWAYS_FALSE: |
1970 node->continue_target()->SetExpectedHeight(); | 1969 node->continue_target()->SetExpectedHeight(); |
1971 break; | 1970 break; |
1972 case DONT_KNOW: | 1971 case DONT_KNOW: |
1973 node->continue_target()->SetExpectedHeight(); | 1972 node->continue_target()->SetExpectedHeight(); |
1974 body.Bind(); | 1973 body.Bind(); |
1975 break; | 1974 break; |
1976 } | 1975 } |
1977 | 1976 |
1978 CheckStack(); // TODO(1222600): ignore if body contains calls. | 1977 CheckStack(); // TODO(1222600): ignore if body contains calls. |
1979 VisitAndSpill(node->body()); | 1978 Visit(node->body()); |
1980 | 1979 |
1981 // Compile the test. | 1980 // Compile the test. |
1982 switch (info) { | 1981 switch (info) { |
1983 case ALWAYS_TRUE: | 1982 case ALWAYS_TRUE: |
1984 // If control can fall off the end of the body, jump back to the | 1983 // If control can fall off the end of the body, jump back to the |
1985 // top. | 1984 // top. |
1986 if (has_valid_frame()) { | 1985 if (has_valid_frame()) { |
1987 node->continue_target()->Jump(); | 1986 node->continue_target()->Jump(); |
1988 } | 1987 } |
1989 break; | 1988 break; |
1990 case ALWAYS_FALSE: | 1989 case ALWAYS_FALSE: |
1991 // If we have a continue in the body, we only have to bind its | 1990 // If we have a continue in the body, we only have to bind its |
1992 // jump target. | 1991 // jump target. |
1993 if (node->continue_target()->is_linked()) { | 1992 if (node->continue_target()->is_linked()) { |
1994 node->continue_target()->Bind(); | 1993 node->continue_target()->Bind(); |
1995 } | 1994 } |
1996 break; | 1995 break; |
1997 case DONT_KNOW: | 1996 case DONT_KNOW: |
1998 // We have to compile the test expression if it can be reached by | 1997 // We have to compile the test expression if it can be reached by |
1999 // control flow falling out of the body or via continue. | 1998 // control flow falling out of the body or via continue. |
2000 if (node->continue_target()->is_linked()) { | 1999 if (node->continue_target()->is_linked()) { |
2001 node->continue_target()->Bind(); | 2000 node->continue_target()->Bind(); |
2002 } | 2001 } |
2003 if (has_valid_frame()) { | 2002 if (has_valid_frame()) { |
2004 Comment cmnt(masm_, "[ DoWhileCondition"); | 2003 Comment cmnt(masm_, "[ DoWhileCondition"); |
2005 CodeForDoWhileConditionPosition(node); | 2004 CodeForDoWhileConditionPosition(node); |
2006 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); | 2005 LoadCondition(node->cond(), &body, node->break_target(), true); |
2007 if (has_valid_frame()) { | 2006 if (has_valid_frame()) { |
2008 // A invalid frame here indicates that control did not | 2007 // A invalid frame here indicates that control did not |
2009 // fall out of the test expression. | 2008 // fall out of the test expression. |
2010 Branch(true, &body); | 2009 Branch(true, &body); |
2011 } | 2010 } |
2012 } | 2011 } |
2013 break; | 2012 break; |
2014 } | 2013 } |
2015 | 2014 |
2016 if (node->break_target()->is_linked()) { | 2015 if (node->break_target()->is_linked()) { |
(...skipping 20 matching lines...) Expand all Loading... |
2037 node->break_target()->SetExpectedHeight(); | 2036 node->break_target()->SetExpectedHeight(); |
2038 IncrementLoopNesting(); | 2037 IncrementLoopNesting(); |
2039 | 2038 |
2040 // Label the top of the loop with the continue target for the backward | 2039 // Label the top of the loop with the continue target for the backward |
2041 // CFG edge. | 2040 // CFG edge. |
2042 node->continue_target()->SetExpectedHeight(); | 2041 node->continue_target()->SetExpectedHeight(); |
2043 node->continue_target()->Bind(); | 2042 node->continue_target()->Bind(); |
2044 | 2043 |
2045 if (info == DONT_KNOW) { | 2044 if (info == DONT_KNOW) { |
2046 JumpTarget body; | 2045 JumpTarget body; |
2047 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); | 2046 LoadCondition(node->cond(), &body, node->break_target(), true); |
2048 if (has_valid_frame()) { | 2047 if (has_valid_frame()) { |
2049 // A NULL frame indicates that control did not fall out of the | 2048 // A NULL frame indicates that control did not fall out of the |
2050 // test expression. | 2049 // test expression. |
2051 Branch(false, node->break_target()); | 2050 Branch(false, node->break_target()); |
2052 } | 2051 } |
2053 if (has_valid_frame() || body.is_linked()) { | 2052 if (has_valid_frame() || body.is_linked()) { |
2054 body.Bind(); | 2053 body.Bind(); |
2055 } | 2054 } |
2056 } | 2055 } |
2057 | 2056 |
2058 if (has_valid_frame()) { | 2057 if (has_valid_frame()) { |
2059 CheckStack(); // TODO(1222600): ignore if body contains calls. | 2058 CheckStack(); // TODO(1222600): ignore if body contains calls. |
2060 VisitAndSpill(node->body()); | 2059 Visit(node->body()); |
2061 | 2060 |
2062 // If control flow can fall out of the body, jump back to the top. | 2061 // If control flow can fall out of the body, jump back to the top. |
2063 if (has_valid_frame()) { | 2062 if (has_valid_frame()) { |
2064 node->continue_target()->Jump(); | 2063 node->continue_target()->Jump(); |
2065 } | 2064 } |
2066 } | 2065 } |
2067 if (node->break_target()->is_linked()) { | 2066 if (node->break_target()->is_linked()) { |
2068 node->break_target()->Bind(); | 2067 node->break_target()->Bind(); |
2069 } | 2068 } |
2070 DecrementLoopNesting(); | 2069 DecrementLoopNesting(); |
2071 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 2070 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
2072 } | 2071 } |
2073 | 2072 |
2074 | 2073 |
2075 void CodeGenerator::VisitForStatement(ForStatement* node) { | 2074 void CodeGenerator::VisitForStatement(ForStatement* node) { |
2076 #ifdef DEBUG | 2075 #ifdef DEBUG |
2077 int original_height = frame_->height(); | 2076 int original_height = frame_->height(); |
2078 #endif | 2077 #endif |
2079 VirtualFrame::SpilledScope spilled_scope(frame_); | 2078 VirtualFrame::SpilledScope spilled_scope(frame_); |
2080 Comment cmnt(masm_, "[ ForStatement"); | 2079 Comment cmnt(masm_, "[ ForStatement"); |
2081 CodeForStatementPosition(node); | 2080 CodeForStatementPosition(node); |
2082 if (node->init() != NULL) { | 2081 if (node->init() != NULL) { |
2083 VisitAndSpill(node->init()); | 2082 Visit(node->init()); |
2084 } | 2083 } |
2085 | 2084 |
2086 // If the test is never true there is no need to compile the test or | 2085 // If the test is never true there is no need to compile the test or |
2087 // body. | 2086 // body. |
2088 ConditionAnalysis info = AnalyzeCondition(node->cond()); | 2087 ConditionAnalysis info = AnalyzeCondition(node->cond()); |
2089 if (info == ALWAYS_FALSE) return; | 2088 if (info == ALWAYS_FALSE) return; |
2090 | 2089 |
2091 node->break_target()->SetExpectedHeight(); | 2090 node->break_target()->SetExpectedHeight(); |
2092 IncrementLoopNesting(); | 2091 IncrementLoopNesting(); |
2093 | 2092 |
2094 // If there is no update statement, label the top of the loop with the | 2093 // If there is no update statement, label the top of the loop with the |
2095 // continue target, otherwise with the loop target. | 2094 // continue target, otherwise with the loop target. |
2096 JumpTarget loop(JumpTarget::BIDIRECTIONAL); | 2095 JumpTarget loop(JumpTarget::BIDIRECTIONAL); |
2097 if (node->next() == NULL) { | 2096 if (node->next() == NULL) { |
2098 node->continue_target()->SetExpectedHeight(); | 2097 node->continue_target()->SetExpectedHeight(); |
2099 node->continue_target()->Bind(); | 2098 node->continue_target()->Bind(); |
2100 } else { | 2099 } else { |
2101 node->continue_target()->SetExpectedHeight(); | 2100 node->continue_target()->SetExpectedHeight(); |
2102 loop.Bind(); | 2101 loop.Bind(); |
2103 } | 2102 } |
2104 | 2103 |
2105 // If the test is always true, there is no need to compile it. | 2104 // If the test is always true, there is no need to compile it. |
2106 if (info == DONT_KNOW) { | 2105 if (info == DONT_KNOW) { |
2107 JumpTarget body; | 2106 JumpTarget body; |
2108 LoadConditionAndSpill(node->cond(), &body, node->break_target(), true); | 2107 LoadCondition(node->cond(), &body, node->break_target(), true); |
2109 if (has_valid_frame()) { | 2108 if (has_valid_frame()) { |
2110 Branch(false, node->break_target()); | 2109 Branch(false, node->break_target()); |
2111 } | 2110 } |
2112 if (has_valid_frame() || body.is_linked()) { | 2111 if (has_valid_frame() || body.is_linked()) { |
2113 body.Bind(); | 2112 body.Bind(); |
2114 } | 2113 } |
2115 } | 2114 } |
2116 | 2115 |
2117 if (has_valid_frame()) { | 2116 if (has_valid_frame()) { |
2118 CheckStack(); // TODO(1222600): ignore if body contains calls. | 2117 CheckStack(); // TODO(1222600): ignore if body contains calls. |
2119 VisitAndSpill(node->body()); | 2118 Visit(node->body()); |
2120 | 2119 |
2121 if (node->next() == NULL) { | 2120 if (node->next() == NULL) { |
2122 // If there is no update statement and control flow can fall out | 2121 // If there is no update statement and control flow can fall out |
2123 // of the loop, jump directly to the continue label. | 2122 // of the loop, jump directly to the continue label. |
2124 if (has_valid_frame()) { | 2123 if (has_valid_frame()) { |
2125 node->continue_target()->Jump(); | 2124 node->continue_target()->Jump(); |
2126 } | 2125 } |
2127 } else { | 2126 } else { |
2128 // If there is an update statement and control flow can reach it | 2127 // If there is an update statement and control flow can reach it |
2129 // via falling out of the body of the loop or continuing, we | 2128 // via falling out of the body of the loop or continuing, we |
2130 // compile the update statement. | 2129 // compile the update statement. |
2131 if (node->continue_target()->is_linked()) { | 2130 if (node->continue_target()->is_linked()) { |
2132 node->continue_target()->Bind(); | 2131 node->continue_target()->Bind(); |
2133 } | 2132 } |
2134 if (has_valid_frame()) { | 2133 if (has_valid_frame()) { |
2135 // Record source position of the statement as this code which is | 2134 // Record source position of the statement as this code which is |
2136 // after the code for the body actually belongs to the loop | 2135 // after the code for the body actually belongs to the loop |
2137 // statement and not the body. | 2136 // statement and not the body. |
2138 CodeForStatementPosition(node); | 2137 CodeForStatementPosition(node); |
2139 VisitAndSpill(node->next()); | 2138 Visit(node->next()); |
2140 loop.Jump(); | 2139 loop.Jump(); |
2141 } | 2140 } |
2142 } | 2141 } |
2143 } | 2142 } |
2144 if (node->break_target()->is_linked()) { | 2143 if (node->break_target()->is_linked()) { |
2145 node->break_target()->Bind(); | 2144 node->break_target()->Bind(); |
2146 } | 2145 } |
2147 DecrementLoopNesting(); | 2146 DecrementLoopNesting(); |
2148 ASSERT(!has_valid_frame() || frame_->height() == original_height); | 2147 ASSERT(!has_valid_frame() || frame_->height() == original_height); |
2149 } | 2148 } |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2350 // If the reference was to a slot we rely on the convenient property | 2349 // If the reference was to a slot we rely on the convenient property |
2351 // that it doesn't matter whether a value (eg, r3 pushed above) is | 2350 // that it doesn't matter whether a value (eg, r3 pushed above) is |
2352 // right on top of or right underneath a zero-sized reference. | 2351 // right on top of or right underneath a zero-sized reference. |
2353 each.SetValue(NOT_CONST_INIT); | 2352 each.SetValue(NOT_CONST_INIT); |
2354 frame_->Drop(); | 2353 frame_->Drop(); |
2355 } | 2354 } |
2356 } | 2355 } |
2357 } | 2356 } |
2358 // Body. | 2357 // Body. |
2359 CheckStack(); // TODO(1222600): ignore if body contains calls. | 2358 CheckStack(); // TODO(1222600): ignore if body contains calls. |
2360 VisitAndSpill(node->body()); | 2359 Visit(node->body()); |
2361 | 2360 |
2362 // Next. Reestablish a spilled frame in case we are coming here via | 2361 // Next. Reestablish a spilled frame in case we are coming here via |
2363 // a continue in the body. | 2362 // a continue in the body. |
2364 node->continue_target()->Bind(); | 2363 node->continue_target()->Bind(); |
2365 frame_->SpillAll(); | 2364 frame_->SpillAll(); |
2366 frame_->EmitPop(r0); | 2365 frame_->EmitPop(r0); |
2367 __ add(r0, r0, Operand(Smi::FromInt(1))); | 2366 __ add(r0, r0, Operand(Smi::FromInt(1))); |
2368 frame_->EmitPush(r0); | 2367 frame_->EmitPush(r0); |
2369 entry.Jump(); | 2368 entry.Jump(); |
2370 | 2369 |
(...skipping 26 matching lines...) Expand all Loading... |
2397 frame_->EmitPush(r0); | 2396 frame_->EmitPush(r0); |
2398 | 2397 |
2399 // Store the caught exception in the catch variable. | 2398 // Store the caught exception in the catch variable. |
2400 Variable* catch_var = node->catch_var()->var(); | 2399 Variable* catch_var = node->catch_var()->var(); |
2401 ASSERT(catch_var != NULL && catch_var->slot() != NULL); | 2400 ASSERT(catch_var != NULL && catch_var->slot() != NULL); |
2402 StoreToSlot(catch_var->slot(), NOT_CONST_INIT); | 2401 StoreToSlot(catch_var->slot(), NOT_CONST_INIT); |
2403 | 2402 |
2404 // Remove the exception from the stack. | 2403 // Remove the exception from the stack. |
2405 frame_->Drop(); | 2404 frame_->Drop(); |
2406 | 2405 |
2407 VisitStatementsAndSpill(node->catch_block()->statements()); | 2406 VisitStatements(node->catch_block()->statements()); |
2408 if (frame_ != NULL) { | 2407 if (frame_ != NULL) { |
2409 exit.Jump(); | 2408 exit.Jump(); |
2410 } | 2409 } |
2411 | 2410 |
2412 | 2411 |
2413 // --- Try block --- | 2412 // --- Try block --- |
2414 try_block.Bind(); | 2413 try_block.Bind(); |
2415 | 2414 |
2416 frame_->PushTryHandler(TRY_CATCH_HANDLER); | 2415 frame_->PushTryHandler(TRY_CATCH_HANDLER); |
2417 int handler_height = frame_->height(); | 2416 int handler_height = frame_->height(); |
(...skipping 14 matching lines...) Expand all Loading... |
2432 bool function_return_was_shadowed = function_return_is_shadowed_; | 2431 bool function_return_was_shadowed = function_return_is_shadowed_; |
2433 function_return_is_shadowed_ = true; | 2432 function_return_is_shadowed_ = true; |
2434 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_); | 2433 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_); |
2435 | 2434 |
2436 // Add the remaining shadow targets. | 2435 // Add the remaining shadow targets. |
2437 for (int i = 0; i < nof_escapes; i++) { | 2436 for (int i = 0; i < nof_escapes; i++) { |
2438 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2437 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
2439 } | 2438 } |
2440 | 2439 |
2441 // Generate code for the statements in the try block. | 2440 // Generate code for the statements in the try block. |
2442 VisitStatementsAndSpill(node->try_block()->statements()); | 2441 VisitStatements(node->try_block()->statements()); |
2443 | 2442 |
2444 // Stop the introduced shadowing and count the number of required unlinks. | 2443 // Stop the introduced shadowing and count the number of required unlinks. |
2445 // After shadowing stops, the original labels are unshadowed and the | 2444 // After shadowing stops, the original labels are unshadowed and the |
2446 // LabelShadows represent the formerly shadowing labels. | 2445 // LabelShadows represent the formerly shadowing labels. |
2447 bool has_unlinks = false; | 2446 bool has_unlinks = false; |
2448 for (int i = 0; i < shadows.length(); i++) { | 2447 for (int i = 0; i < shadows.length(); i++) { |
2449 shadows[i]->StopShadowing(); | 2448 shadows[i]->StopShadowing(); |
2450 has_unlinks = has_unlinks || shadows[i]->is_linked(); | 2449 has_unlinks = has_unlinks || shadows[i]->is_linked(); |
2451 } | 2450 } |
2452 function_return_is_shadowed_ = function_return_was_shadowed; | 2451 function_return_is_shadowed_ = function_return_was_shadowed; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2546 bool function_return_was_shadowed = function_return_is_shadowed_; | 2545 bool function_return_was_shadowed = function_return_is_shadowed_; |
2547 function_return_is_shadowed_ = true; | 2546 function_return_is_shadowed_ = true; |
2548 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_); | 2547 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_); |
2549 | 2548 |
2550 // Add the remaining shadow targets. | 2549 // Add the remaining shadow targets. |
2551 for (int i = 0; i < nof_escapes; i++) { | 2550 for (int i = 0; i < nof_escapes; i++) { |
2552 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2551 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); |
2553 } | 2552 } |
2554 | 2553 |
2555 // Generate code for the statements in the try block. | 2554 // Generate code for the statements in the try block. |
2556 VisitStatementsAndSpill(node->try_block()->statements()); | 2555 VisitStatements(node->try_block()->statements()); |
2557 | 2556 |
2558 // Stop the introduced shadowing and count the number of required unlinks. | 2557 // Stop the introduced shadowing and count the number of required unlinks. |
2559 // After shadowing stops, the original labels are unshadowed and the | 2558 // After shadowing stops, the original labels are unshadowed and the |
2560 // LabelShadows represent the formerly shadowing labels. | 2559 // LabelShadows represent the formerly shadowing labels. |
2561 int nof_unlinks = 0; | 2560 int nof_unlinks = 0; |
2562 for (int i = 0; i < shadows.length(); i++) { | 2561 for (int i = 0; i < shadows.length(); i++) { |
2563 shadows[i]->StopShadowing(); | 2562 shadows[i]->StopShadowing(); |
2564 if (shadows[i]->is_linked()) nof_unlinks++; | 2563 if (shadows[i]->is_linked()) nof_unlinks++; |
2565 } | 2564 } |
2566 function_return_is_shadowed_ = function_return_was_shadowed; | 2565 function_return_is_shadowed_ = function_return_was_shadowed; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 // --- Finally block --- | 2635 // --- Finally block --- |
2637 finally_block.Bind(); | 2636 finally_block.Bind(); |
2638 | 2637 |
2639 // Push the state on the stack. | 2638 // Push the state on the stack. |
2640 frame_->EmitPush(r2); | 2639 frame_->EmitPush(r2); |
2641 | 2640 |
2642 // We keep two elements on the stack - the (possibly faked) result | 2641 // We keep two elements on the stack - the (possibly faked) result |
2643 // and the state - while evaluating the finally block. | 2642 // and the state - while evaluating the finally block. |
2644 // | 2643 // |
2645 // Generate code for the statements in the finally block. | 2644 // Generate code for the statements in the finally block. |
2646 VisitStatementsAndSpill(node->finally_block()->statements()); | 2645 VisitStatements(node->finally_block()->statements()); |
2647 | 2646 |
2648 if (has_valid_frame()) { | 2647 if (has_valid_frame()) { |
2649 // Restore state and return value or faked TOS. | 2648 // Restore state and return value or faked TOS. |
2650 frame_->EmitPop(r2); | 2649 frame_->EmitPop(r2); |
2651 frame_->EmitPop(r0); | 2650 frame_->EmitPop(r0); |
2652 } | 2651 } |
2653 | 2652 |
2654 // Generate code to jump to the right destination for all used | 2653 // Generate code to jump to the right destination for all used |
2655 // formerly shadowing targets. Deallocate each shadow target. | 2654 // formerly shadowing targets. Deallocate each shadow target. |
2656 for (int i = 0; i < shadows.length(); i++) { | 2655 for (int i = 0; i < shadows.length(); i++) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2751 | 2750 |
2752 | 2751 |
2753 void CodeGenerator::VisitConditional(Conditional* node) { | 2752 void CodeGenerator::VisitConditional(Conditional* node) { |
2754 #ifdef DEBUG | 2753 #ifdef DEBUG |
2755 int original_height = frame_->height(); | 2754 int original_height = frame_->height(); |
2756 #endif | 2755 #endif |
2757 VirtualFrame::SpilledScope spilled_scope(frame_); | 2756 VirtualFrame::SpilledScope spilled_scope(frame_); |
2758 Comment cmnt(masm_, "[ Conditional"); | 2757 Comment cmnt(masm_, "[ Conditional"); |
2759 JumpTarget then; | 2758 JumpTarget then; |
2760 JumpTarget else_; | 2759 JumpTarget else_; |
2761 LoadConditionAndSpill(node->condition(), &then, &else_, true); | 2760 LoadCondition(node->condition(), &then, &else_, true); |
2762 if (has_valid_frame()) { | 2761 if (has_valid_frame()) { |
2763 Branch(false, &else_); | 2762 Branch(false, &else_); |
2764 } | 2763 } |
2765 if (has_valid_frame() || then.is_linked()) { | 2764 if (has_valid_frame() || then.is_linked()) { |
2766 then.Bind(); | 2765 then.Bind(); |
2767 Load(node->then_expression()); | 2766 Load(node->then_expression()); |
2768 } | 2767 } |
2769 if (else_.is_linked()) { | 2768 if (else_.is_linked()) { |
2770 JumpTarget exit; | 2769 JumpTarget exit; |
2771 if (has_valid_frame()) exit.Jump(); | 2770 if (has_valid_frame()) exit.Jump(); |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4049 } | 4048 } |
4050 | 4049 |
4051 | 4050 |
4052 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) { | 4051 void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) { |
4053 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc. | 4052 // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc. |
4054 ASSERT_EQ(args->length(), 3); | 4053 ASSERT_EQ(args->length(), 3); |
4055 #ifdef ENABLE_LOGGING_AND_PROFILING | 4054 #ifdef ENABLE_LOGGING_AND_PROFILING |
4056 if (ShouldGenerateLog(args->at(0))) { | 4055 if (ShouldGenerateLog(args->at(0))) { |
4057 Load(args->at(1)); | 4056 Load(args->at(1)); |
4058 Load(args->at(2)); | 4057 Load(args->at(2)); |
4059 frame_->SpillAll(); | |
4060 frame_->CallRuntime(Runtime::kLog, 2); | 4058 frame_->CallRuntime(Runtime::kLog, 2); |
4061 } | 4059 } |
4062 #endif | 4060 #endif |
4063 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); | 4061 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); |
4064 } | 4062 } |
4065 | 4063 |
4066 | 4064 |
4067 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { | 4065 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
4068 ASSERT(args->length() == 1); | 4066 ASSERT(args->length() == 1); |
4069 Load(args->at(0)); | 4067 Load(args->at(0)); |
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4947 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { | 4945 void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { |
4948 #ifdef DEBUG | 4946 #ifdef DEBUG |
4949 int original_height = frame_->height(); | 4947 int original_height = frame_->height(); |
4950 #endif | 4948 #endif |
4951 VirtualFrame::SpilledScope spilled_scope(frame_); | 4949 VirtualFrame::SpilledScope spilled_scope(frame_); |
4952 Comment cmnt(masm_, "[ UnaryOperation"); | 4950 Comment cmnt(masm_, "[ UnaryOperation"); |
4953 | 4951 |
4954 Token::Value op = node->op(); | 4952 Token::Value op = node->op(); |
4955 | 4953 |
4956 if (op == Token::NOT) { | 4954 if (op == Token::NOT) { |
4957 LoadConditionAndSpill(node->expression(), | 4955 LoadCondition(node->expression(), false_target(), true_target(), true); |
4958 false_target(), | |
4959 true_target(), | |
4960 true); | |
4961 // LoadCondition may (and usually does) leave a test and branch to | 4956 // LoadCondition may (and usually does) leave a test and branch to |
4962 // be emitted by the caller. In that case, negate the condition. | 4957 // be emitted by the caller. In that case, negate the condition. |
4963 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); | 4958 if (has_cc()) cc_reg_ = NegateCondition(cc_reg_); |
4964 | 4959 |
4965 } else if (op == Token::DELETE) { | 4960 } else if (op == Token::DELETE) { |
4966 Property* property = node->expression()->AsProperty(); | 4961 Property* property = node->expression()->AsProperty(); |
4967 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); | 4962 Variable* variable = node->expression()->AsVariableProxy()->AsVariable(); |
4968 if (property != NULL) { | 4963 if (property != NULL) { |
4969 Load(property->obj()); | 4964 Load(property->obj()); |
4970 Load(property->key()); | 4965 Load(property->key()); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5193 | 5188 |
5194 // NOTE: If the left hand side produces a materialized value (not in | 5189 // NOTE: If the left hand side produces a materialized value (not in |
5195 // the CC register), we force the right hand side to do the | 5190 // the CC register), we force the right hand side to do the |
5196 // same. This is necessary because we may have to branch to the exit | 5191 // same. This is necessary because we may have to branch to the exit |
5197 // after evaluating the left hand side (due to the shortcut | 5192 // after evaluating the left hand side (due to the shortcut |
5198 // semantics), but the compiler must (statically) know if the result | 5193 // semantics), but the compiler must (statically) know if the result |
5199 // of compiling the binary operation is materialized or not. | 5194 // of compiling the binary operation is materialized or not. |
5200 VirtualFrame::SpilledScope spilled_scope(frame_); | 5195 VirtualFrame::SpilledScope spilled_scope(frame_); |
5201 if (node->op() == Token::AND) { | 5196 if (node->op() == Token::AND) { |
5202 JumpTarget is_true; | 5197 JumpTarget is_true; |
5203 LoadConditionAndSpill(node->left(), | 5198 LoadCondition(node->left(), &is_true, false_target(), false); |
5204 &is_true, | |
5205 false_target(), | |
5206 false); | |
5207 if (has_valid_frame() && !has_cc()) { | 5199 if (has_valid_frame() && !has_cc()) { |
5208 // The left-hand side result is on top of the virtual frame. | 5200 // The left-hand side result is on top of the virtual frame. |
5209 JumpTarget pop_and_continue; | 5201 JumpTarget pop_and_continue; |
5210 JumpTarget exit; | 5202 JumpTarget exit; |
5211 | 5203 |
5212 frame_->Dup(); | 5204 frame_->Dup(); |
5213 // Avoid popping the result if it converts to 'false' using the | 5205 // Avoid popping the result if it converts to 'false' using the |
5214 // standard ToBoolean() conversion as described in ECMA-262, | 5206 // standard ToBoolean() conversion as described in ECMA-262, |
5215 // section 9.2, page 30. | 5207 // section 9.2, page 30. |
5216 ToBoolean(&pop_and_continue, &exit); | 5208 ToBoolean(&pop_and_continue, &exit); |
(...skipping 10 matching lines...) Expand all Loading... |
5227 // Exit (always with a materialized value). | 5219 // Exit (always with a materialized value). |
5228 exit.Bind(); | 5220 exit.Bind(); |
5229 } else if (has_cc() || is_true.is_linked()) { | 5221 } else if (has_cc() || is_true.is_linked()) { |
5230 // The left-hand side is either (a) partially compiled to | 5222 // The left-hand side is either (a) partially compiled to |
5231 // control flow with a final branch left to emit or (b) fully | 5223 // control flow with a final branch left to emit or (b) fully |
5232 // compiled to control flow and possibly true. | 5224 // compiled to control flow and possibly true. |
5233 if (has_cc()) { | 5225 if (has_cc()) { |
5234 Branch(false, false_target()); | 5226 Branch(false, false_target()); |
5235 } | 5227 } |
5236 is_true.Bind(); | 5228 is_true.Bind(); |
5237 LoadConditionAndSpill(node->right(), | 5229 LoadCondition(node->right(), true_target(), false_target(), false); |
5238 true_target(), | |
5239 false_target(), | |
5240 false); | |
5241 } else { | 5230 } else { |
5242 // Nothing to do. | 5231 // Nothing to do. |
5243 ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); | 5232 ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked()); |
5244 } | 5233 } |
5245 | 5234 |
5246 } else { | 5235 } else { |
5247 ASSERT(node->op() == Token::OR); | 5236 ASSERT(node->op() == Token::OR); |
5248 JumpTarget is_false; | 5237 JumpTarget is_false; |
5249 LoadConditionAndSpill(node->left(), | 5238 LoadCondition(node->left(), true_target(), &is_false, false); |
5250 true_target(), | |
5251 &is_false, | |
5252 false); | |
5253 if (has_valid_frame() && !has_cc()) { | 5239 if (has_valid_frame() && !has_cc()) { |
5254 // The left-hand side result is on top of the virtual frame. | 5240 // The left-hand side result is on top of the virtual frame. |
5255 JumpTarget pop_and_continue; | 5241 JumpTarget pop_and_continue; |
5256 JumpTarget exit; | 5242 JumpTarget exit; |
5257 | 5243 |
5258 frame_->Dup(); | 5244 frame_->Dup(); |
5259 // Avoid popping the result if it converts to 'true' using the | 5245 // Avoid popping the result if it converts to 'true' using the |
5260 // standard ToBoolean() conversion as described in ECMA-262, | 5246 // standard ToBoolean() conversion as described in ECMA-262, |
5261 // section 9.2, page 30. | 5247 // section 9.2, page 30. |
5262 ToBoolean(&exit, &pop_and_continue); | 5248 ToBoolean(&exit, &pop_and_continue); |
(...skipping 10 matching lines...) Expand all Loading... |
5273 // Exit (always with a materialized value). | 5259 // Exit (always with a materialized value). |
5274 exit.Bind(); | 5260 exit.Bind(); |
5275 } else if (has_cc() || is_false.is_linked()) { | 5261 } else if (has_cc() || is_false.is_linked()) { |
5276 // The left-hand side is either (a) partially compiled to | 5262 // The left-hand side is either (a) partially compiled to |
5277 // control flow with a final branch left to emit or (b) fully | 5263 // control flow with a final branch left to emit or (b) fully |
5278 // compiled to control flow and possibly false. | 5264 // compiled to control flow and possibly false. |
5279 if (has_cc()) { | 5265 if (has_cc()) { |
5280 Branch(true, true_target()); | 5266 Branch(true, true_target()); |
5281 } | 5267 } |
5282 is_false.Bind(); | 5268 is_false.Bind(); |
5283 LoadConditionAndSpill(node->right(), | 5269 LoadCondition(node->right(), true_target(), false_target(), false); |
5284 true_target(), | |
5285 false_target(), | |
5286 false); | |
5287 } else { | 5270 } else { |
5288 // Nothing to do. | 5271 // Nothing to do. |
5289 ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); | 5272 ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked()); |
5290 } | 5273 } |
5291 } | 5274 } |
5292 } | 5275 } |
5293 | 5276 |
5294 | 5277 |
5295 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { | 5278 void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) { |
5296 #ifdef DEBUG | 5279 #ifdef DEBUG |
(...skipping 4986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10283 __ bind(&string_add_runtime); | 10266 __ bind(&string_add_runtime); |
10284 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 10267 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
10285 } | 10268 } |
10286 | 10269 |
10287 | 10270 |
10288 #undef __ | 10271 #undef __ |
10289 | 10272 |
10290 } } // namespace v8::internal | 10273 } } // namespace v8::internal |
10291 | 10274 |
10292 #endif // V8_TARGET_ARCH_ARM | 10275 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |