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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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.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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 const LocationSummary& locs, 311 const LocationSummary& locs,
312 BranchInstr* branch, 312 BranchInstr* branch,
313 Token::Kind kind, 313 Token::Kind kind,
314 intptr_t deopt_id, 314 intptr_t deopt_id,
315 intptr_t token_pos, 315 intptr_t token_pos,
316 intptr_t try_index) { 316 intptr_t try_index) {
317 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 317 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
318 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 318 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
319 ASSERT(ic_data.NumberOfChecks() > 0); 319 ASSERT(ic_data.NumberOfChecks() > 0);
320 ASSERT(ic_data.num_args_tested() == 1); 320 ASSERT(ic_data.num_args_tested() == 1);
321 Label* deopt = compiler->AddDeoptStub(deopt_id, 321 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality);
322 token_pos,
323 try_index,
324 kDeoptEquality);
325 Register left = locs.in(0).reg(); 322 Register left = locs.in(0).reg();
326 Register right = locs.in(1).reg(); 323 Register right = locs.in(1).reg();
327 __ testl(left, Immediate(kSmiTagMask)); 324 __ testl(left, Immediate(kSmiTagMask));
328 Register temp = locs.temp(0).reg(); 325 Register temp = locs.temp(0).reg();
329 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 326 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
330 Label done, load_class_id; 327 Label done, load_class_id;
331 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 328 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
332 __ movl(temp, Immediate(kSmiCid)); 329 __ movl(temp, Immediate(kSmiCid));
333 __ jmp(&done, Assembler::kNearJump); 330 __ jmp(&done, Assembler::kNearJump);
334 __ Bind(&load_class_id); 331 __ Bind(&load_class_id);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 const LocationSummary& locs, 442 const LocationSummary& locs,
446 Token::Kind kind, 443 Token::Kind kind,
447 BranchInstr* branch, 444 BranchInstr* branch,
448 intptr_t deopt_id, 445 intptr_t deopt_id,
449 intptr_t token_pos, 446 intptr_t token_pos,
450 intptr_t try_index) { 447 intptr_t try_index) {
451 Register left = locs.in(0).reg(); 448 Register left = locs.in(0).reg();
452 Register right = locs.in(1).reg(); 449 Register right = locs.in(1).reg();
453 Register temp = locs.temp(0).reg(); 450 Register temp = locs.temp(0).reg();
454 Label* deopt = compiler->AddDeoptStub(deopt_id, 451 Label* deopt = compiler->AddDeoptStub(deopt_id,
455 token_pos,
456 try_index, 452 try_index,
457 kDeoptSmiCompareSmi, 453 kDeoptSmiCompareSmi,
458 left, 454 left,
459 right); 455 right);
460 __ movl(temp, left); 456 __ movl(temp, left);
461 __ orl(temp, right); 457 __ orl(temp, right);
462 __ testl(temp, Immediate(kSmiTagMask)); 458 __ testl(temp, Immediate(kSmiTagMask));
463 __ j(NOT_ZERO, deopt); 459 __ j(NOT_ZERO, deopt);
464 460
465 Condition true_condition = TokenKindToSmiCondition(kind); 461 Condition true_condition = TokenKindToSmiCondition(kind);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 Token::Kind kind, 496 Token::Kind kind,
501 BranchInstr* branch, 497 BranchInstr* branch,
502 intptr_t deopt_id, 498 intptr_t deopt_id,
503 intptr_t token_pos, 499 intptr_t token_pos,
504 intptr_t try_index) { 500 intptr_t try_index) {
505 Register left = locs.in(0).reg(); 501 Register left = locs.in(0).reg();
506 Register right = locs.in(1).reg(); 502 Register right = locs.in(1).reg();
507 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. 503 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
508 Register temp = locs.temp(0).reg(); 504 Register temp = locs.temp(0).reg();
509 Label* deopt = compiler->AddDeoptStub(deopt_id, 505 Label* deopt = compiler->AddDeoptStub(deopt_id,
510 token_pos,
511 try_index, 506 try_index,
512 kDeoptDoubleComparison, 507 kDeoptDoubleComparison,
513 left, 508 left,
514 right); 509 right);
515 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 510 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
516 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 511 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
517 512
518 Condition true_condition = TokenKindToDoubleCondition(kind); 513 Condition true_condition = TokenKindToDoubleCondition(kind);
519 if (branch != NULL) { 514 if (branch != NULL) {
520 compiler->EmitDoubleCompareBranch( 515 compiler->EmitDoubleCompareBranch(
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 deopt_id(), token_pos(), try_index()); 568 deopt_id(), token_pos(), try_index());
574 return; 569 return;
575 } 570 }
576 if (operands_class_id() == kDoubleCid) { 571 if (operands_class_id() == kDoubleCid) {
577 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 572 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
578 deopt_id(), token_pos(), try_index()); 573 deopt_id(), token_pos(), try_index());
579 return; 574 return;
580 } 575 }
581 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 576 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
582 Label* deopt = compiler->AddDeoptStub(deopt_id(), 577 Label* deopt = compiler->AddDeoptStub(deopt_id(),
583 token_pos(),
584 try_index(), 578 try_index(),
585 kDeoptRelationalOp); 579 kDeoptRelationalOp);
586 // Load receiver into EAX, class into EDI. 580 // Load receiver into EAX, class into EDI.
587 Label done; 581 Label done;
588 const intptr_t kNumArguments = 2; 582 const intptr_t kNumArguments = 2;
589 __ movl(EDI, Immediate(kSmiCid)); 583 __ movl(EDI, Immediate(kSmiCid));
590 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 584 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
591 __ testl(EAX, Immediate(kSmiTagMask)); 585 __ testl(EAX, Immediate(kSmiTagMask));
592 __ j(ZERO, &done); 586 __ j(ZERO, &done);
593 __ LoadClassId(EDI, EAX); 587 __ LoadClassId(EDI, EAX);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 } else { 674 } else {
681 ASSERT(receiver_type() == kIllegalCid); 675 ASSERT(receiver_type() == kIllegalCid);
682 return MakeCallSummary(); 676 return MakeCallSummary();
683 } 677 }
684 } 678 }
685 679
686 680
687 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 681 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
688 LoadIndexedComp* comp) { 682 LoadIndexedComp* comp) {
689 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 683 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
690 comp->token_pos(),
691 comp->try_index(), 684 comp->try_index(),
692 kDeoptLoadIndexedPolymorphic); 685 kDeoptLoadIndexedPolymorphic);
693 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 686 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
694 ASSERT(comp->HasICData()); 687 ASSERT(comp->HasICData());
695 const ICData& ic_data = *comp->ic_data(); 688 const ICData& ic_data = *comp->ic_data();
696 ASSERT(ic_data.num_args_tested() == 1); 689 ASSERT(ic_data.num_args_tested() == 1);
697 // No indexed access on Smi. 690 // No indexed access on Smi.
698 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); 691 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
699 // Load receiver into EAX. 692 // Load receiver into EAX.
700 const intptr_t kNumArguments = 2; 693 const intptr_t kNumArguments = 2;
(...skipping 27 matching lines...) Expand all
728 Register receiver = locs()->in(0).reg(); 721 Register receiver = locs()->in(0).reg();
729 Register index = locs()->in(1).reg(); 722 Register index = locs()->in(1).reg();
730 Register result = locs()->out().reg(); 723 Register result = locs()->out().reg();
731 Register temp = locs()->temp(0).reg(); 724 Register temp = locs()->temp(0).reg();
732 725
733 const DeoptReasonId deopt_reason = 726 const DeoptReasonId deopt_reason =
734 (receiver_type() == kGrowableObjectArrayCid) ? 727 (receiver_type() == kGrowableObjectArrayCid) ?
735 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 728 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
736 729
737 Label* deopt = compiler->AddDeoptStub(deopt_id(), 730 Label* deopt = compiler->AddDeoptStub(deopt_id(),
738 token_pos(),
739 try_index(), 731 try_index(),
740 deopt_reason, 732 deopt_reason,
741 receiver, 733 receiver,
742 index); 734 index);
743 735
744 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 736 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
745 __ j(ZERO, deopt); 737 __ j(ZERO, deopt);
746 __ CompareClassId(receiver, receiver_type(), temp); 738 __ CompareClassId(receiver, receiver_type(), temp);
747 __ j(NOT_EQUAL, deopt); 739 __ j(NOT_EQUAL, deopt);
748 740
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 function_name, 809 function_name,
818 kNumArguments, 810 kNumArguments,
819 Array::ZoneHandle(), // No named arguments. 811 Array::ZoneHandle(), // No named arguments.
820 kNumArgsChecked); 812 kNumArgsChecked);
821 } 813 }
822 814
823 815
824 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 816 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
825 StoreIndexedComp* comp) { 817 StoreIndexedComp* comp) {
826 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 818 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
827 comp->token_pos(),
828 comp->try_index(), 819 comp->try_index(),
829 kDeoptStoreIndexedPolymorphic); 820 kDeoptStoreIndexedPolymorphic);
830 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 821 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
831 ASSERT(comp->HasICData()); 822 ASSERT(comp->HasICData());
832 const ICData& ic_data = *comp->ic_data(); 823 const ICData& ic_data = *comp->ic_data();
833 ASSERT(ic_data.num_args_tested() == 1); 824 ASSERT(ic_data.num_args_tested() == 1);
834 // No indexed access on Smi. 825 // No indexed access on Smi.
835 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); 826 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
836 // Load receiver into EAX. 827 // Load receiver into EAX.
837 const intptr_t kNumArguments = 3; 828 const intptr_t kNumArguments = 3;
(...skipping 22 matching lines...) Expand all
860 } 851 }
861 return; 852 return;
862 } 853 }
863 854
864 Register receiver = locs()->in(0).reg(); 855 Register receiver = locs()->in(0).reg();
865 Register index = locs()->in(1).reg(); 856 Register index = locs()->in(1).reg();
866 Register value = locs()->in(2).reg(); 857 Register value = locs()->in(2).reg();
867 Register temp = locs()->temp(0).reg(); 858 Register temp = locs()->temp(0).reg();
868 859
869 Label* deopt = compiler->AddDeoptStub(deopt_id(), 860 Label* deopt = compiler->AddDeoptStub(deopt_id(),
870 token_pos(),
871 try_index(), 861 try_index(),
872 kDeoptStoreIndexed, 862 kDeoptStoreIndexed,
873 receiver, 863 receiver,
874 index, 864 index,
875 value); 865 value);
876 866
877 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 867 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
878 __ j(ZERO, deopt); 868 __ j(ZERO, deopt);
879 __ CompareClassId(receiver, receiver_type(), temp); 869 __ CompareClassId(receiver, receiver_type(), temp);
880 __ j(NOT_EQUAL, deopt); 870 __ j(NOT_EQUAL, deopt);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 } 915 }
926 916
927 917
928 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 918 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
929 Register instance_reg = locs()->in(0).reg(); 919 Register instance_reg = locs()->in(0).reg();
930 Register result_reg = locs()->out().reg(); 920 Register result_reg = locs()->out().reg();
931 921
932 if (HasICData()) { 922 if (HasICData()) {
933 ASSERT(original() != NULL); 923 ASSERT(original() != NULL);
934 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 924 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
935 original()->token_pos(),
936 original()->try_index(), 925 original()->try_index(),
937 kDeoptInstanceGetterSameTarget, 926 kDeoptInstanceGetterSameTarget,
938 instance_reg); 927 instance_reg);
939 // Smis do not have instance fields (Smi class is always first). 928 // Smis do not have instance fields (Smi class is always first).
940 // Use 'result' as temporary register. 929 // Use 'result' as temporary register.
941 ASSERT(result_reg != instance_reg); 930 ASSERT(result_reg != instance_reg);
942 ASSERT(ic_data() != NULL); 931 ASSERT(ic_data() != NULL);
943 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 932 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
944 } 933 }
945 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); 934 __ movl(result_reg, FieldAddress(instance_reg, field().Offset()));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 LocationSummary::kNoCall); 1048 LocationSummary::kNoCall);
1060 } 1049 }
1061 1050
1062 1051
1063 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1052 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1064 Register instance_reg = locs()->in(0).reg(); 1053 Register instance_reg = locs()->in(0).reg();
1065 Register result_reg = locs()->out().reg(); 1054 Register result_reg = locs()->out().reg();
1066 if (HasICData()) { 1055 if (HasICData()) {
1067 ASSERT(original() != NULL); 1056 ASSERT(original() != NULL);
1068 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(), 1057 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
1069 original()->token_pos(),
1070 original()->try_index(), 1058 original()->try_index(),
1071 kDeoptInstanceGetterSameTarget, 1059 kDeoptInstanceGetterSameTarget,
1072 instance_reg); 1060 instance_reg);
1073 // Smis do not have instance fields (Smi class is always first). 1061 // Smis do not have instance fields (Smi class is always first).
1074 // Use 'result' as temporary register. 1062 // Use 'result' as temporary register.
1075 ASSERT(result_reg != instance_reg); 1063 ASSERT(result_reg != instance_reg);
1076 ASSERT(ic_data() != NULL); 1064 ASSERT(ic_data() != NULL);
1077 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 1065 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1078 } 1066 }
1079 1067
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 } 1423 }
1436 1424
1437 1425
1438 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1426 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1439 Register left = comp->locs()->in(0).reg(); 1427 Register left = comp->locs()->in(0).reg();
1440 Register right = comp->locs()->in(1).reg(); 1428 Register right = comp->locs()->in(1).reg();
1441 Register result = comp->locs()->out().reg(); 1429 Register result = comp->locs()->out().reg();
1442 Register temp = comp->locs()->temp(0).reg(); 1430 Register temp = comp->locs()->temp(0).reg();
1443 ASSERT(left == result); 1431 ASSERT(left == result);
1444 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1432 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1445 comp->instance_call()->token_pos(),
1446 comp->instance_call()->try_index(), 1433 comp->instance_call()->try_index(),
1447 kDeoptSmiBinaryOp, 1434 kDeoptSmiBinaryOp,
1448 temp, 1435 temp,
1449 right); 1436 right);
1450 // TODO(vegorov): for many binary operations this pattern can be rearranged 1437 // TODO(vegorov): for many binary operations this pattern can be rearranged
1451 // to save one move. 1438 // to save one move.
1452 __ movl(temp, left); 1439 __ movl(temp, left);
1453 __ orl(left, right); 1440 __ orl(left, right);
1454 __ testl(left, Immediate(kSmiTagMask)); 1441 __ testl(left, Immediate(kSmiTagMask));
1455 __ j(NOT_ZERO, deopt); 1442 __ j(NOT_ZERO, deopt);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 // receiver and a Mint or Smi argument. We fall back to the run time call if 1580 // receiver and a Mint or Smi argument. We fall back to the run time call if
1594 // both receiver and argument are Mint or if one of them is Mint and the other 1581 // both receiver and argument are Mint or if one of them is Mint and the other
1595 // is a negative Smi. 1582 // is a negative Smi.
1596 Register left = comp->locs()->in(0).reg(); 1583 Register left = comp->locs()->in(0).reg();
1597 Register right = comp->locs()->in(1).reg(); 1584 Register right = comp->locs()->in(1).reg();
1598 Register result = comp->locs()->out().reg(); 1585 Register result = comp->locs()->out().reg();
1599 Register temp = comp->locs()->temp(0).reg(); 1586 Register temp = comp->locs()->temp(0).reg();
1600 ASSERT(left == result); 1587 ASSERT(left == result);
1601 ASSERT(comp->op_kind() == Token::kBIT_AND); 1588 ASSERT(comp->op_kind() == Token::kBIT_AND);
1602 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1589 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1603 comp->instance_call()->token_pos(),
1604 comp->instance_call()->try_index(), 1590 comp->instance_call()->try_index(),
1605 kDeoptMintBinaryOp, 1591 kDeoptMintBinaryOp,
1606 left, 1592 left,
1607 right); 1593 right);
1608 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1594 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1609 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1595 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1610 __ j(NOT_ZERO, &non_smi); 1596 __ j(NOT_ZERO, &non_smi);
1611 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? 1597 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1612 __ j(ZERO, &smi_smi); 1598 __ j(ZERO, &smi_smi);
1613 __ CompareClassId(right, kMintCid, temp); // Is argument Mint? 1599 __ CompareClassId(right, kMintCid, temp); // Is argument Mint?
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 compiler->GenerateCall(instance_call()->token_pos(), 1700 compiler->GenerateCall(instance_call()->token_pos(),
1715 instance_call()->try_index(), 1701 instance_call()->try_index(),
1716 &label, 1702 &label,
1717 PcDescriptors::kOther); 1703 PcDescriptors::kOther);
1718 // Newly allocated object is now in the result register (RAX). 1704 // Newly allocated object is now in the result register (RAX).
1719 ASSERT(result == EAX); 1705 ASSERT(result == EAX);
1720 __ popl(right); 1706 __ popl(right);
1721 __ popl(left); 1707 __ popl(left);
1722 1708
1723 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1709 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1724 instance_call()->token_pos(),
1725 instance_call()->try_index(), 1710 instance_call()->try_index(),
1726 kDeoptDoubleBinaryOp, 1711 kDeoptDoubleBinaryOp,
1727 left, 1712 left,
1728 right); 1713 right);
1729 1714
1730 // Binary operation of two Smi's produces a Smi not a double. 1715 // Binary operation of two Smi's produces a Smi not a double.
1731 __ movl(temp, left); 1716 __ movl(temp, left);
1732 __ orl(temp, right); 1717 __ orl(temp, right);
1733 __ testl(temp, Immediate(kSmiTagMask)); 1718 __ testl(temp, Immediate(kSmiTagMask));
1734 __ j(ZERO, deopt); 1719 __ j(ZERO, deopt);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 // TODO(srdjan): Implement for more checks. 1751 // TODO(srdjan): Implement for more checks.
1767 ASSERT(ic_data.NumberOfChecks() == 1); 1752 ASSERT(ic_data.NumberOfChecks() == 1);
1768 intptr_t test_class_id; 1753 intptr_t test_class_id;
1769 Function& target = Function::Handle(); 1754 Function& target = Function::Handle();
1770 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1755 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1771 1756
1772 Register value = locs()->in(0).reg(); 1757 Register value = locs()->in(0).reg();
1773 Register result = locs()->out().reg(); 1758 Register result = locs()->out().reg();
1774 ASSERT(value == result); 1759 ASSERT(value == result);
1775 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1760 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1776 instance_call()->token_pos(),
1777 instance_call()->try_index(), 1761 instance_call()->try_index(),
1778 kDeoptUnaryOp, 1762 kDeoptUnaryOp,
1779 value); 1763 value);
1780 if (test_class_id == kSmiCid) { 1764 if (test_class_id == kSmiCid) {
1781 __ testl(value, Immediate(kSmiTagMask)); 1765 __ testl(value, Immediate(kSmiTagMask));
1782 __ j(NOT_ZERO, deopt); 1766 __ j(NOT_ZERO, deopt);
1783 switch (op_kind()) { 1767 switch (op_kind()) {
1784 case Token::kNEGATE: 1768 case Token::kNEGATE:
1785 __ negl(value); 1769 __ negl(value);
1786 __ j(OVERFLOW, deopt); 1770 __ j(OVERFLOW, deopt);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 // TODO(srdjan): Implement for more checks. 1802 // TODO(srdjan): Implement for more checks.
1819 ASSERT(ic_data.NumberOfChecks() == 1); 1803 ASSERT(ic_data.NumberOfChecks() == 1);
1820 intptr_t test_class_id; 1804 intptr_t test_class_id;
1821 Function& target = Function::Handle(); 1805 Function& target = Function::Handle();
1822 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1806 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1823 1807
1824 Register value = locs()->in(0).reg(); 1808 Register value = locs()->in(0).reg();
1825 Register result = locs()->out().reg(); 1809 Register result = locs()->out().reg();
1826 ASSERT(value == result); 1810 ASSERT(value == result);
1827 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1811 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1828 instance_call()->token_pos(),
1829 instance_call()->try_index(), 1812 instance_call()->try_index(),
1830 kDeoptUnaryOp, 1813 kDeoptUnaryOp,
1831 value); 1814 value);
1832 if (test_class_id == kDoubleCid) { 1815 if (test_class_id == kDoubleCid) {
1833 Register temp = locs()->temp(0).reg(); 1816 Register temp = locs()->temp(0).reg();
1834 __ testl(value, Immediate(kSmiTagMask)); 1817 __ testl(value, Immediate(kSmiTagMask));
1835 __ j(ZERO, deopt); // Smi. 1818 __ j(ZERO, deopt); // Smi.
1836 __ CompareClassId(value, kDoubleCid, temp); 1819 __ CompareClassId(value, kDoubleCid, temp);
1837 __ j(NOT_EQUAL, deopt); 1820 __ j(NOT_EQUAL, deopt);
1838 // Allocate result object. 1821 // Allocate result object.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1876 } 1859 }
1877 1860
1878 1861
1879 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1862 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1880 Register value = (from() == kDoubleCid) ? locs()->in(0).reg() : EBX; 1863 Register value = (from() == kDoubleCid) ? locs()->in(0).reg() : EBX;
1881 Register result = locs()->out().reg(); 1864 Register result = locs()->out().reg();
1882 1865
1883 const DeoptReasonId deopt_reason = (from() == kDoubleCid) ? 1866 const DeoptReasonId deopt_reason = (from() == kDoubleCid) ?
1884 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1867 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1885 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1868 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1886 instance_call()->token_pos(),
1887 instance_call()->try_index(), 1869 instance_call()->try_index(),
1888 deopt_reason, 1870 deopt_reason,
1889 value); 1871 value);
1890 1872
1891 if (from() == kDoubleCid) { 1873 if (from() == kDoubleCid) {
1892 Register temp = locs()->temp(0).reg(); 1874 Register temp = locs()->temp(0).reg();
1893 __ testl(value, Immediate(kSmiTagMask)); 1875 __ testl(value, Immediate(kSmiTagMask));
1894 __ j(ZERO, deopt); // Deoptimize if Smi. 1876 __ j(ZERO, deopt); // Deoptimize if Smi.
1895 __ CompareClassId(value, kDoubleCid, temp); 1877 __ CompareClassId(value, kDoubleCid, temp);
1896 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1878 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
(...skipping 24 matching lines...) Expand all
1921 } 1903 }
1922 1904
1923 1905
1924 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1906 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1925 return MakeCallSummary(); 1907 return MakeCallSummary();
1926 } 1908 }
1927 1909
1928 1910
1929 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1911 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1930 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1912 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1931 instance_call()->token_pos(),
1932 instance_call()->try_index(), 1913 instance_call()->try_index(),
1933 kDeoptPolymorphicInstanceCallTestFail); 1914 kDeoptPolymorphicInstanceCallTestFail);
1934 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 1915 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1935 __ jmp(deopt); 1916 __ jmp(deopt);
1936 return; 1917 return;
1937 } 1918 }
1938 ASSERT(HasICData()); 1919 ASSERT(HasICData());
1939 ASSERT(ic_data()->num_args_tested() == 1); 1920 ASSERT(ic_data()->num_args_tested() == 1);
1940 Label handle_smi; 1921 Label handle_smi;
1941 Label* is_smi_label = 1922 Label* is_smi_label =
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2072 ASSERT(locs()->out().reg() == EAX); 2053 ASSERT(locs()->out().reg() == EAX);
2073 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2054 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2074 EmitBranchOnCondition(compiler, branch_condition); 2055 EmitBranchOnCondition(compiler, branch_condition);
2075 } 2056 }
2076 2057
2077 } // namespace dart 2058 } // namespace dart
2078 2059
2079 #undef __ 2060 #undef __
2080 2061
2081 #endif // defined TARGET_ARCH_X64 2062 #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