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