Commit 01bd06f4 authored by Georgia Kouveli's avatar Georgia Kouveli Committed by Commit Bot

[arm64] Rewrite Generate_InterpreterPushArgs and its callers.

This moves the handling of the receiver and the final spread argument
into Generate_InterpreterPushArgs and merges the stack allocation to a
single claim operation for the whole argument setup. When we start
padding arguments in TF, we will simply need to claim one extra slot
and store padreg to it in Generate_InterpreterPushArgs (hence the
remaining TODO).

This also replaces the single use of Generate_CheckStackOverflow with
Generate_StackOverflowCheck and removes the former. This change is also
done for arm, ia32 and x64.

Bug: v8:6644
Change-Id: I8d06dda96dbc4a6f219b73c711f894320c2f6cdf
Reviewed-on: https://chromium-review.googlesource.com/738031
Commit-Queue: Georgia Kouveli <georgia.kouveli@arm.com>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49005}
parent bc8c97c7
......@@ -1419,7 +1419,7 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
// We should either have undefined in the allocation_site register or a
// valid AllocationSite.
__ AssertUndefinedOrAllocationSite(allocation_site, x10);
__ AssertUndefinedOrAllocationSite(allocation_site);
}
// Enter the context of the Array function.
......
......@@ -1708,9 +1708,10 @@ void MacroAssembler::AssertGeneratorObject(Register object) {
Check(eq, kOperandIsNotAGeneratorObject);
}
void MacroAssembler::AssertUndefinedOrAllocationSite(Register object,
Register scratch) {
void MacroAssembler::AssertUndefinedOrAllocationSite(Register object) {
if (emit_debug_code()) {
UseScratchRegisterScope temps(this);
Register scratch = temps.AcquireX();
Label done_checking;
AssertNotSmi(object);
JumpIfRoot(object, Heap::kUndefinedValueRootIndex, &done_checking);
......
......@@ -1807,7 +1807,7 @@ class MacroAssembler : public TurboAssembler {
// Abort execution if argument is not undefined or an AllocationSite, enabled
// via --debug-code.
void AssertUndefinedOrAllocationSite(Register object, Register scratch);
void AssertUndefinedOrAllocationSite(Register object);
void JumpIfHeapNumber(Register object, Label* on_heap_number,
SmiCheckType smi_check_type = DONT_DO_SMI_CHECK);
......
......@@ -585,24 +585,19 @@ void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
__ CallRuntime(Runtime::kThrowConstructedNonConstructable);
}
// Clobbers r2; preserves all other registers.
static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc) {
static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
Register scratch,
Label* stack_overflow) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
Label okay;
__ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
// Make r2 the space we have left. The stack might already be overflowed
// here which will cause r2 to become negative.
__ sub(r2, sp, r2);
__ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
// Make scratch the space we have left. The stack might already be overflowed
// here which will cause scratch to become negative.
__ sub(scratch, sp, scratch);
// Check if the arguments will overflow the stack.
__ cmp(r2, Operand(argc, LSL, kPointerSizeLog2));
__ b(gt, &okay); // Signed comparison.
// Out of stack space.
__ CallRuntime(Runtime::kThrowStackOverflow);
__ bind(&okay);
__ cmp(scratch, Operand(num_args, LSL, kPointerSizeLog2));
__ b(le, stack_overflow); // Signed comparison.
}
static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
......@@ -633,7 +628,15 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// Check if we have enough stack space to push all arguments.
// Clobbers r2.
Generate_CheckStackOverflow(masm, r3);
Label enough_stack_space, stack_overflow;
Generate_StackOverflowCheck(masm, r3, r2, &stack_overflow);
__ b(&enough_stack_space);
__ bind(&stack_overflow);
__ CallRuntime(Runtime::kThrowStackOverflow);
// Unreachable code.
__ bkpt(0);
__ bind(&enough_stack_space);
// Remember new.target.
__ mov(r5, r0);
......@@ -1036,21 +1039,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ b(&bytecode_array_loaded);
}
static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
Register scratch,
Label* stack_overflow) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
__ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
// Make scratch the space we have left. The stack might already be overflowed
// here which will cause scratch to become negative.
__ sub(scratch, sp, scratch);
// Check if the arguments will overflow the stack.
__ cmp(scratch, Operand(num_args, LSL, kPointerSizeLog2));
__ b(le, stack_overflow); // Signed comparison.
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register num_args, Register index,
Register limit, Register scratch) {
......
This diff is collapsed.
......@@ -395,33 +395,30 @@ void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
__ CallRuntime(Runtime::kThrowConstructedNonConstructable);
}
// Clobbers ecx, edx, edi; preserves all other registers.
static void Generate_CheckStackOverflow(MacroAssembler* masm) {
// eax : the number of items to be pushed to the stack
//
static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
Register scratch1, Register scratch2,
Label* stack_overflow,
bool include_receiver = false) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
Label okay;
ExternalReference real_stack_limit =
ExternalReference::address_of_real_stack_limit(masm->isolate());
__ mov(edi, Operand::StaticVariable(real_stack_limit));
// Make ecx the space we have left. The stack might already be overflowed
// here which will cause ecx to become negative.
__ mov(ecx, esp);
__ sub(ecx, edi);
// Make edx the space we need for the array when it is unrolled onto the
__ mov(scratch1, Operand::StaticVariable(real_stack_limit));
// Make scratch2 the space we have left. The stack might already be overflowed
// here which will cause scratch2 to become negative.
__ mov(scratch2, esp);
__ sub(scratch2, scratch1);
// Make scratch1 the space we need for the array when it is unrolled onto the
// stack.
__ mov(edx, eax);
__ shl(edx, kPointerSizeLog2);
__ mov(scratch1, num_args);
if (include_receiver) {
__ add(scratch1, Immediate(1));
}
__ shl(scratch1, kPointerSizeLog2);
// Check if the arguments will overflow the stack.
__ cmp(ecx, edx);
__ j(greater, &okay); // Signed comparison.
// Out of stack space.
__ CallRuntime(Runtime::kThrowStackOverflow);
__ bind(&okay);
__ cmp(scratch2, scratch1);
__ j(less_equal, stack_overflow); // Signed comparison.
}
static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
......@@ -448,8 +445,17 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
__ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset));
// Check if we have enough stack space to push all arguments.
// Expects argument count in eax. Clobbers ecx, edx, edi.
Generate_CheckStackOverflow(masm);
// Argument count in eax. Clobbers ecx and edx.
Label enough_stack_space, stack_overflow;
Generate_StackOverflowCheck(masm, eax, ecx, edx, &stack_overflow);
__ jmp(&enough_stack_space);
__ bind(&stack_overflow);
__ CallRuntime(Runtime::kThrowStackOverflow);
// This should be unreachable.
__ int3();
__ bind(&enough_stack_space);
// Copy arguments to the stack in a loop.
Label loop, entry;
......@@ -961,32 +967,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
}
static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
Register scratch1, Register scratch2,
Label* stack_overflow,
bool include_receiver = false) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
ExternalReference real_stack_limit =
ExternalReference::address_of_real_stack_limit(masm->isolate());
__ mov(scratch1, Operand::StaticVariable(real_stack_limit));
// Make scratch2 the space we have left. The stack might already be overflowed
// here which will cause scratch2 to become negative.
__ mov(scratch2, esp);
__ sub(scratch2, scratch1);
// Make scratch1 the space we need for the array when it is unrolled onto the
// stack.
__ mov(scratch1, num_args);
if (include_receiver) {
__ add(scratch1, Immediate(1));
}
__ shl(scratch1, kPointerSizeLog2);
// Check if the arguments will overflow the stack.
__ cmp(scratch2, scratch1);
__ j(less_equal, stack_overflow); // Signed comparison.
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register array_limit,
Register start_address) {
......
......@@ -400,31 +400,23 @@ void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
__ CallRuntime(Runtime::kThrowConstructedNonConstructable);
}
// Clobbers rcx, r11, kScratchRegister; preserves all other registers.
static void Generate_CheckStackOverflow(MacroAssembler* masm) {
// rax : the number of items to be pushed to the stack
//
static void Generate_StackOverflowCheck(
MacroAssembler* masm, Register num_args, Register scratch,
Label* stack_overflow,
Label::Distance stack_overflow_distance = Label::kFar) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
Label okay;
__ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
__ movp(rcx, rsp);
// Make rcx the space we have left. The stack might already be overflowed
// here which will cause rcx to become negative.
__ subp(rcx, kScratchRegister);
// Make r11 the space we need for the array when it is unrolled onto the
// stack.
__ movp(r11, rax);
__ shlq(r11, Immediate(kPointerSizeLog2));
__ movp(scratch, rsp);
// Make scratch the space we have left. The stack might already be overflowed
// here which will cause scratch to become negative.
__ subp(scratch, kScratchRegister);
__ sarp(scratch, Immediate(kPointerSizeLog2));
// Check if the arguments will overflow the stack.
__ cmpp(rcx, r11);
__ j(greater, &okay); // Signed comparison.
// Out of stack space.
__ CallRuntime(Runtime::kThrowStackOverflow);
__ bind(&okay);
__ cmpp(scratch, num_args);
// Signed comparison.
__ j(less_equal, stack_overflow, stack_overflow_distance);
}
static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
......@@ -524,8 +516,17 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// rdx : new.target
// Check if we have enough stack space to push all arguments.
// Expects argument count in rax. Clobbers rcx, r11.
Generate_CheckStackOverflow(masm);
// Argument count in rax. Clobbers rcx.
Label enough_stack_space, stack_overflow;
Generate_StackOverflowCheck(masm, rax, rcx, &stack_overflow, Label::kNear);
__ jmp(&enough_stack_space);
__ bind(&stack_overflow);
__ CallRuntime(Runtime::kThrowStackOverflow);
// This should be unreachable.
__ int3();
__ bind(&enough_stack_space);
// Copy arguments to the stack in a loop.
// Register rbx points to array of pointers to handle locations.
......@@ -1035,25 +1036,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ jmp(&bytecode_array_loaded);
}
static void Generate_StackOverflowCheck(
MacroAssembler* masm, Register num_args, Register scratch,
Label* stack_overflow,
Label::Distance stack_overflow_distance = Label::kFar) {
// Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked.
__ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
__ movp(scratch, rsp);
// Make scratch the space we have left. The stack might already be overflowed
// here which will cause scratch to become negative.
__ subp(scratch, kScratchRegister);
__ sarp(scratch, Immediate(kPointerSizeLog2));
// Check if the arguments will overflow the stack.
__ cmpp(scratch, num_args);
// Signed comparison.
__ j(less_equal, stack_overflow, stack_overflow_distance);
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm,
Register num_args,
Register start_address,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment