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

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

Issue 11362210: Restrict immediate operands to smi where only smis are supported. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/locations.h » ('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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 locs->set_in(0, Location::RequiresXmmRegister()); 275 locs->set_in(0, Location::RequiresXmmRegister());
276 locs->set_in(1, Location::RequiresXmmRegister()); 276 locs->set_in(1, Location::RequiresXmmRegister());
277 locs->set_out(Location::RequiresRegister()); 277 locs->set_out(Location::RequiresRegister());
278 return locs; 278 return locs;
279 } 279 }
280 if (receiver_class_id() == kSmiCid) { 280 if (receiver_class_id() == kSmiCid) {
281 const intptr_t kNumTemps = 0; 281 const intptr_t kNumTemps = 0;
282 LocationSummary* locs = 282 LocationSummary* locs =
283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
284 locs->set_in(0, Location::RegisterOrConstant(left())); 284 locs->set_in(0, Location::RegisterOrConstant(left()));
285 locs->set_in(1, Location::RegisterOrConstant(right())); 285 // Only one input can be a constant operand. The case of two constant
286 // operands should be handled by constant propagation.
287 locs->set_in(1, locs->in(0).IsConstant()
288 ? Location::RequiresRegister()
289 : Location::RegisterOrConstant(right()));
286 locs->set_out(Location::RequiresRegister()); 290 locs->set_out(Location::RequiresRegister());
287 return locs; 291 return locs;
288 } 292 }
289 if (is_checked_strict_equal) { 293 if (is_checked_strict_equal) {
290 const intptr_t kNumTemps = 1; 294 const intptr_t kNumTemps = 1;
291 LocationSummary* locs = 295 LocationSummary* locs =
292 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 296 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
293 locs->set_in(0, Location::RequiresRegister()); 297 locs->set_in(0, Location::RequiresRegister());
294 locs->set_in(1, Location::RequiresRegister()); 298 locs->set_in(1, Location::RequiresRegister());
295 locs->set_temp(0, Location::RequiresRegister()); 299 locs->set_temp(0, Location::RequiresRegister());
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 __ Bind(&done); 604 __ Bind(&done);
601 } 605 }
602 606
603 607
604 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 608 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
605 const LocationSummary& locs, 609 const LocationSummary& locs,
606 Token::Kind kind, 610 Token::Kind kind,
607 BranchInstr* branch) { 611 BranchInstr* branch) {
608 Location left = locs.in(0); 612 Location left = locs.in(0);
609 Location right = locs.in(1); 613 Location right = locs.in(1);
614 ASSERT(!left.IsConstant() || !right.IsConstant());
610 615
611 Condition true_condition = TokenKindToSmiCondition(kind); 616 Condition true_condition = TokenKindToSmiCondition(kind);
612 617
613 if (left.IsConstant() && right.IsConstant()) {
614 bool result = false;
615 // One of them could be NULL (for equality only).
616 if (left.constant().IsNull() || right.constant().IsNull()) {
617 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
618 result = left.constant().IsNull() && right.constant().IsNull();
619 if (kind == Token::kNE) {
620 result = !result;
621 }
622 } else {
623 // TODO(vegorov): should be eliminated earlier by constant propagation.
624 result = FlowGraphCompiler::EvaluateCondition(
625 true_condition,
626 Smi::Cast(left.constant()).Value(),
627 Smi::Cast(right.constant()).Value());
628 }
629
630 if (branch != NULL) {
631 branch->EmitBranchOnValue(compiler, result);
632 } else {
633 __ LoadObject(locs.out().reg(), result ? compiler->bool_true()
634 : compiler->bool_false());
635 }
636
637 return;
638 }
639
640 if (left.IsConstant()) { 618 if (left.IsConstant()) {
641 __ CompareObject(right.reg(), left.constant()); 619 __ CompareObject(right.reg(), left.constant());
642 true_condition = FlowGraphCompiler::FlipCondition(true_condition); 620 true_condition = FlowGraphCompiler::FlipCondition(true_condition);
643 } else if (right.IsConstant()) { 621 } else if (right.IsConstant()) {
644 __ CompareObject(left.reg(), right.constant()); 622 __ CompareObject(left.reg(), right.constant());
645 } else { 623 } else {
646 __ cmpq(left.reg(), right.reg()); 624 __ cmpq(left.reg(), right.reg());
647 } 625 }
648 626
649 if (branch != NULL) { 627 if (branch != NULL) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 LocationSummary* summary = 762 LocationSummary* summary =
785 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 763 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
786 summary->set_in(0, Location::RequiresXmmRegister()); 764 summary->set_in(0, Location::RequiresXmmRegister());
787 summary->set_in(1, Location::RequiresXmmRegister()); 765 summary->set_in(1, Location::RequiresXmmRegister());
788 summary->set_out(Location::RequiresRegister()); 766 summary->set_out(Location::RequiresRegister());
789 return summary; 767 return summary;
790 } else if (operands_class_id() == kSmiCid) { 768 } else if (operands_class_id() == kSmiCid) {
791 LocationSummary* summary = 769 LocationSummary* summary =
792 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 770 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
793 summary->set_in(0, Location::RegisterOrConstant(left())); 771 summary->set_in(0, Location::RegisterOrConstant(left()));
794 summary->set_in(1, Location::RegisterOrConstant(right())); 772 // Only one input can be a constant operand. The case of two constant
773 // operands should be handled by constant propagation.
774 summary->set_in(1, summary->in(0).IsConstant()
775 ? Location::RequiresRegister()
776 : Location::RegisterOrConstant(right()));
795 summary->set_out(Location::RequiresRegister()); 777 summary->set_out(Location::RequiresRegister());
796 return summary; 778 return summary;
797 } 779 }
798 LocationSummary* locs = 780 LocationSummary* locs =
799 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 781 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
800 // Pick arbitrary fixed input registers because this is a call. 782 // Pick arbitrary fixed input registers because this is a call.
801 locs->set_in(0, Location::RegisterLocation(RAX)); 783 locs->set_in(0, Location::RegisterLocation(RAX));
802 locs->set_in(1, Location::RegisterLocation(RCX)); 784 locs->set_in(1, Location::RegisterLocation(RCX));
803 locs->set_out(Location::RegisterLocation(RAX)); 785 locs->set_out(Location::RegisterLocation(RAX));
804 return locs; 786 return locs;
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 summary->set_temp(0, Location::RegisterLocation(RBX)); 1572 summary->set_temp(0, Location::RegisterLocation(RBX));
1591 // Will be used for for sign extension. 1573 // Will be used for for sign extension.
1592 summary->set_temp(1, Location::RegisterLocation(RDX)); 1574 summary->set_temp(1, Location::RegisterLocation(RDX));
1593 summary->set_temp(2, Location::RequiresRegister()); 1575 summary->set_temp(2, Location::RequiresRegister());
1594 return summary; 1576 return summary;
1595 } else if (op_kind() == Token::kSHR) { 1577 } else if (op_kind() == Token::kSHR) {
1596 const intptr_t kNumTemps = 0; 1578 const intptr_t kNumTemps = 0;
1597 LocationSummary* summary = 1579 LocationSummary* summary =
1598 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1580 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1599 summary->set_in(0, Location::RequiresRegister()); 1581 summary->set_in(0, Location::RequiresRegister());
1600 summary->set_in(1, Location::RegisterLocation(RCX)); 1582 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
1601 summary->set_out(Location::SameAsFirstInput()); 1583 summary->set_out(Location::SameAsFirstInput());
1602 return summary; 1584 return summary;
1603 } else if (op_kind() == Token::kSHL) { 1585 } else if (op_kind() == Token::kSHL) {
1604 const intptr_t kNumTemps = 1; 1586 const intptr_t kNumTemps = 1;
1605 LocationSummary* summary = 1587 LocationSummary* summary =
1606 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1588 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1607 summary->set_in(0, Location::RequiresRegister()); 1589 summary->set_in(0, Location::RequiresRegister());
1608 summary->set_in(1, Location::FixedRegisterOrConstant(right(), RCX)); 1590 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), RCX));
1609 summary->set_temp(0, Location::RequiresRegister()); 1591 summary->set_temp(0, Location::RequiresRegister());
1610 summary->set_out(Location::SameAsFirstInput()); 1592 summary->set_out(Location::SameAsFirstInput());
1611 return summary; 1593 return summary;
1612 } else { 1594 } else {
1613 const intptr_t kNumTemps = 0; 1595 const intptr_t kNumTemps = 0;
1614 LocationSummary* summary = 1596 LocationSummary* summary =
1615 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1597 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1616 summary->set_in(0, Location::RequiresRegister()); 1598 summary->set_in(0, Location::RequiresRegister());
1617 summary->set_in(1, Location::RequiresRegister()); 1599 summary->set_in(1, Location::RegisterOrSmiConstant(right()));
1618 summary->set_out(Location::SameAsFirstInput()); 1600 summary->set_out(Location::SameAsFirstInput());
1619 return summary; 1601 return summary;
1620 } 1602 }
1621 } 1603 }
1622 1604
1623 1605
1624 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1606 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1625 Register left = locs()->in(0).reg(); 1607 Register left = locs()->in(0).reg();
1626 Register result = locs()->out().reg(); 1608 Register result = locs()->out().reg();
1627 ASSERT(left == result); 1609 ASSERT(left == result);
(...skipping 12 matching lines...) Expand all
1640 case Token::kADD: { 1622 case Token::kADD: {
1641 __ addq(left, Immediate(imm)); 1623 __ addq(left, Immediate(imm));
1642 if (deopt != NULL) __ j(OVERFLOW, deopt); 1624 if (deopt != NULL) __ j(OVERFLOW, deopt);
1643 break; 1625 break;
1644 } 1626 }
1645 case Token::kSUB: { 1627 case Token::kSUB: {
1646 __ subq(left, Immediate(imm)); 1628 __ subq(left, Immediate(imm));
1647 if (deopt != NULL) __ j(OVERFLOW, deopt); 1629 if (deopt != NULL) __ j(OVERFLOW, deopt);
1648 break; 1630 break;
1649 } 1631 }
1632 case Token::kMUL: {
1633 // Keep left value tagged and untag right value.
1634 const intptr_t value = Smi::Cast(constant).Value();
1635 __ imulq(left, Immediate(value));
1636 if (deopt != NULL) __ j(OVERFLOW, deopt);
1637 break;
1638 }
1650 case Token::kBIT_AND: { 1639 case Token::kBIT_AND: {
1651 // No overflow check. 1640 // No overflow check.
1652 __ andq(left, Immediate(imm)); 1641 __ andq(left, Immediate(imm));
1653 break; 1642 break;
1654 } 1643 }
1655 case Token::kBIT_OR: { 1644 case Token::kBIT_OR: {
1656 // No overflow check. 1645 // No overflow check.
1657 __ orq(left, Immediate(imm)); 1646 __ orq(left, Immediate(imm));
1658 break; 1647 break;
1659 } 1648 }
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
2240 __ testq(value, Immediate(kSmiTagMask)); 2229 __ testq(value, Immediate(kSmiTagMask));
2241 __ j(NOT_ZERO, deopt); 2230 __ j(NOT_ZERO, deopt);
2242 } 2231 }
2243 2232
2244 2233
2245 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 2234 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const {
2246 const intptr_t kNumInputs = 2; 2235 const intptr_t kNumInputs = 2;
2247 const intptr_t kNumTemps = 0; 2236 const intptr_t kNumTemps = 0;
2248 LocationSummary* locs = 2237 LocationSummary* locs =
2249 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2250 locs->set_in(0, Location::RequiresRegister()); 2239 locs->set_in(0, Location::RegisterOrSmiConstant(array()));
2251 locs->set_in(1, Location::RegisterOrConstant(index())); 2240 locs->set_in(1, Location::RegisterOrSmiConstant(index()));
2252 return locs; 2241 return locs;
2253 } 2242 }
2254 2243
2255 2244
2256 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2245 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2257 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2246 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2258 kDeoptCheckArrayBound); 2247 kDeoptCheckArrayBound);
2259 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) { 2248 if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) {
2260 // Unconditionally deoptimize for constant bounds checks because they 2249 // Unconditionally deoptimize for constant bounds checks because they
2261 // only occur only when index is out-of-bounds. 2250 // only occur only when index is out-of-bounds.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2344 2333
2345 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2334 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2346 UNIMPLEMENTED(); 2335 UNIMPLEMENTED();
2347 } 2336 }
2348 2337
2349 } // namespace dart 2338 } // namespace dart
2350 2339
2351 #undef __ 2340 #undef __
2352 2341
2353 #endif // defined TARGET_ARCH_X64 2342 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/locations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698