mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-06 04:00:26 +02:00
Update for Whippet changes, VM stacks scanned partly-conservatively
* libguile/trace.h (scm_from_ref, scm_to_ref): Helpers moved here; update all callers. * libguile/loader.c (scm_trace_loader_roots): * libguile/threads.c (scm_trace_thread_roots): * libguile/vm.c (scm_trace_vm_roots): Update for new pinned-roots prototype. * libguile/whippet-embedder.h (gc_extern_space_visit): Update for Whippet API changes.
This commit is contained in:
parent
fb5a99c752
commit
7b4f4427f8
8 changed files with 143 additions and 131 deletions
|
@ -38,6 +38,7 @@
|
||||||
#include "numbers.h"
|
#include "numbers.h"
|
||||||
#include "ports.h"
|
#include "ports.h"
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
#include "trace.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include <gc-ephemeron.h>
|
#include <gc-ephemeron.h>
|
||||||
|
@ -45,17 +46,6 @@
|
||||||
#include "ephemerons.h"
|
#include "ephemerons.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline SCM ref_to_scm (struct gc_ref ref)
|
|
||||||
{
|
|
||||||
return SCM_PACK (gc_ref_value (ref));
|
|
||||||
}
|
|
||||||
static inline struct gc_ref scm_to_ref (SCM scm)
|
|
||||||
{
|
|
||||||
return gc_ref (SCM_UNPACK (scm));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SCM_EPHEMERON_P(X) (SCM_HAS_TYP7 (X, scm_tc7_ephemeron))
|
#define SCM_EPHEMERON_P(X) (SCM_HAS_TYP7 (X, scm_tc7_ephemeron))
|
||||||
|
@ -95,14 +85,14 @@ SCM
|
||||||
scm_c_ephemeron_key (struct gc_ephemeron *e)
|
scm_c_ephemeron_key (struct gc_ephemeron *e)
|
||||||
{
|
{
|
||||||
struct gc_ref ret = gc_ephemeron_key (e);
|
struct gc_ref ret = gc_ephemeron_key (e);
|
||||||
return gc_ref_is_null (ret) ? SCM_BOOL_F : ref_to_scm (ret);
|
return gc_ref_is_null (ret) ? SCM_BOOL_F : scm_from_ref (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
scm_c_ephemeron_value (struct gc_ephemeron *e)
|
scm_c_ephemeron_value (struct gc_ephemeron *e)
|
||||||
{
|
{
|
||||||
struct gc_ref ret = gc_ephemeron_value (e);
|
struct gc_ref ret = gc_ephemeron_value (e);
|
||||||
return gc_ref_is_null (ret) ? SCM_BOOL_F : ref_to_scm (ret);
|
return gc_ref_is_null (ret) ? SCM_BOOL_F : scm_from_ref (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -117,7 +107,7 @@ scm_c_ephemeron_swap_x (struct gc_ephemeron *e, SCM new_val)
|
||||||
struct gc_ref ret =
|
struct gc_ref ret =
|
||||||
gc_ephemeron_swap_value (SCM_I_CURRENT_THREAD->mutator, e,
|
gc_ephemeron_swap_value (SCM_I_CURRENT_THREAD->mutator, e,
|
||||||
scm_to_ref (new_val));
|
scm_to_ref (new_val));
|
||||||
return gc_ref_is_null (ret) ? SCM_BOOL_F : ref_to_scm (ret);
|
return gc_ref_is_null (ret) ? SCM_BOOL_F : scm_from_ref (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gc_ephemeron*
|
struct gc_ephemeron*
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "smob.h"
|
#include "smob.h"
|
||||||
#include "struct.h"
|
#include "struct.h"
|
||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
|
#include "trace.h"
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
@ -77,15 +78,6 @@ enum builtin_finalizer_kind
|
||||||
FINALIZE_KIND_PORT,
|
FINALIZE_KIND_PORT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline SCM ref_to_scm (struct gc_ref ref)
|
|
||||||
{
|
|
||||||
return SCM_PACK (gc_ref_value (ref));
|
|
||||||
}
|
|
||||||
static inline struct gc_ref scm_to_ref (SCM scm)
|
|
||||||
{
|
|
||||||
return gc_ref (SCM_UNPACK (scm));
|
|
||||||
}
|
|
||||||
|
|
||||||
static SCM
|
static SCM
|
||||||
add_finalizer (struct scm_thread *thread, SCM obj, SCM closure,
|
add_finalizer (struct scm_thread *thread, SCM obj, SCM closure,
|
||||||
enum finalizer_priority priority)
|
enum finalizer_priority priority)
|
||||||
|
@ -213,8 +205,8 @@ run_finalizers (void *raw_data)
|
||||||
finalizer;
|
finalizer;
|
||||||
finalizer = gc_pop_finalizable (mut), data->count++)
|
finalizer = gc_pop_finalizable (mut), data->count++)
|
||||||
run_finalizer (thread,
|
run_finalizer (thread,
|
||||||
ref_to_scm (gc_finalizer_object (finalizer)),
|
scm_from_ref (gc_finalizer_object (finalizer)),
|
||||||
ref_to_scm (gc_finalizer_closure (finalizer)));
|
scm_from_ref (gc_finalizer_closure (finalizer)));
|
||||||
data->success = 1;
|
data->success = 1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,16 +119,16 @@ add_roots(char *lo, char *hi)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_trace_loader_conservative_roots (void (*trace_range)(uintptr_t lo,
|
scm_trace_loader_roots (void (*trace_ambiguous)(uintptr_t lo,
|
||||||
uintptr_t hi,
|
uintptr_t hi,
|
||||||
int possibly_interior,
|
int possibly_interior,
|
||||||
struct gc_heap *heap,
|
struct gc_heap *heap,
|
||||||
void *trace_data),
|
void *trace_data),
|
||||||
struct gc_heap *heap,
|
struct gc_heap *heap,
|
||||||
void *trace_data)
|
void *trace_data)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < roots_count; i++)
|
for (size_t i = 0; i < roots_count; i++)
|
||||||
trace_range(roots[i].lo, roots[i].hi, 0, heap, trace_data);
|
trace_ambiguous(roots[i].lo, roots[i].hi, 0, heap, trace_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The page size. */
|
/* The page size. */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "boolean.h"
|
#include "boolean.h"
|
||||||
#include "gc-internal.h"
|
#include "gc-internal.h"
|
||||||
|
#include "trace.h"
|
||||||
#include "gsubr.h"
|
#include "gsubr.h"
|
||||||
|
|
||||||
#include "pairs.h"
|
#include "pairs.h"
|
||||||
|
@ -75,11 +76,6 @@ scm_cons2 (SCM w, SCM x, SCM y)
|
||||||
return scm_cons (w, scm_cons (x, y));
|
return scm_cons (w, scm_cons (x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct gc_ref scm_to_ref (SCM scm)
|
|
||||||
{
|
|
||||||
return gc_ref (SCM_UNPACK (scm));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
scm_is_mutable_pair (SCM x)
|
scm_is_mutable_pair (SCM x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* 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
|
static void
|
||||||
scm_trace_dynstack (scm_t_dynstack *dynstack,
|
scm_trace_dynstack (scm_t_dynstack *dynstack,
|
||||||
void (*trace_edge) (struct gc_edge edge,
|
void (*trace_edge) (struct gc_edge edge,
|
||||||
|
@ -110,6 +114,7 @@ scm_trace_thread (struct scm_thread *thread,
|
||||||
trace_edge (gc_edge (&thread->join_lock), heap, trace_data);
|
trace_edge (gc_edge (&thread->join_lock), heap, trace_data);
|
||||||
trace_edge (gc_edge (&thread->join_results), heap, trace_data);
|
trace_edge (gc_edge (&thread->join_results), heap, trace_data);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Guile-level thread objects are themselves GC-allocated. A thread
|
/* Guile-level thread objects are themselves GC-allocated. A thread
|
||||||
object has two states: active and finished. A thread is active if it
|
object has two states: active and finished. A thread is active if it
|
||||||
|
@ -125,16 +130,20 @@ scm_trace_thread (struct scm_thread *thread,
|
||||||
precise, threads need to be traced during root identification.
|
precise, threads need to be traced during root identification.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
scm_trace_thread_mutator_roots (struct scm_thread *thread,
|
scm_trace_thread_roots (struct scm_thread *thread,
|
||||||
void (*trace_edge) (struct gc_edge edge,
|
void (*trace_pinned) (struct gc_ref ref,
|
||||||
struct gc_heap *heap,
|
struct gc_heap *heap,
|
||||||
void *trace_data),
|
void *trace_data),
|
||||||
struct gc_heap *heap, void *trace_data)
|
void (*trace_ambiguous) (uintptr_t lo,
|
||||||
|
uintptr_t hi,
|
||||||
|
int possibly_interior,
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data),
|
||||||
|
struct gc_heap *heap, void *trace_data)
|
||||||
{
|
{
|
||||||
scm_trace_vm (&thread->vm, trace_edge, heap, trace_data);
|
trace_pinned (gc_ref_from_heap_object (thread), heap, trace_data);
|
||||||
|
scm_trace_vm_roots (&thread->vm, trace_pinned, trace_ambiguous, heap,
|
||||||
/* FIXME: Call instead via gc_trace_object. */
|
trace_data);
|
||||||
scm_trace_thread (thread, trace_edge, heap, trace_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "libguile/scm.h"
|
#include "libguile/scm.h"
|
||||||
#include "gc-edge.h"
|
#include "gc-ref.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,36 +31,52 @@ struct scm_vm;
|
||||||
struct gc_heap;
|
struct gc_heap;
|
||||||
struct gc_heap_roots { int unused; };
|
struct gc_heap_roots { int unused; };
|
||||||
|
|
||||||
SCM_INTERNAL void
|
static inline SCM
|
||||||
scm_trace_thread_mutator_roots (struct scm_thread *thread,
|
scm_from_ref (struct gc_ref ref)
|
||||||
void (*trace_edge)(struct gc_edge edge,
|
{
|
||||||
struct gc_heap *heap,
|
return SCM_PACK (gc_ref_value (ref));
|
||||||
void *trace_data),
|
}
|
||||||
struct gc_heap *heap,
|
|
||||||
void *trace_data);
|
|
||||||
|
|
||||||
SCM_INTERNAL void scm_trace_thread (struct scm_thread *thread,
|
static inline struct gc_ref
|
||||||
void (*trace_edge)(struct gc_edge edge,
|
scm_to_ref (SCM scm)
|
||||||
struct gc_heap *heap,
|
{
|
||||||
void *trace_data),
|
return gc_ref (SCM_UNPACK (scm));
|
||||||
struct gc_heap *heap,
|
}
|
||||||
void *trace_data);
|
|
||||||
|
|
||||||
SCM_INTERNAL void scm_trace_vm (struct scm_vm *vp,
|
|
||||||
void (*trace_edge)(struct gc_edge edge,
|
|
||||||
struct gc_heap *heap,
|
|
||||||
void *trace_data),
|
|
||||||
struct gc_heap *heap,
|
|
||||||
void *trace_data);
|
|
||||||
|
|
||||||
SCM_INTERNAL void
|
SCM_INTERNAL void
|
||||||
scm_trace_loader_conservative_roots (void (*trace_range)(uintptr_t lo,
|
scm_trace_thread_roots (struct scm_thread *thread,
|
||||||
uintptr_t hi,
|
void (*trace_pinned) (struct gc_ref ref,
|
||||||
int possibly_interior,
|
struct gc_heap *heap,
|
||||||
struct gc_heap *heap,
|
void *trace_data),
|
||||||
void *trace_data),
|
void (*trace_ambiguous) (uintptr_t lo,
|
||||||
struct gc_heap *heap,
|
uintptr_t hi,
|
||||||
void *trace_data);
|
int possibly_interior,
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data);
|
||||||
|
|
||||||
|
SCM_INTERNAL void
|
||||||
|
scm_trace_vm_roots (struct scm_vm *vp,
|
||||||
|
void (*trace_pinned) (struct gc_ref ref,
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data),
|
||||||
|
void (*trace_ambiguous) (uintptr_t lo,
|
||||||
|
uintptr_t hi,
|
||||||
|
int possibly_interior,
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data);
|
||||||
|
|
||||||
|
SCM_INTERNAL void
|
||||||
|
scm_trace_loader_roots (void (*trace_ambiguous) (uintptr_t lo,
|
||||||
|
uintptr_t hi,
|
||||||
|
int possibly_interior,
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data),
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data);
|
||||||
|
|
||||||
|
|
||||||
#endif /* SCM_THREADS_INTERNAL_H */
|
#endif /* SCM_THREADS_INTERNAL_H */
|
||||||
|
|
|
@ -707,11 +707,15 @@ enum slot_desc
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_trace_vm (struct scm_vm *vp,
|
scm_trace_vm_roots (struct scm_vm *vp,
|
||||||
void (*trace_edge) (struct gc_edge edge,
|
void (*trace_pinned) (struct gc_ref ref,
|
||||||
struct gc_heap *heap,
|
struct gc_heap *heap,
|
||||||
void *trace_data),
|
void *trace_data),
|
||||||
struct gc_heap *heap, void *trace_data)
|
void (*trace_ambiguous) (uintptr_t lo, uintptr_t hi,
|
||||||
|
int possibly_interior,
|
||||||
|
struct gc_heap *heap,
|
||||||
|
void *trace_data),
|
||||||
|
struct gc_heap *heap, void *trace_data)
|
||||||
{
|
{
|
||||||
union scm_vm_stack_element *sp, *fp;
|
union scm_vm_stack_element *sp, *fp;
|
||||||
/* The first frame will be marked conservatively (without a slot map).
|
/* The first frame will be marked conservatively (without a slot map).
|
||||||
|
@ -730,29 +734,31 @@ scm_trace_vm (struct scm_vm *vp,
|
||||||
{
|
{
|
||||||
ptrdiff_t nlocals = SCM_FRAME_NUM_LOCALS (fp, sp);
|
ptrdiff_t nlocals = SCM_FRAME_NUM_LOCALS (fp, sp);
|
||||||
size_t slot = nlocals - 1;
|
size_t slot = nlocals - 1;
|
||||||
for (slot = nlocals - 1; sp < fp; sp++, slot--)
|
if (slot_map)
|
||||||
{
|
for (slot = nlocals - 1; sp < fp; sp++, slot--)
|
||||||
enum slot_desc desc = SLOT_DESC_LIVE_GC;
|
{
|
||||||
|
enum slot_desc desc =
|
||||||
|
(slot_map[slot / 4U] >> ((slot % 4U) * 2)) & 3U;
|
||||||
|
|
||||||
if (slot_map)
|
switch (desc)
|
||||||
desc = (slot_map[slot / 4U] >> ((slot % 4U) * 2)) & 3U;
|
{
|
||||||
|
case SLOT_DESC_LIVE_RAW:
|
||||||
|
case SLOT_DESC_UNUSED:
|
||||||
|
break;
|
||||||
|
case SLOT_DESC_LIVE_GC:
|
||||||
|
trace_pinned (scm_to_ref (sp->as_scm), heap, trace_data);
|
||||||
|
break;
|
||||||
|
case SLOT_DESC_DEAD:
|
||||||
|
/* This value may become dead as a result of GC,
|
||||||
|
so we can't just leave it on the stack. */
|
||||||
|
sp->as_scm = SCM_UNSPECIFIED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
trace_ambiguous ((uintptr_t) sp, (uintptr_t) (sp + nlocals), 0,
|
||||||
|
heap, trace_data);
|
||||||
|
|
||||||
switch (desc)
|
|
||||||
{
|
|
||||||
case SLOT_DESC_LIVE_RAW:
|
|
||||||
break;
|
|
||||||
case SLOT_DESC_UNUSED:
|
|
||||||
case SLOT_DESC_LIVE_GC:
|
|
||||||
if (SCM_NIMP (sp->as_scm))
|
|
||||||
trace_edge (gc_edge (sp), heap, trace_data);
|
|
||||||
break;
|
|
||||||
case SLOT_DESC_DEAD:
|
|
||||||
/* This value may become dead as a result of GC,
|
|
||||||
so we can't just leave it on the stack. */
|
|
||||||
sp->as_scm = SCM_UNSPECIFIED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sp = SCM_FRAME_PREVIOUS_SP (fp);
|
sp = SCM_FRAME_PREVIOUS_SP (fp);
|
||||||
/* Inner frames may have a dead slots map for precise marking.
|
/* Inner frames may have a dead slots map for precise marking.
|
||||||
Note that there may be other reasons to not have a dead slots
|
Note that there may be other reasons to not have a dead slots
|
||||||
|
|
|
@ -63,7 +63,6 @@ gc_is_valid_conservative_ref_displacement (uintptr_t displacement) {
|
||||||
// FIXME: Here add tracing for SCM literals in .go files or .data
|
// FIXME: Here add tracing for SCM literals in .go files or .data
|
||||||
// sections, perhaps. For now while we are using BDW-GC we can punt.
|
// sections, perhaps. For now while we are using BDW-GC we can punt.
|
||||||
static inline int gc_extern_space_visit (struct gc_extern_space *space,
|
static inline int gc_extern_space_visit (struct gc_extern_space *space,
|
||||||
struct gc_edge edge,
|
|
||||||
struct gc_ref ref) {
|
struct gc_ref ref) {
|
||||||
#if GC_CONSERVATIVE_TRACE
|
#if GC_CONSERVATIVE_TRACE
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -78,6 +77,14 @@ static inline void gc_extern_space_finish_gc (struct gc_extern_space *space,
|
||||||
int is_minor_gc) {
|
int is_minor_gc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline SCM scm_from_gc_ref (struct gc_ref ref) {
|
||||||
|
return SCM_PACK (gc_ref_value (ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct gc_ref scm_to_gc_ref (SCM scm) {
|
||||||
|
return gc_ref (SCM_UNPACK (scm));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void gc_trace_object (struct gc_ref ref,
|
static inline void gc_trace_object (struct gc_ref ref,
|
||||||
void (*trace_edge) (struct gc_edge edge,
|
void (*trace_edge) (struct gc_edge edge,
|
||||||
struct gc_heap *heap,
|
struct gc_heap *heap,
|
||||||
|
@ -101,8 +108,6 @@ static inline void gc_trace_mutator_roots (struct gc_mutator_roots *roots,
|
||||||
void *trace_data),
|
void *trace_data),
|
||||||
struct gc_heap *heap,
|
struct gc_heap *heap,
|
||||||
void *trace_data) {
|
void *trace_data) {
|
||||||
trace_edge (gc_edge (&roots->thread), heap, trace_data);
|
|
||||||
scm_trace_thread_mutator_roots (roots->thread, trace_edge, heap, trace_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gc_trace_heap_roots (struct gc_heap_roots *roots,
|
static inline void gc_trace_heap_roots (struct gc_heap_roots *roots,
|
||||||
|
@ -114,36 +119,34 @@ static inline void gc_trace_heap_roots (struct gc_heap_roots *roots,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gc_trace_mutator_conservative_roots (struct gc_mutator_roots *roots,
|
gc_trace_mutator_pinned_roots (struct gc_mutator_roots *roots,
|
||||||
void (*trace_range) (uintptr_t lo,
|
void (*trace_pinned) (struct gc_ref ref,
|
||||||
uintptr_t hi,
|
struct gc_heap *heap,
|
||||||
int possibly_interior,
|
void *trace_data),
|
||||||
struct gc_heap *heap,
|
void (*trace_ambiguous) (uintptr_t lo,
|
||||||
void *trace_data),
|
uintptr_t hi,
|
||||||
struct gc_heap *heap,
|
int possibly_interior,
|
||||||
void *trace_data) {
|
struct gc_heap *heap,
|
||||||
/* FIXME: thread stack? Currently traced via the precise
|
void *trace_data),
|
||||||
gc_trace_mutator_roots. */
|
struct gc_heap *heap,
|
||||||
|
void *trace_data) {
|
||||||
|
scm_trace_thread_roots (roots->thread, trace_pinned, trace_ambiguous,
|
||||||
|
heap, trace_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
gc_trace_heap_conservative_roots (struct gc_heap_roots *roots,
|
gc_trace_heap_pinned_roots (struct gc_heap_roots *roots,
|
||||||
void (*trace_range) (uintptr_t lo,
|
void (*trace_pinned) (struct gc_ref ref,
|
||||||
uintptr_t hi,
|
struct gc_heap *heap,
|
||||||
int possibly_interior,
|
void *trace_data),
|
||||||
struct gc_heap *heap,
|
void (*trace_ambiguous) (uintptr_t lo,
|
||||||
void *trace_data),
|
uintptr_t hi,
|
||||||
struct gc_heap *heap,
|
int possibly_interior,
|
||||||
void *trace_data) {
|
struct gc_heap *heap,
|
||||||
scm_trace_loader_conservative_roots(trace_range, heap, trace_data);
|
void *trace_data),
|
||||||
}
|
struct gc_heap *heap,
|
||||||
|
void *trace_data) {
|
||||||
static inline SCM scm_from_gc_ref (struct gc_ref ref) {
|
scm_trace_loader_roots (trace_ambiguous, heap, trace_data);
|
||||||
return SCM_PACK (gc_ref_value (ref));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct gc_ref scm_to_gc_ref (SCM scm) {
|
|
||||||
return gc_ref (SCM_UNPACK (scm));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline scm_t_bits* scm_cell_type_loc (SCM scm) {
|
static inline scm_t_bits* scm_cell_type_loc (SCM scm) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue