mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-05 17:20:18 +02:00
Capturing continuations pins conservative roots
* libguile/continuations.c (pin_conservative_roots): New helper. (capture_auxiliary_stack): (scm_i_make_continuation): Pin aux stack, jmpbuf, and stack items.
This commit is contained in:
parent
12da6739b1
commit
4e5a132f4f
1 changed files with 25 additions and 0 deletions
|
@ -38,6 +38,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "dynstack.h"
|
#include "dynstack.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
|
#include "gc-internal.h"
|
||||||
#include "gsubr.h"
|
#include "gsubr.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "instructions.h"
|
#include "instructions.h"
|
||||||
|
@ -118,6 +119,23 @@ scm_i_print_continuation (SCM obj, SCM port, scm_print_state *state SCM_UNUSED)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pin_conservative_roots (scm_thread *thread, void *base, size_t size)
|
||||||
|
{
|
||||||
|
struct gc_mutator *mut = thread->mutator;
|
||||||
|
struct gc_heap *heap = gc_mutator_heap (mut);
|
||||||
|
|
||||||
|
size_t nwords = size / sizeof (scm_t_bits);
|
||||||
|
scm_t_bits *words = base;
|
||||||
|
for (size_t i = 0; i < nwords; i++)
|
||||||
|
{
|
||||||
|
struct gc_conservative_ref maybe_ref = gc_conservative_ref (words[i]);
|
||||||
|
struct gc_ref ref = gc_resolve_conservative_ref (heap, maybe_ref, 0);
|
||||||
|
if (!gc_ref_is_null (ref))
|
||||||
|
gc_pin_object (mut, ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* James Clark came up with this neat one instruction fix for
|
/* James Clark came up with this neat one instruction fix for
|
||||||
* continuations on the SPARC. It flushes the register windows so
|
* continuations on the SPARC. It flushes the register windows so
|
||||||
* that all the state of the process is contained in the stack.
|
* that all the state of the process is contained in the stack.
|
||||||
|
@ -160,6 +178,10 @@ capture_auxiliary_stack (scm_thread *thread, struct scm_continuation *continuati
|
||||||
"continuation auxiliary stack");
|
"continuation auxiliary stack");
|
||||||
memcpy (continuation->auxiliary_stack, thread->auxiliary_stack_base,
|
memcpy (continuation->auxiliary_stack, thread->auxiliary_stack_base,
|
||||||
continuation->auxiliary_stack_size);
|
continuation->auxiliary_stack_size);
|
||||||
|
|
||||||
|
pin_conservative_roots (thread,
|
||||||
|
continuation->auxiliary_stack,
|
||||||
|
continuation->auxiliary_stack_size);
|
||||||
#endif /* SCM_HAVE_AUXILIARY_STACK */
|
#endif /* SCM_HAVE_AUXILIARY_STACK */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +205,7 @@ scm_i_make_continuation (scm_thread *thread, struct scm_vm_cont *vm_cont)
|
||||||
"continuation");
|
"continuation");
|
||||||
continuation->tag = scm_tc16_continuation;
|
continuation->tag = scm_tc16_continuation;
|
||||||
memcpy (continuation->jmpbuf, thread->vm.registers, sizeof (jmp_buf));
|
memcpy (continuation->jmpbuf, thread->vm.registers, sizeof (jmp_buf));
|
||||||
|
pin_conservative_roots (thread, continuation->jmpbuf, sizeof (jmp_buf));
|
||||||
capture_auxiliary_stack (thread, continuation);
|
capture_auxiliary_stack (thread, continuation);
|
||||||
continuation->root = thread->continuation_root;
|
continuation->root = thread->continuation_root;
|
||||||
continuation->vm_cont = vm_cont;
|
continuation->vm_cont = vm_cont;
|
||||||
|
@ -193,6 +216,8 @@ scm_i_make_continuation (scm_thread *thread, struct scm_vm_cont *vm_cont)
|
||||||
memcpy (continuation->stack, src, sizeof (SCM_STACKITEM) * stack_size);
|
memcpy (continuation->stack, src, sizeof (SCM_STACKITEM) * stack_size);
|
||||||
continuation->offset = continuation->stack - src;
|
continuation->offset = continuation->stack - src;
|
||||||
continuation->num_stack_items = stack_size;
|
continuation->num_stack_items = stack_size;
|
||||||
|
pin_conservative_roots (thread, continuation->stack,
|
||||||
|
sizeof (SCM_STACKITEM) * stack_size);
|
||||||
|
|
||||||
return make_continuation_trampoline (continuation);
|
return make_continuation_trampoline (continuation);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue