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