klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit b2d273fdd9a85af093465d6a1c56a7f858a20155
parent 8f304536670df184a1d73f226187082ed9ee92c8
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 15 Apr 2011 14:54:23 -0300

Added two stacks for rooting both values and variables, and added them to the gc root scanning code.

Diffstat:
Msrc/kgc.c | 12++++++++----
Msrc/kstate.c | 18++++++++++--------
Msrc/kstate.h | 41+++++++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/src/kgc.c b/src/kgc.c @@ -568,10 +568,14 @@ static void markroot (klisp_State *K) { markvalue(K, K->shared_dict); /* Mark all objects in the auxiliary stack, - all valid indexes are below top */ - TValue *ptr = K->sbuf; - for (int i = 0, top = K->stop; i < top; i++, ptr++) { - markvalue(K, *ptr); + (all valid indexes are below top) and all the objects in + the two protected areas */ + markvaluearray(K, K->sbuf, K->stop); + markvaluearray(K, K->rootedtv_buf, K->rootedtv_top); + /* the area protecting variables is an array of type TValue *[] */ + TValue **ptr = K->rootedv_buf; + for (int i = 0, top = K->rootedv_top; i < top; i++, ptr++) { + markvalue(K, **ptr); } /* markmt(g); */ diff --git a/src/kstate.c b/src/kstate.c @@ -100,14 +100,11 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { K->grayagain = NULL; K->weak = NULL; K->tmudata = NULL; - /* how to init other gc values ?? */ K->totalbytes = state_size() + KS_ISSIZE * sizeof(TValue) + KS_ITBSIZE; - /* CHECK this when implementing incremental collector */ - K->GCthreshold = 4*K->totalbytes; /* this is from lua, but we - still have a lot of allocation - to do... */ - + K->GCthreshold = UINT32_MAX; /* we still have a lot of allocation + to do, put a very high value to + avoid collection */ K->estimate = 0; /* doesn't matter, it is set by gc later */ K->gcdept = 0; K->gcpause = KLISPI_GCPAUSE; @@ -166,9 +163,16 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { K->list_app = kwrap(K, kmake_operative(K, KNIL, KNIL, list, 0)); K->ground_env = kmake_empty_environment(K); K->module_params_sym = ksymbol_new(K, "module-parameters"); + + /* init the stacks used to protect variables & values from gc */ + K->rootedtv_top = 0; + K->rootedv_top = 0; kinit_ground_env(K); + /* set the threshold for gc start now that we have allocated all mem */ + K->GCthreshold = 4*K->totalbytes; + return K; } @@ -480,5 +484,3 @@ void klisp_close (klisp_State *K) /* NOTE: this needs to be done "by hand" */ (*(K->frealloc))(K->ud, K, state_size(), 0); } - - diff --git a/src/kstate.h b/src/kstate.h @@ -34,6 +34,9 @@ typedef struct { int32_t saved_col; } ksource_info_t; +/* We would probably do with 3 or 4, but have a little extra just in case */ +#define GC_PROTECT_SIZE 16 + /* NOTE: when adding TValues here, remember to add them to markroot in kgc.c!! */ struct klisp_State { @@ -125,6 +128,16 @@ struct klisp_State { int32_t ssize; /* total size of array */ int32_t stop; /* top of the stack (all elements are below this index) */ TValue *sbuf; + + /* TValue stack to protect values from gc, must not grow, otherwise + it may call the gc */ + int32_t rootedtv_top; + TValue rootedtv_buf[GC_PROTECT_SIZE]; + + /* TValue * stack to protect c variables from gc. This is used when the + object pointed to by a variable may change */ + int32_t rootedv_top; + TValue *rootedv_buf[GC_PROTECT_SIZE]; }; /* some size related macros */ @@ -269,6 +282,34 @@ inline bool ks_tbisempty(klisp_State *K) return ks_tbidx(K) == 0; } +/* +** Functions to protect values from GC +** TODO: add write barriers +*/ +inline void krootedtv_push(klisp_State *K, TValue tv) +{ + klisp_assert(K->rootedtv_top < GC_PROTECT_SIZE); + K->rootedtv_buf[K->rootedtv_top++] = tv; +} + +inline void krootedtv_pop(klisp_State *K) +{ + klisp_assert(K->rootedtv_top > 0); + --(K->rootedtv_top); +} + +inline void krootedv_push(klisp_State *K, TValue *v) +{ + klisp_assert(K->rootedv_top < GC_PROTECT_SIZE); + K->rootedv_buf[K->rootedv_top++] = v; +} + +inline void krootedv_pop(klisp_State *K) +{ + klisp_assert(K->rootedv_top > 0); + --(K->rootedv_top); +} + /* ** prototypes for underlying c functions of continuations &