vm: sketchy signal dispatch from leaf procs
parent
6e4117035e
commit
a374c2da05
|
@ -24,19 +24,30 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell newpc)
|
||||||
that don't create a stack frame will be out of alignment by sizeof(cell)
|
that don't create a stack frame will be out of alignment by sizeof(cell)
|
||||||
bytes. */
|
bytes. */
|
||||||
cell offset = *sp % 16;
|
cell offset = *sp % 16;
|
||||||
if (offset != 0)
|
if (offset == 0) {
|
||||||
fatal_error("fault in unaligned frame at", *pc);
|
signal_from_leaf = false;
|
||||||
|
cell newsp = *sp - sizeof(cell);
|
||||||
/* Nonleaf procedure */
|
*sp = newsp;
|
||||||
cell newsp = *sp - sizeof(cell);
|
*(cell*)newsp = *pc;
|
||||||
*sp = newsp;
|
*pc = newpc;
|
||||||
*(cell*)newsp = *pc;
|
ctx->callstack_top = (stack_frame*)newsp;
|
||||||
*pc = newpc;
|
} else if (offset == 16 - sizeof(cell)) {
|
||||||
ctx->callstack_top = (stack_frame*)newsp;
|
dispatch_signal_handler_from_leaf(sp, pc, newpc);
|
||||||
|
} else {
|
||||||
/* XXX handle leaf procedure */
|
fatal_error("Invalid stack frame during signal handler", *sp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void factor_vm::dispatch_signal_handler_from_leaf(cell *sp, cell *pc, cell newpc)
|
||||||
|
{
|
||||||
|
/* We should try to conjure a stack frame here, but we may need to deal
|
||||||
|
with callstack overflows or the GC moving code around.
|
||||||
|
For now leave the stack untouched so the signal handler returns into
|
||||||
|
the parent procedure. This will cause things to blow up if the stack
|
||||||
|
is left unbalanced. */
|
||||||
|
signal_from_leaf = true;
|
||||||
|
*pc = newpc;
|
||||||
|
}
|
||||||
|
|
||||||
/* We ignore the two topmost frames, the 'callstack' primitive
|
/* We ignore the two topmost frames, the 'callstack' primitive
|
||||||
frame itself, and the frame calling the 'callstack' primitive,
|
frame itself, and the frame calling the 'callstack' primitive,
|
||||||
|
|
|
@ -179,9 +179,11 @@ void factor_vm::enqueue_safepoint_sample()
|
||||||
|
|
||||||
void factor_vm::handle_safepoint()
|
void factor_vm::handle_safepoint()
|
||||||
{
|
{
|
||||||
|
if (signal_from_leaf)
|
||||||
|
std::cout << "XXX SIGNALED FROM LEAF\n";
|
||||||
|
|
||||||
if (safepoint_fep) {
|
if (safepoint_fep) {
|
||||||
std::cout << "Interrupted. Entering low-level debugger...\n";
|
std::cout << "Interrupted\n";
|
||||||
std::cout << "\n";
|
|
||||||
factorbug();
|
factorbug();
|
||||||
code->unguard_safepoint();
|
code->unguard_safepoint();
|
||||||
safepoint_fep = false;
|
safepoint_fep = false;
|
||||||
|
|
|
@ -56,6 +56,7 @@ struct factor_vm
|
||||||
|
|
||||||
/* Global variables used to pass fault handler state from signal handler
|
/* Global variables used to pass fault handler state from signal handler
|
||||||
to VM */
|
to VM */
|
||||||
|
bool signal_from_leaf;
|
||||||
cell signal_number;
|
cell signal_number;
|
||||||
cell signal_fault_addr;
|
cell signal_fault_addr;
|
||||||
unsigned int signal_fpu_status;
|
unsigned int signal_fpu_status;
|
||||||
|
@ -605,6 +606,7 @@ struct factor_vm
|
||||||
void primitive_callstack_bounds();
|
void primitive_callstack_bounds();
|
||||||
template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
|
template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
|
||||||
void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
|
void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
|
||||||
|
void dispatch_signal_handler_from_leaf(cell *sp, cell *pc, cell newpc);
|
||||||
|
|
||||||
template<typename CellA, typename CellB, typename CellC>
|
template<typename CellA, typename CellB, typename CellC>
|
||||||
void dispatch_signal_handler(CellA *sp, CellB *pc, CellC newpc)
|
void dispatch_signal_handler(CellA *sp, CellB *pc, CellC newpc)
|
||||||
|
|
Loading…
Reference in New Issue