| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |