| Index: src/ia32/macro-assembler-ia32.cc
|
| diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
|
| index 44029ea618a7c8385806a6d870ac763c4f5a09af..72e851de05c019617d1dfcaf52c284b4024c634a 100644
|
| --- a/src/ia32/macro-assembler-ia32.cc
|
| +++ b/src/ia32/macro-assembler-ia32.cc
|
| @@ -2086,10 +2086,10 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) {
|
| jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
|
| }
|
|
|
| -void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| - Register caller_args_count_reg,
|
| - Register scratch0, Register scratch1,
|
| - ReturnAddressState ra_state) {
|
| +void MacroAssembler::PrepareForTailCall(
|
| + const ParameterCount& callee_args_count, Register caller_args_count_reg,
|
| + Register scratch0, Register scratch1, ReturnAddressState ra_state,
|
| + int number_of_temp_values_after_return_address) {
|
| #if DEBUG
|
| if (callee_args_count.is_reg()) {
|
| DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0,
|
| @@ -2097,6 +2097,8 @@ void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| } else {
|
| DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1));
|
| }
|
| + DCHECK(ra_state != ReturnAddressState::kNotOnStack ||
|
| + number_of_temp_values_after_return_address == 0);
|
| #endif
|
|
|
| // Calculate the destination address where we will put the return address
|
| @@ -2104,12 +2106,16 @@ void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| Register new_sp_reg = scratch0;
|
| if (callee_args_count.is_reg()) {
|
| sub(caller_args_count_reg, callee_args_count.reg());
|
| - lea(new_sp_reg, Operand(ebp, caller_args_count_reg, times_pointer_size,
|
| - StandardFrameConstants::kCallerPCOffset));
|
| + lea(new_sp_reg,
|
| + Operand(ebp, caller_args_count_reg, times_pointer_size,
|
| + StandardFrameConstants::kCallerPCOffset -
|
| + number_of_temp_values_after_return_address * kPointerSize));
|
| } else {
|
| lea(new_sp_reg, Operand(ebp, caller_args_count_reg, times_pointer_size,
|
| StandardFrameConstants::kCallerPCOffset -
|
| - callee_args_count.immediate() * kPointerSize));
|
| + (callee_args_count.immediate() +
|
| + number_of_temp_values_after_return_address) *
|
| + kPointerSize));
|
| }
|
|
|
| if (FLAG_debug_code) {
|
| @@ -2123,9 +2129,11 @@ void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| Register tmp_reg = scratch1;
|
| if (ra_state == ReturnAddressState::kOnStack) {
|
| mov(tmp_reg, Operand(ebp, StandardFrameConstants::kCallerPCOffset));
|
| - mov(Operand(esp, 0), tmp_reg);
|
| + mov(Operand(esp, number_of_temp_values_after_return_address * kPointerSize),
|
| + tmp_reg);
|
| } else {
|
| DCHECK(ReturnAddressState::kNotOnStack == ra_state);
|
| + DCHECK_EQ(0, number_of_temp_values_after_return_address);
|
| Push(Operand(ebp, StandardFrameConstants::kCallerPCOffset));
|
| }
|
|
|
| @@ -2136,9 +2144,11 @@ void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
|
| // +2 here is to copy both receiver and return address.
|
| Register count_reg = caller_args_count_reg;
|
| if (callee_args_count.is_reg()) {
|
| - lea(count_reg, Operand(callee_args_count.reg(), 2));
|
| + lea(count_reg, Operand(callee_args_count.reg(),
|
| + 2 + number_of_temp_values_after_return_address));
|
| } else {
|
| - mov(count_reg, Immediate(callee_args_count.immediate() + 2));
|
| + mov(count_reg, Immediate(callee_args_count.immediate() + 2 +
|
| + number_of_temp_values_after_return_address));
|
| // TODO(ishell): Unroll copying loop for small immediate values.
|
| }
|
|
|
|
|