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

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

Issue 10559035: Implement a simple register allocator that tries to keep instruction results in registers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_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 10 matching lines...) Expand all
21 DECLARE_FLAG(int, optimization_counter_threshold); 21 DECLARE_FLAG(int, optimization_counter_threshold);
22 DECLARE_FLAG(bool, trace_functions); 22 DECLARE_FLAG(bool, trace_functions);
23 23
24 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 24 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
25 computation()->EmitNativeCode(compiler); 25 computation()->EmitNativeCode(compiler);
26 if (locs()->out().kind() == Location::kRegister) { 26 if (locs()->out().kind() == Location::kRegister) {
27 // TODO(vegorov): this should really happen only for comparisons fused 27 // TODO(vegorov): this should really happen only for comparisons fused
28 // with branches. Currrently IR does not provide an easy way to remove 28 // with branches. Currrently IR does not provide an easy way to remove
29 // instructions from the graph so we just leave fused comparison in it 29 // instructions from the graph so we just leave fused comparison in it
30 // but change its result location to be NoLocation. 30 // but change its result location to be NoLocation.
31 __ pushq(locs()->out().reg()); 31 compiler->frame_register_allocator()->Push(locs()->out().reg(), this);
32 } 32 }
33 } 33 }
34 34
35 35
36 LocationSummary* ReturnInstr::MakeLocationSummary() const { 36 LocationSummary* ReturnInstr::MakeLocationSummary() const {
37 const intptr_t kNumInputs = 1; 37 const intptr_t kNumInputs = 1;
38 const intptr_t kNumTemps = 1; 38 const intptr_t kNumTemps = 1;
39 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 39 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
40 locs->set_in(0, Location::RegisterLocation(RAX)); 40 locs->set_in(0, Location::RegisterLocation(RAX));
41 locs->set_temp(0, Location::RequiresRegister()); 41 locs->set_temp(0, Location::RequiresRegister());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 98 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
99 cid(), 99 cid(),
100 token_index(), 100 token_index(),
101 CatchClauseNode::kInvalidTryIndex); 101 CatchClauseNode::kInvalidTryIndex);
102 } 102 }
103 103
104 104
105 // Generic summary for call instructions that have all arguments pushed 105 // Generic summary for call instructions that have all arguments pushed
106 // on the stack and return the result in a fixed register RAX. 106 // on the stack and return the result in a fixed register RAX.
107 LocationSummary* Computation::MakeCallSummary() { 107 LocationSummary* Computation::MakeCallSummary() {
108 LocationSummary* result = new LocationSummary(0, 0); 108 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
109 result->set_out(Location::RegisterLocation(RAX)); 109 result->set_out(Location::RegisterLocation(RAX));
110 return result; 110 return result;
111 } 111 }
112 112
113 113
114 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 114 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
115 const intptr_t kNumInputs = 0; 115 const intptr_t kNumInputs = 0;
116 const intptr_t kNumTemps = 1; 116 const intptr_t kNumTemps = 1;
117 LocationSummary* result = new LocationSummary(kNumInputs, kNumTemps); 117 LocationSummary* result = new LocationSummary(kNumInputs,
118 kNumTemps,
119 LocationSummary::kCall);
118 result->set_out(Location::RegisterLocation(RAX)); 120 result->set_out(Location::RegisterLocation(RAX));
119 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 121 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
120 return result; 122 return result;
121 } 123 }
122 124
123 125
124 LocationSummary* LoadLocalComp::MakeLocationSummary() const { 126 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
125 return LocationSummary::Make(0, Location::RequiresRegister()); 127 return LocationSummary::Make(0, Location::RequiresRegister());
126 } 128 }
127 129
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 kConditionTypeErrorRuntimeEntry); 193 kConditionTypeErrorRuntimeEntry);
192 // We should never return here. 194 // We should never return here.
193 __ int3(); 195 __ int3();
194 196
195 __ Bind(&done); 197 __ Bind(&done);
196 ASSERT(obj == result); 198 ASSERT(obj == result);
197 } 199 }
198 200
199 201
200 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 202 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
203 const LocationSummary::ContainsBranch contains_branch =
204 is_fused_with_branch() ? LocationSummary::kBranch
205 : LocationSummary::kNoBranch;
206
201 const intptr_t kNumInputs = 2; 207 const intptr_t kNumInputs = 2;
202 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 208 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) {
203 const intptr_t kNumTemps = 1; 209 const intptr_t kNumTemps = 1;
204 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 210 LocationSummary* locs = new LocationSummary(kNumInputs,
211 kNumTemps,
212 LocationSummary::kNoCall,
213 contains_branch);
205 locs->set_in(0, Location::RequiresRegister()); 214 locs->set_in(0, Location::RequiresRegister());
206 locs->set_in(1, Location::RequiresRegister()); 215 locs->set_in(1, Location::RequiresRegister());
207 locs->set_temp(0, Location::RequiresRegister()); 216 locs->set_temp(0, Location::RequiresRegister());
208 if (!is_fused_with_branch()) { 217 if (!is_fused_with_branch()) {
209 locs->set_out(Location::RequiresRegister()); 218 locs->set_out(Location::RequiresRegister());
210 } 219 }
211 return locs; 220 return locs;
212 } 221 }
213 if (NumTargets() > 0) { 222 if (NumTargets() > 0) {
214 const intptr_t kNumTemps = 1; 223 const intptr_t kNumTemps = 1;
215 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 224 LocationSummary* locs = new LocationSummary(kNumInputs,
225 kNumTemps,
226 LocationSummary::kCall,
227 contains_branch);
216 locs->set_in(0, Location::RequiresRegister()); 228 locs->set_in(0, Location::RequiresRegister());
217 locs->set_in(1, Location::RequiresRegister()); 229 locs->set_in(1, Location::RequiresRegister());
218 locs->set_temp(0, Location::RequiresRegister()); 230 locs->set_temp(0, Location::RequiresRegister());
219 if (!is_fused_with_branch()) { 231 if (!is_fused_with_branch()) {
220 locs->set_out(Location::RegisterLocation(RAX)); 232 locs->set_out(Location::RegisterLocation(RAX));
221 } 233 }
222 return locs; 234 return locs;
223 } 235 }
224 const intptr_t kNumTemps = 0; 236 const intptr_t kNumTemps = 0;
225 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 237 LocationSummary* locs = new LocationSummary(kNumInputs,
238 kNumTemps,
239 LocationSummary::kCall,
240 contains_branch);
226 locs->set_in(0, Location::RequiresRegister()); 241 locs->set_in(0, Location::RequiresRegister());
227 locs->set_in(1, Location::RequiresRegister()); 242 locs->set_in(1, Location::RequiresRegister());
228 if (!is_fused_with_branch()) { 243 if (!is_fused_with_branch()) {
229 locs->set_out(Location::RegisterLocation(RAX)); 244 locs->set_out(Location::RegisterLocation(RAX));
230 } 245 }
231 return locs; 246 return locs;
232 } 247 }
233 248
234 249
235 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, 250 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 421 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
407 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 422 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) {
408 EmitSmiEqualityCompare(compiler, this); 423 EmitSmiEqualityCompare(compiler, this);
409 return; 424 return;
410 } 425 }
411 EmitGenericEqualityCompare(compiler, this); 426 EmitGenericEqualityCompare(compiler, this);
412 } 427 }
413 428
414 429
415 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 430 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
431 const LocationSummary::ContainsBranch contains_branch =
432 is_fused_with_branch() ? LocationSummary::kBranch
433 : LocationSummary::kNoBranch;
434
416 if (operands_class_id() == kSmi || operands_class_id() == kDouble) { 435 if (operands_class_id() == kSmi || operands_class_id() == kDouble) {
417 const intptr_t kNumInputs = 2; 436 const intptr_t kNumInputs = 2;
418 const intptr_t kNumTemps = 1; 437 const intptr_t kNumTemps = 1;
419 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 438 LocationSummary* summary = new LocationSummary(kNumInputs,
439 kNumTemps,
440 LocationSummary::kCall,
441 contains_branch);
420 summary->set_in(0, Location::RequiresRegister()); 442 summary->set_in(0, Location::RequiresRegister());
421 summary->set_in(1, Location::RequiresRegister()); 443 summary->set_in(1, Location::RequiresRegister());
422 if (!is_fused_with_branch()) { 444 if (!is_fused_with_branch()) {
423 summary->set_out(Location::RequiresRegister()); 445 summary->set_out(Location::RequiresRegister());
424 } 446 }
425 summary->set_temp(0, Location::RequiresRegister()); 447 summary->set_temp(0, Location::RequiresRegister());
426 return summary; 448 return summary;
427 } 449 }
428 ASSERT(!is_fused_with_branch()); 450 ASSERT(!is_fused_with_branch());
429 ASSERT(operands_class_id() == kObject); 451 ASSERT(operands_class_id() == kObject);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 try_index(), 575 try_index(),
554 function_name, 576 function_name,
555 kNumArguments, 577 kNumArguments,
556 Array::ZoneHandle(), // No optional arguments. 578 Array::ZoneHandle(), // No optional arguments.
557 kNumArgsChecked); 579 kNumArgsChecked);
558 ASSERT(locs()->out().reg() == RAX); 580 ASSERT(locs()->out().reg() == RAX);
559 } 581 }
560 582
561 583
562 LocationSummary* NativeCallComp::MakeLocationSummary() const { 584 LocationSummary* NativeCallComp::MakeLocationSummary() const {
563 LocationSummary* locs = new LocationSummary(0, 3); 585 const intptr_t kNumInputs = 0;
586 const intptr_t kNumTemps = 3;
587 LocationSummary* locs = new LocationSummary(kNumInputs,
588 kNumTemps,
589 LocationSummary::kCall);
564 locs->set_temp(0, Location::RegisterLocation(RAX)); 590 locs->set_temp(0, Location::RegisterLocation(RAX));
565 locs->set_temp(1, Location::RegisterLocation(RBX)); 591 locs->set_temp(1, Location::RegisterLocation(RBX));
566 locs->set_temp(2, Location::RegisterLocation(R10)); 592 locs->set_temp(2, Location::RegisterLocation(R10));
567 locs->set_out(Location::RequiresRegister()); 593 locs->set_out(Location::RequiresRegister());
568 return locs; 594 return locs;
569 } 595 }
570 596
571 597
572 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 598 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
573 ASSERT(locs()->temp(0).reg() == RAX); 599 ASSERT(locs()->temp(0).reg() == RAX);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 798 }
773 799
774 default: 800 default:
775 UNREACHABLE(); 801 UNREACHABLE();
776 break; 802 break;
777 } 803 }
778 } 804 }
779 805
780 806
781 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { 807 LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
782 const intptr_t kNumInputs = 2; 808 return MakeCallSummary();
783 return LocationSummary::Make(kNumInputs, Location::NoLocation());
784 return NULL;
785 } 809 }
786 810
787 811
788 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 812 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
789 Register receiver = locs()->in(0).reg();
790 Register value = locs()->in(1).reg();
791
792 // Preserve the value (second argument) under the arguments as the result
793 // of the computation, then call the setter.
794 const String& function_name = 813 const String& function_name =
795 String::ZoneHandle(Field::SetterSymbol(field_name())); 814 String::ZoneHandle(Field::SetterSymbol(field_name()));
796 815
797 __ pushq(receiver);
798 __ pushq(value);
799 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 816 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
800 cid(), 817 cid(),
801 token_index(), 818 token_index(),
802 try_index()); 819 try_index());
803 const intptr_t kArgumentCount = 2; 820 const intptr_t kArgumentCount = 2;
804 const intptr_t kCheckedArgumentCount = 1; 821 const intptr_t kCheckedArgumentCount = 1;
805 compiler->GenerateInstanceCall(cid(), 822 compiler->GenerateInstanceCall(cid(),
806 token_index(), 823 token_index(),
807 try_index(), 824 try_index(),
808 function_name, 825 function_name,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 921 }
905 922
906 923
907 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 924 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
908 // TODO(regis): The elements of the array could be considered as arguments to 925 // TODO(regis): The elements of the array could be considered as arguments to
909 // CreateArrayComp, thereby making CreateArrayComp a call. 926 // CreateArrayComp, thereby making CreateArrayComp a call.
910 // For VerifyCallComputation to work, CreateArrayComp would need an 927 // For VerifyCallComputation to work, CreateArrayComp would need an
911 // ArgumentCount getter and an ArgumentAt getter. 928 // ArgumentCount getter and an ArgumentAt getter.
912 const intptr_t kNumInputs = 1; 929 const intptr_t kNumInputs = 1;
913 const intptr_t kNumTemps = 1; 930 const intptr_t kNumTemps = 1;
914 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 931 LocationSummary* locs = new LocationSummary(kNumInputs,
932 kNumTemps,
933 LocationSummary::kCall);
915 locs->set_in(0, Location::RegisterLocation(RBX)); 934 locs->set_in(0, Location::RegisterLocation(RBX));
916 locs->set_temp(0, Location::RegisterLocation(R10)); 935 locs->set_temp(0, Location::RegisterLocation(R10));
917 locs->set_out(Location::RegisterLocation(RAX)); 936 locs->set_out(Location::RegisterLocation(RAX));
918 return locs; 937 return locs;
919 } 938 }
920 939
921 940
922 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 941 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
923 Register temp_reg = locs()->temp(0).reg(); 942 Register temp_reg = locs()->temp(0).reg();
924 Register result_reg = locs()->out().reg(); 943 Register result_reg = locs()->out().reg();
(...skipping 11 matching lines...) Expand all
936 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); 955 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset()));
937 for (int i = ElementCount() - 1; i >= 0; --i) { 956 for (int i = ElementCount() - 1; i >= 0; --i) {
938 ASSERT(ElementAt(i)->IsUse()); 957 ASSERT(ElementAt(i)->IsUse());
939 __ popq(Address(temp_reg, i * kWordSize)); 958 __ popq(Address(temp_reg, i * kWordSize));
940 } 959 }
941 } 960 }
942 961
943 962
944 LocationSummary* AllocateObjectWithBoundsCheckComp:: 963 LocationSummary* AllocateObjectWithBoundsCheckComp::
945 MakeLocationSummary() const { 964 MakeLocationSummary() const {
946 return LocationSummary::Make(2, Location::RequiresRegister()); 965 return LocationSummary::Make(2,
966 Location::RequiresRegister(),
967 LocationSummary::kCall);
947 } 968 }
948 969
949 970
950 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 971 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
951 FlowGraphCompiler* compiler) { 972 FlowGraphCompiler* compiler) {
952 const Class& cls = Class::ZoneHandle(constructor().owner()); 973 const Class& cls = Class::ZoneHandle(constructor().owner());
953 Register type_arguments = locs()->in(0).reg(); 974 Register type_arguments = locs()->in(0).reg();
954 Register instantiator_type_arguments = locs()->in(1).reg(); 975 Register instantiator_type_arguments = locs()->in(1).reg();
955 Register result = locs()->out().reg(); 976 Register result = locs()->out().reg();
956 977
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); 1013 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt);
993 } 1014 }
994 1015
995 __ movq(result, FieldAddress(instance, offset_in_bytes())); 1016 __ movq(result, FieldAddress(instance, offset_in_bytes()));
996 } 1017 }
997 1018
998 1019
999 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 1020 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
1000 const intptr_t kNumInputs = 1; 1021 const intptr_t kNumInputs = 1;
1001 const intptr_t kNumTemps = 0; 1022 const intptr_t kNumTemps = 0;
1002 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1023 LocationSummary* locs = new LocationSummary(kNumInputs,
1024 kNumTemps,
1025 LocationSummary::kCall);
1003 locs->set_in(0, Location::RequiresRegister()); 1026 locs->set_in(0, Location::RequiresRegister());
1004 locs->set_out(Location::SameAsFirstInput()); 1027 locs->set_out(Location::SameAsFirstInput());
1005 return locs; 1028 return locs;
1006 } 1029 }
1007 1030
1008 1031
1009 void InstantiateTypeArgumentsComp::EmitNativeCode( 1032 void InstantiateTypeArgumentsComp::EmitNativeCode(
1010 FlowGraphCompiler* compiler) { 1033 FlowGraphCompiler* compiler) {
1011 Register instantiator_reg = locs()->in(0).reg(); 1034 Register instantiator_reg = locs()->in(0).reg();
1012 Register result_reg = locs()->out().reg(); 1035 Register result_reg = locs()->out().reg();
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1194 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1172 } 1195 }
1173 __ Bind(&done); 1196 __ Bind(&done);
1174 // instantiator_reg: instantiator or kNoInstantiator. 1197 // instantiator_reg: instantiator or kNoInstantiator.
1175 } 1198 }
1176 1199
1177 1200
1178 LocationSummary* AllocateContextComp::MakeLocationSummary() const { 1201 LocationSummary* AllocateContextComp::MakeLocationSummary() const {
1179 const intptr_t kNumInputs = 0; 1202 const intptr_t kNumInputs = 0;
1180 const intptr_t kNumTemps = 1; 1203 const intptr_t kNumTemps = 1;
1181 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1204 LocationSummary* locs = new LocationSummary(kNumInputs,
1205 kNumTemps,
1206 LocationSummary::kCall);
1182 locs->set_temp(0, Location::RegisterLocation(R10)); 1207 locs->set_temp(0, Location::RegisterLocation(R10));
1183 locs->set_out(Location::RegisterLocation(RAX)); 1208 locs->set_out(Location::RegisterLocation(RAX));
1184 return locs; 1209 return locs;
1185 } 1210 }
1186 1211
1187 1212
1188 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1213 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1189 ASSERT(locs()->temp(0).reg() == R10); 1214 ASSERT(locs()->temp(0).reg() == R10);
1190 1215
1191 __ movq(R10, Immediate(num_context_variables())); 1216 __ movq(R10, Immediate(num_context_variables()));
1192 const ExternalLabel label("alloc_context", 1217 const ExternalLabel label("alloc_context",
1193 StubCode::AllocateContextEntryPoint()); 1218 StubCode::AllocateContextEntryPoint());
1194 compiler->GenerateCall(token_index(), 1219 compiler->GenerateCall(token_index(),
1195 try_index(), 1220 try_index(),
1196 &label, 1221 &label,
1197 PcDescriptors::kOther); 1222 PcDescriptors::kOther);
1198 } 1223 }
1199 1224
1200 1225
1201 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1226 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1202 return LocationSummary::Make(1, Location::RequiresRegister()); 1227 return LocationSummary::Make(1,
1228 Location::RequiresRegister(),
1229 LocationSummary::kCall);
1203 } 1230 }
1204 1231
1205 1232
1206 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1233 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1207 Register context_value = locs()->in(0).reg(); 1234 Register context_value = locs()->in(0).reg();
1208 Register result = locs()->out().reg(); 1235 Register result = locs()->out().reg();
1209 1236
1210 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1237 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1211 __ pushq(context_value); 1238 __ pushq(context_value);
1212 compiler->GenerateCallRuntime(cid(), 1239 compiler->GenerateCallRuntime(cid(),
(...skipping 26 matching lines...) Expand all
1239 __ movq(Address(RBP, exception_var().index() * kWordSize), 1266 __ movq(Address(RBP, exception_var().index() * kWordSize),
1240 kExceptionObjectReg); 1267 kExceptionObjectReg);
1241 __ movq(Address(RBP, stacktrace_var().index() * kWordSize), 1268 __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
1242 kStackTraceObjectReg); 1269 kStackTraceObjectReg);
1243 } 1270 }
1244 1271
1245 1272
1246 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { 1273 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
1247 const intptr_t kNumInputs = 0; 1274 const intptr_t kNumInputs = 0;
1248 const intptr_t kNumTemps = 1; 1275 const intptr_t kNumTemps = 1;
1249 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1276 // TODO(vegorov): spilling is required only on infrequently executed path.
srdjan 2012/06/18 16:33:20 A quick fix could be to use the deoptimization stu
Vyacheslav Egorov (Google) 2012/06/18 17:51:16 Yes, I agree. In V8 we have a generic "deferred
1277 LocationSummary* summary = new LocationSummary(kNumInputs,
1278 kNumTemps,
1279 LocationSummary::kCall);
1250 summary->set_temp(0, Location::RequiresRegister()); 1280 summary->set_temp(0, Location::RequiresRegister());
1251 return summary; 1281 return summary;
1252 } 1282 }
1253 1283
1254 1284
1255 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1285 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1256 Register temp = locs()->temp(0).reg(); 1286 Register temp = locs()->temp(0).reg();
1257 // Generate stack overflow check. 1287 // Generate stack overflow check.
1258 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); 1288 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
1259 __ cmpq(RSP, Address(temp, 0)); 1289 __ cmpq(RSP, Address(temp, 0));
1260 Label no_stack_overflow; 1290 Label no_stack_overflow;
1261 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 1291 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
1262 compiler->GenerateCallRuntime(cid(), 1292 compiler->GenerateCallRuntime(cid(),
1263 token_index(), 1293 token_index(),
1264 try_index(), 1294 try_index(),
1265 kStackOverflowRuntimeEntry); 1295 kStackOverflowRuntimeEntry);
1266 __ Bind(&no_stack_overflow); 1296 __ Bind(&no_stack_overflow);
1267 } 1297 }
1268 1298
1269 1299
1270 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1300 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
1271 const intptr_t kNumInputs = 2; 1301 const intptr_t kNumInputs = 2;
1272 1302
1273 if (operands_type() == kDoubleOperands) { 1303 if (operands_type() == kDoubleOperands) {
1274 const intptr_t kNumTemps = 1; 1304 return MakeCallSummary(); // Calls into a stub for allocation.
1275 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1276 summary->set_in(0, Location::RequiresRegister());
1277 summary->set_in(1, Location::RequiresRegister());
1278 summary->set_out(Location::RegisterLocation(RAX));
1279 summary->set_temp(0, Location::RequiresRegister());
1280 return summary;
1281 } 1305 }
1282 1306
1283 ASSERT(operands_type() == kSmiOperands); 1307 ASSERT(operands_type() == kSmiOperands);
1284 1308
1285 if (op_kind() == Token::kTRUNCDIV) { 1309 if (op_kind() == Token::kTRUNCDIV) {
1286 const intptr_t kNumTemps = 3; 1310 const intptr_t kNumTemps = 3;
1287 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1311 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1288 summary->set_in(0, Location::RegisterLocation(RAX)); 1312 summary->set_in(0, Location::RegisterLocation(RAX));
1289 summary->set_in(1, Location::RegisterLocation(RCX)); 1313 summary->set_in(1, Location::RegisterLocation(RCX));
1290 summary->set_out(Location::SameAsFirstInput()); 1314 summary->set_out(Location::SameAsFirstInput());
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 } 1473 }
1450 default: 1474 default:
1451 UNREACHABLE(); 1475 UNREACHABLE();
1452 break; 1476 break;
1453 } 1477 }
1454 } 1478 }
1455 1479
1456 1480
1457 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, 1481 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
1458 BinaryOpComp* comp) { 1482 BinaryOpComp* comp) {
1459 Register left = comp->locs()->in(0).reg(); 1483 Register left = RBX;
1460 Register right = comp->locs()->in(1).reg(); 1484 Register right = RCX;
1461 Register temp = comp->locs()->temp(0).reg(); 1485 Register temp = RDX;
1462 Register result = comp->locs()->out().reg(); 1486 Register result = comp->locs()->out().reg();
1463 1487
1464 const Class& double_class = compiler->double_class(); 1488 const Class& double_class = compiler->double_class();
1465 const Code& stub = 1489 const Code& stub =
1466 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1490 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1467 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1491 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1468 __ pushq(left);
1469 __ pushq(right);
1470 compiler->GenerateCall(comp->instance_call()->token_index(), 1492 compiler->GenerateCall(comp->instance_call()->token_index(),
1471 comp->instance_call()->try_index(), 1493 comp->instance_call()->try_index(),
1472 &label, 1494 &label,
1473 PcDescriptors::kOther); 1495 PcDescriptors::kOther);
1474 // Newly allocated object is now in the result register (RAX). 1496 // Newly allocated object is now in the result register (RAX).
1475 ASSERT(result == RAX); 1497 ASSERT(result == RAX);
1476 __ popq(right); 1498 __ popq(right);
1477 __ popq(left); 1499 __ popq(left);
1478 1500
1479 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1501 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 } 1581 }
1560 } else { 1582 } else {
1561 UNREACHABLE(); 1583 UNREACHABLE();
1562 } 1584 }
1563 } 1585 }
1564 1586
1565 1587
1566 LocationSummary* NumberNegateComp::MakeLocationSummary() const { 1588 LocationSummary* NumberNegateComp::MakeLocationSummary() const {
1567 const intptr_t kNumInputs = 1; 1589 const intptr_t kNumInputs = 1;
1568 const intptr_t kNumTemps = 1; // Needed for doubles. 1590 const intptr_t kNumTemps = 1; // Needed for doubles.
1569 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1591 LocationSummary* summary = new LocationSummary(kNumInputs,
1592 kNumTemps,
1593 LocationSummary::kCall);
1570 summary->set_in(0, Location::RequiresRegister()); 1594 summary->set_in(0, Location::RequiresRegister());
1571 summary->set_out(Location::SameAsFirstInput()); 1595 summary->set_out(Location::SameAsFirstInput());
1572 summary->set_temp(0, Location::RequiresRegister()); 1596 summary->set_temp(0, Location::RequiresRegister());
1573 return summary; 1597 return summary;
1574 } 1598 }
1575 1599
1576 1600
1577 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1601 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1578 const ICData& ic_data = *instance_call()->ic_data(); 1602 const ICData& ic_data = *instance_call()->ic_data();
1579 ASSERT(!ic_data.IsNull()); 1603 ASSERT(!ic_data.IsNull());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 LocationSummary* ToDoubleComp::MakeLocationSummary() const { 1649 LocationSummary* ToDoubleComp::MakeLocationSummary() const {
1626 const intptr_t kNumInputs = 1; 1650 const intptr_t kNumInputs = 1;
1627 if (from() == kDouble) { 1651 if (from() == kDouble) {
1628 const intptr_t kNumTemps = 0; 1652 const intptr_t kNumTemps = 0;
1629 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1653 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
1630 locs->set_in(0, Location::RequiresRegister()); 1654 locs->set_in(0, Location::RequiresRegister());
1631 locs->set_out(Location::SameAsFirstInput()); 1655 locs->set_out(Location::SameAsFirstInput());
1632 return locs; 1656 return locs;
1633 } else { 1657 } else {
1634 ASSERT(from() == kSmi); 1658 ASSERT(from() == kSmi);
1635 return LocationSummary::Make(kNumInputs, Location::RegisterLocation(RAX)); 1659 return MakeCallSummary();
1636 } 1660 }
1637 } 1661 }
1638 1662
1639 1663
1640 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1664 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1641 Register value = locs()->in(0).reg(); 1665 Register value = (from() == kDouble) ? locs()->in(0).reg() : RBX;
1642 Register result = locs()->out().reg(); 1666 Register result = locs()->out().reg();
1643 1667
1644 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1668 const DeoptReasonId deopt_reason = (from() == kDouble) ?
1645 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1669 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1646 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1670 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1647 instance_call()->token_index(), 1671 instance_call()->token_index(),
1648 instance_call()->try_index(), 1672 instance_call()->try_index(),
1649 deopt_reason, 1673 deopt_reason,
1650 value); 1674 value);
1651 1675
1652 if (from() == kDouble) { 1676 if (from() == kDouble) {
1653 __ testq(value, Immediate(kSmiTagMask)); 1677 __ testq(value, Immediate(kSmiTagMask));
1654 __ j(ZERO, deopt); // Deoptimize if Smi. 1678 __ j(ZERO, deopt); // Deoptimize if Smi.
1655 __ CompareClassId(value, kDouble); 1679 __ CompareClassId(value, kDouble);
1656 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1680 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1657 ASSERT(value == result); 1681 ASSERT(value == result);
1658 return; 1682 return;
1659 } 1683 }
1660 1684
1661 ASSERT(from() == kSmi); 1685 ASSERT(from() == kSmi);
1662 1686
1663 const Class& double_class = compiler->double_class(); 1687 const Class& double_class = compiler->double_class();
1664 const Code& stub = 1688 const Code& stub =
1665 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1689 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1666 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1690 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1667 1691
1668 // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping. 1692 // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping.
1669 __ pushq(value);
1670 compiler->GenerateCall(instance_call()->token_index(), 1693 compiler->GenerateCall(instance_call()->token_index(),
1671 instance_call()->try_index(), 1694 instance_call()->try_index(),
1672 &label, 1695 &label,
1673 PcDescriptors::kOther); 1696 PcDescriptors::kOther);
1674 ASSERT(result == RAX); 1697 ASSERT(result == RAX);
1675 __ popq(value); 1698 __ popq(value);
1676 1699
1677 __ testq(value, Immediate(kSmiTagMask)); 1700 __ testq(value, Immediate(kSmiTagMask));
1678 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 1701 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
1679 __ SmiUntag(value); 1702 __ SmiUntag(value);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 instance_call()->argument_names()); 1751 instance_call()->argument_names());
1729 } 1752 }
1730 __ Bind(&done); 1753 __ Bind(&done);
1731 } 1754 }
1732 1755
1733 } // namespace dart 1756 } // namespace dart
1734 1757
1735 #undef __ 1758 #undef __
1736 1759
1737 #endif // defined TARGET_ARCH_X64 1760 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698