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

Side by Side Diff: src/x64/fast-codegen-x64.cc

Issue 550010: Cleanup the handling of control flow in the toplevel code generator.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 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/ia32/fast-codegen-ia32.cc ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 __ jmp(false_label_); 1252 __ jmp(false_label_);
1253 break; 1253 break;
1254 } 1254 }
1255 break; 1255 break;
1256 } 1256 }
1257 1257
1258 case Token::NOT: { 1258 case Token::NOT: {
1259 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 1259 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
1260 ASSERT_EQ(Expression::kTest, expr->expression()->context()); 1260 ASSERT_EQ(Expression::kTest, expr->expression()->context());
1261 1261
1262 Label push_true; 1262 Label push_true, push_false, done;
1263 Label push_false;
1264 Label done;
1265 Label* saved_true = true_label_;
1266 Label* saved_false = false_label_;
1267 switch (expr->context()) { 1263 switch (expr->context()) {
1268 case Expression::kUninitialized: 1264 case Expression::kUninitialized:
1269 UNREACHABLE(); 1265 UNREACHABLE();
1270 break; 1266 break;
1271 1267
1272 case Expression::kValue: 1268 case Expression::kValue:
1273 true_label_ = &push_false; 1269 VisitForControl(expr->expression(), &push_false, &push_true);
1274 false_label_ = &push_true;
1275 Visit(expr->expression());
1276 __ bind(&push_true); 1270 __ bind(&push_true);
1277 __ PushRoot(Heap::kTrueValueRootIndex); 1271 __ PushRoot(Heap::kTrueValueRootIndex);
1278 __ jmp(&done); 1272 __ jmp(&done);
1279 __ bind(&push_false); 1273 __ bind(&push_false);
1280 __ PushRoot(Heap::kFalseValueRootIndex); 1274 __ PushRoot(Heap::kFalseValueRootIndex);
1281 __ bind(&done); 1275 __ bind(&done);
1282 break; 1276 break;
1283 1277
1284 case Expression::kEffect: 1278 case Expression::kEffect:
1285 true_label_ = &done; 1279 VisitForControl(expr->expression(), &done, &done);
1286 false_label_ = &done;
1287 Visit(expr->expression());
1288 __ bind(&done); 1280 __ bind(&done);
1289 break; 1281 break;
1290 1282
1291 case Expression::kTest: 1283 case Expression::kTest:
1292 true_label_ = saved_false; 1284 VisitForControl(expr->expression(), false_label_, true_label_);
1293 false_label_ = saved_true;
1294 Visit(expr->expression());
1295 break; 1285 break;
1296 1286
1297 case Expression::kValueTest: 1287 case Expression::kValueTest:
1298 true_label_ = saved_false; 1288 VisitForControl(expr->expression(), false_label_, &push_true);
1299 false_label_ = &push_true;
1300 Visit(expr->expression());
1301 __ bind(&push_true); 1289 __ bind(&push_true);
1302 __ PushRoot(Heap::kTrueValueRootIndex); 1290 __ PushRoot(Heap::kTrueValueRootIndex);
1303 __ jmp(saved_true); 1291 __ jmp(true_label_);
1304 break; 1292 break;
1305 1293
1306 case Expression::kTestValue: 1294 case Expression::kTestValue:
1307 true_label_ = &push_false; 1295 VisitForControl(expr->expression(), &push_false, true_label_);
1308 false_label_ = saved_true;
1309 Visit(expr->expression());
1310 __ bind(&push_false); 1296 __ bind(&push_false);
1311 __ PushRoot(Heap::kFalseValueRootIndex); 1297 __ PushRoot(Heap::kFalseValueRootIndex);
1312 __ jmp(saved_false); 1298 __ jmp(false_label_);
1313 break; 1299 break;
1314 } 1300 }
1315 true_label_ = saved_true;
1316 false_label_ = saved_false;
1317 break; 1301 break;
1318 } 1302 }
1319 1303
1320 case Token::TYPEOF: { 1304 case Token::TYPEOF: {
1321 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 1305 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
1322 ASSERT_EQ(Expression::kValue, expr->expression()->context()); 1306 ASSERT_EQ(Expression::kValue, expr->expression()->context());
1323 1307
1324 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 1308 VariableProxy* proxy = expr->expression()->AsVariableProxy();
1325 if (proxy != NULL && 1309 if (proxy != NULL &&
1326 !proxy->var()->is_this() && 1310 !proxy->var()->is_this() &&
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1534 } 1518 }
1535 1519
1536 1520
1537 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1521 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1538 Comment cmnt(masm_, "[ CompareOperation"); 1522 Comment cmnt(masm_, "[ CompareOperation");
1539 ASSERT_EQ(Expression::kValue, expr->left()->context()); 1523 ASSERT_EQ(Expression::kValue, expr->left()->context());
1540 ASSERT_EQ(Expression::kValue, expr->right()->context()); 1524 ASSERT_EQ(Expression::kValue, expr->right()->context());
1541 Visit(expr->left()); 1525 Visit(expr->left());
1542 Visit(expr->right()); 1526 Visit(expr->right());
1543 1527
1544 // Convert current context to test context: Pre-test code. 1528 // Always perform the comparison for its control flow. Pack the result
1545 Label push_true; 1529 // into the expression's context after the comparison is performed.
1546 Label push_false; 1530 Label push_true, push_false, done;
1547 Label done; 1531 // Initially assume we are in a test context.
1548 Label* saved_true = true_label_; 1532 Label* if_true = true_label_;
1549 Label* saved_false = false_label_; 1533 Label* if_false = false_label_;
1550 switch (expr->context()) { 1534 switch (expr->context()) {
1551 case Expression::kUninitialized: 1535 case Expression::kUninitialized:
1552 UNREACHABLE(); 1536 UNREACHABLE();
1553 break; 1537 break;
1554
1555 case Expression::kValue: 1538 case Expression::kValue:
1556 true_label_ = &push_true; 1539 if_true = &push_true;
1557 false_label_ = &push_false; 1540 if_false = &push_false;
1558 break; 1541 break;
1559
1560 case Expression::kEffect: 1542 case Expression::kEffect:
1561 true_label_ = &done; 1543 if_true = &done;
1562 false_label_ = &done; 1544 if_false = &done;
1563 break; 1545 break;
1564
1565 case Expression::kTest: 1546 case Expression::kTest:
1566 break; 1547 break;
1567
1568 case Expression::kValueTest: 1548 case Expression::kValueTest:
1569 true_label_ = &push_true; 1549 if_true = &push_true;
1570 break; 1550 break;
1571
1572 case Expression::kTestValue: 1551 case Expression::kTestValue:
1573 false_label_ = &push_false; 1552 if_false = &push_false;
1574 break; 1553 break;
1575 } 1554 }
1576 // Convert current context to test context: End pre-test code.
1577 1555
1578 switch (expr->op()) { 1556 switch (expr->op()) {
1579 case Token::IN: { 1557 case Token::IN: {
1580 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 1558 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
1581 __ CompareRoot(rax, Heap::kTrueValueRootIndex); 1559 __ CompareRoot(rax, Heap::kTrueValueRootIndex);
1582 __ j(equal, true_label_); 1560 __ j(equal, if_true);
1583 __ jmp(false_label_); 1561 __ jmp(if_false);
1584 break; 1562 break;
1585 } 1563 }
1586 1564
1587 case Token::INSTANCEOF: { 1565 case Token::INSTANCEOF: {
1588 InstanceofStub stub; 1566 InstanceofStub stub;
1589 __ CallStub(&stub); 1567 __ CallStub(&stub);
1590 __ testq(rax, rax); 1568 __ testq(rax, rax);
1591 __ j(zero, true_label_); // The stub returns 0 for true. 1569 __ j(zero, if_true); // The stub returns 0 for true.
1592 __ jmp(false_label_); 1570 __ jmp(if_false);
1593 break; 1571 break;
1594 } 1572 }
1595 1573
1596 default: { 1574 default: {
1597 Condition cc = no_condition; 1575 Condition cc = no_condition;
1598 bool strict = false; 1576 bool strict = false;
1599 switch (expr->op()) { 1577 switch (expr->op()) {
1600 case Token::EQ_STRICT: 1578 case Token::EQ_STRICT:
1601 strict = true; 1579 strict = true;
1602 // Fall through. 1580 // Fall through.
(...skipping 28 matching lines...) Expand all
1631 case Token::INSTANCEOF: 1609 case Token::INSTANCEOF:
1632 default: 1610 default:
1633 UNREACHABLE(); 1611 UNREACHABLE();
1634 } 1612 }
1635 1613
1636 // The comparison stub expects the smi vs. smi case to be handled 1614 // The comparison stub expects the smi vs. smi case to be handled
1637 // before it is called. 1615 // before it is called.
1638 Label slow_case; 1616 Label slow_case;
1639 __ JumpIfNotBothSmi(rax, rdx, &slow_case); 1617 __ JumpIfNotBothSmi(rax, rdx, &slow_case);
1640 __ SmiCompare(rdx, rax); 1618 __ SmiCompare(rdx, rax);
1641 __ j(cc, true_label_); 1619 __ j(cc, if_true);
1642 __ jmp(false_label_); 1620 __ jmp(if_false);
1643 1621
1644 __ bind(&slow_case); 1622 __ bind(&slow_case);
1645 CompareStub stub(cc, strict); 1623 CompareStub stub(cc, strict);
1646 __ CallStub(&stub); 1624 __ CallStub(&stub);
1647 __ testq(rax, rax); 1625 __ testq(rax, rax);
1648 __ j(cc, true_label_); 1626 __ j(cc, if_true);
1649 __ jmp(false_label_); 1627 __ jmp(if_false);
1650 } 1628 }
1651 } 1629 }
1652 1630
1653 // Convert current context to test context: Post-test code. 1631 // Convert the result of the comparison into one expected for this
1632 // expression's context.
1654 switch (expr->context()) { 1633 switch (expr->context()) {
1655 case Expression::kUninitialized: 1634 case Expression::kUninitialized:
1656 UNREACHABLE(); 1635 UNREACHABLE();
1657 break; 1636 break;
1658 1637
1638 case Expression::kEffect:
1639 __ bind(&done);
1640 break;
1641
1659 case Expression::kValue: 1642 case Expression::kValue:
1660 __ bind(&push_true); 1643 __ bind(&push_true);
1661 __ PushRoot(Heap::kTrueValueRootIndex); 1644 __ PushRoot(Heap::kTrueValueRootIndex);
1662 __ jmp(&done); 1645 __ jmp(&done);
1663 __ bind(&push_false); 1646 __ bind(&push_false);
1664 __ PushRoot(Heap::kFalseValueRootIndex); 1647 __ PushRoot(Heap::kFalseValueRootIndex);
1665 __ bind(&done); 1648 __ bind(&done);
1666 break; 1649 break;
1667 1650
1668 case Expression::kEffect:
1669 __ bind(&done);
1670 break;
1671
1672 case Expression::kTest: 1651 case Expression::kTest:
1673 break; 1652 break;
1674 1653
1675 case Expression::kValueTest: 1654 case Expression::kValueTest:
1676 __ bind(&push_true); 1655 __ bind(&push_true);
1677 __ PushRoot(Heap::kTrueValueRootIndex); 1656 __ PushRoot(Heap::kTrueValueRootIndex);
1678 __ jmp(saved_true); 1657 __ jmp(true_label_);
1679 break; 1658 break;
1680 1659
1681 case Expression::kTestValue: 1660 case Expression::kTestValue:
1682 __ bind(&push_false); 1661 __ bind(&push_false);
1683 __ PushRoot(Heap::kFalseValueRootIndex); 1662 __ PushRoot(Heap::kFalseValueRootIndex);
1684 __ jmp(saved_false); 1663 __ jmp(false_label_);
1685 break; 1664 break;
1686 } 1665 }
1687 true_label_ = saved_true;
1688 false_label_ = saved_false;
1689 // Convert current context to test context: End post-test code.
1690 } 1666 }
1691 1667
1692 1668
1693 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1669 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1694 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 1670 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
1695 Apply(expr->context(), rax); 1671 Apply(expr->context(), rax);
1696 } 1672 }
1697 1673
1698 1674
1699 Register FastCodeGenerator::result_register() { return rax; } 1675 Register FastCodeGenerator::result_register() { return rax; }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 __ movq(Operand(rsp, 0), rdx); 1720 __ movq(Operand(rsp, 0), rdx);
1745 // And return. 1721 // And return.
1746 __ ret(0); 1722 __ ret(0);
1747 } 1723 }
1748 1724
1749 1725
1750 #undef __ 1726 #undef __
1751 1727
1752 1728
1753 } } // namespace v8::internal 1729 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698