summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gc.c19
-rw-r--r--gc.h1
-rw-r--r--lib.c5
-rw-r--r--lib.h2
-rw-r--r--struct.c2
-rw-r--r--vm.c8
6 files changed, 20 insertions, 17 deletions
diff --git a/gc.c b/gc.c
index 18c65915..15384794 100644
--- a/gc.c
+++ b/gc.c
@@ -820,25 +820,27 @@ int gc_is_reachable(val obj)
#if CONFIG_GEN_GC
-val gc_set(loc lo, val obj)
+void gc_assign_check(val p, val c)
{
- val *ptr = valptr(lo);
-
- if (lo.obj && is_ptr(obj) && lo.obj->t.gen == 1 && obj->t.gen == 0 && !full_gc) {
+ if (p && is_ptr(c) && p->t.gen == 1 && c->t.gen == 0 && !full_gc) {
if (checkobj_idx < CHECKOBJ_VEC_SIZE) {
- obj->t.gen = -1;
- checkobj[checkobj_idx++] = obj;
+ c->t.gen = -1;
+ checkobj[checkobj_idx++] = c;
} else if (gc_enabled) {
gc();
- /* obj can't be in gen 0 because there are no baby objects after gc */
+ /* c can't be in gen 0 because there are no baby objects after gc */
} else {
/* We have no space to in checkobj record this backreference, and gc is
not available to promote obj to gen 1. We must schedule a full gc. */
full_gc = 1;
}
}
+}
- *ptr = obj;
+val gc_set(loc lo, val obj)
+{
+ gc_assign_check(lo.obj, obj);
+ *valptr(lo) = obj;
return obj;
}
@@ -862,7 +864,6 @@ val gc_mutated(val obj)
return obj;
}
-
val gc_push(val obj, loc plist)
{
return gc_set(plist, cons(obj, deref(plist)));
diff --git a/gc.h b/gc.h
index 4c3bc042..7025fa59 100644
--- a/gc.h
+++ b/gc.h
@@ -43,6 +43,7 @@ val gc_call_finalizers(val obj);
#if CONFIG_GEN_GC
val gc_set(loc, val);
val gc_push(val, loc);
+void gc_assign_check(val p, val c);
val gc_mutated(val);
extern int full_gc;
#endif
diff --git a/lib.c b/lib.c
index 761646ff..52320dfe 100644
--- a/lib.c
+++ b/lib.c
@@ -2857,9 +2857,8 @@ val cons(val car, val cdr)
if (recycled_conses) {
obj = recycled_conses;
recycled_conses = recycled_conses->c.cdr;
-#if CONFIG_GEN_GC
- gc_mutated(obj);
-#endif
+ setcheck(obj, car);
+ setcheck(obj, cdr);
} else {
obj = make_obj();
obj->c.type = CONS;
diff --git a/lib.h b/lib.h
index 718e2c86..ff432bea 100644
--- a/lib.h
+++ b/lib.h
@@ -337,6 +337,7 @@ INLINE loc mkloc_fun(val *ptr, val obj)
#define deref(lo) (*(lo).ptr)
#define valptr(lo) ((lo).ptr)
#define set(lo, val) (gc_set(lo, val))
+#define setcheck(tgt, src) (gc_assign_check(tgt, src))
#define mut(obj) (gc_mutated(obj));
#define mpush(val, lo) (gc_push(val, lo))
#else
@@ -348,6 +349,7 @@ typedef val *loc;
#define deref(lo) (*(lo))
#define valptr(lo) (lo)
#define set(lo, val) (*(lo) = (val))
+#define setcheck(tgt, src) ((void) 0)
#define mut(obj) ((void) (obj))
#define mpush(val, lo) (push(val, lo))
#endif
diff --git a/struct.c b/struct.c
index 2acc0b65..94f53b6b 100644
--- a/struct.c
+++ b/struct.c
@@ -697,7 +697,7 @@ val clear_struct(val strct, val value)
for (i = 0; i < st->nslots; i++)
si->slot[i] = clear_val;
- mut(strct);
+ setcheck(strct, clear_val);
return strct;
}
diff --git a/vm.c b/vm.c
index 26d73304..774124a4 100644
--- a/vm.c
+++ b/vm.c
@@ -271,7 +271,7 @@ static val vm_make_closure(struct vm *vm, int frsz)
cdi->mem = heap_vec->v.vec;
memcpy(cdi->mem, mem, size);
memset(mem, 0, size);
- mut(closure);
+ setcheck(closure, heap_vec);
*sdi = *cdi;
break;
}
@@ -357,7 +357,7 @@ INLINE void vm_set(struct vm_env *dspl, unsigned ref, val newval)
env->mem[i] = newval;
if (is_ptr(env->vec))
- mut(env->vec);
+ setcheck(env->vec, newval);
}
INLINE void vm_sm_set(struct vm_env *dspl, unsigned ref, val newval)
@@ -372,7 +372,7 @@ INLINE void vm_sm_set(struct vm_env *dspl, unsigned ref, val newval)
env->mem[i] = newval;
if (is_ptr(env->vec))
- mut(env->vec);
+ setcheck(env->vec, newval);
}
@@ -505,7 +505,7 @@ static loc vm_stab(struct vm *vm, unsigned fun,
eval_error(vd->bytecode,
lit("~a ~s is not defined"), kind_str,
vecref(vd->symvec, num(fun)), nao);
- gc_mutated(vd->self);
+ setcheck(vd->self, fe->bind);
return (fe->bindloc = cdr_l(fe->bind));
}