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

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

Issue 10917085: Revert "Remove classes Computation and BindInstr." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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_test.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" 14 #include "vm/parser.h"
15 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
16 #include "vm/symbols.h" 16 #include "vm/symbols.h"
17 17
18 #define __ compiler->assembler()-> 18 #define __ compiler->assembler()->
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DECLARE_FLAG(int, optimization_counter_threshold); 22 DECLARE_FLAG(int, optimization_counter_threshold);
23 DECLARE_FLAG(bool, trace_functions); 23 DECLARE_FLAG(bool, trace_functions);
24 24
25 // Generic summary for call instructions that have all arguments pushed 25 // Generic summary for call instructions that have all arguments pushed
26 // on the stack and return the result in a fixed register EAX. 26 // on the stack and return the result in a fixed register EAX.
27 LocationSummary* Instruction::MakeCallSummary() { 27 LocationSummary* Computation::MakeCallSummary() {
28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 28 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
29 result->set_out(Location::RegisterLocation(EAX)); 29 result->set_out(Location::RegisterLocation(EAX));
30 return result; 30 return result;
31 } 31 }
32 32
33 33
34 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
35 computation()->EmitNativeCode(compiler);
36 if (is_used() && !compiler->is_optimizing()) {
37 __ pushl(locs()->out().reg());
38 }
39 }
40
41
34 LocationSummary* ReturnInstr::MakeLocationSummary() const { 42 LocationSummary* ReturnInstr::MakeLocationSummary() const {
35 const intptr_t kNumInputs = 1; 43 const intptr_t kNumInputs = 1;
36 const intptr_t kNumTemps = 1; 44 const intptr_t kNumTemps = 1;
37 LocationSummary* locs = 45 LocationSummary* locs =
38 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 46 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
39 locs->set_in(0, Location::RegisterLocation(EAX)); 47 locs->set_in(0, Location::RegisterLocation(EAX));
40 locs->set_temp(0, Location::RequiresRegister()); 48 locs->set_temp(0, Location::RequiresRegister());
41 return locs; 49 return locs;
42 } 50 }
43 51
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 111
104 // Generate 1 byte NOP so that the debugger can patch the 112 // Generate 1 byte NOP so that the debugger can patch the
105 // return pattern with a call to the debug stub. 113 // return pattern with a call to the debug stub.
106 __ nop(1); 114 __ nop(1);
107 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 115 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
108 deopt_id(), 116 deopt_id(),
109 token_pos()); 117 token_pos());
110 } 118 }
111 119
112 120
113 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { 121 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
114 const intptr_t kNumInputs = 0; 122 const intptr_t kNumInputs = 0;
115 const intptr_t kNumTemps = 1; 123 const intptr_t kNumTemps = 1;
116 LocationSummary* result = 124 LocationSummary* result =
117 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 125 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
118 result->set_out(Location::RegisterLocation(EAX)); 126 result->set_out(Location::RegisterLocation(EAX));
119 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. 127 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
120 return result; 128 return result;
121 } 129 }
122 130
123 131
124 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { 132 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
125 return LocationSummary::Make(0, 133 return LocationSummary::Make(0,
126 Location::RequiresRegister(), 134 Location::RequiresRegister(),
127 LocationSummary::kNoCall); 135 LocationSummary::kNoCall);
128 } 136 }
129 137
130 138
131 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 139 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
132 Register result = locs()->out().reg(); 140 Register result = locs()->out().reg();
133 __ movl(result, Address(EBP, local().index() * kWordSize)); 141 __ movl(result, Address(EBP, local().index() * kWordSize));
134 } 142 }
135 143
136 144
137 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { 145 LocationSummary* StoreLocalComp::MakeLocationSummary() const {
138 return LocationSummary::Make(1, 146 return LocationSummary::Make(1,
139 Location::SameAsFirstInput(), 147 Location::SameAsFirstInput(),
140 LocationSummary::kNoCall); 148 LocationSummary::kNoCall);
141 } 149 }
142 150
143 151
144 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 152 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) {
145 Register value = locs()->in(0).reg(); 153 Register value = locs()->in(0).reg();
146 Register result = locs()->out().reg(); 154 Register result = locs()->out().reg();
147 ASSERT(result == value); // Assert that register assignment is correct. 155 ASSERT(result == value); // Assert that register assignment is correct.
148 __ movl(Address(EBP, local().index() * kWordSize), value); 156 __ movl(Address(EBP, local().index() * kWordSize), value);
149 } 157 }
150 158
151 159
152 LocationSummary* ConstantInstr::MakeLocationSummary() const { 160 LocationSummary* ConstantComp::MakeLocationSummary() const {
153 return LocationSummary::Make(0, 161 return LocationSummary::Make(0,
154 Location::RequiresRegister(), 162 Location::RequiresRegister(),
155 LocationSummary::kNoCall); 163 LocationSummary::kNoCall);
156 } 164 }
157 165
158 166
159 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 167 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) {
160 // The register allocator drops constant definitions that have no uses. 168 // Register allocator drops constant definitions that have no uses.
161 if (!locs()->out().IsInvalid()) { 169 if (!locs()->out().IsInvalid()) {
162 Register result = locs()->out().reg(); 170 Register result = locs()->out().reg();
163 __ LoadObject(result, value()); 171 __ LoadObject(result, value());
164 } 172 }
165 } 173 }
166 174
167 175
168 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { 176 LocationSummary* AssertAssignableComp::MakeLocationSummary() const {
169 const intptr_t kNumInputs = 3; 177 const intptr_t kNumInputs = 3;
170 const intptr_t kNumTemps = 0; 178 const intptr_t kNumTemps = 0;
171 LocationSummary* summary = 179 LocationSummary* summary =
172 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 180 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
173 summary->set_in(0, Location::RegisterLocation(EAX)); // Value. 181 summary->set_in(0, Location::RegisterLocation(EAX)); // Value.
174 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator. 182 summary->set_in(1, Location::RegisterLocation(ECX)); // Instantiator.
175 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments. 183 summary->set_in(2, Location::RegisterLocation(EDX)); // Type arguments.
176 summary->set_out(Location::RegisterLocation(EAX)); 184 summary->set_out(Location::RegisterLocation(EAX));
177 return summary; 185 return summary;
178 } 186 }
179 187
180 188
181 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 189 LocationSummary* AssertBooleanComp::MakeLocationSummary() const {
182 const intptr_t kNumInputs = 1; 190 const intptr_t kNumInputs = 1;
183 const intptr_t kNumTemps = 0; 191 const intptr_t kNumTemps = 0;
184 LocationSummary* locs = 192 LocationSummary* locs =
185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 193 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
186 locs->set_in(0, Location::RegisterLocation(EAX)); 194 locs->set_in(0, Location::RegisterLocation(EAX));
187 locs->set_out(Location::RegisterLocation(EAX)); 195 locs->set_out(Location::RegisterLocation(EAX));
188 return locs; 196 return locs;
189 } 197 }
190 198
191 199
192 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 200 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) {
193 Register obj = locs()->in(0).reg(); 201 Register obj = locs()->in(0).reg();
194 Register result = locs()->out().reg(); 202 Register result = locs()->out().reg();
195 203
196 if (!is_eliminated()) { 204 if (!is_eliminated()) {
197 // Check that the type of the value is allowed in conditional context. 205 // Check that the type of the value is allowed in conditional context.
198 // Call the runtime if the object is not bool::true or bool::false. 206 // Call the runtime if the object is not bool::true or bool::false.
199 Label done; 207 Label done;
200 __ CompareObject(obj, compiler->bool_true()); 208 __ CompareObject(obj, compiler->bool_true());
201 __ j(EQUAL, &done, Assembler::kNearJump); 209 __ j(EQUAL, &done, Assembler::kNearJump);
202 __ CompareObject(obj, compiler->bool_false()); 210 __ CompareObject(obj, compiler->bool_false());
203 __ j(EQUAL, &done, Assembler::kNearJump); 211 __ j(EQUAL, &done, Assembler::kNearJump);
204 212
205 __ pushl(obj); // Push the source object. 213 __ pushl(obj); // Push the source object.
206 compiler->GenerateCallRuntime(token_pos(), 214 compiler->GenerateCallRuntime(token_pos(),
207 kConditionTypeErrorRuntimeEntry, 215 kConditionTypeErrorRuntimeEntry,
208 locs()); 216 locs());
209 // We should never return here. 217 // We should never return here.
210 __ int3(); 218 __ int3();
211 __ Bind(&done); 219 __ Bind(&done);
212 } 220 }
213 ASSERT(obj == result); 221 ASSERT(obj == result);
214 } 222 }
215 223
216 224
217 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { 225 LocationSummary* ArgumentDefinitionTestComp::MakeLocationSummary() const {
218 const intptr_t kNumInputs = 1; 226 const intptr_t kNumInputs = 1;
219 const intptr_t kNumTemps = 0; 227 const intptr_t kNumTemps = 0;
220 LocationSummary* locs = 228 LocationSummary* locs =
221 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
222 locs->set_in(0, Location::RegisterLocation(EAX)); 230 locs->set_in(0, Location::RegisterLocation(EAX));
223 locs->set_out(Location::RegisterLocation(EAX)); 231 locs->set_out(Location::RegisterLocation(EAX));
224 return locs; 232 return locs;
225 } 233 }
226 234
227 235
228 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 236 void ArgumentDefinitionTestComp::EmitNativeCode(FlowGraphCompiler* compiler) {
229 Register saved_args_desc = locs()->in(0).reg(); 237 Register saved_args_desc = locs()->in(0).reg();
230 Register result = locs()->out().reg(); 238 Register result = locs()->out().reg();
231 239
232 // Push the result place holder initialized to NULL. 240 // Push the result place holder initialized to NULL.
233 __ PushObject(Object::ZoneHandle()); 241 __ PushObject(Object::ZoneHandle());
234 __ pushl(Immediate(Smi::RawValue(formal_parameter_index()))); 242 __ pushl(Immediate(Smi::RawValue(formal_parameter_index())));
235 __ PushObject(formal_parameter_name()); 243 __ PushObject(formal_parameter_name());
236 __ pushl(saved_args_desc); 244 __ pushl(saved_args_desc);
237 compiler->GenerateCallRuntime(token_pos(), 245 compiler->GenerateCallRuntime(token_pos(),
238 kArgumentDefinitionTestRuntimeEntry, 246 kArgumentDefinitionTestRuntimeEntry,
(...skipping 11 matching lines...) Expand all
250 case Token::kGT: return GREATER; 258 case Token::kGT: return GREATER;
251 case Token::kLTE: return LESS_EQUAL; 259 case Token::kLTE: return LESS_EQUAL;
252 case Token::kGTE: return GREATER_EQUAL; 260 case Token::kGTE: return GREATER_EQUAL;
253 default: 261 default:
254 UNREACHABLE(); 262 UNREACHABLE();
255 return OVERFLOW; 263 return OVERFLOW;
256 } 264 }
257 } 265 }
258 266
259 267
260 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { 268 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
261 const intptr_t kNumInputs = 2; 269 const intptr_t kNumInputs = 2;
262 const bool is_checked_strict_equal = 270 const bool is_checked_strict_equal =
263 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 271 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
264 if (receiver_class_id() == kDoubleCid) { 272 if (receiver_class_id() == kDoubleCid) {
265 const intptr_t kNumTemps = 0; 273 const intptr_t kNumTemps = 0;
266 LocationSummary* locs = 274 LocationSummary* locs =
267 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 275 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
268 locs->set_in(0, Location::RequiresXmmRegister()); 276 locs->set_in(0, Location::RequiresXmmRegister());
269 locs->set_in(1, Location::RequiresXmmRegister()); 277 locs->set_in(1, Location::RequiresXmmRegister());
270 locs->set_out(Location::RequiresRegister()); 278 locs->set_out(Location::RequiresRegister());
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 if (branch != NULL) { 610 if (branch != NULL) {
603 compiler->EmitDoubleCompareBranch( 611 compiler->EmitDoubleCompareBranch(
604 true_condition, left, right, branch); 612 true_condition, left, right, branch);
605 } else { 613 } else {
606 compiler->EmitDoubleCompareBool( 614 compiler->EmitDoubleCompareBool(
607 true_condition, left, right, locs.out().reg()); 615 true_condition, left, right, locs.out().reg());
608 } 616 }
609 } 617 }
610 618
611 619
612 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 620 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
613 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 621 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
614 BranchInstr* kNoBranch = NULL; 622 BranchInstr* kNoBranch = NULL;
615 if (receiver_class_id() == kSmiCid) { 623 if (receiver_class_id() == kSmiCid) {
616 // Deoptimizes if both arguments not Smi. 624 // Deoptimizes if both arguments not Smi.
617 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); 625 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
618 return; 626 return;
619 } 627 }
620 if (receiver_class_id() == kDoubleCid) { 628 if (receiver_class_id() == kDoubleCid) {
621 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); 629 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
622 return; 630 return;
(...skipping 12 matching lines...) Expand all
635 } 643 }
636 Register left = locs()->in(0).reg(); 644 Register left = locs()->in(0).reg();
637 Register right = locs()->in(1).reg(); 645 Register right = locs()->in(1).reg();
638 __ pushl(left); 646 __ pushl(left);
639 __ pushl(right); 647 __ pushl(right);
640 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs()); 648 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs());
641 ASSERT(locs()->out().reg() == EAX); 649 ASSERT(locs()->out().reg() == EAX);
642 } 650 }
643 651
644 652
645 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 653 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
646 BranchInstr* branch) { 654 BranchInstr* branch) {
647 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 655 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
648 if (receiver_class_id() == kSmiCid) { 656 if (receiver_class_id() == kSmiCid) {
649 // Deoptimizes if both arguments not Smi. 657 // Deoptimizes if both arguments not Smi.
650 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 658 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
651 return; 659 return;
652 } 660 }
653 if (receiver_class_id() == kDoubleCid) { 661 if (receiver_class_id() == kDoubleCid) {
654 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 662 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
655 return; 663 return;
656 } 664 }
(...skipping 17 matching lines...) Expand all
674 deopt_id(), 682 deopt_id(),
675 token_pos(), 683 token_pos(),
676 Token::kEQ, // kNE reverse occurs at branch. 684 Token::kEQ, // kNE reverse occurs at branch.
677 locs()); 685 locs());
678 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 686 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
679 __ CompareObject(EAX, compiler->bool_true()); 687 __ CompareObject(EAX, compiler->bool_true());
680 branch->EmitBranchOnCondition(compiler, branch_condition); 688 branch->EmitBranchOnCondition(compiler, branch_condition);
681 } 689 }
682 690
683 691
684 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 692 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
685 const intptr_t kNumInputs = 2; 693 const intptr_t kNumInputs = 2;
686 if (operands_class_id() == kDoubleCid) { 694 if (operands_class_id() == kDoubleCid) {
687 const intptr_t kNumTemps = 0; 695 const intptr_t kNumTemps = 0;
688 LocationSummary* summary = 696 LocationSummary* summary =
689 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 697 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
690 summary->set_in(0, Location::RequiresXmmRegister()); 698 summary->set_in(0, Location::RequiresXmmRegister());
691 summary->set_in(1, Location::RequiresXmmRegister()); 699 summary->set_in(1, Location::RequiresXmmRegister());
692 summary->set_out(Location::RequiresRegister()); 700 summary->set_out(Location::RequiresRegister());
693 return summary; 701 return summary;
694 } else if (operands_class_id() == kSmiCid) { 702 } else if (operands_class_id() == kSmiCid) {
(...skipping 10 matching lines...) Expand all
705 LocationSummary* locs = 713 LocationSummary* locs =
706 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 714 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
707 // Pick arbitrary fixed input registers because this is a call. 715 // Pick arbitrary fixed input registers because this is a call.
708 locs->set_in(0, Location::RegisterLocation(EAX)); 716 locs->set_in(0, Location::RegisterLocation(EAX));
709 locs->set_in(1, Location::RegisterLocation(ECX)); 717 locs->set_in(1, Location::RegisterLocation(ECX));
710 locs->set_out(Location::RegisterLocation(EAX)); 718 locs->set_out(Location::RegisterLocation(EAX));
711 return locs; 719 return locs;
712 } 720 }
713 721
714 722
715 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 723 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
716 if (operands_class_id() == kSmiCid) { 724 if (operands_class_id() == kSmiCid) {
717 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); 725 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
718 return; 726 return;
719 } 727 }
720 if (operands_class_id() == kDoubleCid) { 728 if (operands_class_id() == kDoubleCid) {
721 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); 729 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
722 return; 730 return;
723 } 731 }
724 732
725 // Push arguments for the call. 733 // Push arguments for the call.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 compiler->GenerateInstanceCall(deopt_id(), 769 compiler->GenerateInstanceCall(deopt_id(),
762 token_pos(), 770 token_pos(),
763 function_name, 771 function_name,
764 kNumArguments, 772 kNumArguments,
765 Array::ZoneHandle(), // No optional arguments. 773 Array::ZoneHandle(), // No optional arguments.
766 kNumArgsChecked, 774 kNumArgsChecked,
767 locs()); 775 locs());
768 } 776 }
769 777
770 778
771 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 779 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
772 BranchInstr* branch) { 780 BranchInstr* branch) {
773 if (operands_class_id() == kSmiCid) { 781 if (operands_class_id() == kSmiCid) {
774 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 782 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
775 return; 783 return;
776 } 784 }
777 if (operands_class_id() == kDoubleCid) { 785 if (operands_class_id() == kDoubleCid) {
778 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 786 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
779 return; 787 return;
780 } 788 }
781 EmitNativeCode(compiler); 789 EmitNativeCode(compiler);
782 __ CompareObject(EAX, compiler->bool_true()); 790 __ CompareObject(EAX, compiler->bool_true());
783 branch->EmitBranchOnCondition(compiler, EQUAL); 791 branch->EmitBranchOnCondition(compiler, EQUAL);
784 } 792 }
785 793
786 794
787 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 795 LocationSummary* NativeCallComp::MakeLocationSummary() const {
788 const intptr_t kNumInputs = 0; 796 const intptr_t kNumInputs = 0;
789 const intptr_t kNumTemps = 3; 797 const intptr_t kNumTemps = 3;
790 LocationSummary* locs = 798 LocationSummary* locs =
791 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 799 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
792 locs->set_temp(0, Location::RegisterLocation(EAX)); 800 locs->set_temp(0, Location::RegisterLocation(EAX));
793 locs->set_temp(1, Location::RegisterLocation(ECX)); 801 locs->set_temp(1, Location::RegisterLocation(ECX));
794 locs->set_temp(2, Location::RegisterLocation(EDX)); 802 locs->set_temp(2, Location::RegisterLocation(EDX));
795 locs->set_out(Location::RegisterLocation(EAX)); 803 locs->set_out(Location::RegisterLocation(EAX));
796 return locs; 804 return locs;
797 } 805 }
798 806
799 807
800 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 808 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
801 ASSERT(locs()->temp(0).reg() == EAX); 809 ASSERT(locs()->temp(0).reg() == EAX);
802 ASSERT(locs()->temp(1).reg() == ECX); 810 ASSERT(locs()->temp(1).reg() == ECX);
803 ASSERT(locs()->temp(2).reg() == EDX); 811 ASSERT(locs()->temp(2).reg() == EDX);
804 Register result = locs()->out().reg(); 812 Register result = locs()->out().reg();
805 813
806 // Push the result place holder initialized to NULL. 814 // Push the result place holder initialized to NULL.
807 __ PushObject(Object::ZoneHandle()); 815 __ PushObject(Object::ZoneHandle());
808 // Pass a pointer to the first argument in EAX. 816 // Pass a pointer to the first argument in EAX.
809 intptr_t arg_count = argument_count(); 817 intptr_t arg_count = argument_count();
810 if (is_native_instance_closure()) { 818 if (is_native_instance_closure()) {
811 arg_count += 1; 819 arg_count += 1;
812 } 820 }
813 if (!has_optional_parameters() && !is_native_instance_closure()) { 821 if (!has_optional_parameters() && !is_native_instance_closure()) {
814 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); 822 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize));
815 } else { 823 } else {
816 __ leal(EAX, 824 __ leal(EAX,
817 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 825 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
818 } 826 }
819 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); 827 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function())));
820 __ movl(EDX, Immediate(arg_count)); 828 __ movl(EDX, Immediate(arg_count));
821 compiler->GenerateCall(token_pos(), 829 compiler->GenerateCall(token_pos(),
822 &StubCode::CallNativeCFunctionLabel(), 830 &StubCode::CallNativeCFunctionLabel(),
823 PcDescriptors::kOther, 831 PcDescriptors::kOther,
824 locs()); 832 locs());
825 __ popl(result); 833 __ popl(result);
826 } 834 }
827 835
828 836
829 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { 837 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
830 ASSERT((receiver_type() == kGrowableObjectArrayCid) || 838 ASSERT((receiver_type() == kGrowableObjectArrayCid) ||
831 (receiver_type() == kArrayCid) || 839 (receiver_type() == kArrayCid) ||
832 (receiver_type() == kImmutableArrayCid)); 840 (receiver_type() == kImmutableArrayCid));
833 const intptr_t kNumInputs = 2; 841 const intptr_t kNumInputs = 2;
834 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; 842 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0;
835 LocationSummary* locs = 843 LocationSummary* locs =
836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 844 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
837 locs->set_in(0, Location::RequiresRegister()); 845 locs->set_in(0, Location::RequiresRegister());
838 locs->set_in(1, Location::RequiresRegister()); 846 locs->set_in(1, Location::RequiresRegister());
839 if (receiver_type() == kGrowableObjectArrayCid) { 847 if (receiver_type() == kGrowableObjectArrayCid) {
840 locs->set_temp(0, Location::RequiresRegister()); 848 locs->set_temp(0, Location::RequiresRegister());
841 } 849 }
842 locs->set_out(Location::RequiresRegister()); 850 locs->set_out(Location::RequiresRegister());
843 return locs; 851 return locs;
844 } 852 }
845 853
846 854
847 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 855 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
848 Register receiver = locs()->in(0).reg(); 856 Register receiver = locs()->in(0).reg();
849 Register index = locs()->in(1).reg(); 857 Register index = locs()->in(1).reg();
850 Register result = locs()->out().reg(); 858 Register result = locs()->out().reg();
851 859
852 switch (receiver_type()) { 860 switch (receiver_type()) {
853 case kArrayCid: 861 case kArrayCid:
854 case kImmutableArrayCid: 862 case kImmutableArrayCid:
855 // Note that index is Smi, i.e, times 2. 863 // Note that index is Smi, i.e, times 2.
856 ASSERT(kSmiTagShift == 1); 864 ASSERT(kSmiTagShift == 1);
857 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray))); 865 __ movl(result, FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)));
858 break; 866 break;
859 867
860 case kGrowableObjectArrayCid: { 868 case kGrowableObjectArrayCid: {
861 Register temp = locs()->temp(0).reg(); 869 Register temp = locs()->temp(0).reg();
862 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); 870 __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
863 // Note that index is Smi, i.e, times 2. 871 // Note that index is Smi, i.e, times 2.
864 ASSERT(kSmiTagShift == 1); 872 ASSERT(kSmiTagShift == 1);
865 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray))); 873 __ movl(result, FieldAddress(temp, index, TIMES_2, sizeof(RawArray)));
866 break; 874 break;
867 } 875 }
868 876
869 default: 877 default:
870 UNREACHABLE(); 878 UNREACHABLE();
871 break; 879 break;
872 } 880 }
873 } 881 }
874 882
875 883
876 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { 884 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
877 ASSERT((receiver_type() == kGrowableObjectArrayCid) || 885 ASSERT((receiver_type() == kGrowableObjectArrayCid) ||
878 (receiver_type() == kArrayCid)); 886 (receiver_type() == kArrayCid));
879 const intptr_t kNumInputs = 3; 887 const intptr_t kNumInputs = 3;
880 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0; 888 const intptr_t kNumTemps = receiver_type() == kGrowableObjectArrayCid ? 1 : 0;
881 LocationSummary* locs = 889 LocationSummary* locs =
882 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 890 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
883 locs->set_in(0, Location::RequiresRegister()); 891 locs->set_in(0, Location::RequiresRegister());
884 locs->set_in(1, Location::RequiresRegister()); 892 locs->set_in(1, Location::RequiresRegister());
885 locs->set_in(2, Location::RequiresRegister()); 893 locs->set_in(2, Location::RequiresRegister());
886 if (receiver_type() == kGrowableObjectArrayCid) { 894 if (receiver_type() == kGrowableObjectArrayCid) {
887 locs->set_temp(0, Location::RequiresRegister()); 895 locs->set_temp(0, Location::RequiresRegister());
888 } 896 }
889 return locs; 897 return locs;
890 } 898 }
891 899
892 900
893 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 901 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
894 Register receiver = locs()->in(0).reg(); 902 Register receiver = locs()->in(0).reg();
895 Register index = locs()->in(1).reg(); 903 Register index = locs()->in(1).reg();
896 Register value = locs()->in(2).reg(); 904 Register value = locs()->in(2).reg();
897 905
898 switch (receiver_type()) { 906 switch (receiver_type()) {
899 case kArrayCid: 907 case kArrayCid:
900 case kImmutableArrayCid: 908 case kImmutableArrayCid:
901 // Note that index is Smi, i.e, times 2. 909 // Note that index is Smi, i.e, times 2.
902 ASSERT(kSmiTagShift == 1); 910 ASSERT(kSmiTagShift == 1);
903 if (this->value()->NeedsStoreBuffer()) { 911 if (this->value()->NeedsStoreBuffer()) {
(...skipping 24 matching lines...) Expand all
928 break; 936 break;
929 } 937 }
930 938
931 default: 939 default:
932 UNREACHABLE(); 940 UNREACHABLE();
933 break; 941 break;
934 } 942 }
935 } 943 }
936 944
937 945
938 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { 946 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
939 // TODO(fschneider): For this instruction the input register may be 947 // TODO(fschneider): For this instruction the input register may be
940 // reused for the result (but is not required to) because the input 948 // reused for the result (but is not required to) because the input
941 // is not used after the result is defined. We should consider adding 949 // is not used after the result is defined. We should consider adding
942 // this information to the input policy. 950 // this information to the input policy.
943 return LocationSummary::Make(1, 951 return LocationSummary::Make(1,
944 Location::RequiresRegister(), 952 Location::RequiresRegister(),
945 LocationSummary::kNoCall); 953 LocationSummary::kNoCall);
946 } 954 }
947 955
948 956
949 void LoadInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 957 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
950 Register instance_reg = locs()->in(0).reg(); 958 Register instance_reg = locs()->in(0).reg();
951 Register result_reg = locs()->out().reg(); 959 Register result_reg = locs()->out().reg();
952 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); 960 __ movl(result_reg, FieldAddress(instance_reg, field().Offset()));
953 } 961 }
954 962
955 963
956 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { 964 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const {
957 const intptr_t kNumInputs = 2; 965 const intptr_t kNumInputs = 2;
958 const intptr_t num_temps = 0; 966 const intptr_t num_temps = 0;
959 LocationSummary* summary = 967 LocationSummary* summary =
960 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); 968 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall);
961 summary->set_in(0, Location::RequiresRegister()); 969 summary->set_in(0, Location::RequiresRegister());
962 summary->set_in(1, Location::RequiresRegister()); 970 summary->set_in(1, Location::RequiresRegister());
963 return summary; 971 return summary;
964 } 972 }
965 973
966 974
967 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 975 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
968 Register instance_reg = locs()->in(0).reg(); 976 Register instance_reg = locs()->in(0).reg();
969 Register value_reg = locs()->in(1).reg(); 977 Register value_reg = locs()->in(1).reg();
970 if (this->value()->NeedsStoreBuffer()) { 978 if (this->value()->NeedsStoreBuffer()) {
971 __ StoreIntoObject(instance_reg, 979 __ StoreIntoObject(instance_reg,
972 FieldAddress(instance_reg, field().Offset()), value_reg); 980 FieldAddress(instance_reg, field().Offset()), value_reg);
973 } else { 981 } else {
974 __ StoreIntoObjectNoBarrier(instance_reg, 982 __ StoreIntoObjectNoBarrier(instance_reg,
975 FieldAddress(instance_reg, field().Offset()), value_reg); 983 FieldAddress(instance_reg, field().Offset()), value_reg);
976 } 984 }
977 } 985 }
978 986
979 987
980 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { 988 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
981 return LocationSummary::Make(0, 989 return LocationSummary::Make(0,
982 Location::RequiresRegister(), 990 Location::RequiresRegister(),
983 LocationSummary::kNoCall); 991 LocationSummary::kNoCall);
984 } 992 }
985 993
986 994
987 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 995 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
988 Register result = locs()->out().reg(); 996 Register result = locs()->out().reg();
989 __ LoadObject(result, field()); 997 __ LoadObject(result, field());
990 __ movl(result, FieldAddress(result, Field::value_offset())); 998 __ movl(result, FieldAddress(result, Field::value_offset()));
991 } 999 }
992 1000
993 1001
994 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { 1002 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const {
995 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); 1003 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall);
996 locs->set_in(0, Location::RequiresRegister()); 1004 locs->set_in(0, Location::RequiresRegister());
997 locs->set_temp(0, Location::RequiresRegister()); 1005 locs->set_temp(0, Location::RequiresRegister());
998 locs->set_out(Location::SameAsFirstInput()); 1006 locs->set_out(Location::SameAsFirstInput());
999 return locs; 1007 return locs;
1000 } 1008 }
1001 1009
1002 1010
1003 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1011 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1004 Register value = locs()->in(0).reg(); 1012 Register value = locs()->in(0).reg();
1005 Register temp = locs()->temp(0).reg(); 1013 Register temp = locs()->temp(0).reg();
1006 ASSERT(locs()->out().reg() == value); 1014 ASSERT(locs()->out().reg() == value);
1007 1015
1008 __ LoadObject(temp, field()); 1016 __ LoadObject(temp, field());
1009 if (this->value()->NeedsStoreBuffer()) { 1017 if (this->value()->NeedsStoreBuffer()) {
1010 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); 1018 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
1011 } else { 1019 } else {
1012 __ StoreIntoObjectNoBarrier( 1020 __ StoreIntoObjectNoBarrier(
1013 temp, FieldAddress(temp, Field::value_offset()), value); 1021 temp, FieldAddress(temp, Field::value_offset()), value);
1014 } 1022 }
1015 } 1023 }
1016 1024
1017 1025
1018 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { 1026 LocationSummary* InstanceOfComp::MakeLocationSummary() const {
1019 const intptr_t kNumInputs = 3; 1027 const intptr_t kNumInputs = 3;
1020 const intptr_t kNumTemps = 0; 1028 const intptr_t kNumTemps = 0;
1021 LocationSummary* summary = 1029 LocationSummary* summary =
1022 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1030 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1023 summary->set_in(0, Location::RegisterLocation(EAX)); 1031 summary->set_in(0, Location::RegisterLocation(EAX));
1024 summary->set_in(1, Location::RegisterLocation(ECX)); 1032 summary->set_in(1, Location::RegisterLocation(ECX));
1025 summary->set_in(2, Location::RegisterLocation(EDX)); 1033 summary->set_in(2, Location::RegisterLocation(EDX));
1026 summary->set_out(Location::RegisterLocation(EAX)); 1034 summary->set_out(Location::RegisterLocation(EAX));
1027 return summary; 1035 return summary;
1028 } 1036 }
1029 1037
1030 1038
1031 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1039 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1032 ASSERT(locs()->in(0).reg() == EAX); // Value. 1040 ASSERT(locs()->in(0).reg() == EAX); // Value.
1033 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 1041 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
1034 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 1042 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
1035 1043
1036 compiler->GenerateInstanceOf(token_pos(), 1044 compiler->GenerateInstanceOf(token_pos(),
1037 type(), 1045 type(),
1038 negate_result(), 1046 negate_result(),
1039 locs()); 1047 locs());
1040 ASSERT(locs()->out().reg() == EAX); 1048 ASSERT(locs()->out().reg() == EAX);
1041 } 1049 }
1042 1050
1043 1051
1044 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { 1052 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1045 const intptr_t kNumInputs = 1; 1053 const intptr_t kNumInputs = 1;
1046 const intptr_t kNumTemps = 0; 1054 const intptr_t kNumTemps = 0;
1047 LocationSummary* locs = 1055 LocationSummary* locs =
1048 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1056 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1049 locs->set_in(0, Location::RegisterLocation(ECX)); 1057 locs->set_in(0, Location::RegisterLocation(ECX));
1050 locs->set_out(Location::RegisterLocation(EAX)); 1058 locs->set_out(Location::RegisterLocation(EAX));
1051 return locs; 1059 return locs;
1052 } 1060 }
1053 1061
1054 1062
1055 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1063 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1056 // Allocate the array. EDX = length, ECX = element type. 1064 // Allocate the array. EDX = length, ECX = element type.
1057 ASSERT(locs()->in(0).reg() == ECX); 1065 ASSERT(locs()->in(0).reg() == ECX);
1058 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); 1066 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount())));
1059 compiler->GenerateCall(token_pos(), 1067 compiler->GenerateCall(token_pos(),
1060 &StubCode::AllocateArrayLabel(), 1068 &StubCode::AllocateArrayLabel(),
1061 PcDescriptors::kOther, 1069 PcDescriptors::kOther,
1062 locs()); 1070 locs());
1063 ASSERT(locs()->out().reg() == EAX); 1071 ASSERT(locs()->out().reg() == EAX);
1064 1072
1065 // Pop the element values from the stack into the array. 1073 // Pop the element values from the stack into the array.
1066 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); 1074 __ leal(EDX, FieldAddress(EAX, Array::data_offset()));
1067 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1075 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1068 __ popl(Address(EDX, i * kWordSize)); 1076 __ popl(Address(EDX, i * kWordSize));
1069 } 1077 }
1070 } 1078 }
1071 1079
1072 1080
1073 LocationSummary* 1081 LocationSummary*
1074 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { 1082 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const {
1075 const intptr_t kNumInputs = 2; 1083 const intptr_t kNumInputs = 2;
1076 const intptr_t kNumTemps = 0; 1084 const intptr_t kNumTemps = 0;
1077 LocationSummary* locs = 1085 LocationSummary* locs =
1078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1086 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1079 locs->set_in(0, Location::RegisterLocation(EAX)); 1087 locs->set_in(0, Location::RegisterLocation(EAX));
1080 locs->set_in(1, Location::RegisterLocation(ECX)); 1088 locs->set_in(1, Location::RegisterLocation(ECX));
1081 locs->set_out(Location::RegisterLocation(EAX)); 1089 locs->set_out(Location::RegisterLocation(EAX));
1082 return locs; 1090 return locs;
1083 } 1091 }
1084 1092
1085 1093
1086 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( 1094 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
1087 FlowGraphCompiler* compiler) { 1095 FlowGraphCompiler* compiler) {
1088 const Class& cls = Class::ZoneHandle(constructor().Owner()); 1096 const Class& cls = Class::ZoneHandle(constructor().Owner());
1089 Register type_arguments = locs()->in(0).reg(); 1097 Register type_arguments = locs()->in(0).reg();
1090 Register instantiator_type_arguments = locs()->in(1).reg(); 1098 Register instantiator_type_arguments = locs()->in(1).reg();
1091 Register result = locs()->out().reg(); 1099 Register result = locs()->out().reg();
1092 1100
1093 // Push the result place holder initialized to NULL. 1101 // Push the result place holder initialized to NULL.
1094 __ PushObject(Object::ZoneHandle()); 1102 __ PushObject(Object::ZoneHandle());
1095 __ PushObject(cls); 1103 __ PushObject(cls);
1096 __ pushl(type_arguments); 1104 __ pushl(type_arguments);
1097 __ pushl(instantiator_type_arguments); 1105 __ pushl(instantiator_type_arguments);
1098 compiler->GenerateCallRuntime(token_pos(), 1106 compiler->GenerateCallRuntime(token_pos(),
1099 kAllocateObjectWithBoundsCheckRuntimeEntry, 1107 kAllocateObjectWithBoundsCheckRuntimeEntry,
1100 locs()); 1108 locs());
1101 // Pop instantiator type arguments, type arguments, and class. 1109 // Pop instantiator type arguments, type arguments, and class.
1102 // source location. 1110 // source location.
1103 __ Drop(3); 1111 __ Drop(3);
1104 __ popl(result); // Pop new instance. 1112 __ popl(result); // Pop new instance.
1105 } 1113 }
1106 1114
1107 1115
1108 LocationSummary* LoadVMFieldInstr::MakeLocationSummary() const { 1116 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1109 return LocationSummary::Make(1, 1117 return LocationSummary::Make(1,
1110 Location::RequiresRegister(), 1118 Location::RequiresRegister(),
1111 LocationSummary::kNoCall); 1119 LocationSummary::kNoCall);
1112 } 1120 }
1113 1121
1114 1122
1115 void LoadVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1123 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1116 Register instance_reg = locs()->in(0).reg(); 1124 Register instance_reg = locs()->in(0).reg();
1117 Register result_reg = locs()->out().reg(); 1125 Register result_reg = locs()->out().reg();
1118 1126
1119 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes())); 1127 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1120 } 1128 }
1121 1129
1122 1130
1123 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { 1131 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
1124 const intptr_t kNumInputs = 1; 1132 const intptr_t kNumInputs = 1;
1125 const intptr_t kNumTemps = 1; 1133 const intptr_t kNumTemps = 1;
1126 LocationSummary* locs = 1134 LocationSummary* locs =
1127 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1135 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1128 locs->set_in(0, Location::RegisterLocation(EAX)); 1136 locs->set_in(0, Location::RegisterLocation(EAX));
1129 locs->set_temp(0, Location::RegisterLocation(ECX)); 1137 locs->set_temp(0, Location::RegisterLocation(ECX));
1130 locs->set_out(Location::RegisterLocation(EAX)); 1138 locs->set_out(Location::RegisterLocation(EAX));
1131 return locs; 1139 return locs;
1132 } 1140 }
1133 1141
1134 1142
1135 void InstantiateTypeArgumentsInstr::EmitNativeCode( 1143 void InstantiateTypeArgumentsComp::EmitNativeCode(
1136 FlowGraphCompiler* compiler) { 1144 FlowGraphCompiler* compiler) {
1137 Register instantiator_reg = locs()->in(0).reg(); 1145 Register instantiator_reg = locs()->in(0).reg();
1138 Register temp = locs()->temp(0).reg(); 1146 Register temp = locs()->temp(0).reg();
1139 Register result_reg = locs()->out().reg(); 1147 Register result_reg = locs()->out().reg();
1140 1148
1141 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 1149 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
1142 // (or null). 1150 // (or null).
1143 // If the instantiator is null and if the type argument vector 1151 // If the instantiator is null and if the type argument vector
1144 // instantiated from null becomes a vector of Dynamic, then use null as 1152 // instantiated from null becomes a vector of Dynamic, then use null as
1145 // the type arguments. 1153 // the type arguments.
(...skipping 29 matching lines...) Expand all
1175 locs()); 1183 locs());
1176 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1184 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1177 __ popl(result_reg); // Pop instantiated type arguments. 1185 __ popl(result_reg); // Pop instantiated type arguments.
1178 __ Bind(&type_arguments_instantiated); 1186 __ Bind(&type_arguments_instantiated);
1179 ASSERT(instantiator_reg == result_reg); 1187 ASSERT(instantiator_reg == result_reg);
1180 // 'result_reg': Instantiated type arguments. 1188 // 'result_reg': Instantiated type arguments.
1181 } 1189 }
1182 1190
1183 1191
1184 LocationSummary* 1192 LocationSummary*
1185 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { 1193 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
1186 const intptr_t kNumInputs = 1; 1194 const intptr_t kNumInputs = 1;
1187 const intptr_t kNumTemps = 1; 1195 const intptr_t kNumTemps = 1;
1188 LocationSummary* locs = 1196 LocationSummary* locs =
1189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1197 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1190 locs->set_in(0, Location::RequiresRegister()); 1198 locs->set_in(0, Location::RequiresRegister());
1191 locs->set_out(Location::SameAsFirstInput()); 1199 locs->set_out(Location::SameAsFirstInput());
1192 locs->set_temp(0, Location::RequiresRegister()); 1200 locs->set_temp(0, Location::RequiresRegister());
1193 return locs; 1201 return locs;
1194 } 1202 }
1195 1203
1196 1204
1197 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( 1205 void ExtractConstructorTypeArgumentsComp::EmitNativeCode(
1198 FlowGraphCompiler* compiler) { 1206 FlowGraphCompiler* compiler) {
1199 Register instantiator_reg = locs()->in(0).reg(); 1207 Register instantiator_reg = locs()->in(0).reg();
1200 Register result_reg = locs()->out().reg(); 1208 Register result_reg = locs()->out().reg();
1201 ASSERT(instantiator_reg == result_reg); 1209 ASSERT(instantiator_reg == result_reg);
1202 Register temp_reg = locs()->temp(0).reg(); 1210 Register temp_reg = locs()->temp(0).reg();
1203 1211
1204 // instantiator_reg is the instantiator type argument vector, i.e. an 1212 // instantiator_reg is the instantiator type argument vector, i.e. an
1205 // AbstractTypeArguments object (or null). 1213 // AbstractTypeArguments object (or null).
1206 // If the instantiator is null and if the type argument vector 1214 // If the instantiator is null and if the type argument vector
1207 // instantiated from null becomes a vector of Dynamic, then use null as 1215 // instantiated from null becomes a vector of Dynamic, then use null as
(...skipping 25 matching lines...) Expand all
1233 // In the non-factory case, we rely on the allocation stub to 1241 // In the non-factory case, we rely on the allocation stub to
1234 // instantiate the type arguments. 1242 // instantiate the type arguments.
1235 __ LoadObject(result_reg, type_arguments()); 1243 __ LoadObject(result_reg, type_arguments());
1236 // result_reg: uninstantiated type arguments. 1244 // result_reg: uninstantiated type arguments.
1237 __ Bind(&type_arguments_instantiated); 1245 __ Bind(&type_arguments_instantiated);
1238 // result_reg: uninstantiated or instantiated type arguments. 1246 // result_reg: uninstantiated or instantiated type arguments.
1239 } 1247 }
1240 1248
1241 1249
1242 LocationSummary* 1250 LocationSummary*
1243 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { 1251 ExtractConstructorInstantiatorComp::MakeLocationSummary() const {
1244 const intptr_t kNumInputs = 1; 1252 const intptr_t kNumInputs = 1;
1245 const intptr_t kNumTemps = 1; 1253 const intptr_t kNumTemps = 1;
1246 LocationSummary* locs = 1254 LocationSummary* locs =
1247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1255 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1248 locs->set_in(0, Location::RequiresRegister()); 1256 locs->set_in(0, Location::RequiresRegister());
1249 locs->set_out(Location::SameAsFirstInput()); 1257 locs->set_out(Location::SameAsFirstInput());
1250 locs->set_temp(0, Location::RequiresRegister()); 1258 locs->set_temp(0, Location::RequiresRegister());
1251 return locs; 1259 return locs;
1252 } 1260 }
1253 1261
1254 1262
1255 void ExtractConstructorInstantiatorInstr::EmitNativeCode( 1263 void ExtractConstructorInstantiatorComp::EmitNativeCode(
1256 FlowGraphCompiler* compiler) { 1264 FlowGraphCompiler* compiler) {
1257 Register instantiator_reg = locs()->in(0).reg(); 1265 Register instantiator_reg = locs()->in(0).reg();
1258 ASSERT(locs()->out().reg() == instantiator_reg); 1266 ASSERT(locs()->out().reg() == instantiator_reg);
1259 Register temp_reg = locs()->temp(0).reg(); 1267 Register temp_reg = locs()->temp(0).reg();
1260 1268
1261 // instantiator_reg is the instantiator AbstractTypeArguments object 1269 // instantiator_reg is the instantiator AbstractTypeArguments object
1262 // (or null). If the instantiator is null and if the type argument vector 1270 // (or null). If the instantiator is null and if the type argument vector
1263 // instantiated from null becomes a vector of Dynamic, then use null as 1271 // instantiated from null becomes a vector of Dynamic, then use null as
1264 // the type arguments and do not pass the instantiator. 1272 // the type arguments and do not pass the instantiator.
1265 Label done; 1273 Label done;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 // The instantiator was used in VisitExtractConstructorTypeArguments as the 1307 // The instantiator was used in VisitExtractConstructorTypeArguments as the
1300 // instantiated type arguments, no proper instantiator needed. 1308 // instantiated type arguments, no proper instantiator needed.
1301 __ movl(instantiator_reg, 1309 __ movl(instantiator_reg,
1302 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1310 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1303 } 1311 }
1304 __ Bind(&done); 1312 __ Bind(&done);
1305 // instantiator_reg: instantiator or kNoInstantiator. 1313 // instantiator_reg: instantiator or kNoInstantiator.
1306 } 1314 }
1307 1315
1308 1316
1309 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { 1317 LocationSummary* AllocateContextComp::MakeLocationSummary() const {
1310 const intptr_t kNumInputs = 0; 1318 const intptr_t kNumInputs = 0;
1311 const intptr_t kNumTemps = 1; 1319 const intptr_t kNumTemps = 1;
1312 LocationSummary* locs = 1320 LocationSummary* locs =
1313 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1321 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1314 locs->set_temp(0, Location::RegisterLocation(EDX)); 1322 locs->set_temp(0, Location::RegisterLocation(EDX));
1315 locs->set_out(Location::RegisterLocation(EAX)); 1323 locs->set_out(Location::RegisterLocation(EAX));
1316 return locs; 1324 return locs;
1317 } 1325 }
1318 1326
1319 1327
1320 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1328 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1321 ASSERT(locs()->temp(0).reg() == EDX); 1329 ASSERT(locs()->temp(0).reg() == EDX);
1322 ASSERT(locs()->out().reg() == EAX); 1330 ASSERT(locs()->out().reg() == EAX);
1323 1331
1324 __ movl(EDX, Immediate(num_context_variables())); 1332 __ movl(EDX, Immediate(num_context_variables()));
1325 const ExternalLabel label("alloc_context", 1333 const ExternalLabel label("alloc_context",
1326 StubCode::AllocateContextEntryPoint()); 1334 StubCode::AllocateContextEntryPoint());
1327 compiler->GenerateCall(token_pos(), 1335 compiler->GenerateCall(token_pos(),
1328 &label, 1336 &label,
1329 PcDescriptors::kOther, 1337 PcDescriptors::kOther,
1330 locs()); 1338 locs());
1331 } 1339 }
1332 1340
1333 1341
1334 LocationSummary* CloneContextInstr::MakeLocationSummary() const { 1342 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1335 const intptr_t kNumInputs = 1; 1343 const intptr_t kNumInputs = 1;
1336 const intptr_t kNumTemps = 0; 1344 const intptr_t kNumTemps = 0;
1337 LocationSummary* locs = 1345 LocationSummary* locs =
1338 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1346 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1339 locs->set_in(0, Location::RegisterLocation(EAX)); 1347 locs->set_in(0, Location::RegisterLocation(EAX));
1340 locs->set_out(Location::RegisterLocation(EAX)); 1348 locs->set_out(Location::RegisterLocation(EAX));
1341 return locs; 1349 return locs;
1342 } 1350 }
1343 1351
1344 1352
1345 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1353 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1346 Register context_value = locs()->in(0).reg(); 1354 Register context_value = locs()->in(0).reg();
1347 Register result = locs()->out().reg(); 1355 Register result = locs()->out().reg();
1348 1356
1349 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1357 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1350 __ pushl(context_value); 1358 __ pushl(context_value);
1351 compiler->GenerateCallRuntime(token_pos(), 1359 compiler->GenerateCallRuntime(token_pos(),
1352 kCloneContextRuntimeEntry, 1360 kCloneContextRuntimeEntry,
1353 locs()); 1361 locs());
1354 __ popl(result); // Remove argument. 1362 __ popl(result); // Remove argument.
1355 __ popl(result); // Get result (cloned context). 1363 __ popl(result); // Get result (cloned context).
1356 } 1364 }
1357 1365
1358 1366
1359 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { 1367 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1360 return LocationSummary::Make(0, 1368 return LocationSummary::Make(0,
1361 Location::NoLocation(), 1369 Location::NoLocation(),
1362 LocationSummary::kNoCall); 1370 LocationSummary::kNoCall);
1363 } 1371 }
1364 1372
1365 1373
1366 // Restore stack and initialize the two exception variables: 1374 // Restore stack and initialize the two exception variables:
1367 // exception and stack trace variables. 1375 // exception and stack trace variables.
1368 void CatchEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1376 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1369 // Restore RSP from RBP as we are coming from a throw and the code for 1377 // Restore RSP from RBP as we are coming from a throw and the code for
1370 // popping arguments has not been run. 1378 // popping arguments has not been run.
1371 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; 1379 const intptr_t locals_space_size = compiler->StackSize() * kWordSize;
1372 ASSERT(locals_space_size >= 0); 1380 ASSERT(locals_space_size >= 0);
1373 const intptr_t offset_size = 1381 const intptr_t offset_size =
1374 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; 1382 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP;
1375 __ leal(ESP, Address(EBP, offset_size)); 1383 __ leal(ESP, Address(EBP, offset_size));
1376 1384
1377 ASSERT(!exception_var().is_captured()); 1385 ASSERT(!exception_var().is_captured());
1378 ASSERT(!stacktrace_var().is_captured()); 1386 ASSERT(!stacktrace_var().is_captured());
1379 __ movl(Address(EBP, exception_var().index() * kWordSize), 1387 __ movl(Address(EBP, exception_var().index() * kWordSize),
1380 kExceptionObjectReg); 1388 kExceptionObjectReg);
1381 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), 1389 __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
1382 kStackTraceObjectReg); 1390 kStackTraceObjectReg);
1383 } 1391 }
1384 1392
1385 1393
1386 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { 1394 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
1387 const intptr_t kNumInputs = 0; 1395 const intptr_t kNumInputs = 0;
1388 const intptr_t kNumTemps = 0; 1396 const intptr_t kNumTemps = 0;
1389 LocationSummary* summary = 1397 LocationSummary* summary =
1390 new LocationSummary(kNumInputs, 1398 new LocationSummary(kNumInputs,
1391 kNumTemps, 1399 kNumTemps,
1392 LocationSummary::kCallOnSlowPath); 1400 LocationSummary::kCallOnSlowPath);
1393 return summary; 1401 return summary;
1394 } 1402 }
1395 1403
1396 1404
1397 class CheckStackOverflowSlowPath : public SlowPathCode { 1405 class CheckStackOverflowSlowPath : public SlowPathCode {
1398 public: 1406 public:
1399 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) 1407 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation)
1400 : instruction_(instruction) { } 1408 : computation_(computation) { }
1401 1409
1402 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1410 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1403 __ Bind(entry_label()); 1411 __ Bind(entry_label());
1404 compiler->SaveLiveRegisters(instruction_->locs()); 1412 compiler->SaveLiveRegisters(computation_->locs());
1405 compiler->GenerateCallRuntime(instruction_->token_pos(), 1413 compiler->GenerateCallRuntime(computation_->token_pos(),
1406 kStackOverflowRuntimeEntry, 1414 kStackOverflowRuntimeEntry,
1407 instruction_->locs()); 1415 computation_->locs());
1408 compiler->RestoreLiveRegisters(instruction_->locs()); 1416 compiler->RestoreLiveRegisters(computation_->locs());
1409 __ jmp(exit_label()); 1417 __ jmp(exit_label());
1410 } 1418 }
1411 1419
1412 private: 1420 private:
1413 CheckStackOverflowInstr* instruction_; 1421 CheckStackOverflowComp* computation_;
1414 }; 1422 };
1415 1423
1416 1424
1417 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1425 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1418 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); 1426 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
1419 compiler->AddSlowPathCode(slow_path); 1427 compiler->AddSlowPathCode(slow_path);
1420 1428
1421 __ cmpl(ESP, 1429 __ cmpl(ESP,
1422 Address::Absolute(Isolate::Current()->stack_limit_address())); 1430 Address::Absolute(Isolate::Current()->stack_limit_address()));
1423 __ j(BELOW_EQUAL, slow_path->entry_label()); 1431 __ j(BELOW_EQUAL, slow_path->entry_label());
1424 __ Bind(slow_path->exit_label()); 1432 __ Bind(slow_path->exit_label());
1425 } 1433 }
1426 1434
1427 1435
1428 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { 1436 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const {
1429 const intptr_t kNumInputs = 2; 1437 const intptr_t kNumInputs = 2;
1430 if (op_kind() == Token::kTRUNCDIV) { 1438 if (op_kind() == Token::kTRUNCDIV) {
1431 const intptr_t kNumTemps = 3; 1439 const intptr_t kNumTemps = 3;
1432 LocationSummary* summary = 1440 LocationSummary* summary =
1433 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1441 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1434 summary->set_in(0, Location::RegisterLocation(EAX)); 1442 summary->set_in(0, Location::RegisterLocation(EAX));
1435 summary->set_in(1, Location::RegisterLocation(ECX)); 1443 summary->set_in(1, Location::RegisterLocation(ECX));
1436 summary->set_out(Location::SameAsFirstInput()); 1444 summary->set_out(Location::SameAsFirstInput());
1437 summary->set_temp(0, Location::RegisterLocation(EBX)); 1445 summary->set_temp(0, Location::RegisterLocation(EBX));
1438 // Will be used for for sign extension. 1446 // Will be used for for sign extension.
(...skipping 24 matching lines...) Expand all
1463 LocationSummary* summary = 1471 LocationSummary* summary =
1464 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1472 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1465 summary->set_in(0, Location::RequiresRegister()); 1473 summary->set_in(0, Location::RequiresRegister());
1466 summary->set_in(1, Location::RegisterOrConstant(right())); 1474 summary->set_in(1, Location::RegisterOrConstant(right()));
1467 summary->set_out(Location::SameAsFirstInput()); 1475 summary->set_out(Location::SameAsFirstInput());
1468 return summary; 1476 return summary;
1469 } 1477 }
1470 } 1478 }
1471 1479
1472 1480
1473 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1481 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1474 Register left = locs()->in(0).reg(); 1482 Register left = locs()->in(0).reg();
1475 Register result = locs()->out().reg(); 1483 Register result = locs()->out().reg();
1476 ASSERT(left == result); 1484 ASSERT(left == result);
1477 Label* deopt = NULL; 1485 Label* deopt = NULL;
1478 switch (op_kind()) { 1486 switch (op_kind()) {
1479 case Token::kBIT_AND: 1487 case Token::kBIT_AND:
1480 case Token::kBIT_OR: 1488 case Token::kBIT_OR:
1481 case Token::kBIT_XOR: 1489 case Token::kBIT_XOR:
1482 // Can't deoptimize. Arguments are already checked for smi. 1490 // Can't deoptimize. Arguments are already checked for smi.
1483 break; 1491 break;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 UNREACHABLE(); 1692 UNREACHABLE();
1685 break; 1693 break;
1686 } 1694 }
1687 default: 1695 default:
1688 UNREACHABLE(); 1696 UNREACHABLE();
1689 break; 1697 break;
1690 } 1698 }
1691 } 1699 }
1692 1700
1693 1701
1694 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { 1702 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const {
1695 const intptr_t kNumInputs = 2; 1703 const intptr_t kNumInputs = 2;
1696 ASSERT(op_kind() == Token::kBIT_AND); 1704 ASSERT(op_kind() == Token::kBIT_AND);
1697 const intptr_t kNumTemps = 1; 1705 const intptr_t kNumTemps = 1;
1698 LocationSummary* summary = 1706 LocationSummary* summary =
1699 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1707 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1700 summary->set_in(0, Location::RegisterLocation(EAX)); 1708 summary->set_in(0, Location::RegisterLocation(EAX));
1701 summary->set_in(1, Location::RegisterLocation(ECX)); 1709 summary->set_in(1, Location::RegisterLocation(ECX));
1702 summary->set_temp(0, Location::RegisterLocation(EDX)); 1710 summary->set_temp(0, Location::RegisterLocation(EDX));
1703 summary->set_out(Location::RegisterLocation(EAX)); 1711 summary->set_out(Location::RegisterLocation(EAX));
1704 return summary; 1712 return summary;
1705 } 1713 }
1706 1714
1707 1715
1708 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1716 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1709 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1717 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1710 // receiver and a Mint or Smi argument. We fall back to the run time call if 1718 // receiver and a Mint or Smi argument. We fall back to the run time call if
1711 // both receiver and argument are Mint or if one of them is Mint and the other 1719 // both receiver and argument are Mint or if one of them is Mint and the other
1712 // is a negative Smi. 1720 // is a negative Smi.
1713 Register left = locs()->in(0).reg(); 1721 Register left = locs()->in(0).reg();
1714 Register right = locs()->in(1).reg(); 1722 Register right = locs()->in(1).reg();
1715 Register result = locs()->out().reg(); 1723 Register result = locs()->out().reg();
1716 Register temp = locs()->temp(0).reg(); 1724 Register temp = locs()->temp(0).reg();
1717 ASSERT(left == result); 1725 ASSERT(left == result);
1718 ASSERT(op_kind() == Token::kBIT_AND); 1726 ASSERT(op_kind() == Token::kBIT_AND);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 instance_call()->ArgumentCount(), 1796 instance_call()->ArgumentCount(),
1789 instance_call()->argument_names(), 1797 instance_call()->argument_names(),
1790 locs()); 1798 locs());
1791 ASSERT(result == EAX); 1799 ASSERT(result == EAX);
1792 } 1800 }
1793 } 1801 }
1794 __ Bind(&done); 1802 __ Bind(&done);
1795 } 1803 }
1796 1804
1797 1805
1798 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { 1806 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const {
1799 ASSERT((left()->ResultCid() != kDoubleCid) && 1807 ASSERT((left()->ResultCid() != kDoubleCid) &&
1800 (right()->ResultCid() != kDoubleCid)); 1808 (right()->ResultCid() != kDoubleCid));
1801 const intptr_t kNumInputs = 2; 1809 const intptr_t kNumInputs = 2;
1802 const intptr_t kNumTemps = 1; 1810 const intptr_t kNumTemps = 1;
1803 LocationSummary* summary = 1811 LocationSummary* summary =
1804 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1812 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1805 summary->set_in(0, Location::RequiresRegister()); 1813 summary->set_in(0, Location::RequiresRegister());
1806 summary->set_in(1, Location::RequiresRegister()); 1814 summary->set_in(1, Location::RequiresRegister());
1807 summary->set_temp(0, Location::RequiresRegister()); 1815 summary->set_temp(0, Location::RequiresRegister());
1808 return summary; 1816 return summary;
1809 } 1817 }
1810 1818
1811 1819
1812 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1820 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1813 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); 1821 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(),
1822 kDeoptBinaryDoubleOp);
1823
1814 Register temp = locs()->temp(0).reg(); 1824 Register temp = locs()->temp(0).reg();
1815 __ movl(temp, locs()->in(0).reg()); 1825 __ movl(temp, locs()->in(0).reg());
1816 __ orl(temp, locs()->in(1).reg()); 1826 __ orl(temp, locs()->in(1).reg());
1817 __ testl(temp, Immediate(kSmiTagMask)); 1827 __ testl(temp, Immediate(kSmiTagMask));
1818 __ j(ZERO, deopt); 1828 __ j(ZERO, deopt);
1819 } 1829 }
1820 1830
1821 1831
1822 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { 1832 LocationSummary* BoxDoubleComp::MakeLocationSummary() const {
1823 const intptr_t kNumInputs = 1; 1833 const intptr_t kNumInputs = 1;
1824 const intptr_t kNumTemps = 0; 1834 const intptr_t kNumTemps = 0;
1825 LocationSummary* summary = 1835 LocationSummary* summary =
1826 new LocationSummary(kNumInputs, 1836 new LocationSummary(kNumInputs,
1827 kNumTemps, 1837 kNumTemps,
1828 LocationSummary::kCallOnSlowPath); 1838 LocationSummary::kCallOnSlowPath);
1829 summary->set_in(0, Location::RequiresXmmRegister()); 1839 summary->set_in(0, Location::RequiresXmmRegister());
1830 summary->set_out(Location::RequiresRegister()); 1840 summary->set_out(Location::RequiresRegister());
1831 return summary; 1841 return summary;
1832 } 1842 }
1833 1843
1834 1844
1835 class BoxDoubleSlowPath : public SlowPathCode { 1845 class BoxDoubleSlowPath : public SlowPathCode {
1836 public: 1846 public:
1837 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) 1847 explicit BoxDoubleSlowPath(BoxDoubleComp* computation)
1838 : instruction_(instruction) { } 1848 : computation_(computation) { }
1839 1849
1840 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1850 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1841 __ Bind(entry_label()); 1851 __ Bind(entry_label());
1842 const Class& double_class = compiler->double_class(); 1852 const Class& double_class = compiler->double_class();
1843 const Code& stub = 1853 const Code& stub =
1844 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1854 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1845 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1855 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1846 1856
1847 LocationSummary* locs = instruction_->locs(); 1857 LocationSummary* locs = computation_->locs();
1848 locs->live_registers()->Remove(locs->out()); 1858 locs->live_registers()->Remove(locs->out());
1849 1859
1850 compiler->SaveLiveRegisters(locs); 1860 compiler->SaveLiveRegisters(locs);
1851 compiler->GenerateCall(instruction_->token_pos(), 1861 compiler->GenerateCall(computation_->token_pos(),
1852 &label, 1862 &label,
1853 PcDescriptors::kOther, 1863 PcDescriptors::kOther,
1854 locs); 1864 locs);
1855 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); 1865 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX);
1856 compiler->RestoreLiveRegisters(locs); 1866 compiler->RestoreLiveRegisters(locs);
1857 1867
1858 __ jmp(exit_label()); 1868 __ jmp(exit_label());
1859 } 1869 }
1860 1870
1861 private: 1871 private:
1862 BoxDoubleInstr* instruction_; 1872 BoxDoubleComp* computation_;
1863 }; 1873 };
1864 1874
1865 1875
1866 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1876 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1867 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); 1877 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this);
1868 compiler->AddSlowPathCode(slow_path); 1878 compiler->AddSlowPathCode(slow_path);
1869 1879
1870 Register out_reg = locs()->out().reg(); 1880 Register out_reg = locs()->out().reg();
1871 XmmRegister value = locs()->in(0).xmm_reg(); 1881 XmmRegister value = locs()->in(0).xmm_reg();
1872 1882
1873 AssemblerMacros::TryAllocate(compiler->assembler(), 1883 AssemblerMacros::TryAllocate(compiler->assembler(),
1874 compiler->double_class(), 1884 compiler->double_class(),
1875 slow_path->entry_label(), 1885 slow_path->entry_label(),
1876 Assembler::kFarJump, 1886 Assembler::kFarJump,
1877 out_reg); 1887 out_reg);
1878 __ Bind(slow_path->exit_label()); 1888 __ Bind(slow_path->exit_label());
1879 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 1889 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
1880 } 1890 }
1881 1891
1882 1892
1883 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { 1893 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const {
1884 const intptr_t v_cid = value()->ResultCid(); 1894 const intptr_t v_cid = value()->ResultCid();
1885 1895
1886 const intptr_t kNumInputs = 1; 1896 const intptr_t kNumInputs = 1;
1887 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; 1897 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0;
1888 LocationSummary* summary = 1898 LocationSummary* summary =
1889 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1899 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1890 summary->set_in(0, Location::RequiresRegister()); 1900 summary->set_in(0, Location::RequiresRegister());
1891 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); 1901 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister());
1892 summary->set_out(Location::RequiresXmmRegister()); 1902 summary->set_out(Location::RequiresXmmRegister());
1893 return summary; 1903 return summary;
1894 } 1904 }
1895 1905
1896 1906
1897 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1907 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1898 const intptr_t v_cid = value()->ResultCid(); 1908 const intptr_t v_cid = value()->ResultCid();
1899 1909
1900 const Register value = locs()->in(0).reg(); 1910 const Register value = locs()->in(0).reg();
1901 const XmmRegister result = locs()->out().xmm_reg(); 1911 const XmmRegister result = locs()->out().xmm_reg();
1902 if (v_cid != kDoubleCid) { 1912 if (v_cid != kDoubleCid) {
1903 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); 1913 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp);
1904 compiler->LoadDoubleOrSmiToXmm(result, 1914 compiler->LoadDoubleOrSmiToXmm(result,
1905 value, 1915 value,
1906 locs()->temp(0).reg(), 1916 locs()->temp(0).reg(),
1907 deopt); 1917 deopt);
1908 } else { 1918 } else {
1909 __ movsd(result, FieldAddress(value, Double::value_offset())); 1919 __ movsd(result, FieldAddress(value, Double::value_offset()));
1910 } 1920 }
1911 } 1921 }
1912 1922
1913 1923
1914 LocationSummary* UnboxedDoubleBinaryOpInstr::MakeLocationSummary() const { 1924 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const {
1915 const intptr_t kNumInputs = 2; 1925 const intptr_t kNumInputs = 2;
1916 const intptr_t kNumTemps = 0; 1926 const intptr_t kNumTemps = 0;
1917 LocationSummary* summary = 1927 LocationSummary* summary =
1918 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1928 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1919 summary->set_in(0, Location::RequiresXmmRegister()); 1929 summary->set_in(0, Location::RequiresXmmRegister());
1920 summary->set_in(1, Location::RequiresXmmRegister()); 1930 summary->set_in(1, Location::RequiresXmmRegister());
1921 summary->set_out(Location::SameAsFirstInput()); 1931 summary->set_out(Location::SameAsFirstInput());
1922 return summary; 1932 return summary;
1923 } 1933 }
1924 1934
1925 1935
1926 void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1936 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1927 XmmRegister left = locs()->in(0).xmm_reg(); 1937 XmmRegister left = locs()->in(0).xmm_reg();
1928 XmmRegister right = locs()->in(1).xmm_reg(); 1938 XmmRegister right = locs()->in(1).xmm_reg();
1929 1939
1930 ASSERT(locs()->out().xmm_reg() == left); 1940 ASSERT(locs()->out().xmm_reg() == left);
1931 1941
1932 switch (op_kind()) { 1942 switch (op_kind()) {
1933 case Token::kADD: __ addsd(left, right); break; 1943 case Token::kADD: __ addsd(left, right); break;
1934 case Token::kSUB: __ subsd(left, right); break; 1944 case Token::kSUB: __ subsd(left, right); break;
1935 case Token::kMUL: __ mulsd(left, right); break; 1945 case Token::kMUL: __ mulsd(left, right); break;
1936 case Token::kDIV: __ divsd(left, right); break; 1946 case Token::kDIV: __ divsd(left, right); break;
1937 default: UNREACHABLE(); 1947 default: UNREACHABLE();
1938 } 1948 }
1939 } 1949 }
1940 1950
1941 1951
1942 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { 1952 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const {
1943 const intptr_t kNumInputs = 1; 1953 const intptr_t kNumInputs = 1;
1944 const intptr_t kNumTemps = 0; 1954 const intptr_t kNumTemps = 0;
1945 LocationSummary* summary = 1955 LocationSummary* summary =
1946 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1956 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1947 summary->set_in(0, Location::RequiresRegister()); 1957 summary->set_in(0, Location::RequiresRegister());
1948 summary->set_out(Location::SameAsFirstInput()); 1958 summary->set_out(Location::SameAsFirstInput());
1949 return summary; 1959 return summary;
1950 } 1960 }
1951 1961
1952 1962
1953 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1963 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1954 Register value = locs()->in(0).reg(); 1964 Register value = locs()->in(0).reg();
1955 ASSERT(value == locs()->out().reg()); 1965 ASSERT(value == locs()->out().reg());
1956 switch (op_kind()) { 1966 switch (op_kind()) {
1957 case Token::kNEGATE: { 1967 case Token::kNEGATE: {
1958 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1968 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1959 kDeoptUnaryOp); 1969 kDeoptUnaryOp);
1960 __ negl(value); 1970 __ negl(value);
1961 __ j(OVERFLOW, deopt); 1971 __ j(OVERFLOW, deopt);
1962 break; 1972 break;
1963 } 1973 }
1964 case Token::kBIT_NOT: 1974 case Token::kBIT_NOT:
1965 __ notl(value); 1975 __ notl(value);
1966 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 1976 __ andl(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
1967 break; 1977 break;
1968 default: 1978 default:
1969 UNREACHABLE(); 1979 UNREACHABLE();
1970 } 1980 }
1971 } 1981 }
1972 1982
1973 1983
1974 LocationSummary* NumberNegateInstr::MakeLocationSummary() const { 1984 LocationSummary* NumberNegateComp::MakeLocationSummary() const {
1975 const intptr_t kNumInputs = 1; 1985 const intptr_t kNumInputs = 1;
1976 const intptr_t kNumTemps = 1; // Needed for doubles. 1986 const intptr_t kNumTemps = 1; // Needed for doubles.
1977 LocationSummary* summary = 1987 LocationSummary* summary =
1978 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1988 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1979 summary->set_in(0, Location::RegisterLocation(EAX)); 1989 summary->set_in(0, Location::RegisterLocation(EAX));
1980 summary->set_temp(0, Location::RegisterLocation(ECX)); 1990 summary->set_temp(0, Location::RegisterLocation(ECX));
1981 summary->set_out(Location::RegisterLocation(EAX)); 1991 summary->set_out(Location::RegisterLocation(EAX));
1982 return summary; 1992 return summary;
1983 } 1993 }
1984 1994
1985 1995
1986 void NumberNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1996 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1987 const ICData& ic_data = *instance_call()->ic_data(); 1997 const ICData& ic_data = *instance_call()->ic_data();
1988 ASSERT(!ic_data.IsNull()); 1998 ASSERT(!ic_data.IsNull());
1989 ASSERT(ic_data.num_args_tested() == 1); 1999 ASSERT(ic_data.num_args_tested() == 1);
1990 2000
1991 // TODO(srdjan): Implement for more checks. 2001 // TODO(srdjan): Implement for more checks.
1992 ASSERT(ic_data.NumberOfChecks() == 1); 2002 ASSERT(ic_data.NumberOfChecks() == 1);
1993 intptr_t test_class_id; 2003 intptr_t test_class_id;
1994 Function& target = Function::Handle(); 2004 Function& target = Function::Handle();
1995 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 2005 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1996 2006
(...skipping 25 matching lines...) Expand all
2022 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 2032 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
2023 __ DoubleNegate(XMM0); 2033 __ DoubleNegate(XMM0);
2024 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2034 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
2025 } else { 2035 } else {
2026 UNREACHABLE(); 2036 UNREACHABLE();
2027 } 2037 }
2028 ASSERT(ResultCid() == kDoubleCid); 2038 ASSERT(ResultCid() == kDoubleCid);
2029 } 2039 }
2030 2040
2031 2041
2032 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { 2042 LocationSummary* DoubleToDoubleComp::MakeLocationSummary() const {
2033 const intptr_t kNumInputs = 1; 2043 const intptr_t kNumInputs = 1;
2034 const intptr_t kNumTemps = 1; 2044 const intptr_t kNumTemps = 1;
2035 LocationSummary* locs = 2045 LocationSummary* locs =
2036 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2046 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2037 locs->set_in(0, Location::RequiresRegister()); 2047 locs->set_in(0, Location::RequiresRegister());
2038 locs->set_temp(0, Location::RequiresRegister()); 2048 locs->set_temp(0, Location::RequiresRegister());
2039 locs->set_out(Location::SameAsFirstInput()); 2049 locs->set_out(Location::SameAsFirstInput());
2040 return locs; 2050 return locs;
2041 } 2051 }
2042 2052
2043 2053
2044 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2054 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2045 Register value = locs()->in(0).reg(); 2055 Register value = locs()->in(0).reg();
2046 Register result = locs()->out().reg(); 2056 Register result = locs()->out().reg();
2047 2057
2048 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2058 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2049 kDeoptDoubleToDouble); 2059 kDeoptDoubleToDouble);
2050 Register temp = locs()->temp(0).reg(); 2060 Register temp = locs()->temp(0).reg();
2051 __ testl(value, Immediate(kSmiTagMask)); 2061 __ testl(value, Immediate(kSmiTagMask));
2052 __ j(ZERO, deopt); // Deoptimize if Smi. 2062 __ j(ZERO, deopt); // Deoptimize if Smi.
2053 __ CompareClassId(value, kDoubleCid, temp); 2063 __ CompareClassId(value, kDoubleCid, temp);
2054 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 2064 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
2055 ASSERT(value == result); 2065 ASSERT(value == result);
2056 } 2066 }
2057 2067
2058 2068
2059 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { 2069 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const {
2060 return MakeCallSummary(); // Calls a stub to allocate result. 2070 return MakeCallSummary(); // Calls a stub to allocate result.
2061 } 2071 }
2062 2072
2063 2073
2064 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2074 void SmiToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2065 Register result = locs()->out().reg(); 2075 Register result = locs()->out().reg();
2066 2076
2067 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2077 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2068 kDeoptIntegerToDouble); 2078 kDeoptIntegerToDouble);
2069 2079
2070 const Class& double_class = compiler->double_class(); 2080 const Class& double_class = compiler->double_class();
2071 const Code& stub = 2081 const Code& stub =
2072 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2082 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2073 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2083 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2074 2084
2075 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 2085 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
2076 compiler->GenerateCall(instance_call()->token_pos(), 2086 compiler->GenerateCall(instance_call()->token_pos(),
2077 &label, 2087 &label,
2078 PcDescriptors::kOther, 2088 PcDescriptors::kOther,
2079 locs()); 2089 locs());
2080 ASSERT(result == EAX); 2090 ASSERT(result == EAX);
2081 Register value = EBX; 2091 Register value = EBX;
2082 // Preserve argument on the stack until after the deoptimization point. 2092 // Preserve argument on the stack until after the deoptimization point.
2083 __ movl(value, Address(ESP, 0)); 2093 __ movl(value, Address(ESP, 0));
2084 2094
2085 __ testl(value, Immediate(kSmiTagMask)); 2095 __ testl(value, Immediate(kSmiTagMask));
2086 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 2096 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
2087 __ SmiUntag(value); 2097 __ SmiUntag(value);
2088 __ cvtsi2sd(XMM0, value); 2098 __ cvtsi2sd(XMM0, value);
2089 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2099 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
2090 __ Drop(1); 2100 __ Drop(1);
2091 } 2101 }
2092 2102
2093 2103
2094 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { 2104 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
2095 return MakeCallSummary(); 2105 return MakeCallSummary();
2096 } 2106 }
2097 2107
2098 2108
2099 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2109 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2100 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2110 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2101 kDeoptPolymorphicInstanceCallTestFail); 2111 kDeoptPolymorphicInstanceCallTestFail);
2102 if (ic_data().NumberOfChecks() == 0) { 2112 if (ic_data().NumberOfChecks() == 0) {
2103 __ jmp(deopt); 2113 __ jmp(deopt);
2104 return; 2114 return;
2105 } 2115 }
2106 ASSERT(ic_data().num_args_tested() == 1); 2116 ASSERT(ic_data().num_args_tested() == 1);
2107 if (!with_checks()) { 2117 if (!with_checks()) {
2108 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); 2118 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
2109 compiler->GenerateStaticCall(instance_call()->deopt_id(), 2119 compiler->GenerateStaticCall(instance_call()->deopt_id(),
(...skipping 20 matching lines...) Expand all
2130 EDI, // Class id register. 2140 EDI, // Class id register.
2131 instance_call()->ArgumentCount(), 2141 instance_call()->ArgumentCount(),
2132 instance_call()->argument_names(), 2142 instance_call()->argument_names(),
2133 deopt, 2143 deopt,
2134 instance_call()->deopt_id(), 2144 instance_call()->deopt_id(),
2135 instance_call()->token_pos(), 2145 instance_call()->token_pos(),
2136 locs()); 2146 locs());
2137 } 2147 }
2138 2148
2139 2149
2140 LocationSummary* BranchInstr::MakeLocationSummary() const {
2141 UNREACHABLE();
2142 return NULL;
2143 }
2144
2145
2146 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2150 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2147 comparison()->EmitBranchCode(compiler, this); 2151 computation()->EmitBranchCode(compiler, this);
2148 } 2152 }
2149 2153
2150 2154
2151 LocationSummary* CheckClassInstr::MakeLocationSummary() const { 2155 LocationSummary* CheckClassComp::MakeLocationSummary() const {
2152 const intptr_t kNumInputs = 1; 2156 const intptr_t kNumInputs = 1;
2153 const intptr_t kNumTemps = 1; 2157 const intptr_t kNumTemps = 1;
2154 LocationSummary* summary = 2158 LocationSummary* summary =
2155 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2159 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2156 summary->set_in(0, Location::RequiresRegister()); 2160 summary->set_in(0, Location::RequiresRegister());
2157 summary->set_temp(0, Location::RequiresRegister()); 2161 summary->set_temp(0, Location::RequiresRegister());
2158 return summary; 2162 return summary;
2159 } 2163 }
2160 2164
2161 2165
2162 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2166 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2163 Register value = locs()->in(0).reg(); 2167 Register value = locs()->in(0).reg();
2164 Register temp = locs()->temp(0).reg(); 2168 Register temp = locs()->temp(0).reg();
2165 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2169 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2166 kDeoptCheckClass); 2170 kDeoptCheckClass);
2167 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); 2171 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid);
2168 __ testl(value, Immediate(kSmiTagMask)); 2172 __ testl(value, Immediate(kSmiTagMask));
2169 __ j(ZERO, deopt); 2173 __ j(ZERO, deopt);
2170 __ LoadClassId(temp, value); 2174 __ LoadClassId(temp, value);
2171 Label is_ok; 2175 Label is_ok;
2172 const intptr_t num_checks = unary_checks().NumberOfChecks(); 2176 const intptr_t num_checks = unary_checks().NumberOfChecks();
2173 const bool use_near_jump = num_checks < 5; 2177 const bool use_near_jump = num_checks < 5;
2174 for (intptr_t i = 0; i < num_checks; i++) { 2178 for (intptr_t i = 0; i < num_checks; i++) {
2175 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); 2179 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i)));
2176 if (i == (num_checks - 1)) { 2180 if (i == (num_checks - 1)) {
2177 __ j(NOT_EQUAL, deopt); 2181 __ j(NOT_EQUAL, deopt);
2178 } else { 2182 } else {
2179 if (use_near_jump) { 2183 if (use_near_jump) {
2180 __ j(EQUAL, &is_ok, Assembler::kNearJump); 2184 __ j(EQUAL, &is_ok, Assembler::kNearJump);
2181 } else { 2185 } else {
2182 __ j(EQUAL, &is_ok); 2186 __ j(EQUAL, &is_ok);
2183 } 2187 }
2184 } 2188 }
2185 } 2189 }
2186 __ Bind(&is_ok); 2190 __ Bind(&is_ok);
2187 } 2191 }
2188 2192
2189 2193
2190 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { 2194 LocationSummary* CheckSmiComp::MakeLocationSummary() const {
2191 const intptr_t kNumInputs = 1; 2195 const intptr_t kNumInputs = 1;
2192 const intptr_t kNumTemps = 0; 2196 const intptr_t kNumTemps = 0;
2193 LocationSummary* summary = 2197 LocationSummary* summary =
2194 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2198 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2195 summary->set_in(0, Location::RequiresRegister()); 2199 summary->set_in(0, Location::RequiresRegister());
2196 return summary; 2200 return summary;
2197 } 2201 }
2198 2202
2199 2203
2200 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2204 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2201 Register value = locs()->in(0).reg(); 2205 Register value = locs()->in(0).reg();
2202 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2206 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2203 kDeoptCheckSmi); 2207 kDeoptCheckSmi);
2204 __ testl(value, Immediate(kSmiTagMask)); 2208 __ testl(value, Immediate(kSmiTagMask));
2205 __ j(NOT_ZERO, deopt); 2209 __ j(NOT_ZERO, deopt);
2206 } 2210 }
2207 2211
2208 2212
2209 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { 2213 LocationSummary* CheckArrayBoundComp::MakeLocationSummary() const {
2210 const intptr_t kNumInputs = 2; 2214 const intptr_t kNumInputs = 2;
2211 const intptr_t kNumTemps = 0; 2215 const intptr_t kNumTemps = 0;
2212 LocationSummary* locs = 2216 LocationSummary* locs =
2213 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2214 locs->set_in(0, Location::RequiresRegister()); 2218 locs->set_in(0, Location::RequiresRegister());
2215 locs->set_in(1, Location::RegisterOrConstant(index())); 2219 locs->set_in(1, Location::RegisterOrConstant(index()));
2216 return locs; 2220 return locs;
2217 } 2221 }
2218 2222
2219 2223
2220 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2224 void CheckArrayBoundComp::EmitNativeCode(FlowGraphCompiler* compiler) {
2221 Register receiver = locs()->in(0).reg(); 2225 Register receiver = locs()->in(0).reg();
2222 2226
2223 const DeoptReasonId deopt_reason = 2227 const DeoptReasonId deopt_reason =
2224 (array_type() == kGrowableObjectArrayCid) ? 2228 (array_type() == kGrowableObjectArrayCid) ?
2225 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 2229 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
2226 Label* deopt = compiler->AddDeoptStub(deopt_id(), 2230 Label* deopt = compiler->AddDeoptStub(deopt_id(),
2227 deopt_reason); 2231 deopt_reason);
2228 ASSERT(array_type() == kArrayCid || 2232 ASSERT(array_type() == kArrayCid ||
2229 array_type() == kImmutableArrayCid || 2233 array_type() == kImmutableArrayCid ||
2230 array_type() == kGrowableObjectArrayCid); 2234 array_type() == kGrowableObjectArrayCid);
(...skipping 14 matching lines...) Expand all
2245 __ j(ABOVE_EQUAL, deopt); 2249 __ j(ABOVE_EQUAL, deopt);
2246 } 2250 }
2247 } 2251 }
2248 2252
2249 2253
2250 } // namespace dart 2254 } // namespace dart
2251 2255
2252 #undef __ 2256 #undef __
2253 2257
2254 #endif // defined TARGET_ARCH_X64 2258 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698