fix stack alignment bug in vmJumpAndInvoke

This was causing crashes on 32-bit OS X continuations=true builds.

There were two important differences between vmInvoke and
vmJumpAndInvoke: (1) vmInvoke expects its stack to be aligned on
entry, modulo the return address whereas the stack argument to
vmJumpAndInvoke is aligned without allowing for the return address,
and (2) vmInvoke pushes EBP before doing its frame allocation, whereas
vmJumpAndInvoke did not take that into account.  So in order for
vmJumpAndInvoke to allocate the exact same frame size that vmInvoke
would have when calling the same method, it needed to add an extra two
words beyond what it was already allocating.

Aside from alignment concerns, the code is not particularly sensitive
to vmJumpAndInvoke allocating a different frame size than vmInvoke,
since we store the frame pointer in a "thread local" variable:

   // remember this stack position, since we won't be able to rely on
   // %rbp being restored when the call returns
   movl   8(%ebp),%eax
   movl   %esp,TARGET_THREAD_SCRATCH(%eax)
...
GLOBAL(vmInvoke_returnAddress):
   // restore stack pointer
   movl   TARGET_THREAD_SCRATCH(%ebx),%esp

My original patch makes an equivalent change for the 64-bit changes,
but I'll leave that for after we release 1.0 since we're in
bugfix-only mode right now
This commit is contained in:
Joel Dice 2014-05-08 09:20:12 -06:00
parent 18e9a01184
commit 3696edeb1e

View File

@ -400,9 +400,10 @@ GLOBAL(vmJumpAndInvoke):
movl 12(%esp),%ecx
// allocate new frame, adding room for callee-saved registers
// allocate new frame, adding room for callee-saved registers,
// return address, and frame pointer
subl 24(%esp),%ecx
subl $CALLEE_SAVED_REGISTER_FOOTPRINT,%ecx
subl $CALLEE_SAVED_REGISTER_FOOTPRINT+8,%ecx
movl 4(%esp),%ebx