klisp

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

commit feae5bcdbe41d8abfaf64077495305144eeff1ac
parent dd4b78baa4ef92456d15a58ef80f03e6a28354ca
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 15 Apr 2011 15:49:14 -0300

Added dummy pairs a generalized mechanism to protect from the GC some lists that are created in many ground functions.

Diffstat:
Msrc/kgc.c | 8+++++---
Msrc/kpair.h | 29+++++++++++++++++++++++++++++
Msrc/kstate.c | 13+++++++++----
Msrc/kstate.h | 9+++++++++
4 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/src/kgc.c b/src/kgc.c @@ -568,8 +568,8 @@ static void markroot (klisp_State *K) { markvalue(K, K->shared_dict); /* Mark all objects in the auxiliary stack, - (all valid indexes are below top) and all the objects in - the two protected areas */ + (all valid indexes are below top), all the objects in + the two protected areas, and the two two dummy pairs */ markvaluearray(K, K->sbuf, K->stop); markvaluearray(K, K->rootedtv_buf, K->rootedtv_top); /* the area protecting variables is an array of type TValue *[] */ @@ -577,7 +577,9 @@ static void markroot (klisp_State *K) { for (int i = 0, top = K->rootedv_top; i < top; i++, ptr++) { markvalue(K, **ptr); } - + + markvalue(K, K->dummy_pair1); + markvalue(K, K->dummy_pair2); /* markmt(g); */ K->gcstate = GCSpropagate; } diff --git a/src/kpair.h b/src/kpair.h @@ -9,6 +9,7 @@ #include "kobject.h" #include "kstate.h" +#include "klimits.h" /* TODO: add type assertions */ #define kcar(p_) (tv2pair(p_)->car) @@ -63,4 +64,32 @@ TValue kcons_g(klisp_State *K, bool m, TValue car, TValue cdr); bool kpairp(TValue obj); +inline TValue kget_dummy1(klisp_State *K) +{ + klisp_assert(ttispair(K->dummy_pair2) && ttisnil(kcdr(K->dummy_pair2))); + return K->dummy_pair1; +} + +inline TValue kcutoff_dummy1(klisp_State *K) +{ + klisp_assert(ttispair(K->dummy_pair1)); + TValue res = kcdr(K->dummy_pair1); + kset_cdr(K->dummy_pair1, KNIL); + return res; +} + +inline TValue kget_dummy2(klisp_State *K) +{ + klisp_assert(ttispair(K->dummy_pair2) && ttisnil(kcdr(K->dummy_pair2))); + return K->dummy_pair2; +} + +inline TValue kcutoff_dummy2(klisp_State *K) +{ + klisp_assert(ttispair(K->dummy_pair2)); + TValue res = kcdr(K->dummy_pair2); + kset_cdr(K->dummy_pair2, KNIL); + return res; +} + #endif diff --git a/src/kstate.c b/src/kstate.c @@ -113,6 +113,15 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { /* TEMP: err */ /* do nothing for now */ + /* init the stacks used to protect variables & values from gc, + this should be done before any new object is created because + they are used by them */ + K->rootedtv_top = 0; + K->rootedv_top = 0; + + K->dummy_pair1 = kcons(K, KINERT, KNIL); + K->dummy_pair2 = kcons(K, KINERT, KNIL); + /* initialize strings */ /* Empty string */ /* TODO: make it uncollectible */ @@ -164,10 +173,6 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { 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 */ diff --git a/src/kstate.h b/src/kstate.h @@ -138,6 +138,13 @@ struct klisp_State { object pointed to by a variable may change */ int32_t rootedv_top; TValue *rootedv_buf[GC_PROTECT_SIZE]; + + /* These two are useful for constructing lists by means of set-car & + set-cdr. The idea is that these dummy pairs start as the head of + the list (protecting the entire chain from GC) and at the end of the + construction, the list is cut off from the cdr of the dummy */ + TValue dummy_pair1; + TValue dummy_pair2; }; /* some size related macros */ @@ -310,6 +317,8 @@ inline void krootedv_pop(klisp_State *K) --(K->rootedv_top); } +/* dummy functions will be in kpair.h, because we can't include + it from here */ /* ** prototypes for underlying c functions of continuations &