1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-02 15:40:38 +02:00

Allow precise tracing of dynstacks

Gosh this was a slog

* libguile/dynstack.c (dynstack_ensure_space): Use malloc and free.
Threads have off-heap dynstacks, with manual marking.
(scm_trace_dynstack): Implement tracing.
(trace_pinned_trampoline, scm_trace_dynstack_roots): Implement tracing
for active threads.
(scm_dynstack_capture): Tag dynstacks.
* libguile/dynstack.h (scm_t_dynstack): Add a tag.
(scm_t_dynstack_winder_flags): Add SCM_F_DYNSTACK_WINDER_MANAGED.
* libguile/dynwind.h (scm_t_wind_flags): Add SCM_F_WIND_MANAGED.
* libguile/dynwind.c (scm_dynwind_unwind_handler_with_scm)
(scm_dynwind_rewind_handler_with_scm): These values need to be traced by
GC.
* libguile/scm.h (scm_tc16_dynstack_slice): New typecode.  No need for
equality etc because it shouldn't escape to Scheme (currently).
* libguile/trace.h: Add trace decls.
* libguile/threads.c (scm_trace_thread_roots): Trace dynstacks
explicitly here, as they are off-heap.
This commit is contained in:
Andy Wingo 2025-06-19 16:32:56 +02:00
parent 923bfdc7ed
commit 278ba99027
7 changed files with 155 additions and 43 deletions

View file

@ -87,18 +87,6 @@
/* FIXME: For the moment, the bodies of thread objects are traced
conservatively; only bdw, heap-conservative-mmc, and
heap-conservative-parallel-mmc are supported. */
static void
scm_trace_dynstack (scm_t_dynstack *dynstack,
void (*trace_edge) (struct gc_edge edge,
struct gc_heap *heap,
void *trace_data),
struct gc_heap *heap, void *trace_data)
{
/* FIXME: Untagged array. Perhaps this should be off-heap... or
interleaved on the main stack. */
trace_edge (gc_edge (&dynstack->base), heap, trace_data);
}
void
scm_trace_thread (struct scm_thread *thread,
void (*trace_edge) (struct gc_edge edge,
@ -151,6 +139,10 @@ scm_trace_thread_roots (struct scm_thread *thread,
struct gc_heap *heap, void *trace_data)
{
trace_pinned (gc_ref_from_heap_object (thread), heap, trace_data);
#if GC_CONSERVATIVE_TRACE
scm_trace_dynstack_roots (&thread->dynstack, trace_pinned, heap, trace_data);
#endif
/* FIXME: Trace is not a tagged allocation. */
scm_trace_vm_roots (&thread->vm, trace_pinned, trace_ambiguous, heap,
trace_data);
}
@ -480,9 +472,7 @@ guilify_self_2 (SCM dynamic_state)
t->dynamic_state->thread_local_values = scm_c_make_hash_table (0);
scm_set_current_dynamic_state (dynamic_state);
t->dynstack.base = scm_gc_malloc (16 * sizeof (scm_t_bits), "dynstack");
t->dynstack.limit = t->dynstack.base + 16;
t->dynstack.top = t->dynstack.base + SCM_DYNSTACK_HEADER_LEN;
scm_dynstack_init_for_thread (&t->dynstack);
t->block_asyncs = 0;
}