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 24 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |