diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-01-06 23:58:14 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-01-06 23:58:14 -0800 |
commit | 1d427b61be3f8f42a6e740b3080102f54f4d806b (patch) | |
tree | bd58be9dc17baf2f5143db3b146ba0357ae0ec4e | |
parent | 5464e5ab1ae7d1eeba1dfbea36bc5e81714d1694 (diff) | |
download | txr-1d427b61be3f8f42a6e740b3080102f54f4d806b.tar.gz txr-1d427b61be3f8f42a6e740b3080102f54f4d806b.tar.bz2 txr-1d427b61be3f8f42a6e740b3080102f54f4d806b.zip |
lib: review cobj calls for gc incorrectness and fix.
I looked at all cobj calls to see if there is a potential
problem, looking for situations whereby the cobj call could
trigger a gc that would destroy Lisp objects that the
new object either stores, or that its continued initialization
depends on.
* stream.c (make_strlist_input_stream): call cobj earlier,
then fill in the structure. Use chk_calloc to allocate
the structure so any Lisp objects in it look like nil
until it is initialized.
* struct.c (make_struct_impl, make_lazy_struct):
Use gc_hint on the type argument, to pin down the
st structure that we use in initializations after
the cobj call. If the type object were to disappear,
the st structure would become invalid.
* tree.c (copy_search_tree, make_similar_tree):
Use gc_hint on the tree argument to pin down the otr
structure that we reference in initializations
(copy_tree_iter): Use gc_hint on iter, for similar
reasons.
* vm.c (vm_copy_closure): Use gc_hint on oclosure,
to pin down the environment we are copying from it.
-rw-r--r-- | stream.c | 5 | ||||
-rw-r--r-- | struct.c | 4 | ||||
-rw-r--r-- | tree.c | 4 | ||||
-rw-r--r-- | vm.c | 2 |
4 files changed, 13 insertions, 2 deletions
@@ -2243,12 +2243,13 @@ static struct strm_ops strlist_in_ops = val make_strlist_input_stream(val list) { - struct strlist_in *s = coerce(struct strlist_in *, chk_malloc(sizeof *s)); + struct strlist_in *s = coerce(struct strlist_in *, chk_calloc(sizeof *s, 1)); + val stream = cobj(coerce(mem_t *, s), stream_cls, &strlist_in_ops.cobj_ops); strm_base_init(&s->a); s->string = car(list); s->pos = zero; s->list = cdr(list); - return cobj(coerce(mem_t *, s), stream_cls, &strlist_in_ops.cobj_ops); + return stream; } struct string_out { @@ -856,6 +856,8 @@ static val make_struct_impl(val self, val type, uw_catch_end; + gc_hint(type); + return sinst; } @@ -947,6 +949,8 @@ val make_lazy_struct(val type, val argfun) bug_unless (type == st->self); + gc_hint(type); + si->slot[0] = argfun; return sinst; @@ -921,6 +921,7 @@ val copy_search_tree(val tree) val ntree = cobj(coerce(mem_t *, ntr), tree_cls, &tree_ops); *ntr = *otr; ntr->root = nroot; + gc_hint(tree); return ntree; } @@ -933,6 +934,7 @@ val make_similar_tree(val tree) *ntr = *otr; ntr->root = nil; ntr->size = ntr->max_size = 0; + gc_hint(tree); return ntree; } @@ -1014,6 +1016,8 @@ val copy_tree_iter(val iter) memcpy(tdid->ti.path, tdis->ti.path, sizeof tdid->ti.path[0] * depth); + gc_hint(iter); + return iter_copy; } @@ -317,6 +317,8 @@ val vm_copy_closure(val oclosure) } } + gc_hint(oclosure); + return nclosure; } |