From 2bbe1533e8cf0f3954229d55b03f265d1a82fc90 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 11 Oct 2008 11:54:12 +0200 Subject: [PATCH] truly thread-local vms; don't compile popen.scm * ice-9/Makefile.am: Don't compile popen.scm, its behaviour at runtime is not consistent -- seems to miss some GC references? I suspect a bug in the compiler. In any case without popen.scm being compiled, continuations.test, r4rs.tes, and r5rs_pitfall.test do pass. * libguile/threads.h (scm_i_thread): * libguile/threads.c (thread_mark, guilify_self_2): Add a field for the thread's vm. Previously I had this as a fluid, but it seems that newly created threads share their fluid values from the creator thread; as expected, I guess. In any case one VM should not be active in two threads. * libguile/vm.c (scm_the_vm): Change to access the thread-local vm, instead of accessing a fluid. (scm_the_vm_fluid): Removed. * module/system/vm/vm.scm: Removed *the-vm*. --- ice-9/Makefile.am | 7 +++++-- libguile/threads.c | 2 ++ libguile/threads.h | 1 + libguile/vm.c | 19 +++++++------------ module/system/vm/vm.scm | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ice-9/Makefile.am b/ice-9/Makefile.am index e14548671..134d6f7b3 100644 --- a/ice-9/Makefile.am +++ b/ice-9/Makefile.am @@ -35,7 +35,7 @@ SOURCES = psyntax-pp.scm boot-9.scm \ debug.scm debugger.scm documentation.scm emacs.scm expect.scm \ format.scm getopt-long.scm hcons.scm i18n.scm \ lineio.scm ls.scm mapping.scm \ - networking.scm null.scm optargs.scm poe.scm popen.scm \ + networking.scm null.scm optargs.scm poe.scm \ posix.scm q.scm r4rs.scm r5rs.scm \ rdelim.scm receive.scm regex.scm runq.scm rw.scm \ safe-r5rs.scm safe.scm session.scm slib.scm stack-catch.scm \ @@ -48,6 +48,9 @@ SOURCES = psyntax-pp.scm boot-9.scm \ # match.scm compiles, but then using it (via # snarf-check-and-output-texi) fails. need to figure out what the # problem is. +# +# popen.scm compiles, but then breaks the test suite via random lost gc +# references. need to figure out what's going on there. # # occam-channel and gds-client use goops, which is not yet vm-compatible # (it does some compilation-like optimizations for the interpreter), so @@ -55,7 +58,7 @@ SOURCES = psyntax-pp.scm boot-9.scm \ # # psyntax.scm needs help. fortunately it's only needed when recompiling # psyntax-pp.scm. -NOCOMP_SOURCES = match.scm occam-channel.scm gds-client.scm psyntax.scm +NOCOMP_SOURCES = match.scm occam-channel.scm gds-client.scm psyntax.scm popen.scm include $(top_srcdir)/guilec.mk diff --git a/libguile/threads.c b/libguile/threads.c index 72af3d17f..d67ff06a7 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -158,6 +158,7 @@ thread_mark (SCM obj) scm_gc_mark (t->dynwinds); scm_gc_mark (t->active_asyncs); scm_gc_mark (t->continuation_root); + scm_gc_mark (t->vm); return t->dynamic_state; } @@ -506,6 +507,7 @@ guilify_self_2 (SCM parent) scm_gc_register_collectable_memory (t, sizeof (scm_i_thread), "thread"); t->continuation_root = scm_cons (t->handle, SCM_EOL); t->continuation_base = t->base; + t->vm = SCM_BOOL_F; if (scm_is_true (parent)) t->dynamic_state = scm_make_dynamic_state (parent); diff --git a/libguile/threads.h b/libguile/threads.h index dea1a8e5d..398c30fb9 100644 --- a/libguile/threads.h +++ b/libguile/threads.h @@ -111,6 +111,7 @@ typedef struct scm_i_thread { SCM_STACKITEM *continuation_base; /* For keeping track of the stack and registers. */ + SCM vm; SCM_STACKITEM *base; SCM_STACKITEM *top; jmp_buf regs; diff --git a/libguile/vm.c b/libguile/vm.c index efffb89ca..c0cf672d5 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -360,8 +360,6 @@ vm_heapify_frames (SCM vm) scm_t_bits scm_tc16_vm; -SCM scm_the_vm_fluid; - static SCM make_vm (void) #define FUNC_NAME "make_vm" @@ -372,6 +370,9 @@ make_vm (void) vp->stack_size = VM_DEFAULT_STACK_SIZE; vp->stack_base = scm_gc_malloc (vp->stack_size * sizeof (SCM), "stack-base"); +#ifdef VM_ENABLE_STACK_NULLING + memset (vp->stack_base, 0, vp->stack_size * sizeof (SCM)); +#endif vp->stack_limit = vp->stack_base + vp->stack_size - 3; vp->ip = NULL; vp->sp = vp->stack_base - 1; @@ -448,14 +449,12 @@ SCM_DEFINE (scm_the_vm, "the-vm", 0, 0, 0, "") #define FUNC_NAME s_scm_the_vm { - SCM ret; + scm_i_thread *t = SCM_I_CURRENT_THREAD; - if (SCM_NFALSEP ((ret = scm_fluid_ref (scm_the_vm_fluid)))) - return ret; + if (SCM_UNLIKELY (SCM_FALSEP ((t->vm)))) + t->vm = make_vm (); - ret = make_vm (); - scm_fluid_set_x (scm_the_vm_fluid, ret); - return ret; + return t->vm; } #undef FUNC_NAME @@ -771,10 +770,6 @@ scm_bootstrap_vm (void) scm_set_smob_free (scm_tc16_vm, vm_free); scm_set_smob_apply (scm_tc16_vm, scm_vm_apply, 1, 0, 1); - scm_the_vm_fluid = scm_permanent_object (scm_make_fluid ()); - scm_fluid_set_x (scm_the_vm_fluid, make_vm ()); - scm_c_define ("*the-vm*", scm_the_vm_fluid); - scm_c_define ("load-compiled", scm_c_make_gsubr ("load-compiled/vm", 1, 0, 0, scm_load_compiled_with_vm)); diff --git a/module/system/vm/vm.scm b/module/system/vm/vm.scm index e4f5e98a3..725c1a281 100644 --- a/module/system/vm/vm.scm +++ b/module/system/vm/vm.scm @@ -22,7 +22,7 @@ (define-module (system vm vm) #:use-module (system vm frame) #:use-module (system vm objcode) - #:export (vm? the-vm *the-vm* make-vm vm-version + #:export (vm? the-vm make-vm vm-version vm:ip vm:sp vm:fp vm:last-ip vm-load vm-return-value