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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 | 385 |
386 // Setup argc and argv in callee-saved registers. | 386 // Setup argc and argv in callee-saved registers. |
387 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 387 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
388 mov(edi, Operand(eax)); | 388 mov(edi, Operand(eax)); |
389 lea(esi, Operand(ebp, eax, times_4, offset)); | 389 lea(esi, Operand(ebp, eax, times_4, offset)); |
390 | 390 |
391 EnterExitFrameEpilogue(2); | 391 EnterExitFrameEpilogue(2); |
392 } | 392 } |
393 | 393 |
394 | 394 |
395 void MacroAssembler::EnterApiExitFrame(int stack_space, | 395 void MacroAssembler::EnterApiExitFrame(int argc) { |
396 int argc) { | |
397 EnterExitFramePrologue(); | 396 EnterExitFramePrologue(); |
398 | |
399 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | |
400 lea(esi, Operand(ebp, (stack_space * kPointerSize) + offset)); | |
401 | |
402 EnterExitFrameEpilogue(argc); | 397 EnterExitFrameEpilogue(argc); |
403 } | 398 } |
404 | 399 |
405 | 400 |
406 void MacroAssembler::LeaveExitFrame() { | 401 void MacroAssembler::LeaveExitFrame() { |
407 // Get the return address from the stack and restore the frame pointer. | 402 // Get the return address from the stack and restore the frame pointer. |
408 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 403 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
409 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 404 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
410 | 405 |
411 // Pop the arguments and the receiver from the caller stack. | 406 // Pop the arguments and the receiver from the caller stack. |
412 lea(esp, Operand(esi, 1 * kPointerSize)); | 407 lea(esp, Operand(esi, 1 * kPointerSize)); |
413 | 408 |
414 // Restore current context from top and clear it in debug mode. | 409 // Restore current context from top and clear it in debug mode. |
415 ExternalReference context_address(Top::k_context_address); | 410 ExternalReference context_address(Top::k_context_address); |
416 mov(esi, Operand::StaticVariable(context_address)); | 411 mov(esi, Operand::StaticVariable(context_address)); |
417 #ifdef DEBUG | 412 #ifdef DEBUG |
418 mov(Operand::StaticVariable(context_address), Immediate(0)); | 413 mov(Operand::StaticVariable(context_address), Immediate(0)); |
419 #endif | 414 #endif |
420 | 415 |
421 // Push the return address to get ready to return. | 416 // Push the return address to get ready to return. |
422 push(ecx); | 417 push(ecx); |
423 | 418 |
424 // Clear the top frame. | 419 // Clear the top frame. |
425 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | 420 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); |
426 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | 421 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); |
427 } | 422 } |
428 | 423 |
429 | 424 |
425 void MacroAssembler::LeaveApiExitFrame() { | |
426 mov(esp, Operand(ebp)); | |
427 pop(ebp); | |
428 | |
429 // Restore current context from top and clear it in debug mode. | |
antonm
2010/11/16 14:32:26
I'd suggest (but not insisting) to factor out comm
SeRya
2010/11/16 14:53:28
Done.
| |
430 ExternalReference context_address(Top::k_context_address); | |
431 mov(esi, Operand::StaticVariable(context_address)); | |
432 #ifdef DEBUG | |
433 mov(Operand::StaticVariable(context_address), Immediate(0)); | |
434 #endif | |
435 | |
436 // Clear the top frame. | |
437 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | |
438 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | |
439 } | |
440 | |
441 | |
430 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 442 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
431 HandlerType type) { | 443 HandlerType type) { |
432 // Adjust this code if not the case. | 444 // Adjust this code if not the case. |
433 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 445 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
434 // The pc (return address) is already on TOS. | 446 // The pc (return address) is already on TOS. |
435 if (try_location == IN_JAVASCRIPT) { | 447 if (try_location == IN_JAVASCRIPT) { |
436 if (type == TRY_CATCH_HANDLER) { | 448 if (type == TRY_CATCH_HANDLER) { |
437 push(Immediate(StackHandler::TRY_CATCH)); | 449 push(Immediate(StackHandler::TRY_CATCH)); |
438 } else { | 450 } else { |
439 push(Immediate(StackHandler::TRY_FINALLY)); | 451 push(Immediate(StackHandler::TRY_FINALLY)); |
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1144 #else | 1156 #else |
1145 static const bool kPassHandlesDirectly = false; | 1157 static const bool kPassHandlesDirectly = false; |
1146 #endif | 1158 #endif |
1147 | 1159 |
1148 | 1160 |
1149 Operand ApiParameterOperand(int index) { | 1161 Operand ApiParameterOperand(int index) { |
1150 return Operand(esp, (index + (kPassHandlesDirectly ? 0 : 1)) * kPointerSize); | 1162 return Operand(esp, (index + (kPassHandlesDirectly ? 0 : 1)) * kPointerSize); |
1151 } | 1163 } |
1152 | 1164 |
1153 | 1165 |
1154 void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) { | 1166 void MacroAssembler::PrepareCallApiFunction(int argc, Register scratch) { |
1155 if (kPassHandlesDirectly) { | 1167 if (kPassHandlesDirectly) { |
1156 EnterApiExitFrame(stack_space, argc); | 1168 EnterApiExitFrame(argc); |
1157 // When handles as passed directly we don't have to allocate extra | 1169 // When handles as passed directly we don't have to allocate extra |
1158 // space for and pass an out parameter. | 1170 // space for and pass an out parameter. |
1159 } else { | 1171 } else { |
1160 // We allocate two additional slots: return value and pointer to it. | 1172 // We allocate two additional slots: return value and pointer to it. |
1161 EnterApiExitFrame(stack_space, argc + 2); | 1173 EnterApiExitFrame(argc + 2); |
1162 } | |
1163 } | |
1164 | 1174 |
1165 | |
1166 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, | |
1167 int argc) { | |
1168 if (!kPassHandlesDirectly) { | |
1169 // The argument slots are filled as follows: | 1175 // The argument slots are filled as follows: |
1170 // | 1176 // |
1171 // n + 1: output cell | 1177 // n + 1: output cell |
1172 // n: arg n | 1178 // n: arg n |
1173 // ... | 1179 // ... |
1174 // 1: arg1 | 1180 // 1: arg1 |
1175 // 0: pointer to the output cell | 1181 // 0: pointer to the output cell |
1176 // | 1182 // |
1177 // Note that this is one more "argument" than the function expects | 1183 // Note that this is one more "argument" than the function expects |
1178 // so the out cell will have to be popped explicitly after returning | 1184 // so the out cell will have to be popped explicitly after returning |
1179 // from the function. The out cell contains Handle. | 1185 // from the function. The out cell contains Handle. |
1180 lea(eax, Operand(esp, (argc + 1) * kPointerSize)); // pointer to out cell. | 1186 |
1181 mov(Operand(esp, 0 * kPointerSize), eax); // output. | 1187 // pointer to out cell. |
1182 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. | 1188 lea(scratch, Operand(esp, (argc + 1) * kPointerSize)); |
1189 mov(Operand(esp, 0 * kPointerSize), scratch); // output. | |
1190 if (FLAG_debug_code) { | |
1191 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. | |
1192 } | |
1183 } | 1193 } |
1194 } | |
1184 | 1195 |
1196 | |
1197 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, | |
1198 int stack_space) { | |
1185 ExternalReference next_address = | 1199 ExternalReference next_address = |
1186 ExternalReference::handle_scope_next_address(); | 1200 ExternalReference::handle_scope_next_address(); |
1187 ExternalReference limit_address = | 1201 ExternalReference limit_address = |
1188 ExternalReference::handle_scope_limit_address(); | 1202 ExternalReference::handle_scope_limit_address(); |
1189 ExternalReference level_address = | 1203 ExternalReference level_address = |
1190 ExternalReference::handle_scope_level_address(); | 1204 ExternalReference::handle_scope_level_address(); |
1191 | 1205 |
1192 // Allocate HandleScope in callee-save registers. | 1206 // Allocate HandleScope in callee-save registers. |
1193 mov(ebx, Operand::StaticVariable(next_address)); | 1207 mov(ebx, Operand::StaticVariable(next_address)); |
1194 mov(edi, Operand::StaticVariable(limit_address)); | 1208 mov(edi, Operand::StaticVariable(limit_address)); |
(...skipping 28 matching lines...) Expand all Loading... | |
1223 cmp(edi, Operand::StaticVariable(limit_address)); | 1237 cmp(edi, Operand::StaticVariable(limit_address)); |
1224 j(not_equal, &delete_allocated_handles, not_taken); | 1238 j(not_equal, &delete_allocated_handles, not_taken); |
1225 bind(&leave_exit_frame); | 1239 bind(&leave_exit_frame); |
1226 | 1240 |
1227 // Check if the function scheduled an exception. | 1241 // Check if the function scheduled an exception. |
1228 ExternalReference scheduled_exception_address = | 1242 ExternalReference scheduled_exception_address = |
1229 ExternalReference::scheduled_exception_address(); | 1243 ExternalReference::scheduled_exception_address(); |
1230 cmp(Operand::StaticVariable(scheduled_exception_address), | 1244 cmp(Operand::StaticVariable(scheduled_exception_address), |
1231 Immediate(Factory::the_hole_value())); | 1245 Immediate(Factory::the_hole_value())); |
1232 j(not_equal, &promote_scheduled_exception, not_taken); | 1246 j(not_equal, &promote_scheduled_exception, not_taken); |
1233 LeaveExitFrame(); | 1247 LeaveApiExitFrame(); |
1234 ret(0); | 1248 ret(stack_space * kPointerSize); |
1235 bind(&promote_scheduled_exception); | 1249 bind(&promote_scheduled_exception); |
1236 MaybeObject* result = | 1250 MaybeObject* result = |
1237 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 1251 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
1238 if (result->IsFailure()) { | 1252 if (result->IsFailure()) { |
1239 return result; | 1253 return result; |
1240 } | 1254 } |
1241 bind(&empty_handle); | 1255 bind(&empty_handle); |
1242 // It was zero; the result is undefined. | 1256 // It was zero; the result is undefined. |
1243 mov(eax, Factory::undefined_value()); | 1257 mov(eax, Factory::undefined_value()); |
1244 jmp(&prologue); | 1258 jmp(&prologue); |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1799 | 1813 |
1800 // Check that the code was patched as expected. | 1814 // Check that the code was patched as expected. |
1801 ASSERT(masm_.pc_ == address_ + size_); | 1815 ASSERT(masm_.pc_ == address_ + size_); |
1802 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 1816 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
1803 } | 1817 } |
1804 | 1818 |
1805 | 1819 |
1806 } } // namespace v8::internal | 1820 } } // namespace v8::internal |
1807 | 1821 |
1808 #endif // V8_TARGET_ARCH_IA32 | 1822 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |