diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-04-01 19:47:56 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-04-01 19:47:56 -0700 |
commit | 87ed8a692c059f1e81f8deeea3b4f727044a45fa (patch) | |
tree | b8f86e21ef965c2dbb0c3f8e8621760a62cf1943 | |
parent | 34d0567bce45cc89fc6f476353b00b2649bcce4d (diff) | |
download | txr-87ed8a692c059f1e81f8deeea3b4f727044a45fa.tar.gz txr-87ed8a692c059f1e81f8deeea3b4f727044a45fa.tar.bz2 txr-87ed8a692c059f1e81f8deeea3b4f727044a45fa.zip |
Start of ground-work for ephemeral GC. We must add some abstraction
to places where we potentially assign a reference to a younger object
inside a field located in an older object (chronological
backreference) and also where we take the address of an object
field, making it possible that the user of the address will do so.
This patch does not take care of vectors.
No, this is not an April Fool's joke.
* eval.c (env_fbind, env_vbind, env_replace_vbind, lookup_var,
lookup_sym_lisp1): Use set macro instead of assignment.
* hash.c (hash_grow, set_hash_userdata, hash_next):
Use set macro instead of assignment.
* lib.c (rplaca, rplacd, string_extend, length_str, replace_str,
rehome_sym, lazy_stream_func, lazy_str, lazy_str_force,
lazy_str_force_upto, obj_init): Use set macro instead of assignment.
(car_l, cdr_l): Use loc instead of address-of operator.
* lib.h (set, loc): New macros.
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | eval.c | 10 | ||||
-rw-r--r-- | hash.c | 6 | ||||
-rw-r--r-- | lib.c | 44 | ||||
-rw-r--r-- | lib.h | 3 |
5 files changed, 59 insertions, 30 deletions
@@ -1,3 +1,29 @@ +2012-04-01 Kaz Kylheku <kaz@kylheku.com> + + Start of ground-work for ephemeral GC. We must add some abstraction + to places where we potentially assign a reference to a younger object + inside a field located in an older object (chronological + backreference) and also where we take the address of an object + field, making it possible that the user of the address will do so. + + This patch does not take care of vectors. + + No, this is not an April Fool's joke. + + * eval.c (env_fbind, env_vbind, env_replace_vbind, lookup_var, + lookup_sym_lisp1): Use set macro instead of assignment. + + * hash.c (hash_grow, set_hash_userdata, hash_next): + Use set macro instead of assignment. + + * lib.c (rplaca, rplacd, string_extend, length_str, replace_str, + rehome_sym, lazy_stream_func, lazy_str, lazy_str_force, + lazy_str_force_upto, obj_init): Use set macro instead of assignment. + + (car_l, cdr_l): Use loc instead of address-of operator. + + * lib.h (set, loc): New macros. + 2012-03-31 Kaz Kylheku <kaz@kylheku.com> * hash.c (last_equal_key, last_equal_hash): New static variables. @@ -82,21 +82,21 @@ val make_env(val vbindings, val fbindings, val up_env) val env_fbind(val env, val sym, val fun) { type_check(env, ENV); - env->e.fbindings = acons_new(sym, fun, env->e.fbindings); + set(env->e.fbindings, acons_new(sym, fun, env->e.fbindings)); return sym; } val env_vbind(val env, val sym, val obj) { type_check(env, ENV); - env->e.vbindings = acons_new(sym, obj, env->e.vbindings); + set(env->e.vbindings, acons_new(sym, obj, env->e.vbindings)); return sym; } static void env_replace_vbind(val env, val bindings) { type_check(env, ENV); - env->e.vbindings = bindings; + set(env->e.vbindings, bindings); } noreturn static val eval_error(val form, val fmt, ...) @@ -120,7 +120,7 @@ val lookup_var(val env, val sym) val bind = gethash(top_vb, sym); if (cobjp(bind)) { struct c_var *cv = (struct c_var *) cptr_get(bind); - cv->bind->c.cdr = *cv->loc; + set(cv->bind->c.cdr, *cv->loc); return cv->bind; } return bind; @@ -183,7 +183,7 @@ static val lookup_sym_lisp1(val env, val sym) val bind = gethash(top_vb, sym); if (cobjp(bind)) { struct c_var *cv = (struct c_var *) cptr_get(bind); - cv->bind->c.cdr = *cv->loc; + set(cv->bind->c.cdr, *cv->loc); return cv->bind; } return or2(bind, gethash(top_fb, sym)); @@ -346,7 +346,7 @@ static void hash_grow(struct hash *h) } h->modulus = new_modulus; - h->table = new_table; + set(h->table, new_table); } val make_hash(val weak_keys, val weak_vals, val equal_based) @@ -451,7 +451,7 @@ val set_hash_userdata(val hash, val data) { struct hash *h = (struct hash *) cobj_handle(hash, hash_s); val olddata = h->userdata; - h->userdata = data; + set(h->userdata, data); return olddata; } @@ -502,7 +502,7 @@ val hash_next(val *iter) *iter = nil; return nil; } - hi->cons = vecref(h->table, num(hi->chain)); + set(hi->cons, vecref(h->table, num(hi->chain))); } return car(hi->cons); } @@ -224,9 +224,9 @@ val rplaca(val cons, val new_car) { switch (type(cons)) { case CONS: - return cons->c.car = new_car; + return set(cons->c.car, new_car); case LCONS: - return cons->lc.car = new_car; + return set(cons->lc.car, new_car); default: type_mismatch(lit("~s is not a cons"), cons, nao); } @@ -237,9 +237,9 @@ val rplacd(val cons, val new_cdr) { switch (type(cons)) { case CONS: - return cons->c.cdr = new_cdr; + return set(cons->c.cdr, new_cdr); case LCONS: - return cons->lc.cdr = new_cdr; + return set(cons->lc.cdr, new_cdr); default: type_mismatch(lit("~s is not a cons"), cons, nao); } @@ -249,13 +249,13 @@ val *car_l(val cons) { switch (type(cons)) { case CONS: - return &cons->c.car; + return loc(cons->c.car); case LCONS: if (cons->lc.func) { funcall1(cons->lc.func, cons); cons->lc.func = nil; } - return &cons->lc.car; + return loc(cons->lc.car); default: type_mismatch(lit("~s is not a cons"), cons, nao); } @@ -265,13 +265,13 @@ val *cdr_l(val cons) { switch (type(cons)) { case CONS: - return &cons->c.cdr; + return loc(cons->c.cdr); case LCONS: if (cons->lc.func) { funcall1(cons->lc.func, cons); cons->lc.func = nil; } - return &cons->lc.cdr; + return loc(cons->lc.cdr); default: type_mismatch(lit("~s is not a cons"), cons, nao); } @@ -1431,8 +1431,8 @@ val string_extend(val str, val tail) str->st.str = (wchar_t *) chk_realloc((mem_t *) str->st.str, alloc * sizeof *str->st.str); - str->st.alloc = num(alloc); - str->st.len = plus(str->st.len, needed); + set(str->st.alloc, num(alloc)); + set(str->st.len, plus(str->st.len, needed)); if (stringp(tail)) { wmemcpy(str->st.str + len, c_str(tail), c_num(needed) + 1); @@ -1475,8 +1475,8 @@ val length_str(val str) } if (!str->st.len) { - str->st.len = num(wcslen(str->st.str)); - str->st.alloc = plus(str->st.len, one); + set(str->st.len, num(wcslen(str->st.str))); + set(str->st.alloc, plus(str->st.len, one)); } return str->st.len; } @@ -1741,7 +1741,7 @@ val replace_str(val str_in, val items, val from, val to) wmemmove(str_in->st.str + t - c_num(len_diff), str_in->st.str + t, (l - t) + 1); - str_in->st.len = minus(len, len_diff); + set(str_in->st.len, minus(len, len_diff)); to = plus(from, len_it); } else if (lt(len_rep, len_it)) { val len_diff = minus(len_it, len_rep); @@ -2262,7 +2262,7 @@ static val rehome_sym(val sym, val package) if (sym->s.package) remhash(sym->s.package->pk.symhash, symbol_name(sym)); - sym->s.package = package; + set(sym->s.package, package); sethash(package->pk.symhash, symbol_name(sym), sym); return sym; } @@ -3316,8 +3316,8 @@ static val lazy_stream_func(val env, val lcons) val next = cdr(env) ? pop(cdr_l(env)) : get_line(stream); val ahead = get_line(stream); - lcons->lc.car = next; - lcons->lc.cdr = if2(ahead, make_lazy_cons(lcons->lc.func)); + set(lcons->lc.car, next); + set(lcons->lc.cdr, if2(ahead, make_lazy_cons(lcons->lc.func))); lcons->lc.func = nil; if (!next || !ahead) @@ -3357,12 +3357,12 @@ val lazy_str(val lst, val term, val limit) obj->ls.prefix = null_string; obj->ls.list = nil; } else { - obj->ls.prefix = cat_str(list(first(lst), term, nao), nil); - obj->ls.list = rest(lst); + set(obj->ls.prefix, cat_str(list(first(lst), term, nao), nil)); + set(obj->ls.list, rest(lst)); limit = if2(limit, minus(limit, one)); } - obj->ls.opts = cons(term, limit); + set(obj->ls.opts, cons(term, limit)); return obj; } @@ -3376,7 +3376,7 @@ val lazy_str_force(val lstr) while ((!lim || gt(lim, zero)) && lstr->ls.list) { val next = pop(&lstr->ls.list); val term = car(lstr->ls.opts); - lstr->ls.prefix = cat_str(list(lstr->ls.prefix, next, term, nao), nil); + set(lstr->ls.prefix, cat_str(list(lstr->ls.prefix, next, term, nao), nil)); if (lim) lim = minus(lim, one); } @@ -3399,7 +3399,7 @@ val lazy_str_force_upto(val lstr, val index) { val next = pop(&lstr->ls.list); val term = car(lstr->ls.opts); - lstr->ls.prefix = cat_str(list(lstr->ls.prefix, next, term, nao), nil); + set(lstr->ls.prefix, cat_str(list(lstr->ls.prefix, next, term, nao), nil)); if (lim) lim = minus(lim, one); } @@ -4048,7 +4048,7 @@ static void obj_init(void) /* t can't be interned, because gethash_l needs t in order to do its job. */ t = *gethash_l(user_package->pk.symhash, lit("t"), 0) = make_sym(lit("t")); - t->s.package = user_package; + set(t->s.package, user_package); null = intern(lit("null"), user_package); cons_s = intern(lit("cons"), user_package); @@ -217,6 +217,9 @@ union obj { struct flonum fl; }; +#define set(place, val) ((place) = (val)) +#define loc(place) (&(place)) + INLINE cnum tag(val obj) { return ((cnum) obj) & TAG_MASK; } INLINE int is_ptr(val obj) { return obj && tag(obj) == TAG_PTR; } INLINE int is_num(val obj) { return tag(obj) == TAG_NUM; } |