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

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

Issue 10651008: Minimize differences between ia32 and x64 sources to facilitate maintenance. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | « no previous file | 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"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/parser.h"
srdjan 2012/06/22 00:34:40 Why do we need this include?
regis 2012/06/22 01:24:53 Actually, I wonder why it was not needed in the fi
14 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
15 16
16 #define __ compiler->assembler()-> 17 #define __ compiler->assembler()->
17 18
18 namespace dart { 19 namespace dart {
19 20
20 DECLARE_FLAG(int, optimization_counter_threshold); 21 DECLARE_FLAG(int, optimization_counter_threshold);
21 DECLARE_FLAG(bool, trace_functions); 22 DECLARE_FLAG(bool, trace_functions);
22 23
23 // Generic summary for call instructions that have all arguments pushed 24 // Generic summary for call instructions that have all arguments pushed
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 __ pushl(temp); 86 __ pushl(temp);
86 compiler->GenerateCallRuntime(AstNode::kNoId, 87 compiler->GenerateCallRuntime(AstNode::kNoId,
87 0, 88 0,
88 CatchClauseNode::kInvalidTryIndex, 89 CatchClauseNode::kInvalidTryIndex,
89 kTraceFunctionExitRuntimeEntry); 90 kTraceFunctionExitRuntimeEntry);
90 __ popl(temp); // Remove argument. 91 __ popl(temp); // Remove argument.
91 __ popl(result); // Restore result. 92 __ popl(result); // Restore result.
92 } 93 }
93 __ LeaveFrame(); 94 __ LeaveFrame();
94 __ ret(); 95 __ ret();
95 // Add a NOP to make return code pattern 5 bytes long for patching 96
96 // in breakpoints during debugging. 97 // Generate 1 byte NOP so that the debugger can patch the
98 // return pattern with a call to the debug stub.
97 __ nop(1); 99 __ nop(1);
98 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 100 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
99 cid(), 101 cid(),
100 token_index(), 102 token_index(),
101 CatchClauseNode::kInvalidTryIndex); 103 CatchClauseNode::kInvalidTryIndex);
102 } 104 }
103 105
104 106
105 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 107 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
106 const intptr_t kNumInputs = 0; 108 const intptr_t kNumInputs = 0;
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 LocationSummary::kNoCall, 439 LocationSummary::kNoCall,
438 contains_branch); 440 contains_branch);
439 summary->set_in(0, Location::RequiresRegister()); 441 summary->set_in(0, Location::RequiresRegister());
440 summary->set_in(1, Location::RequiresRegister()); 442 summary->set_in(1, Location::RequiresRegister());
441 if (!is_fused_with_branch()) { 443 if (!is_fused_with_branch()) {
442 summary->set_out(Location::RequiresRegister()); 444 summary->set_out(Location::RequiresRegister());
443 } 445 }
444 summary->set_temp(0, Location::RequiresRegister()); 446 summary->set_temp(0, Location::RequiresRegister());
445 return summary; 447 return summary;
446 } 448 }
449 ASSERT(!is_fused_with_branch());
447 ASSERT(operands_class_id() == kObject); 450 ASSERT(operands_class_id() == kObject);
448 return MakeCallSummary(); 451 return MakeCallSummary();
449 } 452 }
450 453
451 454
452 static Condition TokenKindToSmiCondition(Token::Kind kind) { 455 static Condition TokenKindToSmiCondition(Token::Kind kind) {
453 switch (kind) { 456 switch (kind) {
454 case Token::kEQ: return EQUAL; 457 case Token::kEQ: return EQUAL;
455 case Token::kNE: return NOT_EQUAL; 458 case Token::kNE: return NOT_EQUAL;
456 case Token::kLT: return LESS; 459 case Token::kLT: return LESS;
(...skipping 24 matching lines...) Expand all
481 __ j(NOT_ZERO, deopt); 484 __ j(NOT_ZERO, deopt);
482 485
483 Condition true_condition = TokenKindToSmiCondition(comp->kind()); 486 Condition true_condition = TokenKindToSmiCondition(comp->kind());
484 __ cmpl(left, right); 487 __ cmpl(left, right);
485 488
486 if (comp->is_fused_with_branch()) { 489 if (comp->is_fused_with_branch()) {
487 comp->fused_with_branch()->EmitBranchOnCondition(compiler, true_condition); 490 comp->fused_with_branch()->EmitBranchOnCondition(compiler, true_condition);
488 } else { 491 } else {
489 Register result = comp->locs()->out().reg(); 492 Register result = comp->locs()->out().reg();
490 Label done, is_true; 493 Label done, is_true;
491
492 __ j(true_condition, &is_true); 494 __ j(true_condition, &is_true);
493 __ LoadObject(result, compiler->bool_false()); 495 __ LoadObject(result, compiler->bool_false());
494 __ jmp(&done); 496 __ jmp(&done);
495 __ Bind(&is_true); 497 __ Bind(&is_true);
496 __ LoadObject(result, compiler->bool_true()); 498 __ LoadObject(result, compiler->bool_true());
497 __ Bind(&done); 499 __ Bind(&done);
498 } 500 }
499 } 501 }
500 502
501 503
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 try_index(), 576 try_index(),
575 function_name, 577 function_name,
576 kNumArguments, 578 kNumArguments,
577 Array::ZoneHandle(), // No optional arguments. 579 Array::ZoneHandle(), // No optional arguments.
578 kNumArgsChecked); 580 kNumArgsChecked);
579 ASSERT(locs()->out().reg() == EAX); 581 ASSERT(locs()->out().reg() == EAX);
580 } 582 }
581 583
582 584
583 LocationSummary* NativeCallComp::MakeLocationSummary() const { 585 LocationSummary* NativeCallComp::MakeLocationSummary() const {
584 LocationSummary* locs = new LocationSummary(0, 3, LocationSummary::kCall); 586 const intptr_t kNumInputs = 0;
587 const intptr_t kNumTemps = 3;
588 LocationSummary* locs = new LocationSummary(kNumInputs,
589 kNumTemps,
590 LocationSummary::kCall);
585 locs->set_temp(0, Location::RegisterLocation(EAX)); 591 locs->set_temp(0, Location::RegisterLocation(EAX));
586 locs->set_temp(1, Location::RegisterLocation(ECX)); 592 locs->set_temp(1, Location::RegisterLocation(ECX));
587 locs->set_temp(2, Location::RegisterLocation(EDX)); 593 locs->set_temp(2, Location::RegisterLocation(EDX));
588 locs->set_out(Location::RequiresRegister()); 594 locs->set_out(Location::RequiresRegister());
589 return locs; 595 return locs;
590 } 596 }
591 597
592 598
593 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 599 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
594 ASSERT(locs()->temp(0).reg() == EAX); 600 ASSERT(locs()->temp(0).reg() == EAX);
595 ASSERT(locs()->temp(1).reg() == ECX); 601 ASSERT(locs()->temp(1).reg() == ECX);
596 ASSERT(locs()->temp(2).reg() == EDX); 602 ASSERT(locs()->temp(2).reg() == EDX);
597 Register result = locs()->out().reg(); 603 Register result = locs()->out().reg();
604
598 // Push the result place holder initialized to NULL. 605 // Push the result place holder initialized to NULL.
599 __ PushObject(Object::ZoneHandle()); 606 __ PushObject(Object::ZoneHandle());
600 // Pass a pointer to the first argument in EAX. 607 // Pass a pointer to the first argument in EAX.
601 intptr_t arg_count = argument_count(); 608 intptr_t arg_count = argument_count();
602 if (is_native_instance_closure()) { 609 if (is_native_instance_closure()) {
603 arg_count += 1; 610 arg_count += 1;
604 } 611 }
605 if (!has_optional_parameters() && !is_native_instance_closure()) { 612 if (!has_optional_parameters() && !is_native_instance_closure()) {
606 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); 613 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize));
607 } else { 614 } else {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 681 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
675 if (receiver_type() == kIllegalObjectKind) { 682 if (receiver_type() == kIllegalObjectKind) {
676 if (HasICData()) { 683 if (HasICData()) {
677 EmitLoadIndexedPolymorphic(compiler, this); 684 EmitLoadIndexedPolymorphic(compiler, this);
678 } else { 685 } else {
679 compiler->EmitLoadIndexedGeneric(this); 686 compiler->EmitLoadIndexedGeneric(this);
680 } 687 }
681 ASSERT(locs()->out().reg() == EAX); 688 ASSERT(locs()->out().reg() == EAX);
682 return; 689 return;
683 } 690 }
691
684 Register receiver = locs()->in(0).reg(); 692 Register receiver = locs()->in(0).reg();
685 Register index = locs()->in(1).reg(); 693 Register index = locs()->in(1).reg();
686 Register result = locs()->out().reg(); 694 Register result = locs()->out().reg();
687 Register temp = locs()->temp(0).reg(); 695 Register temp = locs()->temp(0).reg();
688 696
689 const Class& receiver_class =
690 Class::ZoneHandle(Isolate::Current()->class_table()->At(
691 receiver_type()));
692
693 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? 697 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ?
694 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 698 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
695 699
696 Label* deopt = compiler->AddDeoptStub(cid(), 700 Label* deopt = compiler->AddDeoptStub(cid(),
697 token_index(), 701 token_index(),
698 try_index(), 702 try_index(),
699 deopt_reason, 703 deopt_reason,
700 receiver, 704 receiver,
701 index); 705 index);
702 706
703 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 707 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
704 __ j(ZERO, deopt); 708 __ j(ZERO, deopt);
705 __ CompareClassId(receiver, receiver_class.id(), temp); 709 __ CompareClassId(receiver, receiver_type(), temp);
706 __ j(NOT_EQUAL, deopt); 710 __ j(NOT_EQUAL, deopt);
707 711
708 __ testl(index, Immediate(kSmiTagMask)); 712 __ testl(index, Immediate(kSmiTagMask));
709 __ j(NOT_ZERO, deopt); 713 __ j(NOT_ZERO, deopt);
710 714
711 switch (receiver_type()) { 715 switch (receiver_type()) {
712 case kArray: 716 case kArray:
713 case kImmutableArray: 717 case kImmutableArray:
714 __ cmpl(index, FieldAddress(receiver, Array::length_offset())); 718 __ cmpl(index, FieldAddress(receiver, Array::length_offset()));
715 __ j(ABOVE_EQUAL, deopt); 719 __ j(ABOVE_EQUAL, deopt);
(...skipping 17 matching lines...) Expand all
733 737
734 default: 738 default:
735 UNREACHABLE(); 739 UNREACHABLE();
736 break; 740 break;
737 } 741 }
738 } 742 }
739 743
740 744
741 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { 745 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
742 const intptr_t kNumInputs = 3; 746 const intptr_t kNumInputs = 3;
743 if (receiver_type() == kGrowableObjectArray || receiver_type() == kArray) { 747 if ((receiver_type() == kGrowableObjectArray) ||
748 (receiver_type() == kArray)) {
744 const intptr_t kNumTemps = 1; 749 const intptr_t kNumTemps = 1;
745 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 750 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
746 locs->set_in(0, Location::RequiresRegister()); 751 locs->set_in(0, Location::RequiresRegister());
747 locs->set_in(1, Location::RequiresRegister()); 752 locs->set_in(1, Location::RequiresRegister());
748 locs->set_in(2, Location::RequiresRegister()); 753 locs->set_in(2, Location::RequiresRegister());
749 locs->set_temp(0, Location::RequiresRegister()); 754 locs->set_temp(0, Location::RequiresRegister());
750 locs->set_out(Location::NoLocation()); 755 locs->set_out(Location::NoLocation());
751 return locs; 756 return locs;
752 } else { 757 } else {
753 ASSERT(receiver_type() == kIllegalObjectKind); 758 ASSERT(receiver_type() == kIllegalObjectKind);
(...skipping 12 matching lines...) Expand all
766 comp->token_index(), 771 comp->token_index(),
767 comp->try_index()); 772 comp->try_index());
768 773
769 const intptr_t kNumArguments = 3; 774 const intptr_t kNumArguments = 3;
770 const intptr_t kNumArgsChecked = 1; // Type-feedback. 775 const intptr_t kNumArgsChecked = 1; // Type-feedback.
771 compiler->GenerateInstanceCall(comp->cid(), 776 compiler->GenerateInstanceCall(comp->cid(),
772 comp->token_index(), 777 comp->token_index(),
773 comp->try_index(), 778 comp->try_index(),
774 function_name, 779 function_name,
775 kNumArguments, 780 kNumArguments,
776 Array::ZoneHandle(), // No named args. 781 Array::ZoneHandle(), // No named arguments.
777 kNumArgsChecked); 782 kNumArgsChecked);
778 } 783 }
779 784
780 785
781 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 786 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
782 StoreIndexedComp* comp) { 787 StoreIndexedComp* comp) {
783 Label* deopt = compiler->AddDeoptStub(comp->cid(), 788 Label* deopt = compiler->AddDeoptStub(comp->cid(),
784 comp->token_index(), 789 comp->token_index(),
785 comp->try_index(), 790 comp->try_index(),
786 kDeoptStoreIndexedPolymorphic); 791 kDeoptStoreIndexedPolymorphic);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 locs->set_in(0, Location::RegisterLocation(ECX)); 1011 locs->set_in(0, Location::RegisterLocation(ECX));
1007 locs->set_temp(0, Location::RegisterLocation(EDX)); 1012 locs->set_temp(0, Location::RegisterLocation(EDX));
1008 locs->set_out(Location::RegisterLocation(EAX)); 1013 locs->set_out(Location::RegisterLocation(EAX));
1009 return locs; 1014 return locs;
1010 } 1015 }
1011 1016
1012 1017
1013 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1018 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1014 Register temp_reg = locs()->temp(0).reg(); 1019 Register temp_reg = locs()->temp(0).reg();
1015 Register result_reg = locs()->out().reg(); 1020 Register result_reg = locs()->out().reg();
1021
1022 // Allocate the array. EDX = length, ECX = element type.
1016 ASSERT(temp_reg == EDX); 1023 ASSERT(temp_reg == EDX);
1017 ASSERT(locs()->in(0).reg() == ECX); 1024 ASSERT(locs()->in(0).reg() == ECX);
1018 // 1. Allocate the array. EDX = length, ECX = element type. 1025 __ movl(temp_reg, Immediate(Smi::RawValue(ElementCount())));
1019 __ movl(EDX, Immediate(Smi::RawValue(ElementCount())));
1020 compiler->GenerateCall(token_index(), 1026 compiler->GenerateCall(token_index(),
1021 try_index(), 1027 try_index(),
1022 &StubCode::AllocateArrayLabel(), 1028 &StubCode::AllocateArrayLabel(),
1023 PcDescriptors::kOther); 1029 PcDescriptors::kOther);
1024 ASSERT(result_reg == EAX); 1030 ASSERT(result_reg == EAX);
1031
1025 // Pop the element values from the stack into the array. 1032 // Pop the element values from the stack into the array.
1026 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); 1033 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset()));
1027 for (int i = ElementCount() - 1; i >= 0; --i) { 1034 for (int i = ElementCount() - 1; i >= 0; --i) {
1028 ASSERT(ElementAt(i)->IsUse()); 1035 ASSERT(ElementAt(i)->IsUse());
1029 __ popl(Address(temp_reg, i * kWordSize)); 1036 __ popl(Address(temp_reg, i * kWordSize));
1030 } 1037 }
1031 } 1038 }
1032 1039
1033 1040
1034 LocationSummary* 1041 LocationSummary*
1035 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { 1042 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const {
1036 return LocationSummary::Make(2, 1043 return LocationSummary::Make(2,
1037 Location::RequiresRegister(), 1044 Location::RequiresRegister(),
1038 LocationSummary::kCall); 1045 LocationSummary::kCall);
1039 } 1046 }
1040 1047
1041 1048
1042 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 1049 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
1043 FlowGraphCompiler* compiler) { 1050 FlowGraphCompiler* compiler) {
1044 const Class& cls = Class::ZoneHandle(constructor().owner()); 1051 const Class& cls = Class::ZoneHandle(constructor().owner());
1045 Register type_arguments = locs()->in(0).reg(); 1052 Register type_arguments = locs()->in(0).reg();
1046 Register instantiator_type_arguments = locs()->in(1).reg(); 1053 Register instantiator_type_arguments = locs()->in(1).reg();
1047 Register result = locs()->out().reg(); 1054 Register result = locs()->out().reg();
1048 1055
1056 // Push the result place holder initialized to NULL.
1049 __ PushObject(Object::ZoneHandle()); 1057 __ PushObject(Object::ZoneHandle());
1050 __ pushl(Immediate(Smi::RawValue(token_index()))); 1058 __ pushl(Immediate(Smi::RawValue(token_index())));
1051 __ PushObject(cls); 1059 __ PushObject(cls);
1052 __ pushl(type_arguments); 1060 __ pushl(type_arguments);
1053 __ pushl(instantiator_type_arguments); 1061 __ pushl(instantiator_type_arguments);
1054 compiler->GenerateCallRuntime(cid(), 1062 compiler->GenerateCallRuntime(cid(),
1055 token_index(), 1063 token_index(),
1056 try_index(), 1064 try_index(),
1057 kAllocateObjectWithBoundsCheckRuntimeEntry); 1065 kAllocateObjectWithBoundsCheckRuntimeEntry);
1058 // Pop instantiator type arguments, type arguments, class, and 1066 // Pop instantiator type arguments, type arguments, class, and
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 if (type_arguments().IsRawInstantiatedRaw(len)) { 1125 if (type_arguments().IsRawInstantiatedRaw(len)) {
1118 const Immediate raw_null = 1126 const Immediate raw_null =
1119 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1127 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1120 __ cmpl(instantiator_reg, raw_null); 1128 __ cmpl(instantiator_reg, raw_null);
1121 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1129 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1122 } 1130 }
1123 // Instantiate non-null type arguments. 1131 // Instantiate non-null type arguments.
1124 if (type_arguments().IsUninstantiatedIdentity()) { 1132 if (type_arguments().IsUninstantiatedIdentity()) {
1125 // Check if the instantiator type argument vector is a TypeArguments of a 1133 // Check if the instantiator type argument vector is a TypeArguments of a
1126 // matching length and, if so, use it as the instantiated type_arguments. 1134 // matching length and, if so, use it as the instantiated type_arguments.
1127 // No need to check instantiator for null (again), because a null instance 1135 // No need to check the instantiator ('instantiator_reg') for null here,
1128 // will have the wrong class (Null instead of TypeArguments). 1136 // because a null instantiator will have the wrong class (Null instead of
1137 // TypeArguments).
1129 Label type_arguments_uninstantiated; 1138 Label type_arguments_uninstantiated;
1130 __ CompareClassId(instantiator_reg, kTypeArguments, temp); 1139 __ CompareClassId(instantiator_reg, kTypeArguments, temp);
1131 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1140 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1132 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1141 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1133 Immediate(Smi::RawValue(len))); 1142 Immediate(Smi::RawValue(len)));
1134 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1143 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1135 __ Bind(&type_arguments_uninstantiated); 1144 __ Bind(&type_arguments_uninstantiated);
1136 } 1145 }
1137 // A runtime call to instantiate the type arguments is required. 1146 // A runtime call to instantiate the type arguments is required.
1138 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1147 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1139 __ PushObject(type_arguments()); 1148 __ PushObject(type_arguments());
1140 __ pushl(instantiator_reg); // Push instantiator type arguments. 1149 __ pushl(instantiator_reg); // Push instantiator type arguments.
1141 compiler->GenerateCallRuntime(cid(), 1150 compiler->GenerateCallRuntime(cid(),
1142 token_index(), 1151 token_index(),
1143 try_index(), 1152 try_index(),
1144 kInstantiateTypeArgumentsRuntimeEntry); 1153 kInstantiateTypeArgumentsRuntimeEntry);
1145 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1154 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1146 __ popl(result_reg); // Pop instantiated type arguments. 1155 __ popl(result_reg); // Pop instantiated type arguments.
1147 __ Bind(&type_arguments_instantiated); 1156 __ Bind(&type_arguments_instantiated);
1148 ASSERT(instantiator_reg == result_reg); 1157 ASSERT(instantiator_reg == result_reg);
1158 // 'result_reg': Instantiated type arguments.
1149 } 1159 }
1150 1160
1151 1161
1152 LocationSummary* 1162 LocationSummary*
1153 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { 1163 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
1154 const intptr_t kNumInputs = 1; 1164 const intptr_t kNumInputs = 1;
1155 const intptr_t kNumTemps = 1; 1165 const intptr_t kNumTemps = 1;
1156 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1166 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
1157 locs->set_in(0, Location::RequiresRegister()); 1167 locs->set_in(0, Location::RequiresRegister());
1158 locs->set_out(Location::SameAsFirstInput()); 1168 locs->set_out(Location::SameAsFirstInput());
1159 locs->set_temp(0, Location::RequiresRegister()); 1169 locs->set_temp(0, Location::RequiresRegister());
1160 return locs; 1170 return locs;
1161 } 1171 }
1162 1172
1163 1173
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 // In the non-factory case, we rely on the allocation stub to 1210 // In the non-factory case, we rely on the allocation stub to
1201 // instantiate the type arguments. 1211 // instantiate the type arguments.
1202 __ LoadObject(result_reg, type_arguments()); 1212 __ LoadObject(result_reg, type_arguments());
1203 // result_reg: uninstantiated type arguments. 1213 // result_reg: uninstantiated type arguments.
1204 __ Bind(&type_arguments_instantiated); 1214 __ Bind(&type_arguments_instantiated);
1205 // result_reg: uninstantiated or instantiated type arguments. 1215 // result_reg: uninstantiated or instantiated type arguments.
1206 } 1216 }
1207 1217
1208 1218
1209 LocationSummary* 1219 LocationSummary*
1210 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { 1220 ExtractConstructorInstantiatorComp::MakeLocationSummary() const {
1211 const intptr_t kNumInputs = 1; 1221 const intptr_t kNumInputs = 1;
1212 const intptr_t kNumTemps = 1; 1222 const intptr_t kNumTemps = 1;
1213 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1223 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
1214 locs->set_in(0, Location::RequiresRegister()); 1224 locs->set_in(0, Location::RequiresRegister());
1215 locs->set_out(Location::SameAsFirstInput()); 1225 locs->set_out(Location::SameAsFirstInput());
1216 locs->set_temp(0, Location::RequiresRegister()); 1226 locs->set_temp(0, Location::RequiresRegister());
1217 return locs; 1227 return locs;
1218 } 1228 }
1219 1229
1220 1230
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
1812 Register value = locs()->in(0).reg(); 1822 Register value = locs()->in(0).reg();
1813 Register result = locs()->out().reg(); 1823 Register result = locs()->out().reg();
1814 ASSERT(value == result); 1824 ASSERT(value == result);
1815 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1825 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1816 instance_call()->token_index(), 1826 instance_call()->token_index(),
1817 instance_call()->try_index(), 1827 instance_call()->try_index(),
1818 kDeoptUnaryOp, 1828 kDeoptUnaryOp,
1819 value); 1829 value);
1820 if (test_class_id == kDouble) { 1830 if (test_class_id == kDouble) {
1821 Register temp = locs()->temp(0).reg(); 1831 Register temp = locs()->temp(0).reg();
1822 ASSERT(result != temp);
1823 __ testl(value, Immediate(kSmiTagMask)); 1832 __ testl(value, Immediate(kSmiTagMask));
1824 __ j(ZERO, deopt); // Smi. 1833 __ j(ZERO, deopt); // Smi.
1825 __ CompareClassId(value, kDouble, temp); 1834 __ CompareClassId(value, kDouble, temp);
1826 __ j(NOT_EQUAL, deopt); 1835 __ j(NOT_EQUAL, deopt);
1827 // Allocate result object. 1836 // Allocate result object.
1828 const Class& double_class = compiler->double_class(); 1837 const Class& double_class = compiler->double_class();
1829 const Code& stub = 1838 const Code& stub =
1830 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1839 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1831 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1840 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1832 __ pushl(value); 1841 __ pushl(value);
1833 compiler->GenerateCall(instance_call()->token_index(), 1842 compiler->GenerateCall(instance_call()->token_index(),
1834 instance_call()->try_index(), 1843 instance_call()->try_index(),
1835 &label, 1844 &label,
1836 PcDescriptors::kOther); 1845 PcDescriptors::kOther);
1837 // Result is in EAX. 1846 // Result is in EAX.
1847 ASSERT(result != temp);
1838 __ movl(result, EAX); 1848 __ movl(result, EAX);
1839 __ popl(temp); 1849 __ popl(temp);
1840 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1850 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1841 __ DoubleNegate(XMM0); 1851 __ DoubleNegate(XMM0);
1842 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1852 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1843 } else { 1853 } else {
1844 UNREACHABLE(); 1854 UNREACHABLE();
1845 } 1855 }
1846 } 1856 }
1847 1857
1848 1858
1849 LocationSummary* ToDoubleComp::MakeLocationSummary() const { 1859 LocationSummary* ToDoubleComp::MakeLocationSummary() const {
1850 const intptr_t kNumInputs = 1; 1860 const intptr_t kNumInputs = 1;
1851 if (from() == kDouble) { 1861 if (from() == kDouble) {
1852 const intptr_t kNumTemps = 1; 1862 const intptr_t kNumTemps = 1;
1853 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1863 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
1854 locs->set_in(0, Location::RequiresRegister()); 1864 locs->set_in(0, Location::RequiresRegister());
1855 locs->set_temp(0, Location::RequiresRegister()); 1865 locs->set_temp(0, Location::RequiresRegister());
1856 locs->set_out(Location::SameAsFirstInput()); 1866 locs->set_out(Location::SameAsFirstInput());
1857 locs->set_temp(0, Location::RequiresRegister()); 1867 locs->set_temp(0, Location::RequiresRegister());
1858 return locs; 1868 return locs;
1859 } else { 1869 } else {
1860 ASSERT(from() == kSmi); 1870 ASSERT(from() == kSmi);
1861 return MakeCallSummary(); // Calls a stub to allocate result. 1871 return MakeCallSummary(); // Calls a stub to allocate result.
1862 } 1872 }
1863 } 1873 }
1864 1874
1865 1875
1866 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1876 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1877 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX;
1867 Register result = locs()->out().reg(); 1878 Register result = locs()->out().reg();
1868 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX;
1869 1879
1870 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1880 const DeoptReasonId deopt_reason = (from() == kDouble) ?
1871 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1881 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1872 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1882 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1873 instance_call()->token_index(), 1883 instance_call()->token_index(),
1874 instance_call()->try_index(), 1884 instance_call()->try_index(),
1875 deopt_reason, 1885 deopt_reason,
1876 value); 1886 value);
1877 1887
1878 if (from() == kDouble) { 1888 if (from() == kDouble) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 instance_call()->argument_names()); 1966 instance_call()->argument_names());
1957 } 1967 }
1958 __ Bind(&done); 1968 __ Bind(&done);
1959 } 1969 }
1960 1970
1961 } // namespace dart 1971 } // namespace dart
1962 1972
1963 #undef __ 1973 #undef __
1964 1974
1965 #endif // defined TARGET_ARCH_X64 1975 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698