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

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

Issue 18592: Experimental: add a function to the API for recording assembler... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 11 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/codegen-ia32.h ('k') | no next file » | 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 119
120 120
121 // Calling conventions: 121 // Calling conventions:
122 // ebp: frame pointer 122 // ebp: frame pointer
123 // esp: stack pointer 123 // esp: stack pointer
124 // edi: caller's parameter pointer 124 // edi: caller's parameter pointer
125 // esi: callee's context 125 // esi: callee's context
126 126
127 void CodeGenerator::GenCode(FunctionLiteral* fun) { 127 void CodeGenerator::GenCode(FunctionLiteral* fun) {
128 // Record the position for debugging purposes. 128 // Record the position for debugging purposes.
129 CodeForSourcePosition(fun->start_position()); 129 CodeForFunctionPosition(fun);
130 130
131 ZoneList<Statement*>* body = fun->body(); 131 ZoneList<Statement*>* body = fun->body();
132 132
133 // Initialize state. 133 // Initialize state.
134 ASSERT(scope_ == NULL); 134 ASSERT(scope_ == NULL);
135 scope_ = fun->scope(); 135 scope_ = fun->scope();
136 ASSERT(allocator_ == NULL); 136 ASSERT(allocator_ == NULL);
137 RegisterAllocator register_allocator(this); 137 RegisterAllocator register_allocator(this);
138 allocator_ = &register_allocator; 138 allocator_ = &register_allocator;
139 ASSERT(frame_ == NULL); 139 ASSERT(frame_ == NULL);
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 }; 1388 };
1389 1389
1390 1390
1391 void DeferredStackCheck::Generate() { 1391 void DeferredStackCheck::Generate() {
1392 enter()->Bind(); 1392 enter()->Bind();
1393 // The stack check can trigger the debugger. Before calling it, all 1393 // The stack check can trigger the debugger. Before calling it, all
1394 // values including constants must be spilled to the frame. 1394 // values including constants must be spilled to the frame.
1395 generator()->frame()->SpillAll(); 1395 generator()->frame()->SpillAll();
1396 StackCheckStub stub; 1396 StackCheckStub stub;
1397 Result ignored = generator()->frame()->CallStub(&stub, 0); 1397 Result ignored = generator()->frame()->CallStub(&stub, 0);
1398 ignored.Unuse();
1398 exit()->Jump(); 1399 exit()->Jump();
1399 } 1400 }
1400 1401
1401 1402
1402 void CodeGenerator::CheckStack() { 1403 void CodeGenerator::CheckStack() {
1403 if (FLAG_check_stack) { 1404 if (FLAG_check_stack) {
1404 DeferredStackCheck* deferred = new DeferredStackCheck(this); 1405 DeferredStackCheck* deferred = new DeferredStackCheck(this);
1405 ExternalReference stack_guard_limit = 1406 ExternalReference stack_guard_limit =
1406 ExternalReference::address_of_stack_guard_limit(); 1407 ExternalReference::address_of_stack_guard_limit();
1407 __ cmp(esp, Operand::StaticVariable(stack_guard_limit)); 1408 __ cmp(esp, Operand::StaticVariable(stack_guard_limit));
1408 deferred->enter()->Branch(below, not_taken); 1409 deferred->enter()->Branch(below, not_taken);
1409 deferred->exit()->Bind(); 1410 deferred->exit()->Bind();
1410 } 1411 }
1411 } 1412 }
1412 1413
1413 1414
1414 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1415 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1415 ASSERT(!in_spilled_code()); 1416 ASSERT(!in_spilled_code());
1416 for (int i = 0; has_valid_frame() && i < statements->length(); i++) { 1417 for (int i = 0; has_valid_frame() && i < statements->length(); i++) {
1417 Visit(statements->at(i)); 1418 Visit(statements->at(i));
1418 } 1419 }
1419 } 1420 }
1420 1421
1421 1422
1422 void CodeGenerator::VisitBlock(Block* node) { 1423 void CodeGenerator::VisitBlock(Block* node) {
1423 ASSERT(!in_spilled_code()); 1424 ASSERT(!in_spilled_code());
1424 Comment cmnt(masm_, "[ Block"); 1425 Comment cmnt(masm_, "[ Block");
1425 CodeForStatement(node); 1426 CodeForStatementPosition(node);
1426 node->set_break_stack_height(break_stack_height_); 1427 node->set_break_stack_height(break_stack_height_);
1427 node->break_target()->Initialize(this); 1428 node->break_target()->Initialize(this);
1428 VisitStatements(node->statements()); 1429 VisitStatements(node->statements());
1429 if (node->break_target()->is_linked()) { 1430 if (node->break_target()->is_linked()) {
1430 node->break_target()->Bind(); 1431 node->break_target()->Bind();
1431 } 1432 }
1432 } 1433 }
1433 1434
1434 1435
1435 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 1436 void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
1436 VirtualFrame::SpilledScope spilled_scope(this); 1437 VirtualFrame::SpilledScope spilled_scope(this);
1437 frame_->EmitPush(Immediate(pairs)); 1438 frame_->EmitPush(Immediate(pairs));
1438 frame_->EmitPush(esi); 1439 frame_->EmitPush(esi);
1439 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); 1440 frame_->EmitPush(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
1440 frame_->CallRuntime(Runtime::kDeclareGlobals, 3); 1441 frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
1441 // Return value is ignored. 1442 // Return value is ignored.
1442 } 1443 }
1443 1444
1444 1445
1445 void CodeGenerator::VisitDeclaration(Declaration* node) { 1446 void CodeGenerator::VisitDeclaration(Declaration* node) {
1446 Comment cmnt(masm_, "[ Declaration"); 1447 Comment cmnt(masm_, "[ Declaration");
1447 CodeForStatement(node); 1448 CodeForStatementPosition(node);
1448 Variable* var = node->proxy()->var(); 1449 Variable* var = node->proxy()->var();
1449 ASSERT(var != NULL); // must have been resolved 1450 ASSERT(var != NULL); // must have been resolved
1450 Slot* slot = var->slot(); 1451 Slot* slot = var->slot();
1451 1452
1452 // If it was not possible to allocate the variable at compile time, 1453 // If it was not possible to allocate the variable at compile time,
1453 // we need to "declare" it at runtime to make sure it actually 1454 // we need to "declare" it at runtime to make sure it actually
1454 // exists in the local context. 1455 // exists in the local context.
1455 if (slot != NULL && slot->type() == Slot::LOOKUP) { 1456 if (slot != NULL && slot->type() == Slot::LOOKUP) {
1456 // Variables with a "LOOKUP" slot were introduced as non-locals 1457 // Variables with a "LOOKUP" slot were introduced as non-locals
1457 // during variable resolution and must have mode DYNAMIC. 1458 // during variable resolution and must have mode DYNAMIC.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 // the reference itself (which preserves the top of stack) because we 1503 // the reference itself (which preserves the top of stack) because we
1503 // know that it is a zero-sized reference. 1504 // know that it is a zero-sized reference.
1504 frame_->Drop(); 1505 frame_->Drop();
1505 } 1506 }
1506 } 1507 }
1507 1508
1508 1509
1509 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) { 1510 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
1510 ASSERT(!in_spilled_code()); 1511 ASSERT(!in_spilled_code());
1511 Comment cmnt(masm_, "[ ExpressionStatement"); 1512 Comment cmnt(masm_, "[ ExpressionStatement");
1512 CodeForStatement(node); 1513 CodeForStatementPosition(node);
1513 Expression* expression = node->expression(); 1514 Expression* expression = node->expression();
1514 expression->MarkAsStatement(); 1515 expression->MarkAsStatement();
1515 Load(expression); 1516 Load(expression);
1516 // Remove the lingering expression result from the top of stack. 1517 // Remove the lingering expression result from the top of stack.
1517 frame_->Drop(); 1518 frame_->Drop();
1518 } 1519 }
1519 1520
1520 1521
1521 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) { 1522 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
1522 ASSERT(!in_spilled_code()); 1523 ASSERT(!in_spilled_code());
1523 Comment cmnt(masm_, "// EmptyStatement"); 1524 Comment cmnt(masm_, "// EmptyStatement");
1524 CodeForStatement(node); 1525 CodeForStatementPosition(node);
1525 // nothing to do 1526 // nothing to do
1526 } 1527 }
1527 1528
1528 1529
1529 void CodeGenerator::VisitIfStatement(IfStatement* node) { 1530 void CodeGenerator::VisitIfStatement(IfStatement* node) {
1530 ASSERT(!in_spilled_code()); 1531 ASSERT(!in_spilled_code());
1531 Comment cmnt(masm_, "[ IfStatement"); 1532 Comment cmnt(masm_, "[ IfStatement");
1532 // Generate different code depending on which parts of the if statement 1533 // Generate different code depending on which parts of the if statement
1533 // are present or not. 1534 // are present or not.
1534 bool has_then_stm = node->HasThenStatement(); 1535 bool has_then_stm = node->HasThenStatement();
1535 bool has_else_stm = node->HasElseStatement(); 1536 bool has_else_stm = node->HasElseStatement();
1536 1537
1537 CodeForStatement(node); 1538 CodeForStatementPosition(node);
1538 JumpTarget exit(this); 1539 JumpTarget exit(this);
1539 if (has_then_stm && has_else_stm) { 1540 if (has_then_stm && has_else_stm) {
1540 JumpTarget then(this); 1541 JumpTarget then(this);
1541 JumpTarget else_(this); 1542 JumpTarget else_(this);
1542 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true); 1543 LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true);
1543 if (then.is_linked()) { 1544 if (then.is_linked()) {
1544 then.Bind(); 1545 then.Bind();
1545 Visit(node->then_statement()); 1546 Visit(node->then_statement());
1546 if (has_valid_frame() && else_.is_linked()) { 1547 if (has_valid_frame() && else_.is_linked()) {
1547 // We have fallen through from the then block and we need to compile 1548 // We have fallen through from the then block and we need to compile
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 1594
1594 void CodeGenerator::CleanStack(int num_bytes) { 1595 void CodeGenerator::CleanStack(int num_bytes) {
1595 ASSERT(num_bytes % kPointerSize == 0); 1596 ASSERT(num_bytes % kPointerSize == 0);
1596 frame_->Drop(num_bytes / kPointerSize); 1597 frame_->Drop(num_bytes / kPointerSize);
1597 } 1598 }
1598 1599
1599 1600
1600 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) { 1601 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
1601 ASSERT(!in_spilled_code()); 1602 ASSERT(!in_spilled_code());
1602 Comment cmnt(masm_, "[ ContinueStatement"); 1603 Comment cmnt(masm_, "[ ContinueStatement");
1603 CodeForStatement(node); 1604 CodeForStatementPosition(node);
1604 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1605 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1605 node->target()->continue_target()->Jump(); 1606 node->target()->continue_target()->Jump();
1606 } 1607 }
1607 1608
1608 1609
1609 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 1610 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1610 ASSERT(!in_spilled_code()); 1611 ASSERT(!in_spilled_code());
1611 Comment cmnt(masm_, "[ BreakStatement"); 1612 Comment cmnt(masm_, "[ BreakStatement");
1612 CodeForStatement(node); 1613 CodeForStatementPosition(node);
1613 CleanStack(break_stack_height_ - node->target()->break_stack_height()); 1614 CleanStack(break_stack_height_ - node->target()->break_stack_height());
1614 node->target()->break_target()->Jump(); 1615 node->target()->break_target()->Jump();
1615 } 1616 }
1616 1617
1617 1618
1618 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 1619 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1619 ASSERT(!in_spilled_code()); 1620 ASSERT(!in_spilled_code());
1620 Comment cmnt(masm_, "[ ReturnStatement"); 1621 Comment cmnt(masm_, "[ ReturnStatement");
1621 1622
1622 if (function_return_is_shadowed_) { 1623 if (function_return_is_shadowed_) {
1623 // If the function return is shadowed, we spill all information 1624 // If the function return is shadowed, we spill all information
1624 // and just jump to the label. 1625 // and just jump to the label.
1625 VirtualFrame::SpilledScope spilled_scope(this); 1626 VirtualFrame::SpilledScope spilled_scope(this);
1626 CodeForStatement(node); 1627 CodeForStatementPosition(node);
1627 LoadAndSpill(node->expression()); 1628 LoadAndSpill(node->expression());
1628 frame_->EmitPop(eax); 1629 frame_->EmitPop(eax);
1629 function_return_.Jump(); 1630 function_return_.Jump();
1630 } else { 1631 } else {
1631 // Load the returned value. 1632 // Load the returned value.
1632 CodeForStatement(node); 1633 CodeForStatementPosition(node);
1633 Load(node->expression()); 1634 Load(node->expression());
1634 1635
1635 // Pop the result from the frame and prepare the frame for 1636 // Pop the result from the frame and prepare the frame for
1636 // returning thus making it easier to merge. 1637 // returning thus making it easier to merge.
1637 Result result = frame_->Pop(); 1638 Result result = frame_->Pop();
1638 frame_->PrepareForReturn(); 1639 frame_->PrepareForReturn();
1639 1640
1640 // Move the result into register eax where it belongs. 1641 // Move the result into register eax where it belongs.
1641 result.ToRegister(eax); 1642 result.ToRegister(eax);
1642 // TODO(203): Instead of explictly calling Unuse on the result, it 1643 // TODO(203): Instead of explictly calling Unuse on the result, it
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 // Check that the size of the code used for returning matches what is 1680 // Check that the size of the code used for returning matches what is
1680 // expected by the debugger. 1681 // expected by the debugger.
1681 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength, 1682 ASSERT_EQ(Debug::kIa32JSReturnSequenceLength,
1682 __ SizeOfCodeGeneratedSince(&check_exit_codesize)); 1683 __ SizeOfCodeGeneratedSince(&check_exit_codesize));
1683 } 1684 }
1684 1685
1685 1686
1686 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) { 1687 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
1687 ASSERT(!in_spilled_code()); 1688 ASSERT(!in_spilled_code());
1688 Comment cmnt(masm_, "[ WithEnterStatement"); 1689 Comment cmnt(masm_, "[ WithEnterStatement");
1689 CodeForStatement(node); 1690 CodeForStatementPosition(node);
1690 Load(node->expression()); 1691 Load(node->expression());
1691 Result context(this); 1692 Result context(this);
1692 if (node->is_catch_block()) { 1693 if (node->is_catch_block()) {
1693 context = frame_->CallRuntime(Runtime::kPushCatchContext, 1); 1694 context = frame_->CallRuntime(Runtime::kPushCatchContext, 1);
1694 } else { 1695 } else {
1695 context = frame_->CallRuntime(Runtime::kPushContext, 1); 1696 context = frame_->CallRuntime(Runtime::kPushContext, 1);
1696 } 1697 }
1697 1698
1698 if (kDebug) { 1699 if (kDebug) {
1699 JumpTarget verified_true(this); 1700 JumpTarget verified_true(this);
1700 // Verify that the result of the runtime call and the esi register are 1701 // Verify that the result of the runtime call and the esi register are
1701 // the same in debug mode. 1702 // the same in debug mode.
1702 __ cmp(context.reg(), Operand(esi)); 1703 __ cmp(context.reg(), Operand(esi));
1703 context.Unuse(); 1704 context.Unuse();
1704 verified_true.Branch(equal); 1705 verified_true.Branch(equal);
1705 frame_->SpillAll(); 1706 frame_->SpillAll();
1706 __ int3(); 1707 __ int3();
1707 verified_true.Bind(); 1708 verified_true.Bind();
1708 } 1709 }
1709 1710
1710 // Update context local. 1711 // Update context local.
1711 frame_->SaveContextRegister(); 1712 frame_->SaveContextRegister();
1712 } 1713 }
1713 1714
1714 1715
1715 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) { 1716 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
1716 ASSERT(!in_spilled_code()); 1717 ASSERT(!in_spilled_code());
1717 Comment cmnt(masm_, "[ WithExitStatement"); 1718 Comment cmnt(masm_, "[ WithExitStatement");
1718 CodeForStatement(node); 1719 CodeForStatementPosition(node);
1719 // Pop context. 1720 // Pop context.
1720 __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX)); 1721 __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX));
1721 // Update context local. 1722 // Update context local.
1722 frame_->SaveContextRegister(); 1723 frame_->SaveContextRegister();
1723 } 1724 }
1724 1725
1725 1726
1726 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() { 1727 int CodeGenerator::FastCaseSwitchMaxOverheadFactor() {
1727 return kFastSwitchMaxOverheadFactor; 1728 return kFastSwitchMaxOverheadFactor;
1728 } 1729 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 i < range; 1798 i < range;
1798 i++, entry_pos += sizeof(uint32_t)) { 1799 i++, entry_pos += sizeof(uint32_t)) {
1799 __ WriteInternalReference(entry_pos, *case_targets[i]->entry_label()); 1800 __ WriteInternalReference(entry_pos, *case_targets[i]->entry_label());
1800 } 1801 }
1801 } 1802 }
1802 1803
1803 1804
1804 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) { 1805 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
1805 ASSERT(!in_spilled_code()); 1806 ASSERT(!in_spilled_code());
1806 Comment cmnt(masm_, "[ SwitchStatement"); 1807 Comment cmnt(masm_, "[ SwitchStatement");
1807 CodeForStatement(node); 1808 CodeForStatementPosition(node);
1808 node->set_break_stack_height(break_stack_height_); 1809 node->set_break_stack_height(break_stack_height_);
1809 node->break_target()->Initialize(this); 1810 node->break_target()->Initialize(this);
1810 1811
1811 Load(node->tag()); 1812 Load(node->tag());
1812 1813
1813 if (TryGenerateFastCaseSwitchStatement(node)) { 1814 if (TryGenerateFastCaseSwitchStatement(node)) {
1814 return; 1815 return;
1815 } 1816 }
1816 1817
1817 JumpTarget next_test(this); 1818 JumpTarget next_test(this);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1896 1897
1897 if (node->break_target()->is_linked()) { 1898 if (node->break_target()->is_linked()) {
1898 node->break_target()->Bind(); 1899 node->break_target()->Bind();
1899 } 1900 }
1900 } 1901 }
1901 1902
1902 1903
1903 void CodeGenerator::VisitLoopStatement(LoopStatement* node) { 1904 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
1904 ASSERT(!in_spilled_code()); 1905 ASSERT(!in_spilled_code());
1905 Comment cmnt(masm_, "[ LoopStatement"); 1906 Comment cmnt(masm_, "[ LoopStatement");
1906 CodeForStatement(node); 1907 CodeForStatementPosition(node);
1907 node->set_break_stack_height(break_stack_height_); 1908 node->set_break_stack_height(break_stack_height_);
1908 node->break_target()->Initialize(this); 1909 node->break_target()->Initialize(this);
1909 1910
1910 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a 1911 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
1911 // known result for the test expression, with no side effects. 1912 // known result for the test expression, with no side effects.
1912 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW; 1913 enum { ALWAYS_TRUE, ALWAYS_FALSE, DONT_KNOW } info = DONT_KNOW;
1913 if (node->cond() == NULL) { 1914 if (node->cond() == NULL) {
1914 ASSERT(node->type() == LoopStatement::FOR_LOOP); 1915 ASSERT(node->type() == LoopStatement::FOR_LOOP);
1915 info = ALWAYS_TRUE; 1916 info = ALWAYS_TRUE;
1916 } else { 1917 } else {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 // If there is an update statement and control flow can reach it 2058 // If there is an update statement and control flow can reach it
2058 // via falling out of the body of the loop or continuing, we 2059 // via falling out of the body of the loop or continuing, we
2059 // compile the update statement. 2060 // compile the update statement.
2060 if (node->continue_target()->is_linked()) { 2061 if (node->continue_target()->is_linked()) {
2061 node->continue_target()->Bind(); 2062 node->continue_target()->Bind();
2062 } 2063 }
2063 if (has_valid_frame()) { 2064 if (has_valid_frame()) {
2064 // Record source position of the statement as this code which is 2065 // Record source position of the statement as this code which is
2065 // after the code for the body actually belongs to the loop 2066 // after the code for the body actually belongs to the loop
2066 // statement and not the body. 2067 // statement and not the body.
2067 CodeForStatement(node); 2068 CodeForStatementPosition(node);
2068 ASSERT(node->type() == LoopStatement::FOR_LOOP); 2069 ASSERT(node->type() == LoopStatement::FOR_LOOP);
2069 Visit(node->next()); 2070 Visit(node->next());
2070 loop.Jump(); 2071 loop.Jump();
2071 } 2072 }
2072 } 2073 }
2073 } 2074 }
2074 break; 2075 break;
2075 } 2076 }
2076 } 2077 }
2077 2078
2078 DecrementLoopNesting(); 2079 DecrementLoopNesting();
2079 if (node->break_target()->is_linked()) { 2080 if (node->break_target()->is_linked()) {
2080 node->break_target()->Bind(); 2081 node->break_target()->Bind();
2081 } 2082 }
2082 } 2083 }
2083 2084
2084 2085
2085 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 2086 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
2086 ASSERT(!in_spilled_code()); 2087 ASSERT(!in_spilled_code());
2087 VirtualFrame::SpilledScope spilled_scope(this); 2088 VirtualFrame::SpilledScope spilled_scope(this);
2088 Comment cmnt(masm_, "[ ForInStatement"); 2089 Comment cmnt(masm_, "[ ForInStatement");
2089 CodeForStatement(node); 2090 CodeForStatementPosition(node);
2090 2091
2091 // We keep stuff on the stack while the body is executing. 2092 // We keep stuff on the stack while the body is executing.
2092 // Record it, so that a break/continue crossing this statement 2093 // Record it, so that a break/continue crossing this statement
2093 // can restore the stack. 2094 // can restore the stack.
2094 const int kForInStackSize = 5 * kPointerSize; 2095 const int kForInStackSize = 5 * kPointerSize;
2095 break_stack_height_ += kForInStackSize; 2096 break_stack_height_ += kForInStackSize;
2096 node->set_break_stack_height(break_stack_height_); 2097 node->set_break_stack_height(break_stack_height_);
2097 node->break_target()->Initialize(this); 2098 node->break_target()->Initialize(this);
2098 node->continue_target()->Initialize(this); 2099 node->continue_target()->Initialize(this);
2099 2100
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2271 exit.Bind(); 2272 exit.Bind();
2272 2273
2273 break_stack_height_ -= kForInStackSize; 2274 break_stack_height_ -= kForInStackSize;
2274 } 2275 }
2275 2276
2276 2277
2277 void CodeGenerator::VisitTryCatch(TryCatch* node) { 2278 void CodeGenerator::VisitTryCatch(TryCatch* node) {
2278 ASSERT(!in_spilled_code()); 2279 ASSERT(!in_spilled_code());
2279 VirtualFrame::SpilledScope spilled_scope(this); 2280 VirtualFrame::SpilledScope spilled_scope(this);
2280 Comment cmnt(masm_, "[ TryCatch"); 2281 Comment cmnt(masm_, "[ TryCatch");
2281 CodeForStatement(node); 2282 CodeForStatementPosition(node);
2282 2283
2283 JumpTarget try_block(this); 2284 JumpTarget try_block(this);
2284 JumpTarget exit(this); 2285 JumpTarget exit(this);
2285 2286
2286 try_block.Call(); 2287 try_block.Call();
2287 // --- Catch block --- 2288 // --- Catch block ---
2288 frame_->EmitPush(eax); 2289 frame_->EmitPush(eax);
2289 2290
2290 // Store the caught exception in the catch variable. 2291 // Store the caught exception in the catch variable.
2291 { Reference ref(this, node->catch_var()); 2292 { Reference ref(this, node->catch_var());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2400 } 2401 }
2401 2402
2402 exit.Bind(); 2403 exit.Bind();
2403 } 2404 }
2404 2405
2405 2406
2406 void CodeGenerator::VisitTryFinally(TryFinally* node) { 2407 void CodeGenerator::VisitTryFinally(TryFinally* node) {
2407 ASSERT(!in_spilled_code()); 2408 ASSERT(!in_spilled_code());
2408 VirtualFrame::SpilledScope spilled_scope(this); 2409 VirtualFrame::SpilledScope spilled_scope(this);
2409 Comment cmnt(masm_, "[ TryFinally"); 2410 Comment cmnt(masm_, "[ TryFinally");
2410 CodeForStatement(node); 2411 CodeForStatementPosition(node);
2411 2412
2412 // State: Used to keep track of reason for entering the finally 2413 // State: Used to keep track of reason for entering the finally
2413 // block. Should probably be extended to hold information for 2414 // block. Should probably be extended to hold information for
2414 // break/continue from within the try block. 2415 // break/continue from within the try block.
2415 enum { FALLING, THROWING, JUMPING }; 2416 enum { FALLING, THROWING, JUMPING };
2416 2417
2417 JumpTarget unlink(this); 2418 JumpTarget unlink(this);
2418 JumpTarget try_block(this); 2419 JumpTarget try_block(this);
2419 JumpTarget finally_block(this); 2420 JumpTarget finally_block(this);
2420 2421
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 2569
2569 // Done. 2570 // Done.
2570 exit.Bind(); 2571 exit.Bind();
2571 } 2572 }
2572 } 2573 }
2573 2574
2574 2575
2575 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2576 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2576 ASSERT(!in_spilled_code()); 2577 ASSERT(!in_spilled_code());
2577 Comment cmnt(masm_, "[ DebuggerStatement"); 2578 Comment cmnt(masm_, "[ DebuggerStatement");
2578 CodeForStatement(node); 2579 CodeForStatementPosition(node);
2579 // Spill everything, even constants, to the frame. 2580 // Spill everything, even constants, to the frame.
2580 frame_->SpillAll(); 2581 frame_->SpillAll();
2581 frame_->CallRuntime(Runtime::kDebugBreak, 0); 2582 frame_->CallRuntime(Runtime::kDebugBreak, 0);
2582 // Ignore the return value. 2583 // Ignore the return value.
2583 } 2584 }
2584 2585
2585 2586
2586 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2587 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2587 ASSERT(boilerplate->IsBoilerplate()); 2588 ASSERT(boilerplate->IsBoilerplate());
2588 2589
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
3073 3074
3074 bool CodeGenerator::IsInlineSmi(Literal* literal) { 3075 bool CodeGenerator::IsInlineSmi(Literal* literal) {
3075 if (literal == NULL || !literal->handle()->IsSmi()) return false; 3076 if (literal == NULL || !literal->handle()->IsSmi()) return false;
3076 int int_value = Smi::cast(*literal->handle())->value(); 3077 int int_value = Smi::cast(*literal->handle())->value();
3077 return is_intn(int_value, kMaxSmiInlinedBits); 3078 return is_intn(int_value, kMaxSmiInlinedBits);
3078 } 3079 }
3079 3080
3080 3081
3081 void CodeGenerator::VisitAssignment(Assignment* node) { 3082 void CodeGenerator::VisitAssignment(Assignment* node) {
3082 Comment cmnt(masm_, "[ Assignment"); 3083 Comment cmnt(masm_, "[ Assignment");
3083 CodeForStatement(node); 3084 CodeForStatementPosition(node);
3084 3085
3085 { Reference target(this, node->target()); 3086 { Reference target(this, node->target());
3086 if (target.is_illegal()) { 3087 if (target.is_illegal()) {
3087 // Fool the virtual frame into thinking that we left the assignment's 3088 // Fool the virtual frame into thinking that we left the assignment's
3088 // value on the frame. 3089 // value on the frame.
3089 frame_->Push(Smi::FromInt(0)); 3090 frame_->Push(Smi::FromInt(0));
3090 return; 3091 return;
3091 } 3092 }
3092 3093
3093 if (node->op() == Token::ASSIGN || 3094 if (node->op() == Token::ASSIGN ||
(...skipping 30 matching lines...) Expand all
3124 target.SetValue(NOT_CONST_INIT); 3125 target.SetValue(NOT_CONST_INIT);
3125 } 3126 }
3126 } 3127 }
3127 } 3128 }
3128 } 3129 }
3129 3130
3130 3131
3131 void CodeGenerator::VisitThrow(Throw* node) { 3132 void CodeGenerator::VisitThrow(Throw* node) {
3132 VirtualFrame::SpilledScope spilled_scope(this); 3133 VirtualFrame::SpilledScope spilled_scope(this);
3133 Comment cmnt(masm_, "[ Throw"); 3134 Comment cmnt(masm_, "[ Throw");
3134 CodeForStatement(node); 3135 CodeForStatementPosition(node);
3135 3136
3136 LoadAndSpill(node->exception()); 3137 LoadAndSpill(node->exception());
3137 frame_->CallRuntime(Runtime::kThrow, 1); 3138 frame_->CallRuntime(Runtime::kThrow, 1);
3138 frame_->EmitPush(eax); 3139 frame_->EmitPush(eax);
3139 } 3140 }
3140 3141
3141 3142
3142 void CodeGenerator::VisitProperty(Property* node) { 3143 void CodeGenerator::VisitProperty(Property* node) {
3143 Comment cmnt(masm_, "[ Property"); 3144 Comment cmnt(masm_, "[ Property");
3144 Reference property(this, node); 3145 Reference property(this, node);
3145 property.GetValue(typeof_state()); 3146 property.GetValue(typeof_state());
3146 } 3147 }
3147 3148
3148 3149
3149 void CodeGenerator::VisitCall(Call* node) { 3150 void CodeGenerator::VisitCall(Call* node) {
3150 Comment cmnt(masm_, "[ Call"); 3151 Comment cmnt(masm_, "[ Call");
3151 3152
3152 ZoneList<Expression*>* args = node->arguments(); 3153 ZoneList<Expression*>* args = node->arguments();
3153 3154
3154 CodeForStatement(node); 3155 CodeForStatementPosition(node);
3155 3156
3156 // Check if the function is a variable or a property. 3157 // Check if the function is a variable or a property.
3157 Expression* function = node->expression(); 3158 Expression* function = node->expression();
3158 Variable* var = function->AsVariableProxy()->AsVariable(); 3159 Variable* var = function->AsVariableProxy()->AsVariable();
3159 Property* property = function->AsProperty(); 3160 Property* property = function->AsProperty();
3160 3161
3161 // ------------------------------------------------------------------------ 3162 // ------------------------------------------------------------------------
3162 // Fast-case: Use inline caching. 3163 // Fast-case: Use inline caching.
3163 // --- 3164 // ---
3164 // According to ECMA-262, section 11.2.3, page 44, the function to call 3165 // According to ECMA-262, section 11.2.3, page 44, the function to call
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
3280 LoadGlobalReceiver(); 3281 LoadGlobalReceiver();
3281 3282
3282 // Call the function. 3283 // Call the function.
3283 CallWithArguments(args, node->position()); 3284 CallWithArguments(args, node->position());
3284 } 3285 }
3285 } 3286 }
3286 3287
3287 3288
3288 void CodeGenerator::VisitCallNew(CallNew* node) { 3289 void CodeGenerator::VisitCallNew(CallNew* node) {
3289 Comment cmnt(masm_, "[ CallNew"); 3290 Comment cmnt(masm_, "[ CallNew");
3290 CodeForStatement(node); 3291 CodeForStatementPosition(node);
3291 3292
3292 // According to ECMA-262, section 11.2.2, page 44, the function 3293 // According to ECMA-262, section 11.2.2, page 44, the function
3293 // expression in new calls must be evaluated before the 3294 // expression in new calls must be evaluated before the
3294 // arguments. This is different from ordinary calls, where the 3295 // arguments. This is different from ordinary calls, where the
3295 // actual function to call is resolved after the arguments have been 3296 // actual function to call is resolved after the arguments have been
3296 // evaluated. 3297 // evaluated.
3297 3298
3298 // Compute function to call and use the global object as the 3299 // Compute function to call and use the global object as the
3299 // receiver. There is no need to use the global proxy here because 3300 // receiver. There is no need to use the global proxy here because
3300 // it will always be replaced with a newly allocated object. 3301 // it will always be replaced with a newly allocated object.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3338 VirtualFrame::SpilledScope spilled_scope(this); 3339 VirtualFrame::SpilledScope spilled_scope(this);
3339 Comment cmnt(masm_, "[ CallEval"); 3340 Comment cmnt(masm_, "[ CallEval");
3340 3341
3341 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve 3342 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
3342 // the function we need to call and the receiver of the call. 3343 // the function we need to call and the receiver of the call.
3343 // Then we call the resolved function using the given arguments. 3344 // Then we call the resolved function using the given arguments.
3344 3345
3345 ZoneList<Expression*>* args = node->arguments(); 3346 ZoneList<Expression*>* args = node->arguments();
3346 Expression* function = node->expression(); 3347 Expression* function = node->expression();
3347 3348
3348 CodeForStatement(node); 3349 CodeForStatementPosition(node);
3349 3350
3350 // Prepare stack for call to resolved function. 3351 // Prepare stack for call to resolved function.
3351 LoadAndSpill(function); 3352 LoadAndSpill(function);
3352 3353
3353 // Allocate a frame slot for the receiver. 3354 // Allocate a frame slot for the receiver.
3354 frame_->EmitPush(Immediate(Factory::undefined_value())); 3355 frame_->EmitPush(Immediate(Factory::undefined_value()));
3355 int arg_count = args->length(); 3356 int arg_count = args->length();
3356 for (int i = 0; i < arg_count; i++) { 3357 for (int i = 0; i < arg_count; i++) {
3357 LoadAndSpill(args->at(i)); 3358 LoadAndSpill(args->at(i));
3358 } 3359 }
(...skipping 2827 matching lines...) Expand 10 before | Expand all | Expand 10 after
6186 6187
6187 // Slow-case: Go through the JavaScript implementation. 6188 // Slow-case: Go through the JavaScript implementation.
6188 __ bind(&slow); 6189 __ bind(&slow);
6189 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6190 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6190 } 6191 }
6191 6192
6192 6193
6193 #undef __ 6194 #undef __
6194 6195
6195 } } // namespace v8::internal 6196 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698