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

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

Issue 2414001: ARM: Remove LoadConditionAndSpill and VisitAndSpill. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 6 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 | « src/arm/codegen-arm.h ('k') | src/arm/codegen-arm-inl.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 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/codegen-arm-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698