vm: factor out dispatch_signal_handler logic
parent
dc42365007
commit
6e4117035e
|
@ -18,6 +18,26 @@ callstack *factor_vm::allot_callstack(cell size)
|
|||
return stack;
|
||||
}
|
||||
|
||||
void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell newpc)
|
||||
{
|
||||
/* True stack frames are always 16-byte aligned. Leaf procedures
|
||||
that don't create a stack frame will be out of alignment by sizeof(cell)
|
||||
bytes. */
|
||||
cell offset = *sp % 16;
|
||||
if (offset != 0)
|
||||
fatal_error("fault in unaligned frame at", *pc);
|
||||
|
||||
/* Nonleaf procedure */
|
||||
cell newsp = *sp - sizeof(cell);
|
||||
*sp = newsp;
|
||||
*(cell*)newsp = *pc;
|
||||
*pc = newpc;
|
||||
ctx->callstack_top = (stack_frame*)newsp;
|
||||
|
||||
/* XXX handle leaf procedure */
|
||||
}
|
||||
|
||||
|
||||
/* We ignore the two topmost frames, the 'callstack' primitive
|
||||
frame itself, and the frame calling the 'callstack' primitive,
|
||||
so that set-callstack doesn't get stuck in an infinite loop.
|
||||
|
|
|
@ -35,25 +35,18 @@ void factor_vm::call_fault_handler(
|
|||
MACH_THREAD_STATE_TYPE *thread_state,
|
||||
MACH_FLOAT_STATE_TYPE *float_state)
|
||||
{
|
||||
cell offset = MACH_STACK_POINTER(thread_state) % 16;
|
||||
if (offset != 0)
|
||||
fatal_error("fault in unaligned frame with offset", offset);
|
||||
MACH_STACK_POINTER(thread_state) -= sizeof(cell);
|
||||
*(cell*)MACH_STACK_POINTER(thread_state) = MACH_PROGRAM_COUNTER(thread_state);
|
||||
cell handler = 0;
|
||||
|
||||
ctx->callstack_top = (stack_frame *)MACH_STACK_POINTER(thread_state);
|
||||
|
||||
/* Now we point the program counter at the right handler function. */
|
||||
if(exception == EXC_BAD_ACCESS)
|
||||
{
|
||||
signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
|
||||
MACH_PROGRAM_COUNTER(thread_state) = (cell)factor::memory_signal_handler_impl;
|
||||
handler = (cell)factor::memory_signal_handler_impl;
|
||||
}
|
||||
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
|
||||
{
|
||||
signal_fpu_status = fpu_status(mach_fpu_status(float_state));
|
||||
mach_clear_fpu_status(float_state);
|
||||
MACH_PROGRAM_COUNTER(thread_state) = (cell)factor::fp_signal_handler_impl;
|
||||
handler = (cell)factor::fp_signal_handler_impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -64,8 +57,16 @@ void factor_vm::call_fault_handler(
|
|||
default: signal_number = SIGABRT; break;
|
||||
}
|
||||
|
||||
MACH_PROGRAM_COUNTER(thread_state) = (cell)factor::synchronous_signal_handler_impl;
|
||||
handler = (cell)factor::synchronous_signal_handler_impl;
|
||||
}
|
||||
|
||||
assert(handler != 0);
|
||||
|
||||
dispatch_signal_handler(
|
||||
&MACH_STACK_POINTER(thread_state),
|
||||
&MACH_PROGRAM_COUNTER(thread_state),
|
||||
handler
|
||||
);
|
||||
}
|
||||
|
||||
static void call_fault_handler(
|
||||
|
|
|
@ -138,15 +138,12 @@ void code_heap::unguard_safepoint()
|
|||
|
||||
void factor_vm::dispatch_signal(void *uap, void (handler)())
|
||||
{
|
||||
cell sp = (cell)UAP_STACK_POINTER(uap);
|
||||
cell offset = sp % 16;
|
||||
if (offset != 0)
|
||||
fatal_error("fault in unaligned frame with offset", offset);
|
||||
UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)(sp - sizeof(cell));
|
||||
*(cell*)(UAP_STACK_POINTER(uap)) = (cell)UAP_PROGRAM_COUNTER(uap);
|
||||
UAP_PROGRAM_COUNTER(uap) = (cell)FUNCTION_CODE_POINTER(handler);
|
||||
dispatch_signal_handler(
|
||||
&UAP_STACK_POINTER(uap),
|
||||
&UAP_PROGRAM_COUNTER(uap),
|
||||
FUNCTION_CODE_POINTER(handler)
|
||||
);
|
||||
UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler));
|
||||
ctx->callstack_top = (stack_frame *)UAP_STACK_POINTER(uap);
|
||||
}
|
||||
|
||||
void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
|
||||
|
|
11
vm/vm.hpp
11
vm/vm.hpp
|
@ -604,6 +604,17 @@ struct factor_vm
|
|||
void primitive_set_innermost_stack_frame_quot();
|
||||
void primitive_callstack_bounds();
|
||||
template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
|
||||
void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
|
||||
|
||||
template<typename CellA, typename CellB, typename CellC>
|
||||
void dispatch_signal_handler(CellA *sp, CellB *pc, CellC newpc)
|
||||
{
|
||||
dispatch_signal_handler(
|
||||
reinterpret_cast<cell*>(sp),
|
||||
reinterpret_cast<cell*>(pc),
|
||||
(cell)newpc
|
||||
);
|
||||
}
|
||||
|
||||
// alien
|
||||
char *pinned_alien_offset(cell obj);
|
||||
|
|
Loading…
Reference in New Issue