Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1138 | 1138 |
| 1139 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) { | 1139 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) { |
| 1140 // If the expected number of arguments of the runtime function is | 1140 // If the expected number of arguments of the runtime function is |
| 1141 // constant, we check that the actual number of arguments match the | 1141 // constant, we check that the actual number of arguments match the |
| 1142 // expectation. | 1142 // expectation. |
| 1143 if (f->nargs >= 0 && f->nargs != num_arguments) { | 1143 if (f->nargs >= 0 && f->nargs != num_arguments) { |
| 1144 IllegalOperation(num_arguments); | 1144 IllegalOperation(num_arguments); |
| 1145 return; | 1145 return; |
| 1146 } | 1146 } |
| 1147 | 1147 |
| 1148 // TODO(1236192): Most runtime routines don't need the number of | 1148 if (Runtime::EXIT_FRAME_CALL == f->calling_convention) { |
| 1149 // arguments passed in because it is constant. At some point we | 1149 // TODO(1236192): Most runtime routines don't need the number of |
| 1150 // should remove this need and make the runtime routine entry code | 1150 // arguments passed in because it is constant. At some point we |
| 1151 // smarter. | 1151 // should remove this need and make the runtime routine entry code |
| 1152 Set(eax, Immediate(num_arguments)); | 1152 // smarter. |
| 1153 mov(ebx, Immediate(ExternalReference(f))); | 1153 Set(eax, Immediate(num_arguments)); |
| 1154 CEntryStub ces(1); | 1154 mov(ebx, Immediate(ExternalReference(f))); |
| 1155 CallStub(&ces); | 1155 CEntryStub ces(1); |
| 1156 CallStub(&ces); | |
| 1157 } else { | |
| 1158 DirectInvokeRuntime(f, CALL_FUNCTION); | |
| 1159 } | |
| 1160 } | |
| 1161 | |
| 1162 | |
| 1163 void MacroAssembler::DirectInvokeRuntime(Runtime::Function* f, | |
| 1164 InvokeFlag flag) { | |
| 1165 // Stack: | |
| 1166 // arg1 | |
| 1167 // ... | |
| 1168 // argN | |
| 1169 // ret addr (if tail call) | |
| 1170 static const int kFrameAlignment = OS::ActivationFrameAlignment(); | |
| 1171 | |
|
Søren Thygesen Gjesse
2010/02/22 12:38:22
I still think we should have the handling of calli
| |
| 1172 ASSERT(kFrameAlignment > 0); | |
| 1173 if (flag == JUMP_FUNCTION) { | |
| 1174 mov(eax, esp); | |
| 1175 } else { | |
| 1176 // This value will be stored on stack and then loaded into esp | |
| 1177 // to remove arguments. | |
| 1178 lea(eax, Operand(esp, f->nargs * kPointerSize)); | |
| 1179 } | |
| 1180 | |
| 1181 ASSERT(IsPowerOf2(kFrameAlignment)); | |
| 1182 and_(esp, -kFrameAlignment); | |
| 1183 | |
| 1184 // How many bytes need to be reserved to keep stack aligned after | |
| 1185 // pushing eax and args. | |
| 1186 const int alignmentPlaceholder = (-(f->nargs + 1) * kPointerSize) | |
| 1187 & (kFrameAlignment - 1); | |
| 1188 sub(Operand(esp), Immediate(alignmentPlaceholder)); | |
| 1189 ASSERT((alignmentPlaceholder + kPointerSize * (f->nargs + 1)) | |
| 1190 % kFrameAlignment == 0); | |
| 1191 | |
| 1192 push(eax); | |
| 1193 for (int i = 0; i < f->nargs; i++) { | |
| 1194 if (flag == JUMP_FUNCTION) { | |
| 1195 push(Operand(eax, (i + 1) * kPointerSize)); | |
| 1196 } else { | |
| 1197 push(Operand(eax, (i - f->nargs) * kPointerSize)); | |
| 1198 } | |
| 1199 } | |
| 1200 | |
| 1201 // Stack: | |
| 1202 // ag1 | |
| 1203 // ... | |
| 1204 // argN | |
| 1205 // ret addr (if tail call) | |
| 1206 // <stack alignment placeholder> | |
| 1207 // esp to restore | |
| 1208 // argN | |
| 1209 // ... | |
| 1210 // arg1 | |
| 1211 | |
| 1212 // Performing a semi tail call as we need to copy the arguments for alignment. | |
| 1213 call(FUNCTION_ADDR(ExternalReference(f).address()), RelocInfo::RUNTIME_ENTRY); | |
| 1214 | |
| 1215 mov(esp, Operand(esp, f->nargs * kPointerSize)); | |
| 1216 if (flag == JUMP_FUNCTION) { | |
| 1217 ret(f->nargs); | |
| 1218 } | |
|
Søren Thygesen Gjesse
2010/02/22 12:38:22
Maybe just adjust the stack by f->nargs in an else
| |
| 1156 } | 1219 } |
| 1157 | 1220 |
| 1158 | 1221 |
| 1159 void MacroAssembler::CallExternalReference(ExternalReference ref, | 1222 void MacroAssembler::CallExternalReference(ExternalReference ref, |
| 1160 int num_arguments) { | 1223 int num_arguments) { |
| 1161 mov(eax, Immediate(num_arguments)); | 1224 mov(eax, Immediate(num_arguments)); |
| 1162 mov(ebx, Immediate(ref)); | 1225 mov(ebx, Immediate(ref)); |
| 1163 | 1226 |
| 1164 CEntryStub stub(1); | 1227 CEntryStub stub(1); |
| 1165 CallStub(&stub); | 1228 CallStub(&stub); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1179 // arguments passed in because it is constant. At some point we | 1242 // arguments passed in because it is constant. At some point we |
| 1180 // should remove this need and make the runtime routine entry code | 1243 // should remove this need and make the runtime routine entry code |
| 1181 // smarter. | 1244 // smarter. |
| 1182 Set(eax, Immediate(num_arguments)); | 1245 Set(eax, Immediate(num_arguments)); |
| 1183 mov(ebx, Immediate(ExternalReference(f))); | 1246 mov(ebx, Immediate(ExternalReference(f))); |
| 1184 CEntryStub ces(1); | 1247 CEntryStub ces(1); |
| 1185 return TryCallStub(&ces); | 1248 return TryCallStub(&ces); |
| 1186 } | 1249 } |
| 1187 | 1250 |
| 1188 | 1251 |
| 1189 void MacroAssembler::TailCallRuntime(const ExternalReference& ext, | 1252 void MacroAssembler::TailCallRuntime(Runtime::FunctionId id, |
| 1190 int num_arguments, | 1253 int num_arguments, |
| 1191 int result_size) { | 1254 int result_size) { |
| 1255 Runtime::Function* f = Runtime::FunctionForId(id); | |
| 1256 // TODO(1236192): Most runtime routines don't need the number of | |
| 1257 // arguments passed in because it is constant. At some point we | |
| 1258 // should remove this need and make the runtime routine entry code | |
| 1259 // smarter. | |
| 1260 if (f->calling_convention == Runtime::EXIT_FRAME_CALL) { | |
| 1261 TailCallExternalReference(ExternalReference(f), num_arguments, result_size); | |
| 1262 } else { | |
| 1263 DirectInvokeRuntime(f, JUMP_FUNCTION); | |
| 1264 } | |
| 1265 } | |
| 1266 | |
| 1267 | |
| 1268 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, | |
| 1269 int num_arguments, | |
| 1270 int result_size) { | |
| 1192 // TODO(1236192): Most runtime routines don't need the number of | 1271 // TODO(1236192): Most runtime routines don't need the number of |
| 1193 // arguments passed in because it is constant. At some point we | 1272 // arguments passed in because it is constant. At some point we |
| 1194 // should remove this need and make the runtime routine entry code | 1273 // should remove this need and make the runtime routine entry code |
| 1195 // smarter. | 1274 // smarter. |
| 1196 Set(eax, Immediate(num_arguments)); | 1275 Set(eax, Immediate(num_arguments)); |
| 1197 JumpToRuntime(ext); | 1276 JumpToRuntime(ext); |
| 1198 } | 1277 } |
| 1199 | 1278 |
| 1200 | 1279 |
| 1201 void MacroAssembler::PushHandleScope(Register scratch) { | 1280 void MacroAssembler::PushHandleScope(Register scratch) { |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1628 // Indicate that code has changed. | 1707 // Indicate that code has changed. |
| 1629 CPU::FlushICache(address_, size_); | 1708 CPU::FlushICache(address_, size_); |
| 1630 | 1709 |
| 1631 // Check that the code was patched as expected. | 1710 // Check that the code was patched as expected. |
| 1632 ASSERT(masm_.pc_ == address_ + size_); | 1711 ASSERT(masm_.pc_ == address_ + size_); |
| 1633 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 1712 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 1634 } | 1713 } |
| 1635 | 1714 |
| 1636 | 1715 |
| 1637 } } // namespace v8::internal | 1716 } } // namespace v8::internal |
| OLD | NEW |