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" |
(...skipping 28 matching lines...) Expand all Loading... |
39 // instructions from the graph so we just leave fused comparison in it | 39 // instructions from the graph so we just leave fused comparison in it |
40 // but change its result location to be NoLocation. | 40 // but change its result location to be NoLocation. |
41 compiler->frame_register_allocator()->Push(locs()->out().reg(), this); | 41 compiler->frame_register_allocator()->Push(locs()->out().reg(), this); |
42 } | 42 } |
43 } | 43 } |
44 | 44 |
45 | 45 |
46 LocationSummary* ReturnInstr::MakeLocationSummary() const { | 46 LocationSummary* ReturnInstr::MakeLocationSummary() const { |
47 const intptr_t kNumInputs = 1; | 47 const intptr_t kNumInputs = 1; |
48 const intptr_t kNumTemps = 1; | 48 const intptr_t kNumTemps = 1; |
49 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 49 LocationSummary* locs = |
| 50 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
50 locs->set_in(0, Location::RegisterLocation(RAX)); | 51 locs->set_in(0, Location::RegisterLocation(RAX)); |
51 locs->set_temp(0, Location::RequiresRegister()); | 52 locs->set_temp(0, Location::RequiresRegister()); |
52 return locs; | 53 return locs; |
53 } | 54 } |
54 | 55 |
55 | 56 |
56 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 57 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
57 Register result = locs()->in(0).reg(); | 58 Register result = locs()->in(0).reg(); |
58 Register temp = locs()->temp(0).reg(); | 59 Register temp = locs()->temp(0).reg(); |
59 ASSERT(result == RAX); | 60 ASSERT(result == RAX); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, | 112 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
112 cid(), | 113 cid(), |
113 token_pos(), | 114 token_pos(), |
114 CatchClauseNode::kInvalidTryIndex); | 115 CatchClauseNode::kInvalidTryIndex); |
115 } | 116 } |
116 | 117 |
117 | 118 |
118 LocationSummary* ClosureCallComp::MakeLocationSummary() const { | 119 LocationSummary* ClosureCallComp::MakeLocationSummary() const { |
119 const intptr_t kNumInputs = 0; | 120 const intptr_t kNumInputs = 0; |
120 const intptr_t kNumTemps = 1; | 121 const intptr_t kNumTemps = 1; |
121 LocationSummary* result = new LocationSummary(kNumInputs, | 122 LocationSummary* result = |
122 kNumTemps, | 123 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
123 LocationSummary::kCall); | |
124 result->set_out(Location::RegisterLocation(RAX)); | 124 result->set_out(Location::RegisterLocation(RAX)); |
125 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. | 125 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
126 return result; | 126 return result; |
127 } | 127 } |
128 | 128 |
129 | 129 |
130 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 130 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
131 return LocationSummary::Make(0, Location::RequiresRegister()); | 131 return LocationSummary::Make(0, |
| 132 Location::RequiresRegister(), |
| 133 LocationSummary::kNoCall); |
132 } | 134 } |
133 | 135 |
134 | 136 |
135 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 137 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
136 Register result = locs()->out().reg(); | 138 Register result = locs()->out().reg(); |
137 __ movq(result, Address(RBP, local().index() * kWordSize)); | 139 __ movq(result, Address(RBP, local().index() * kWordSize)); |
138 } | 140 } |
139 | 141 |
140 | 142 |
141 LocationSummary* StoreLocalComp::MakeLocationSummary() const { | 143 LocationSummary* StoreLocalComp::MakeLocationSummary() const { |
142 return LocationSummary::Make(1, Location::SameAsFirstInput()); | 144 return LocationSummary::Make(1, |
| 145 Location::SameAsFirstInput(), |
| 146 LocationSummary::kNoCall); |
143 } | 147 } |
144 | 148 |
145 | 149 |
146 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 150 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
147 Register value = locs()->in(0).reg(); | 151 Register value = locs()->in(0).reg(); |
148 Register result = locs()->out().reg(); | 152 Register result = locs()->out().reg(); |
149 ASSERT(result == value); // Assert that register assignment is correct. | 153 ASSERT(result == value); // Assert that register assignment is correct. |
150 __ movq(Address(RBP, local().index() * kWordSize), value); | 154 __ movq(Address(RBP, local().index() * kWordSize), value); |
151 } | 155 } |
152 | 156 |
153 | 157 |
154 LocationSummary* ConstantVal::MakeLocationSummary() const { | 158 LocationSummary* ConstantVal::MakeLocationSummary() const { |
155 return LocationSummary::Make(0, Location::RequiresRegister()); | 159 return LocationSummary::Make(0, |
| 160 Location::RequiresRegister(), |
| 161 LocationSummary::kNoCall); |
156 } | 162 } |
157 | 163 |
158 | 164 |
159 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 165 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { |
160 Register result = locs()->out().reg(); | 166 Register result = locs()->out().reg(); |
161 __ LoadObject(result, value()); | 167 __ LoadObject(result, value()); |
162 } | 168 } |
163 | 169 |
164 | 170 |
165 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { | 171 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { |
166 const intptr_t kNumInputs = 3; | 172 const intptr_t kNumInputs = 3; |
167 const intptr_t kNumTemps = 0; | 173 const intptr_t kNumTemps = 0; |
168 LocationSummary* summary = new LocationSummary(kNumInputs, | 174 LocationSummary* summary = |
169 kNumTemps, | 175 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
170 LocationSummary::kCall); | |
171 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. | 176 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. |
172 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. | 177 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. |
173 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. | 178 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. |
174 summary->set_out(Location::RegisterLocation(RAX)); | 179 summary->set_out(Location::RegisterLocation(RAX)); |
175 return summary; | 180 return summary; |
176 } | 181 } |
177 | 182 |
178 | 183 |
179 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { | 184 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
180 const intptr_t kNumInputs = 1; | 185 const intptr_t kNumInputs = 1; |
181 const intptr_t kNumTemps = 0; | 186 const intptr_t kNumTemps = 0; |
182 LocationSummary* locs = new LocationSummary(kNumInputs, | 187 LocationSummary* locs = |
183 kNumTemps, | 188 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
184 LocationSummary::kCall); | |
185 locs->set_in(0, Location::RegisterLocation(RAX)); | 189 locs->set_in(0, Location::RegisterLocation(RAX)); |
186 locs->set_out(Location::RegisterLocation(RAX)); | 190 locs->set_out(Location::RegisterLocation(RAX)); |
187 return locs; | 191 return locs; |
188 } | 192 } |
189 | 193 |
190 | 194 |
191 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 195 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
192 Register obj = locs()->in(0).reg(); | 196 Register obj = locs()->in(0).reg(); |
193 Register result = locs()->out().reg(); | 197 Register result = locs()->out().reg(); |
194 | 198 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 } | 231 } |
228 } | 232 } |
229 | 233 |
230 | 234 |
231 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 235 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
232 const intptr_t kNumInputs = 2; | 236 const intptr_t kNumInputs = 2; |
233 if (receiver_class_id() != kObject) { | 237 if (receiver_class_id() != kObject) { |
234 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); | 238 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); |
235 // No temporary register needed for double comparison. | 239 // No temporary register needed for double comparison. |
236 const intptr_t kNumTemps = (receiver_class_id() == kSmi) ? 1 : 0; | 240 const intptr_t kNumTemps = (receiver_class_id() == kSmi) ? 1 : 0; |
237 LocationSummary* locs = new LocationSummary(kNumInputs, | 241 LocationSummary* locs = |
238 kNumTemps, | 242 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
239 LocationSummary::kNoCall); | |
240 locs->set_in(0, Location::RequiresRegister()); | 243 locs->set_in(0, Location::RequiresRegister()); |
241 locs->set_in(1, Location::RequiresRegister()); | 244 locs->set_in(1, Location::RequiresRegister()); |
242 if (receiver_class_id() == kSmi) { | 245 if (receiver_class_id() == kSmi) { |
243 locs->set_temp(0, Location::RequiresRegister()); | 246 locs->set_temp(0, Location::RequiresRegister()); |
244 } | 247 } |
245 locs->set_out(Location::RequiresRegister()); | 248 locs->set_out(Location::RequiresRegister()); |
246 return locs; | 249 return locs; |
247 } | 250 } |
248 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 251 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
249 const intptr_t kNumTemps = 1; | 252 const intptr_t kNumTemps = 1; |
250 LocationSummary* locs = new LocationSummary(kNumInputs, | 253 LocationSummary* locs = |
251 kNumTemps, | 254 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
252 LocationSummary::kCall); | |
253 locs->set_in(0, Location::RegisterLocation(RCX)); | 255 locs->set_in(0, Location::RegisterLocation(RCX)); |
254 locs->set_in(1, Location::RegisterLocation(RDX)); | 256 locs->set_in(1, Location::RegisterLocation(RDX)); |
255 locs->set_temp(0, Location::RegisterLocation(RBX)); | 257 locs->set_temp(0, Location::RegisterLocation(RBX)); |
256 locs->set_out(Location::RegisterLocation(RAX)); | 258 locs->set_out(Location::RegisterLocation(RAX)); |
257 return locs; | 259 return locs; |
258 } | 260 } |
259 const intptr_t kNumTemps = 0; | 261 const intptr_t kNumTemps = 0; |
260 LocationSummary* locs = new LocationSummary(kNumInputs, | 262 LocationSummary* locs = |
261 kNumTemps, | 263 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
262 LocationSummary::kCall); | |
263 locs->set_in(0, Location::RegisterLocation(RCX)); | 264 locs->set_in(0, Location::RegisterLocation(RCX)); |
264 locs->set_in(1, Location::RegisterLocation(RDX)); | 265 locs->set_in(1, Location::RegisterLocation(RDX)); |
265 locs->set_out(Location::RegisterLocation(RAX)); | 266 locs->set_out(Location::RegisterLocation(RAX)); |
266 return locs; | 267 return locs; |
267 } | 268 } |
268 | 269 |
269 | 270 |
270 // Optional integer arguments can often be null. Null is not collected | 271 // Optional integer arguments can often be null. Null is not collected |
271 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? | 272 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? |
272 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, | 273 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 __ pushq(right); | 507 __ pushq(right); |
507 EmitEqualityAsInstanceCall(compiler, this); | 508 EmitEqualityAsInstanceCall(compiler, this); |
508 } | 509 } |
509 } | 510 } |
510 | 511 |
511 | 512 |
512 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 513 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
513 if (operands_class_id() == kSmi || operands_class_id() == kDouble) { | 514 if (operands_class_id() == kSmi || operands_class_id() == kDouble) { |
514 const intptr_t kNumInputs = 2; | 515 const intptr_t kNumInputs = 2; |
515 const intptr_t kNumTemps = 1; | 516 const intptr_t kNumTemps = 1; |
516 LocationSummary* summary = new LocationSummary(kNumInputs, | 517 LocationSummary* summary = |
517 kNumTemps); | 518 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
518 summary->set_in(0, Location::RequiresRegister()); | 519 summary->set_in(0, Location::RequiresRegister()); |
519 summary->set_in(1, Location::RequiresRegister()); | 520 summary->set_in(1, Location::RequiresRegister()); |
520 summary->set_out(Location::RequiresRegister()); | 521 summary->set_out(Location::RequiresRegister()); |
521 summary->set_temp(0, Location::RequiresRegister()); | 522 summary->set_temp(0, Location::RequiresRegister()); |
522 return summary; | 523 return summary; |
523 } | 524 } |
524 ASSERT(operands_class_id() == kObject); | 525 ASSERT(operands_class_id() == kObject); |
525 return MakeCallSummary(); | 526 return MakeCallSummary(); |
526 } | 527 } |
527 | 528 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 kNumArguments, | 663 kNumArguments, |
663 Array::ZoneHandle(), // No optional arguments. | 664 Array::ZoneHandle(), // No optional arguments. |
664 kNumArgsChecked); | 665 kNumArgsChecked); |
665 ASSERT(locs()->out().reg() == RAX); | 666 ASSERT(locs()->out().reg() == RAX); |
666 } | 667 } |
667 | 668 |
668 | 669 |
669 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 670 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
670 const intptr_t kNumInputs = 0; | 671 const intptr_t kNumInputs = 0; |
671 const intptr_t kNumTemps = 3; | 672 const intptr_t kNumTemps = 3; |
672 LocationSummary* locs = new LocationSummary(kNumInputs, | 673 LocationSummary* locs = |
673 kNumTemps, | 674 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
674 LocationSummary::kCall); | |
675 locs->set_temp(0, Location::RegisterLocation(RAX)); | 675 locs->set_temp(0, Location::RegisterLocation(RAX)); |
676 locs->set_temp(1, Location::RegisterLocation(RBX)); | 676 locs->set_temp(1, Location::RegisterLocation(RBX)); |
677 locs->set_temp(2, Location::RegisterLocation(R10)); | 677 locs->set_temp(2, Location::RegisterLocation(R10)); |
678 locs->set_out(Location::RegisterLocation(RAX)); | 678 locs->set_out(Location::RegisterLocation(RAX)); |
679 return locs; | 679 return locs; |
680 } | 680 } |
681 | 681 |
682 | 682 |
683 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 683 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
684 ASSERT(locs()->temp(0).reg() == RAX); | 684 ASSERT(locs()->temp(0).reg() == RAX); |
(...skipping 21 matching lines...) Expand all Loading... |
706 &StubCode::CallNativeCFunctionLabel(), | 706 &StubCode::CallNativeCFunctionLabel(), |
707 PcDescriptors::kOther); | 707 PcDescriptors::kOther); |
708 __ popq(result); | 708 __ popq(result); |
709 } | 709 } |
710 | 710 |
711 | 711 |
712 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { | 712 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { |
713 const intptr_t kNumInputs = 2; | 713 const intptr_t kNumInputs = 2; |
714 if (receiver_type() == kGrowableObjectArray) { | 714 if (receiver_type() == kGrowableObjectArray) { |
715 const intptr_t kNumTemps = 1; | 715 const intptr_t kNumTemps = 1; |
716 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 716 LocationSummary* locs = |
| 717 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
717 locs->set_in(0, Location::RequiresRegister()); | 718 locs->set_in(0, Location::RequiresRegister()); |
718 locs->set_in(1, Location::RequiresRegister()); | 719 locs->set_in(1, Location::RequiresRegister()); |
719 locs->set_temp(0, Location::RequiresRegister()); | 720 locs->set_temp(0, Location::RequiresRegister()); |
720 locs->set_out(Location::RequiresRegister()); | 721 locs->set_out(Location::RequiresRegister()); |
721 return locs; | 722 return locs; |
722 } else if ((receiver_type() == kArray) || | 723 } else if ((receiver_type() == kArray) || |
723 (receiver_type() == kImmutableArray)) { | 724 (receiver_type() == kImmutableArray)) { |
724 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 725 return LocationSummary::Make(kNumInputs, |
| 726 Location::RequiresRegister(), |
| 727 LocationSummary::kNoCall); |
725 } else { | 728 } else { |
726 ASSERT(receiver_type() == kIllegalObjectKind); | 729 ASSERT(receiver_type() == kIllegalObjectKind); |
727 return MakeCallSummary(); | 730 return MakeCallSummary(); |
728 } | 731 } |
729 } | 732 } |
730 | 733 |
731 | 734 |
732 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, | 735 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, |
733 LoadIndexedComp* comp) { | 736 LoadIndexedComp* comp) { |
734 Label* deopt = compiler->AddDeoptStub(comp->cid(), | 737 Label* deopt = compiler->AddDeoptStub(comp->cid(), |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 UNREACHABLE(); | 822 UNREACHABLE(); |
820 break; | 823 break; |
821 } | 824 } |
822 } | 825 } |
823 | 826 |
824 | 827 |
825 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 828 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
826 const intptr_t kNumInputs = 3; | 829 const intptr_t kNumInputs = 3; |
827 if (receiver_type() == kGrowableObjectArray) { | 830 if (receiver_type() == kGrowableObjectArray) { |
828 const intptr_t kNumTemps = 1; | 831 const intptr_t kNumTemps = 1; |
829 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 832 LocationSummary* locs = |
| 833 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
830 locs->set_in(0, Location::RequiresRegister()); | 834 locs->set_in(0, Location::RequiresRegister()); |
831 locs->set_in(1, Location::RequiresRegister()); | 835 locs->set_in(1, Location::RequiresRegister()); |
832 locs->set_in(2, Location::RequiresRegister()); | 836 locs->set_in(2, Location::RequiresRegister()); |
833 locs->set_temp(0, Location::RequiresRegister()); | 837 locs->set_temp(0, Location::RequiresRegister()); |
834 locs->set_out(Location::NoLocation()); | 838 locs->set_out(Location::NoLocation()); |
835 return locs; | 839 return locs; |
836 } else if (receiver_type() == kArray) { | 840 } else if (receiver_type() == kArray) { |
837 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 841 return LocationSummary::Make(kNumInputs, |
| 842 Location::NoLocation(), |
| 843 LocationSummary::kNoCall); |
838 } else { | 844 } else { |
839 ASSERT(receiver_type() == kIllegalObjectKind); | 845 ASSERT(receiver_type() == kIllegalObjectKind); |
840 return MakeCallSummary(); | 846 return MakeCallSummary(); |
841 } | 847 } |
842 } | 848 } |
843 | 849 |
844 | 850 |
845 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, | 851 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, |
846 StoreIndexedComp* comp) { | 852 StoreIndexedComp* comp) { |
847 const String& function_name = | 853 const String& function_name = |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 function_name, | 1015 function_name, |
1010 kArgumentCount, | 1016 kArgumentCount, |
1011 Array::ZoneHandle(), | 1017 Array::ZoneHandle(), |
1012 kCheckedArgumentCount); | 1018 kCheckedArgumentCount); |
1013 } | 1019 } |
1014 } | 1020 } |
1015 | 1021 |
1016 | 1022 |
1017 LocationSummary* StaticSetterComp::MakeLocationSummary() const { | 1023 LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
1018 const intptr_t kNumInputs = 1; | 1024 const intptr_t kNumInputs = 1; |
1019 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 1025 return LocationSummary::Make(kNumInputs, |
| 1026 Location::RequiresRegister(), |
| 1027 LocationSummary::kNoCall); |
1020 } | 1028 } |
1021 | 1029 |
1022 | 1030 |
1023 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1031 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1024 Register value = locs()->in(0).reg(); | 1032 Register value = locs()->in(0).reg(); |
1025 Register result = locs()->out().reg(); | 1033 Register result = locs()->out().reg(); |
1026 | 1034 |
1027 // Preserve the argument as the result of the computation, | 1035 // Preserve the argument as the result of the computation, |
1028 // then call the setter. | 1036 // then call the setter. |
1029 | 1037 |
1030 // Duplicate the argument. | 1038 // Duplicate the argument. |
1031 // TODO(fschneider): Avoid preserving the value if the result is not used. | 1039 // TODO(fschneider): Avoid preserving the value if the result is not used. |
1032 __ pushq(value); | 1040 __ pushq(value); |
1033 __ pushq(value); | 1041 __ pushq(value); |
1034 compiler->GenerateStaticCall(cid(), | 1042 compiler->GenerateStaticCall(cid(), |
1035 token_pos(), | 1043 token_pos(), |
1036 try_index(), | 1044 try_index(), |
1037 setter_function(), | 1045 setter_function(), |
1038 1, | 1046 1, |
1039 Array::ZoneHandle()); | 1047 Array::ZoneHandle()); |
1040 __ popq(result); | 1048 __ popq(result); |
1041 } | 1049 } |
1042 | 1050 |
1043 | 1051 |
1044 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 1052 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
1045 // TODO(fschneider): For this instruction the input register may be | 1053 // TODO(fschneider): For this instruction the input register may be |
1046 // reused for the result (but is not required to) because the input | 1054 // reused for the result (but is not required to) because the input |
1047 // is not used after the result is defined. We should consider adding | 1055 // is not used after the result is defined. We should consider adding |
1048 // this information to the input policy. | 1056 // this information to the input policy. |
1049 return LocationSummary::Make(1, Location::RequiresRegister()); | 1057 return LocationSummary::Make(1, |
| 1058 Location::RequiresRegister(), |
| 1059 LocationSummary::kNoCall); |
1050 } | 1060 } |
1051 | 1061 |
1052 | 1062 |
1053 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1063 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1054 Register instance_reg = locs()->in(0).reg(); | 1064 Register instance_reg = locs()->in(0).reg(); |
1055 Register result_reg = locs()->out().reg(); | 1065 Register result_reg = locs()->out().reg(); |
1056 | 1066 |
1057 if (HasICData()) { | 1067 if (HasICData()) { |
1058 ASSERT(original() != NULL); | 1068 ASSERT(original() != NULL); |
1059 Label* deopt = compiler->AddDeoptStub(original()->cid(), | 1069 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
1060 original()->token_pos(), | 1070 original()->token_pos(), |
1061 original()->try_index(), | 1071 original()->try_index(), |
1062 kDeoptInstanceGetterSameTarget, | 1072 kDeoptInstanceGetterSameTarget, |
1063 instance_reg); | 1073 instance_reg); |
1064 // Smis do not have instance fields (Smi class is always first). | 1074 // Smis do not have instance fields (Smi class is always first). |
1065 // Use 'result' as temporary register. | 1075 // Use 'result' as temporary register. |
1066 ASSERT(result_reg != instance_reg); | 1076 ASSERT(result_reg != instance_reg); |
1067 ASSERT(ic_data() != NULL); | 1077 ASSERT(ic_data() != NULL); |
1068 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | 1078 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); |
1069 } | 1079 } |
1070 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); | 1080 __ movq(result_reg, FieldAddress(instance_reg, field().Offset())); |
1071 } | 1081 } |
1072 | 1082 |
1073 | 1083 |
1074 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { | 1084 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { |
1075 return LocationSummary::Make(0, Location::RequiresRegister()); | 1085 return LocationSummary::Make(0, |
| 1086 Location::RequiresRegister(), |
| 1087 LocationSummary::kNoCall); |
1076 } | 1088 } |
1077 | 1089 |
1078 | 1090 |
1079 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1091 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1080 Register result = locs()->out().reg(); | 1092 Register result = locs()->out().reg(); |
1081 __ LoadObject(result, field()); | 1093 __ LoadObject(result, field()); |
1082 __ movq(result, FieldAddress(result, Field::value_offset())); | 1094 __ movq(result, FieldAddress(result, Field::value_offset())); |
1083 } | 1095 } |
1084 | 1096 |
1085 | 1097 |
1086 LocationSummary* InstanceOfComp::MakeLocationSummary() const { | 1098 LocationSummary* InstanceOfComp::MakeLocationSummary() const { |
1087 const intptr_t kNumInputs = 3; | 1099 const intptr_t kNumInputs = 3; |
1088 const intptr_t kNumTemps = 0; | 1100 const intptr_t kNumTemps = 0; |
1089 LocationSummary* summary = new LocationSummary(kNumInputs, | 1101 LocationSummary* summary = |
1090 kNumTemps, | 1102 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1091 LocationSummary::kCall); | |
1092 summary->set_in(0, Location::RegisterLocation(RAX)); | 1103 summary->set_in(0, Location::RegisterLocation(RAX)); |
1093 summary->set_in(1, Location::RegisterLocation(RCX)); | 1104 summary->set_in(1, Location::RegisterLocation(RCX)); |
1094 summary->set_in(2, Location::RegisterLocation(RDX)); | 1105 summary->set_in(2, Location::RegisterLocation(RDX)); |
1095 summary->set_out(Location::RegisterLocation(RAX)); | 1106 summary->set_out(Location::RegisterLocation(RAX)); |
1096 return summary; | 1107 return summary; |
1097 } | 1108 } |
1098 | 1109 |
1099 | 1110 |
1100 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1111 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1101 ASSERT(locs()->in(0).reg() == RAX); // Value. | 1112 ASSERT(locs()->in(0).reg() == RAX); // Value. |
1102 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. | 1113 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. |
1103 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. | 1114 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. |
1104 | 1115 |
1105 compiler->GenerateInstanceOf(cid(), | 1116 compiler->GenerateInstanceOf(cid(), |
1106 token_pos(), | 1117 token_pos(), |
1107 try_index(), | 1118 try_index(), |
1108 type(), | 1119 type(), |
1109 negate_result()); | 1120 negate_result()); |
1110 ASSERT(locs()->out().reg() == RAX); | 1121 ASSERT(locs()->out().reg() == RAX); |
1111 } | 1122 } |
1112 | 1123 |
1113 | 1124 |
1114 LocationSummary* CreateArrayComp::MakeLocationSummary() const { | 1125 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
1115 // TODO(regis): The elements of the array could be considered as arguments to | 1126 // TODO(regis): The elements of the array could be considered as arguments to |
1116 // CreateArrayComp, thereby making CreateArrayComp a call. | 1127 // CreateArrayComp, thereby making CreateArrayComp a call. |
1117 // For VerifyCallComputation to work, CreateArrayComp would need an | 1128 // For VerifyCallComputation to work, CreateArrayComp would need an |
1118 // ArgumentCount getter and an ArgumentAt getter. | 1129 // ArgumentCount getter and an ArgumentAt getter. |
1119 const intptr_t kNumInputs = 1; | 1130 const intptr_t kNumInputs = 1; |
1120 const intptr_t kNumTemps = 1; | 1131 const intptr_t kNumTemps = 1; |
1121 LocationSummary* locs = new LocationSummary(kNumInputs, | 1132 LocationSummary* locs = |
1122 kNumTemps, | 1133 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1123 LocationSummary::kCall); | |
1124 locs->set_in(0, Location::RegisterLocation(RBX)); | 1134 locs->set_in(0, Location::RegisterLocation(RBX)); |
1125 locs->set_temp(0, Location::RegisterLocation(R10)); | 1135 locs->set_temp(0, Location::RegisterLocation(R10)); |
1126 locs->set_out(Location::RegisterLocation(RAX)); | 1136 locs->set_out(Location::RegisterLocation(RAX)); |
1127 return locs; | 1137 return locs; |
1128 } | 1138 } |
1129 | 1139 |
1130 | 1140 |
1131 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1141 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1132 Register temp_reg = locs()->temp(0).reg(); | 1142 Register temp_reg = locs()->temp(0).reg(); |
1133 Register result_reg = locs()->out().reg(); | 1143 Register result_reg = locs()->out().reg(); |
(...skipping 14 matching lines...) Expand all Loading... |
1148 ASSERT(ElementAt(i)->IsUse()); | 1158 ASSERT(ElementAt(i)->IsUse()); |
1149 __ popq(Address(temp_reg, i * kWordSize)); | 1159 __ popq(Address(temp_reg, i * kWordSize)); |
1150 } | 1160 } |
1151 } | 1161 } |
1152 | 1162 |
1153 | 1163 |
1154 LocationSummary* | 1164 LocationSummary* |
1155 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { | 1165 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { |
1156 const intptr_t kNumInputs = 2; | 1166 const intptr_t kNumInputs = 2; |
1157 const intptr_t kNumTemps = 0; | 1167 const intptr_t kNumTemps = 0; |
1158 LocationSummary* locs = new LocationSummary(kNumInputs, | 1168 LocationSummary* locs = |
1159 kNumTemps, | 1169 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1160 LocationSummary::kCall); | |
1161 locs->set_in(0, Location::RegisterLocation(RAX)); | 1170 locs->set_in(0, Location::RegisterLocation(RAX)); |
1162 locs->set_in(1, Location::RegisterLocation(RCX)); | 1171 locs->set_in(1, Location::RegisterLocation(RCX)); |
1163 locs->set_out(Location::RegisterLocation(RAX)); | 1172 locs->set_out(Location::RegisterLocation(RAX)); |
1164 return locs; | 1173 return locs; |
1165 } | 1174 } |
1166 | 1175 |
1167 | 1176 |
1168 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( | 1177 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
1169 FlowGraphCompiler* compiler) { | 1178 FlowGraphCompiler* compiler) { |
1170 const Class& cls = Class::ZoneHandle(constructor().owner()); | 1179 const Class& cls = Class::ZoneHandle(constructor().owner()); |
(...skipping 10 matching lines...) Expand all Loading... |
1181 token_pos(), | 1190 token_pos(), |
1182 try_index(), | 1191 try_index(), |
1183 kAllocateObjectWithBoundsCheckRuntimeEntry); | 1192 kAllocateObjectWithBoundsCheckRuntimeEntry); |
1184 // Pop instantiator type arguments, type arguments, and class. | 1193 // Pop instantiator type arguments, type arguments, and class. |
1185 __ Drop(3); | 1194 __ Drop(3); |
1186 __ popq(result); // Pop new instance. | 1195 __ popq(result); // Pop new instance. |
1187 } | 1196 } |
1188 | 1197 |
1189 | 1198 |
1190 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 1199 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
1191 return LocationSummary::Make(1, Location::RequiresRegister()); | 1200 return LocationSummary::Make(1, |
| 1201 Location::RequiresRegister(), |
| 1202 LocationSummary::kNoCall); |
1192 } | 1203 } |
1193 | 1204 |
1194 | 1205 |
1195 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1206 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1196 Register instance_reg = locs()->in(0).reg(); | 1207 Register instance_reg = locs()->in(0).reg(); |
1197 Register result_reg = locs()->out().reg(); | 1208 Register result_reg = locs()->out().reg(); |
1198 if (HasICData()) { | 1209 if (HasICData()) { |
1199 ASSERT(original() != NULL); | 1210 ASSERT(original() != NULL); |
1200 Label* deopt = compiler->AddDeoptStub(original()->cid(), | 1211 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
1201 original()->token_pos(), | 1212 original()->token_pos(), |
1202 original()->try_index(), | 1213 original()->try_index(), |
1203 kDeoptInstanceGetterSameTarget, | 1214 kDeoptInstanceGetterSameTarget, |
1204 instance_reg); | 1215 instance_reg); |
1205 // Smis do not have instance fields (Smi class is always first). | 1216 // Smis do not have instance fields (Smi class is always first). |
1206 // Use 'result' as temporary register. | 1217 // Use 'result' as temporary register. |
1207 ASSERT(result_reg != instance_reg); | 1218 ASSERT(result_reg != instance_reg); |
1208 ASSERT(ic_data() != NULL); | 1219 ASSERT(ic_data() != NULL); |
1209 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); | 1220 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); |
1210 } | 1221 } |
1211 | 1222 |
1212 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); | 1223 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes())); |
1213 } | 1224 } |
1214 | 1225 |
1215 | 1226 |
1216 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { | 1227 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
1217 const intptr_t kNumInputs = 1; | 1228 const intptr_t kNumInputs = 1; |
1218 const intptr_t kNumTemps = 0; | 1229 const intptr_t kNumTemps = 0; |
1219 LocationSummary* locs = new LocationSummary(kNumInputs, | 1230 LocationSummary* locs = |
1220 kNumTemps, | 1231 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1221 LocationSummary::kCall); | |
1222 locs->set_in(0, Location::RegisterLocation(RAX)); | 1232 locs->set_in(0, Location::RegisterLocation(RAX)); |
1223 locs->set_out(Location::RegisterLocation(RAX)); | 1233 locs->set_out(Location::RegisterLocation(RAX)); |
1224 return locs; | 1234 return locs; |
1225 } | 1235 } |
1226 | 1236 |
1227 | 1237 |
1228 void InstantiateTypeArgumentsComp::EmitNativeCode( | 1238 void InstantiateTypeArgumentsComp::EmitNativeCode( |
1229 FlowGraphCompiler* compiler) { | 1239 FlowGraphCompiler* compiler) { |
1230 Register instantiator_reg = locs()->in(0).reg(); | 1240 Register instantiator_reg = locs()->in(0).reg(); |
1231 Register result_reg = locs()->out().reg(); | 1241 Register result_reg = locs()->out().reg(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 __ Bind(&type_arguments_instantiated); | 1281 __ Bind(&type_arguments_instantiated); |
1272 ASSERT(instantiator_reg == result_reg); | 1282 ASSERT(instantiator_reg == result_reg); |
1273 // 'result_reg': Instantiated type arguments. | 1283 // 'result_reg': Instantiated type arguments. |
1274 } | 1284 } |
1275 | 1285 |
1276 | 1286 |
1277 LocationSummary* | 1287 LocationSummary* |
1278 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { | 1288 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { |
1279 const intptr_t kNumInputs = 1; | 1289 const intptr_t kNumInputs = 1; |
1280 const intptr_t kNumTemps = 0; | 1290 const intptr_t kNumTemps = 0; |
1281 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 1291 LocationSummary* locs = |
| 1292 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1282 locs->set_in(0, Location::RequiresRegister()); | 1293 locs->set_in(0, Location::RequiresRegister()); |
1283 locs->set_out(Location::SameAsFirstInput()); | 1294 locs->set_out(Location::SameAsFirstInput()); |
1284 return locs; | 1295 return locs; |
1285 } | 1296 } |
1286 | 1297 |
1287 | 1298 |
1288 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( | 1299 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( |
1289 FlowGraphCompiler* compiler) { | 1300 FlowGraphCompiler* compiler) { |
1290 Register instantiator_reg = locs()->in(0).reg(); | 1301 Register instantiator_reg = locs()->in(0).reg(); |
1291 Register result_reg = locs()->out().reg(); | 1302 Register result_reg = locs()->out().reg(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 // result_reg: uninstantiated type arguments. | 1337 // result_reg: uninstantiated type arguments. |
1327 __ Bind(&type_arguments_instantiated); | 1338 __ Bind(&type_arguments_instantiated); |
1328 // result_reg: uninstantiated or instantiated type arguments. | 1339 // result_reg: uninstantiated or instantiated type arguments. |
1329 } | 1340 } |
1330 | 1341 |
1331 | 1342 |
1332 LocationSummary* | 1343 LocationSummary* |
1333 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { | 1344 ExtractConstructorInstantiatorComp::MakeLocationSummary() const { |
1334 const intptr_t kNumInputs = 1; | 1345 const intptr_t kNumInputs = 1; |
1335 const intptr_t kNumTemps = 0; | 1346 const intptr_t kNumTemps = 0; |
1336 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 1347 LocationSummary* locs = |
| 1348 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1337 locs->set_in(0, Location::RequiresRegister()); | 1349 locs->set_in(0, Location::RequiresRegister()); |
1338 locs->set_out(Location::SameAsFirstInput()); | 1350 locs->set_out(Location::SameAsFirstInput()); |
1339 return locs; | 1351 return locs; |
1340 } | 1352 } |
1341 | 1353 |
1342 | 1354 |
1343 void ExtractConstructorInstantiatorComp::EmitNativeCode( | 1355 void ExtractConstructorInstantiatorComp::EmitNativeCode( |
1344 FlowGraphCompiler* compiler) { | 1356 FlowGraphCompiler* compiler) { |
1345 ASSERT(instantiator()->IsUse()); | 1357 ASSERT(instantiator()->IsUse()); |
1346 Register instantiator_reg = locs()->in(0).reg(); | 1358 Register instantiator_reg = locs()->in(0).reg(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1402 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
1391 } | 1403 } |
1392 __ Bind(&done); | 1404 __ Bind(&done); |
1393 // instantiator_reg: instantiator or kNoInstantiator. | 1405 // instantiator_reg: instantiator or kNoInstantiator. |
1394 } | 1406 } |
1395 | 1407 |
1396 | 1408 |
1397 LocationSummary* AllocateContextComp::MakeLocationSummary() const { | 1409 LocationSummary* AllocateContextComp::MakeLocationSummary() const { |
1398 const intptr_t kNumInputs = 0; | 1410 const intptr_t kNumInputs = 0; |
1399 const intptr_t kNumTemps = 1; | 1411 const intptr_t kNumTemps = 1; |
1400 LocationSummary* locs = new LocationSummary(kNumInputs, | 1412 LocationSummary* locs = |
1401 kNumTemps, | 1413 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1402 LocationSummary::kCall); | |
1403 locs->set_temp(0, Location::RegisterLocation(R10)); | 1414 locs->set_temp(0, Location::RegisterLocation(R10)); |
1404 locs->set_out(Location::RegisterLocation(RAX)); | 1415 locs->set_out(Location::RegisterLocation(RAX)); |
1405 return locs; | 1416 return locs; |
1406 } | 1417 } |
1407 | 1418 |
1408 | 1419 |
1409 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1420 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1410 ASSERT(locs()->temp(0).reg() == R10); | 1421 ASSERT(locs()->temp(0).reg() == R10); |
1411 ASSERT(locs()->out().reg() == RAX); | 1422 ASSERT(locs()->out().reg() == RAX); |
1412 | 1423 |
1413 __ movq(R10, Immediate(num_context_variables())); | 1424 __ movq(R10, Immediate(num_context_variables())); |
1414 const ExternalLabel label("alloc_context", | 1425 const ExternalLabel label("alloc_context", |
1415 StubCode::AllocateContextEntryPoint()); | 1426 StubCode::AllocateContextEntryPoint()); |
1416 compiler->GenerateCall(token_pos(), | 1427 compiler->GenerateCall(token_pos(), |
1417 try_index(), | 1428 try_index(), |
1418 &label, | 1429 &label, |
1419 PcDescriptors::kOther); | 1430 PcDescriptors::kOther); |
1420 } | 1431 } |
1421 | 1432 |
1422 | 1433 |
1423 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 1434 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
1424 const intptr_t kNumInputs = 1; | 1435 const intptr_t kNumInputs = 1; |
1425 const intptr_t kNumTemps = 0; | 1436 const intptr_t kNumTemps = 0; |
1426 LocationSummary* locs = new LocationSummary(kNumInputs, | 1437 LocationSummary* locs = |
1427 kNumTemps, | 1438 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1428 LocationSummary::kCall); | |
1429 locs->set_in(0, Location::RegisterLocation(RAX)); | 1439 locs->set_in(0, Location::RegisterLocation(RAX)); |
1430 locs->set_out(Location::RegisterLocation(RAX)); | 1440 locs->set_out(Location::RegisterLocation(RAX)); |
1431 return locs; | 1441 return locs; |
1432 } | 1442 } |
1433 | 1443 |
1434 | 1444 |
1435 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1445 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1436 Register context_value = locs()->in(0).reg(); | 1446 Register context_value = locs()->in(0).reg(); |
1437 Register result = locs()->out().reg(); | 1447 Register result = locs()->out().reg(); |
1438 | 1448 |
1439 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1449 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
1440 __ pushq(context_value); | 1450 __ pushq(context_value); |
1441 compiler->GenerateCallRuntime(cid(), | 1451 compiler->GenerateCallRuntime(cid(), |
1442 token_pos(), | 1452 token_pos(), |
1443 try_index(), | 1453 try_index(), |
1444 kCloneContextRuntimeEntry); | 1454 kCloneContextRuntimeEntry); |
1445 __ popq(result); // Remove argument. | 1455 __ popq(result); // Remove argument. |
1446 __ popq(result); // Get result (cloned context). | 1456 __ popq(result); // Get result (cloned context). |
1447 } | 1457 } |
1448 | 1458 |
1449 | 1459 |
1450 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 1460 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
1451 return LocationSummary::Make(0, Location::NoLocation()); | 1461 return LocationSummary::Make(0, |
| 1462 Location::NoLocation(), |
| 1463 LocationSummary::kNoCall); |
1452 } | 1464 } |
1453 | 1465 |
1454 | 1466 |
1455 // Restore stack and initialize the two exception variables: | 1467 // Restore stack and initialize the two exception variables: |
1456 // exception and stack trace variables. | 1468 // exception and stack trace variables. |
1457 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1469 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1458 // Restore RSP from RBP as we are coming from a throw and the code for | 1470 // Restore RSP from RBP as we are coming from a throw and the code for |
1459 // popping arguments has not been run. | 1471 // popping arguments has not been run. |
1460 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; | 1472 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
1461 ASSERT(locals_space_size >= 0); | 1473 ASSERT(locals_space_size >= 0); |
1462 const intptr_t offset_size = | 1474 const intptr_t offset_size = |
1463 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; | 1475 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
1464 __ leaq(RSP, Address(RBP, offset_size)); | 1476 __ leaq(RSP, Address(RBP, offset_size)); |
1465 | 1477 |
1466 ASSERT(!exception_var().is_captured()); | 1478 ASSERT(!exception_var().is_captured()); |
1467 ASSERT(!stacktrace_var().is_captured()); | 1479 ASSERT(!stacktrace_var().is_captured()); |
1468 __ movq(Address(RBP, exception_var().index() * kWordSize), | 1480 __ movq(Address(RBP, exception_var().index() * kWordSize), |
1469 kExceptionObjectReg); | 1481 kExceptionObjectReg); |
1470 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), | 1482 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), |
1471 kStackTraceObjectReg); | 1483 kStackTraceObjectReg); |
1472 } | 1484 } |
1473 | 1485 |
1474 | 1486 |
1475 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { | 1487 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { |
1476 const intptr_t kNumInputs = 0; | 1488 const intptr_t kNumInputs = 0; |
1477 const intptr_t kNumTemps = 1; | 1489 const intptr_t kNumTemps = 1; |
1478 // TODO(vegorov): spilling is required only on an infrequently executed path. | 1490 // TODO(vegorov): spilling is required only on an infrequently executed path. |
1479 LocationSummary* summary = new LocationSummary(kNumInputs, | 1491 LocationSummary* summary = |
1480 kNumTemps, | 1492 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1481 LocationSummary::kCall); | |
1482 // All registers are blocked for a call. Instructions marked at calls can use | 1493 // All registers are blocked for a call. Instructions marked at calls can use |
1483 // only fixed register temps. | 1494 // only fixed register temps. |
1484 summary->set_temp(0, Location::RegisterLocation(RAX)); | 1495 summary->set_temp(0, Location::RegisterLocation(RAX)); |
1485 return summary; | 1496 return summary; |
1486 } | 1497 } |
1487 | 1498 |
1488 | 1499 |
1489 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1500 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1490 Register temp = locs()->temp(0).reg(); | 1501 Register temp = locs()->temp(0).reg(); |
1491 // Generate stack overflow check. | 1502 // Generate stack overflow check. |
(...skipping 24 matching lines...) Expand all Loading... |
1516 summary->set_in(0, Location::RegisterLocation(RAX)); | 1527 summary->set_in(0, Location::RegisterLocation(RAX)); |
1517 summary->set_in(1, Location::RegisterLocation(RCX)); | 1528 summary->set_in(1, Location::RegisterLocation(RCX)); |
1518 summary->set_out(Location::RegisterLocation(RAX)); | 1529 summary->set_out(Location::RegisterLocation(RAX)); |
1519 return summary; | 1530 return summary; |
1520 } | 1531 } |
1521 | 1532 |
1522 ASSERT(operands_type() == kSmiOperands); | 1533 ASSERT(operands_type() == kSmiOperands); |
1523 | 1534 |
1524 if (op_kind() == Token::kTRUNCDIV) { | 1535 if (op_kind() == Token::kTRUNCDIV) { |
1525 const intptr_t kNumTemps = 3; | 1536 const intptr_t kNumTemps = 3; |
1526 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1537 LocationSummary* summary = |
| 1538 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1527 summary->set_in(0, Location::RegisterLocation(RAX)); | 1539 summary->set_in(0, Location::RegisterLocation(RAX)); |
1528 summary->set_in(1, Location::RegisterLocation(RCX)); | 1540 summary->set_in(1, Location::RegisterLocation(RCX)); |
1529 summary->set_out(Location::SameAsFirstInput()); | 1541 summary->set_out(Location::SameAsFirstInput()); |
1530 summary->set_temp(0, Location::RegisterLocation(RBX)); | 1542 summary->set_temp(0, Location::RegisterLocation(RBX)); |
1531 // Will be used for for sign extension. | 1543 // Will be used for for sign extension. |
1532 summary->set_temp(1, Location::RegisterLocation(RDX)); | 1544 summary->set_temp(1, Location::RegisterLocation(RDX)); |
1533 summary->set_temp(2, Location::RequiresRegister()); | 1545 summary->set_temp(2, Location::RequiresRegister()); |
1534 return summary; | 1546 return summary; |
1535 } else if (op_kind() == Token::kSHR) { | 1547 } else if (op_kind() == Token::kSHR) { |
1536 const intptr_t kNumTemps = 1; | 1548 const intptr_t kNumTemps = 1; |
1537 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1549 LocationSummary* summary = |
| 1550 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1538 summary->set_in(0, Location::RequiresRegister()); | 1551 summary->set_in(0, Location::RequiresRegister()); |
1539 summary->set_in(1, Location::RegisterLocation(RCX)); | 1552 summary->set_in(1, Location::RegisterLocation(RCX)); |
1540 summary->set_out(Location::SameAsFirstInput()); | 1553 summary->set_out(Location::SameAsFirstInput()); |
1541 summary->set_temp(0, Location::RequiresRegister()); | 1554 summary->set_temp(0, Location::RequiresRegister()); |
1542 return summary; | 1555 return summary; |
1543 } else if (op_kind() == Token::kSHL) { | 1556 } else if (op_kind() == Token::kSHL) { |
1544 // Two Smi operands can easily overflow into Mint. | 1557 // Two Smi operands can easily overflow into Mint. |
1545 const intptr_t kNumTemps = 2; | 1558 const intptr_t kNumTemps = 2; |
1546 LocationSummary* summary = | 1559 LocationSummary* summary = |
1547 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1560 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1548 summary->set_in(0, Location::RegisterLocation(RAX)); | 1561 summary->set_in(0, Location::RegisterLocation(RAX)); |
1549 summary->set_in(1, Location::RegisterLocation(RDX)); | 1562 summary->set_in(1, Location::RegisterLocation(RDX)); |
1550 summary->set_out(Location::RegisterLocation(RAX)); | 1563 summary->set_out(Location::RegisterLocation(RAX)); |
1551 summary->set_temp(0, Location::RegisterLocation(RBX)); | 1564 summary->set_temp(0, Location::RegisterLocation(RBX)); |
1552 summary->set_temp(1, Location::RegisterLocation(RCX)); | 1565 summary->set_temp(1, Location::RegisterLocation(RCX)); |
1553 return summary; | 1566 return summary; |
1554 } else { | 1567 } else { |
1555 const intptr_t kNumTemps = 1; | 1568 const intptr_t kNumTemps = 1; |
1556 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1569 LocationSummary* summary = |
| 1570 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1557 summary->set_in(0, Location::RequiresRegister()); | 1571 summary->set_in(0, Location::RequiresRegister()); |
1558 summary->set_in(1, Location::RequiresRegister()); | 1572 summary->set_in(1, Location::RequiresRegister()); |
1559 summary->set_out(Location::SameAsFirstInput()); | 1573 summary->set_out(Location::SameAsFirstInput()); |
1560 summary->set_temp(0, Location::RequiresRegister()); | 1574 summary->set_temp(0, Location::RequiresRegister()); |
1561 return summary; | 1575 return summary; |
1562 } | 1576 } |
1563 } | 1577 } |
1564 | 1578 |
1565 | 1579 |
1566 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { | 1580 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 | 1879 |
1866 default: | 1880 default: |
1867 UNREACHABLE(); | 1881 UNREACHABLE(); |
1868 } | 1882 } |
1869 } | 1883 } |
1870 | 1884 |
1871 | 1885 |
1872 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { | 1886 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { |
1873 const intptr_t kNumInputs = 1; | 1887 const intptr_t kNumInputs = 1; |
1874 const intptr_t kNumTemps = 0; | 1888 const intptr_t kNumTemps = 0; |
1875 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1889 LocationSummary* summary = |
| 1890 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1876 summary->set_in(0, Location::RequiresRegister()); | 1891 summary->set_in(0, Location::RequiresRegister()); |
1877 summary->set_out(Location::SameAsFirstInput()); | 1892 summary->set_out(Location::SameAsFirstInput()); |
1878 return summary; | 1893 return summary; |
1879 } | 1894 } |
1880 | 1895 |
1881 | 1896 |
1882 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1897 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1883 const ICData& ic_data = *instance_call()->ic_data(); | 1898 const ICData& ic_data = *instance_call()->ic_data(); |
1884 ASSERT(!ic_data.IsNull()); | 1899 ASSERT(!ic_data.IsNull()); |
1885 ASSERT(ic_data.num_args_tested() == 1); | 1900 ASSERT(ic_data.num_args_tested() == 1); |
(...skipping 28 matching lines...) Expand all Loading... |
1914 } | 1929 } |
1915 } else { | 1930 } else { |
1916 UNREACHABLE(); | 1931 UNREACHABLE(); |
1917 } | 1932 } |
1918 } | 1933 } |
1919 | 1934 |
1920 | 1935 |
1921 LocationSummary* NumberNegateComp::MakeLocationSummary() const { | 1936 LocationSummary* NumberNegateComp::MakeLocationSummary() const { |
1922 const intptr_t kNumInputs = 1; | 1937 const intptr_t kNumInputs = 1; |
1923 const intptr_t kNumTemps = 1; // Needed for doubles. | 1938 const intptr_t kNumTemps = 1; // Needed for doubles. |
1924 LocationSummary* summary = new LocationSummary(kNumInputs, | 1939 LocationSummary* summary = |
1925 kNumTemps, | 1940 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1926 LocationSummary::kCall); | |
1927 summary->set_in(0, Location::RegisterLocation(RAX)); | 1941 summary->set_in(0, Location::RegisterLocation(RAX)); |
1928 summary->set_out(Location::RegisterLocation(RAX)); | 1942 summary->set_out(Location::RegisterLocation(RAX)); |
1929 summary->set_temp(0, Location::RegisterLocation(RCX)); | 1943 summary->set_temp(0, Location::RegisterLocation(RCX)); |
1930 return summary; | 1944 return summary; |
1931 } | 1945 } |
1932 | 1946 |
1933 | 1947 |
1934 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1948 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1935 const ICData& ic_data = *instance_call()->ic_data(); | 1949 const ICData& ic_data = *instance_call()->ic_data(); |
1936 ASSERT(!ic_data.IsNull()); | 1950 ASSERT(!ic_data.IsNull()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1976 } else { | 1990 } else { |
1977 UNREACHABLE(); | 1991 UNREACHABLE(); |
1978 } | 1992 } |
1979 } | 1993 } |
1980 | 1994 |
1981 | 1995 |
1982 LocationSummary* ToDoubleComp::MakeLocationSummary() const { | 1996 LocationSummary* ToDoubleComp::MakeLocationSummary() const { |
1983 const intptr_t kNumInputs = 1; | 1997 const intptr_t kNumInputs = 1; |
1984 if (from() == kDouble) { | 1998 if (from() == kDouble) { |
1985 const intptr_t kNumTemps = 0; | 1999 const intptr_t kNumTemps = 0; |
1986 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); | 2000 LocationSummary* locs = |
| 2001 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1987 locs->set_in(0, Location::RequiresRegister()); | 2002 locs->set_in(0, Location::RequiresRegister()); |
1988 locs->set_out(Location::SameAsFirstInput()); | 2003 locs->set_out(Location::SameAsFirstInput()); |
1989 return locs; | 2004 return locs; |
1990 } else { | 2005 } else { |
1991 ASSERT(from() == kSmi); | 2006 ASSERT(from() == kSmi); |
1992 return MakeCallSummary(); // Calls a stub to allocate result. | 2007 return MakeCallSummary(); // Calls a stub to allocate result. |
1993 } | 2008 } |
1994 } | 2009 } |
1995 | 2010 |
1996 | 2011 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 GrowableArray<intptr_t> class_ids; | 2112 GrowableArray<intptr_t> class_ids; |
2098 ic_data.GetCheckAt(0, &class_ids, &target); | 2113 ic_data.GetCheckAt(0, &class_ids, &target); |
2099 return (class_ids[0] == class_id) && (class_ids[1] == class_id); | 2114 return (class_ids[0] == class_id) && (class_ids[1] == class_id); |
2100 } | 2115 } |
2101 | 2116 |
2102 | 2117 |
2103 LocationSummary* BranchInstr::MakeLocationSummary() const { | 2118 LocationSummary* BranchInstr::MakeLocationSummary() const { |
2104 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) { | 2119 if ((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)) { |
2105 const int kNumInputs = 2; | 2120 const int kNumInputs = 2; |
2106 const int kNumTemps = 0; | 2121 const int kNumTemps = 0; |
2107 LocationSummary* locs = new LocationSummary(kNumInputs, | 2122 LocationSummary* locs = |
2108 kNumTemps, | 2123 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2109 LocationSummary::kNoCall); | |
2110 locs->set_in(0, Location::RequiresRegister()); | 2124 locs->set_in(0, Location::RequiresRegister()); |
2111 locs->set_in(1, Location::RequiresRegister()); | 2125 locs->set_in(1, Location::RequiresRegister()); |
2112 return locs; | 2126 return locs; |
2113 } | 2127 } |
2114 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 2128 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
2115 if (ICDataWithBothClassIds(*ic_data(), kSmi) || | 2129 if (ICDataWithBothClassIds(*ic_data(), kSmi) || |
2116 ICDataWithBothClassIds(*ic_data(), kDouble)) { | 2130 ICDataWithBothClassIds(*ic_data(), kDouble)) { |
2117 const intptr_t kNumInputs = 2; | 2131 const intptr_t kNumInputs = 2; |
2118 const intptr_t kNumTemps = 1; | 2132 const intptr_t kNumTemps = 1; |
2119 LocationSummary* summary = new LocationSummary(kNumInputs, | 2133 LocationSummary* summary = |
2120 kNumTemps, | 2134 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
2121 LocationSummary::kNoCall); | |
2122 summary->set_in(0, Location::RequiresRegister()); | 2135 summary->set_in(0, Location::RequiresRegister()); |
2123 summary->set_in(1, Location::RequiresRegister()); | 2136 summary->set_in(1, Location::RequiresRegister()); |
2124 summary->set_temp(0, Location::RequiresRegister()); | 2137 summary->set_temp(0, Location::RequiresRegister()); |
2125 return summary; | 2138 return summary; |
2126 } | 2139 } |
2127 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { | 2140 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { |
2128 const intptr_t kNumInputs = 2; | 2141 const intptr_t kNumInputs = 2; |
2129 const intptr_t kNumTemps = 1; | 2142 const intptr_t kNumTemps = 1; |
2130 LocationSummary* locs = new LocationSummary(kNumInputs, | 2143 LocationSummary* locs = |
2131 kNumTemps, | 2144 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
2132 LocationSummary::kCall); | |
2133 locs->set_in(0, Location::RegisterLocation(RAX)); | 2145 locs->set_in(0, Location::RegisterLocation(RAX)); |
2134 locs->set_in(1, Location::RegisterLocation(RCX)); | 2146 locs->set_in(1, Location::RegisterLocation(RCX)); |
2135 locs->set_temp(0, Location::RegisterLocation(RDX)); | 2147 locs->set_temp(0, Location::RegisterLocation(RDX)); |
2136 return locs; | 2148 return locs; |
2137 } | 2149 } |
2138 // Otherwise polymorphic dispatch. | 2150 // Otherwise polymorphic dispatch. |
2139 } | 2151 } |
2140 // Call. | 2152 // Call. |
2141 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); | 2153 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
2142 result->set_out(Location::RegisterLocation(RAX)); | 2154 result->set_out(Location::RegisterLocation(RAX)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 ASSERT(locs()->out().reg() == RAX); | 2206 ASSERT(locs()->out().reg() == RAX); |
2195 __ CompareObject(locs()->out().reg(), compiler->bool_true()); | 2207 __ CompareObject(locs()->out().reg(), compiler->bool_true()); |
2196 EmitBranchOnCondition(compiler, branch_condition); | 2208 EmitBranchOnCondition(compiler, branch_condition); |
2197 } | 2209 } |
2198 | 2210 |
2199 } // namespace dart | 2211 } // namespace dart |
2200 | 2212 |
2201 #undef __ | 2213 #undef __ |
2202 | 2214 |
2203 #endif // defined TARGET_ARCH_X64 | 2215 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |