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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.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.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('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_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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698