| OLD | NEW |
| 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 15 matching lines...) Expand all Loading... |
| 26 // on the stack and return the result in a fixed register EAX. | 26 // on the stack and return the result in a fixed register EAX. |
| 27 LocationSummary* Computation::MakeCallSummary() { | 27 LocationSummary* Computation::MakeCallSummary() { |
| 28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| 29 result->set_out(Location::RegisterLocation(EAX)); | 29 result->set_out(Location::RegisterLocation(EAX)); |
| 30 return result; | 30 return result; |
| 31 } | 31 } |
| 32 | 32 |
| 33 | 33 |
| 34 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 34 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 35 computation()->EmitNativeCode(compiler); | 35 computation()->EmitNativeCode(compiler); |
| 36 if (is_used() && locs()->out().IsRegister()) { | 36 if (is_used() && !compiler->is_optimizing()) { |
| 37 // TODO(vegorov): this should really happen only for comparisons fused | 37 __ pushl(locs()->out().reg()); |
| 38 // with branches. Currrently IR does not provide an easy way to remove | |
| 39 // instructions from the graph so we just leave fused comparison in it | |
| 40 // but change its result location to be NoLocation. | |
| 41 compiler->frame_register_allocator()->Push(locs()->out().reg(), this); | |
| 42 } | 38 } |
| 43 } | 39 } |
| 44 | 40 |
| 45 | 41 |
| 46 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 42 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
| 47 const intptr_t kNumInputs = 1; | 43 const intptr_t kNumInputs = 1; |
| 48 const intptr_t kNumTemps = 1; | 44 const intptr_t kNumTemps = 1; |
| 49 LocationSummary* locs = | 45 LocationSummary* locs = |
| 50 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 46 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 51 locs->set_in(0, Location::RegisterLocation(EAX)); | 47 locs->set_in(0, Location::RegisterLocation(EAX)); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 BranchInstr* branch, | 443 BranchInstr* branch, |
| 448 intptr_t deopt_id, | 444 intptr_t deopt_id, |
| 449 intptr_t token_pos, | 445 intptr_t token_pos, |
| 450 intptr_t try_index) { | 446 intptr_t try_index) { |
| 451 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 447 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 452 Register left = locs.in(0).reg(); | 448 Register left = locs.in(0).reg(); |
| 453 Register right = locs.in(1).reg(); | 449 Register right = locs.in(1).reg(); |
| 454 Register temp = locs.temp(0).reg(); | 450 Register temp = locs.temp(0).reg(); |
| 455 Label* deopt = compiler->AddDeoptStub(deopt_id, | 451 Label* deopt = compiler->AddDeoptStub(deopt_id, |
| 456 try_index, | 452 try_index, |
| 457 kDeoptEquality, | 453 kDeoptEquality); |
| 458 left, | |
| 459 right); | |
| 460 __ testl(left, Immediate(kSmiTagMask)); | 454 __ testl(left, Immediate(kSmiTagMask)); |
| 461 __ j(ZERO, deopt); | 455 __ j(ZERO, deopt); |
| 462 // 'left' is not Smi. | 456 // 'left' is not Smi. |
| 463 const Immediate raw_null = | 457 const Immediate raw_null = |
| 464 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 458 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 465 Label identity_compare; | 459 Label identity_compare; |
| 466 __ cmpl(right, raw_null); | 460 __ cmpl(right, raw_null); |
| 467 __ j(EQUAL, &identity_compare); | 461 __ j(EQUAL, &identity_compare); |
| 468 __ cmpl(left, raw_null); | 462 __ cmpl(left, raw_null); |
| 469 __ j(EQUAL, &identity_compare); | 463 __ j(EQUAL, &identity_compare); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 Register left = locs.in(0).reg(); | 550 Register left = locs.in(0).reg(); |
| 557 Register right = locs.in(1).reg(); | 551 Register right = locs.in(1).reg(); |
| 558 const bool left_is_smi = (branch == NULL) ? | 552 const bool left_is_smi = (branch == NULL) ? |
| 559 false : (branch->left()->ResultCid() == kSmiCid); | 553 false : (branch->left()->ResultCid() == kSmiCid); |
| 560 const bool right_is_smi = (branch == NULL) ? | 554 const bool right_is_smi = (branch == NULL) ? |
| 561 false : (branch->right()->ResultCid() == kSmiCid); | 555 false : (branch->right()->ResultCid() == kSmiCid); |
| 562 if (!left_is_smi || !right_is_smi) { | 556 if (!left_is_smi || !right_is_smi) { |
| 563 Register temp = locs.temp(0).reg(); | 557 Register temp = locs.temp(0).reg(); |
| 564 Label* deopt = compiler->AddDeoptStub(deopt_id, | 558 Label* deopt = compiler->AddDeoptStub(deopt_id, |
| 565 try_index, | 559 try_index, |
| 566 kDeoptSmiCompareSmi, | 560 kDeoptSmiCompareSmi); |
| 567 left, | |
| 568 right); | |
| 569 __ movl(temp, left); | 561 __ movl(temp, left); |
| 570 __ orl(temp, right); | 562 __ orl(temp, right); |
| 571 __ testl(temp, Immediate(kSmiTagMask)); | 563 __ testl(temp, Immediate(kSmiTagMask)); |
| 572 __ j(NOT_ZERO, deopt); | 564 __ j(NOT_ZERO, deopt); |
| 573 } | 565 } |
| 574 | 566 |
| 575 Condition true_condition = TokenKindToSmiCondition(kind); | 567 Condition true_condition = TokenKindToSmiCondition(kind); |
| 576 __ cmpl(left, right); | 568 __ cmpl(left, right); |
| 577 | 569 |
| 578 if (branch != NULL) { | 570 if (branch != NULL) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 BranchInstr* branch, | 603 BranchInstr* branch, |
| 612 intptr_t deopt_id, | 604 intptr_t deopt_id, |
| 613 intptr_t token_pos, | 605 intptr_t token_pos, |
| 614 intptr_t try_index) { | 606 intptr_t try_index) { |
| 615 Register left = locs.in(0).reg(); | 607 Register left = locs.in(0).reg(); |
| 616 Register right = locs.in(1).reg(); | 608 Register right = locs.in(1).reg(); |
| 617 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. | 609 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. |
| 618 Register temp = locs.temp(0).reg(); | 610 Register temp = locs.temp(0).reg(); |
| 619 Label* deopt = compiler->AddDeoptStub(deopt_id, | 611 Label* deopt = compiler->AddDeoptStub(deopt_id, |
| 620 try_index, | 612 try_index, |
| 621 kDeoptDoubleComparison, | 613 kDeoptDoubleComparison); |
| 622 left, | |
| 623 right); | |
| 624 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); | 614 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); |
| 625 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); | 615 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); |
| 626 | 616 |
| 627 Condition true_condition = TokenKindToDoubleCondition(kind); | 617 Condition true_condition = TokenKindToDoubleCondition(kind); |
| 628 if (branch != NULL) { | 618 if (branch != NULL) { |
| 629 compiler->EmitDoubleCompareBranch( | 619 compiler->EmitDoubleCompareBranch( |
| 630 true_condition, XMM0, XMM1, branch); | 620 true_condition, XMM0, XMM1, branch); |
| 631 } else { | 621 } else { |
| 632 compiler->EmitDoubleCompareBool( | 622 compiler->EmitDoubleCompareBool( |
| 633 true_condition, XMM0, XMM1, locs.out().reg()); | 623 true_condition, XMM0, XMM1, locs.out().reg()); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 Register index = locs()->in(1).reg(); | 819 Register index = locs()->in(1).reg(); |
| 830 Register result = locs()->out().reg(); | 820 Register result = locs()->out().reg(); |
| 831 Register temp = locs()->temp(0).reg(); | 821 Register temp = locs()->temp(0).reg(); |
| 832 | 822 |
| 833 const DeoptReasonId deopt_reason = | 823 const DeoptReasonId deopt_reason = |
| 834 (receiver_type() == kGrowableObjectArrayCid) ? | 824 (receiver_type() == kGrowableObjectArrayCid) ? |
| 835 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 825 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| 836 | 826 |
| 837 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | 827 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 838 original()->try_index(), | 828 original()->try_index(), |
| 839 deopt_reason, | 829 deopt_reason); |
| 840 receiver, | |
| 841 index); | |
| 842 | 830 |
| 843 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 831 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 844 __ j(ZERO, deopt); | 832 __ j(ZERO, deopt); |
| 845 __ CompareClassId(receiver, receiver_type(), temp); | 833 __ CompareClassId(receiver, receiver_type(), temp); |
| 846 __ j(NOT_EQUAL, deopt); | 834 __ j(NOT_EQUAL, deopt); |
| 847 | 835 |
| 848 __ testl(index, Immediate(kSmiTagMask)); | 836 __ testl(index, Immediate(kSmiTagMask)); |
| 849 __ j(NOT_ZERO, deopt); | 837 __ j(NOT_ZERO, deopt); |
| 850 | 838 |
| 851 switch (receiver_type()) { | 839 switch (receiver_type()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 | 883 |
| 896 | 884 |
| 897 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 885 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 898 Register receiver = locs()->in(0).reg(); | 886 Register receiver = locs()->in(0).reg(); |
| 899 Register index = locs()->in(1).reg(); | 887 Register index = locs()->in(1).reg(); |
| 900 Register value = locs()->in(2).reg(); | 888 Register value = locs()->in(2).reg(); |
| 901 Register temp = locs()->temp(0).reg(); | 889 Register temp = locs()->temp(0).reg(); |
| 902 | 890 |
| 903 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | 891 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 904 original()->try_index(), | 892 original()->try_index(), |
| 905 kDeoptStoreIndexed, | 893 kDeoptStoreIndexed); |
| 906 receiver, | |
| 907 index, | |
| 908 value); | |
| 909 | 894 |
| 910 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 895 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 911 __ j(ZERO, deopt); | 896 __ j(ZERO, deopt); |
| 912 __ CompareClassId(receiver, receiver_type(), temp); | 897 __ CompareClassId(receiver, receiver_type(), temp); |
| 913 __ j(NOT_EQUAL, deopt); | 898 __ j(NOT_EQUAL, deopt); |
| 914 | 899 |
| 915 __ testl(index, Immediate(kSmiTagMask)); | 900 __ testl(index, Immediate(kSmiTagMask)); |
| 916 __ j(NOT_ZERO, deopt); | 901 __ j(NOT_ZERO, deopt); |
| 917 | 902 |
| 918 switch (receiver_type()) { | 903 switch (receiver_type()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 | 944 |
| 960 | 945 |
| 961 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 946 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 962 Register instance_reg = locs()->in(0).reg(); | 947 Register instance_reg = locs()->in(0).reg(); |
| 963 Register result_reg = locs()->out().reg(); | 948 Register result_reg = locs()->out().reg(); |
| 964 | 949 |
| 965 if (HasICData()) { | 950 if (HasICData()) { |
| 966 ASSERT(original() != NULL); | 951 ASSERT(original() != NULL); |
| 967 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | 952 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 968 original()->try_index(), | 953 original()->try_index(), |
| 969 kDeoptInstanceGetterSameTarget, | 954 kDeoptInstanceGetterSameTarget); |
| 970 instance_reg); | |
| 971 // Smis do not have instance fields (Smi class is always first). | 955 // Smis do not have instance fields (Smi class is always first). |
| 972 // Use 'result' as temporary register. | 956 // Use 'result' as temporary register. |
| 973 ASSERT(result_reg != instance_reg); | 957 ASSERT(result_reg != instance_reg); |
| 974 ASSERT(ic_data() != NULL); | 958 ASSERT(ic_data() != NULL); |
| 975 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | 959 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); |
| 976 } | 960 } |
| 977 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); | 961 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); |
| 978 } | 962 } |
| 979 | 963 |
| 980 | 964 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 } | 1079 } |
| 1096 | 1080 |
| 1097 | 1081 |
| 1098 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1082 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1099 Register instance_reg = locs()->in(0).reg(); | 1083 Register instance_reg = locs()->in(0).reg(); |
| 1100 Register result_reg = locs()->out().reg(); | 1084 Register result_reg = locs()->out().reg(); |
| 1101 if (HasICData()) { | 1085 if (HasICData()) { |
| 1102 ASSERT(original() != NULL); | 1086 ASSERT(original() != NULL); |
| 1103 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), | 1087 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), |
| 1104 original()->try_index(), | 1088 original()->try_index(), |
| 1105 kDeoptInstanceGetterSameTarget, | 1089 kDeoptInstanceGetterSameTarget); |
| 1106 instance_reg); | |
| 1107 // Smis do not have instance fields (Smi class is always first). | 1090 // Smis do not have instance fields (Smi class is always first). |
| 1108 // Use 'result' as temporary register. | 1091 // Use 'result' as temporary register. |
| 1109 ASSERT(result_reg != instance_reg); | 1092 ASSERT(result_reg != instance_reg); |
| 1110 ASSERT(ic_data() != NULL); | 1093 ASSERT(ic_data() != NULL); |
| 1111 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | 1094 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); |
| 1112 } | 1095 } |
| 1113 | 1096 |
| 1114 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1097 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
| 1115 } | 1098 } |
| 1116 | 1099 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 case Token::kBIT_XOR: | 1491 case Token::kBIT_XOR: |
| 1509 can_deopt = !(right_is_smi && left_is_smi); | 1492 can_deopt = !(right_is_smi && left_is_smi); |
| 1510 break; | 1493 break; |
| 1511 default: | 1494 default: |
| 1512 can_deopt = true; | 1495 can_deopt = true; |
| 1513 } | 1496 } |
| 1514 Label* deopt = NULL; | 1497 Label* deopt = NULL; |
| 1515 if (can_deopt) { | 1498 if (can_deopt) { |
| 1516 deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), | 1499 deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), |
| 1517 comp->instance_call()->try_index(), | 1500 comp->instance_call()->try_index(), |
| 1518 kDeoptSmiBinaryOp, | 1501 kDeoptSmiBinaryOp); |
| 1519 temp, | |
| 1520 right); | |
| 1521 } | 1502 } |
| 1522 if (left_is_smi && right_is_smi) { | 1503 if (left_is_smi && right_is_smi) { |
| 1523 if (can_deopt) { | 1504 if (can_deopt) { |
| 1524 // Preserve left for deopt. | 1505 // Preserve left for deopt. |
| 1525 __ movl(temp, left); | 1506 __ movl(temp, left); |
| 1526 } | 1507 } |
| 1527 } else { | 1508 } else { |
| 1528 // TODO(vegorov): for many binary operations this pattern can be rearranged | 1509 // TODO(vegorov): for many binary operations this pattern can be rearranged |
| 1529 // to save one move. | 1510 // to save one move. |
| 1530 __ movl(temp, left); | 1511 __ movl(temp, left); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1675 // both receiver and argument are Mint or if one of them is Mint and the other | 1656 // both receiver and argument are Mint or if one of them is Mint and the other |
| 1676 // is a negative Smi. | 1657 // is a negative Smi. |
| 1677 Register left = comp->locs()->in(0).reg(); | 1658 Register left = comp->locs()->in(0).reg(); |
| 1678 Register right = comp->locs()->in(1).reg(); | 1659 Register right = comp->locs()->in(1).reg(); |
| 1679 Register result = comp->locs()->out().reg(); | 1660 Register result = comp->locs()->out().reg(); |
| 1680 Register temp = comp->locs()->temp(0).reg(); | 1661 Register temp = comp->locs()->temp(0).reg(); |
| 1681 ASSERT(left == result); | 1662 ASSERT(left == result); |
| 1682 ASSERT(comp->op_kind() == Token::kBIT_AND); | 1663 ASSERT(comp->op_kind() == Token::kBIT_AND); |
| 1683 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), | 1664 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), |
| 1684 comp->instance_call()->try_index(), | 1665 comp->instance_call()->try_index(), |
| 1685 kDeoptMintBinaryOp, | 1666 kDeoptMintBinaryOp); |
| 1686 left, | |
| 1687 right); | |
| 1688 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; | 1667 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; |
| 1689 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? | 1668 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? |
| 1690 __ j(NOT_ZERO, &non_smi); | 1669 __ j(NOT_ZERO, &non_smi); |
| 1691 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? | 1670 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? |
| 1692 __ j(ZERO, &smi_smi); | 1671 __ j(ZERO, &smi_smi); |
| 1693 __ CompareClassId(right, kMintCid, temp); // Is argument Mint? | 1672 __ CompareClassId(right, kMintCid, temp); // Is argument Mint? |
| 1694 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint. | 1673 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint. |
| 1695 __ cmpl(left, Immediate(0)); | 1674 __ cmpl(left, Immediate(0)); |
| 1696 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument. | 1675 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument. |
| 1697 | 1676 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1851 ASSERT(ic_data.NumberOfChecks() == 1); | 1830 ASSERT(ic_data.NumberOfChecks() == 1); |
| 1852 intptr_t test_class_id; | 1831 intptr_t test_class_id; |
| 1853 Function& target = Function::Handle(); | 1832 Function& target = Function::Handle(); |
| 1854 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); | 1833 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); |
| 1855 | 1834 |
| 1856 Register value = locs()->in(0).reg(); | 1835 Register value = locs()->in(0).reg(); |
| 1857 Register result = locs()->out().reg(); | 1836 Register result = locs()->out().reg(); |
| 1858 ASSERT(value == result); | 1837 ASSERT(value == result); |
| 1859 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1838 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1860 instance_call()->try_index(), | 1839 instance_call()->try_index(), |
| 1861 kDeoptUnaryOp, | 1840 kDeoptUnaryOp); |
| 1862 value); | |
| 1863 if (test_class_id == kSmiCid) { | 1841 if (test_class_id == kSmiCid) { |
| 1864 __ testl(value, Immediate(kSmiTagMask)); | 1842 __ testl(value, Immediate(kSmiTagMask)); |
| 1865 __ j(NOT_ZERO, deopt); | 1843 __ j(NOT_ZERO, deopt); |
| 1866 switch (op_kind()) { | 1844 switch (op_kind()) { |
| 1867 case Token::kNEGATE: | 1845 case Token::kNEGATE: |
| 1868 __ negl(value); | 1846 __ negl(value); |
| 1869 __ j(OVERFLOW, deopt); | 1847 __ j(OVERFLOW, deopt); |
| 1870 break; | 1848 break; |
| 1871 case Token::kBIT_NOT: | 1849 case Token::kBIT_NOT: |
| 1872 __ notl(value); | 1850 __ notl(value); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1902 ASSERT(ic_data.NumberOfChecks() == 1); | 1880 ASSERT(ic_data.NumberOfChecks() == 1); |
| 1903 intptr_t test_class_id; | 1881 intptr_t test_class_id; |
| 1904 Function& target = Function::Handle(); | 1882 Function& target = Function::Handle(); |
| 1905 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); | 1883 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); |
| 1906 | 1884 |
| 1907 Register value = locs()->in(0).reg(); | 1885 Register value = locs()->in(0).reg(); |
| 1908 Register result = locs()->out().reg(); | 1886 Register result = locs()->out().reg(); |
| 1909 ASSERT(value == result); | 1887 ASSERT(value == result); |
| 1910 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1888 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1911 instance_call()->try_index(), | 1889 instance_call()->try_index(), |
| 1912 kDeoptUnaryOp, | 1890 kDeoptUnaryOp); |
| 1913 value); | |
| 1914 if (test_class_id == kDoubleCid) { | 1891 if (test_class_id == kDoubleCid) { |
| 1915 Register temp = locs()->temp(0).reg(); | 1892 Register temp = locs()->temp(0).reg(); |
| 1916 __ testl(value, Immediate(kSmiTagMask)); | 1893 __ testl(value, Immediate(kSmiTagMask)); |
| 1917 __ j(ZERO, deopt); // Smi. | 1894 __ j(ZERO, deopt); // Smi. |
| 1918 __ CompareClassId(value, kDoubleCid, temp); | 1895 __ CompareClassId(value, kDoubleCid, temp); |
| 1919 __ j(NOT_EQUAL, deopt); | 1896 __ j(NOT_EQUAL, deopt); |
| 1920 // Allocate result object. | 1897 // Allocate result object. |
| 1921 const Class& double_class = compiler->double_class(); | 1898 const Class& double_class = compiler->double_class(); |
| 1922 const Code& stub = | 1899 const Code& stub = |
| 1923 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1900 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1953 return locs; | 1930 return locs; |
| 1954 } | 1931 } |
| 1955 | 1932 |
| 1956 | 1933 |
| 1957 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1934 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1958 Register value = locs()->in(0).reg(); | 1935 Register value = locs()->in(0).reg(); |
| 1959 Register result = locs()->out().reg(); | 1936 Register result = locs()->out().reg(); |
| 1960 | 1937 |
| 1961 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1938 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
| 1962 instance_call()->try_index(), | 1939 instance_call()->try_index(), |
| 1963 kDeoptDoubleToDouble, | 1940 kDeoptDoubleToDouble); |
| 1964 value); | |
| 1965 Register temp = locs()->temp(0).reg(); | 1941 Register temp = locs()->temp(0).reg(); |
| 1966 __ testl(value, Immediate(kSmiTagMask)); | 1942 __ testl(value, Immediate(kSmiTagMask)); |
| 1967 __ j(ZERO, deopt); // Deoptimize if Smi. | 1943 __ j(ZERO, deopt); // Deoptimize if Smi. |
| 1968 __ CompareClassId(value, kDoubleCid, temp); | 1944 __ CompareClassId(value, kDoubleCid, temp); |
| 1969 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. | 1945 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. |
| 1970 ASSERT(value == result); | 1946 ASSERT(value == result); |
| 1971 } | 1947 } |
| 1972 | 1948 |
| 1973 | 1949 |
| 1974 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { | 1950 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2206 summary->set_temp(0, Location::RequiresRegister()); | 2182 summary->set_temp(0, Location::RequiresRegister()); |
| 2207 return summary; | 2183 return summary; |
| 2208 } | 2184 } |
| 2209 | 2185 |
| 2210 | 2186 |
| 2211 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 2187 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2212 Register value = locs()->in(0).reg(); | 2188 Register value = locs()->in(0).reg(); |
| 2213 Register temp = locs()->temp(0).reg(); | 2189 Register temp = locs()->temp(0).reg(); |
| 2214 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2190 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
| 2215 try_index(), | 2191 try_index(), |
| 2216 kDeoptCheckClass, | 2192 kDeoptCheckClass); |
| 2217 value); | |
| 2218 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); | 2193 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); |
| 2219 __ testl(value, Immediate(kSmiTagMask)); | 2194 __ testl(value, Immediate(kSmiTagMask)); |
| 2220 __ j(ZERO, deopt); | 2195 __ j(ZERO, deopt); |
| 2221 __ LoadClassId(temp, value); | 2196 __ LoadClassId(temp, value); |
| 2222 Label is_ok; | 2197 Label is_ok; |
| 2223 const intptr_t num_checks = ic_data()->NumberOfChecks(); | 2198 const intptr_t num_checks = ic_data()->NumberOfChecks(); |
| 2224 const bool use_near_jump = num_checks < 5; | 2199 const bool use_near_jump = num_checks < 5; |
| 2225 for (intptr_t i = 0; i < num_checks; i++) { | 2200 for (intptr_t i = 0; i < num_checks; i++) { |
| 2226 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); | 2201 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); |
| 2227 if (i == (num_checks - 1)) { | 2202 if (i == (num_checks - 1)) { |
| 2228 __ j(NOT_EQUAL, deopt); | 2203 __ j(NOT_EQUAL, deopt); |
| 2229 } else { | 2204 } else { |
| 2230 if (use_near_jump) { | 2205 if (use_near_jump) { |
| 2231 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 2206 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
| 2232 } else { | 2207 } else { |
| 2233 __ j(EQUAL, &is_ok); | 2208 __ j(EQUAL, &is_ok); |
| 2234 } | 2209 } |
| 2235 } | 2210 } |
| 2236 } | 2211 } |
| 2237 __ Bind(&is_ok); | 2212 __ Bind(&is_ok); |
| 2238 } | 2213 } |
| 2239 | 2214 |
| 2240 } // namespace dart | 2215 } // namespace dart |
| 2241 | 2216 |
| 2242 #undef __ | 2217 #undef __ |
| 2243 | 2218 |
| 2244 #endif // defined TARGET_ARCH_X64 | 2219 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |