summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-04-20 06:19:04 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-04-20 06:19:04 -0700
commitc636a168cd57ca5db253db7a0907f06621a6991e (patch)
treeff2626d075047b04dd91b432ad96a3ff348452f2 /lib.c
parentf852a574e4a33ae81d257eb372d2d6947625d81e (diff)
downloadtxr-c636a168cd57ca5db253db7a0907f06621a6991e.tar.gz
txr-c636a168cd57ca5db253db7a0907f06621a6991e.tar.bz2
txr-c636a168cd57ca5db253db7a0907f06621a6991e.zip
Mechanism for recycling conses outside of GC.
* lib.c (recycled_conses): New static variable. (rcyc_pop, rcyc_cons, rcyc_list, rcyc_empty): New functions. (cons): Take a recycled cons, if available. * lib.h (rcyc_pop, rcyc_cons, rcyc_list, rcyc_empty): Declared. * gc.c (gc): Call rcyc_empty to make recycle_list unreachable.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index 8af48c8e..0c648534 100644
--- a/lib.c
+++ b/lib.c
@@ -118,6 +118,7 @@ val time_s, time_local_s, time_utc_s;
val year_s, month_s, day_s, hour_s, min_s, sec_s, dst_s;
static val env_list;
+static val recycled_conses;
mem_t *(*oom_realloc)(mem_t *, size_t);
@@ -602,6 +603,15 @@ val pop(val *plist)
return ret;
}
+val rcyc_pop(val *plist)
+{
+ val rcyc = *plist;
+ val ret = car(rcyc);
+ *plist = cdr(rcyc);
+ rcyc_cons(rcyc);
+ return ret;
+}
+
val upop(val *plist, val *pundo)
{
*pundo = *plist;
@@ -2487,8 +2497,16 @@ mem_t *chk_copy_obj(mem_t *orig, size_t size)
val cons(val car, val cdr)
{
- val obj = make_obj();
- obj->c.type = CONS;
+ val obj;
+
+ if (recycled_conses) {
+ obj = recycled_conses;
+ recycled_conses = recycled_conses->c.cdr;
+ } else {
+ obj = make_obj();
+ obj->c.type = CONS;
+ }
+
obj->c.car = car;
obj->c.cdr = cdr;
return obj;
@@ -2513,6 +2531,33 @@ val make_half_lazy_cons(val func, val car)
return obj;
}
+void rcyc_cons(val cons)
+{
+ rplacd(cons, recycled_conses);
+ cons->c.car = nil;
+ recycled_conses = cons;
+}
+
+void rcyc_list(val list)
+{
+ if (list) {
+ val rl_orig = recycled_conses;
+ recycled_conses = list;
+ for (; list; list = list->c.cdr) {
+ list->c.car = nil;
+ if (!list->c.cdr) {
+ set(mkloc(list->lc.cdr, list), rl_orig);
+ break;
+ }
+ }
+ }
+}
+
+void rcyc_empty(void)
+{
+ recycled_conses = nil;
+}
+
val lcons_fun(val lcons)
{
type_check(lcons, LCONS);