| 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,
|
|
|