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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
15 15
16 #define __ compiler->assembler()-> 16 #define __ compiler->assembler()->
17 17
18 namespace dart { 18 namespace dart {
19 19
20 DECLARE_FLAG(int, optimization_counter_threshold); 20 DECLARE_FLAG(int, optimization_counter_threshold);
21 DECLARE_FLAG(bool, trace_functions); 21 DECLARE_FLAG(bool, trace_functions);
22 22
23 // Generic summary for call instructions that have all arguments pushed 23 // Generic summary for call instructions that have all arguments pushed
24 // on the stack and return the result in a fixed register EAX. 24 // on the stack and return the result in a fixed register EAX.
25 LocationSummary* Computation::MakeCallSummary() { 25 LocationSummary* Computation::MakeCallSummary() {
26 LocationSummary* result = new LocationSummary(0, 0); 26 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
27 result->set_out(Location::RegisterLocation(EAX)); 27 result->set_out(Location::RegisterLocation(EAX));
28 return result; 28 return result;
29 } 29 }
30 30
31 31
32 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 32 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
33 computation()->EmitNativeCode(compiler); 33 computation()->EmitNativeCode(compiler);
34 if (locs()->out().kind() == Location::kRegister) { 34 if (locs()->out().kind() == Location::kRegister) {
35 // TODO(vegorov): this should really happen only for comparisons fused 35 // TODO(vegorov): this should really happen only for comparisons fused
36 // with branches. Currrently IR does not provide an easy way to remove 36 // with branches. Currrently IR does not provide an easy way to remove
37 // instructions from the graph so we just leave fused comparison in it 37 // instructions from the graph so we just leave fused comparison in it
38 // but change its result location to be NoLocation. 38 // but change its result location to be NoLocation.
39 __ pushl(locs()->out().reg()); 39 compiler->frame_register_allocator()->Push(locs()->out().reg(), this);
40 } 40 }
41 } 41 }
42 42
43 43
44 LocationSummary* ReturnInstr::MakeLocationSummary() const { 44 LocationSummary* ReturnInstr::MakeLocationSummary() const {
45 const intptr_t kNumInputs = 1; 45 const intptr_t kNumInputs = 1;
46 const intptr_t kNumTemps = 1; 46 const intptr_t kNumTemps = 1;
47 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 47 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
48 locs->set_in(0, Location::RegisterLocation(EAX)); 48 locs->set_in(0, Location::RegisterLocation(EAX));
49 locs->set_temp(0, Location::RequiresRegister()); 49 locs->set_temp(0, Location::RequiresRegister());
(...skipping 48 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 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 105 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
106 const intptr_t kNumInputs = 0; 106 const intptr_t kNumInputs = 0;
107 const intptr_t kNumTemps = 1; 107 const intptr_t kNumTemps = 1;
108 LocationSummary* result = new LocationSummary(kNumInputs, kNumTemps); 108 LocationSummary* result = new LocationSummary(kNumInputs,
109 kNumTemps,
110 LocationSummary::kCall);
109 result->set_out(Location::RegisterLocation(EAX)); 111 result->set_out(Location::RegisterLocation(EAX));
110 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. 112 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
111 return result; 113 return result;
112 } 114 }
113 115
114 116
115 LocationSummary* LoadLocalComp::MakeLocationSummary() const { 117 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
116 return LocationSummary::Make(0, Location::RequiresRegister()); 118 return LocationSummary::Make(0, Location::RequiresRegister());
117 } 119 }
118 120
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 kConditionTypeErrorRuntimeEntry); 184 kConditionTypeErrorRuntimeEntry);
183 // We should never return here. 185 // We should never return here.
184 __ int3(); 186 __ int3();
185 187
186 __ Bind(&done); 188 __ Bind(&done);
187 ASSERT(obj == result); 189 ASSERT(obj == result);
188 } 190 }
189 191
190 192
191 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 193 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
194 const LocationSummary::ContainsBranch contains_branch =
195 is_fused_with_branch() ? LocationSummary::kBranch
196 : LocationSummary::kNoBranch;
197
192 const intptr_t kNumInputs = 2; 198 const intptr_t kNumInputs = 2;
193 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 199 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) {
194 const intptr_t kNumTemps = 1; 200 const intptr_t kNumTemps = 1;
195 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 201 LocationSummary* locs = new LocationSummary(kNumInputs,
202 kNumTemps,
203 LocationSummary::kNoCall,
204 contains_branch);
196 locs->set_in(0, Location::RequiresRegister()); 205 locs->set_in(0, Location::RequiresRegister());
197 locs->set_in(1, Location::RequiresRegister()); 206 locs->set_in(1, Location::RequiresRegister());
198 locs->set_temp(0, Location::RequiresRegister()); 207 locs->set_temp(0, Location::RequiresRegister());
199 if (!is_fused_with_branch()) { 208 if (!is_fused_with_branch()) {
200 locs->set_out(Location::RequiresRegister()); 209 locs->set_out(Location::RequiresRegister());
201 } 210 }
202 return locs; 211 return locs;
203 } 212 }
204 if (NumTargets() > 0) { 213 if (NumTargets() > 0) {
205 const intptr_t kNumTemps = 1; 214 const intptr_t kNumTemps = 1;
206 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 215 LocationSummary* locs = new LocationSummary(kNumInputs,
216 kNumTemps,
217 LocationSummary::kCall,
218 contains_branch);
207 locs->set_in(0, Location::RequiresRegister()); 219 locs->set_in(0, Location::RequiresRegister());
208 locs->set_in(1, Location::RequiresRegister()); 220 locs->set_in(1, Location::RequiresRegister());
209 locs->set_temp(0, Location::RequiresRegister()); 221 locs->set_temp(0, Location::RequiresRegister());
210 if (!is_fused_with_branch()) { 222 if (!is_fused_with_branch()) {
211 locs->set_out(Location::RegisterLocation(EAX)); 223 locs->set_out(Location::RegisterLocation(EAX));
212 } 224 }
213 return locs; 225 return locs;
214 } 226 }
215 const intptr_t kNumTemps = 0; 227 const intptr_t kNumTemps = 0;
216 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 228 LocationSummary* locs = new LocationSummary(kNumInputs,
229 kNumTemps,
230 LocationSummary::kCall,
231 contains_branch);
217 locs->set_in(0, Location::RequiresRegister()); 232 locs->set_in(0, Location::RequiresRegister());
218 locs->set_in(1, Location::RequiresRegister()); 233 locs->set_in(1, Location::RequiresRegister());
219 if (!is_fused_with_branch()) { 234 if (!is_fused_with_branch()) {
220 locs->set_out(Location::RegisterLocation(EAX)); 235 locs->set_out(Location::RegisterLocation(EAX));
221 } 236 }
222 return locs; 237 return locs;
223 } 238 }
224 239
225 240
226 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, 241 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 411 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
397 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 412 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) {
398 EmitSmiEqualityCompare(compiler, this); 413 EmitSmiEqualityCompare(compiler, this);
399 return; 414 return;
400 } 415 }
401 EmitGenericEqualityCompare(compiler, this); 416 EmitGenericEqualityCompare(compiler, this);
402 } 417 }
403 418
404 419
405 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 420 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
421 const LocationSummary::ContainsBranch contains_branch =
422 is_fused_with_branch() ? LocationSummary::kBranch
423 : LocationSummary::kNoBranch;
424
406 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) { 425 if ((operands_class_id() == kSmi) || (operands_class_id() == kDouble)) {
407 const intptr_t kNumInputs = 2; 426 const intptr_t kNumInputs = 2;
408 const intptr_t kNumTemps = 1; 427 const intptr_t kNumTemps = 1;
409 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 428 LocationSummary* summary = new LocationSummary(kNumInputs,
429 kNumTemps,
430 LocationSummary::kNoCall,
431 contains_branch);
410 summary->set_in(0, Location::RequiresRegister()); 432 summary->set_in(0, Location::RequiresRegister());
411 summary->set_in(1, Location::RequiresRegister()); 433 summary->set_in(1, Location::RequiresRegister());
412 if (!is_fused_with_branch()) { 434 if (!is_fused_with_branch()) {
413 summary->set_out(Location::RequiresRegister()); 435 summary->set_out(Location::RequiresRegister());
414 } 436 }
415 summary->set_temp(0, Location::RequiresRegister()); 437 summary->set_temp(0, Location::RequiresRegister());
416 return summary; 438 return summary;
417 } 439 }
418 ASSERT(operands_class_id() == kObject); 440 ASSERT(operands_class_id() == kObject);
419 return MakeCallSummary(); 441 return MakeCallSummary();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 try_index(), 566 try_index(),
545 function_name, 567 function_name,
546 kNumArguments, 568 kNumArguments,
547 Array::ZoneHandle(), // No optional arguments. 569 Array::ZoneHandle(), // No optional arguments.
548 kNumArgsChecked); 570 kNumArgsChecked);
549 ASSERT(locs()->out().reg() == EAX); 571 ASSERT(locs()->out().reg() == EAX);
550 } 572 }
551 573
552 574
553 LocationSummary* NativeCallComp::MakeLocationSummary() const { 575 LocationSummary* NativeCallComp::MakeLocationSummary() const {
554 LocationSummary* locs = new LocationSummary(0, 3); 576 LocationSummary* locs = new LocationSummary(0, 3, LocationSummary::kCall);
555 locs->set_temp(0, Location::RegisterLocation(EAX)); 577 locs->set_temp(0, Location::RegisterLocation(EAX));
556 locs->set_temp(1, Location::RegisterLocation(ECX)); 578 locs->set_temp(1, Location::RegisterLocation(ECX));
557 locs->set_temp(2, Location::RegisterLocation(EDX)); 579 locs->set_temp(2, Location::RegisterLocation(EDX));
558 locs->set_out(Location::RequiresRegister()); 580 locs->set_out(Location::RequiresRegister());
559 return locs; 581 return locs;
560 } 582 }
561 583
562 584
563 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 585 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
564 ASSERT(locs()->temp(0).reg() == EAX); 586 ASSERT(locs()->temp(0).reg() == EAX);
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 } 783 }
762 784
763 default: 785 default:
764 UNREACHABLE(); 786 UNREACHABLE();
765 break; 787 break;
766 } 788 }
767 } 789 }
768 790
769 791
770 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { 792 LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
771 const intptr_t kNumInputs = 2; 793 return MakeCallSummary();
772 return LocationSummary::Make(kNumInputs, Location::NoLocation());
773 } 794 }
774 795
775 796
776 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 797 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
777 Register receiver = locs()->in(0).reg();
778 Register value = locs()->in(1).reg();
779
780 // Preserve the value (second argument) under the arguments as the result
781 // of the computation, then call the setter.
782 const String& function_name = 798 const String& function_name =
783 String::ZoneHandle(Field::SetterSymbol(field_name())); 799 String::ZoneHandle(Field::SetterSymbol(field_name()));
784 800
785 __ pushl(receiver);
786 __ pushl(value);
787 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 801 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
788 cid(), 802 cid(),
789 token_index(), 803 token_index(),
790 try_index()); 804 try_index());
791 const intptr_t kArgumentCount = 2; 805 const intptr_t kArgumentCount = 2;
792 const intptr_t kCheckedArgumentCount = 1; 806 const intptr_t kCheckedArgumentCount = 1;
793 compiler->GenerateInstanceCall(cid(), 807 compiler->GenerateInstanceCall(cid(),
794 token_index(), 808 token_index(),
795 try_index(), 809 try_index(),
796 function_name, 810 function_name,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 } 906 }
893 907
894 908
895 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 909 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
896 // TODO(regis): The elements of the array could be considered as arguments to 910 // TODO(regis): The elements of the array could be considered as arguments to
897 // CreateArrayComp, thereby making CreateArrayComp a call. 911 // CreateArrayComp, thereby making CreateArrayComp a call.
898 // For VerifyCallComputation to work, CreateArrayComp would need an 912 // For VerifyCallComputation to work, CreateArrayComp would need an
899 // ArgumentCount getter and an ArgumentAt getter. 913 // ArgumentCount getter and an ArgumentAt getter.
900 const intptr_t kNumInputs = 1; 914 const intptr_t kNumInputs = 1;
901 const intptr_t kNumTemps = 1; 915 const intptr_t kNumTemps = 1;
902 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 916 LocationSummary* locs = new LocationSummary(kNumInputs,
917 kNumTemps,
918 LocationSummary::kCall);
903 locs->set_in(0, Location::RegisterLocation(ECX)); 919 locs->set_in(0, Location::RegisterLocation(ECX));
904 locs->set_temp(0, Location::RegisterLocation(EDX)); 920 locs->set_temp(0, Location::RegisterLocation(EDX));
905 locs->set_out(Location::RegisterLocation(EAX)); 921 locs->set_out(Location::RegisterLocation(EAX));
906 return locs; 922 return locs;
907 } 923 }
908 924
909 925
910 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 926 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
911 Register temp_reg = locs()->temp(0).reg(); 927 Register temp_reg = locs()->temp(0).reg();
912 Register result_reg = locs()->out().reg(); 928 Register result_reg = locs()->out().reg();
(...skipping 10 matching lines...) Expand all
923 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); 939 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset()));
924 for (int i = ElementCount() - 1; i >= 0; --i) { 940 for (int i = ElementCount() - 1; i >= 0; --i) {
925 ASSERT(ElementAt(i)->IsUse()); 941 ASSERT(ElementAt(i)->IsUse());
926 __ popl(Address(temp_reg, i * kWordSize)); 942 __ popl(Address(temp_reg, i * kWordSize));
927 } 943 }
928 } 944 }
929 945
930 946
931 LocationSummary* 947 LocationSummary*
932 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const { 948 AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const {
933 return LocationSummary::Make(2, Location::RequiresRegister()); 949 return LocationSummary::Make(2,
950 Location::RequiresRegister(),
951 LocationSummary::kCall);
934 } 952 }
935 953
936 954
937 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 955 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
938 FlowGraphCompiler* compiler) { 956 FlowGraphCompiler* compiler) {
939 const Class& cls = Class::ZoneHandle(constructor().owner()); 957 const Class& cls = Class::ZoneHandle(constructor().owner());
940 Register type_arguments = locs()->in(0).reg(); 958 Register type_arguments = locs()->in(0).reg();
941 Register instantiator_type_arguments = locs()->in(1).reg(); 959 Register instantiator_type_arguments = locs()->in(1).reg();
942 Register result = locs()->out().reg(); 960 Register result = locs()->out().reg();
943 961
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); 996 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt);
979 } 997 }
980 998
981 __ movl(result, FieldAddress(instance, offset_in_bytes())); 999 __ movl(result, FieldAddress(instance, offset_in_bytes()));
982 } 1000 }
983 1001
984 1002
985 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 1003 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
986 const intptr_t kNumInputs = 1; 1004 const intptr_t kNumInputs = 1;
987 const intptr_t kNumTemps = 1; 1005 const intptr_t kNumTemps = 1;
988 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1006 LocationSummary* locs = new LocationSummary(kNumInputs,
1007 kNumTemps,
1008 LocationSummary::kCall);
989 locs->set_in(0, Location::RequiresRegister()); 1009 locs->set_in(0, Location::RequiresRegister());
990 locs->set_temp(0, Location::RequiresRegister()); 1010 locs->set_temp(0, Location::RequiresRegister());
991 locs->set_out(Location::SameAsFirstInput()); 1011 locs->set_out(Location::SameAsFirstInput());
992 return locs; 1012 return locs;
993 } 1013 }
994 1014
995 1015
996 void InstantiateTypeArgumentsComp::EmitNativeCode( 1016 void InstantiateTypeArgumentsComp::EmitNativeCode(
997 FlowGraphCompiler* compiler) { 1017 FlowGraphCompiler* compiler) {
998 Register instantiator_reg = locs()->in(0).reg(); 1018 Register instantiator_reg = locs()->in(0).reg();
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1181 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1162 } 1182 }
1163 __ Bind(&done); 1183 __ Bind(&done);
1164 // instantiator_reg: instantiator or kNoInstantiator. 1184 // instantiator_reg: instantiator or kNoInstantiator.
1165 } 1185 }
1166 1186
1167 1187
1168 LocationSummary* AllocateContextComp::MakeLocationSummary() const { 1188 LocationSummary* AllocateContextComp::MakeLocationSummary() const {
1169 const intptr_t kNumInputs = 0; 1189 const intptr_t kNumInputs = 0;
1170 const intptr_t kNumTemps = 1; 1190 const intptr_t kNumTemps = 1;
1171 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1191 LocationSummary* locs = new LocationSummary(kNumInputs,
1192 kNumTemps,
1193 LocationSummary::kCall);
1172 locs->set_temp(0, Location::RegisterLocation(EDX)); 1194 locs->set_temp(0, Location::RegisterLocation(EDX));
1173 locs->set_out(Location::RegisterLocation(EAX)); 1195 locs->set_out(Location::RegisterLocation(EAX));
1174 return locs; 1196 return locs;
1175 } 1197 }
1176 1198
1177 1199
1178 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1200 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1179 ASSERT(locs()->temp(0).reg() == EDX); 1201 ASSERT(locs()->temp(0).reg() == EDX);
1180 ASSERT(locs()->out().reg() == EAX); 1202 ASSERT(locs()->out().reg() == EAX);
1181 1203
1182 __ movl(EDX, Immediate(num_context_variables())); 1204 __ movl(EDX, Immediate(num_context_variables()));
1183 const ExternalLabel label("alloc_context", 1205 const ExternalLabel label("alloc_context",
1184 StubCode::AllocateContextEntryPoint()); 1206 StubCode::AllocateContextEntryPoint());
1185 compiler->GenerateCall(token_index(), 1207 compiler->GenerateCall(token_index(),
1186 try_index(), 1208 try_index(),
1187 &label, 1209 &label,
1188 PcDescriptors::kOther); 1210 PcDescriptors::kOther);
1189 } 1211 }
1190 1212
1191 1213
1192 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1214 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1193 return LocationSummary::Make(1, Location::RequiresRegister()); 1215 return LocationSummary::Make(1,
1216 Location::RequiresRegister(),
1217 LocationSummary::kCall);
1194 } 1218 }
1195 1219
1196 1220
1197 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1221 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1198 Register context_value = locs()->in(0).reg(); 1222 Register context_value = locs()->in(0).reg();
1199 Register result = locs()->out().reg(); 1223 Register result = locs()->out().reg();
1200 1224
1201 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1225 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1202 __ pushl(context_value); 1226 __ pushl(context_value);
1203 compiler->GenerateCallRuntime(cid(), 1227 compiler->GenerateCallRuntime(cid(),
(...skipping 24 matching lines...) Expand all
1228 ASSERT(!exception_var().is_captured()); 1252 ASSERT(!exception_var().is_captured());
1229 ASSERT(!stacktrace_var().is_captured()); 1253 ASSERT(!stacktrace_var().is_captured());
1230 __ movl(Address(EBP, exception_var().index() * kWordSize), 1254 __ movl(Address(EBP, exception_var().index() * kWordSize),
1231 kExceptionObjectReg); 1255 kExceptionObjectReg);
1232 __ movl(Address(EBP, stacktrace_var().index() * kWordSize), 1256 __ movl(Address(EBP, stacktrace_var().index() * kWordSize),
1233 kStackTraceObjectReg); 1257 kStackTraceObjectReg);
1234 } 1258 }
1235 1259
1236 1260
1237 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { 1261 LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const {
1238 return LocationSummary::Make(0, Location::NoLocation()); 1262 return LocationSummary::Make(0,
1263 Location::NoLocation(),
1264 LocationSummary::kCall);
1239 } 1265 }
1240 1266
1241 1267
1242 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1268 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1243 __ cmpl(ESP, 1269 __ cmpl(ESP,
1244 Address::Absolute(Isolate::Current()->stack_limit_address())); 1270 Address::Absolute(Isolate::Current()->stack_limit_address()));
1245 Label no_stack_overflow; 1271 Label no_stack_overflow;
1246 __ j(ABOVE, &no_stack_overflow); 1272 __ j(ABOVE, &no_stack_overflow);
1247 compiler->GenerateCallRuntime(cid(), 1273 compiler->GenerateCallRuntime(cid(),
1248 token_index(), 1274 token_index(),
1249 try_index(), 1275 try_index(),
1250 kStackOverflowRuntimeEntry); 1276 kStackOverflowRuntimeEntry);
1251 __ Bind(&no_stack_overflow); 1277 __ Bind(&no_stack_overflow);
1252 } 1278 }
1253 1279
1254 1280
1255 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1281 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
1256 const intptr_t kNumInputs = 2; 1282 const intptr_t kNumInputs = 2;
1257 if (operands_type() == kDoubleOperands) { 1283 if (operands_type() == kDoubleOperands) {
1258 const intptr_t kNumTemps = 1; 1284 return MakeCallSummary(); // Calls into a stub for allocation.
1259 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1260 summary->set_in(0, Location::RequiresRegister());
1261 summary->set_in(1, Location::RequiresRegister());
1262 summary->set_out(Location::RegisterLocation(EAX));
1263 summary->set_temp(0, Location::RequiresRegister());
1264 return summary;
1265 } 1285 }
1266 ASSERT(operands_type() == kSmiOperands); 1286 ASSERT(operands_type() == kSmiOperands);
1267 if (op_kind() == Token::kTRUNCDIV) { 1287 if (op_kind() == Token::kTRUNCDIV) {
1268 const intptr_t kNumTemps = 3; 1288 const intptr_t kNumTemps = 3;
1269 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1289 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1270 summary->set_in(0, Location::RegisterLocation(EAX)); 1290 summary->set_in(0, Location::RegisterLocation(EAX));
1271 summary->set_in(1, Location::RegisterLocation(ECX)); 1291 summary->set_in(1, Location::RegisterLocation(ECX));
1272 summary->set_out(Location::SameAsFirstInput()); 1292 summary->set_out(Location::SameAsFirstInput());
1273 summary->set_temp(0, Location::RegisterLocation(EBX)); 1293 summary->set_temp(0, Location::RegisterLocation(EBX));
1274 // Will be used for for sign extension. 1294 // Will be used for for sign extension.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 Register right = comp->locs()->in(1).reg(); 1329 Register right = comp->locs()->in(1).reg();
1310 Register result = comp->locs()->out().reg(); 1330 Register result = comp->locs()->out().reg();
1311 Register temp = comp->locs()->temp(0).reg(); 1331 Register temp = comp->locs()->temp(0).reg();
1312 ASSERT(left == result); 1332 ASSERT(left == result);
1313 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1333 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1314 comp->instance_call()->token_index(), 1334 comp->instance_call()->token_index(),
1315 comp->instance_call()->try_index(), 1335 comp->instance_call()->try_index(),
1316 kDeoptSmiBinaryOp, 1336 kDeoptSmiBinaryOp,
1317 temp, 1337 temp,
1318 right); 1338 right);
1339 // TODO(vegorov): for many binary operations this pattern can be rearrange
srdjan 2012/06/18 16:33:20 rearranged
Vyacheslav Egorov (Google) 2012/06/18 17:51:16 Done.
1340 // to save one move.
1319 __ movl(temp, left); 1341 __ movl(temp, left);
1320 __ orl(left, right); 1342 __ orl(left, right);
1321 __ testl(left, Immediate(kSmiTagMask)); 1343 __ testl(left, Immediate(kSmiTagMask));
1322 __ j(NOT_ZERO, deopt); 1344 __ j(NOT_ZERO, deopt);
1323 __ movl(left, temp); 1345 __ movl(left, temp);
1324 switch (comp->op_kind()) { 1346 switch (comp->op_kind()) {
1325 case Token::kADD: { 1347 case Token::kADD: {
1326 __ addl(left, right); 1348 __ addl(left, right);
1327 __ j(OVERFLOW, deopt); 1349 __ j(OVERFLOW, deopt);
1328 break; 1350 break;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 } 1453 }
1432 default: 1454 default:
1433 UNREACHABLE(); 1455 UNREACHABLE();
1434 break; 1456 break;
1435 } 1457 }
1436 } 1458 }
1437 1459
1438 1460
1439 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, 1461 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
1440 BinaryOpComp* comp) { 1462 BinaryOpComp* comp) {
1441 Register left = comp->locs()->in(0).reg(); 1463 Register left = EBX;
1442 Register right = comp->locs()->in(1).reg(); 1464 Register right = ECX;
1443 Register temp = comp->locs()->temp(0).reg(); 1465 Register temp = EDX;
1444 Register result = comp->locs()->out().reg(); 1466 Register result = comp->locs()->out().reg();
1445 1467
1446 const Class& double_class = compiler->double_class(); 1468 const Class& double_class = compiler->double_class();
1447 const Code& stub = 1469 const Code& stub =
1448 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1470 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1449 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1471 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1450 __ pushl(left);
1451 __ pushl(right);
1452 compiler->GenerateCall(comp->instance_call()->token_index(), 1472 compiler->GenerateCall(comp->instance_call()->token_index(),
1453 comp->instance_call()->try_index(), 1473 comp->instance_call()->try_index(),
1454 &label, 1474 &label,
1455 PcDescriptors::kOther); 1475 PcDescriptors::kOther);
1456 // Newly allocated object is now in the result register (RAX). 1476 // Newly allocated object is now in the result register (RAX).
1457 ASSERT(result == EAX); 1477 ASSERT(result == EAX);
1458 __ popl(right); 1478 __ popl(right);
1459 __ popl(left); 1479 __ popl(left);
1460 1480
1461 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1481 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 } 1561 }
1542 } else { 1562 } else {
1543 UNREACHABLE(); 1563 UNREACHABLE();
1544 } 1564 }
1545 } 1565 }
1546 1566
1547 1567
1548 LocationSummary* NumberNegateComp::MakeLocationSummary() const { 1568 LocationSummary* NumberNegateComp::MakeLocationSummary() const {
1549 const intptr_t kNumInputs = 1; 1569 const intptr_t kNumInputs = 1;
1550 const intptr_t kNumTemps = 1; // Needed for doubles. 1570 const intptr_t kNumTemps = 1; // Needed for doubles.
1551 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1571 LocationSummary* summary = new LocationSummary(kNumInputs,
1572 kNumTemps,
1573 LocationSummary::kCall);
1552 summary->set_in(0, Location::RequiresRegister()); 1574 summary->set_in(0, Location::RequiresRegister());
1553 summary->set_out(Location::SameAsFirstInput()); 1575 summary->set_out(Location::SameAsFirstInput());
1554 summary->set_temp(0, Location::RequiresRegister()); 1576 summary->set_temp(0, Location::RequiresRegister());
1555 return summary; 1577 return summary;
1556 } 1578 }
1557 1579
1558 1580
1559 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1581 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1560 const ICData& ic_data = *instance_call()->ic_data(); 1582 const ICData& ic_data = *instance_call()->ic_data();
1561 ASSERT(!ic_data.IsNull()); 1583 ASSERT(!ic_data.IsNull());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 1627
1606 1628
1607 LocationSummary* ToDoubleComp::MakeLocationSummary() const { 1629 LocationSummary* ToDoubleComp::MakeLocationSummary() const {
1608 const intptr_t kNumInputs = 1; 1630 const intptr_t kNumInputs = 1;
1609 if (from() == kDouble) { 1631 if (from() == kDouble) {
1610 const intptr_t kNumTemps = 1; 1632 const intptr_t kNumTemps = 1;
1611 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 1633 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
1612 locs->set_in(0, Location::RequiresRegister()); 1634 locs->set_in(0, Location::RequiresRegister());
1613 locs->set_temp(0, Location::RequiresRegister()); 1635 locs->set_temp(0, Location::RequiresRegister());
1614 locs->set_out(Location::SameAsFirstInput()); 1636 locs->set_out(Location::SameAsFirstInput());
1637 locs->set_temp(0, Location::RequiresRegister());
1615 return locs; 1638 return locs;
1616 } else { 1639 } else {
1617 ASSERT(from() == kSmi); 1640 ASSERT(from() == kSmi);
1618 return LocationSummary::Make(kNumInputs, Location::RegisterLocation(EAX)); 1641 return MakeCallSummary(); // Calls a stub to allocate result.
1619 } 1642 }
1620 } 1643 }
1621 1644
1622 1645
1623 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1646 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1624 Register value = locs()->in(0).reg();
1625 Register result = locs()->out().reg(); 1647 Register result = locs()->out().reg();
1648 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX;
1626 1649
1627 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1650 const DeoptReasonId deopt_reason = (from() == kDouble) ?
1628 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1651 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1629 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1652 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1630 instance_call()->token_index(), 1653 instance_call()->token_index(),
1631 instance_call()->try_index(), 1654 instance_call()->try_index(),
1632 deopt_reason, 1655 deopt_reason,
1633 value); 1656 value);
1634 1657
1635 if (from() == kDouble) { 1658 if (from() == kDouble) {
1636 Register temp = locs()->temp(0).reg(); 1659 Register temp = locs()->temp(0).reg();
1637 __ testl(value, Immediate(kSmiTagMask)); 1660 __ testl(value, Immediate(kSmiTagMask));
1638 __ j(ZERO, deopt); // Deoptimize if Smi. 1661 __ j(ZERO, deopt); // Deoptimize if Smi.
1639 __ CompareClassId(value, kDouble, temp); 1662 __ CompareClassId(value, kDouble, temp);
1640 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1663 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1641 ASSERT(value == result); 1664 ASSERT(value == result);
1642 return; 1665 return;
1643 } 1666 }
1644 1667
1645 ASSERT(from() == kSmi); 1668 ASSERT(from() == kSmi);
1646 1669
1647 const Class& double_class = compiler->double_class(); 1670 const Class& double_class = compiler->double_class();
1648 const Code& stub = 1671 const Code& stub =
1649 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1672 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1650 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1673 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1651 1674
1652 // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping. 1675 // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping.
Florian Schneider 2012/06/18 16:50:55 s/poping/popping/
Vyacheslav Egorov (Google) 2012/06/18 17:51:16 Done.
1653 __ pushl(value);
1654 compiler->GenerateCall(instance_call()->token_index(), 1676 compiler->GenerateCall(instance_call()->token_index(),
1655 instance_call()->try_index(), 1677 instance_call()->try_index(),
1656 &label, 1678 &label,
1657 PcDescriptors::kOther); 1679 PcDescriptors::kOther);
1658 ASSERT(result == EAX); 1680 ASSERT(result == EAX);
1659 __ popl(value); 1681 __ popl(value);
1660 1682
1661 __ testl(value, Immediate(kSmiTagMask)); 1683 __ testl(value, Immediate(kSmiTagMask));
1662 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 1684 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
1663 __ SmiUntag(value); 1685 __ SmiUntag(value);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1713 } 1735 }
1714 __ Bind(&done); 1736 __ Bind(&done);
1715 } 1737 }
1716 1738
1717 1739
1718 } // namespace dart 1740 } // namespace dart
1719 1741
1720 #undef __ 1742 #undef __
1721 1743
1722 #endif // defined TARGET_ARCH_X64 1744 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698