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

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: rebase, fix off by one in deopt stub generation Created 8 years, 5 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 21 matching lines...) Expand all
32 32
33 if (deoptimization_env_ == NULL) { 33 if (deoptimization_env_ == NULL) {
34 for (intptr_t i = 0; i < registers_.length(); i++) { 34 for (intptr_t i = 0; i < registers_.length(); i++) {
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 the 40 // We have a deoptimization environment, we have to tear down the
41 // optimized frame and recreate a non-optimized one. 41 // optimized frame and recreate a non-optimized one.
42 const intptr_t fixed_parameter_count =
43 deoptimization_env_->fixed_parameter_count();
42 44
43 // 1. Set the stack pointer to the top of the non-optimized frame. 45 // 1. Set the stack pointer to the top of the non-optimized frame.
44 const GrowableArray<Value*>& values = deoptimization_env_->values(); 46 const GrowableArray<Value*>& values = deoptimization_env_->values();
47 const intptr_t local_slot_count = values.length() - fixed_parameter_count;
45 const intptr_t top_offset = 48 const intptr_t top_offset =
46 ParsedFunction::kFirstLocalSlotIndex - values.length(); 49 ParsedFunction::kFirstLocalSlotIndex - (local_slot_count - 1);
47 __ leaq(RSP, Address(RBP, top_offset * kWordSize)); 50 __ leaq(RSP, Address(RBP, top_offset * kWordSize));
48 51
49 // 2. Build and emit a parallel move representing the frame translation. 52 // 2. Build and emit a parallel move representing the frame translation.
50 ParallelMoveInstr* move = new ParallelMoveInstr(); 53 ParallelMoveInstr* move = new ParallelMoveInstr();
51 for (intptr_t i = 0; i < values.length(); i++) { 54 for (intptr_t i = 0; i < values.length(); i++) {
52 Location destination = Location::SpillSlot(i); 55 Location destination = Location::StackSlot(i - fixed_parameter_count);
53 Location source = deoptimization_env_->LocationAt(i); 56 Location source = deoptimization_env_->LocationAt(i);
54 if (!source.IsRegister() && !source.IsInvalid()) { 57 if (!source.IsRegister() && !source.IsInvalid()) {
55 compiler->Bailout("unsupported deoptimization state"); 58 compiler->Bailout("unsupported deoptimization state");
56 } 59 }
57 if (source.IsInvalid()) { 60 if (source.IsInvalid()) {
58 ASSERT(values[i]->IsConstant()); 61 ASSERT(values[i]->IsConstant());
59 source = Location::Constant(values[i]->AsConstant()->value()); 62 source = Location::Constant(values[i]->AsConstant()->value());
60 } 63 }
61 move->AddMove(destination, source); 64 move->AddMove(destination, source);
62 } 65 }
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 CatchClauseNode::kInvalidTryIndex, 963 CatchClauseNode::kInvalidTryIndex,
961 kClosureArgumentMismatchRuntimeEntry); 964 kClosureArgumentMismatchRuntimeEntry);
962 } else { 965 } else {
963 __ Stop("Wrong number of arguments"); 966 __ Stop("Wrong number of arguments");
964 } 967 }
965 __ Bind(&argc_in_range); 968 __ Bind(&argc_in_range);
966 } 969 }
967 } else { 970 } else {
968 CopyParameters(); 971 CopyParameters();
969 } 972 }
973
974 // TODO(vegorov): introduce stack maps and stop initializing all spill slots
975 // with null.
976 const intptr_t stack_slot_count =
977 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count()
978 : local_count;
979
980 const intptr_t slot_base = parsed_function().first_stack_local_index();
981
970 // Initialize (non-argument) stack allocated locals to null. 982 // Initialize (non-argument) stack allocated locals to null.
971 if (local_count > 0) { 983 if (stack_slot_count > 0) {
972 const Immediate raw_null = 984 const Immediate raw_null =
973 Immediate(reinterpret_cast<intptr_t>(Object::null())); 985 Immediate(reinterpret_cast<intptr_t>(Object::null()));
974 __ movq(RAX, raw_null); 986 __ movq(RAX, raw_null);
975 const int base = parsed_function().first_stack_local_index(); 987 for (intptr_t i = 0; i < stack_slot_count; ++i) {
976 for (int i = 0; i < local_count; ++i) {
977 // Subtract index i (locals lie at lower addresses than RBP). 988 // Subtract index i (locals lie at lower addresses than RBP).
978 __ movq(Address(RBP, (base - i) * kWordSize), RAX); 989 __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX);
979 } 990 }
980 } 991 }
981 992
982 if (!IsLeaf()) { 993 if (!IsLeaf()) {
983 // Generate stack overflow check. 994 // Generate stack overflow check.
984 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address())); 995 __ movq(RDI, Immediate(Isolate::Current()->stack_limit_address()));
985 __ cmpq(RSP, Address(RDI, 0)); 996 __ cmpq(RSP, Address(RDI, 0));
986 Label no_stack_overflow; 997 Label no_stack_overflow;
987 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 998 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
988 GenerateCallRuntime(AstNode::kNoId, 999 GenerateCallRuntime(AstNode::kNoId,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 __ SmiUntag(temp); 1123 __ SmiUntag(temp);
1113 __ cvtsi2sd(result, temp); 1124 __ cvtsi2sd(result, temp);
1114 __ Bind(&done); 1125 __ Bind(&done);
1115 } 1126 }
1116 1127
1117 1128
1118 #undef __ 1129 #undef __
1119 #define __ compiler_->assembler()-> 1130 #define __ compiler_->assembler()->
1120 1131
1121 1132
1122 static Address ToAddress(Location loc) { 1133 static Address ToStackSlotAddress(Location loc) {
1123 ASSERT(loc.IsSpillSlot()); 1134 ASSERT(loc.IsStackSlot());
1124 const intptr_t offset = 1135 const intptr_t index = loc.stack_index();
1125 (ParsedFunction::kFirstLocalSlotIndex - loc.spill_index()) * kWordSize; 1136 if (index < 0) {
1126 return Address(RBP, offset); 1137 const intptr_t offset = (1 - index) * kWordSize;
1138 return Address(RBP, offset);
1139 } else {
1140 const intptr_t offset =
1141 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize;
1142 return Address(RBP, offset);
1143 }
1127 } 1144 }
1128 1145
1129 1146
1130 void ParallelMoveResolver::EmitMove(int index) { 1147 void ParallelMoveResolver::EmitMove(int index) {
1131 MoveOperands* move = moves_[index]; 1148 MoveOperands* move = moves_[index];
1132 const Location source = move->src(); 1149 const Location source = move->src();
1133 const Location destination = move->dest(); 1150 const Location destination = move->dest();
1134 1151
1135 if (source.IsRegister()) { 1152 if (source.IsRegister()) {
1136 if (destination.IsRegister()) { 1153 if (destination.IsRegister()) {
1137 __ movq(destination.reg(), source.reg()); 1154 __ movq(destination.reg(), source.reg());
1138 } else { 1155 } else {
1139 ASSERT(destination.IsSpillSlot()); 1156 ASSERT(destination.IsStackSlot());
1140 __ movq(ToAddress(destination), source.reg()); 1157 __ movq(ToStackSlotAddress(destination), source.reg());
1141 } 1158 }
1142 } else if (source.IsSpillSlot()) { 1159 } else if (source.IsStackSlot()) {
1143 if (destination.IsRegister()) { 1160 if (destination.IsRegister()) {
1144 __ movq(destination.reg(), ToAddress(source)); 1161 __ movq(destination.reg(), ToStackSlotAddress(source));
1145 } else { 1162 } else {
1146 ASSERT(destination.IsSpillSlot()); 1163 ASSERT(destination.IsStackSlot());
1147 MoveMemoryToMemory(ToAddress(destination), ToAddress(source)); 1164 MoveMemoryToMemory(ToStackSlotAddress(destination),
1165 ToStackSlotAddress(source));
1148 } 1166 }
1149 } else { 1167 } else {
1150 ASSERT(source.IsConstant()); 1168 ASSERT(source.IsConstant());
1151 if (destination.IsRegister()) { 1169 if (destination.IsRegister()) {
1152 __ LoadObject(destination.reg(), source.constant()); 1170 __ LoadObject(destination.reg(), source.constant());
1153 } else { 1171 } else {
1154 ASSERT(destination.IsSpillSlot()); 1172 ASSERT(destination.IsStackSlot());
1155 StoreObject(ToAddress(destination), source.constant()); 1173 StoreObject(ToStackSlotAddress(destination), source.constant());
1156 } 1174 }
1157 } 1175 }
1158 1176
1159 move->Eliminate(); 1177 move->Eliminate();
1160 } 1178 }
1161 1179
1162 1180
1163 void ParallelMoveResolver::EmitSwap(int index) { 1181 void ParallelMoveResolver::EmitSwap(int index) {
1164 MoveOperands* move = moves_[index]; 1182 MoveOperands* move = moves_[index];
1165 const Location source = move->src(); 1183 const Location source = move->src();
1166 const Location destination = move->dest(); 1184 const Location destination = move->dest();
1167 1185
1168 if (source.IsRegister() && destination.IsRegister()) { 1186 if (source.IsRegister() && destination.IsRegister()) {
1169 __ xchgq(destination.reg(), source.reg()); 1187 __ xchgq(destination.reg(), source.reg());
1170 } else if (source.IsRegister() && destination.IsSpillSlot()) { 1188 } else if (source.IsRegister() && destination.IsStackSlot()) {
1171 Exchange(source.reg(), ToAddress(destination)); 1189 Exchange(source.reg(), ToStackSlotAddress(destination));
1172 } else if (source.IsSpillSlot() && destination.IsRegister()) { 1190 } else if (source.IsStackSlot() && destination.IsRegister()) {
1173 Exchange(destination.reg(), ToAddress(source)); 1191 Exchange(destination.reg(), ToStackSlotAddress(source));
1174 } else if (source.IsSpillSlot() && destination.IsSpillSlot()) { 1192 } else if (source.IsStackSlot() && destination.IsStackSlot()) {
1175 Exchange(ToAddress(destination), ToAddress(source)); 1193 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source));
1176 } else { 1194 } else {
1177 UNREACHABLE(); 1195 UNREACHABLE();
1178 } 1196 }
1179 1197
1180 // The swap of source and destination has executed a move from source to 1198 // The swap of source and destination has executed a move from source to
1181 // destination. 1199 // destination.
1182 move->Eliminate(); 1200 move->Eliminate();
1183 1201
1184 // Any unperformed (including pending) move with a source of either 1202 // Any unperformed (including pending) move with a source of either
1185 // this move's source or destination needs to have their source 1203 // this move's source or destination needs to have their source
(...skipping 28 matching lines...) Expand all
1214 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1232 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1215 __ Exchange(mem1, mem2); 1233 __ Exchange(mem1, mem2);
1216 } 1234 }
1217 1235
1218 1236
1219 #undef __ 1237 #undef __
1220 1238
1221 } // namespace dart 1239 } // namespace dart
1222 1240
1223 #endif // defined TARGET_ARCH_X64 1241 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698