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_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/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 __ pushl(registers_[i]); | 36 __ pushl(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 __ leal(ESP, Address(EBP, top_offset * kWordSize)); | 50 __ leal(ESP, Address(EBP, 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 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 CatchClauseNode::kInvalidTryIndex, | 960 CatchClauseNode::kInvalidTryIndex, |
958 kClosureArgumentMismatchRuntimeEntry); | 961 kClosureArgumentMismatchRuntimeEntry); |
959 } else { | 962 } else { |
960 __ Stop("Wrong number of arguments"); | 963 __ Stop("Wrong number of arguments"); |
961 } | 964 } |
962 __ Bind(&argc_in_range); | 965 __ Bind(&argc_in_range); |
963 } | 966 } |
964 } else { | 967 } else { |
965 CopyParameters(); | 968 CopyParameters(); |
966 } | 969 } |
| 970 |
| 971 // TODO(vegorov): introduce stack maps and stop initializing all spill slots |
| 972 // with null. |
| 973 const intptr_t stack_slot_count = |
| 974 is_ssa_ ? block_order_[0]->AsGraphEntry()->spill_slot_count() |
| 975 : local_count; |
| 976 |
| 977 const intptr_t slot_base = parsed_function().first_stack_local_index(); |
| 978 |
967 // Initialize (non-argument) stack allocated locals to null. | 979 // Initialize (non-argument) stack allocated locals to null. |
968 if (local_count > 0) { | 980 if (stack_slot_count > 0) { |
969 const Immediate raw_null = | 981 const Immediate raw_null = |
970 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 982 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
971 __ movl(EAX, raw_null); | 983 __ movl(EAX, raw_null); |
972 const int base = parsed_function().first_stack_local_index(); | 984 for (intptr_t i = 0; i < stack_slot_count; ++i) { |
973 for (int i = 0; i < local_count; ++i) { | |
974 // Subtract index i (locals lie at lower addresses than EBP). | 985 // Subtract index i (locals lie at lower addresses than EBP). |
975 __ movl(Address(EBP, (base - i) * kWordSize), EAX); | 986 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); |
976 } | 987 } |
977 } | 988 } |
978 | 989 |
979 if (!IsLeaf()) { | 990 if (!IsLeaf()) { |
980 // Generate stack overflow check. | 991 // Generate stack overflow check. |
981 __ cmpl(ESP, | 992 __ cmpl(ESP, |
982 Address::Absolute(Isolate::Current()->stack_limit_address())); | 993 Address::Absolute(Isolate::Current()->stack_limit_address())); |
983 Label no_stack_overflow; | 994 Label no_stack_overflow; |
984 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); | 995 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); |
985 GenerateCallRuntime(AstNode::kNoId, | 996 GenerateCallRuntime(AstNode::kNoId, |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 __ SmiUntag(temp); | 1120 __ SmiUntag(temp); |
1110 __ cvtsi2sd(result, temp); | 1121 __ cvtsi2sd(result, temp); |
1111 __ Bind(&done); | 1122 __ Bind(&done); |
1112 } | 1123 } |
1113 | 1124 |
1114 | 1125 |
1115 #undef __ | 1126 #undef __ |
1116 #define __ compiler_->assembler()-> | 1127 #define __ compiler_->assembler()-> |
1117 | 1128 |
1118 | 1129 |
1119 static Address ToSpillAddress(Location loc) { | 1130 static Address ToStackSlotAddress(Location loc) { |
1120 ASSERT(loc.IsSpillSlot()); | 1131 ASSERT(loc.IsStackSlot()); |
1121 const intptr_t offset = | 1132 const intptr_t index = loc.stack_index(); |
1122 (ParsedFunction::kFirstLocalSlotIndex - loc.spill_index()) * kWordSize; | 1133 if (index < 0) { |
1123 return Address(EBP, offset); | 1134 const intptr_t offset = (1 - index) * kWordSize; |
| 1135 return Address(EBP, offset); |
| 1136 } else { |
| 1137 const intptr_t offset = |
| 1138 (ParsedFunction::kFirstLocalSlotIndex - index) * kWordSize; |
| 1139 return Address(EBP, offset); |
| 1140 } |
1124 } | 1141 } |
1125 | 1142 |
1126 | 1143 |
1127 void ParallelMoveResolver::EmitMove(int index) { | 1144 void ParallelMoveResolver::EmitMove(int index) { |
1128 MoveOperands* move = moves_[index]; | 1145 MoveOperands* move = moves_[index]; |
1129 const Location source = move->src(); | 1146 const Location source = move->src(); |
1130 const Location destination = move->dest(); | 1147 const Location destination = move->dest(); |
1131 | 1148 |
1132 if (source.IsRegister()) { | 1149 if (source.IsRegister()) { |
1133 if (destination.IsRegister()) { | 1150 if (destination.IsRegister()) { |
1134 __ movl(destination.reg(), source.reg()); | 1151 __ movl(destination.reg(), source.reg()); |
1135 } else { | 1152 } else { |
1136 ASSERT(destination.IsSpillSlot()); | 1153 ASSERT(destination.IsStackSlot()); |
1137 __ movl(ToSpillAddress(destination), source.reg()); | 1154 __ movl(ToStackSlotAddress(destination), source.reg()); |
1138 } | 1155 } |
1139 } else if (source.IsSpillSlot()) { | 1156 } else if (source.IsStackSlot()) { |
1140 if (destination.IsRegister()) { | 1157 if (destination.IsRegister()) { |
1141 __ movl(destination.reg(), ToSpillAddress(source)); | 1158 __ movl(destination.reg(), ToStackSlotAddress(source)); |
1142 } else { | 1159 } else { |
1143 ASSERT(destination.IsSpillSlot()); | 1160 ASSERT(destination.IsStackSlot()); |
1144 MoveMemoryToMemory(ToSpillAddress(destination), ToSpillAddress(source)); | 1161 MoveMemoryToMemory(ToStackSlotAddress(destination), |
| 1162 ToStackSlotAddress(source)); |
1145 } | 1163 } |
1146 } else { | 1164 } else { |
1147 ASSERT(source.IsConstant()); | 1165 ASSERT(source.IsConstant()); |
1148 if (destination.IsRegister()) { | 1166 if (destination.IsRegister()) { |
1149 __ LoadObject(destination.reg(), source.constant()); | 1167 __ LoadObject(destination.reg(), source.constant()); |
1150 } else { | 1168 } else { |
1151 ASSERT(destination.IsSpillSlot()); | 1169 ASSERT(destination.IsStackSlot()); |
1152 StoreObject(ToSpillAddress(destination), source.constant()); | 1170 StoreObject(ToStackSlotAddress(destination), source.constant()); |
1153 } | 1171 } |
1154 } | 1172 } |
1155 | 1173 |
1156 move->Eliminate(); | 1174 move->Eliminate(); |
1157 } | 1175 } |
1158 | 1176 |
1159 | 1177 |
1160 void ParallelMoveResolver::EmitSwap(int index) { | 1178 void ParallelMoveResolver::EmitSwap(int index) { |
1161 MoveOperands* move = moves_[index]; | 1179 MoveOperands* move = moves_[index]; |
1162 const Location source = move->src(); | 1180 const Location source = move->src(); |
1163 const Location destination = move->dest(); | 1181 const Location destination = move->dest(); |
1164 | 1182 |
1165 if (source.IsRegister() && destination.IsRegister()) { | 1183 if (source.IsRegister() && destination.IsRegister()) { |
1166 __ xchgl(destination.reg(), source.reg()); | 1184 __ xchgl(destination.reg(), source.reg()); |
1167 } else if (source.IsRegister() && destination.IsSpillSlot()) { | 1185 } else if (source.IsRegister() && destination.IsStackSlot()) { |
1168 Exchange(source.reg(), ToSpillAddress(destination)); | 1186 Exchange(source.reg(), ToStackSlotAddress(destination)); |
1169 } else if (source.IsSpillSlot() && destination.IsRegister()) { | 1187 } else if (source.IsStackSlot() && destination.IsRegister()) { |
1170 Exchange(destination.reg(), ToSpillAddress(source)); | 1188 Exchange(destination.reg(), ToStackSlotAddress(source)); |
1171 } else if (source.IsSpillSlot() && destination.IsSpillSlot()) { | 1189 } else if (source.IsStackSlot() && destination.IsStackSlot()) { |
1172 Exchange(ToSpillAddress(destination), ToSpillAddress(source)); | 1190 Exchange(ToStackSlotAddress(destination), ToStackSlotAddress(source)); |
1173 } else { | 1191 } else { |
1174 UNREACHABLE(); | 1192 UNREACHABLE(); |
1175 } | 1193 } |
1176 | 1194 |
1177 // The swap of source and destination has executed a move from source to | 1195 // The swap of source and destination has executed a move from source to |
1178 // destination. | 1196 // destination. |
1179 move->Eliminate(); | 1197 move->Eliminate(); |
1180 | 1198 |
1181 // Any unperformed (including pending) move with a source of either | 1199 // Any unperformed (including pending) move with a source of either |
1182 // this move's source or destination needs to have their source | 1200 // this move's source or destination needs to have their source |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 __ popl(ECX); | 1251 __ popl(ECX); |
1234 __ popl(EAX); | 1252 __ popl(EAX); |
1235 } | 1253 } |
1236 | 1254 |
1237 | 1255 |
1238 #undef __ | 1256 #undef __ |
1239 | 1257 |
1240 } // namespace dart | 1258 } // namespace dart |
1241 | 1259 |
1242 #endif // defined TARGET_ARCH_IA32 | 1260 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |