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

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

Issue 10832214: Move deopt reason into PcDescriptor so the EAX/RAX register is not destroyed. Some cleanups in PC d… (Closed) Base URL: http://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
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/object.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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 const LocationSummary& locs, 319 const LocationSummary& locs,
320 BranchInstr* branch, 320 BranchInstr* branch,
321 Token::Kind kind, 321 Token::Kind kind,
322 intptr_t deopt_id, 322 intptr_t deopt_id,
323 intptr_t token_pos, 323 intptr_t token_pos,
324 intptr_t try_index) { 324 intptr_t try_index) {
325 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 325 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
326 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 326 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
327 ASSERT(ic_data.NumberOfChecks() > 0); 327 ASSERT(ic_data.NumberOfChecks() > 0);
328 ASSERT(ic_data.num_args_tested() == 1); 328 ASSERT(ic_data.num_args_tested() == 1);
329 Label* deopt = compiler->AddDeoptStub(deopt_id, 329 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality);
330 token_pos,
331 try_index,
332 kDeoptEquality);
333 Register left = locs.in(0).reg(); 330 Register left = locs.in(0).reg();
334 Register right = locs.in(1).reg(); 331 Register right = locs.in(1).reg();
335 __ testq(left, Immediate(kSmiTagMask)); 332 __ testq(left, Immediate(kSmiTagMask));
336 Register temp = locs.temp(0).reg(); 333 Register temp = locs.temp(0).reg();
337 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 334 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
338 Label done, load_class_id; 335 Label done, load_class_id;
339 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 336 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
340 __ movq(temp, Immediate(kSmiCid)); 337 __ movq(temp, Immediate(kSmiCid));
341 __ jmp(&done, Assembler::kNearJump); 338 __ jmp(&done, Assembler::kNearJump);
342 __ Bind(&load_class_id); 339 __ Bind(&load_class_id);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 const LocationSummary& locs, 450 const LocationSummary& locs,
454 Token::Kind kind, 451 Token::Kind kind,
455 BranchInstr* branch, 452 BranchInstr* branch,
456 intptr_t deopt_id, 453 intptr_t deopt_id,
457 intptr_t token_pos, 454 intptr_t token_pos,
458 intptr_t try_index) { 455 intptr_t try_index) {
459 Register left = locs.in(0).reg(); 456 Register left = locs.in(0).reg();
460 Register right = locs.in(1).reg(); 457 Register right = locs.in(1).reg();
461 Register temp = locs.temp(0).reg(); 458 Register temp = locs.temp(0).reg();
462 Label* deopt = compiler->AddDeoptStub(deopt_id, 459 Label* deopt = compiler->AddDeoptStub(deopt_id,
463 token_pos,
464 try_index, 460 try_index,
465 kDeoptSmiCompareSmi, 461 kDeoptSmiCompareSmi,
466 left, 462 left,
467 right); 463 right);
468 __ movq(temp, left); 464 __ movq(temp, left);
469 __ orq(temp, right); 465 __ orq(temp, right);
470 __ testq(temp, Immediate(kSmiTagMask)); 466 __ testq(temp, Immediate(kSmiTagMask));
471 __ j(NOT_ZERO, deopt); 467 __ j(NOT_ZERO, deopt);
472 468
473 Condition true_condition = TokenKindToSmiCondition(kind); 469 Condition true_condition = TokenKindToSmiCondition(kind);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 Token::Kind kind, 504 Token::Kind kind,
509 BranchInstr* branch, 505 BranchInstr* branch,
510 intptr_t deopt_id, 506 intptr_t deopt_id,
511 intptr_t token_pos, 507 intptr_t token_pos,
512 intptr_t try_index) { 508 intptr_t try_index) {
513 Register left = locs.in(0).reg(); 509 Register left = locs.in(0).reg();
514 Register right = locs.in(1).reg(); 510 Register right = locs.in(1).reg();
515 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. 511 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
516 Register temp = locs.temp(0).reg(); 512 Register temp = locs.temp(0).reg();
517 Label* deopt = compiler->AddDeoptStub(deopt_id, 513 Label* deopt = compiler->AddDeoptStub(deopt_id,
518 token_pos,
519 try_index, 514 try_index,
520 kDeoptDoubleComparison, 515 kDeoptDoubleComparison,
521 left, 516 left,
522 right); 517 right);
523 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 518 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
524 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 519 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
525 520
526 Condition true_condition = TokenKindToDoubleCondition(kind); 521 Condition true_condition = TokenKindToDoubleCondition(kind);
527 if (branch != NULL) { 522 if (branch != NULL) {
528 compiler->EmitDoubleCompareBranch( 523 compiler->EmitDoubleCompareBranch(
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 deopt_id(), token_pos(), try_index()); 576 deopt_id(), token_pos(), try_index());
582 return; 577 return;
583 } 578 }
584 if (operands_class_id() == kDoubleCid) { 579 if (operands_class_id() == kDoubleCid) {
585 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 580 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
586 deopt_id(), token_pos(), try_index()); 581 deopt_id(), token_pos(), try_index());
587 return; 582 return;
588 } 583 }
589 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 584 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
590 Label* deopt = compiler->AddDeoptStub(deopt_id(), 585 Label* deopt = compiler->AddDeoptStub(deopt_id(),
591 token_pos(),
592 try_index(), 586 try_index(),
593 kDeoptRelationalOp); 587 kDeoptRelationalOp);
594 // Load receiver into RAX, class into RDI. 588 // Load receiver into RAX, class into RDI.
595 Label done; 589 Label done;
596 const intptr_t kNumArguments = 2; 590 const intptr_t kNumArguments = 2;
597 __ movq(RDI, Immediate(kSmiCid)); 591 __ movq(RDI, Immediate(kSmiCid));
598 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 592 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
599 __ testq(RAX, Immediate(kSmiTagMask)); 593 __ testq(RAX, Immediate(kSmiTagMask));
600 __ j(ZERO, &done); 594 __ j(ZERO, &done);
601 __ LoadClassId(RDI, RAX); 595 __ LoadClassId(RDI, RAX);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 } else { 685 } else {
692 ASSERT(receiver_type() == kIllegalCid); 686 ASSERT(receiver_type() == kIllegalCid);
693 return MakeCallSummary(); 687 return MakeCallSummary();
694 } 688 }
695 } 689 }
696 690
697 691
698 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 692 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
699 LoadIndexedComp* comp) { 693 LoadIndexedComp* comp) {
700 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 694 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
701 comp->token_pos(),
702 comp->try_index(), 695 comp->try_index(),
703 kDeoptLoadIndexedPolymorphic); 696 kDeoptLoadIndexedPolymorphic);
704 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 697 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
705 ASSERT(comp->HasICData()); 698 ASSERT(comp->HasICData());
706 const ICData& ic_data = *comp->ic_data(); 699 const ICData& ic_data = *comp->ic_data();
707 ASSERT(ic_data.num_args_tested() == 1); 700 ASSERT(ic_data.num_args_tested() == 1);
708 // No indexed access on Smi. 701 // No indexed access on Smi.
709 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); 702 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
710 // Load receiver into RAX. 703 // Load receiver into RAX.
711 const intptr_t kNumArguments = 2; 704 const intptr_t kNumArguments = 2;
(...skipping 26 matching lines...) Expand all
738 731
739 Register receiver = locs()->in(0).reg(); 732 Register receiver = locs()->in(0).reg();
740 Register index = locs()->in(1).reg(); 733 Register index = locs()->in(1).reg();
741 Register result = locs()->out().reg(); 734 Register result = locs()->out().reg();
742 735
743 const DeoptReasonId deopt_reason = 736 const DeoptReasonId deopt_reason =
744 (receiver_type() == kGrowableObjectArrayCid) ? 737 (receiver_type() == kGrowableObjectArrayCid) ?
745 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 738 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
746 739
747 Label* deopt = compiler->AddDeoptStub(deopt_id(), 740 Label* deopt = compiler->AddDeoptStub(deopt_id(),
748 token_pos(),
749 try_index(), 741 try_index(),
750 deopt_reason, 742 deopt_reason,
751 receiver, 743 receiver,
752 index); 744 index);
753 745
754 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 746 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
755 __ j(ZERO, deopt); 747 __ j(ZERO, deopt);
756 __ CompareClassId(receiver, receiver_type()); 748 __ CompareClassId(receiver, receiver_type());
757 __ j(NOT_EQUAL, deopt); 749 __ j(NOT_EQUAL, deopt);
758 750
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 function_name, 822 function_name,
831 kNumArguments, 823 kNumArguments,
832 Array::ZoneHandle(), // No named arguments. 824 Array::ZoneHandle(), // No named arguments.
833 kNumArgsChecked); 825 kNumArgsChecked);
834 } 826 }
835 827
836 828
837 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 829 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
838 StoreIndexedComp* comp) { 830 StoreIndexedComp* comp) {
839 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 831 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
840 comp->token_pos(),
841 comp->try_index(), 832 comp->try_index(),
842 kDeoptStoreIndexedPolymorphic); 833 kDeoptStoreIndexedPolymorphic);
843 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 834 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
844 ASSERT(comp->HasICData()); 835 ASSERT(comp->HasICData());
845 const ICData& ic_data = *comp->ic_data(); 836 const ICData& ic_data = *comp->ic_data();
846 ASSERT(ic_data.num_args_tested() == 1); 837 ASSERT(ic_data.num_args_tested() == 1);
847 // No indexed access on Smi. 838 // No indexed access on Smi.
848 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); 839 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
849 // Load receiver into RAX. 840 // Load receiver into RAX.
850 const intptr_t kNumArguments = 3; 841 const intptr_t kNumArguments = 3;
(...skipping 21 matching lines...) Expand all
872 EmitStoreIndexedGeneric(compiler, this); 863 EmitStoreIndexedGeneric(compiler, this);
873 } 864 }
874 return; 865 return;
875 } 866 }
876 867
877 Register receiver = locs()->in(0).reg(); 868 Register receiver = locs()->in(0).reg();
878 Register index = locs()->in(1).reg(); 869 Register index = locs()->in(1).reg();
879 Register value = locs()->in(2).reg(); 870 Register value = locs()->in(2).reg();
880 871
881 Label* deopt = compiler->AddDeoptStub(deopt_id(), 872 Label* deopt = compiler->AddDeoptStub(deopt_id(),
882 token_pos(),
883 try_index(), 873 try_index(),
884 kDeoptStoreIndexed, 874 kDeoptStoreIndexed,
885 receiver, 875 receiver,
886 index, 876 index,
887 value); 877 value);
888 878
889 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 879 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
890 __ j(ZERO, deopt); 880 __ j(ZERO, deopt);
891 __ CompareClassId(receiver, receiver_type()); 881 __ CompareClassId(receiver, receiver_type());
892 __ j(NOT_EQUAL, deopt); 882 __ j(NOT_EQUAL, deopt);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 } 928 }
939 929
940 930
941 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 931 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
942 Register instance_reg = locs()->in(0).reg(); 932 Register instance_reg = locs()->in(0).reg();
943 Register result_reg = locs()->out().reg(); 933 Register result_reg = locs()->out().reg();
944 934
945 if (HasICData()) { 935 if (HasICData()) {
946 ASSERT(original() != NULL); 936 ASSERT(original() != NULL);
947 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 937 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
948 original()->token_pos(),
949 original()->try_index(), 938 original()->try_index(),
950 kDeoptInstanceGetterSameTarget, 939 kDeoptInstanceGetterSameTarget,
951 instance_reg); 940 instance_reg);
952 // Smis do not have instance fields (Smi class is always first). 941 // Smis do not have instance fields (Smi class is always first).
953 // Use 'result' as temporary register. 942 // Use 'result' as temporary register.
954 ASSERT(result_reg != instance_reg); 943 ASSERT(result_reg != instance_reg);
955 ASSERT(ic_data() != NULL); 944 ASSERT(ic_data() != NULL);
956 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 945 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
957 } 946 }
958 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); 947 __ movq(result_reg, FieldAddress(instance_reg, field().Offset()));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 LocationSummary::kNoCall); 1060 LocationSummary::kNoCall);
1072 } 1061 }
1073 1062
1074 1063
1075 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1064 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1076 Register instance_reg = locs()->in(0).reg(); 1065 Register instance_reg = locs()->in(0).reg();
1077 Register result_reg = locs()->out().reg(); 1066 Register result_reg = locs()->out().reg();
1078 if (HasICData()) { 1067 if (HasICData()) {
1079 ASSERT(original() != NULL); 1068 ASSERT(original() != NULL);
1080 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 1069 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
1081 original()->token_pos(),
1082 original()->try_index(), 1070 original()->try_index(),
1083 kDeoptInstanceGetterSameTarget, 1071 kDeoptInstanceGetterSameTarget,
1084 instance_reg); 1072 instance_reg);
1085 // Smis do not have instance fields (Smi class is always first). 1073 // Smis do not have instance fields (Smi class is always first).
1086 // Use 'result' as temporary register. 1074 // Use 'result' as temporary register.
1087 ASSERT(result_reg != instance_reg); 1075 ASSERT(result_reg != instance_reg);
1088 ASSERT(ic_data() != NULL); 1076 ASSERT(ic_data() != NULL);
1089 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 1077 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1090 } 1078 }
1091 1079
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 } 1433 }
1446 1434
1447 1435
1448 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1436 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1449 Register left = comp->locs()->in(0).reg(); 1437 Register left = comp->locs()->in(0).reg();
1450 Register right = comp->locs()->in(1).reg(); 1438 Register right = comp->locs()->in(1).reg();
1451 Register result = comp->locs()->out().reg(); 1439 Register result = comp->locs()->out().reg();
1452 Register temp = comp->locs()->temp(0).reg(); 1440 Register temp = comp->locs()->temp(0).reg();
1453 ASSERT(left == result); 1441 ASSERT(left == result);
1454 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1442 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1455 comp->instance_call()->token_pos(),
1456 comp->instance_call()->try_index(), 1443 comp->instance_call()->try_index(),
1457 kDeoptSmiBinaryOp, 1444 kDeoptSmiBinaryOp,
1458 temp, 1445 temp,
1459 right); 1446 right);
1460 // TODO(vegorov): for many binary operations this pattern can be rearranged 1447 // TODO(vegorov): for many binary operations this pattern can be rearranged
1461 // to save one move. 1448 // to save one move.
1462 __ movq(temp, left); 1449 __ movq(temp, left);
1463 __ orq(left, right); 1450 __ orq(left, right);
1464 __ testq(left, Immediate(kSmiTagMask)); 1451 __ testq(left, Immediate(kSmiTagMask));
1465 __ j(NOT_ZERO, deopt); 1452 __ j(NOT_ZERO, deopt);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1589 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1603 // receiver and a Mint or Smi argument. We fall back to the run time call if 1590 // receiver and a Mint or Smi argument. We fall back to the run time call if
1604 // both receiver and argument are Mint or if one of them is Mint and the other 1591 // both receiver and argument are Mint or if one of them is Mint and the other
1605 // is a negative Smi. 1592 // is a negative Smi.
1606 Register left = comp->locs()->in(0).reg(); 1593 Register left = comp->locs()->in(0).reg();
1607 Register right = comp->locs()->in(1).reg(); 1594 Register right = comp->locs()->in(1).reg();
1608 Register result = comp->locs()->out().reg(); 1595 Register result = comp->locs()->out().reg();
1609 ASSERT(left == result); 1596 ASSERT(left == result);
1610 ASSERT(comp->op_kind() == Token::kBIT_AND); 1597 ASSERT(comp->op_kind() == Token::kBIT_AND);
1611 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1598 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1612 comp->instance_call()->token_pos(),
1613 comp->instance_call()->try_index(), 1599 comp->instance_call()->try_index(),
1614 kDeoptMintBinaryOp, 1600 kDeoptMintBinaryOp,
1615 left, 1601 left,
1616 right); 1602 right);
1617 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1603 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1618 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1604 __ testq(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1619 __ j(NOT_ZERO, &non_smi); 1605 __ j(NOT_ZERO, &non_smi);
1620 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi? 1606 __ testq(right, Immediate(kSmiTagMask)); // Is argument Smi?
1621 __ j(ZERO, &smi_smi); 1607 __ j(ZERO, &smi_smi);
1622 __ CompareClassId(right, kMintCid); // Is argument Mint? 1608 __ CompareClassId(right, kMintCid); // Is argument Mint?
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 compiler->GenerateCall(instance_call()->token_pos(), 1709 compiler->GenerateCall(instance_call()->token_pos(),
1724 instance_call()->try_index(), 1710 instance_call()->try_index(),
1725 &label, 1711 &label,
1726 PcDescriptors::kOther); 1712 PcDescriptors::kOther);
1727 // Newly allocated object is now in the result register (RAX). 1713 // Newly allocated object is now in the result register (RAX).
1728 ASSERT(result == RAX); 1714 ASSERT(result == RAX);
1729 __ popq(right); 1715 __ popq(right);
1730 __ popq(left); 1716 __ popq(left);
1731 1717
1732 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1718 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1733 instance_call()->token_pos(),
1734 instance_call()->try_index(), 1719 instance_call()->try_index(),
1735 kDeoptDoubleBinaryOp, 1720 kDeoptDoubleBinaryOp,
1736 left, 1721 left,
1737 right); 1722 right);
1738 1723
1739 // Binary operation of two Smi's produces a Smi not a double. 1724 // Binary operation of two Smi's produces a Smi not a double.
1740 __ movq(temp, left); 1725 __ movq(temp, left);
1741 __ orq(temp, right); 1726 __ orq(temp, right);
1742 __ testq(temp, Immediate(kSmiTagMask)); 1727 __ testq(temp, Immediate(kSmiTagMask));
1743 __ j(ZERO, deopt); 1728 __ j(ZERO, deopt);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 // TODO(srdjan): Implement for more checks. 1760 // TODO(srdjan): Implement for more checks.
1776 ASSERT(ic_data.NumberOfChecks() == 1); 1761 ASSERT(ic_data.NumberOfChecks() == 1);
1777 intptr_t test_class_id; 1762 intptr_t test_class_id;
1778 Function& target = Function::Handle(); 1763 Function& target = Function::Handle();
1779 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1764 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1780 1765
1781 Register value = locs()->in(0).reg(); 1766 Register value = locs()->in(0).reg();
1782 Register result = locs()->out().reg(); 1767 Register result = locs()->out().reg();
1783 ASSERT(value == result); 1768 ASSERT(value == result);
1784 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1769 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1785 instance_call()->token_pos(),
1786 instance_call()->try_index(), 1770 instance_call()->try_index(),
1787 kDeoptUnaryOp, 1771 kDeoptUnaryOp,
1788 value); 1772 value);
1789 if (test_class_id == kSmiCid) { 1773 if (test_class_id == kSmiCid) {
1790 __ testq(value, Immediate(kSmiTagMask)); 1774 __ testq(value, Immediate(kSmiTagMask));
1791 __ j(NOT_ZERO, deopt); 1775 __ j(NOT_ZERO, deopt);
1792 switch (op_kind()) { 1776 switch (op_kind()) {
1793 case Token::kNEGATE: 1777 case Token::kNEGATE:
1794 __ negq(value); 1778 __ negq(value);
1795 __ j(OVERFLOW, deopt); 1779 __ j(OVERFLOW, deopt);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 // TODO(srdjan): Implement for more checks. 1811 // TODO(srdjan): Implement for more checks.
1828 ASSERT(ic_data.NumberOfChecks() == 1); 1812 ASSERT(ic_data.NumberOfChecks() == 1);
1829 intptr_t test_class_id; 1813 intptr_t test_class_id;
1830 Function& target = Function::Handle(); 1814 Function& target = Function::Handle();
1831 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1815 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1832 1816
1833 Register value = locs()->in(0).reg(); 1817 Register value = locs()->in(0).reg();
1834 Register result = locs()->out().reg(); 1818 Register result = locs()->out().reg();
1835 ASSERT(value == result); 1819 ASSERT(value == result);
1836 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1820 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1837 instance_call()->token_pos(),
1838 instance_call()->try_index(), 1821 instance_call()->try_index(),
1839 kDeoptUnaryOp, 1822 kDeoptUnaryOp,
1840 value); 1823 value);
1841 if (test_class_id == kDoubleCid) { 1824 if (test_class_id == kDoubleCid) {
1842 Register temp = locs()->temp(0).reg(); 1825 Register temp = locs()->temp(0).reg();
1843 __ testq(value, Immediate(kSmiTagMask)); 1826 __ testq(value, Immediate(kSmiTagMask));
1844 __ j(ZERO, deopt); // Smi. 1827 __ j(ZERO, deopt); // Smi.
1845 __ CompareClassId(value, kDoubleCid); 1828 __ CompareClassId(value, kDoubleCid);
1846 __ j(NOT_EQUAL, deopt); 1829 __ j(NOT_EQUAL, deopt);
1847 // Allocate result object. 1830 // Allocate result object.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1883 } 1866 }
1884 1867
1885 1868
1886 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1869 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1887 Register value = (from() == kDoubleCid) ? locs()->in(0).reg() : RBX; 1870 Register value = (from() == kDoubleCid) ? locs()->in(0).reg() : RBX;
1888 Register result = locs()->out().reg(); 1871 Register result = locs()->out().reg();
1889 1872
1890 const DeoptReasonId deopt_reason = (from() == kDoubleCid) ? 1873 const DeoptReasonId deopt_reason = (from() == kDoubleCid) ?
1891 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1874 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1892 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1875 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1893 instance_call()->token_pos(),
1894 instance_call()->try_index(), 1876 instance_call()->try_index(),
1895 deopt_reason, 1877 deopt_reason,
1896 value); 1878 value);
1897 1879
1898 if (from() == kDoubleCid) { 1880 if (from() == kDoubleCid) {
1899 __ testq(value, Immediate(kSmiTagMask)); 1881 __ testq(value, Immediate(kSmiTagMask));
1900 __ j(ZERO, deopt); // Deoptimize if Smi. 1882 __ j(ZERO, deopt); // Deoptimize if Smi.
1901 __ CompareClassId(value, kDoubleCid); 1883 __ CompareClassId(value, kDoubleCid);
1902 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1884 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1903 ASSERT(value == result); 1885 ASSERT(value == result);
(...skipping 23 matching lines...) Expand all
1927 } 1909 }
1928 1910
1929 1911
1930 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1912 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1931 return MakeCallSummary(); 1913 return MakeCallSummary();
1932 } 1914 }
1933 1915
1934 1916
1935 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1917 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1936 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1918 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1937 instance_call()->token_pos(),
1938 instance_call()->try_index(), 1919 instance_call()->try_index(),
1939 kDeoptPolymorphicInstanceCallTestFail); 1920 kDeoptPolymorphicInstanceCallTestFail);
1940 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 1921 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1941 __ jmp(deopt); 1922 __ jmp(deopt);
1942 return; 1923 return;
1943 } 1924 }
1944 ASSERT(HasICData()); 1925 ASSERT(HasICData());
1945 ASSERT(ic_data()->num_args_tested() == 1); 1926 ASSERT(ic_data()->num_args_tested() == 1);
1946 Label handle_smi; 1927 Label handle_smi;
1947 Label* is_smi_label = 1928 Label* is_smi_label =
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 ASSERT(locs()->out().reg() == RAX); 2059 ASSERT(locs()->out().reg() == RAX);
2079 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2060 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2080 EmitBranchOnCondition(compiler, branch_condition); 2061 EmitBranchOnCondition(compiler, branch_condition);
2081 } 2062 }
2082 2063
2083 } // namespace dart 2064 } // namespace dart
2084 2065
2085 #undef __ 2066 #undef __
2086 2067
2087 #endif // defined TARGET_ARCH_X64 2068 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698