morestack.S (__morestack_non_split): If there is enough stack space already, don't split.
* config/i386/morestack.S (__morestack_non_split): If there is enough stack space already, don't split. Ask for more stack space than we required. From-SVN: r182555
This commit is contained in:
parent
3752b2ab7c
commit
a0c8d0c1e3
2 changed files with 108 additions and 2 deletions
|
@ -1,3 +1,9 @@
|
|||
2011-12-20 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* config/i386/morestack.S (__morestack_non_split): If there is
|
||||
enough stack space already, don't split. Ask for more stack space
|
||||
than we required.
|
||||
|
||||
2011-12-20 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
* unwind-arm-common.inc: Include `tconfig.h', `tsystem.h' and
|
||||
|
|
|
@ -96,13 +96,113 @@
|
|||
#endif
|
||||
|
||||
__morestack_non_split:
|
||||
.cfi_startproc
|
||||
|
||||
#ifndef __x86_64__
|
||||
addl $0x4000,4(%esp)
|
||||
|
||||
# See below for an extended explanation of the CFI instructions.
|
||||
.cfi_offset 8, 8 # New PC stored at CFA + 8
|
||||
.cfi_escape 0x15, 4, 0x7d # DW_CFA_val_offset_sf, %esp, 12/-4
|
||||
# i.e., next %esp is CFA + 12
|
||||
|
||||
pushl %eax # Save %eax in case it is a parameter.
|
||||
|
||||
.cfi_def_cfa %esp,8 # Account for pushed register.
|
||||
|
||||
movl %esp,%eax # Current stack,
|
||||
subl 8(%esp),%eax # less required stack frame size,
|
||||
subl $0x4000,%eax # less space for non-split code.
|
||||
cmpl %gs:0x30,%eax # See if we have enough space.
|
||||
jb 2f # Get more space if we need it.
|
||||
|
||||
# Here the stack is
|
||||
# %esp + 20: stack pointer after two returns
|
||||
# %esp + 16: return address of morestack caller's caller
|
||||
# %esp + 12: size of parameters
|
||||
# %esp + 8: new stack frame size
|
||||
# %esp + 4: return address of this function
|
||||
# %esp: saved %eax
|
||||
#
|
||||
# Since we aren't doing a full split stack, we don't need to
|
||||
# do anything when our caller returns. So we return to our
|
||||
# caller rather than calling it, and let it return as usual.
|
||||
# To make that work we adjust the return address.
|
||||
|
||||
# This breaks call/return address prediction for the call to
|
||||
# this function. I can't figure out a way to make it work
|
||||
# short of copying the parameters down the stack, which will
|
||||
# probably take more clock cycles than we will lose breaking
|
||||
# call/return address prediction. We will only break
|
||||
# prediction for this call, not for our caller.
|
||||
|
||||
movl 4(%esp),%eax # Increment the return address
|
||||
cmpb $0xc3,(%eax) # to skip the ret instruction;
|
||||
je 1f # see above.
|
||||
addl $2,%eax
|
||||
1: inc %eax
|
||||
movl %eax,4(%esp) # Update return address.
|
||||
|
||||
popl %eax # Restore %eax and stack.
|
||||
|
||||
.cfi_def_cfa %esp,4 # Account for popped register.
|
||||
|
||||
ret $8 # Return to caller, popping args.
|
||||
|
||||
2:
|
||||
.cfi_def_cfa %esp,8 # Back to where we were.
|
||||
|
||||
popl %eax # Restore %eax and stack.
|
||||
|
||||
.cfi_def_cfa %esp,4 # Account for popped register.
|
||||
|
||||
addl $0x5000+BACKOFF,4(%esp) # Increment space we request.
|
||||
|
||||
# Fall through into morestack.
|
||||
|
||||
#else
|
||||
addq $0x4000,%r10
|
||||
|
||||
# See below for an extended explanation of the CFI instructions.
|
||||
.cfi_offset 16, 0
|
||||
.cfi_escape 0x15, 7, 0x7f # DW_CFA_val_offset_sf, %esp, 8/-8
|
||||
|
||||
pushq %rax # Save %rax in case caller is using
|
||||
# it to preserve original %r10.
|
||||
.cfi_def_cfa %rsp,16 # Adjust for pushed register.
|
||||
|
||||
movq %rsp,%rax # Current stack,
|
||||
subq %r10,%rax # less required stack frame size,
|
||||
subq $0x4000,%rax # less space for non-split code.
|
||||
|
||||
#ifdef __LP64__
|
||||
cmpq %fs:0x70,%rax # See if we have enough space.
|
||||
#else
|
||||
cmpl %fs:0x40,%eax
|
||||
#endif
|
||||
jb 2f # Get more space if we need it.
|
||||
|
||||
# This breaks call/return prediction, as described above.
|
||||
incq 8(%rsp) # Increment the return address.
|
||||
|
||||
popq %rax # Restore register.
|
||||
|
||||
.cfi_def_cfa %rsp,8 # Adjust for popped register.
|
||||
|
||||
ret # Return to caller.
|
||||
|
||||
2:
|
||||
.cfi_def_cfa %rsp,16 # Back to where we were.
|
||||
|
||||
popq %rax # Restore register.
|
||||
|
||||
.cfi_def_cfa %rsp,8 # Adjust for popped register.
|
||||
|
||||
addq $0x5000+BACKOFF,%r10 # Increment space we request.
|
||||
|
||||
# Fall throug into morestack.
|
||||
|
||||
#endif
|
||||
|
||||
.cfi_endproc
|
||||
#ifdef __ELF__
|
||||
.size __morestack_non_split, . - __morestack_non_split
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue