OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |