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

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

Issue 13246: Experimental: more code generator changes.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 years 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/codegen-ia32.h ('k') | src/jump-target-ia32.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 allocator_(NULL), 83 allocator_(NULL),
84 cc_reg_(no_condition), 84 cc_reg_(no_condition),
85 state_(NULL), 85 state_(NULL),
86 is_inside_try_(false), 86 is_inside_try_(false),
87 break_stack_height_(0), 87 break_stack_height_(0),
88 loop_nesting_(0), 88 loop_nesting_(0),
89 function_return_is_shadowed_(false) { 89 function_return_is_shadowed_(false) {
90 } 90 }
91 91
92 92
93 void CodeGenerator::SetFrame(VirtualFrame* frame) {
94 if (frame_ != NULL) {
95 frame_->DetachFromCodeGenerator();
96 }
97 if (frame != NULL) {
98 frame->AttachToCodeGenerator();
99 }
100 frame_ = frame;
101 }
102
103
104 void CodeGenerator::DeleteFrame() {
105 if (frame_ != NULL) {
106 frame_->DetachFromCodeGenerator();
107 delete frame_;
108 frame_ = NULL;
109 }
110 }
111
112
93 // Calling conventions: 113 // Calling conventions:
94 // ebp: frame pointer 114 // ebp: frame pointer
95 // esp: stack pointer 115 // esp: stack pointer
96 // edi: caller's parameter pointer 116 // edi: caller's parameter pointer
97 // esi: callee's context 117 // esi: callee's context
98 118
99 void CodeGenerator::GenCode(FunctionLiteral* fun) { 119 void CodeGenerator::GenCode(FunctionLiteral* fun) {
100 // Record the position for debugging purposes. 120 // Record the position for debugging purposes.
101 __ RecordPosition(fun->start_position()); 121 __ RecordPosition(fun->start_position());
102 122
103 ZoneList<Statement*>* body = fun->body(); 123 ZoneList<Statement*>* body = fun->body();
104 124
105 // Initialize state. 125 // Initialize state.
106 ASSERT(scope_ == NULL); 126 ASSERT(scope_ == NULL);
107 scope_ = fun->scope(); 127 scope_ = fun->scope();
108 ASSERT(frame_ == NULL);
109 set_frame(new VirtualFrame(this));
110 ASSERT(allocator_ == NULL); 128 ASSERT(allocator_ == NULL);
111 RegisterAllocator register_allocator(this); 129 RegisterAllocator register_allocator(this);
112 allocator_ = &register_allocator; 130 allocator_ = &register_allocator;
131 ASSERT(frame_ == NULL);
132 SetFrame(new VirtualFrame(this));
113 cc_reg_ = no_condition; 133 cc_reg_ = no_condition;
114 function_return_.set_code_generator(this); 134 function_return_.set_code_generator(this);
115 function_return_is_shadowed_ = false; 135 function_return_is_shadowed_ = false;
116 136
117 // Adjust for function-level loop nesting. 137 // Adjust for function-level loop nesting.
118 loop_nesting_ += fun->loop_nesting(); 138 loop_nesting_ += fun->loop_nesting();
119 139
120 { 140 {
121 CodeGenState state(this); 141 CodeGenState state(this);
122 142
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 loop_nesting_ -= fun->loop_nesting(); 301 loop_nesting_ -= fun->loop_nesting();
282 302
283 // Code generation state must be reset. 303 // Code generation state must be reset.
284 ASSERT(state_ == NULL); 304 ASSERT(state_ == NULL);
285 ASSERT(loop_nesting() == 0); 305 ASSERT(loop_nesting() == 0);
286 ASSERT(!function_return_is_shadowed_); 306 ASSERT(!function_return_is_shadowed_);
287 function_return_.Unuse(); 307 function_return_.Unuse();
288 ASSERT(!has_cc()); 308 ASSERT(!has_cc());
289 // There is no need to delete the register allocator, it is a 309 // There is no need to delete the register allocator, it is a
290 // stack-allocated local. 310 // stack-allocated local.
311 DeleteFrame();
291 allocator_ = NULL; 312 allocator_ = NULL;
292 delete_frame();
293 scope_ = NULL; 313 scope_ = NULL;
294 } 314 }
295 315
296 316
297 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) { 317 Operand CodeGenerator::SlotOperand(Slot* slot, Register tmp) {
298 // Currently, this assertion will fail if we try to assign to 318 // Currently, this assertion will fail if we try to assign to
299 // a constant variable that is constant because it is read-only 319 // a constant variable that is constant because it is read-only
300 // (such as the variable referring to a named function expression). 320 // (such as the variable referring to a named function expression).
301 // We need to implement assignments to read-only variables. 321 // We need to implement assignments to read-only variables.
302 // Ideally, we should do this during AST generation (by converting 322 // Ideally, we should do this during AST generation (by converting
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 ref->set_type(Reference::NAMED); 510 ref->set_type(Reference::NAMED);
491 } else { 511 } else {
492 Load(property->key()); 512 Load(property->key());
493 frame_->SpillAll(); 513 frame_->SpillAll();
494 ref->set_type(Reference::KEYED); 514 ref->set_type(Reference::KEYED);
495 } 515 }
496 } else if (var != NULL) { 516 } else if (var != NULL) {
497 // The expression is a variable proxy that does not rewrite to a 517 // The expression is a variable proxy that does not rewrite to a
498 // property. Global variables are treated as named property references. 518 // property. Global variables are treated as named property references.
499 if (var->is_global()) { 519 if (var->is_global()) {
520 frame_->SpillAll();
500 LoadGlobal(); 521 LoadGlobal();
501 ref->set_type(Reference::NAMED); 522 ref->set_type(Reference::NAMED);
502 } else { 523 } else {
503 ASSERT(var->slot() != NULL); 524 ASSERT(var->slot() != NULL);
504 ref->set_type(Reference::SLOT); 525 ref->set_type(Reference::SLOT);
505 } 526 }
506 } else { 527 } else {
507 // Anything else is a runtime error. 528 // Anything else is a runtime error.
508 Load(e); 529 Load(e);
509 frame_->SpillAll(); 530 frame_->SpillAll();
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 1275
1255 1276
1256 void CodeGenerator::CheckStack() { 1277 void CodeGenerator::CheckStack() {
1257 if (FLAG_check_stack) { 1278 if (FLAG_check_stack) {
1258 JumpTarget stack_is_ok(this); 1279 JumpTarget stack_is_ok(this);
1259 StackCheckStub stub; 1280 StackCheckStub stub;
1260 ExternalReference stack_guard_limit = 1281 ExternalReference stack_guard_limit =
1261 ExternalReference::address_of_stack_guard_limit(); 1282 ExternalReference::address_of_stack_guard_limit();
1262 __ cmp(esp, Operand::StaticVariable(stack_guard_limit)); 1283 __ cmp(esp, Operand::StaticVariable(stack_guard_limit));
1263 stack_is_ok.Branch(above_equal, taken); 1284 stack_is_ok.Branch(above_equal, taken);
1285 // The stack check can trigger the debugger. Before calling it, all
1286 // values including constants must be spilled to the frame.
1287 frame_->SpillAll();
1264 frame_->CallStub(&stub, 0); 1288 frame_->CallStub(&stub, 0);
1265 stack_is_ok.Bind(); 1289 stack_is_ok.Bind();
1266 } 1290 }
1267 } 1291 }
1268 1292
1269 1293
1270 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1294 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1271 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 1295 for (int i = 0; frame_ != NULL && i < statements->length(); i++) {
1272 Visit(statements->at(i)); 1296 Visit(statements->at(i));
1273 } 1297 }
1274 } 1298 }
1275 1299
1276 1300
1277 void CodeGenerator::VisitBlock(Block* node) { 1301 void CodeGenerator::VisitBlock(Block* node) {
1278 frame_->SpillAll();
1279 Comment cmnt(masm_, "[ Block"); 1302 Comment cmnt(masm_, "[ Block");
1280 RecordStatementPosition(node); 1303 RecordStatementPosition(node);
1281 node->set_break_stack_height(break_stack_height_); 1304 node->set_break_stack_height(break_stack_height_);
1282 node->break_target()->set_code_generator(this); 1305 node->break_target()->set_code_generator(this);
1283 VisitStatements(node->statements()); 1306 VisitStatements(node->statements());
1284 if (node->break_target()->is_linked()) { 1307 if (node->break_target()->is_linked()) {
1285 node->break_target()->Bind(); 1308 node->break_target()->Bind();
1286 } 1309 }
1287 } 1310 }
1288 1311
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 1386
1364 1387
1365 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1388 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1366 Comment cmnt(masm_, "[ ExpressionStatement"); 1389 Comment cmnt(masm_, "[ ExpressionStatement");
1367 RecordStatementPosition(node); 1390 RecordStatementPosition(node);
1368 Expression* expression = node->expression(); 1391 Expression* expression = node->expression();
1369 expression->MarkAsStatement(); 1392 expression->MarkAsStatement();
1370 Load(expression); 1393 Load(expression);
1371 // Remove the lingering expression result from the top of stack. 1394 // Remove the lingering expression result from the top of stack.
1372 frame_->Drop(); 1395 frame_->Drop();
1373 // Rather than using SpillAll after all recursive calls to Visit over
1374 // statements, we spill here in the only statement type that uses the
1375 // virtual frame. This is temporary.
1376 frame_->SpillAll();
1377 } 1396 }
1378 1397
1379 1398
1380 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1399 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1381 frame_->SpillAll(); 1400 frame_->SpillAll();
1382 Comment cmnt(masm_, "// EmptyStatement"); 1401 Comment cmnt(masm_, "// EmptyStatement");
1383 // nothing to do 1402 // nothing to do
1384 } 1403 }
1385 1404
1386 1405
(...skipping 22 matching lines...) Expand all
1409 // If control flow can reach the then part via fall-through from the 1428 // If control flow can reach the then part via fall-through from the
1410 // test or a branch to the target, compile it. 1429 // test or a branch to the target, compile it.
1411 then.Bind(); 1430 then.Bind();
1412 Visit(node->then_statement()); 1431 Visit(node->then_statement());
1413 } 1432 }
1414 if (frame_ != NULL) { 1433 if (frame_ != NULL) {
1415 // A NULL frame here indicates that control did not fall out of the 1434 // A NULL frame here indicates that control did not fall out of the
1416 // then statement, it escaped on all branches. In that case, a jump 1435 // then statement, it escaped on all branches. In that case, a jump
1417 // to the exit label would be dead code (and impossible, because we 1436 // to the exit label would be dead code (and impossible, because we
1418 // don't have a current virtual frame to set at the exit label). 1437 // don't have a current virtual frame to set at the exit label).
1438 frame_->SpillAll();
1419 exit.Jump(); 1439 exit.Jump();
1420 } 1440 }
1421 // else 1441 // else
1422 if (else_.is_linked()) { 1442 if (else_.is_linked()) {
1423 // Control flow for if-then-else does not fall-through to the else 1443 // Control flow for if-then-else does not fall-through to the else
1424 // part, it can only reach here via jump if at all. 1444 // part, it can only reach here via jump if at all.
1425 else_.Bind(); 1445 else_.Bind();
1426 Visit(node->else_statement()); 1446 Visit(node->else_statement());
1427 } 1447 }
1428 1448
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 } 1545 }
1526 1546
1527 // Add a label for checking the size of the code used for returning. 1547 // Add a label for checking the size of the code used for returning.
1528 Label check_exit_codesize; 1548 Label check_exit_codesize;
1529 __ bind(&check_exit_codesize); 1549 __ bind(&check_exit_codesize);
1530 1550
1531 // Leave the frame and return popping the arguments and the 1551 // Leave the frame and return popping the arguments and the
1532 // receiver. 1552 // receiver.
1533 frame_->Exit(); 1553 frame_->Exit();
1534 __ ret((scope_->num_parameters() + 1) * kPointerSize); 1554 __ ret((scope_->num_parameters() + 1) * kPointerSize);
1535 delete_frame(); 1555 DeleteFrame();
1536 1556
1537 // Check that the size of the code used for returning matches what is 1557 // Check that the size of the code used for returning matches what is
1538 // expected by the debugger. 1558 // expected by the debugger.
1539 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, 1559 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength,
1540 __ SizeOfCodeGeneratedSince(&check_exit_codesize)); 1560 __ SizeOfCodeGeneratedSince(&check_exit_codesize));
1541 } 1561 }
1542 } 1562 }
1543 1563
1544 1564
1545 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1565 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 default_exit.Bind(); 1722 default_exit.Bind();
1703 } else { 1723 } else {
1704 fall_through.Bind(); 1724 fall_through.Bind();
1705 fall_through.Unuse(); 1725 fall_through.Unuse();
1706 } 1726 }
1707 VisitStatements(clause->statements()); 1727 VisitStatements(clause->statements());
1708 1728
1709 // If control flow can fall through from the body, jump to the next body 1729 // If control flow can fall through from the body, jump to the next body
1710 // or the end of the statement. 1730 // or the end of the statement.
1711 if (frame_ != NULL) { 1731 if (frame_ != NULL) {
1732 frame_->SpillAll();
1712 if (i < length - 1 && cases->at(i + 1)->is_default()) { 1733 if (i < length - 1 && cases->at(i + 1)->is_default()) {
1713 default_entry.Jump(); 1734 default_entry.Jump();
1714 } else { 1735 } else {
1715 fall_through.Jump(); 1736 fall_through.Jump();
1716 } 1737 }
1717 } 1738 }
1718 } 1739 }
1719 1740
1720 // The final "test" removes the switch value. 1741 // The final "test" removes the switch value.
1721 next_test.Bind(); 1742 next_test.Bind();
1722 frame_->Drop(); 1743 frame_->Drop();
1723 1744
1724 // If there is a default clause, compile it. 1745 // If there is a default clause, compile it.
1725 if (default_clause != NULL) { 1746 if (default_clause != NULL) {
1726 Comment cmnt(masm_, "[ Default clause"); 1747 Comment cmnt(masm_, "[ Default clause");
1727 default_entry.Bind(); 1748 default_entry.Bind();
1728 VisitStatements(default_clause->statements()); 1749 VisitStatements(default_clause->statements());
1750 if (frame_ != NULL) {
1751 frame_->SpillAll();
1752 }
1729 // If control flow can fall out of the default and there is a case after 1753 // If control flow can fall out of the default and there is a case after
1730 // it, jump to that case's body. 1754 // it, jump to that case's body.
1731 if (frame_ != NULL && default_exit.is_bound()) { 1755 if (frame_ != NULL && default_exit.is_bound()) {
1732 default_exit.Jump(); 1756 default_exit.Jump();
1733 } 1757 }
1734 } 1758 }
1735 1759
1736 if (fall_through.is_linked()) { 1760 if (fall_through.is_linked()) {
1737 fall_through.Bind(); 1761 fall_through.Bind();
1738 } 1762 }
1739 1763
1740 if (node->break_target()->is_linked()) { 1764 if (node->break_target()->is_linked()) {
1741 node->break_target()->Bind(); 1765 node->break_target()->Bind();
1742 } 1766 }
1743 } 1767 }
1744 1768
1745 1769
1746 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1770 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1747 frame_->SpillAll();
1748 Comment cmnt(masm_, "[ LoopStatement"); 1771 Comment cmnt(masm_, "[ LoopStatement");
1749 RecordStatementPosition(node); 1772 RecordStatementPosition(node);
1750 node->set_break_stack_height(break_stack_height_); 1773 node->set_break_stack_height(break_stack_height_);
1751 node->break_target()->set_code_generator(this); 1774 node->break_target()->set_code_generator(this);
1752 node->continue_target()->set_code_generator(this); 1775 node->continue_target()->set_code_generator(this);
1753 1776
1754 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1777 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1755 // known result for the test expression, with no side effects. 1778 // known result for the test expression, with no side effects.
1756 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1779 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1757 if (node->cond() == NULL) { 1780 if (node->cond() == NULL) {
1758 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1781 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1759 info = ALWAYS_TRUE; 1782 info = ALWAYS_TRUE;
1760 } else { 1783 } else {
1761 Literal* lit = node->cond()->AsLiteral(); 1784 Literal* lit = node->cond()->AsLiteral();
1762 if (lit != NULL) { 1785 if (lit != NULL) {
1763 if (lit->IsTrue()) { 1786 if (lit->IsTrue()) {
1764 info = ALWAYS_TRUE; 1787 info = ALWAYS_TRUE;
1765 } else if (lit->IsFalse()) { 1788 } else if (lit->IsFalse()) {
1766 info = ALWAYS_FALSE; 1789 info = ALWAYS_FALSE;
1767 } 1790 }
1768 } 1791 }
1769 } 1792 }
1770 1793
1771 switch (node->type()) { 1794 switch (node->type()) {
1772 case LoopStatement::DO_LOOP: { 1795 case LoopStatement::DO_LOOP: {
1796 // The new code generator does not yet compile do loops.
1797 frame_->SpillAll();
1773 JumpTarget body(this); 1798 JumpTarget body(this);
1774 IncrementLoopNesting(); 1799 IncrementLoopNesting();
1775 // Label the body. 1800 // Label the body.
1776 if (info == ALWAYS_TRUE) { 1801 if (info == ALWAYS_TRUE) {
1777 node->continue_target()->Bind(); 1802 node->continue_target()->Bind();
1778 } else if (info == ALWAYS_FALSE) { 1803 } else if (info == ALWAYS_FALSE) {
1779 // There is no need, we will never jump back. 1804 // There is no need, we will never jump back.
1780 } else { 1805 } else {
1781 ASSERT(info == DONT_KNOW); 1806 ASSERT(info == DONT_KNOW);
1782 body.Bind(); 1807 body.Bind();
1783 } 1808 }
1784 CheckStack(); // TODO(1222600): ignore if body contains calls. 1809 CheckStack(); // TODO(1222600): ignore if body contains calls.
1785 Visit(node->body()); 1810 Visit(node->body());
1811 if (frame_ != NULL) {
1812 frame_->SpillAll();
1813 }
1786 1814
1787 // Compile the "test". 1815 // Compile the "test".
1788 if (info == ALWAYS_TRUE) { 1816 if (info == ALWAYS_TRUE) {
1789 if (frame_ != NULL) { 1817 if (frame_ != NULL) {
1790 // If control flow can fall off the end of the body, jump back to 1818 // If control flow can fall off the end of the body, jump back to
1791 // the top. 1819 // the top.
1792 node->continue_target()->Jump(); 1820 node->continue_target()->Jump();
1793 } 1821 }
1794 } else if (info == ALWAYS_FALSE) { 1822 } else if (info == ALWAYS_FALSE) {
1795 // If we have a continue in the body, we only have to bind its jump 1823 // If we have a continue in the body, we only have to bind its jump
(...skipping 13 matching lines...) Expand all
1809 // A NULL frame here indicates that control flow did not fall 1837 // A NULL frame here indicates that control flow did not fall
1810 // out of the test expression. 1838 // out of the test expression.
1811 Branch(true, &body); 1839 Branch(true, &body);
1812 } 1840 }
1813 } 1841 }
1814 } 1842 }
1815 break; 1843 break;
1816 } 1844 }
1817 1845
1818 case LoopStatement::WHILE_LOOP: { 1846 case LoopStatement::WHILE_LOOP: {
1847 // The new code generator does not yet compile while loops.
1848 frame_->SpillAll();
1819 JumpTarget body(this); 1849 JumpTarget body(this);
1820 IncrementLoopNesting(); 1850 IncrementLoopNesting();
1821 // Generate the loop header. 1851 // Generate the loop header.
1822 if (info == ALWAYS_TRUE) { 1852 if (info == ALWAYS_TRUE) {
1823 // Merely label the body with the continue target. 1853 // Merely label the body with the continue target.
1824 node->continue_target()->Bind(); 1854 node->continue_target()->Bind();
1825 } else if (info == ALWAYS_FALSE) { 1855 } else if (info == ALWAYS_FALSE) {
1826 // There is no need to even compile the test or body. 1856 // There is no need to even compile the test or body.
1827 break; 1857 break;
1828 } else { 1858 } else {
(...skipping 11 matching lines...) Expand all
1840 if (frame_ != NULL || body.is_linked()) { 1870 if (frame_ != NULL || body.is_linked()) {
1841 body.Bind(); 1871 body.Bind();
1842 } 1872 }
1843 } 1873 }
1844 if (frame_ != NULL) { 1874 if (frame_ != NULL) {
1845 CheckStack(); // TODO(1222600): ignore if body contains calls. 1875 CheckStack(); // TODO(1222600): ignore if body contains calls.
1846 Visit(node->body()); 1876 Visit(node->body());
1847 1877
1848 // If control flow can fall out of the body, jump back to the top. 1878 // If control flow can fall out of the body, jump back to the top.
1849 if (frame_ != NULL) { 1879 if (frame_ != NULL) {
1880 frame_->SpillAll();
1850 node->continue_target()->Jump(); 1881 node->continue_target()->Jump();
1851 } 1882 }
1852 } 1883 }
1853 break; 1884 break;
1854 } 1885 }
1855 1886
1856 case LoopStatement::FOR_LOOP: { 1887 case LoopStatement::FOR_LOOP: {
1857 JumpTarget loop(this); 1888 JumpTarget loop(this);
1858 JumpTarget body(this); 1889 JumpTarget body(this);
1859 if (node->init() != NULL) { 1890 if (node->init() != NULL) {
1860 Visit(node->init()); 1891 Visit(node->init());
1861 } 1892 }
1862 1893
1863 IncrementLoopNesting(); 1894 IncrementLoopNesting();
1864 // There is no need to compile the test or body. 1895 // There is no need to compile the test or body.
1865 if (info == ALWAYS_FALSE) break; 1896 if (info == ALWAYS_FALSE) break;
1866 1897
1867 // If there is no update statement, label the top of the loop with the 1898 // Label the top of the loop for the backward CFG edge. If there is
1868 // continue target, otherwise with the loop target. 1899 // no update expression label it with the continue target, otherwise
1900 // with the loop target.
1869 if (node->next() == NULL) { 1901 if (node->next() == NULL) {
1870 node->continue_target()->Bind(); 1902 node->continue_target()->Bind();
1871 } else { 1903 } else {
1872 loop.Bind(); 1904 loop.Bind();
1873 } 1905 }
1874 1906
1875 // If the test is always true, there is no need to compile it. 1907 // If the test is always true, there is no need to compile it.
1876 if (info == DONT_KNOW) { 1908 if (info == DONT_KNOW) {
1877 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, 1909 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
1878 &body, node->break_target(), true); 1910 &body, node->break_target(), true);
1879 if (frame_ != NULL) { 1911 if (frame_ != NULL) {
1880 Branch(false, node->break_target()); 1912 Branch(false, node->break_target());
1881 } 1913 }
1882 if (frame_ != NULL || body.is_linked()) { 1914 if (frame_ != NULL || body.is_linked()) {
1883 body.Bind(); 1915 body.Bind();
1884 } 1916 }
1885 } 1917 }
1886 1918
1887 if (frame_ != NULL) { 1919 if (frame_ != NULL) {
1888 CheckStack(); // TODO(1222600): ignore if body contains calls. 1920 CheckStack(); // TODO(1222600): ignore if body contains calls.
1889 Visit(node->body()); 1921 Visit(node->body());
1890 1922
1891 if (node->next() == NULL) { 1923 if (node->next() == NULL) {
1892 // If there is no update statement and control flow can fall out 1924 // If there is no update statement and control flow can fall out
1893 // of the loop, jump directly to the continue label. 1925 // of the loop, jump to the continue label.
1894 if (frame_ != NULL) { 1926 if (frame_ != NULL) {
1895 node->continue_target()->Jump(); 1927 node->continue_target()->Jump();
1896 } 1928 }
1897 } else { 1929 } else {
1898 // If there is an update statement and control flow can reach it 1930 // If there is an update statement and control flow can reach it
1899 // via falling out of the body of the loop or continuing, we 1931 // via falling out of the body of the loop or continuing, we
1900 // compile the update statement. 1932 // compile the update statement.
1901 if (frame_ != NULL || node->continue_target()->is_linked()) { 1933 if (frame_ != NULL || node->continue_target()->is_linked()) {
1902 node->continue_target()->Bind(); 1934 node->continue_target()->Bind();
1903 // Record source position of the statement as this code which is 1935 // Record source position of the statement as this code which is
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 } 2114 }
2083 } 2115 }
2084 } 2116 }
2085 // Discard the i'th entry pushed above or else the remainder of the 2117 // Discard the i'th entry pushed above or else the remainder of the
2086 // reference, whichever is currently on top of the stack. 2118 // reference, whichever is currently on top of the stack.
2087 frame_->Drop(); 2119 frame_->Drop();
2088 2120
2089 // Body. 2121 // Body.
2090 CheckStack(); // TODO(1222600): ignore if body contains calls. 2122 CheckStack(); // TODO(1222600): ignore if body contains calls.
2091 Visit(node->body()); 2123 Visit(node->body());
2124 if (frame_ != NULL) {
2125 frame_->SpillAll();
2126 }
2092 2127
2093 // Next. 2128 // Next.
2094 node->continue_target()->Bind(); 2129 node->continue_target()->Bind();
2095 frame_->EmitPop(eax); 2130 frame_->EmitPop(eax);
2096 __ add(Operand(eax), Immediate(Smi::FromInt(1))); 2131 __ add(Operand(eax), Immediate(Smi::FromInt(1)));
2097 frame_->EmitPush(eax); 2132 frame_->EmitPush(eax);
2098 entry.Jump(); 2133 entry.Jump();
2099 2134
2100 // Cleanup. 2135 // Cleanup.
2101 cleanup.Bind(); 2136 cleanup.Bind();
(...skipping 25 matching lines...) Expand all
2127 // convenient property that it doesn't matter whether a value is 2162 // convenient property that it doesn't matter whether a value is
2128 // immediately on top of or underneath a zero-sized reference. 2163 // immediately on top of or underneath a zero-sized reference.
2129 ref.SetValue(NOT_CONST_INIT); 2164 ref.SetValue(NOT_CONST_INIT);
2130 } 2165 }
2131 2166
2132 // Remove the exception from the stack. 2167 // Remove the exception from the stack.
2133 frame_->Drop(); 2168 frame_->Drop();
2134 2169
2135 VisitStatements(node->catch_block()->statements()); 2170 VisitStatements(node->catch_block()->statements());
2136 if (frame_ != NULL) { 2171 if (frame_ != NULL) {
2172 frame_->SpillAll();
2137 exit.Jump(); 2173 exit.Jump();
2138 } 2174 }
2139 2175
2140 2176
2141 // --- Try block --- 2177 // --- Try block ---
2142 try_block.Bind(); 2178 try_block.Bind();
2143 2179
2144 frame_->PushTryHandler(TRY_CATCH_HANDLER); 2180 frame_->PushTryHandler(TRY_CATCH_HANDLER);
2145 int handler_height = frame_->height(); 2181 int handler_height = frame_->height();
2146 2182
(...skipping 10 matching lines...) Expand all
2157 for (int i = 0; i < nof_escapes; i++) { 2193 for (int i = 0; i < nof_escapes; i++) {
2158 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2194 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2159 } 2195 }
2160 bool function_return_was_shadowed = function_return_is_shadowed_; 2196 bool function_return_was_shadowed = function_return_is_shadowed_;
2161 function_return_is_shadowed_ = true; 2197 function_return_is_shadowed_ = true;
2162 2198
2163 // Generate code for the statements in the try block. 2199 // Generate code for the statements in the try block.
2164 bool was_inside_try = is_inside_try_; 2200 bool was_inside_try = is_inside_try_;
2165 is_inside_try_ = true; 2201 is_inside_try_ = true;
2166 VisitStatements(node->try_block()->statements()); 2202 VisitStatements(node->try_block()->statements());
2203 if (frame_ != NULL) {
2204 frame_->SpillAll();
2205 }
2167 is_inside_try_ = was_inside_try; 2206 is_inside_try_ = was_inside_try;
2168 2207
2169 // Stop the introduced shadowing and count the number of required unlinks. 2208 // Stop the introduced shadowing and count the number of required unlinks.
2170 // After shadowing stops, the original targets are unshadowed and the 2209 // After shadowing stops, the original targets are unshadowed and the
2171 // ShadowTargets represent the formerly shadowing targets. 2210 // ShadowTargets represent the formerly shadowing targets.
2172 int nof_unlinks = 0; 2211 int nof_unlinks = 0;
2173 for (int i = 0; i <= nof_escapes; i++) { 2212 for (int i = 0; i <= nof_escapes; i++) {
2174 shadows[i]->StopShadowing(); 2213 shadows[i]->StopShadowing();
2175 if (shadows[i]->is_linked()) nof_unlinks++; 2214 if (shadows[i]->is_linked()) nof_unlinks++;
2176 } 2215 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 for (int i = 0; i < nof_escapes; i++) { 2304 for (int i = 0; i < nof_escapes; i++) {
2266 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2305 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2267 } 2306 }
2268 bool function_return_was_shadowed = function_return_is_shadowed_; 2307 bool function_return_was_shadowed = function_return_is_shadowed_;
2269 function_return_is_shadowed_ = true; 2308 function_return_is_shadowed_ = true;
2270 2309
2271 // Generate code for the statements in the try block. 2310 // Generate code for the statements in the try block.
2272 bool was_inside_try = is_inside_try_; 2311 bool was_inside_try = is_inside_try_;
2273 is_inside_try_ = true; 2312 is_inside_try_ = true;
2274 VisitStatements(node->try_block()->statements()); 2313 VisitStatements(node->try_block()->statements());
2314 if (frame_ != NULL) {
2315 frame_->SpillAll();
2316 }
2275 is_inside_try_ = was_inside_try; 2317 is_inside_try_ = was_inside_try;
2276 2318
2277 // Stop the introduced shadowing and count the number of required unlinks. 2319 // Stop the introduced shadowing and count the number of required unlinks.
2278 // After shadowing stops, the original targets are unshadowed and the 2320 // After shadowing stops, the original targets are unshadowed and the
2279 // ShadowTargets represent the formerly shadowing targets. 2321 // ShadowTargets represent the formerly shadowing targets.
2280 int nof_unlinks = 0; 2322 int nof_unlinks = 0;
2281 for (int i = 0; i <= nof_escapes; i++) { 2323 for (int i = 0; i <= nof_escapes; i++) {
2282 shadows[i]->StopShadowing(); 2324 shadows[i]->StopShadowing();
2283 if (shadows[i]->is_linked()) nof_unlinks++; 2325 if (shadows[i]->is_linked()) nof_unlinks++;
2284 } 2326 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2341 // that a break/continue crossing this statement can restore the 2383 // that a break/continue crossing this statement can restore the
2342 // stack. 2384 // stack.
2343 const int kFinallyStackSize = 2 * kPointerSize; 2385 const int kFinallyStackSize = 2 * kPointerSize;
2344 break_stack_height_ += kFinallyStackSize; 2386 break_stack_height_ += kFinallyStackSize;
2345 2387
2346 // Generate code for the statements in the finally block. 2388 // Generate code for the statements in the finally block.
2347 VisitStatements(node->finally_block()->statements()); 2389 VisitStatements(node->finally_block()->statements());
2348 2390
2349 break_stack_height_ -= kFinallyStackSize; 2391 break_stack_height_ -= kFinallyStackSize;
2350 if (frame_ != NULL) { 2392 if (frame_ != NULL) {
2393 frame_->SpillAll();
2351 JumpTarget exit(this); 2394 JumpTarget exit(this);
2352 // Restore state and return value or faked TOS. 2395 // Restore state and return value or faked TOS.
2353 frame_->EmitPop(ecx); 2396 frame_->EmitPop(ecx);
2354 frame_->EmitPop(eax); 2397 frame_->EmitPop(eax);
2355 2398
2356 // Generate code to jump to the right destination for all used 2399 // Generate code to jump to the right destination for all used
2357 // (formerly) shadowing targets. 2400 // (formerly) shadowing targets.
2358 for (int i = 0; i <= nof_escapes; i++) { 2401 for (int i = 0; i <= nof_escapes; i++) {
2359 if (shadows[i]->is_bound()) { 2402 if (shadows[i]->is_bound()) {
2360 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); 2403 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i)));
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
2845 2888
2846 2889
2847 bool CodeGenerator::IsInlineSmi(Literal* literal) { 2890 bool CodeGenerator::IsInlineSmi(Literal* literal) {
2848 if (literal == NULL || !literal->handle()->IsSmi()) return false; 2891 if (literal == NULL || !literal->handle()->IsSmi()) return false;
2849 int int_value = Smi::cast(*literal->handle())->value(); 2892 int int_value = Smi::cast(*literal->handle())->value();
2850 return is_intn(int_value, kMaxSmiInlinedBits); 2893 return is_intn(int_value, kMaxSmiInlinedBits);
2851 } 2894 }
2852 2895
2853 2896
2854 void CodeGenerator::VisitAssignment(Assignment* node) { 2897 void CodeGenerator::VisitAssignment(Assignment* node) {
2855 frame_->SpillAll();
2856 Comment cmnt(masm_, "[ Assignment"); 2898 Comment cmnt(masm_, "[ Assignment");
2857 2899
2858 RecordStatementPosition(node); 2900 RecordStatementPosition(node);
2859 { Reference target(this, node->target()); 2901 { Reference target(this, node->target());
2860 if (target.is_illegal()) { 2902 if (target.is_illegal()) {
2861 // Fool the virtual frame into thinking that we left the assignment's 2903 // Fool the virtual frame into thinking that we left the assignment's
2862 // value on the frame. 2904 // value on the frame.
2863 frame_->EmitPush(Immediate(Smi::FromInt(0))); 2905 frame_->EmitPush(Immediate(Smi::FromInt(0)));
2864 return; 2906 return;
2865 } 2907 }
2866 2908
2867 if (node->op() == Token::ASSIGN || 2909 if (node->op() == Token::ASSIGN ||
2868 node->op() == Token::INIT_VAR || 2910 node->op() == Token::INIT_VAR ||
2869 node->op() == Token::INIT_CONST) { 2911 node->op() == Token::INIT_CONST) {
2870 Load(node->value()); 2912 Load(node->value());
2871 2913
2872 } else { 2914 } else {
2915 frame_->SpillAll();
2873 target.GetValue(NOT_INSIDE_TYPEOF); 2916 target.GetValue(NOT_INSIDE_TYPEOF);
2874 Literal* literal = node->value()->AsLiteral(); 2917 Literal* literal = node->value()->AsLiteral();
2875 if (IsInlineSmi(literal)) { 2918 if (IsInlineSmi(literal)) {
2876 SmiOperation(node->binary_op(), node->type(), literal->handle(), false, 2919 SmiOperation(node->binary_op(), node->type(), literal->handle(), false,
2877 NO_OVERWRITE); 2920 NO_OVERWRITE);
2878 } else { 2921 } else {
2879 Load(node->value()); 2922 Load(node->value());
2880 frame_->SpillAll(); 2923 frame_->SpillAll();
2881 GenericBinaryOperation(node->binary_op(), node->type()); 2924 GenericBinaryOperation(node->binary_op(), node->type());
2882 } 2925 }
(...skipping 2604 matching lines...) Expand 10 before | Expand all | Expand 10 after
5487 5530
5488 // Slow-case: Go through the JavaScript implementation. 5531 // Slow-case: Go through the JavaScript implementation.
5489 __ bind(&slow); 5532 __ bind(&slow);
5490 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5533 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5491 } 5534 }
5492 5535
5493 5536
5494 #undef __ 5537 #undef __
5495 5538
5496 } } // namespace v8::internal 5539 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | src/jump-target-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698