| Index: src/x64/macro-assembler-x64.cc
|
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
|
| index f404b9c663f248eab18802d65e66116cc3cb0228..0a626ef593745ced6c4ef6daeda77c42b5deef2d 100644
|
| --- a/src/x64/macro-assembler-x64.cc
|
| +++ b/src/x64/macro-assembler-x64.cc
|
| @@ -2797,6 +2797,11 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
|
| }
|
| }
|
|
|
| +#ifdef _WIN64
|
| +static const int kRegisterPassedArguments = 4;
|
| +#else
|
| +static const int kRegisterPassedArguments = 6;
|
| +#endif
|
|
|
| int MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) {
|
| // On Windows 64 stack slots are reserved by the caller for all arguments
|
| @@ -2807,11 +2812,10 @@ int MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) {
|
| // and the caller does not reserve stack slots for them.
|
| ASSERT(num_arguments >= 0);
|
| #ifdef _WIN64
|
| - static const int kMinimumStackSlots = 4;
|
| + const int kMinimumStackSlots = kRegisterPassedArguments;
|
| if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots;
|
| return num_arguments;
|
| #else
|
| - static const int kRegisterPassedArguments = 6;
|
| if (num_arguments < kRegisterPassedArguments) return 0;
|
| return num_arguments - kRegisterPassedArguments;
|
| #endif
|
| @@ -2822,6 +2826,10 @@ void MacroAssembler::PrepareCallCFunction(int num_arguments) {
|
| int frame_alignment = OS::ActivationFrameAlignment();
|
| ASSERT(frame_alignment != 0);
|
| ASSERT(num_arguments >= 0);
|
| +
|
| + // Reserve space for Isolate address which is always passed as last parameter
|
| + num_arguments += 1;
|
| +
|
| // Make stack end at alignment and allocate space for arguments and old rsp.
|
| movq(kScratchRegister, rsp);
|
| ASSERT(IsPowerOf2(frame_alignment));
|
| @@ -2841,6 +2849,26 @@ void MacroAssembler::CallCFunction(ExternalReference function,
|
|
|
|
|
| void MacroAssembler::CallCFunction(Register function, int num_arguments) {
|
| + // Pass current isolate address as additional parameter.
|
| + if (num_arguments < kRegisterPassedArguments) {
|
| +#ifdef _WIN64
|
| + // First four arguments are passed in registers on Windows.
|
| + Register arg_to_reg[] = {rcx, rdx, r8, r9};
|
| +#else
|
| + // First six arguments are passed in registers on other platforms.
|
| + Register arg_to_reg[] = {rdi, rsi, rdx, rcx, r8, r9};
|
| +#endif
|
| + Register reg = arg_to_reg[num_arguments];
|
| + movq(reg, ExternalReference::isolate_address());
|
| + } else {
|
| + // Push Isolate pointer after all parameters.
|
| + int argument_slots_on_stack =
|
| + ArgumentStackSlotsForCFunctionCall(num_arguments);
|
| + movq(kScratchRegister, ExternalReference::isolate_address());
|
| + movq(Operand(rsp, argument_slots_on_stack * kPointerSize),
|
| + kScratchRegister);
|
| + }
|
| +
|
| // Check stack alignment.
|
| if (FLAG_debug_code) {
|
| CheckStackAlignment();
|
| @@ -2849,6 +2877,7 @@ void MacroAssembler::CallCFunction(Register function, int num_arguments) {
|
| call(function);
|
| ASSERT(OS::ActivationFrameAlignment() != 0);
|
| ASSERT(num_arguments >= 0);
|
| + num_arguments += 1;
|
| int argument_slots_on_stack =
|
| ArgumentStackSlotsForCFunctionCall(num_arguments);
|
| movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize));
|
|
|