Index: src/ia32/macro-assembler-ia32.cc |
=================================================================== |
--- src/ia32/macro-assembler-ia32.cc (revision 5846) |
+++ src/ia32/macro-assembler-ia32.cc (working copy) |
@@ -392,13 +392,8 @@ |
} |
-void MacroAssembler::EnterApiExitFrame(int stack_space, |
- int argc) { |
+void MacroAssembler::EnterApiExitFrame(int argc) { |
EnterExitFramePrologue(); |
- |
- int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
- lea(esi, Operand(ebp, (stack_space * kPointerSize) + offset)); |
- |
EnterExitFrameEpilogue(argc); |
} |
@@ -411,6 +406,13 @@ |
// Pop the arguments and the receiver from the caller stack. |
lea(esp, Operand(esi, 1 * kPointerSize)); |
+ // Push the return address to get ready to return. |
+ push(ecx); |
+ |
+ LeaveExitFrameEpilogue(); |
+} |
+ |
+void MacroAssembler::LeaveExitFrameEpilogue() { |
// Restore current context from top and clear it in debug mode. |
ExternalReference context_address(Top::k_context_address); |
mov(esi, Operand::StaticVariable(context_address)); |
@@ -418,15 +420,20 @@ |
mov(Operand::StaticVariable(context_address), Immediate(0)); |
#endif |
- // Push the return address to get ready to return. |
- push(ecx); |
- |
// Clear the top frame. |
ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); |
mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); |
} |
+void MacroAssembler::LeaveApiExitFrame() { |
+ mov(esp, Operand(ebp)); |
+ pop(ebp); |
+ |
+ LeaveExitFrameEpilogue(); |
+} |
+ |
+ |
void MacroAssembler::PushTryHandler(CodeLocation try_location, |
HandlerType type) { |
// Adjust this code if not the case. |
@@ -1110,6 +1117,17 @@ |
} |
+MaybeObject* MacroAssembler::TryTailCallExternalReference( |
+ const ExternalReference& ext, int num_arguments, int result_size) { |
+ // TODO(1236192): Most runtime routines don't need the number of |
+ // arguments passed in because it is constant. At some point we |
+ // should remove this need and make the runtime routine entry code |
+ // smarter. |
+ Set(eax, Immediate(num_arguments)); |
+ return TryJumpToExternalReference(ext); |
+} |
+ |
+ |
void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, |
int num_arguments, |
int result_size) { |
@@ -1117,6 +1135,14 @@ |
} |
+MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid, |
+ int num_arguments, |
+ int result_size) { |
+ return TryTailCallExternalReference( |
+ ExternalReference(fid), num_arguments, result_size); |
+} |
+ |
+ |
// If true, a Handle<T> passed by value is passed and returned by |
// using the location_ field directly. If false, it is passed and |
// returned as a pointer to a handle. |
@@ -1132,20 +1158,15 @@ |
} |
-void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) { |
+void MacroAssembler::PrepareCallApiFunction(int argc, Register scratch) { |
if (kPassHandlesDirectly) { |
- EnterApiExitFrame(stack_space, argc); |
+ EnterApiExitFrame(argc); |
// When handles as passed directly we don't have to allocate extra |
// space for and pass an out parameter. |
} else { |
// We allocate two additional slots: return value and pointer to it. |
- EnterApiExitFrame(stack_space, argc + 2); |
- } |
-} |
+ EnterApiExitFrame(argc + 2); |
- |
-void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function, int argc) { |
- if (!kPassHandlesDirectly) { |
// The argument slots are filled as follows: |
// |
// n + 1: output cell |
@@ -1157,11 +1178,19 @@ |
// Note that this is one more "argument" than the function expects |
// so the out cell will have to be popped explicitly after returning |
// from the function. The out cell contains Handle. |
- lea(eax, Operand(esp, (argc + 1) * kPointerSize)); // pointer to out cell. |
- mov(Operand(esp, 0 * kPointerSize), eax); // output. |
- mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. |
+ |
+ // pointer to out cell. |
+ lea(scratch, Operand(esp, (argc + 1) * kPointerSize)); |
+ mov(Operand(esp, 0 * kPointerSize), scratch); // output. |
+ if (FLAG_debug_code) { |
+ mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. |
+ } |
} |
+} |
+ |
+MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, |
+ int stack_space) { |
ExternalReference next_address = |
ExternalReference::handle_scope_next_address(); |
ExternalReference limit_address = |
@@ -1210,10 +1239,14 @@ |
cmp(Operand::StaticVariable(scheduled_exception_address), |
Immediate(Factory::the_hole_value())); |
j(not_equal, &promote_scheduled_exception, not_taken); |
- LeaveExitFrame(); |
- ret(0); |
+ LeaveApiExitFrame(); |
+ ret(stack_space * kPointerSize); |
bind(&promote_scheduled_exception); |
- TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
+ MaybeObject* result = |
+ TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
+ if (result->IsFailure()) { |
+ return result; |
+ } |
bind(&empty_handle); |
// It was zero; the result is undefined. |
mov(eax, Factory::undefined_value()); |
@@ -1227,6 +1260,8 @@ |
call(Operand(eax)); |
mov(eax, edi); |
jmp(&leave_exit_frame); |
+ |
+ return result; |
} |
@@ -1238,6 +1273,15 @@ |
} |
+MaybeObject* MacroAssembler::TryJumpToExternalReference( |
+ const ExternalReference& ext) { |
+ // Set the entry point and jump to the C entry runtime stub. |
+ mov(ebx, Immediate(ext)); |
+ CEntryStub ces(1); |
+ return TryTailCallStub(&ces); |
+} |
+ |
+ |
void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
const ParameterCount& actual, |
Handle<Code> code_constant, |