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

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

Issue 10828018: Add support for fixed parameters in the register allocator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 24 matching lines...) Expand all
35 if (registers_[i] != kNoRegister) { 35 if (registers_[i] != kNoRegister) {
36 __ pushq(registers_[i]); 36 __ pushq(registers_[i]);
37 } 37 }
38 } 38 }
39 } else { 39 } else {
40 // We have a deoptimization environment, we have to tear down optimized 40 // We have a deoptimization environment, we have to tear down optimized
41 // frame and recreate non-optimized one. 41 // frame and recreate non-optimized one.
42 __ leaq(RSP, 42 __ leaq(RSP,
43 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 43 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
44 44
45 const intptr_t fixed_param_count = deoptimization_env_->fixed_param_count();
45 const GrowableArray<Value*>& values = deoptimization_env_->values(); 46 const GrowableArray<Value*>& values = deoptimization_env_->values();
46 for (intptr_t i = 0; i < values.length(); i++) { 47
48 for (intptr_t i = 0; i < fixed_param_count; i++) {
49 const intptr_t offset = (2 + (fixed_param_count - 1) - i) * kWordSize;
47 const Location loc = deoptimization_env_->LocationAt(i); 50 const Location loc = deoptimization_env_->LocationAt(i);
48 if (loc.IsInvalid()) { 51 if (loc.IsInvalid()) {
49 ASSERT(values[i]->IsConstant()); 52 ASSERT(values[i]->IsConstant());
53 __ StoreObject(Address(RBP, offset), values[i]->AsConstant()->value());
54 } else if (loc.IsRegister()) {
55 __ movq(Address(RBP, offset), loc.reg());
56 } else if (loc.IsStackSlot() &&
57 (loc.stack_index() < 0) &&
58 (loc.stack_index() == (i - fixed_param_count))) {
59 // Do nothing.
60 } else {
61 compiler->Bailout("unsupported deoptimization state");
62 }
63 }
srdjan 2012/07/26 00:33:56 Sync this with Kevin's upcoming change.
Vyacheslav Egorov (Google) 2012/07/26 11:33:53 Will do.
64
65 for (intptr_t i = fixed_param_count; i < values.length(); i++) {
66 const Location loc = deoptimization_env_->LocationAt(i);
67 if (loc.IsInvalid()) {
68 ASSERT(values[i]->IsConstant());
50 __ PushObject(values[i]->AsConstant()->value()); 69 __ PushObject(values[i]->AsConstant()->value());
51 } else if (loc.IsRegister()) { 70 } else if (loc.IsRegister()) {
52 __ pushq(loc.reg()); 71 __ pushq(loc.reg());
53 } else { 72 } else {
54 compiler->Bailout("unsupported deoptimization state"); 73 compiler->Bailout("unsupported deoptimization state");
55 } 74 }
56 } 75 }
57 } 76 }
58 77
59 if (compiler->IsLeaf()) { 78 if (compiler->IsLeaf()) {
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 CatchClauseNode::kInvalidTryIndex, 972 CatchClauseNode::kInvalidTryIndex,
954 kClosureArgumentMismatchRuntimeEntry); 973 kClosureArgumentMismatchRuntimeEntry);
955 } else { 974 } else {
956 __ Stop("Wrong number of arguments"); 975 __ Stop("Wrong number of arguments");
957 } 976 }
958 __ Bind(&argc_in_range); 977 __ Bind(&argc_in_range);
959 } 978 }
960 } else { 979 } else {
961 CopyParameters(); 980 CopyParameters();
962 } 981 }
982
983 // TODO(vegorov): introduce stack maps and stop initializing all spill slots
984 // with null.
985 const int stack_slot_count =
986 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count()
987 : local_count;
988
989 const int slot_base =
990 is_ssa_ ? -2 : parsed_function().first_stack_local_index();
srdjan 2012/07/26 00:33:56 ditto, not needed, I guess.
Vyacheslav Egorov (Google) 2012/07/26 11:33:53 Done.
991
963 // Initialize (non-argument) stack allocated locals to null. 992 // Initialize (non-argument) stack allocated locals to null.
964 if (local_count > 0) { 993 if (stack_slot_count > 0) {
965 const Immediate raw_null = 994 const Immediate raw_null =
966 Immediate(reinterpret_cast<intptr_t>(Object::null())); 995 Immediate(reinterpret_cast<intptr_t>(Object::null()));
967 __ movq(RAX, raw_null); 996 __ movq(RAX, raw_null);
968 const int base = parsed_function().first_stack_local_index(); 997 for (int i = 0; i < stack_slot_count; ++i) {
969 for (int i = 0; i < local_count; ++i) {
970 // Subtract index i (locals lie at lower addresses than RBP). 998 // Subtract index i (locals lie at lower addresses than RBP).
971 __ movq(Address(RBP, (base - i) * kWordSize), RAX); 999 __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX);
972 } 1000 }
973 } 1001 }
974 1002
975 if (!IsLeaf()) { 1003 if (!IsLeaf()) {
976 // Generate stack overflow check. 1004 // Generate stack overflow check.
977 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address())); 1005 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address()));
978 __ cmpq(RSP, Address(RDI, 0)); 1006 __ cmpq(RSP, Address(RDI, 0));
979 Label no_stack_overflow; 1007 Label no_stack_overflow;
980 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 1008 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
981 GenerateCallRuntime(AstNode::kNoId, 1009 GenerateCallRuntime(AstNode::kNoId,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 __ SmiUntag(temp); 1133 __ SmiUntag(temp);
1106 __ cvtsi2sd(result, temp); 1134 __ cvtsi2sd(result, temp);
1107 __ Bind(&done); 1135 __ Bind(&done);
1108 } 1136 }
1109 1137
1110 1138
1111 #undef __ 1139 #undef __
1112 #define __ compiler_->assembler()-> 1140 #define __ compiler_->assembler()->
1113 1141
1114 1142
1115 static Address ToAddress(Location loc) { 1143 static Address ToStackSlotAddress(Location loc) {
1116 ASSERT(loc.IsSpillSlot()); 1144 ASSERT(loc.IsStackSlot());
1117 const intptr_t offset = 1145 const intptr_t index = loc.stack_index();
1118 (ParsedFunction::kFirstLocalSlotIndex - loc.spill_index()) * kWordSize; 1146 if (index < 0) {
1119 return Address(RBP, offset); 1147 const intptr_t offset = (1 - index) * kWordSize;
1148 return Address(RBP, offset);
1149 } else {
1150 const intptr_t offset =
1151 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize;
1152 return Address(RBP, offset);
1153 }
1120 } 1154 }
1121 1155
1122 1156
1123 void ParallelMoveResolver::EmitMove(int index) { 1157 void ParallelMoveResolver::EmitMove(int index) {
1124 MoveOperands* move = moves_[index]; 1158 MoveOperands* move = moves_[index];
1125 const Location source = move->src(); 1159 const Location source = move->src();
1126 const Location destination = move->dest(); 1160 const Location destination = move->dest();
1127 1161
1128 if (source.IsRegister()) { 1162 if (source.IsRegister()) {
1129 if (destination.IsRegister()) { 1163 if (destination.IsRegister()) {
1130 __ movq(destination.reg(), source.reg()); 1164 __ movq(destination.reg(), source.reg());
1131 } else { 1165 } else {
1132 ASSERT(destination.IsSpillSlot()); 1166 ASSERT(destination.IsStackSlot());
1133 __ movq(ToAddress(destination), source.reg()); 1167 __ movq(ToStackSlotAddress(destination), source.reg());
1134 } 1168 }
1135 } else if (source.IsSpillSlot()) { 1169 } else if (source.IsStackSlot()) {
1136 if (destination.IsRegister()) { 1170 if (destination.IsRegister()) {
1137 __ movq(destination.reg(), ToAddress(source)); 1171 __ movq(destination.reg(), ToStackSlotAddress(source));
1138 } else { 1172 } else {
1139 ASSERT(destination.IsSpillSlot()); 1173 ASSERT(destination.IsStackSlot());
1140 MoveMemoryToMemory(ToAddress(destination), ToAddress(source)); 1174 MoveMemoryToMemory(ToStackSlotAddress(destination),
1175 ToStackSlotAddress(source));
1141 } 1176 }
1142 } else { 1177 } else {
1143 ASSERT(source.IsConstant()); 1178 ASSERT(source.IsConstant());
1144 if (destination.IsRegister()) { 1179 if (destination.IsRegister()) {
1145 __ LoadObject(destination.reg(), source.constant()); 1180 __ LoadObject(destination.reg(), source.constant());
1146 } else { 1181 } else {
1147 ASSERT(destination.IsSpillSlot()); 1182 ASSERT(destination.IsStackSlot());
1148 StoreObject(ToAddress(destination), source.constant()); 1183 StoreObject(ToStackSlotAddress(destination), source.constant());
1149 } 1184 }
1150 } 1185 }
1151 1186
1152 move->Eliminate(); 1187 move->Eliminate();
1153 } 1188 }
1154 1189
1155 1190
1156 void ParallelMoveResolver::EmitSwap(int index) { 1191 void ParallelMoveResolver::EmitSwap(int index) {
1157 MoveOperands* move = moves_[index]; 1192 MoveOperands* move = moves_[index];
1158 const Location source = move->src(); 1193 const Location source = move->src();
1159 const Location destination = move->dest(); 1194 const Location destination = move->dest();
1160 1195
1161 if (source.IsRegister() && destination.IsRegister()) { 1196 if (source.IsRegister() && destination.IsRegister()) {
1162 __ xchgq(destination.reg(), source.reg()); 1197 __ xchgq(destination.reg(), source.reg());
1163 } else if (source.IsRegister() && destination.IsSpillSlot()) { 1198 } else if (source.IsRegister() && destination.IsStackSlot()) {
1164 Exchange(source.reg(), ToAddress(destination)); 1199 Exchange(source.reg(), ToStackSlotAddress(destination));
1165 } else if (source.IsSpillSlot() && destination.IsRegister()) { 1200 } else if (source.IsStackSlot() && destination.IsRegister()) {
1166 Exchange(destination.reg(), ToAddress(source)); 1201 Exchange(destination.reg(), ToStackSlotAddress(source));
1167 } else if (source.IsSpillSlot() && destination.IsSpillSlot()) { 1202 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1168 Exchange(ToAddress(destination), ToAddress(source)); 1203 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source));
1169 } else { 1204 } else {
1170 UNREACHABLE(); 1205 UNREACHABLE();
1171 } 1206 }
1172 1207
1173 // The swap of source and destination has executed a move from source to 1208 // The swap of source and destination has executed a move from source to
1174 // destination. 1209 // destination.
1175 move->Eliminate(); 1210 move->Eliminate();
1176 1211
1177 // Any unperformed (including pending) move with a source of either 1212 // Any unperformed (including pending) move with a source of either
1178 // this move's source or destination needs to have their source 1213 // this move's source or destination needs to have their source
(...skipping 28 matching lines...) Expand all
1207 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1242 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1208 __ Exchange(mem1, mem2); 1243 __ Exchange(mem1, mem2);
1209 } 1244 }
1210 1245
1211 1246
1212 #undef __ 1247 #undef __
1213 1248
1214 } // namespace dart 1249 } // namespace dart
1215 1250
1216 #endif // defined TARGET_ARCH_X64 1251 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698