Each platform and architecture defines the va_list type differently;
on some we can treat it as a pointer and on others we must treat it as
a non-pointer. Turns out Windows is one of the latter.
If a native method using the fast calling convention throws an
exception, we need to make sure the frame for that method is popped
before handling the exception.
We risked deadlock when waiting for other non-daemon threads to exit
since they could not exit without entering exclusive state, which
required waiting for all other threads to go idle.
If AVIAN_USE_FRAME_POINTER is not defined, the caller of vmInvoke will
calculate a frame size which assumes vmInvoke does not push rbp on the
stack before allocating the frame. However, vmInvoke pushes rbp
reguardless, so we need to adjust the frame size to ensure the stack
remains aligned.
That code was unused and will be unecessary until we add proper
support for unwinding through tail calls in nextFrame, at which point
it may be reinstated in some form.
It is dangerous to initiate a GC from a thunk like divideLong (which
was possible when allocating a new ArithmeticException to signal
divide-by-zero) since we don't currently generate a GC root frame map
for the return address of the thunk call. Instead, we use the backup
heap area if there is room, or else throw a pre-allocated exception
instead.
Like, PowerPC, ARM has an instruction cache which must be manually
flushed if/when we compile a new method. This commit updates
syncInstructionCache to use GCC's builtin __clear_cache routine.
This fixes the tails=true build (at least for x86_64) and eliminates
the need for a frame table in the tails=false build. In the
tails=true build, we still need a frame table on x86(_64) to help
determine whether we've caught a thread executing code to do a tail
call or pop arguments off the stack. However, I've not yet written
the code to actually use this table, and it is only needed to handle
asynchronous unwinds via Thread.getStackTrace.