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 |