I'm running into situations where a function implemented in C needs to
allocate objects in the scheme heap. I'm concerned about GC. Consider
the following:
scheme_cons(scheme_mk_vector(...), scheme_mk_vector(...))
it seems to me that the following sequence might occur
vector_alloc in scheme heap (saved to sc.value)
vector_alloc in scheme heap (saved to sc.value)
--- gc allocating cons cell ---
cons_alloc in scheme heap (saved to sc.value)
my concern is that at the time of the GC the first vector is not
referenced (therefore not markable) from the scheme heap, and will be
GC'd. Note that this pattern exists in any external call to
scheme_define as well, because scheme_define allocates a symbol
internally.
I could export reserve_cells, but this won't really help. Some of the
algorithms I want to build are building complex structures involving
allocation patterns similar to the one above, and it's not always easy
to know how many cells to reserve. I could *probably* export mark() and
do the preservation by hand, but this seems error prone. Given where
sc.value is updated, I could do some incredible hack with cons cells to
ensure reachability, but that doesn't seem likely to lead to readable C
code. :-)
Because of these issues, I am considering altering the foreign function
call mechanism to proceed as follows:
- Store the stack pointer before calling C. Zero it on return.
- in GC, if the C-stack observer pointer is set, GC the C stack
**conservatively**
Note that this can actually be done portably!
I also considered generalizing this to region tracking, so that it would
support multiple calls back and forth between Scheme and C, but my
expectation is that C only calls scheme to allocate objects, so in the
absence of threading a single C region is conservative, but sufficient.
I would greatly appreciate your reaction to this, in three regards:
1. Does this problem really exist? Is there something I have
missed that prevents it?
2. Is there a cleaner solution?
3. If not, is this a reasonable way to solve it?
4. Do you think that tracking the nesting of C regions on
the stack is worthwhile? It's not that hard to do.
Thank you