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

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

Issue 10832411: Remove support for non-ssa optimizing code generation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: disable optimizations on bailout Created 8 years, 4 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 | « runtime/vm/intermediate_language.cc ('k') | 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 15 matching lines...) Expand all
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698