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

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 10632010: Fix excessive deoptimizations in Meteor: kSHL on two Smi-s can easily overflow, which led to deopti… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | « no previous file | runtime/vm/intermediate_language_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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 return summary; 1400 return summary;
1401 } else if (op_kind() == Token::kSHR) { 1401 } else if (op_kind() == Token::kSHR) {
1402 const intptr_t kNumTemps = 1; 1402 const intptr_t kNumTemps = 1;
1403 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1403 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1404 summary->set_in(0, Location::RequiresRegister()); 1404 summary->set_in(0, Location::RequiresRegister());
1405 summary->set_in(1, Location::RegisterLocation(ECX)); 1405 summary->set_in(1, Location::RegisterLocation(ECX));
1406 summary->set_out(Location::SameAsFirstInput()); 1406 summary->set_out(Location::SameAsFirstInput());
1407 summary->set_temp(0, Location::RequiresRegister()); 1407 summary->set_temp(0, Location::RequiresRegister());
1408 return summary; 1408 return summary;
1409 } else if (op_kind() == Token::kSHL) { 1409 } else if (op_kind() == Token::kSHL) {
1410 // Two Smi operands can easily overflow into Mint.
1410 const intptr_t kNumTemps = 2; 1411 const intptr_t kNumTemps = 2;
1411 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1412 LocationSummary* summary =
1412 summary->set_in(0, Location::RequiresRegister()); 1413 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1414 summary->set_in(0, Location::RegisterLocation(EAX));
1413 summary->set_in(1, Location::RequiresRegister()); 1415 summary->set_in(1, Location::RequiresRegister());
1414 summary->set_out(Location::SameAsFirstInput()); 1416 summary->set_out(Location::SameAsFirstInput());
1415 summary->set_temp(0, Location::RequiresRegister()); 1417 summary->set_temp(0, Location::RequiresRegister());
1416 summary->set_temp(1, Location::RegisterLocation(ECX)); 1418 summary->set_temp(1, Location::RegisterLocation(ECX));
1417 return summary; 1419 return summary;
1418 } else { 1420 } else {
1419 const intptr_t kNumTemps = 1; 1421 const intptr_t kNumTemps = 1;
1420 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1422 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1421 summary->set_in(0, Location::RequiresRegister()); 1423 summary->set_in(0, Location::RequiresRegister());
1422 summary->set_in(1, Location::RequiresRegister()); 1424 summary->set_in(1, Location::RequiresRegister());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 __ j(LESS, &count_ok, Assembler::kNearJump); 1514 __ j(LESS, &count_ok, Assembler::kNearJump);
1513 __ movl(right, kCountLimit); 1515 __ movl(right, kCountLimit);
1514 __ Bind(&count_ok); 1516 __ Bind(&count_ok);
1515 ASSERT(right == ECX); // Count must be in ECX 1517 ASSERT(right == ECX); // Count must be in ECX
1516 __ SmiUntag(left); 1518 __ SmiUntag(left);
1517 __ sarl(left, right); 1519 __ sarl(left, right);
1518 __ SmiTag(left); 1520 __ SmiTag(left);
1519 break; 1521 break;
1520 } 1522 }
1521 case Token::kSHL: { 1523 case Token::kSHL: {
1524 Label call_method, done;
1522 // Check if count too large for handling it inlined. 1525 // Check if count too large for handling it inlined.
1523 __ cmpl(right, 1526 __ cmpl(right,
1524 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits)))); 1527 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
1525 __ j(ABOVE_EQUAL, deopt); 1528 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
1526 Register right_temp = comp->locs()->temp(1).reg(); 1529 Register right_temp = comp->locs()->temp(1).reg();
1527 ASSERT(right_temp == ECX); // Count must be in ECX 1530 ASSERT(right_temp == ECX); // Count must be in ECX
1528 __ movl(right_temp, right); 1531 __ movl(right_temp, right);
1529 __ SmiUntag(right_temp); 1532 __ SmiUntag(right_temp);
1530 // Overflow test (preserve temp and right); 1533 // Overflow test (preserve temp and right);
1531 __ shll(left, right_temp); 1534 __ shll(left, right_temp);
1532 __ sarl(left, right_temp); 1535 __ sarl(left, right_temp);
1533 __ cmpl(left, temp); 1536 __ cmpl(left, temp);
1534 __ j(NOT_EQUAL, deopt); // Overflow. 1537 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
1535 // Shift for result now we know there is no overflow. 1538 // Shift for result now we know there is no overflow.
1536 __ shll(left, right_temp); 1539 __ shll(left, right_temp);
1540 __ jmp(&done);
1541 {
1542 __ Bind(&call_method);
1543 Function& target = Function::ZoneHandle(
1544 comp->ic_data()->GetTargetForReceiverClassId(kSmi));
1545 ASSERT(!target.IsNull());
1546 const intptr_t kArgumentCount = 2;
1547 __ pushl(temp);
1548 __ pushl(right);
1549 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1550 comp->instance_call()->token_index(),
1551 comp->instance_call()->try_index(),
1552 target,
1553 kArgumentCount,
1554 Array::Handle()); // No argument names.
1555 ASSERT(result == EAX);
1556 }
1557 __ Bind(&done);
1537 break; 1558 break;
1538 } 1559 }
1539 case Token::kDIV: { 1560 case Token::kDIV: {
1540 // Dispatches to 'Double./'. 1561 // Dispatches to 'Double./'.
1541 // TODO(srdjan): Implement as conversion to double and double division. 1562 // TODO(srdjan): Implement as conversion to double and double division.
1542 UNREACHABLE(); 1563 UNREACHABLE();
1543 break; 1564 break;
1544 } 1565 }
1545 case Token::kMOD: { 1566 case Token::kMOD: {
1546 // TODO(srdjan): Implement. 1567 // TODO(srdjan): Implement.
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 intptr_t test_class_id; 1755 intptr_t test_class_id;
1735 Function& target = Function::Handle(); 1756 Function& target = Function::Handle();
1736 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1757 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1737 1758
1738 Register value = locs()->in(0).reg(); 1759 Register value = locs()->in(0).reg();
1739 Register result = locs()->out().reg(); 1760 Register result = locs()->out().reg();
1740 ASSERT(value == result); 1761 ASSERT(value == result);
1741 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1762 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1742 instance_call()->token_index(), 1763 instance_call()->token_index(),
1743 instance_call()->try_index(), 1764 instance_call()->try_index(),
1744 kDeoptSmiBinaryOp, 1765 kDeoptUnaryOp,
1745 value); 1766 value);
1746 if (test_class_id == kSmi) { 1767 if (test_class_id == kSmi) {
1747 __ testl(value, Immediate(kSmiTagMask)); 1768 __ testl(value, Immediate(kSmiTagMask));
1748 __ j(NOT_ZERO, deopt); 1769 __ j(NOT_ZERO, deopt);
1749 switch (op_kind()) { 1770 switch (op_kind()) {
1750 case Token::kNEGATE: 1771 case Token::kNEGATE:
1751 __ negl(value); 1772 __ negl(value);
1752 __ j(OVERFLOW, deopt); 1773 __ j(OVERFLOW, deopt);
1753 break; 1774 break;
1754 case Token::kBIT_NOT: 1775 case Token::kBIT_NOT:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 intptr_t test_class_id; 1808 intptr_t test_class_id;
1788 Function& target = Function::Handle(); 1809 Function& target = Function::Handle();
1789 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1810 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1790 1811
1791 Register value = locs()->in(0).reg(); 1812 Register value = locs()->in(0).reg();
1792 Register result = locs()->out().reg(); 1813 Register result = locs()->out().reg();
1793 ASSERT(value == result); 1814 ASSERT(value == result);
1794 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1815 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1795 instance_call()->token_index(), 1816 instance_call()->token_index(),
1796 instance_call()->try_index(), 1817 instance_call()->try_index(),
1797 kDeoptSmiBinaryOp, 1818 kDeoptUnaryOp,
1798 value); 1819 value);
1799 if (test_class_id == kDouble) { 1820 if (test_class_id == kDouble) {
1800 Register temp = locs()->temp(0).reg(); 1821 Register temp = locs()->temp(0).reg();
1801 ASSERT(result != temp); 1822 ASSERT(result != temp);
1802 __ testl(value, Immediate(kSmiTagMask)); 1823 __ testl(value, Immediate(kSmiTagMask));
1803 __ j(ZERO, deopt); // Smi. 1824 __ j(ZERO, deopt); // Smi.
1804 __ CompareClassId(value, kDouble, temp); 1825 __ CompareClassId(value, kDouble, temp);
1805 __ j(NOT_EQUAL, deopt); 1826 __ j(NOT_EQUAL, deopt);
1806 // Allocate result object. 1827 // Allocate result object.
1807 const Class& double_class = compiler->double_class(); 1828 const Class& double_class = compiler->double_class();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 instance_call()->argument_names()); 1956 instance_call()->argument_names());
1936 } 1957 }
1937 __ Bind(&done); 1958 __ Bind(&done);
1938 } 1959 }
1939 1960
1940 } // namespace dart 1961 } // namespace dart
1941 1962
1942 #undef __ 1963 #undef __
1943 1964
1944 #endif // defined TARGET_ARCH_X64 1965 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698