diff options
Diffstat (limited to 'libguile/vm.c')
-rw-r--r-- | libguile/vm.c | 128 |
1 files changed, 33 insertions, 95 deletions
diff --git a/libguile/vm.c b/libguile/vm.c index a042e9535..cb46c54cc 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -39,7 +39,6 @@ #include "async.h" #include "atomic.h" #include "atomics-internal.h" -#include "bdw-gc.h" #include "cache-internal.h" #include "continuations.h" #include "control.h" @@ -79,8 +78,6 @@ #include "vm.h" -#include <gc/gc_mark.h> - #if (defined __GNUC__) # define SCM_NOINLINE __attribute__ ((__noinline__)) #else @@ -777,29 +774,17 @@ scm_i_vm_free_stack (struct scm_vm *vp) memset (vp, 0, sizeof (*vp)); } -struct vm_expand_stack_data -{ - struct scm_vm *vp; - size_t stack_size; - union scm_vm_stack_element *new_sp; -}; - -static void * -vm_expand_stack_inner (void *data_ptr) +static union scm_vm_stack_element * +vm_expand_stack_inner (struct scm_vm *vp, size_t needed_size, + union scm_vm_stack_element *new_sp) { - struct vm_expand_stack_data *data = data_ptr; - - struct scm_vm *vp = data->vp; - union scm_vm_stack_element *old_top, *new_bottom; - size_t new_size; - ptrdiff_t reloc; - - old_top = vp->stack_top; - new_size = vp->stack_size; - while (new_size < data->stack_size) + union scm_vm_stack_element *old_top = vp->stack_top; + size_t new_size = vp->stack_size; + while (new_size < needed_size) new_size *= 2; - new_bottom = expand_stack (vp->stack_bottom, vp->stack_size, new_size); + union scm_vm_stack_element *new_bottom = + expand_stack (vp->stack_bottom, vp->stack_size, new_size); if (!new_bottom) return NULL; @@ -807,13 +792,12 @@ vm_expand_stack_inner (void *data_ptr) vp->stack_size = new_size; vp->stack_top = vp->stack_bottom + new_size; vp->stack_limit = vp->stack_bottom; - reloc = vp->stack_top - old_top; + ptrdiff_t reloc = vp->stack_top - old_top; if (vp->fp) vp->fp += reloc; - data->new_sp += reloc; - return new_bottom; + return new_sp + reloc; } static ptrdiff_t @@ -873,17 +857,13 @@ vm_expand_stack (struct scm_vm *vp, union scm_vm_stack_element *new_sp) if (stack_size > vp->stack_size) { - struct vm_expand_stack_data data; + gc_inhibit_preemption (SCM_I_CURRENT_THREAD->mutator); + new_sp = vm_expand_stack_inner (vp, stack_size, new_sp); + gc_reallow_preemption (SCM_I_CURRENT_THREAD->mutator); - data.vp = vp; - data.stack_size = stack_size; - data.new_sp = new_sp; - - if (!GC_call_with_alloc_lock (vm_expand_stack_inner, &data)) + if (!new_sp) /* Throw an unwind-only exception. */ scm_report_stack_overflow (); - - new_sp = data.new_sp; } vp->sp = new_sp; @@ -1082,34 +1062,6 @@ push_interrupt_frame (scm_thread *thread, uint8_t *mra) thread->vm.fp = new_fp; } -struct return_to_continuation_data -{ - struct scm_vm_cont *cp; - struct scm_vm *vp; -}; - -/* Called with the GC lock to prevent the stack marker from traversing a - stack in an inconsistent state. */ -static void * -vm_return_to_continuation_inner (void *data_ptr) -{ - struct return_to_continuation_data *data = data_ptr; - struct scm_vm *vp = data->vp; - struct scm_vm_cont *cp = data->cp; - - /* We know that there is enough space for the continuation, because we - captured it in the past. However there may have been an expansion - since the capture, so we may have to re-link the frame - pointers. */ - memcpy (vp->stack_top - cp->stack_size, - cp->stack_bottom, - cp->stack_size * sizeof (*cp->stack_bottom)); - vp->fp = vp->stack_top - cp->fp_offset; - vm_restore_sp (vp, vp->stack_top - cp->stack_size); - - return NULL; -} - static void reinstate_continuation_x (scm_thread *thread, SCM cont) SCM_NORETURN; static void @@ -1120,7 +1072,6 @@ reinstate_continuation_x (scm_thread *thread, SCM cont) struct scm_vm_cont *cp; size_t n, i, frame_overhead = 3; union scm_vm_stack_element *argv; - struct return_to_continuation_data data; if (!scm_is_eq (continuation->root, thread->continuation_root)) scm_misc_error @@ -1134,9 +1085,17 @@ reinstate_continuation_x (scm_thread *thread, SCM cont) cp = SCM_VM_CONT_DATA (continuation->vm_cont); - data.cp = cp; - data.vp = vp; - GC_call_with_alloc_lock (vm_return_to_continuation_inner, &data); + gc_inhibit_preemption (thread->mutator); + /* We know that there is enough space for the continuation, because we + captured it in the past. However there may have been an expansion + since the capture, so we may have to re-link the frame + pointers. */ + memcpy (vp->stack_top - cp->stack_size, + cp->stack_bottom, + cp->stack_size * sizeof (*cp->stack_bottom)); + vp->fp = vp->stack_top - cp->fp_offset; + vm_restore_sp (vp, vp->stack_top - cp->stack_size); + gc_reallow_preemption (thread->mutator); /* Now we have the continuation properly copied over. We just need to copy on an empty frame and the return values, as the continuation @@ -1170,39 +1129,14 @@ capture_continuation (scm_thread *thread) return scm_i_make_continuation (thread, vm_cont); } -struct compose_continuation_data -{ - struct scm_vm *vp; - struct scm_vm_cont *cp; -}; - -static void * -compose_continuation_inner (void *data_ptr) -{ - struct compose_continuation_data *data = data_ptr; - struct scm_vm *vp = data->vp; - struct scm_vm_cont *cp = data->cp; - - memcpy (vp->fp - cp->stack_size, - cp->stack_bottom, - cp->stack_size * sizeof (*cp->stack_bottom)); - - vp->fp -= cp->fp_offset; - vp->ip = cp->vra; - - return cp->mra; -} - static uint8_t* compose_continuation (scm_thread *thread, SCM cont) { struct scm_vm *vp = &thread->vm; size_t nargs; - struct compose_continuation_data data; struct scm_vm_cont *cp; union scm_vm_stack_element *args; ptrdiff_t old_fp_offset; - uint8_t *mra; if (SCM_UNLIKELY (! SCM_VM_CONT_REWINDABLE_P (cont))) scm_wrong_type_arg_msg (NULL, 0, cont, "resumable continuation"); @@ -1223,9 +1157,13 @@ compose_continuation (scm_thread *thread, SCM cont) vm_push_sp (vp, vp->fp - (cp->stack_size + nargs)); - data.vp = vp; - data.cp = cp; - mra = GC_call_with_alloc_lock (compose_continuation_inner, &data); + gc_inhibit_preemption (thread->mutator); + memcpy (vp->fp - cp->stack_size, + cp->stack_bottom, + cp->stack_size * sizeof (*cp->stack_bottom)); + vp->fp -= cp->fp_offset; + vp->ip = cp->vra; + gc_reallow_preemption (thread->mutator); /* The resumed continuation will expect ARGS on the stack as if from a multiple-value return. */ @@ -1251,7 +1189,7 @@ compose_continuation (scm_thread *thread, SCM cont) } } - return mra; + return cp->mra; } static void |