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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 RAX. | 26 // on the stack and return the result in a fixed register RAX. |
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(RAX)); | 29 result->set_out(Location::RegisterLocation(RAX)); |
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 __ pushq(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(RAX)); | 47 locs->set_in(0, Location::RegisterLocation(RAX)); |
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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 __ nop(1); | 120 __ nop(1); |
113 __ nop(1); | 121 __ nop(1); |
114 __ nop(1); | 122 __ nop(1); |
115 __ nop(1); | 123 __ nop(1); |
116 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, | 124 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
117 deopt_id(), | 125 deopt_id(), |
118 token_pos()); | 126 token_pos()); |
119 } | 127 } |
120 | 128 |
121 | 129 |
122 LocationSummary* ClosureCallInstr::MakeLocationSummary() const { | 130 LocationSummary* ClosureCallComp::MakeLocationSummary() const { |
123 const intptr_t kNumInputs = 0; | 131 const intptr_t kNumInputs = 0; |
124 const intptr_t kNumTemps = 1; | 132 const intptr_t kNumTemps = 1; |
125 LocationSummary* result = | 133 LocationSummary* result = |
126 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
127 result->set_out(Location::RegisterLocation(RAX)); | 135 result->set_out(Location::RegisterLocation(RAX)); |
128 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. | 136 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
129 return result; | 137 return result; |
130 } | 138 } |
131 | 139 |
132 | 140 |
133 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { | 141 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
134 return LocationSummary::Make(0, | 142 return LocationSummary::Make(0, |
135 Location::RequiresRegister(), | 143 Location::RequiresRegister(), |
136 LocationSummary::kNoCall); | 144 LocationSummary::kNoCall); |
137 } | 145 } |
138 | 146 |
139 | 147 |
140 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 148 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
141 Register result = locs()->out().reg(); | 149 Register result = locs()->out().reg(); |
142 __ movq(result, Address(RBP, local().index() * kWordSize)); | 150 __ movq(result, Address(RBP, local().index() * kWordSize)); |
143 } | 151 } |
144 | 152 |
145 | 153 |
146 LocationSummary* StoreLocalInstr::MakeLocationSummary() const { | 154 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
147 return LocationSummary::Make(1, | 155 return LocationSummary::Make(1, |
148 Location::SameAsFirstInput(), | 156 Location::SameAsFirstInput(), |
149 LocationSummary::kNoCall); | 157 LocationSummary::kNoCall); |
150 } | 158 } |
151 | 159 |
152 | 160 |
153 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 161 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
154 Register value = locs()->in(0).reg(); | 162 Register value = locs()->in(0).reg(); |
155 Register result = locs()->out().reg(); | 163 Register result = locs()->out().reg(); |
156 ASSERT(result == value); // Assert that register assignment is correct. | 164 ASSERT(result == value); // Assert that register assignment is correct. |
157 __ movq(Address(RBP, local().index() * kWordSize), value); | 165 __ movq(Address(RBP, local().index() * kWordSize), value); |
158 } | 166 } |
159 | 167 |
160 | 168 |
161 LocationSummary* ConstantInstr::MakeLocationSummary() const { | 169 LocationSummary* ConstantComp::MakeLocationSummary() const { |
162 return LocationSummary::Make(0, | 170 return LocationSummary::Make(0, |
163 Location::RequiresRegister(), | 171 Location::RequiresRegister(), |
164 LocationSummary::kNoCall); | 172 LocationSummary::kNoCall); |
165 } | 173 } |
166 | 174 |
167 | 175 |
168 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 176 void ConstantComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
169 // The register allocator drops constant definitions that have no uses. | 177 // Register allocator drops constant definitions that have no uses. |
170 if (!locs()->out().IsInvalid()) { | 178 if (!locs()->out().IsInvalid()) { |
171 Register result = locs()->out().reg(); | 179 Register result = locs()->out().reg(); |
172 __ LoadObject(result, value()); | 180 __ LoadObject(result, value()); |
173 } | 181 } |
174 } | 182 } |
175 | 183 |
176 | 184 |
177 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { | 185 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { |
178 const intptr_t kNumInputs = 3; | 186 const intptr_t kNumInputs = 3; |
179 const intptr_t kNumTemps = 0; | 187 const intptr_t kNumTemps = 0; |
180 LocationSummary* summary = | 188 LocationSummary* summary = |
181 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
182 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. | 190 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. |
183 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. | 191 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. |
184 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. | 192 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. |
185 summary->set_out(Location::RegisterLocation(RAX)); | 193 summary->set_out(Location::RegisterLocation(RAX)); |
186 return summary; | 194 return summary; |
187 } | 195 } |
188 | 196 |
189 | 197 |
190 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { | 198 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
191 const intptr_t kNumInputs = 1; | 199 const intptr_t kNumInputs = 1; |
192 const intptr_t kNumTemps = 0; | 200 const intptr_t kNumTemps = 0; |
193 LocationSummary* locs = | 201 LocationSummary* locs = |
194 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 202 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
195 locs->set_in(0, Location::RegisterLocation(RAX)); | 203 locs->set_in(0, Location::RegisterLocation(RAX)); |
196 locs->set_out(Location::RegisterLocation(RAX)); | 204 locs->set_out(Location::RegisterLocation(RAX)); |
197 return locs; | 205 return locs; |
198 } | 206 } |
199 | 207 |
200 | 208 |
201 void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 209 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
202 Register obj = locs()->in(0).reg(); | 210 Register obj = locs()->in(0).reg(); |
203 Register result = locs()->out().reg(); | 211 Register result = locs()->out().reg(); |
204 | 212 |
205 if (!is_eliminated()) { | 213 if (!is_eliminated()) { |
206 // Check that the type of the value is allowed in conditional context. | 214 // Check that the type of the value is allowed in conditional context. |
207 // Call the runtime if the object is not bool::true or bool::false. | 215 // Call the runtime if the object is not bool::true or bool::false. |
208 Label done; | 216 Label done; |
209 __ CompareObject(obj, compiler->bool_true()); | 217 __ CompareObject(obj, compiler->bool_true()); |
210 __ j(EQUAL, &done, Assembler::kNearJump); | 218 __ j(EQUAL, &done, Assembler::kNearJump); |
211 __ CompareObject(obj, compiler->bool_false()); | 219 __ CompareObject(obj, compiler->bool_false()); |
212 __ j(EQUAL, &done, Assembler::kNearJump); | 220 __ j(EQUAL, &done, Assembler::kNearJump); |
213 | 221 |
214 __ pushq(obj); // Push the source object. | 222 __ pushq(obj); // Push the source object. |
215 compiler->GenerateCallRuntime(token_pos(), | 223 compiler->GenerateCallRuntime(token_pos(), |
216 kConditionTypeErrorRuntimeEntry, | 224 kConditionTypeErrorRuntimeEntry, |
217 locs()); | 225 locs()); |
218 // We should never return here. | 226 // We should never return here. |
219 __ int3(); | 227 __ int3(); |
220 __ Bind(&done); | 228 __ Bind(&done); |
221 } | 229 } |
222 ASSERT(obj == result); | 230 ASSERT(obj == result); |
223 } | 231 } |
224 | 232 |
225 | 233 |
226 LocationSummary* ArgumentDefinitionTestInstr::MakeLocationSummary() const { | 234 LocationSummary* ArgumentDefinitionTestComp::MakeLocationSummary() const { |
227 const intptr_t kNumInputs = 1; | 235 const intptr_t kNumInputs = 1; |
228 const intptr_t kNumTemps = 0; | 236 const intptr_t kNumTemps = 0; |
229 LocationSummary* locs = | 237 LocationSummary* locs = |
230 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 238 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
231 locs->set_in(0, Location::RegisterLocation(RAX)); | 239 locs->set_in(0, Location::RegisterLocation(RAX)); |
232 locs->set_out(Location::RegisterLocation(RAX)); | 240 locs->set_out(Location::RegisterLocation(RAX)); |
233 return locs; | 241 return locs; |
234 } | 242 } |
235 | 243 |
236 | 244 |
237 void ArgumentDefinitionTestInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 245 void ArgumentDefinitionTestComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
238 Register saved_args_desc = locs()->in(0).reg(); | 246 Register saved_args_desc = locs()->in(0).reg(); |
239 Register result = locs()->out().reg(); | 247 Register result = locs()->out().reg(); |
240 | 248 |
241 // Push the result place holder initialized to NULL. | 249 // Push the result place holder initialized to NULL. |
242 __ PushObject(Object::ZoneHandle()); | 250 __ PushObject(Object::ZoneHandle()); |
243 __ pushq(Immediate(Smi::RawValue(formal_parameter_index()))); | 251 __ pushq(Immediate(Smi::RawValue(formal_parameter_index()))); |
244 __ PushObject(formal_parameter_name()); | 252 __ PushObject(formal_parameter_name()); |
245 __ pushq(saved_args_desc); | 253 __ pushq(saved_args_desc); |
246 compiler->GenerateCallRuntime(token_pos(), | 254 compiler->GenerateCallRuntime(token_pos(), |
247 kArgumentDefinitionTestRuntimeEntry, | 255 kArgumentDefinitionTestRuntimeEntry, |
(...skipping 11 matching lines...) Expand all Loading... |
259 case Token::kGT: return GREATER; | 267 case Token::kGT: return GREATER; |
260 case Token::kLTE: return LESS_EQUAL; | 268 case Token::kLTE: return LESS_EQUAL; |
261 case Token::kGTE: return GREATER_EQUAL; | 269 case Token::kGTE: return GREATER_EQUAL; |
262 default: | 270 default: |
263 UNREACHABLE(); | 271 UNREACHABLE(); |
264 return OVERFLOW; | 272 return OVERFLOW; |
265 } | 273 } |
266 } | 274 } |
267 | 275 |
268 | 276 |
269 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const { | 277 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
270 const intptr_t kNumInputs = 2; | 278 const intptr_t kNumInputs = 2; |
271 const bool is_checked_strict_equal = | 279 const bool is_checked_strict_equal = |
272 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); | 280 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); |
273 if (receiver_class_id() == kDoubleCid) { | 281 if (receiver_class_id() == kDoubleCid) { |
274 const intptr_t kNumTemps = 0; | 282 const intptr_t kNumTemps = 0; |
275 LocationSummary* locs = | 283 LocationSummary* locs = |
276 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 284 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
277 locs->set_in(0, Location::RequiresXmmRegister()); | 285 locs->set_in(0, Location::RequiresXmmRegister()); |
278 locs->set_in(1, Location::RequiresXmmRegister()); | 286 locs->set_in(1, Location::RequiresXmmRegister()); |
279 locs->set_out(Location::RequiresRegister()); | 287 locs->set_out(Location::RequiresRegister()); |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 if (branch != NULL) { | 620 if (branch != NULL) { |
613 compiler->EmitDoubleCompareBranch( | 621 compiler->EmitDoubleCompareBranch( |
614 true_condition, left, right, branch); | 622 true_condition, left, right, branch); |
615 } else { | 623 } else { |
616 compiler->EmitDoubleCompareBool( | 624 compiler->EmitDoubleCompareBool( |
617 true_condition, left, right, locs.out().reg()); | 625 true_condition, left, right, locs.out().reg()); |
618 } | 626 } |
619 } | 627 } |
620 | 628 |
621 | 629 |
622 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 630 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
623 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); | 631 ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
624 BranchInstr* kNoBranch = NULL; | 632 BranchInstr* kNoBranch = NULL; |
625 if (receiver_class_id() == kSmiCid) { | 633 if (receiver_class_id() == kSmiCid) { |
626 // Deoptimizes if both arguments not Smi. | 634 // Deoptimizes if both arguments not Smi. |
627 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); | 635 EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch); |
628 return; | 636 return; |
629 } | 637 } |
630 if (receiver_class_id() == kDoubleCid) { | 638 if (receiver_class_id() == kDoubleCid) { |
631 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. | 639 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. |
632 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); | 640 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
(...skipping 17 matching lines...) Expand all Loading... |
650 __ pushq(right); | 658 __ pushq(right); |
651 EmitEqualityAsInstanceCall(compiler, | 659 EmitEqualityAsInstanceCall(compiler, |
652 deopt_id(), | 660 deopt_id(), |
653 token_pos(), | 661 token_pos(), |
654 kind(), | 662 kind(), |
655 locs()); | 663 locs()); |
656 ASSERT(locs()->out().reg() == RAX); | 664 ASSERT(locs()->out().reg() == RAX); |
657 } | 665 } |
658 | 666 |
659 | 667 |
660 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 668 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, |
661 BranchInstr* branch) { | 669 BranchInstr* branch) { |
662 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 670 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
663 if (receiver_class_id() == kSmiCid) { | 671 if (receiver_class_id() == kSmiCid) { |
664 // Deoptimizes if both arguments not Smi. | 672 // Deoptimizes if both arguments not Smi. |
665 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 673 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
666 return; | 674 return; |
667 } | 675 } |
668 if (receiver_class_id() == kDoubleCid) { | 676 if (receiver_class_id() == kDoubleCid) { |
669 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. | 677 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. |
670 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 678 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
671 return; | 679 return; |
(...skipping 18 matching lines...) Expand all Loading... |
690 deopt_id(), | 698 deopt_id(), |
691 token_pos(), | 699 token_pos(), |
692 Token::kEQ, // kNE reverse occurs at branch. | 700 Token::kEQ, // kNE reverse occurs at branch. |
693 locs()); | 701 locs()); |
694 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 702 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
695 __ CompareObject(RAX, compiler->bool_true()); | 703 __ CompareObject(RAX, compiler->bool_true()); |
696 branch->EmitBranchOnCondition(compiler, branch_condition); | 704 branch->EmitBranchOnCondition(compiler, branch_condition); |
697 } | 705 } |
698 | 706 |
699 | 707 |
700 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 708 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
701 const intptr_t kNumInputs = 2; | 709 const intptr_t kNumInputs = 2; |
702 if (operands_class_id() == kDoubleCid) { | 710 if (operands_class_id() == kDoubleCid) { |
703 const intptr_t kNumTemps = 0; | 711 const intptr_t kNumTemps = 0; |
704 LocationSummary* summary = | 712 LocationSummary* summary = |
705 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 713 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
706 summary->set_in(0, Location::RequiresXmmRegister()); | 714 summary->set_in(0, Location::RequiresXmmRegister()); |
707 summary->set_in(1, Location::RequiresXmmRegister()); | 715 summary->set_in(1, Location::RequiresXmmRegister()); |
708 summary->set_out(Location::RequiresRegister()); | 716 summary->set_out(Location::RequiresRegister()); |
709 return summary; | 717 return summary; |
710 } else if (operands_class_id() == kSmiCid) { | 718 } else if (operands_class_id() == kSmiCid) { |
(...skipping 10 matching lines...) Expand all Loading... |
721 LocationSummary* locs = | 729 LocationSummary* locs = |
722 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 730 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
723 // Pick arbitrary fixed input registers because this is a call. | 731 // Pick arbitrary fixed input registers because this is a call. |
724 locs->set_in(0, Location::RegisterLocation(RAX)); | 732 locs->set_in(0, Location::RegisterLocation(RAX)); |
725 locs->set_in(1, Location::RegisterLocation(RCX)); | 733 locs->set_in(1, Location::RegisterLocation(RCX)); |
726 locs->set_out(Location::RegisterLocation(RAX)); | 734 locs->set_out(Location::RegisterLocation(RAX)); |
727 return locs; | 735 return locs; |
728 } | 736 } |
729 | 737 |
730 | 738 |
731 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 739 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
732 if (operands_class_id() == kSmiCid) { | 740 if (operands_class_id() == kSmiCid) { |
733 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); | 741 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL); |
734 return; | 742 return; |
735 } | 743 } |
736 if (operands_class_id() == kDoubleCid) { | 744 if (operands_class_id() == kDoubleCid) { |
737 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); | 745 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL); |
738 return; | 746 return; |
739 } | 747 } |
740 | 748 |
741 // Push arguments for the call. | 749 // Push arguments for the call. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 compiler->GenerateInstanceCall(deopt_id(), | 786 compiler->GenerateInstanceCall(deopt_id(), |
779 token_pos(), | 787 token_pos(), |
780 function_name, | 788 function_name, |
781 kNumArguments, | 789 kNumArguments, |
782 Array::ZoneHandle(), // No optional arguments. | 790 Array::ZoneHandle(), // No optional arguments. |
783 kNumArgsChecked, | 791 kNumArgsChecked, |
784 locs()); | 792 locs()); |
785 } | 793 } |
786 | 794 |
787 | 795 |
788 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 796 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, |
789 BranchInstr* branch) { | 797 BranchInstr* branch) { |
790 if (operands_class_id() == kSmiCid) { | 798 if (operands_class_id() == kSmiCid) { |
791 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 799 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
792 return; | 800 return; |
793 } | 801 } |
794 if (operands_class_id() == kDoubleCid) { | 802 if (operands_class_id() == kDoubleCid) { |
795 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 803 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
796 return; | 804 return; |
797 } | 805 } |
798 EmitNativeCode(compiler); | 806 EmitNativeCode(compiler); |
799 __ CompareObject(RAX, compiler->bool_true()); | 807 __ CompareObject(RAX, compiler->bool_true()); |
800 branch->EmitBranchOnCondition(compiler, EQUAL); | 808 branch->EmitBranchOnCondition(compiler, EQUAL); |
801 } | 809 } |
802 | 810 |
803 | 811 |
804 LocationSummary* NativeCallInstr::MakeLocationSummary() const { | 812 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
805 const intptr_t kNumInputs = 0; | 813 const intptr_t kNumInputs = 0; |
806 const intptr_t kNumTemps = 3; | 814 const intptr_t kNumTemps = 3; |
807 LocationSummary* locs = | 815 LocationSummary* locs = |
808 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 816 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
809 locs->set_temp(0, Location::RegisterLocation(RAX)); | 817 locs->set_temp(0, Location::RegisterLocation(RAX)); |
810 locs->set_temp(1, Location::RegisterLocation(RBX)); | 818 locs->set_temp(1, Location::RegisterLocation(RBX)); |
811 locs->set_temp(2, Location::RegisterLocation(R10)); | 819 locs->set_temp(2, Location::RegisterLocation(R10)); |
812 locs->set_out(Location::RegisterLocation(RAX)); | 820 locs->set_out(Location::RegisterLocation(RAX)); |
813 return locs; | 821 return locs; |
814 } | 822 } |
815 | 823 |
816 | 824 |
817 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 825 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
818 ASSERT(locs()->temp(0).reg() == RAX); | 826 ASSERT(locs()->temp(0).reg() == RAX); |
819 ASSERT(locs()->temp(1).reg() == RBX); | 827 ASSERT(locs()->temp(1).reg() == RBX); |
820 ASSERT(locs()->temp(2).reg() == R10); | 828 ASSERT(locs()->temp(2).reg() == R10); |
821 Register result = locs()->out().reg(); | 829 Register result = locs()->out().reg(); |
822 | 830 |
823 // Push the result place holder initialized to NULL. | 831 // Push the result place holder initialized to NULL. |
824 __ PushObject(Object::ZoneHandle()); | 832 __ PushObject(Object::ZoneHandle()); |
825 // Pass a pointer to the first argument in RAX. | 833 // Pass a pointer to the first argument in RAX. |
826 intptr_t arg_count = argument_count(); | 834 intptr_t arg_count = argument_count(); |
827 if (is_native_instance_closure()) { | 835 if (is_native_instance_closure()) { |
828 arg_count += 1; | 836 arg_count += 1; |
829 } | 837 } |
830 if (!has_optional_parameters() && !is_native_instance_closure()) { | 838 if (!has_optional_parameters() && !is_native_instance_closure()) { |
831 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); | 839 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); |
832 } else { | 840 } else { |
833 __ leaq(RAX, | 841 __ leaq(RAX, |
834 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 842 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
835 } | 843 } |
836 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 844 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
837 __ movq(R10, Immediate(arg_count)); | 845 __ movq(R10, Immediate(arg_count)); |
838 compiler->GenerateCall(token_pos(), | 846 compiler->GenerateCall(token_pos(), |
839 &StubCode::CallNativeCFunctionLabel(), | 847 &StubCode::CallNativeCFunctionLabel(), |
840 PcDescriptors::kOther, | 848 PcDescriptors::kOther, |
841 locs()); | 849 locs()); |
842 __ popq(result); | 850 __ popq(result); |
843 } | 851 } |
844 | 852 |
845 | 853 |
846 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 854 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { |
847 const intptr_t kNumInputs = 2; | 855 const intptr_t kNumInputs = 2; |
848 if (receiver_type() == kGrowableObjectArrayCid) { | 856 if (receiver_type() == kGrowableObjectArrayCid) { |
849 const intptr_t kNumTemps = 1; | 857 const intptr_t kNumTemps = 1; |
850 LocationSummary* locs = | 858 LocationSummary* locs = |
851 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 859 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
852 locs->set_in(0, Location::RequiresRegister()); | 860 locs->set_in(0, Location::RequiresRegister()); |
853 locs->set_in(1, Location::RequiresRegister()); | 861 locs->set_in(1, Location::RequiresRegister()); |
854 locs->set_temp(0, Location::RequiresRegister()); | 862 locs->set_temp(0, Location::RequiresRegister()); |
855 locs->set_out(Location::RequiresRegister()); | 863 locs->set_out(Location::RequiresRegister()); |
856 return locs; | 864 return locs; |
857 } else { | 865 } else { |
858 ASSERT((receiver_type() == kArrayCid) || | 866 ASSERT((receiver_type() == kArrayCid) || |
859 (receiver_type() == kImmutableArrayCid)); | 867 (receiver_type() == kImmutableArrayCid)); |
860 return LocationSummary::Make(kNumInputs, | 868 return LocationSummary::Make(kNumInputs, |
861 Location::RequiresRegister(), | 869 Location::RequiresRegister(), |
862 LocationSummary::kNoCall); | 870 LocationSummary::kNoCall); |
863 } | 871 } |
864 } | 872 } |
865 | 873 |
866 | 874 |
867 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 875 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
868 Register receiver = locs()->in(0).reg(); | 876 Register receiver = locs()->in(0).reg(); |
869 Register index = locs()->in(1).reg(); | 877 Register index = locs()->in(1).reg(); |
870 Register result = locs()->out().reg(); | 878 Register result = locs()->out().reg(); |
871 | 879 |
872 switch (receiver_type()) { | 880 switch (receiver_type()) { |
873 case kArrayCid: | 881 case kArrayCid: |
874 case kImmutableArrayCid: | 882 case kImmutableArrayCid: |
875 // Note that index is Smi, i.e, times 4. | 883 // Note that index is Smi, i.e, times 4. |
876 ASSERT(kSmiTagShift == 1); | 884 ASSERT(kSmiTagShift == 1); |
877 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray))); | 885 __ movq(result, FieldAddress(receiver, index, TIMES_4, sizeof(RawArray))); |
878 break; | 886 break; |
879 | 887 |
880 case kGrowableObjectArrayCid: { | 888 case kGrowableObjectArrayCid: { |
881 Register temp = locs()->temp(0).reg(); | 889 Register temp = locs()->temp(0).reg(); |
882 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); | 890 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); |
883 // Note that index is Smi, i.e, times 4. | 891 // Note that index is Smi, i.e, times 4. |
884 ASSERT(kSmiTagShift == 1); | 892 ASSERT(kSmiTagShift == 1); |
885 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray))); | 893 __ movq(result, FieldAddress(temp, index, TIMES_4, sizeof(RawArray))); |
886 break; | 894 break; |
887 } | 895 } |
888 | 896 |
889 default: | 897 default: |
890 UNREACHABLE(); | 898 UNREACHABLE(); |
891 break; | 899 break; |
892 } | 900 } |
893 } | 901 } |
894 | 902 |
895 | 903 |
896 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 904 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
897 const intptr_t kNumInputs = 3; | 905 const intptr_t kNumInputs = 3; |
898 if (receiver_type() == kGrowableObjectArrayCid) { | 906 if (receiver_type() == kGrowableObjectArrayCid) { |
899 const intptr_t kNumTemps = 1; | 907 const intptr_t kNumTemps = 1; |
900 LocationSummary* locs = | 908 LocationSummary* locs = |
901 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 909 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
902 locs->set_in(0, Location::RequiresRegister()); | 910 locs->set_in(0, Location::RequiresRegister()); |
903 locs->set_in(1, Location::RequiresRegister()); | 911 locs->set_in(1, Location::RequiresRegister()); |
904 locs->set_in(2, Location::RequiresRegister()); | 912 locs->set_in(2, Location::RequiresRegister()); |
905 locs->set_temp(0, Location::RequiresRegister()); | 913 locs->set_temp(0, Location::RequiresRegister()); |
906 return locs; | 914 return locs; |
907 } else { | 915 } else { |
908 ASSERT(receiver_type() == kArrayCid); | 916 ASSERT(receiver_type() == kArrayCid); |
909 return LocationSummary::Make(kNumInputs, | 917 return LocationSummary::Make(kNumInputs, |
910 Location::NoLocation(), | 918 Location::NoLocation(), |
911 LocationSummary::kNoCall); | 919 LocationSummary::kNoCall); |
912 } | 920 } |
913 } | 921 } |
914 | 922 |
915 | 923 |
916 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 924 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
917 Register receiver = locs()->in(0).reg(); | 925 Register receiver = locs()->in(0).reg(); |
918 Register index = locs()->in(1).reg(); | 926 Register index = locs()->in(1).reg(); |
919 Register value = locs()->in(2).reg(); | 927 Register value = locs()->in(2).reg(); |
920 | 928 |
921 switch (receiver_type()) { | 929 switch (receiver_type()) { |
922 case kArrayCid: | 930 case kArrayCid: |
923 case kImmutableArrayCid: | 931 case kImmutableArrayCid: |
924 // Note that index is Smi, i.e, times 4. | 932 // Note that index is Smi, i.e, times 4. |
925 ASSERT(kSmiTagShift == 1); | 933 ASSERT(kSmiTagShift == 1); |
926 if (this->value()->NeedsStoreBuffer()) { | 934 if (this->value()->NeedsStoreBuffer()) { |
(...skipping 24 matching lines...) Expand all Loading... |
951 break; | 959 break; |
952 } | 960 } |
953 | 961 |
954 default: | 962 default: |
955 UNREACHABLE(); | 963 UNREACHABLE(); |
956 break; | 964 break; |
957 } | 965 } |
958 } | 966 } |
959 | 967 |
960 | 968 |
961 LocationSummary* LoadInstanceFieldInstr::MakeLocationSummary() const { | 969 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
962 // TODO(fschneider): For this instruction the input register may be | 970 // TODO(fschneider): For this instruction the input register may be |
963 // reused for the result (but is not required to) because the input | 971 // reused for the result (but is not required to) because the input |
964 // is not used after the result is defined. We should consider adding | 972 // is not used after the result is defined. We should consider adding |
965 // this information to the input policy. | 973 // this information to the input policy. |
966 return LocationSummary::Make(1, | 974 return LocationSummary::Make(1, |
967 Location::RequiresRegister(), | 975 Location::RequiresRegister(), |
968 LocationSummary::kNoCall); | 976 LocationSummary::kNoCall); |
969 } | 977 } |
970 | 978 |
971 | 979 |
972 void LoadInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 980 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
973 Register instance_reg = locs()->in(0).reg(); | 981 Register instance_reg = locs()->in(0).reg(); |
974 Register result_reg = locs()->out().reg(); | 982 Register result_reg = locs()->out().reg(); |
975 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); | 983 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); |
976 } | 984 } |
977 | 985 |
978 | 986 |
979 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 987 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
980 const intptr_t kNumInputs = 2; | 988 const intptr_t kNumInputs = 2; |
981 const intptr_t num_temps = 0; | 989 const intptr_t num_temps = 0; |
982 LocationSummary* summary = | 990 LocationSummary* summary = |
983 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); | 991 new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall); |
984 summary->set_in(0, Location::RequiresRegister()); | 992 summary->set_in(0, Location::RequiresRegister()); |
985 summary->set_in(1, Location::RequiresRegister()); | 993 summary->set_in(1, Location::RequiresRegister()); |
986 return summary; | 994 return summary; |
987 } | 995 } |
988 | 996 |
989 | 997 |
990 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 998 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
991 Register instance_reg = locs()->in(0).reg(); | 999 Register instance_reg = locs()->in(0).reg(); |
992 Register value_reg = locs()->in(1).reg(); | 1000 Register value_reg = locs()->in(1).reg(); |
993 if (this->value()->NeedsStoreBuffer()) { | 1001 if (this->value()->NeedsStoreBuffer()) { |
994 __ StoreIntoObject(instance_reg, | 1002 __ StoreIntoObject(instance_reg, |
995 FieldAddress(instance_reg, field().Offset()), value_reg); | 1003 FieldAddress(instance_reg, field().Offset()), value_reg); |
996 } else { | 1004 } else { |
997 __ StoreIntoObjectNoBarrier(instance_reg, | 1005 __ StoreIntoObjectNoBarrier(instance_reg, |
998 FieldAddress(instance_reg, field().Offset()), value_reg); | 1006 FieldAddress(instance_reg, field().Offset()), value_reg); |
999 } | 1007 } |
1000 } | 1008 } |
1001 | 1009 |
1002 | 1010 |
1003 LocationSummary* LoadStaticFieldInstr::MakeLocationSummary() const { | 1011 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
1004 return LocationSummary::Make(0, | 1012 return LocationSummary::Make(0, |
1005 Location::RequiresRegister(), | 1013 Location::RequiresRegister(), |
1006 LocationSummary::kNoCall); | 1014 LocationSummary::kNoCall); |
1007 } | 1015 } |
1008 | 1016 |
1009 | 1017 |
1010 void LoadStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1018 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1011 Register result = locs()->out().reg(); | 1019 Register result = locs()->out().reg(); |
1012 __ LoadObject(result, field()); | 1020 __ LoadObject(result, field()); |
1013 __ movq(result, FieldAddress(result, Field::value_offset())); | 1021 __ movq(result, FieldAddress(result, Field::value_offset())); |
1014 } | 1022 } |
1015 | 1023 |
1016 | 1024 |
1017 LocationSummary* StoreStaticFieldInstr::MakeLocationSummary() const { | 1025 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { |
1018 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); | 1026 LocationSummary* locs = new LocationSummary(1, 1, LocationSummary::kNoCall); |
1019 locs->set_in(0, Location::RequiresRegister()); | 1027 locs->set_in(0, Location::RequiresRegister()); |
1020 locs->set_temp(0, Location::RequiresRegister()); | 1028 locs->set_temp(0, Location::RequiresRegister()); |
1021 locs->set_out(Location::SameAsFirstInput()); | 1029 locs->set_out(Location::SameAsFirstInput()); |
1022 return locs; | 1030 return locs; |
1023 } | 1031 } |
1024 | 1032 |
1025 | 1033 |
1026 void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1034 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1027 Register value = locs()->in(0).reg(); | 1035 Register value = locs()->in(0).reg(); |
1028 Register temp = locs()->temp(0).reg(); | 1036 Register temp = locs()->temp(0).reg(); |
1029 ASSERT(locs()->out().reg() == value); | 1037 ASSERT(locs()->out().reg() == value); |
1030 | 1038 |
1031 __ LoadObject(temp, field()); | 1039 __ LoadObject(temp, field()); |
1032 if (this->value()->NeedsStoreBuffer()) { | 1040 if (this->value()->NeedsStoreBuffer()) { |
1033 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); | 1041 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value); |
1034 } else { | 1042 } else { |
1035 __ StoreIntoObjectNoBarrier( | 1043 __ StoreIntoObjectNoBarrier( |
1036 temp, FieldAddress(temp, Field::value_offset()), value); | 1044 temp, FieldAddress(temp, Field::value_offset()), value); |
1037 } | 1045 } |
1038 } | 1046 } |
1039 | 1047 |
1040 | 1048 |
1041 LocationSummary* InstanceOfInstr::MakeLocationSummary() const { | 1049 LocationSummary* InstanceOfComp::MakeLocationSummary() const { |
1042 const intptr_t kNumInputs = 3; | 1050 const intptr_t kNumInputs = 3; |
1043 const intptr_t kNumTemps = 0; | 1051 const intptr_t kNumTemps = 0; |
1044 LocationSummary* summary = | 1052 LocationSummary* summary = |
1045 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1053 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1046 summary->set_in(0, Location::RegisterLocation(RAX)); | 1054 summary->set_in(0, Location::RegisterLocation(RAX)); |
1047 summary->set_in(1, Location::RegisterLocation(RCX)); | 1055 summary->set_in(1, Location::RegisterLocation(RCX)); |
1048 summary->set_in(2, Location::RegisterLocation(RDX)); | 1056 summary->set_in(2, Location::RegisterLocation(RDX)); |
1049 summary->set_out(Location::RegisterLocation(RAX)); | 1057 summary->set_out(Location::RegisterLocation(RAX)); |
1050 return summary; | 1058 return summary; |
1051 } | 1059 } |
1052 | 1060 |
1053 | 1061 |
1054 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1062 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1055 ASSERT(locs()->in(0).reg() == RAX); // Value. | 1063 ASSERT(locs()->in(0).reg() == RAX); // Value. |
1056 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. | 1064 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. |
1057 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. | 1065 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. |
1058 | 1066 |
1059 compiler->GenerateInstanceOf(token_pos(), | 1067 compiler->GenerateInstanceOf(token_pos(), |
1060 type(), | 1068 type(), |
1061 negate_result(), | 1069 negate_result(), |
1062 locs()); | 1070 locs()); |
1063 ASSERT(locs()->out().reg() == RAX); | 1071 ASSERT(locs()->out().reg() == RAX); |
1064 } | 1072 } |
1065 | 1073 |
1066 | 1074 |
1067 LocationSummary* CreateArrayInstr::MakeLocationSummary() const { | 1075 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
1068 const intptr_t kNumInputs = 1; | 1076 const intptr_t kNumInputs = 1; |
1069 const intptr_t kNumTemps = 0; | 1077 const intptr_t kNumTemps = 0; |
1070 LocationSummary* locs = | 1078 LocationSummary* locs = |
1071 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1079 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1072 locs->set_in(0, Location::RegisterLocation(RBX)); | 1080 locs->set_in(0, Location::RegisterLocation(RBX)); |
1073 locs->set_out(Location::RegisterLocation(RAX)); | 1081 locs->set_out(Location::RegisterLocation(RAX)); |
1074 return locs; | 1082 return locs; |
1075 } | 1083 } |
1076 | 1084 |
1077 | 1085 |
1078 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1086 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1079 // Allocate the array. R10 = length, RBX = element type. | 1087 // Allocate the array. R10 = length, RBX = element type. |
1080 ASSERT(locs()->in(0).reg() == RBX); | 1088 ASSERT(locs()->in(0).reg() == RBX); |
1081 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); | 1089 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); |
1082 compiler->GenerateCall(token_pos(), | 1090 compiler->GenerateCall(token_pos(), |
1083 &StubCode::AllocateArrayLabel(), | 1091 &StubCode::AllocateArrayLabel(), |
1084 PcDescriptors::kOther, | 1092 PcDescriptors::kOther, |
1085 locs()); | 1093 locs()); |
1086 ASSERT(locs()->out().reg() == RAX); | 1094 ASSERT(locs()->out().reg() == RAX); |
1087 | 1095 |
1088 // Pop the element values from the stack into the array. | 1096 // Pop the element values from the stack into the array. |
1089 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); | 1097 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); |
1090 for (int i = ArgumentCount() - 1; i >= 0; --i) { | 1098 for (int i = ArgumentCount() - 1; i >= 0; --i) { |
1091 __ popq(Address(R10, i * kWordSize)); | 1099 __ popq(Address(R10, i * kWordSize)); |
1092 } | 1100 } |
1093 } | 1101 } |
1094 | 1102 |
1095 | 1103 |
1096 LocationSummary* | 1104 LocationSummary* |
1097 AllocateObjectWithBoundsCheckInstr::MakeLocationSummary() const { | 1105 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { |
1098 const intptr_t kNumInputs = 2; | 1106 const intptr_t kNumInputs = 2; |
1099 const intptr_t kNumTemps = 0; | 1107 const intptr_t kNumTemps = 0; |
1100 LocationSummary* locs = | 1108 LocationSummary* locs = |
1101 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1109 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1102 locs->set_in(0, Location::RegisterLocation(RAX)); | 1110 locs->set_in(0, Location::RegisterLocation(RAX)); |
1103 locs->set_in(1, Location::RegisterLocation(RCX)); | 1111 locs->set_in(1, Location::RegisterLocation(RCX)); |
1104 locs->set_out(Location::RegisterLocation(RAX)); | 1112 locs->set_out(Location::RegisterLocation(RAX)); |
1105 return locs; | 1113 return locs; |
1106 } | 1114 } |
1107 | 1115 |
1108 | 1116 |
1109 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode( | 1117 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
1110 FlowGraphCompiler* compiler) { | 1118 FlowGraphCompiler* compiler) { |
1111 const Class& cls = Class::ZoneHandle(constructor().Owner()); | 1119 const Class& cls = Class::ZoneHandle(constructor().Owner()); |
1112 Register type_arguments = locs()->in(0).reg(); | 1120 Register type_arguments = locs()->in(0).reg(); |
1113 Register instantiator_type_arguments = locs()->in(1).reg(); | 1121 Register instantiator_type_arguments = locs()->in(1).reg(); |
1114 Register result = locs()->out().reg(); | 1122 Register result = locs()->out().reg(); |
1115 | 1123 |
1116 // Push the result place holder initialized to NULL. | 1124 // Push the result place holder initialized to NULL. |
1117 __ PushObject(Object::ZoneHandle()); | 1125 __ PushObject(Object::ZoneHandle()); |
1118 __ PushObject(cls); | 1126 __ PushObject(cls); |
1119 __ pushq(type_arguments); | 1127 __ pushq(type_arguments); |
1120 __ pushq(instantiator_type_arguments); | 1128 __ pushq(instantiator_type_arguments); |
1121 compiler->GenerateCallRuntime(token_pos(), | 1129 compiler->GenerateCallRuntime(token_pos(), |
1122 kAllocateObjectWithBoundsCheckRuntimeEntry, | 1130 kAllocateObjectWithBoundsCheckRuntimeEntry, |
1123 locs()); | 1131 locs()); |
1124 // Pop instantiator type arguments, type arguments, and class. | 1132 // Pop instantiator type arguments, type arguments, and class. |
1125 __ Drop(3); | 1133 __ Drop(3); |
1126 __ popq(result); // Pop new instance. | 1134 __ popq(result); // Pop new instance. |
1127 } | 1135 } |
1128 | 1136 |
1129 | 1137 |
1130 LocationSummary* LoadVMFieldInstr::MakeLocationSummary() const { | 1138 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
1131 return LocationSummary::Make(1, | 1139 return LocationSummary::Make(1, |
1132 Location::RequiresRegister(), | 1140 Location::RequiresRegister(), |
1133 LocationSummary::kNoCall); | 1141 LocationSummary::kNoCall); |
1134 } | 1142 } |
1135 | 1143 |
1136 | 1144 |
1137 void LoadVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1145 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1138 Register instance_reg = locs()->in(0).reg(); | 1146 Register instance_reg = locs()->in(0).reg(); |
1139 Register result_reg = locs()->out().reg(); | 1147 Register result_reg = locs()->out().reg(); |
1140 | 1148 |
1141 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1149 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
1142 } | 1150 } |
1143 | 1151 |
1144 | 1152 |
1145 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const { | 1153 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
1146 const intptr_t kNumInputs = 1; | 1154 const intptr_t kNumInputs = 1; |
1147 const intptr_t kNumTemps = 0; | 1155 const intptr_t kNumTemps = 0; |
1148 LocationSummary* locs = | 1156 LocationSummary* locs = |
1149 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1157 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1150 locs->set_in(0, Location::RegisterLocation(RAX)); | 1158 locs->set_in(0, Location::RegisterLocation(RAX)); |
1151 locs->set_out(Location::RegisterLocation(RAX)); | 1159 locs->set_out(Location::RegisterLocation(RAX)); |
1152 return locs; | 1160 return locs; |
1153 } | 1161 } |
1154 | 1162 |
1155 | 1163 |
1156 void InstantiateTypeArgumentsInstr::EmitNativeCode( | 1164 void InstantiateTypeArgumentsComp::EmitNativeCode( |
1157 FlowGraphCompiler* compiler) { | 1165 FlowGraphCompiler* compiler) { |
1158 Register instantiator_reg = locs()->in(0).reg(); | 1166 Register instantiator_reg = locs()->in(0).reg(); |
1159 Register result_reg = locs()->out().reg(); | 1167 Register result_reg = locs()->out().reg(); |
1160 | 1168 |
1161 // 'instantiator_reg' is the instantiator AbstractTypeArguments object | 1169 // 'instantiator_reg' is the instantiator AbstractTypeArguments object |
1162 // (or null). | 1170 // (or null). |
1163 // If the instantiator is null and if the type argument vector | 1171 // If the instantiator is null and if the type argument vector |
1164 // instantiated from null becomes a vector of Dynamic, then use null as | 1172 // instantiated from null becomes a vector of Dynamic, then use null as |
1165 // the type arguments. | 1173 // the type arguments. |
1166 Label type_arguments_instantiated; | 1174 Label type_arguments_instantiated; |
(...skipping 28 matching lines...) Expand all Loading... |
1195 locs()); | 1203 locs()); |
1196 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 1204 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
1197 __ popq(result_reg); // Pop instantiated type arguments. | 1205 __ popq(result_reg); // Pop instantiated type arguments. |
1198 __ Bind(&type_arguments_instantiated); | 1206 __ Bind(&type_arguments_instantiated); |
1199 ASSERT(instantiator_reg == result_reg); | 1207 ASSERT(instantiator_reg == result_reg); |
1200 // 'result_reg': Instantiated type arguments. | 1208 // 'result_reg': Instantiated type arguments. |
1201 } | 1209 } |
1202 | 1210 |
1203 | 1211 |
1204 LocationSummary* | 1212 LocationSummary* |
1205 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const { | 1213 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { |
1206 const intptr_t kNumInputs = 1; | 1214 const intptr_t kNumInputs = 1; |
1207 const intptr_t kNumTemps = 0; | 1215 const intptr_t kNumTemps = 0; |
1208 LocationSummary* locs = | 1216 LocationSummary* locs = |
1209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1217 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1210 locs->set_in(0, Location::RequiresRegister()); | 1218 locs->set_in(0, Location::RequiresRegister()); |
1211 locs->set_out(Location::SameAsFirstInput()); | 1219 locs->set_out(Location::SameAsFirstInput()); |
1212 return locs; | 1220 return locs; |
1213 } | 1221 } |
1214 | 1222 |
1215 | 1223 |
1216 void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( | 1224 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( |
1217 FlowGraphCompiler* compiler) { | 1225 FlowGraphCompiler* compiler) { |
1218 Register instantiator_reg = locs()->in(0).reg(); | 1226 Register instantiator_reg = locs()->in(0).reg(); |
1219 Register result_reg = locs()->out().reg(); | 1227 Register result_reg = locs()->out().reg(); |
1220 ASSERT(instantiator_reg == result_reg); | 1228 ASSERT(instantiator_reg == result_reg); |
1221 | 1229 |
1222 // instantiator_reg is the instantiator type argument vector, i.e. an | 1230 // instantiator_reg is the instantiator type argument vector, i.e. an |
1223 // AbstractTypeArguments object (or null). | 1231 // AbstractTypeArguments object (or null). |
1224 // If the instantiator is null and if the type argument vector | 1232 // If the instantiator is null and if the type argument vector |
1225 // instantiated from null becomes a vector of Dynamic, then use null as | 1233 // instantiated from null becomes a vector of Dynamic, then use null as |
1226 // the type arguments. | 1234 // the type arguments. |
(...skipping 24 matching lines...) Expand all Loading... |
1251 // In the non-factory case, we rely on the allocation stub to | 1259 // In the non-factory case, we rely on the allocation stub to |
1252 // instantiate the type arguments. | 1260 // instantiate the type arguments. |
1253 __ LoadObject(result_reg, type_arguments()); | 1261 __ LoadObject(result_reg, type_arguments()); |
1254 // result_reg: uninstantiated type arguments. | 1262 // result_reg: uninstantiated type arguments. |
1255 __ Bind(&type_arguments_instantiated); | 1263 __ Bind(&type_arguments_instantiated); |
1256 // result_reg: uninstantiated or instantiated type arguments. | 1264 // result_reg: uninstantiated or instantiated type arguments. |
1257 } | 1265 } |
1258 | 1266 |
1259 | 1267 |
1260 LocationSummary* | 1268 LocationSummary* |
1261 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const { | 1269 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { |
1262 const intptr_t kNumInputs = 1; | 1270 const intptr_t kNumInputs = 1; |
1263 const intptr_t kNumTemps = 0; | 1271 const intptr_t kNumTemps = 0; |
1264 LocationSummary* locs = | 1272 LocationSummary* locs = |
1265 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1273 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1266 locs->set_in(0, Location::RequiresRegister()); | 1274 locs->set_in(0, Location::RequiresRegister()); |
1267 locs->set_out(Location::SameAsFirstInput()); | 1275 locs->set_out(Location::SameAsFirstInput()); |
1268 return locs; | 1276 return locs; |
1269 } | 1277 } |
1270 | 1278 |
1271 | 1279 |
1272 void ExtractConstructorInstantiatorInstr::EmitNativeCode( | 1280 void ExtractConstructorInstantiatorComp::EmitNativeCode( |
1273 FlowGraphCompiler* compiler) { | 1281 FlowGraphCompiler* compiler) { |
1274 Register instantiator_reg = locs()->in(0).reg(); | 1282 Register instantiator_reg = locs()->in(0).reg(); |
1275 ASSERT(locs()->out().reg() == instantiator_reg); | 1283 ASSERT(locs()->out().reg() == instantiator_reg); |
1276 | 1284 |
1277 // instantiator_reg is the instantiator AbstractTypeArguments object | 1285 // instantiator_reg is the instantiator AbstractTypeArguments object |
1278 // (or null). If the instantiator is null and if the type argument vector | 1286 // (or null). If the instantiator is null and if the type argument vector |
1279 // instantiated from null becomes a vector of Dynamic, then use null as | 1287 // instantiated from null becomes a vector of Dynamic, then use null as |
1280 // the type arguments and do not pass the instantiator. | 1288 // the type arguments and do not pass the instantiator. |
1281 Label done; | 1289 Label done; |
1282 const intptr_t len = type_arguments().Length(); | 1290 const intptr_t len = type_arguments().Length(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 // The instantiator was used in VisitExtractConstructorTypeArguments as the | 1323 // The instantiator was used in VisitExtractConstructorTypeArguments as the |
1316 // instantiated type arguments, no proper instantiator needed. | 1324 // instantiated type arguments, no proper instantiator needed. |
1317 __ movq(instantiator_reg, | 1325 __ movq(instantiator_reg, |
1318 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1326 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
1319 } | 1327 } |
1320 __ Bind(&done); | 1328 __ Bind(&done); |
1321 // instantiator_reg: instantiator or kNoInstantiator. | 1329 // instantiator_reg: instantiator or kNoInstantiator. |
1322 } | 1330 } |
1323 | 1331 |
1324 | 1332 |
1325 LocationSummary* AllocateContextInstr::MakeLocationSummary() const { | 1333 LocationSummary* AllocateContextComp::MakeLocationSummary() const { |
1326 const intptr_t kNumInputs = 0; | 1334 const intptr_t kNumInputs = 0; |
1327 const intptr_t kNumTemps = 1; | 1335 const intptr_t kNumTemps = 1; |
1328 LocationSummary* locs = | 1336 LocationSummary* locs = |
1329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1337 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1330 locs->set_temp(0, Location::RegisterLocation(R10)); | 1338 locs->set_temp(0, Location::RegisterLocation(R10)); |
1331 locs->set_out(Location::RegisterLocation(RAX)); | 1339 locs->set_out(Location::RegisterLocation(RAX)); |
1332 return locs; | 1340 return locs; |
1333 } | 1341 } |
1334 | 1342 |
1335 | 1343 |
1336 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1344 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1337 ASSERT(locs()->temp(0).reg() == R10); | 1345 ASSERT(locs()->temp(0).reg() == R10); |
1338 ASSERT(locs()->out().reg() == RAX); | 1346 ASSERT(locs()->out().reg() == RAX); |
1339 | 1347 |
1340 __ movq(R10, Immediate(num_context_variables())); | 1348 __ movq(R10, Immediate(num_context_variables())); |
1341 const ExternalLabel label("alloc_context", | 1349 const ExternalLabel label("alloc_context", |
1342 StubCode::AllocateContextEntryPoint()); | 1350 StubCode::AllocateContextEntryPoint()); |
1343 compiler->GenerateCall(token_pos(), | 1351 compiler->GenerateCall(token_pos(), |
1344 &label, | 1352 &label, |
1345 PcDescriptors::kOther, | 1353 PcDescriptors::kOther, |
1346 locs()); | 1354 locs()); |
1347 } | 1355 } |
1348 | 1356 |
1349 | 1357 |
1350 LocationSummary* CloneContextInstr::MakeLocationSummary() const { | 1358 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
1351 const intptr_t kNumInputs = 1; | 1359 const intptr_t kNumInputs = 1; |
1352 const intptr_t kNumTemps = 0; | 1360 const intptr_t kNumTemps = 0; |
1353 LocationSummary* locs = | 1361 LocationSummary* locs = |
1354 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1362 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1355 locs->set_in(0, Location::RegisterLocation(RAX)); | 1363 locs->set_in(0, Location::RegisterLocation(RAX)); |
1356 locs->set_out(Location::RegisterLocation(RAX)); | 1364 locs->set_out(Location::RegisterLocation(RAX)); |
1357 return locs; | 1365 return locs; |
1358 } | 1366 } |
1359 | 1367 |
1360 | 1368 |
1361 void CloneContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1369 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1362 Register context_value = locs()->in(0).reg(); | 1370 Register context_value = locs()->in(0).reg(); |
1363 Register result = locs()->out().reg(); | 1371 Register result = locs()->out().reg(); |
1364 | 1372 |
1365 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1373 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
1366 __ pushq(context_value); | 1374 __ pushq(context_value); |
1367 compiler->GenerateCallRuntime(token_pos(), | 1375 compiler->GenerateCallRuntime(token_pos(), |
1368 kCloneContextRuntimeEntry, | 1376 kCloneContextRuntimeEntry, |
1369 locs()); | 1377 locs()); |
1370 __ popq(result); // Remove argument. | 1378 __ popq(result); // Remove argument. |
1371 __ popq(result); // Get result (cloned context). | 1379 __ popq(result); // Get result (cloned context). |
1372 } | 1380 } |
1373 | 1381 |
1374 | 1382 |
1375 LocationSummary* CatchEntryInstr::MakeLocationSummary() const { | 1383 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
1376 return LocationSummary::Make(0, | 1384 return LocationSummary::Make(0, |
1377 Location::NoLocation(), | 1385 Location::NoLocation(), |
1378 LocationSummary::kNoCall); | 1386 LocationSummary::kNoCall); |
1379 } | 1387 } |
1380 | 1388 |
1381 | 1389 |
1382 // Restore stack and initialize the two exception variables: | 1390 // Restore stack and initialize the two exception variables: |
1383 // exception and stack trace variables. | 1391 // exception and stack trace variables. |
1384 void CatchEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1392 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1385 // Restore RSP from RBP as we are coming from a throw and the code for | 1393 // Restore RSP from RBP as we are coming from a throw and the code for |
1386 // popping arguments has not been run. | 1394 // popping arguments has not been run. |
1387 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 1395 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
1388 ASSERT(locals_space_size >= 0); | 1396 ASSERT(locals_space_size >= 0); |
1389 const intptr_t offset_size = | 1397 const intptr_t offset_size = |
1390 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; | 1398 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
1391 __ leaq(RSP, Address(RBP, offset_size)); | 1399 __ leaq(RSP, Address(RBP, offset_size)); |
1392 | 1400 |
1393 ASSERT(!exception_var().is_captured()); | 1401 ASSERT(!exception_var().is_captured()); |
1394 ASSERT(!stacktrace_var().is_captured()); | 1402 ASSERT(!stacktrace_var().is_captured()); |
1395 __ movq(Address(RBP, exception_var().index() * kWordSize), | 1403 __ movq(Address(RBP, exception_var().index() * kWordSize), |
1396 kExceptionObjectReg); | 1404 kExceptionObjectReg); |
1397 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), | 1405 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), |
1398 kStackTraceObjectReg); | 1406 kStackTraceObjectReg); |
1399 } | 1407 } |
1400 | 1408 |
1401 | 1409 |
1402 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const { | 1410 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { |
1403 const intptr_t kNumInputs = 0; | 1411 const intptr_t kNumInputs = 0; |
1404 const intptr_t kNumTemps = 1; | 1412 const intptr_t kNumTemps = 1; |
1405 LocationSummary* summary = | 1413 LocationSummary* summary = |
1406 new LocationSummary(kNumInputs, | 1414 new LocationSummary(kNumInputs, |
1407 kNumTemps, | 1415 kNumTemps, |
1408 LocationSummary::kCallOnSlowPath); | 1416 LocationSummary::kCallOnSlowPath); |
1409 summary->set_temp(0, Location::RequiresRegister()); | 1417 summary->set_temp(0, Location::RequiresRegister()); |
1410 return summary; | 1418 return summary; |
1411 } | 1419 } |
1412 | 1420 |
1413 | 1421 |
1414 class CheckStackOverflowSlowPath : public SlowPathCode { | 1422 class CheckStackOverflowSlowPath : public SlowPathCode { |
1415 public: | 1423 public: |
1416 explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction) | 1424 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) |
1417 : instruction_(instruction) { } | 1425 : computation_(computation) { } |
1418 | 1426 |
1419 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1427 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
1420 __ Bind(entry_label()); | 1428 __ Bind(entry_label()); |
1421 compiler->SaveLiveRegisters(instruction_->locs()); | 1429 compiler->SaveLiveRegisters(computation_->locs()); |
1422 compiler->GenerateCallRuntime(instruction_->token_pos(), | 1430 compiler->GenerateCallRuntime(computation_->token_pos(), |
1423 kStackOverflowRuntimeEntry, | 1431 kStackOverflowRuntimeEntry, |
1424 instruction_->locs()); | 1432 computation_->locs()); |
1425 compiler->RestoreLiveRegisters(instruction_->locs()); | 1433 compiler->RestoreLiveRegisters(computation_->locs()); |
1426 __ jmp(exit_label()); | 1434 __ jmp(exit_label()); |
1427 } | 1435 } |
1428 | 1436 |
1429 private: | 1437 private: |
1430 CheckStackOverflowInstr* instruction_; | 1438 CheckStackOverflowComp* computation_; |
1431 }; | 1439 }; |
1432 | 1440 |
1433 | 1441 |
1434 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1442 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1435 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); | 1443 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); |
1436 compiler->AddSlowPathCode(slow_path); | 1444 compiler->AddSlowPathCode(slow_path); |
1437 | 1445 |
1438 Register temp = locs()->temp(0).reg(); | 1446 Register temp = locs()->temp(0).reg(); |
1439 // Generate stack overflow check. | 1447 // Generate stack overflow check. |
1440 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); | 1448 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); |
1441 __ cmpq(RSP, Address(temp, 0)); | 1449 __ cmpq(RSP, Address(temp, 0)); |
1442 __ j(BELOW_EQUAL, slow_path->entry_label()); | 1450 __ j(BELOW_EQUAL, slow_path->entry_label()); |
1443 __ Bind(slow_path->exit_label()); | 1451 __ Bind(slow_path->exit_label()); |
1444 } | 1452 } |
1445 | 1453 |
1446 | 1454 |
1447 static bool CanBeImmediate(const Object& constant) { | 1455 static bool CanBeImmediate(const Object& constant) { |
1448 return constant.IsSmi() && | 1456 return constant.IsSmi() && |
1449 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); | 1457 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); |
1450 } | 1458 } |
1451 | 1459 |
1452 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const { | 1460 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const { |
1453 const intptr_t kNumInputs = 2; | 1461 const intptr_t kNumInputs = 2; |
1454 | 1462 |
1455 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 1463 ConstantComp* right_constant = right()->definition()->AsConstant(); |
1456 if ((right_constant != NULL) && | 1464 if ((right_constant != NULL) && |
1457 (op_kind() != Token::kTRUNCDIV) && | 1465 (op_kind() != Token::kTRUNCDIV) && |
1458 (op_kind() != Token::kSHL) && | 1466 (op_kind() != Token::kSHL) && |
1459 (op_kind() != Token::kMUL) && | 1467 (op_kind() != Token::kMUL) && |
1460 CanBeImmediate(right_constant->value())) { | 1468 CanBeImmediate(right_constant->value())) { |
1461 const intptr_t kNumTemps = 0; | 1469 const intptr_t kNumTemps = 0; |
1462 LocationSummary* summary = | 1470 LocationSummary* summary = |
1463 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1471 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1464 summary->set_in(0, Location::RequiresRegister()); | 1472 summary->set_in(0, Location::RequiresRegister()); |
1465 summary->set_in(1, Location::Constant(right_constant->value())); | 1473 summary->set_in(1, Location::Constant(right_constant->value())); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 LocationSummary* summary = | 1511 LocationSummary* summary = |
1504 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1512 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1505 summary->set_in(0, Location::RequiresRegister()); | 1513 summary->set_in(0, Location::RequiresRegister()); |
1506 summary->set_in(1, Location::RequiresRegister()); | 1514 summary->set_in(1, Location::RequiresRegister()); |
1507 summary->set_out(Location::SameAsFirstInput()); | 1515 summary->set_out(Location::SameAsFirstInput()); |
1508 return summary; | 1516 return summary; |
1509 } | 1517 } |
1510 } | 1518 } |
1511 | 1519 |
1512 | 1520 |
1513 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1521 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1514 Register left = locs()->in(0).reg(); | 1522 Register left = locs()->in(0).reg(); |
1515 Register result = locs()->out().reg(); | 1523 Register result = locs()->out().reg(); |
1516 ASSERT(left == result); | 1524 ASSERT(left == result); |
1517 Label* deopt = NULL; | 1525 Label* deopt = NULL; |
1518 switch (op_kind()) { | 1526 switch (op_kind()) { |
1519 case Token::kBIT_AND: | 1527 case Token::kBIT_AND: |
1520 case Token::kBIT_OR: | 1528 case Token::kBIT_OR: |
1521 case Token::kBIT_XOR: | 1529 case Token::kBIT_XOR: |
1522 // Can't deoptimize. Arguments are already checked for smi. | 1530 // Can't deoptimize. Arguments are already checked for smi. |
1523 break; | 1531 break; |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 UNREACHABLE(); | 1726 UNREACHABLE(); |
1719 break; | 1727 break; |
1720 } | 1728 } |
1721 default: | 1729 default: |
1722 UNREACHABLE(); | 1730 UNREACHABLE(); |
1723 break; | 1731 break; |
1724 } | 1732 } |
1725 } | 1733 } |
1726 | 1734 |
1727 | 1735 |
1728 LocationSummary* BinaryMintOpInstr::MakeLocationSummary() const { | 1736 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const { |
1729 ASSERT(op_kind() == Token::kBIT_AND); | 1737 ASSERT(op_kind() == Token::kBIT_AND); |
1730 const intptr_t kNumInputs = 2; | 1738 const intptr_t kNumInputs = 2; |
1731 const intptr_t kNumTemps = 0; | 1739 const intptr_t kNumTemps = 0; |
1732 LocationSummary* summary = | 1740 LocationSummary* summary = |
1733 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1741 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1734 summary->set_in(0, Location::RegisterLocation(RAX)); | 1742 summary->set_in(0, Location::RegisterLocation(RAX)); |
1735 summary->set_in(1, Location::RegisterLocation(RCX)); | 1743 summary->set_in(1, Location::RegisterLocation(RCX)); |
1736 summary->set_out(Location::RegisterLocation(RAX)); | 1744 summary->set_out(Location::RegisterLocation(RAX)); |
1737 return summary; | 1745 return summary; |
1738 } | 1746 } |
1739 | 1747 |
1740 | 1748 |
1741 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1749 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1742 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi | 1750 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi |
1743 // receiver and a Mint or Smi argument. We fall back to the run time call if | 1751 // receiver and a Mint or Smi argument. We fall back to the run time call if |
1744 // both receiver and argument are Mint or if one of them is Mint and the other | 1752 // both receiver and argument are Mint or if one of them is Mint and the other |
1745 // is a negative Smi. | 1753 // is a negative Smi. |
1746 Register left = locs()->in(0).reg(); | 1754 Register left = locs()->in(0).reg(); |
1747 Register right = locs()->in(1).reg(); | 1755 Register right = locs()->in(1).reg(); |
1748 Register result = locs()->out().reg(); | 1756 Register result = locs()->out().reg(); |
1749 ASSERT(left == result); | 1757 ASSERT(left == result); |
1750 ASSERT(op_kind() == Token::kBIT_AND); | 1758 ASSERT(op_kind() == Token::kBIT_AND); |
1751 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1759 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 instance_call()->ArgumentCount(), | 1828 instance_call()->ArgumentCount(), |
1821 instance_call()->argument_names(), | 1829 instance_call()->argument_names(), |
1822 locs()); | 1830 locs()); |
1823 ASSERT(result == RAX); | 1831 ASSERT(result == RAX); |
1824 } | 1832 } |
1825 } | 1833 } |
1826 __ Bind(&done); | 1834 __ Bind(&done); |
1827 } | 1835 } |
1828 | 1836 |
1829 | 1837 |
1830 LocationSummary* CheckEitherNonSmiInstr::MakeLocationSummary() const { | 1838 LocationSummary* CheckEitherNonSmiComp::MakeLocationSummary() const { |
1831 ASSERT((left()->ResultCid() != kDoubleCid) && | 1839 ASSERT((left()->ResultCid() != kDoubleCid) && |
1832 (right()->ResultCid() != kDoubleCid)); | 1840 (right()->ResultCid() != kDoubleCid)); |
1833 const intptr_t kNumInputs = 2; | 1841 const intptr_t kNumInputs = 2; |
1834 const intptr_t kNumTemps = 1; | 1842 const intptr_t kNumTemps = 1; |
1835 LocationSummary* summary = | 1843 LocationSummary* summary = |
1836 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1844 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1837 summary->set_in(0, Location::RequiresRegister()); | 1845 summary->set_in(0, Location::RequiresRegister()); |
1838 summary->set_in(1, Location::RequiresRegister()); | 1846 summary->set_in(1, Location::RequiresRegister()); |
1839 summary->set_temp(0, Location::RequiresRegister()); | 1847 summary->set_temp(0, Location::RequiresRegister()); |
1840 return summary; | 1848 return summary; |
1841 } | 1849 } |
1842 | 1850 |
1843 | 1851 |
1844 void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1852 void CheckEitherNonSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1845 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryDoubleOp); | 1853 Label* deopt = compiler->AddDeoptStub(instance_call_->deopt_id(), |
| 1854 kDeoptBinaryDoubleOp); |
| 1855 |
1846 Register temp = locs()->temp(0).reg(); | 1856 Register temp = locs()->temp(0).reg(); |
1847 __ movq(temp, locs()->in(0).reg()); | 1857 __ movq(temp, locs()->in(0).reg()); |
1848 __ orq(temp, locs()->in(1).reg()); | 1858 __ orq(temp, locs()->in(1).reg()); |
1849 __ testl(temp, Immediate(kSmiTagMask)); | 1859 __ testl(temp, Immediate(kSmiTagMask)); |
1850 __ j(ZERO, deopt); | 1860 __ j(ZERO, deopt); |
1851 } | 1861 } |
1852 | 1862 |
1853 | 1863 |
1854 LocationSummary* BoxDoubleInstr::MakeLocationSummary() const { | 1864 LocationSummary* BoxDoubleComp::MakeLocationSummary() const { |
1855 const intptr_t kNumInputs = 1; | 1865 const intptr_t kNumInputs = 1; |
1856 const intptr_t kNumTemps = 0; | 1866 const intptr_t kNumTemps = 0; |
1857 LocationSummary* summary = | 1867 LocationSummary* summary = |
1858 new LocationSummary(kNumInputs, | 1868 new LocationSummary(kNumInputs, |
1859 kNumTemps, | 1869 kNumTemps, |
1860 LocationSummary::kCallOnSlowPath); | 1870 LocationSummary::kCallOnSlowPath); |
1861 summary->set_in(0, Location::RequiresXmmRegister()); | 1871 summary->set_in(0, Location::RequiresXmmRegister()); |
1862 summary->set_out(Location::RequiresRegister()); | 1872 summary->set_out(Location::RequiresRegister()); |
1863 return summary; | 1873 return summary; |
1864 } | 1874 } |
1865 | 1875 |
1866 | 1876 |
1867 class BoxDoubleSlowPath : public SlowPathCode { | 1877 class BoxDoubleSlowPath : public SlowPathCode { |
1868 public: | 1878 public: |
1869 explicit BoxDoubleSlowPath(BoxDoubleInstr* instruction) | 1879 explicit BoxDoubleSlowPath(BoxDoubleComp* computation) |
1870 : instruction_(instruction) { } | 1880 : computation_(computation) { } |
1871 | 1881 |
1872 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 1882 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
1873 __ Bind(entry_label()); | 1883 __ Bind(entry_label()); |
1874 const Class& double_class = compiler->double_class(); | 1884 const Class& double_class = compiler->double_class(); |
1875 const Code& stub = | 1885 const Code& stub = |
1876 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1886 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
1877 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1887 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
1878 | 1888 |
1879 LocationSummary* locs = instruction_->locs(); | 1889 LocationSummary* locs = computation_->locs(); |
1880 locs->live_registers()->Remove(locs->out()); | 1890 locs->live_registers()->Remove(locs->out()); |
1881 | 1891 |
1882 compiler->SaveLiveRegisters(locs); | 1892 compiler->SaveLiveRegisters(locs); |
1883 compiler->GenerateCall(instruction_->token_pos(), | 1893 compiler->GenerateCall(computation_->token_pos(), |
1884 &label, | 1894 &label, |
1885 PcDescriptors::kOther, | 1895 PcDescriptors::kOther, |
1886 locs); | 1896 locs); |
1887 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); | 1897 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); |
1888 compiler->RestoreLiveRegisters(locs); | 1898 compiler->RestoreLiveRegisters(locs); |
1889 | 1899 |
1890 __ jmp(exit_label()); | 1900 __ jmp(exit_label()); |
1891 } | 1901 } |
1892 | 1902 |
1893 private: | 1903 private: |
1894 BoxDoubleInstr* instruction_; | 1904 BoxDoubleComp* computation_; |
1895 }; | 1905 }; |
1896 | 1906 |
1897 | 1907 |
1898 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1908 void BoxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1899 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); | 1909 BoxDoubleSlowPath* slow_path = new BoxDoubleSlowPath(this); |
1900 compiler->AddSlowPathCode(slow_path); | 1910 compiler->AddSlowPathCode(slow_path); |
1901 | 1911 |
1902 Register out_reg = locs()->out().reg(); | 1912 Register out_reg = locs()->out().reg(); |
1903 XmmRegister value = locs()->in(0).xmm_reg(); | 1913 XmmRegister value = locs()->in(0).xmm_reg(); |
1904 | 1914 |
1905 AssemblerMacros::TryAllocate(compiler->assembler(), | 1915 AssemblerMacros::TryAllocate(compiler->assembler(), |
1906 compiler->double_class(), | 1916 compiler->double_class(), |
1907 slow_path->entry_label(), | 1917 slow_path->entry_label(), |
1908 Assembler::kFarJump, | 1918 Assembler::kFarJump, |
1909 out_reg); | 1919 out_reg); |
1910 __ Bind(slow_path->exit_label()); | 1920 __ Bind(slow_path->exit_label()); |
1911 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 1921 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
1912 } | 1922 } |
1913 | 1923 |
1914 | 1924 |
1915 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 1925 LocationSummary* UnboxDoubleComp::MakeLocationSummary() const { |
1916 const intptr_t v_cid = value()->ResultCid(); | 1926 const intptr_t v_cid = value()->ResultCid(); |
1917 | 1927 |
1918 const intptr_t kNumInputs = 1; | 1928 const intptr_t kNumInputs = 1; |
1919 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; | 1929 const intptr_t kNumTemps = (v_cid != kDoubleCid) ? 1 : 0; |
1920 LocationSummary* summary = | 1930 LocationSummary* summary = |
1921 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1931 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1922 summary->set_in(0, Location::RequiresRegister()); | 1932 summary->set_in(0, Location::RequiresRegister()); |
1923 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); | 1933 if (v_cid != kDoubleCid) summary->set_temp(0, Location::RequiresRegister()); |
1924 summary->set_out(Location::RequiresXmmRegister()); | 1934 summary->set_out(Location::RequiresXmmRegister()); |
1925 return summary; | 1935 return summary; |
1926 } | 1936 } |
1927 | 1937 |
1928 | 1938 |
1929 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1939 void UnboxDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1930 const intptr_t v_cid = value()->ResultCid(); | 1940 const intptr_t v_cid = value()->ResultCid(); |
1931 | 1941 |
1932 const Register value = locs()->in(0).reg(); | 1942 const Register value = locs()->in(0).reg(); |
1933 const XmmRegister result = locs()->out().xmm_reg(); | 1943 const XmmRegister result = locs()->out().xmm_reg(); |
1934 if (v_cid != kDoubleCid) { | 1944 if (v_cid != kDoubleCid) { |
1935 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 1945 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); |
1936 compiler->LoadDoubleOrSmiToXmm(result, | 1946 compiler->LoadDoubleOrSmiToXmm(result, |
1937 value, | 1947 value, |
1938 locs()->temp(0).reg(), | 1948 locs()->temp(0).reg(), |
1939 deopt); | 1949 deopt); |
1940 } else { | 1950 } else { |
1941 __ movsd(result, FieldAddress(value, Double::value_offset())); | 1951 __ movsd(result, FieldAddress(value, Double::value_offset())); |
1942 } | 1952 } |
1943 } | 1953 } |
1944 | 1954 |
1945 | 1955 |
1946 LocationSummary* UnboxedDoubleBinaryOpInstr::MakeLocationSummary() const { | 1956 LocationSummary* UnboxedDoubleBinaryOpComp::MakeLocationSummary() const { |
1947 const intptr_t kNumInputs = 2; | 1957 const intptr_t kNumInputs = 2; |
1948 const intptr_t kNumTemps = 0; | 1958 const intptr_t kNumTemps = 0; |
1949 LocationSummary* summary = | 1959 LocationSummary* summary = |
1950 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1960 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1951 summary->set_in(0, Location::RequiresXmmRegister()); | 1961 summary->set_in(0, Location::RequiresXmmRegister()); |
1952 summary->set_in(1, Location::RequiresXmmRegister()); | 1962 summary->set_in(1, Location::RequiresXmmRegister()); |
1953 summary->set_out(Location::SameAsFirstInput()); | 1963 summary->set_out(Location::SameAsFirstInput()); |
1954 return summary; | 1964 return summary; |
1955 } | 1965 } |
1956 | 1966 |
1957 | 1967 |
1958 void UnboxedDoubleBinaryOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1968 void UnboxedDoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1959 XmmRegister left = locs()->in(0).xmm_reg(); | 1969 XmmRegister left = locs()->in(0).xmm_reg(); |
1960 XmmRegister right = locs()->in(1).xmm_reg(); | 1970 XmmRegister right = locs()->in(1).xmm_reg(); |
1961 | 1971 |
1962 ASSERT(locs()->out().xmm_reg() == left); | 1972 ASSERT(locs()->out().xmm_reg() == left); |
1963 | 1973 |
1964 switch (op_kind()) { | 1974 switch (op_kind()) { |
1965 case Token::kADD: __ addsd(left, right); break; | 1975 case Token::kADD: __ addsd(left, right); break; |
1966 case Token::kSUB: __ subsd(left, right); break; | 1976 case Token::kSUB: __ subsd(left, right); break; |
1967 case Token::kMUL: __ mulsd(left, right); break; | 1977 case Token::kMUL: __ mulsd(left, right); break; |
1968 case Token::kDIV: __ divsd(left, right); break; | 1978 case Token::kDIV: __ divsd(left, right); break; |
1969 default: UNREACHABLE(); | 1979 default: UNREACHABLE(); |
1970 } | 1980 } |
1971 } | 1981 } |
1972 | 1982 |
1973 | 1983 |
1974 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 1984 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
1975 const intptr_t kNumInputs = 1; | 1985 const intptr_t kNumInputs = 1; |
1976 const intptr_t kNumTemps = 0; | 1986 const intptr_t kNumTemps = 0; |
1977 LocationSummary* summary = | 1987 LocationSummary* summary = |
1978 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1988 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1979 summary->set_in(0, Location::RequiresRegister()); | 1989 summary->set_in(0, Location::RequiresRegister()); |
1980 summary->set_out(Location::SameAsFirstInput()); | 1990 summary->set_out(Location::SameAsFirstInput()); |
1981 return summary; | 1991 return summary; |
1982 } | 1992 } |
1983 | 1993 |
1984 | 1994 |
1985 void UnarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1995 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1986 Register value = locs()->in(0).reg(); | 1996 Register value = locs()->in(0).reg(); |
1987 ASSERT(value == locs()->out().reg()); | 1997 ASSERT(value == locs()->out().reg()); |
1988 switch (op_kind()) { | 1998 switch (op_kind()) { |
1989 case Token::kNEGATE: { | 1999 case Token::kNEGATE: { |
1990 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2000 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
1991 kDeoptUnaryOp); | 2001 kDeoptUnaryOp); |
1992 __ negq(value); | 2002 __ negq(value); |
1993 __ j(OVERFLOW, deopt); | 2003 __ j(OVERFLOW, deopt); |
1994 break; | 2004 break; |
1995 } | 2005 } |
1996 case Token::kBIT_NOT: | 2006 case Token::kBIT_NOT: |
1997 __ notq(value); | 2007 __ notq(value); |
1998 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. | 2008 __ andq(value, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. |
1999 break; | 2009 break; |
2000 default: | 2010 default: |
2001 UNREACHABLE(); | 2011 UNREACHABLE(); |
2002 } | 2012 } |
2003 } | 2013 } |
2004 | 2014 |
2005 | 2015 |
2006 LocationSummary* NumberNegateInstr::MakeLocationSummary() const { | 2016 LocationSummary* NumberNegateComp::MakeLocationSummary() const { |
2007 const intptr_t kNumInputs = 1; | 2017 const intptr_t kNumInputs = 1; |
2008 const intptr_t kNumTemps = 1; // Needed for doubles. | 2018 const intptr_t kNumTemps = 1; // Needed for doubles. |
2009 LocationSummary* summary = | 2019 LocationSummary* summary = |
2010 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 2020 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
2011 summary->set_in(0, Location::RegisterLocation(RAX)); | 2021 summary->set_in(0, Location::RegisterLocation(RAX)); |
2012 summary->set_out(Location::RegisterLocation(RAX)); | 2022 summary->set_out(Location::RegisterLocation(RAX)); |
2013 summary->set_temp(0, Location::RegisterLocation(RCX)); | 2023 summary->set_temp(0, Location::RegisterLocation(RCX)); |
2014 return summary; | 2024 return summary; |
2015 } | 2025 } |
2016 | 2026 |
2017 | 2027 |
2018 void NumberNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2028 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2019 const ICData& ic_data = *instance_call()->ic_data(); | 2029 const ICData& ic_data = *instance_call()->ic_data(); |
2020 ASSERT(!ic_data.IsNull()); | 2030 ASSERT(!ic_data.IsNull()); |
2021 ASSERT(ic_data.num_args_tested() == 1); | 2031 ASSERT(ic_data.num_args_tested() == 1); |
2022 | 2032 |
2023 // TODO(srdjan): Implement for more checks. | 2033 // TODO(srdjan): Implement for more checks. |
2024 ASSERT(ic_data.NumberOfChecks() == 1); | 2034 ASSERT(ic_data.NumberOfChecks() == 1); |
2025 intptr_t test_class_id; | 2035 intptr_t test_class_id; |
2026 Function& target = Function::Handle(); | 2036 Function& target = Function::Handle(); |
2027 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); | 2037 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); |
2028 | 2038 |
(...skipping 25 matching lines...) Expand all Loading... |
2054 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 2064 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
2055 __ DoubleNegate(XMM0); | 2065 __ DoubleNegate(XMM0); |
2056 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 2066 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
2057 } else { | 2067 } else { |
2058 UNREACHABLE(); | 2068 UNREACHABLE(); |
2059 } | 2069 } |
2060 ASSERT(ResultCid() == kDoubleCid); | 2070 ASSERT(ResultCid() == kDoubleCid); |
2061 } | 2071 } |
2062 | 2072 |
2063 | 2073 |
2064 LocationSummary* DoubleToDoubleInstr::MakeLocationSummary() const { | 2074 LocationSummary* DoubleToDoubleComp::MakeLocationSummary() const { |
2065 const intptr_t kNumInputs = 1; | 2075 const intptr_t kNumInputs = 1; |
2066 const intptr_t kNumTemps = 0; | 2076 const intptr_t kNumTemps = 0; |
2067 LocationSummary* locs = | 2077 LocationSummary* locs = |
2068 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2078 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2069 locs->set_in(0, Location::RequiresRegister()); | 2079 locs->set_in(0, Location::RequiresRegister()); |
2070 locs->set_out(Location::SameAsFirstInput()); | 2080 locs->set_out(Location::SameAsFirstInput()); |
2071 return locs; | 2081 return locs; |
2072 } | 2082 } |
2073 | 2083 |
2074 | 2084 |
2075 void DoubleToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2085 void DoubleToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2076 Register value = locs()->in(0).reg(); | 2086 Register value = locs()->in(0).reg(); |
2077 Register result = locs()->out().reg(); | 2087 Register result = locs()->out().reg(); |
2078 | 2088 |
2079 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2089 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
2080 kDeoptDoubleToDouble); | 2090 kDeoptDoubleToDouble); |
2081 | 2091 |
2082 __ testq(value, Immediate(kSmiTagMask)); | 2092 __ testq(value, Immediate(kSmiTagMask)); |
2083 __ j(ZERO, deopt); // Deoptimize if Smi. | 2093 __ j(ZERO, deopt); // Deoptimize if Smi. |
2084 __ CompareClassId(value, kDoubleCid); | 2094 __ CompareClassId(value, kDoubleCid); |
2085 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. | 2095 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. |
2086 ASSERT(value == result); | 2096 ASSERT(value == result); |
2087 } | 2097 } |
2088 | 2098 |
2089 | 2099 |
2090 LocationSummary* SmiToDoubleInstr::MakeLocationSummary() const { | 2100 LocationSummary* SmiToDoubleComp::MakeLocationSummary() const { |
2091 return MakeCallSummary(); // Calls a stub to allocate result. | 2101 return MakeCallSummary(); // Calls a stub to allocate result. |
2092 } | 2102 } |
2093 | 2103 |
2094 | 2104 |
2095 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2105 void SmiToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2096 Register result = locs()->out().reg(); | 2106 Register result = locs()->out().reg(); |
2097 | 2107 |
2098 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2108 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
2099 kDeoptIntegerToDouble); | 2109 kDeoptIntegerToDouble); |
2100 | 2110 |
2101 const Class& double_class = compiler->double_class(); | 2111 const Class& double_class = compiler->double_class(); |
2102 const Code& stub = | 2112 const Code& stub = |
2103 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 2113 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
2104 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 2114 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
2105 | 2115 |
(...skipping 10 matching lines...) Expand all Loading... |
2116 | 2126 |
2117 __ testq(value, Immediate(kSmiTagMask)); | 2127 __ testq(value, Immediate(kSmiTagMask)); |
2118 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. | 2128 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. |
2119 __ SmiUntag(value); | 2129 __ SmiUntag(value); |
2120 __ cvtsi2sd(XMM0, value); | 2130 __ cvtsi2sd(XMM0, value); |
2121 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 2131 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
2122 __ Drop(1); | 2132 __ Drop(1); |
2123 } | 2133 } |
2124 | 2134 |
2125 | 2135 |
2126 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 2136 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { |
2127 return MakeCallSummary(); | 2137 return MakeCallSummary(); |
2128 } | 2138 } |
2129 | 2139 |
2130 | 2140 |
2131 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2141 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2132 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 2142 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
2133 kDeoptPolymorphicInstanceCallTestFail); | 2143 kDeoptPolymorphicInstanceCallTestFail); |
2134 if (ic_data().NumberOfChecks() == 0) { | 2144 if (ic_data().NumberOfChecks() == 0) { |
2135 __ jmp(deopt); | 2145 __ jmp(deopt); |
2136 return; | 2146 return; |
2137 } | 2147 } |
2138 ASSERT(ic_data().num_args_tested() == 1); | 2148 ASSERT(ic_data().num_args_tested() == 1); |
2139 if (!with_checks()) { | 2149 if (!with_checks()) { |
2140 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); | 2150 const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0)); |
2141 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 2151 compiler->GenerateStaticCall(instance_call()->deopt_id(), |
(...skipping 18 matching lines...) Expand all Loading... |
2160 RDI, // Class id register. | 2170 RDI, // Class id register. |
2161 instance_call()->ArgumentCount(), | 2171 instance_call()->ArgumentCount(), |
2162 instance_call()->argument_names(), | 2172 instance_call()->argument_names(), |
2163 deopt, | 2173 deopt, |
2164 instance_call()->deopt_id(), | 2174 instance_call()->deopt_id(), |
2165 instance_call()->token_pos(), | 2175 instance_call()->token_pos(), |
2166 locs()); | 2176 locs()); |
2167 } | 2177 } |
2168 | 2178 |
2169 | 2179 |
2170 LocationSummary* BranchInstr::MakeLocationSummary() const { | |
2171 UNREACHABLE(); | |
2172 return NULL; | |
2173 } | |
2174 | |
2175 | |
2176 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2180 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2177 comparison()->EmitBranchCode(compiler, this); | 2181 computation()->EmitBranchCode(compiler, this); |
2178 } | 2182 } |
2179 | 2183 |
2180 | 2184 |
2181 LocationSummary* CheckClassInstr::MakeLocationSummary() const { | 2185 LocationSummary* CheckClassComp::MakeLocationSummary() const { |
2182 const intptr_t kNumInputs = 1; | 2186 const intptr_t kNumInputs = 1; |
2183 const intptr_t kNumTemps = 1; | 2187 const intptr_t kNumTemps = 1; |
2184 LocationSummary* summary = | 2188 LocationSummary* summary = |
2185 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2189 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2186 summary->set_in(0, Location::RequiresRegister()); | 2190 summary->set_in(0, Location::RequiresRegister()); |
2187 summary->set_temp(0, Location::RequiresRegister()); | 2191 summary->set_temp(0, Location::RequiresRegister()); |
2188 return summary; | 2192 return summary; |
2189 } | 2193 } |
2190 | 2194 |
2191 | 2195 |
2192 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2196 void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2193 Register value = locs()->in(0).reg(); | 2197 Register value = locs()->in(0).reg(); |
2194 Register temp = locs()->temp(0).reg(); | 2198 Register temp = locs()->temp(0).reg(); |
2195 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2199 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
2196 kDeoptCheckClass); | 2200 kDeoptCheckClass); |
2197 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); | 2201 ASSERT(unary_checks().GetReceiverClassIdAt(0) != kSmiCid); |
2198 __ testq(value, Immediate(kSmiTagMask)); | 2202 __ testq(value, Immediate(kSmiTagMask)); |
2199 __ j(ZERO, deopt); | 2203 __ j(ZERO, deopt); |
2200 __ LoadClassId(temp, value); | 2204 __ LoadClassId(temp, value); |
2201 Label is_ok; | 2205 Label is_ok; |
2202 const intptr_t num_checks = unary_checks().NumberOfChecks(); | 2206 const intptr_t num_checks = unary_checks().NumberOfChecks(); |
2203 const bool use_near_jump = num_checks < 5; | 2207 const bool use_near_jump = num_checks < 5; |
2204 for (intptr_t i = 0; i < num_checks; i++) { | 2208 for (intptr_t i = 0; i < num_checks; i++) { |
2205 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); | 2209 __ cmpl(temp, Immediate(unary_checks().GetReceiverClassIdAt(i))); |
2206 if (i == (num_checks - 1)) { | 2210 if (i == (num_checks - 1)) { |
2207 __ j(NOT_EQUAL, deopt); | 2211 __ j(NOT_EQUAL, deopt); |
2208 } else { | 2212 } else { |
2209 if (use_near_jump) { | 2213 if (use_near_jump) { |
2210 __ j(EQUAL, &is_ok, Assembler::kNearJump); | 2214 __ j(EQUAL, &is_ok, Assembler::kNearJump); |
2211 } else { | 2215 } else { |
2212 __ j(EQUAL, &is_ok); | 2216 __ j(EQUAL, &is_ok); |
2213 } | 2217 } |
2214 } | 2218 } |
2215 } | 2219 } |
2216 __ Bind(&is_ok); | 2220 __ Bind(&is_ok); |
2217 } | 2221 } |
2218 | 2222 |
2219 | 2223 |
2220 LocationSummary* CheckSmiInstr::MakeLocationSummary() const { | 2224 LocationSummary* CheckSmiComp::MakeLocationSummary() const { |
2221 const intptr_t kNumInputs = 1; | 2225 const intptr_t kNumInputs = 1; |
2222 const intptr_t kNumTemps = 0; | 2226 const intptr_t kNumTemps = 0; |
2223 LocationSummary* summary = | 2227 LocationSummary* summary = |
2224 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2228 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2225 summary->set_in(0, Location::RequiresRegister()); | 2229 summary->set_in(0, Location::RequiresRegister()); |
2226 return summary; | 2230 return summary; |
2227 } | 2231 } |
2228 | 2232 |
2229 | 2233 |
2230 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2234 void CheckSmiComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2231 Register value = locs()->in(0).reg(); | 2235 Register value = locs()->in(0).reg(); |
2232 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2236 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
2233 kDeoptCheckSmi); | 2237 kDeoptCheckSmi); |
2234 __ testq(value, Immediate(kSmiTagMask)); | 2238 __ testq(value, Immediate(kSmiTagMask)); |
2235 __ j(NOT_ZERO, deopt); | 2239 __ j(NOT_ZERO, deopt); |
2236 } | 2240 } |
2237 | 2241 |
2238 | 2242 |
2239 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const { | 2243 LocationSummary* CheckArrayBoundComp::MakeLocationSummary() const { |
2240 const intptr_t kNumInputs = 2; | 2244 const intptr_t kNumInputs = 2; |
2241 const intptr_t kNumTemps = 0; | 2245 const intptr_t kNumTemps = 0; |
2242 LocationSummary* locs = | 2246 LocationSummary* locs = |
2243 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2247 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2244 locs->set_in(0, Location::RequiresRegister()); | 2248 locs->set_in(0, Location::RequiresRegister()); |
2245 locs->set_in(1, Location::RegisterOrConstant(index())); | 2249 locs->set_in(1, Location::RegisterOrConstant(index())); |
2246 return locs; | 2250 return locs; |
2247 } | 2251 } |
2248 | 2252 |
2249 | 2253 |
2250 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2254 void CheckArrayBoundComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
2251 Register receiver = locs()->in(0).reg(); | 2255 Register receiver = locs()->in(0).reg(); |
2252 | 2256 |
2253 const DeoptReasonId deopt_reason = | 2257 const DeoptReasonId deopt_reason = |
2254 (array_type() == kGrowableObjectArrayCid) ? | 2258 (array_type() == kGrowableObjectArrayCid) ? |
2255 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 2259 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
2256 Label* deopt = compiler->AddDeoptStub(deopt_id(), | 2260 Label* deopt = compiler->AddDeoptStub(deopt_id(), |
2257 deopt_reason); | 2261 deopt_reason); |
2258 ASSERT(array_type() == kArrayCid || | 2262 ASSERT(array_type() == kArrayCid || |
2259 array_type() == kImmutableArrayCid || | 2263 array_type() == kImmutableArrayCid || |
2260 array_type() == kGrowableObjectArrayCid); | 2264 array_type() == kGrowableObjectArrayCid); |
(...skipping 14 matching lines...) Expand all Loading... |
2275 __ j(ABOVE_EQUAL, deopt); | 2279 __ j(ABOVE_EQUAL, deopt); |
2276 } | 2280 } |
2277 } | 2281 } |
2278 | 2282 |
2279 | 2283 |
2280 } // namespace dart | 2284 } // namespace dart |
2281 | 2285 |
2282 #undef __ | 2286 #undef __ |
2283 | 2287 |
2284 #endif // defined TARGET_ARCH_X64 | 2288 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |