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

Side by Side Diff: runtime/vm/intermediate_language_x64.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: 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
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 15 matching lines...) Expand all
26 // on the stack and return the result in a fixed register RAX. 26 // on the stack and return the result in a fixed register RAX.
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(RAX)); 29 result->set_out(Location::RegisterLocation(RAX));
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 __ pushq(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(RAX)); 47 locs->set_in(0, Location::RegisterLocation(RAX));
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 BranchInstr* branch, 453 BranchInstr* branch,
458 intptr_t deopt_id, 454 intptr_t deopt_id,
459 intptr_t token_pos, 455 intptr_t token_pos,
460 intptr_t try_index) { 456 intptr_t try_index) {
461 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 457 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
462 Register left = locs.in(0).reg(); 458 Register left = locs.in(0).reg();
463 Register right = locs.in(1).reg(); 459 Register right = locs.in(1).reg();
464 Register temp = locs.temp(0).reg(); 460 Register temp = locs.temp(0).reg();
465 Label* deopt = compiler->AddDeoptStub(deopt_id, 461 Label* deopt = compiler->AddDeoptStub(deopt_id,
466 try_index, 462 try_index,
467 kDeoptEquality, 463 kDeoptEquality);
468 left,
469 right);
470 __ testq(left, Immediate(kSmiTagMask)); 464 __ testq(left, Immediate(kSmiTagMask));
471 __ j(ZERO, deopt); 465 __ j(ZERO, deopt);
472 // 'left' is not Smi. 466 // 'left' is not Smi.
473 const Immediate raw_null = 467 const Immediate raw_null =
474 Immediate(reinterpret_cast<intptr_t>(Object::null())); 468 Immediate(reinterpret_cast<intptr_t>(Object::null()));
475 Label identity_compare; 469 Label identity_compare;
476 __ cmpq(right, raw_null); 470 __ cmpq(right, raw_null);
477 __ j(EQUAL, &identity_compare); 471 __ j(EQUAL, &identity_compare);
478 __ cmpq(left, raw_null); 472 __ cmpq(left, raw_null);
479 __ j(EQUAL, &identity_compare); 473 __ j(EQUAL, &identity_compare);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 Register left = locs.in(0).reg(); 560 Register left = locs.in(0).reg();
567 Register right = locs.in(1).reg(); 561 Register right = locs.in(1).reg();
568 const bool left_is_smi = (branch == NULL) ? 562 const bool left_is_smi = (branch == NULL) ?
569 false : (branch->left()->ResultCid() == kSmiCid); 563 false : (branch->left()->ResultCid() == kSmiCid);
570 const bool right_is_smi = (branch == NULL) ? 564 const bool right_is_smi = (branch == NULL) ?
571 false : (branch->right()->ResultCid() == kSmiCid); 565 false : (branch->right()->ResultCid() == kSmiCid);
572 if (!left_is_smi || !right_is_smi) { 566 if (!left_is_smi || !right_is_smi) {
573 Register temp = locs.temp(0).reg(); 567 Register temp = locs.temp(0).reg();
574 Label* deopt = compiler->AddDeoptStub(deopt_id, 568 Label* deopt = compiler->AddDeoptStub(deopt_id,
575 try_index, 569 try_index,
576 kDeoptSmiCompareSmi, 570 kDeoptSmiCompareSmi);
577 left,
578 right);
579 __ movq(temp, left); 571 __ movq(temp, left);
580 __ orq(temp, right); 572 __ orq(temp, right);
581 __ testq(temp, Immediate(kSmiTagMask)); 573 __ testq(temp, Immediate(kSmiTagMask));
582 __ j(NOT_ZERO, deopt); 574 __ j(NOT_ZERO, deopt);
583 } 575 }
584 576
585 Condition true_condition = TokenKindToSmiCondition(kind); 577 Condition true_condition = TokenKindToSmiCondition(kind);
586 __ cmpq(left, right); 578 __ cmpq(left, right);
587 579
588 if (branch != NULL) { 580 if (branch != NULL) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 BranchInstr* branch, 613 BranchInstr* branch,
622 intptr_t deopt_id, 614 intptr_t deopt_id,
623 intptr_t token_pos, 615 intptr_t token_pos,
624 intptr_t try_index) { 616 intptr_t try_index) {
625 Register left = locs.in(0).reg(); 617 Register left = locs.in(0).reg();
626 Register right = locs.in(1).reg(); 618 Register right = locs.in(1).reg();
627 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. 619 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
628 Register temp = locs.temp(0).reg(); 620 Register temp = locs.temp(0).reg();
629 Label* deopt = compiler->AddDeoptStub(deopt_id, 621 Label* deopt = compiler->AddDeoptStub(deopt_id,
630 try_index, 622 try_index,
631 kDeoptDoubleComparison, 623 kDeoptDoubleComparison);
632 left,
633 right);
634 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 624 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
635 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 625 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
636 626
637 Condition true_condition = TokenKindToDoubleCondition(kind); 627 Condition true_condition = TokenKindToDoubleCondition(kind);
638 if (branch != NULL) { 628 if (branch != NULL) {
639 compiler->EmitDoubleCompareBranch( 629 compiler->EmitDoubleCompareBranch(
640 true_condition, XMM0, XMM1, branch); 630 true_condition, XMM0, XMM1, branch);
641 } else { 631 } else {
642 compiler->EmitDoubleCompareBool( 632 compiler->EmitDoubleCompareBool(
643 true_condition, XMM0, XMM1, locs.out().reg()); 633 true_condition, XMM0, XMM1, locs.out().reg());
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 Register receiver = locs()->in(0).reg(); 834 Register receiver = locs()->in(0).reg();
845 Register index = locs()->in(1).reg(); 835 Register index = locs()->in(1).reg();
846 Register result = locs()->out().reg(); 836 Register result = locs()->out().reg();
847 837
848 const DeoptReasonId deopt_reason = 838 const DeoptReasonId deopt_reason =
849 (receiver_type() == kGrowableObjectArrayCid) ? 839 (receiver_type() == kGrowableObjectArrayCid) ?
850 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 840 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
851 841
852 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 842 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
853 original()->try_index(), 843 original()->try_index(),
854 deopt_reason, 844 deopt_reason);
855 receiver,
856 index);
857 845
858 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 846 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
859 __ j(ZERO, deopt); 847 __ j(ZERO, deopt);
860 __ CompareClassId(receiver, receiver_type()); 848 __ CompareClassId(receiver, receiver_type());
861 __ j(NOT_EQUAL, deopt); 849 __ j(NOT_EQUAL, deopt);
862 850
863 __ testq(index, Immediate(kSmiTagMask)); 851 __ testq(index, Immediate(kSmiTagMask));
864 __ j(NOT_ZERO, deopt); 852 __ j(NOT_ZERO, deopt);
865 853
866 switch (receiver_type()) { 854 switch (receiver_type()) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } 902 }
915 903
916 904
917 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 905 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
918 Register receiver = locs()->in(0).reg(); 906 Register receiver = locs()->in(0).reg();
919 Register index = locs()->in(1).reg(); 907 Register index = locs()->in(1).reg();
920 Register value = locs()->in(2).reg(); 908 Register value = locs()->in(2).reg();
921 909
922 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 910 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
923 original()->try_index(), 911 original()->try_index(),
924 kDeoptStoreIndexed, 912 kDeoptStoreIndexed);
925 receiver,
926 index,
927 value);
928 913
929 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 914 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
930 __ j(ZERO, deopt); 915 __ j(ZERO, deopt);
931 __ CompareClassId(receiver, receiver_type()); 916 __ CompareClassId(receiver, receiver_type());
932 __ j(NOT_EQUAL, deopt); 917 __ j(NOT_EQUAL, deopt);
933 918
934 __ testq(index, Immediate(kSmiTagMask)); 919 __ testq(index, Immediate(kSmiTagMask));
935 __ j(NOT_ZERO, deopt); 920 __ j(NOT_ZERO, deopt);
936 921
937 switch (receiver_type()) { 922 switch (receiver_type()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 964
980 965
981 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 966 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
982 Register instance_reg = locs()->in(0).reg(); 967 Register instance_reg = locs()->in(0).reg();
983 Register result_reg = locs()->out().reg(); 968 Register result_reg = locs()->out().reg();
984 969
985 if (HasICData()) { 970 if (HasICData()) {
986 ASSERT(original() != NULL); 971 ASSERT(original() != NULL);
987 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 972 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
988 original()->try_index(), 973 original()->try_index(),
989 kDeoptInstanceGetterSameTarget, 974 kDeoptInstanceGetterSameTarget);
990 instance_reg);
991 // Smis do not have instance fields (Smi class is always first). 975 // Smis do not have instance fields (Smi class is always first).
992 // Use 'result' as temporary register. 976 // Use 'result' as temporary register.
993 ASSERT(result_reg != instance_reg); 977 ASSERT(result_reg != instance_reg);
994 ASSERT(ic_data() != NULL); 978 ASSERT(ic_data() != NULL);
995 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 979 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
996 } 980 }
997 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); 981 __ movq(result_reg, FieldAddress(instance_reg, field().Offset()));
998 } 982 }
999 983
1000 984
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 } 1098 }
1115 1099
1116 1100
1117 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1101 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1118 Register instance_reg = locs()->in(0).reg(); 1102 Register instance_reg = locs()->in(0).reg();
1119 Register result_reg = locs()->out().reg(); 1103 Register result_reg = locs()->out().reg();
1120 if (HasICData()) { 1104 if (HasICData()) {
1121 ASSERT(original() != NULL); 1105 ASSERT(original() != NULL);
1122 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 1106 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
1123 original()->try_index(), 1107 original()->try_index(),
1124 kDeoptInstanceGetterSameTarget, 1108 kDeoptInstanceGetterSameTarget);
1125 instance_reg);
1126 // Smis do not have instance fields (Smi class is always first). 1109 // Smis do not have instance fields (Smi class is always first).
1127 // Use 'result' as temporary register. 1110 // Use 'result' as temporary register.
1128 ASSERT(result_reg != instance_reg); 1111 ASSERT(result_reg != instance_reg);
1129 ASSERT(ic_data() != NULL); 1112 ASSERT(ic_data() != NULL);
1130 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 1113 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1131 } 1114 }
1132 1115
1133 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1116 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1134 } 1117 }
1135 1118
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 case Token::kBIT_XOR: 1506 case Token::kBIT_XOR:
1524 can_deopt = !(right_is_smi && left_is_smi); 1507 can_deopt = !(right_is_smi && left_is_smi);
1525 break; 1508 break;
1526 default: 1509 default:
1527 can_deopt = true; 1510 can_deopt = true;
1528 } 1511 }
1529 Label* deopt = NULL; 1512 Label* deopt = NULL;
1530 if (can_deopt) { 1513 if (can_deopt) {
1531 deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1514 deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1532 comp->instance_call()->try_index(), 1515 comp->instance_call()->try_index(),
1533 kDeoptSmiBinaryOp, 1516 kDeoptSmiBinaryOp);
1534 temp,
1535 right);
1536 } 1517 }
1537 if (left_is_smi && right_is_smi) { 1518 if (left_is_smi && right_is_smi) {
1538 if (can_deopt) { 1519 if (can_deopt) {
1539 // Preserve left for deopt. 1520 // Preserve left for deopt.
1540 __ movq(temp, left); 1521 __ movq(temp, left);
1541 } 1522 }
1542 } else { 1523 } else {
1543 // TODO(vegorov): for many binary operations this pattern can be rearranged 1524 // TODO(vegorov): for many binary operations this pattern can be rearranged
1544 // to save one move. 1525 // to save one move.
1545 __ movq(temp, left); 1526 __ movq(temp, left);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 // receiver and a Mint or Smi argument. We fall back to the run time call if 1670 // receiver and a Mint or Smi argument. We fall back to the run time call if
1690 // both receiver and argument are Mint or if one of them is Mint and the other 1671 // both receiver and argument are Mint or if one of them is Mint and the other
1691 // is a negative Smi. 1672 // is a negative Smi.
1692 Register left = comp->locs()->in(0).reg(); 1673 Register left = comp->locs()->in(0).reg();
1693 Register right = comp->locs()->in(1).reg(); 1674 Register right = comp->locs()->in(1).reg();
1694 Register result = comp->locs()->out().reg(); 1675 Register result = comp->locs()->out().reg();
1695 ASSERT(left == result); 1676 ASSERT(left == result);
1696 ASSERT(comp->op_kind() == Token::kBIT_AND); 1677 ASSERT(comp->op_kind() == Token::kBIT_AND);
1697 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1678 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1698 comp->instance_call()->try_index(), 1679 comp->instance_call()->try_index(),
1699 kDeoptMintBinaryOp, 1680 kDeoptMintBinaryOp);
1700 left,
1701 right);
1702 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1681 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1703 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1682 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1704 __ j(NOT_ZERO, &non_smi); 1683 __ j(NOT_ZERO, &non_smi);
1705 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi? 1684 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi?
1706 __ j(ZERO, &smi_smi); 1685 __ j(ZERO, &smi_smi);
1707 __ CompareClassId(right, kMintCid); // Is argument Mint? 1686 __ CompareClassId(right, kMintCid); // Is argument Mint?
1708 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint. 1687 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1709 __ cmpq(left, Immediate(0)); 1688 __ cmpq(left, Immediate(0));
1710 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument. 1689 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1711 1690
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 ASSERT(ic_data.NumberOfChecks() == 1); 1844 ASSERT(ic_data.NumberOfChecks() == 1);
1866 intptr_t test_class_id; 1845 intptr_t test_class_id;
1867 Function& target = Function::Handle(); 1846 Function& target = Function::Handle();
1868 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1847 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1869 1848
1870 Register value = locs()->in(0).reg(); 1849 Register value = locs()->in(0).reg();
1871 Register result = locs()->out().reg(); 1850 Register result = locs()->out().reg();
1872 ASSERT(value == result); 1851 ASSERT(value == result);
1873 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1852 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1874 instance_call()->try_index(), 1853 instance_call()->try_index(),
1875 kDeoptUnaryOp, 1854 kDeoptUnaryOp);
1876 value);
1877 if (test_class_id == kSmiCid) { 1855 if (test_class_id == kSmiCid) {
1878 __ testq(value, Immediate(kSmiTagMask)); 1856 __ testq(value, Immediate(kSmiTagMask));
1879 __ j(NOT_ZERO, deopt); 1857 __ j(NOT_ZERO, deopt);
1880 switch (op_kind()) { 1858 switch (op_kind()) {
1881 case Token::kNEGATE: 1859 case Token::kNEGATE:
1882 __ negq(value); 1860 __ negq(value);
1883 __ j(OVERFLOW, deopt); 1861 __ j(OVERFLOW, deopt);
1884 break; 1862 break;
1885 case Token::kBIT_NOT: 1863 case Token::kBIT_NOT:
1886 __ notq(value); 1864 __ notq(value);
(...skipping 29 matching lines...) Expand all
1916 ASSERT(ic_data.NumberOfChecks() == 1); 1894 ASSERT(ic_data.NumberOfChecks() == 1);
1917 intptr_t test_class_id; 1895 intptr_t test_class_id;
1918 Function& target = Function::Handle(); 1896 Function& target = Function::Handle();
1919 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1897 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1920 1898
1921 Register value = locs()->in(0).reg(); 1899 Register value = locs()->in(0).reg();
1922 Register result = locs()->out().reg(); 1900 Register result = locs()->out().reg();
1923 ASSERT(value == result); 1901 ASSERT(value == result);
1924 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1902 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1925 instance_call()->try_index(), 1903 instance_call()->try_index(),
1926 kDeoptUnaryOp, 1904 kDeoptUnaryOp);
1927 value);
1928 if (test_class_id == kDoubleCid) { 1905 if (test_class_id == kDoubleCid) {
1929 Register temp = locs()->temp(0).reg(); 1906 Register temp = locs()->temp(0).reg();
1930 __ testq(value, Immediate(kSmiTagMask)); 1907 __ testq(value, Immediate(kSmiTagMask));
1931 __ j(ZERO, deopt); // Smi. 1908 __ j(ZERO, deopt); // Smi.
1932 __ CompareClassId(value, kDoubleCid); 1909 __ CompareClassId(value, kDoubleCid);
1933 __ j(NOT_EQUAL, deopt); 1910 __ j(NOT_EQUAL, deopt);
1934 // Allocate result object. 1911 // Allocate result object.
1935 const Class& double_class = compiler->double_class(); 1912 const Class& double_class = compiler->double_class();
1936 const Code& stub = 1913 const Code& stub =
1937 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1914 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
(...skipping 28 matching lines...) Expand all
1966 return locs; 1943 return locs;
1967 } 1944 }
1968 1945
1969 1946
1970 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1947 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1971 Register value = locs()->in(0).reg(); 1948 Register value = locs()->in(0).reg();
1972 Register result = locs()->out().reg(); 1949 Register result = locs()->out().reg();
1973 1950
1974 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1951 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1975 instance_call()->try_index(), 1952 instance_call()->try_index(),
1976 kDeoptDoubleToDouble, 1953 kDeoptDoubleToDouble);
1977 value);
1978 1954
1979 __ testq(value, Immediate(kSmiTagMask)); 1955 __ testq(value, Immediate(kSmiTagMask));
1980 __ j(ZERO, deopt); // Deoptimize if Smi. 1956 __ j(ZERO, deopt); // Deoptimize if Smi.
1981 __ CompareClassId(value, kDoubleCid); 1957 __ CompareClassId(value, kDoubleCid);
1982 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1958 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1983 ASSERT(value == result); 1959 ASSERT(value == result);
1984 } 1960 }
1985 1961
1986 1962
1987 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { 1963 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 summary->set_temp(0, Location::RequiresRegister()); 2195 summary->set_temp(0, Location::RequiresRegister());
2220 return summary; 2196 return summary;
2221 } 2197 }
2222 2198
2223 2199
2224 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { 2200 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2225 Register value = locs()->in(0).reg(); 2201 Register value = locs()->in(0).reg();
2226 Register temp = locs()->temp(0).reg(); 2202 Register temp = locs()->temp(0).reg();
2227 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2203 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2228 try_index(), 2204 try_index(),
2229 kDeoptCheckClass, 2205 kDeoptCheckClass);
2230 value);
2231 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); 2206 ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid);
2232 __ testq(value, Immediate(kSmiTagMask)); 2207 __ testq(value, Immediate(kSmiTagMask));
2233 __ j(ZERO, deopt); 2208 __ j(ZERO, deopt);
2234 __ LoadClassId(temp, value); 2209 __ LoadClassId(temp, value);
2235 Label is_ok; 2210 Label is_ok;
2236 const intptr_t num_checks = ic_data()->NumberOfChecks(); 2211 const intptr_t num_checks = ic_data()->NumberOfChecks();
2237 const bool use_near_jump = num_checks < 5; 2212 const bool use_near_jump = num_checks < 5;
2238 for (intptr_t i = 0; i < num_checks; i++) { 2213 for (intptr_t i = 0; i < num_checks; i++) {
2239 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); 2214 __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i)));
2240 if (i == (num_checks - 1)) { 2215 if (i == (num_checks - 1)) {
2241 __ j(NOT_EQUAL, deopt); 2216 __ j(NOT_EQUAL, deopt);
2242 } else { 2217 } else {
2243 if (use_near_jump) { 2218 if (use_near_jump) {
2244 __ j(EQUAL, &is_ok, Assembler::kNearJump); 2219 __ j(EQUAL, &is_ok, Assembler::kNearJump);
2245 } else { 2220 } else {
2246 __ j(EQUAL, &is_ok); 2221 __ j(EQUAL, &is_ok);
2247 } 2222 }
2248 } 2223 }
2249 } 2224 }
2250 __ Bind(&is_ok); 2225 __ Bind(&is_ok);
2251 } 2226 }
2252 2227
2253 } // namespace dart 2228 } // namespace dart
2254 2229
2255 #undef __ 2230 #undef __
2256 2231
2257 #endif // defined TARGET_ARCH_X64 2232 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/compiler.cc ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698