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:
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 &