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

Side by Side Diff: src/ia32/fast-codegen-ia32.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/fast-codegen.cc ('k') | src/x64/fast-codegen-x64.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 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 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 __ jmp(false_label_); 1233 __ jmp(false_label_);
1234 break; 1234 break;
1235 } 1235 }
1236 break; 1236 break;
1237 } 1237 }
1238 1238
1239 case Token::NOT: { 1239 case Token::NOT: {
1240 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 1240 Comment cmnt(masm_, "[ UnaryOperation (NOT)");
1241 ASSERT_EQ(Expression::kTest, expr->expression()->context()); 1241 ASSERT_EQ(Expression::kTest, expr->expression()->context());
1242 1242
1243 Label push_true; 1243 Label push_true, push_false, done;
1244 Label push_false;
1245 Label done;
1246 Label* saved_true = true_label_;
1247 Label* saved_false = false_label_;
1248 switch (expr->context()) { 1244 switch (expr->context()) {
1249 case Expression::kUninitialized: 1245 case Expression::kUninitialized:
1250 UNREACHABLE(); 1246 UNREACHABLE();
1251 break; 1247 break;
1252 1248
1249 case Expression::kEffect:
1250 VisitForControl(expr->expression(), &done, &done);
1251 __ bind(&done);
1252 break;
1253
1253 case Expression::kValue: 1254 case Expression::kValue:
1254 true_label_ = &push_false; 1255 VisitForControl(expr->expression(), &push_false, &push_true);
1255 false_label_ = &push_true;
1256 Visit(expr->expression());
1257 __ bind(&push_true); 1256 __ bind(&push_true);
1258 __ push(Immediate(Factory::true_value())); 1257 __ push(Immediate(Factory::true_value()));
1259 __ jmp(&done); 1258 __ jmp(&done);
1260 __ bind(&push_false); 1259 __ bind(&push_false);
1261 __ push(Immediate(Factory::false_value())); 1260 __ push(Immediate(Factory::false_value()));
1262 __ bind(&done); 1261 __ bind(&done);
1263 break; 1262 break;
1264 1263
1265 case Expression::kEffect:
1266 true_label_ = &done;
1267 false_label_ = &done;
1268 Visit(expr->expression());
1269 __ bind(&done);
1270 break;
1271
1272 case Expression::kTest: 1264 case Expression::kTest:
1273 true_label_ = saved_false; 1265 VisitForControl(expr->expression(), false_label_, true_label_);
1274 false_label_ = saved_true;
1275 Visit(expr->expression());
1276 break; 1266 break;
1277 1267
1278 case Expression::kValueTest: 1268 case Expression::kValueTest:
1279 true_label_ = saved_false; 1269 VisitForControl(expr->expression(), false_label_, &push_true);
1280 false_label_ = &push_true;
1281 Visit(expr->expression());
1282 __ bind(&push_true); 1270 __ bind(&push_true);
1283 __ push(Immediate(Factory::true_value())); 1271 __ push(Immediate(Factory::true_value()));
1284 __ jmp(saved_true); 1272 __ jmp(true_label_);
1285 break; 1273 break;
1286 1274
1287 case Expression::kTestValue: 1275 case Expression::kTestValue:
1288 true_label_ = &push_false; 1276 VisitForControl(expr->expression(), &push_false, true_label_);
1289 false_label_ = saved_true;
1290 Visit(expr->expression());
1291 __ bind(&push_false); 1277 __ bind(&push_false);
1292 __ push(Immediate(Factory::false_value())); 1278 __ push(Immediate(Factory::false_value()));
1293 __ jmp(saved_false); 1279 __ jmp(false_label_);
1294 break; 1280 break;
1295 } 1281 }
1296 true_label_ = saved_true;
1297 false_label_ = saved_false;
1298 break; 1282 break;
1299 } 1283 }
1300 1284
1301 case Token::TYPEOF: { 1285 case Token::TYPEOF: {
1302 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 1286 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
1303 ASSERT_EQ(Expression::kValue, expr->expression()->context()); 1287 ASSERT_EQ(Expression::kValue, expr->expression()->context());
1304 1288
1305 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 1289 VariableProxy* proxy = expr->expression()->AsVariableProxy();
1306 if (proxy != NULL && 1290 if (proxy != NULL &&
1307 !proxy->var()->is_this() && 1291 !proxy->var()->is_this() &&
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 } 1500 }
1517 1501
1518 1502
1519 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 1503 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
1520 Comment cmnt(masm_, "[ CompareOperation"); 1504 Comment cmnt(masm_, "[ CompareOperation");
1521 ASSERT_EQ(Expression::kValue, expr->left()->context()); 1505 ASSERT_EQ(Expression::kValue, expr->left()->context());
1522 ASSERT_EQ(Expression::kValue, expr->right()->context()); 1506 ASSERT_EQ(Expression::kValue, expr->right()->context());
1523 Visit(expr->left()); 1507 Visit(expr->left());
1524 Visit(expr->right()); 1508 Visit(expr->right());
1525 1509
1526 // Convert current context to test context: Pre-test code. 1510 // Always perform the comparison for its control flow. Pack the result
1527 Label push_true; 1511 // into the expression's context after the comparison is performed.
1528 Label push_false; 1512 Label push_true, push_false, done;
1529 Label done; 1513 // Initially assume we are in a test context.
1530 Label* saved_true = true_label_; 1514 Label* if_true = true_label_;
1531 Label* saved_false = false_label_; 1515 Label* if_false = false_label_;
1532 switch (expr->context()) { 1516 switch (expr->context()) {
1533 case Expression::kUninitialized: 1517 case Expression::kUninitialized:
1534 UNREACHABLE(); 1518 UNREACHABLE();
1535 break; 1519 break;
1536 1520 case Expression::kEffect:
1521 if_true = &done;
1522 if_false = &done;
1523 break;
1537 case Expression::kValue: 1524 case Expression::kValue:
1538 true_label_ = &push_true; 1525 if_true = &push_true;
1539 false_label_ = &push_false; 1526 if_false = &push_false;
1540 break; 1527 break;
1541
1542 case Expression::kEffect:
1543 true_label_ = &done;
1544 false_label_ = &done;
1545 break;
1546
1547 case Expression::kTest: 1528 case Expression::kTest:
1548 break; 1529 break;
1549
1550 case Expression::kValueTest: 1530 case Expression::kValueTest:
1551 true_label_ = &push_true; 1531 if_true = &push_true;
1552 break; 1532 break;
1553
1554 case Expression::kTestValue: 1533 case Expression::kTestValue:
1555 false_label_ = &push_false; 1534 if_false = &push_false;
1556 break; 1535 break;
1557 } 1536 }
1558 // Convert current context to test context: End pre-test code.
1559 1537
1560 switch (expr->op()) { 1538 switch (expr->op()) {
1561 case Token::IN: { 1539 case Token::IN: {
1562 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 1540 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
1563 __ cmp(eax, Factory::true_value()); 1541 __ cmp(eax, Factory::true_value());
1564 __ j(equal, true_label_); 1542 __ j(equal, if_true);
1565 __ jmp(false_label_); 1543 __ jmp(if_false);
1566 break; 1544 break;
1567 } 1545 }
1568 1546
1569 case Token::INSTANCEOF: { 1547 case Token::INSTANCEOF: {
1570 InstanceofStub stub; 1548 InstanceofStub stub;
1571 __ CallStub(&stub); 1549 __ CallStub(&stub);
1572 __ test(eax, Operand(eax)); 1550 __ test(eax, Operand(eax));
1573 __ j(zero, true_label_); // The stub returns 0 for true. 1551 __ j(zero, if_true); // The stub returns 0 for true.
1574 __ jmp(false_label_); 1552 __ jmp(if_false);
1575 break; 1553 break;
1576 } 1554 }
1577 1555
1578 default: { 1556 default: {
1579 Condition cc = no_condition; 1557 Condition cc = no_condition;
1580 bool strict = false; 1558 bool strict = false;
1581 switch (expr->op()) { 1559 switch (expr->op()) {
1582 case Token::EQ_STRICT: 1560 case Token::EQ_STRICT:
1583 strict = true; 1561 strict = true;
1584 // Fall through 1562 // Fall through
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 } 1594 }
1617 1595
1618 // The comparison stub expects the smi vs. smi case to be handled 1596 // The comparison stub expects the smi vs. smi case to be handled
1619 // before it is called. 1597 // before it is called.
1620 Label slow_case; 1598 Label slow_case;
1621 __ mov(ecx, Operand(edx)); 1599 __ mov(ecx, Operand(edx));
1622 __ or_(ecx, Operand(eax)); 1600 __ or_(ecx, Operand(eax));
1623 __ test(ecx, Immediate(kSmiTagMask)); 1601 __ test(ecx, Immediate(kSmiTagMask));
1624 __ j(not_zero, &slow_case, not_taken); 1602 __ j(not_zero, &slow_case, not_taken);
1625 __ cmp(edx, Operand(eax)); 1603 __ cmp(edx, Operand(eax));
1626 __ j(cc, true_label_); 1604 __ j(cc, if_true);
1627 __ jmp(false_label_); 1605 __ jmp(if_false);
1628 1606
1629 __ bind(&slow_case); 1607 __ bind(&slow_case);
1630 CompareStub stub(cc, strict); 1608 CompareStub stub(cc, strict);
1631 __ CallStub(&stub); 1609 __ CallStub(&stub);
1632 __ test(eax, Operand(eax)); 1610 __ test(eax, Operand(eax));
1633 __ j(cc, true_label_); 1611 __ j(cc, if_true);
1634 __ jmp(false_label_); 1612 __ jmp(if_false);
1635 } 1613 }
1636 } 1614 }
1637 1615
1638 // Convert current context to test context: Post-test code. 1616 // Convert the result of the comparison into one expected for this
1617 // expression's context.
1639 switch (expr->context()) { 1618 switch (expr->context()) {
1640 case Expression::kUninitialized: 1619 case Expression::kUninitialized:
1641 UNREACHABLE(); 1620 UNREACHABLE();
1642 break; 1621 break;
1643 1622
1623 case Expression::kEffect:
1624 __ bind(&done);
1625 break;
1626
1644 case Expression::kValue: 1627 case Expression::kValue:
1645 __ bind(&push_true); 1628 __ bind(&push_true);
1646 __ push(Immediate(Factory::true_value())); 1629 __ push(Immediate(Factory::true_value()));
1647 __ jmp(&done); 1630 __ jmp(&done);
1648 __ bind(&push_false); 1631 __ bind(&push_false);
1649 __ push(Immediate(Factory::false_value())); 1632 __ push(Immediate(Factory::false_value()));
1650 __ bind(&done); 1633 __ bind(&done);
1651 break; 1634 break;
1652 1635
1653 case Expression::kEffect:
1654 __ bind(&done);
1655 break;
1656
1657 case Expression::kTest: 1636 case Expression::kTest:
1658 break; 1637 break;
1659 1638
1660 case Expression::kValueTest: 1639 case Expression::kValueTest:
1661 __ bind(&push_true); 1640 __ bind(&push_true);
1662 __ push(Immediate(Factory::true_value())); 1641 __ push(Immediate(Factory::true_value()));
1663 __ jmp(saved_true); 1642 __ jmp(true_label_);
1664 break; 1643 break;
1665 1644
1666 case Expression::kTestValue: 1645 case Expression::kTestValue:
1667 __ bind(&push_false); 1646 __ bind(&push_false);
1668 __ push(Immediate(Factory::false_value())); 1647 __ push(Immediate(Factory::false_value()));
1669 __ jmp(saved_false); 1648 __ jmp(false_label_);
1670 break; 1649 break;
1671 } 1650 }
1672 true_label_ = saved_true;
1673 false_label_ = saved_false;
1674 // Convert current context to test context: End post-test code.
1675 } 1651 }
1676 1652
1677 1653
1678 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 1654 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
1679 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1655 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
1680 Apply(expr->context(), eax); 1656 Apply(expr->context(), eax);
1681 } 1657 }
1682 1658
1683 1659
1684 Register FastCodeGenerator::result_register() { return eax; } 1660 Register FastCodeGenerator::result_register() { return eax; }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 __ add(Operand(edx), Immediate(masm_->CodeObject())); 1701 __ add(Operand(edx), Immediate(masm_->CodeObject()));
1726 __ mov(Operand(esp, 0), edx); 1702 __ mov(Operand(esp, 0), edx);
1727 // And return. 1703 // And return.
1728 __ ret(0); 1704 __ ret(0);
1729 } 1705 }
1730 1706
1731 1707
1732 #undef __ 1708 #undef __
1733 1709
1734 } } // namespace v8::internal 1710 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.cc ('k') | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698