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

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

Issue 17004: Experimental: add a has_valid_frame predicate to the code generator... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 12 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') | 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 in_spilled_code_(false) { 90 in_spilled_code_(false) {
91 } 91 }
92 92
93 93
94 void CodeGenerator::SetFrame(VirtualFrame* new_frame) { 94 void CodeGenerator::SetFrame(VirtualFrame* new_frame) {
95 if (frame_ != NULL) { 95 if (has_valid_frame()) {
96 frame_->DetachFromCodeGenerator(); 96 frame_->DetachFromCodeGenerator();
97 } 97 }
98 if (new_frame != NULL) { 98 if (new_frame != NULL) {
99 new_frame->AttachToCodeGenerator(); 99 new_frame->AttachToCodeGenerator();
100 } 100 }
101 frame_ = new_frame; 101 frame_ = new_frame;
102 } 102 }
103 103
104 104
105 void CodeGenerator::DeleteFrame() { 105 void CodeGenerator::DeleteFrame() {
106 if (frame_ != NULL) { 106 if (has_valid_frame()) {
107 frame_->DetachFromCodeGenerator(); 107 frame_->DetachFromCodeGenerator();
108 delete frame_; 108 delete frame_;
109 frame_ = NULL; 109 frame_ = NULL;
110 } 110 }
111 } 111 }
112 112
113 113
114 // Calling conventions: 114 // Calling conventions:
115 // ebp: frame pointer 115 // ebp: frame pointer
116 // esp: stack pointer 116 // esp: stack pointer
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 if (should_trace) { 283 if (should_trace) {
284 frame_->CallRuntime(Runtime::kDebugTrace, 0); 284 frame_->CallRuntime(Runtime::kDebugTrace, 0);
285 // Ignore the return value. 285 // Ignore the return value.
286 } 286 }
287 #endif 287 #endif
288 VisitStatements(body); 288 VisitStatements(body);
289 289
290 // Generate a return statement if necessary. A NULL frame indicates 290 // Generate a return statement if necessary. A NULL frame indicates
291 // that control flow leaves the body on all paths and cannot fall 291 // that control flow leaves the body on all paths and cannot fall
292 // through. 292 // through.
293 if (frame_ != NULL) { 293 if (has_valid_frame()) {
294 Literal undefined(Factory::undefined_value()); 294 Literal undefined(Factory::undefined_value());
295 ReturnStatement statement(&undefined); 295 ReturnStatement statement(&undefined);
296 statement.set_statement_pos(fun->end_position()); 296 statement.set_statement_pos(fun->end_position());
297 VisitReturnStatement(&statement); 297 VisitReturnStatement(&statement);
298 } 298 }
299 } 299 }
300 } 300 }
301 301
302 // Adjust for function-level loop nesting. 302 // Adjust for function-level loop nesting.
303 loop_nesting_ -= fun->loop_nesting(); 303 loop_nesting_ -= fun->loop_nesting();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 JumpTarget* true_target, 382 JumpTarget* true_target,
383 JumpTarget* false_target, 383 JumpTarget* false_target,
384 bool force_cc) { 384 bool force_cc) {
385 ASSERT(!in_spilled_code()); 385 ASSERT(!in_spilled_code());
386 ASSERT(!has_cc()); 386 ASSERT(!has_cc());
387 387
388 { CodeGenState new_state(this, typeof_state, true_target, false_target); 388 { CodeGenState new_state(this, typeof_state, true_target, false_target);
389 Visit(x); 389 Visit(x);
390 } 390 }
391 391
392 if (force_cc && frame_ != NULL && !has_cc()) { 392 if (force_cc && has_valid_frame() && !has_cc()) {
393 // Convert the TOS value to a boolean in the condition code register. 393 // Convert the TOS value to a boolean in the condition code register.
394 VirtualFrame::SpilledScope spilled_scope(this); 394 VirtualFrame::SpilledScope spilled_scope(this);
395 ToBoolean(true_target, false_target); 395 ToBoolean(true_target, false_target);
396 } 396 }
397 397
398 ASSERT(!force_cc || frame_ == NULL || has_cc()); 398 ASSERT(!force_cc || frame_ == NULL || has_cc());
399 } 399 }
400 400
401 401
402 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { 402 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
403 ASSERT(!in_spilled_code()); 403 ASSERT(!in_spilled_code());
404 JumpTarget true_target(this); 404 JumpTarget true_target(this);
405 JumpTarget false_target(this); 405 JumpTarget false_target(this);
406 LoadCondition(x, typeof_state, &true_target, &false_target, false); 406 LoadCondition(x, typeof_state, &true_target, &false_target, false);
407 407
408 if (has_cc()) { 408 if (has_cc()) {
409 ASSERT(frame_ != NULL); 409 ASSERT(has_valid_frame());
410 VirtualFrame::SpilledScope spilled_scope(this); 410 VirtualFrame::SpilledScope spilled_scope(this);
411 // Convert cc_reg_ into a boolean value. 411 // Convert cc_reg_ into a boolean value.
412 JumpTarget loaded(this); 412 JumpTarget loaded(this);
413 JumpTarget materialize_true(this); 413 JumpTarget materialize_true(this);
414 materialize_true.Branch(cc_reg_); 414 materialize_true.Branch(cc_reg_);
415 frame_->EmitPush(Immediate(Factory::false_value())); 415 frame_->EmitPush(Immediate(Factory::false_value()));
416 loaded.Jump(); 416 loaded.Jump();
417 materialize_true.Bind(); 417 materialize_true.Bind();
418 frame_->EmitPush(Immediate(Factory::true_value())); 418 frame_->EmitPush(Immediate(Factory::true_value()));
419 loaded.Bind(); 419 loaded.Bind();
420 cc_reg_ = no_condition; 420 cc_reg_ = no_condition;
421 } 421 }
422 422
423 if (true_target.is_linked() || false_target.is_linked()) { 423 if (true_target.is_linked() || false_target.is_linked()) {
424 // We have at least one condition value that has been "translated" into 424 // We have at least one condition value that has been "translated" into
425 // a branch, thus it needs to be loaded explicitly. 425 // a branch, thus it needs to be loaded explicitly.
426 JumpTarget loaded(this); 426 JumpTarget loaded(this);
427 if (frame_ != NULL) { 427 if (has_valid_frame()) {
428 loaded.Jump(); // Don't lose the current TOS. 428 loaded.Jump(); // Don't lose the current TOS.
429 } 429 }
430 bool both = true_target.is_linked() && false_target.is_linked(); 430 bool both = true_target.is_linked() && false_target.is_linked();
431 // Load "true" if necessary. 431 // Load "true" if necessary.
432 if (true_target.is_linked()) { 432 if (true_target.is_linked()) {
433 true_target.Bind(); 433 true_target.Bind();
434 VirtualFrame::SpilledScope spilled_scope(this); 434 VirtualFrame::SpilledScope spilled_scope(this);
435 frame_->EmitPush(Immediate(Factory::true_value())); 435 frame_->EmitPush(Immediate(Factory::true_value()));
436 } 436 }
437 // If both "true" and "false" need to be reincarnated jump across the 437 // If both "true" and "false" need to be reincarnated jump across the
438 // code for "false". 438 // code for "false".
439 if (both) { 439 if (both) {
440 loaded.Jump(); 440 loaded.Jump();
441 } 441 }
442 // Load "false" if necessary. 442 // Load "false" if necessary.
443 if (false_target.is_linked()) { 443 if (false_target.is_linked()) {
444 false_target.Bind(); 444 false_target.Bind();
445 VirtualFrame::SpilledScope spilled_scope(this); 445 VirtualFrame::SpilledScope spilled_scope(this);
446 frame_->EmitPush(Immediate(Factory::false_value())); 446 frame_->EmitPush(Immediate(Factory::false_value()));
447 } 447 }
448 // A value is loaded on all paths reaching this point. 448 // A value is loaded on all paths reaching this point.
449 loaded.Bind(); 449 loaded.Bind();
450 } 450 }
451 ASSERT(frame_ != NULL); 451 ASSERT(has_valid_frame());
452 ASSERT(!has_cc()); 452 ASSERT(!has_cc());
453 } 453 }
454 454
455 455
456 void CodeGenerator::LoadGlobal() { 456 void CodeGenerator::LoadGlobal() {
457 frame_->EmitPush(GlobalObject()); 457 frame_->EmitPush(GlobalObject());
458 } 458 }
459 459
460 460
461 void CodeGenerator::LoadGlobalReceiver(Register scratch) { 461 void CodeGenerator::LoadGlobalReceiver(Register scratch) {
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 // values including constants must be spilled to the frame. 1350 // values including constants must be spilled to the frame.
1351 frame_->SpillAll(); 1351 frame_->SpillAll();
1352 frame_->CallStub(&stub, 0); 1352 frame_->CallStub(&stub, 0);
1353 stack_is_ok.Bind(); 1353 stack_is_ok.Bind();
1354 } 1354 }
1355 } 1355 }
1356 1356
1357 1357
1358 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) { 1358 void CodeGenerator::VisitStatements(ZoneList<Statement*>* statements) {
1359 ASSERT(!in_spilled_code()); 1359 ASSERT(!in_spilled_code());
1360 for (int i = 0; frame_ != NULL && i < statements->length(); i++) { 1360 for (int i = 0; has_valid_frame() && i < statements->length(); i++) {
1361 Visit(statements->at(i)); 1361 Visit(statements->at(i));
1362 } 1362 }
1363 } 1363 }
1364 1364
1365 1365
1366 void CodeGenerator::VisitBlock(Block* node) { 1366 void CodeGenerator::VisitBlock(Block* node) {
1367 ASSERT(!in_spilled_code()); 1367 ASSERT(!in_spilled_code());
1368 Comment cmnt(masm_, "[ Block"); 1368 Comment cmnt(masm_, "[ Block");
1369 CodeForStatement(node); 1369 CodeForStatement(node);
1370 node->set_break_stack_height(break_stack_height_); 1370 node->set_break_stack_height(break_stack_height_);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 bool has_else_stm = node->HasElseStatement(); 1481 bool has_else_stm = node->HasElseStatement();
1482 1482
1483 CodeForStatement(node); 1483 CodeForStatement(node);
1484 JumpTarget exit(this); 1484 JumpTarget exit(this);
1485 if (has_then_stm && has_else_stm) { 1485 if (has_then_stm && has_else_stm) {
1486 JumpTarget then(this); 1486 JumpTarget then(this);
1487 JumpTarget else_(this); 1487 JumpTarget else_(this);
1488 // if (cond) 1488 // if (cond)
1489 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 1489 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
1490 &then, &else_, true); 1490 &then, &else_, true);
1491 if (frame_ != NULL) { 1491 // An invalid frame here indicates that the code for the condition
1492 // A NULL frame here indicates that the code for the condition cannot 1492 // cannot fall-through, i.e. it caused unconditional jumps to the
1493 // fall-through, i.e. it causes unconditional branchs to targets. 1493 // targets.
1494 if (has_valid_frame()) {
1494 Branch(false, &else_); 1495 Branch(false, &else_);
1495 } 1496 }
1496 // then 1497 // then
1497 if (frame_ != NULL || then.is_linked()) { 1498 if (has_valid_frame() || then.is_linked()) {
1498 // If control flow can reach the then part via fall-through from the 1499 // If control flow can reach the then part via fall-through from the
1499 // test or a branch to the target, compile it. 1500 // test or a branch to the target, compile it.
1500 then.Bind(); 1501 then.Bind();
1501 VisitAndSpill(node->then_statement()); 1502 VisitAndSpill(node->then_statement());
1502 } 1503 }
1503 if (frame_ != NULL) { 1504 // A NULL frame here indicates that control did not fall out of the then
1504 // A NULL frame here indicates that control did not fall out of the 1505 // statement, it escaped on all branches. In that case, a jump to the
1505 // then statement, it escaped on all branches. In that case, a jump 1506 // exit label would be dead code (and impossible, because we don't have
1506 // to the exit label would be dead code (and impossible, because we 1507 // a current virtual frame to set at the exit label).
1507 // don't have a current virtual frame to set at the exit label). 1508 if (has_valid_frame()) {
1508 exit.Jump(); 1509 exit.Jump();
1509 } 1510 }
1510 // else 1511 // else
1511 if (else_.is_linked()) { 1512 if (else_.is_linked()) {
1512 // Control flow for if-then-else does not fall-through to the else 1513 // Control flow for if-then-else does not fall-through to the else
1513 // part, it can only reach here via jump if at all. 1514 // part, it can only reach here via jump if at all.
1514 else_.Bind(); 1515 else_.Bind();
1515 VisitAndSpill(node->else_statement()); 1516 VisitAndSpill(node->else_statement());
1516 } 1517 }
1517 1518
1518 } else if (has_then_stm) { 1519 } else if (has_then_stm) {
1519 ASSERT(!has_else_stm); 1520 ASSERT(!has_else_stm);
1520 JumpTarget then(this); 1521 JumpTarget then(this);
1521 // if (cond) 1522 // if (cond)
1522 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 1523 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
1523 &then, &exit, true); 1524 &then, &exit, true);
1524 if (frame_ != NULL) { 1525 if (has_valid_frame()) {
1525 Branch(false, &exit); 1526 Branch(false, &exit);
1526 } 1527 }
1527 // then 1528 // then
1528 if (frame_ != NULL || then.is_linked()) { 1529 if (has_valid_frame() || then.is_linked()) {
1529 then.Bind(); 1530 then.Bind();
1530 VisitAndSpill(node->then_statement()); 1531 VisitAndSpill(node->then_statement());
1531 } 1532 }
1532 1533
1533 } else if (has_else_stm) { 1534 } else if (has_else_stm) {
1534 ASSERT(!has_then_stm); 1535 ASSERT(!has_then_stm);
1535 JumpTarget else_(this); 1536 JumpTarget else_(this);
1536 // if (!cond) 1537 // if (!cond)
1537 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 1538 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
1538 &exit, &else_, true); 1539 &exit, &else_, true);
1539 if (frame_ != NULL) { 1540 if (has_valid_frame()) {
1540 Branch(true, &exit); 1541 Branch(true, &exit);
1541 } 1542 }
1542 // else 1543 // else
1543 if (frame_ != NULL || else_.is_linked()) { 1544 if (has_valid_frame() || else_.is_linked()) {
1544 else_.Bind(); 1545 else_.Bind();
1545 VisitAndSpill(node->else_statement()); 1546 VisitAndSpill(node->else_statement());
1546 } 1547 }
1547 1548
1548 } else { 1549 } else {
1549 ASSERT(!has_then_stm && !has_else_stm); 1550 ASSERT(!has_then_stm && !has_else_stm);
1550 // if (cond) 1551 // if (cond)
1551 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 1552 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
1552 &exit, &exit, false); 1553 &exit, &exit, false);
1553 if (frame_ != NULL) { 1554 if (has_valid_frame()) {
1554 if (has_cc()) { 1555 if (has_cc()) {
1555 cc_reg_ = no_condition; 1556 cc_reg_ = no_condition;
1556 } else { 1557 } else {
1557 // No cc value set up, that means the boolean was pushed. 1558 // No cc value set up, that means the boolean was pushed.
1558 // Pop it again, since it is not going to be used. 1559 // Pop it again, since it is not going to be used.
1559 frame_->Drop(); 1560 frame_->Drop();
1560 } 1561 }
1561 } 1562 }
1562 } 1563 }
1563 1564
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 if (i > 0 && cases->at(i - 1)->is_default()) { 1800 if (i > 0 && cases->at(i - 1)->is_default()) {
1800 default_exit.Bind(); 1801 default_exit.Bind();
1801 } else { 1802 } else {
1802 fall_through.Bind(); 1803 fall_through.Bind();
1803 fall_through.Unuse(); 1804 fall_through.Unuse();
1804 } 1805 }
1805 VisitStatementsAndSpill(clause->statements()); 1806 VisitStatementsAndSpill(clause->statements());
1806 1807
1807 // If control flow can fall through from the body, jump to the next body 1808 // If control flow can fall through from the body, jump to the next body
1808 // or the end of the statement. 1809 // or the end of the statement.
1809 if (frame_ != NULL) { 1810 if (has_valid_frame()) {
1810 if (i < length - 1 && cases->at(i + 1)->is_default()) { 1811 if (i < length - 1 && cases->at(i + 1)->is_default()) {
1811 default_entry.Jump(); 1812 default_entry.Jump();
1812 } else { 1813 } else {
1813 fall_through.Jump(); 1814 fall_through.Jump();
1814 } 1815 }
1815 } 1816 }
1816 } 1817 }
1817 1818
1818 // The final "test" removes the switch value. 1819 // The final "test" removes the switch value.
1819 next_test.Bind(); 1820 next_test.Bind();
1820 frame_->Drop(); 1821 frame_->Drop();
1821 1822
1822 // If there is a default clause, compile it. 1823 // If there is a default clause, compile it.
1823 if (default_clause != NULL) { 1824 if (default_clause != NULL) {
1824 Comment cmnt(masm_, "[ Default clause"); 1825 Comment cmnt(masm_, "[ Default clause");
1825 default_entry.Bind(); 1826 default_entry.Bind();
1826 VisitStatementsAndSpill(default_clause->statements()); 1827 VisitStatementsAndSpill(default_clause->statements());
1827 if (frame_ != NULL) {
1828 }
1829 // If control flow can fall out of the default and there is a case after 1828 // If control flow can fall out of the default and there is a case after
1830 // it, jump to that case's body. 1829 // it, jump to that case's body.
1831 if (frame_ != NULL && default_exit.is_bound()) { 1830 if (has_valid_frame() && default_exit.is_bound()) {
1832 default_exit.Jump(); 1831 default_exit.Jump();
1833 } 1832 }
1834 } 1833 }
1835 1834
1836 if (fall_through.is_linked()) { 1835 if (fall_through.is_linked()) {
1837 fall_through.Bind(); 1836 fall_through.Bind();
1838 } 1837 }
1839 1838
1840 if (node->break_target()->is_linked()) { 1839 if (node->break_target()->is_linked()) {
1841 node->break_target()->Bind(); 1840 node->break_target()->Bind();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 // There is no need, we will never jump back. 1880 // There is no need, we will never jump back.
1882 } else { 1881 } else {
1883 ASSERT(info == DONT_KNOW); 1882 ASSERT(info == DONT_KNOW);
1884 body.Bind(); 1883 body.Bind();
1885 } 1884 }
1886 CheckStack(); // TODO(1222600): ignore if body contains calls. 1885 CheckStack(); // TODO(1222600): ignore if body contains calls.
1887 VisitAndSpill(node->body()); 1886 VisitAndSpill(node->body());
1888 1887
1889 // Compile the "test". 1888 // Compile the "test".
1890 if (info == ALWAYS_TRUE) { 1889 if (info == ALWAYS_TRUE) {
1891 if (frame_ != NULL) { 1890 if (has_valid_frame()) {
1892 // If control flow can fall off the end of the body, jump back to 1891 // If control flow can fall off the end of the body, jump back to
1893 // the top. 1892 // the top.
1894 node->continue_target()->Jump(); 1893 node->continue_target()->Jump();
1895 } 1894 }
1896 } else if (info == ALWAYS_FALSE) { 1895 } else if (info == ALWAYS_FALSE) {
1897 // If we have a continue in the body, we only have to bind its jump 1896 // If we have a continue in the body, we only have to bind its jump
1898 // target. 1897 // target.
1899 if (node->continue_target()->is_linked()) { 1898 if (node->continue_target()->is_linked()) {
1900 node->continue_target()->Bind(); 1899 node->continue_target()->Bind();
1901 } 1900 }
1902 } else { 1901 } else {
1903 ASSERT(info == DONT_KNOW); 1902 ASSERT(info == DONT_KNOW);
1904 // We have to compile the test expression if it can be reached by 1903 // We have to compile the test expression if it can be reached by
1905 // control flow falling out of the body or via continue. 1904 // control flow falling out of the body or via continue.
1906 if (frame_ != NULL || node->continue_target()->is_linked()) { 1905 if (has_valid_frame() || node->continue_target()->is_linked()) {
1907 node->continue_target()->Bind(); 1906 node->continue_target()->Bind();
1908 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, 1907 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF,
1909 &body, node->break_target(), true); 1908 &body, node->break_target(), true);
1910 if (frame_ != NULL) { 1909 // An invalid frame here indicates that control flow did not fall
1911 // A NULL frame here indicates that control flow did not fall 1910 // out of the test expression.
1912 // out of the test expression. 1911 if (has_valid_frame()) {
1913 Branch(true, &body); 1912 Branch(true, &body);
1914 } 1913 }
1915 } 1914 }
1916 } 1915 }
1917 break; 1916 break;
1918 } 1917 }
1919 1918
1920 case LoopStatement::WHILE_LOOP: { 1919 case LoopStatement::WHILE_LOOP: {
1921 // The new code generator does not yet compile while loops. 1920 // The new code generator does not yet compile while loops.
1922 VirtualFrame::SpilledScope spilled_scope(this); 1921 VirtualFrame::SpilledScope spilled_scope(this);
1923 JumpTarget body(this); 1922 JumpTarget body(this);
1924 IncrementLoopNesting(); 1923 IncrementLoopNesting();
1925 // Generate the loop header. 1924 // Generate the loop header.
1926 if (info == ALWAYS_TRUE) { 1925 if (info == ALWAYS_TRUE) {
1927 // Merely label the body with the continue target. 1926 // Merely label the body with the continue target.
1928 node->continue_target()->Bind(); 1927 node->continue_target()->Bind();
1929 } else if (info == ALWAYS_FALSE) { 1928 } else if (info == ALWAYS_FALSE) {
1930 // There is no need to even compile the test or body. 1929 // There is no need to even compile the test or body.
1931 break; 1930 break;
1932 } else { 1931 } else {
1933 // Compile the test labeled with the continue target and label the 1932 // Compile the test labeled with the continue target and label the
1934 // body with the body target. 1933 // body with the body target.
1935 ASSERT(info == DONT_KNOW); 1934 ASSERT(info == DONT_KNOW);
1936 node->continue_target()->Bind(); 1935 node->continue_target()->Bind();
1937 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF, 1936 LoadConditionAndSpill(node->cond(), NOT_INSIDE_TYPEOF,
1938 &body, node->break_target(), true); 1937 &body, node->break_target(), true);
1939 if (frame_ != NULL) { 1938 // An invalid frame indicates that control did not fall out of the
1940 // A NULL frame indicates that control did not fall out of the 1939 // test expression.
1941 // test expression. 1940 if (has_valid_frame()) {
1942 Branch(false, node->break_target()); 1941 Branch(false, node->break_target());
1943 } 1942 }
1944 if (frame_ != NULL || body.is_linked()) { 1943 if (has_valid_frame() || body.is_linked()) {
1945 body.Bind(); 1944 body.Bind();
1946 } 1945 }
1947 } 1946 }
1948 if (frame_ != NULL) { 1947 if (has_valid_frame()) {
1949 CheckStack(); // TODO(1222600): ignore if body contains calls. 1948 CheckStack(); // TODO(1222600): ignore if body contains calls.
1950 VisitAndSpill(node->body()); 1949 VisitAndSpill(node->body());
1951 1950
1952 // If control flow can fall out of the body, jump back to the top. 1951 // If control flow can fall out of the body, jump back to the top.
1953 if (frame_ != NULL) { 1952 if (has_valid_frame()) {
1954 node->continue_target()->Jump(); 1953 node->continue_target()->Jump();
1955 } 1954 }
1956 } 1955 }
1957 break; 1956 break;
1958 } 1957 }
1959 1958
1960 case LoopStatement::FOR_LOOP: { 1959 case LoopStatement::FOR_LOOP: {
1961 JumpTarget loop(this); 1960 JumpTarget loop(this);
1962 JumpTarget body(this); 1961 JumpTarget body(this);
1963 if (node->init() != NULL) { 1962 if (node->init() != NULL) {
(...skipping 10 matching lines...) Expand all
1974 if (node->next() == NULL) { 1973 if (node->next() == NULL) {
1975 node->continue_target()->Bind(); 1974 node->continue_target()->Bind();
1976 } else { 1975 } else {
1977 loop.Bind(); 1976 loop.Bind();
1978 } 1977 }
1979 1978
1980 // If the test is always true, there is no need to compile it. 1979 // If the test is always true, there is no need to compile it.
1981 if (info == DONT_KNOW) { 1980 if (info == DONT_KNOW) {
1982 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF, 1981 LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
1983 &body, node->break_target(), true); 1982 &body, node->break_target(), true);
1984 if (frame_ != NULL) { 1983 if (has_valid_frame()) {
1985 Branch(false, node->break_target()); 1984 Branch(false, node->break_target());
1986 } 1985 }
1987 if (frame_ != NULL || body.is_linked()) { 1986 if (has_valid_frame() || body.is_linked()) {
1988 body.Bind(); 1987 body.Bind();
1989 } 1988 }
1990 } 1989 }
1991 1990
1992 if (frame_ != NULL) { 1991 if (has_valid_frame()) {
1993 CheckStack(); // TODO(1222600): ignore if body contains calls. 1992 CheckStack(); // TODO(1222600): ignore if body contains calls.
1994 Visit(node->body()); 1993 Visit(node->body());
1995 1994
1996 if (node->next() == NULL) { 1995 if (node->next() == NULL) {
1997 // If there is no update statement and control flow can fall out 1996 // If there is no update statement and control flow can fall out
1998 // of the loop, jump to the continue label. 1997 // of the loop, jump to the continue label.
1999 if (frame_ != NULL) { 1998 if (has_valid_frame()) {
2000 node->continue_target()->Jump(); 1999 node->continue_target()->Jump();
2001 } 2000 }
2002 } else { 2001 } else {
2003 // If there is an update statement and control flow can reach it 2002 // If there is an update statement and control flow can reach it
2004 // via falling out of the body of the loop or continuing, we 2003 // via falling out of the body of the loop or continuing, we
2005 // compile the update statement. 2004 // compile the update statement.
2006 if (frame_ != NULL || node->continue_target()->is_linked()) { 2005 if (has_valid_frame() || node->continue_target()->is_linked()) {
2007 node->continue_target()->Bind(); 2006 node->continue_target()->Bind();
2008 // Record source position of the statement as this code which is 2007 // Record source position of the statement as this code which is
2009 // after the code for the body actually belongs to the loop 2008 // after the code for the body actually belongs to the loop
2010 // statement and not the body. 2009 // statement and not the body.
2011 CodeForStatement(node); 2010 CodeForStatement(node);
2012 ASSERT(node->type() == LoopStatement::FOR_LOOP); 2011 ASSERT(node->type() == LoopStatement::FOR_LOOP);
2013 Visit(node->next()); 2012 Visit(node->next());
2014 loop.Jump(); 2013 loop.Jump();
2015 } 2014 }
2016 } 2015 }
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 // Load the exception to the top of the stack. Here we make use of the 2231 // Load the exception to the top of the stack. Here we make use of the
2233 // convenient property that it doesn't matter whether a value is 2232 // convenient property that it doesn't matter whether a value is
2234 // immediately on top of or underneath a zero-sized reference. 2233 // immediately on top of or underneath a zero-sized reference.
2235 ref.SetValue(NOT_CONST_INIT); 2234 ref.SetValue(NOT_CONST_INIT);
2236 } 2235 }
2237 2236
2238 // Remove the exception from the stack. 2237 // Remove the exception from the stack.
2239 frame_->Drop(); 2238 frame_->Drop();
2240 2239
2241 VisitStatementsAndSpill(node->catch_block()->statements()); 2240 VisitStatementsAndSpill(node->catch_block()->statements());
2242 if (frame_ != NULL) { 2241 if (has_valid_frame()) {
2243 exit.Jump(); 2242 exit.Jump();
2244 } 2243 }
2245 2244
2246 2245
2247 // --- Try block --- 2246 // --- Try block ---
2248 try_block.Bind(); 2247 try_block.Bind();
2249 2248
2250 frame_->PushTryHandler(TRY_CATCH_HANDLER); 2249 frame_->PushTryHandler(TRY_CATCH_HANDLER);
2251 int handler_height = frame_->height(); 2250 int handler_height = frame_->height();
2252 2251
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 // Make sure that there's nothing left on the stack above the 2286 // Make sure that there's nothing left on the stack above the
2288 // handler structure. 2287 // handler structure.
2289 if (FLAG_debug_code) { 2288 if (FLAG_debug_code) {
2290 __ mov(eax, Operand::StaticVariable(handler_address)); 2289 __ mov(eax, Operand::StaticVariable(handler_address));
2291 __ lea(eax, Operand(eax, StackHandlerConstants::kAddressDisplacement)); 2290 __ lea(eax, Operand(eax, StackHandlerConstants::kAddressDisplacement));
2292 __ cmp(esp, Operand(eax)); 2291 __ cmp(esp, Operand(eax));
2293 __ Assert(equal, "stack pointer should point to top handler"); 2292 __ Assert(equal, "stack pointer should point to top handler");
2294 } 2293 }
2295 2294
2296 // If we can fall off the end of the try block, unlink from try chain. 2295 // If we can fall off the end of the try block, unlink from try chain.
2297 if (frame_ != NULL) { 2296 if (has_valid_frame()) {
2298 frame_->EmitPop(eax); 2297 frame_->EmitPop(eax);
2299 __ mov(Operand::StaticVariable(handler_address), eax); // TOS == next_sp 2298 __ mov(Operand::StaticVariable(handler_address), eax); // TOS == next_sp
2300 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2299 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2301 // next_sp popped. 2300 // next_sp popped.
2302 if (nof_unlinks > 0) { 2301 if (nof_unlinks > 0) {
2303 exit.Jump(); 2302 exit.Jump();
2304 } 2303 }
2305 } 2304 }
2306 2305
2307 // Generate unlink code for the (formerly) shadowing targets that have been 2306 // Generate unlink code for the (formerly) shadowing targets that have been
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2385 // ShadowTargets represent the formerly shadowing targets. 2384 // ShadowTargets represent the formerly shadowing targets.
2386 int nof_unlinks = 0; 2385 int nof_unlinks = 0;
2387 for (int i = 0; i <= nof_escapes; i++) { 2386 for (int i = 0; i <= nof_escapes; i++) {
2388 shadows[i]->StopShadowing(); 2387 shadows[i]->StopShadowing();
2389 if (shadows[i]->is_linked()) nof_unlinks++; 2388 if (shadows[i]->is_linked()) nof_unlinks++;
2390 } 2389 }
2391 function_return_is_shadowed_ = function_return_was_shadowed; 2390 function_return_is_shadowed_ = function_return_was_shadowed;
2392 2391
2393 // If we can fall off the end of the try block, set the state on the stack 2392 // If we can fall off the end of the try block, set the state on the stack
2394 // to FALLING. 2393 // to FALLING.
2395 if (frame_ != NULL) { 2394 if (has_valid_frame()) {
2396 frame_->EmitPush(Immediate(Factory::undefined_value())); // fake TOS 2395 frame_->EmitPush(Immediate(Factory::undefined_value())); // fake TOS
2397 __ Set(ecx, Immediate(Smi::FromInt(FALLING))); 2396 __ Set(ecx, Immediate(Smi::FromInt(FALLING)));
2398 if (nof_unlinks > 0) { 2397 if (nof_unlinks > 0) {
2399 unlink.Jump(); 2398 unlink.Jump();
2400 } 2399 }
2401 } 2400 }
2402 2401
2403 // Generate code to set the state for the (formerly) shadowing targets that 2402 // Generate code to set the state for the (formerly) shadowing targets that
2404 // have been jumped to. 2403 // have been jumped to.
2405 for (int i = 0; i <= nof_escapes; i++) { 2404 for (int i = 0; i <= nof_escapes; i++) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 // and the state - while evaluating the finally block. Record it, so 2445 // and the state - while evaluating the finally block. Record it, so
2447 // that a break/continue crossing this statement can restore the 2446 // that a break/continue crossing this statement can restore the
2448 // stack. 2447 // stack.
2449 const int kFinallyStackSize = 2 * kPointerSize; 2448 const int kFinallyStackSize = 2 * kPointerSize;
2450 break_stack_height_ += kFinallyStackSize; 2449 break_stack_height_ += kFinallyStackSize;
2451 2450
2452 // Generate code for the statements in the finally block. 2451 // Generate code for the statements in the finally block.
2453 VisitStatementsAndSpill(node->finally_block()->statements()); 2452 VisitStatementsAndSpill(node->finally_block()->statements());
2454 2453
2455 break_stack_height_ -= kFinallyStackSize; 2454 break_stack_height_ -= kFinallyStackSize;
2456 if (frame_ != NULL) { 2455 if (has_valid_frame()) {
2457 JumpTarget exit(this); 2456 JumpTarget exit(this);
2458 // Restore state and return value or faked TOS. 2457 // Restore state and return value or faked TOS.
2459 frame_->EmitPop(ecx); 2458 frame_->EmitPop(ecx);
2460 frame_->EmitPop(eax); 2459 frame_->EmitPop(eax);
2461 2460
2462 // Generate code to jump to the right destination for all used 2461 // Generate code to jump to the right destination for all used
2463 // (formerly) shadowing targets. 2462 // (formerly) shadowing targets.
2464 for (int i = 0; i <= nof_escapes; i++) { 2463 for (int i = 0; i <= nof_escapes; i++) {
2465 if (shadows[i]->is_bound()) { 2464 if (shadows[i]->is_bound()) {
2466 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); 2465 __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i)));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2526 2525
2527 2526
2528 void CodeGenerator::VisitConditional(Conditional* node) { 2527 void CodeGenerator::VisitConditional(Conditional* node) {
2529 VirtualFrame::SpilledScope spilled_scope(this); 2528 VirtualFrame::SpilledScope spilled_scope(this);
2530 Comment cmnt(masm_, "[ Conditional"); 2529 Comment cmnt(masm_, "[ Conditional");
2531 JumpTarget then(this); 2530 JumpTarget then(this);
2532 JumpTarget else_(this); 2531 JumpTarget else_(this);
2533 JumpTarget exit(this); 2532 JumpTarget exit(this);
2534 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF, 2533 LoadConditionAndSpill(node->condition(), NOT_INSIDE_TYPEOF,
2535 &then, &else_, true); 2534 &then, &else_, true);
2536 if (frame_ != NULL) { 2535 if (has_valid_frame()) {
2537 Branch(false, &else_); 2536 Branch(false, &else_);
2538 } 2537 }
2539 if (frame_ != NULL || then.is_linked()) { 2538 if (has_valid_frame() || then.is_linked()) {
2540 then.Bind(); 2539 then.Bind();
2541 LoadAndSpill(node->then_expression(), typeof_state()); 2540 LoadAndSpill(node->then_expression(), typeof_state());
2542 exit.Jump(); 2541 exit.Jump();
2543 } 2542 }
2544 if (else_.is_linked()) { 2543 if (else_.is_linked()) {
2545 else_.Bind(); 2544 else_.Bind();
2546 LoadAndSpill(node->else_expression(), typeof_state()); 2545 LoadAndSpill(node->else_expression(), typeof_state());
2547 } 2546 }
2548 exit.Bind(); 2547 exit.Bind();
2549 } 2548 }
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2692 Expression* expr = var->rewrite(); 2691 Expression* expr = var->rewrite();
2693 if (expr != NULL) { 2692 if (expr != NULL) {
2694 // We have to be wary of calling Visit directly on expressions. Because 2693 // We have to be wary of calling Visit directly on expressions. Because
2695 // of special casing comparisons of the form typeof<expr> === "string", 2694 // of special casing comparisons of the form typeof<expr> === "string",
2696 // we can return from a call from Visit (to a comparison or a unary 2695 // we can return from a call from Visit (to a comparison or a unary
2697 // operation) without a virtual frame; which will probably crash if we 2696 // operation) without a virtual frame; which will probably crash if we
2698 // try to emit frame code before reestablishing a frame. Here we're 2697 // try to emit frame code before reestablishing a frame. Here we're
2699 // safe as long as variable proxies can't rewrite into typeof 2698 // safe as long as variable proxies can't rewrite into typeof
2700 // comparisons or unary logical not expressions. 2699 // comparisons or unary logical not expressions.
2701 Visit(expr); 2700 Visit(expr);
2702 ASSERT(frame_ != NULL); 2701 ASSERT(has_valid_frame());
2703 } else { 2702 } else {
2704 ASSERT(var->is_global()); 2703 ASSERT(var->is_global());
2705 Reference ref(this, node); 2704 Reference ref(this, node);
2706 ref.GetValue(typeof_state()); 2705 ref.GetValue(typeof_state());
2707 } 2706 }
2708 } 2707 }
2709 2708
2710 2709
2711 void CodeGenerator::VisitLiteral(Literal* node) { 2710 void CodeGenerator::VisitLiteral(Literal* node) {
2712 Comment cmnt(masm_, "[ Literal"); 2711 Comment cmnt(masm_, "[ Literal");
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3868 // after evaluating the left hand side (due to the shortcut 3867 // after evaluating the left hand side (due to the shortcut
3869 // semantics), but the compiler must (statically) know if the result 3868 // semantics), but the compiler must (statically) know if the result
3870 // of compiling the binary operation is materialized or not. 3869 // of compiling the binary operation is materialized or not.
3871 3870
3872 if (op == Token::AND) { 3871 if (op == Token::AND) {
3873 JumpTarget is_true(this); 3872 JumpTarget is_true(this);
3874 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF, 3873 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF,
3875 &is_true, false_target(), false); 3874 &is_true, false_target(), false);
3876 if (has_cc() || frame_ == NULL) { 3875 if (has_cc() || frame_ == NULL) {
3877 if (has_cc()) { 3876 if (has_cc()) {
3878 ASSERT(frame_ != NULL); 3877 ASSERT(has_valid_frame());
3879 Branch(false, false_target()); 3878 Branch(false, false_target());
3880 } 3879 }
3881 3880
3882 if (frame_ != NULL || is_true.is_linked()) { 3881 if (has_valid_frame() || is_true.is_linked()) {
3883 // Evaluate right side expression. 3882 // Evaluate right side expression.
3884 is_true.Bind(); 3883 is_true.Bind();
3885 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF, 3884 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF,
3886 true_target(), false_target(), false); 3885 true_target(), false_target(), false);
3887 } 3886 }
3888 } else { 3887 } else {
3889 // We have a materialized value on the frame. 3888 // We have a materialized value on the frame.
3890 JumpTarget pop_and_continue(this); 3889 JumpTarget pop_and_continue(this);
3891 JumpTarget exit(this); 3890 JumpTarget exit(this);
3892 3891
(...skipping 18 matching lines...) Expand all
3911 // Exit (always with a materialized value). 3910 // Exit (always with a materialized value).
3912 exit.Bind(); 3911 exit.Bind();
3913 } 3912 }
3914 3913
3915 } else if (op == Token::OR) { 3914 } else if (op == Token::OR) {
3916 JumpTarget is_false(this); 3915 JumpTarget is_false(this);
3917 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF, 3916 LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF,
3918 true_target(), &is_false, false); 3917 true_target(), &is_false, false);
3919 if (has_cc() || frame_ == NULL) { 3918 if (has_cc() || frame_ == NULL) {
3920 if (has_cc()) { 3919 if (has_cc()) {
3921 ASSERT(frame_ != NULL); 3920 ASSERT(has_valid_frame());
3922 Branch(true, true_target()); 3921 Branch(true, true_target());
3923 } 3922 }
3924 3923
3925 if (frame_ != NULL || is_false.is_linked()) { 3924 if (has_valid_frame() || is_false.is_linked()) {
3926 // Evaluate right side expression. 3925 // Evaluate right side expression.
3927 is_false.Bind(); 3926 is_false.Bind();
3928 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF, 3927 LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF,
3929 true_target(), false_target(), false); 3928 true_target(), false_target(), false);
3930 } 3929 }
3931 3930
3932 } else { 3931 } else {
3933 // We have a materialized value on the frame. 3932 // We have a materialized value on the frame.
3934 JumpTarget pop_and_continue(this); 3933 JumpTarget pop_and_continue(this);
3935 JumpTarget exit(this); 3934 JumpTarget exit(this);
(...skipping 1829 matching lines...) Expand 10 before | Expand all | Expand 10 after
5765 5764
5766 // Slow-case: Go through the JavaScript implementation. 5765 // Slow-case: Go through the JavaScript implementation.
5767 __ bind(&slow); 5766 __ bind(&slow);
5768 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5767 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5769 } 5768 }
5770 5769
5771 5770
5772 #undef __ 5771 #undef __
5773 5772
5774 } } // namespace v8::internal 5773 } } // 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