diff --git a/gc.c b/gc.c index 54643207..17a8126f 100644 --- a/gc.c +++ b/gc.c @@ -105,8 +105,15 @@ void sexp_conservative_mark (sexp ctx) { p = (sexp) (((char*)p) + r->size); continue; } - if (! sexp_gc_mark(p) && stack_references_pointer_p(ctx, p)) + if (! sexp_gc_mark(p) && stack_references_pointer_p(ctx, p)) { +#if SEXP_USE_DEBUG_GC > 1 + if (p && sexp_pointerp(p)) { + fprintf(stderr, "GC MISS: %p: %s\n", p, sexp_pointer_source(p)); + fflush(stderr); + } +#endif sexp_mark(ctx, p); + } p = (sexp) (((char*)p)+sexp_heap_align(sexp_allocated_bytes(ctx, p))); } } @@ -235,6 +242,9 @@ sexp sexp_gc (sexp ctx, size_t *sum_freed) { sexp_mark(ctx, ctx); sexp_conservative_mark(ctx); #if SEXP_USE_DEBUG_GC + fprintf(stderr, "******************** GC ********************\n"); +#endif +#if SEXP_USE_DEBUG_GC > 2 sexp_sweep_stats(ctx, 2, NULL, "* \x1B[31mFREE:\x1B[0m "); #endif #if SEXP_USE_WEAK_REFERENCES diff --git a/include/chibi/features.h b/include/chibi/features.h index a1c6d1cb..02e42ddf 100644 --- a/include/chibi/features.h +++ b/include/chibi/features.h @@ -77,6 +77,9 @@ /* uncomment this to add additional native checks to only mark objects in the heap */ /* #define SEXP_USE_SAFE_GC_MARK 1 */ +/* uncomment this to track what C source line each object is allocated from */ +/* #define SEXP_USE_TRACK_ALLOC_SOURCE 1 */ + /* uncomment this to add additional native gc checks to verify a magic header */ /* #define SEXP_USE_HEADER_MAGIC 1 */ @@ -91,7 +94,7 @@ /* uncomment this to make type definitions common to all contexts */ /* By default types are only global if you don't allow user type */ /* definitions, so new types will be local to a given set of */ -/* contexts sharing thei heap. */ +/* contexts sharing their heap. */ /* #define SEXP_USE_GLOBAL_TYPES 1 */ /* uncomment this to make the symbol table common to all contexts */ @@ -303,7 +306,11 @@ #endif #ifndef SEXP_USE_CONSERVATIVE_GC -#define SEXP_USE_CONSERVATIVE_GC 0 +#define SEXP_USE_CONSERVATIVE_GC SEXP_USE_DEBUG_GC > 1 +#endif + +#ifndef SEXP_USE_TRACK_ALLOC_SOURCE +#define SEXP_USE_TRACK_ALLOC_SOURCE SEXP_USE_DEBUG_GC > 1 #endif #ifndef SEXP_USE_HEADER_MAGIC diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 3a2c75cb..16a23a4e 100644 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -232,6 +232,9 @@ struct sexp_struct { unsigned int freep:1; unsigned int brokenp:1; unsigned int syntacticp:1; +#if SEXP_USE_TRACK_ALLOC_SOURCE + const char* source; +#endif #if SEXP_USE_HEADER_MAGIC unsigned int magic; #endif @@ -444,13 +447,19 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size); #define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \ + sizeof(((sexp)0)->value.x)) - #define sexp_offsetof(type, f) (offsetof(struct sexp_struct, value.type.f)) - #define sexp_offsetof_slot0 (offsetof(struct sexp_struct, value)) - #define sexp_sizeof_header (sexp_sizeof(flonum) - sizeof(double)) +#if SEXP_USE_TRACK_ALLOC_SOURCE +#define sexp_with_current_source0(file, line) file ": " #line +#define sexp_with_current_source(file, line) , sexp_with_current_source0(file, line) +#else +#define sexp_with_current_source(file, line) +#endif + +#define sexp_alloc_tagged(ctx, type, tag) sexp_alloc_tagged_aux(ctx, type, tag sexp_with_current_source(__FILE__, __LINE__)) + #define sexp_alloc_type(ctx, type, tag) sexp_alloc_tagged(ctx, sexp_sizeof(type), tag) #define sexp_alloc_bytecode(ctx, i) sexp_alloc_tagged(ctx, sexp_sizeof(bytecode) + i, SEXP_BYTECODE) @@ -478,6 +487,12 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size); #define sexp_brokenp(x) ((x)->brokenp) #define sexp_pointer_magic(x) ((x)->magic) +#if SEXP_USE_TRACK_ALLOC_SOURCE +#define sexp_pointer_source(x) ((x)->source) +#else +#define sexp_pointer_source(x) "" +#endif + #define sexp_check_tag(x,t) (sexp_pointerp(x) && (sexp_pointer_tag(x) == (t))) #define sexp_slot_ref(x,i) (((sexp*)&((x)->value))[i]) @@ -990,8 +1005,14 @@ SEXP_API sexp sexp_buffered_flush (sexp ctx, sexp p); #define sexp_at_eofp(p) (feof(sexp_port_stream(p))) #define sexp_port_fileno(p) (fileno(sexp_port_stream(p))) +#if SEXP_USE_TRACK_ALLOC_SOURCE +#define sexp_current_source_param , const char* source +#else +#define sexp_current_source_param +#endif + +SEXP_API sexp sexp_alloc_tagged_aux(sexp ctx, size_t size, sexp_uint_t tag sexp_current_source_param); SEXP_API sexp sexp_make_context(sexp ctx, size_t size); -SEXP_API sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag); SEXP_API sexp sexp_cons_op(sexp ctx sexp_api_params(self, n), sexp head, sexp tail); SEXP_API sexp sexp_list2(sexp ctx, sexp a, sexp b); SEXP_API sexp sexp_equalp_op (sexp ctx sexp_api_params(self, n), sexp a, sexp b); diff --git a/sexp.c b/sexp.c index db994d69..58700e80 100644 --- a/sexp.c +++ b/sexp.c @@ -47,10 +47,13 @@ static int is_separator(int c) { sexp sexp_symbol_table[SEXP_SYMBOL_TABLE_SIZE]; #endif -sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag) { +sexp sexp_alloc_tagged_aux(sexp ctx, size_t size, sexp_uint_t tag sexp_current_source_param) { sexp res = (sexp) sexp_alloc(ctx, size); if (res && ! sexp_exceptionp(res)) { sexp_pointer_tag(res) = tag; +#if SEXP_USE_TRACK_ALLOC_SOURCE + sexp_pointer_source(res) = source; +#endif #if SEXP_USE_HEADER_MAGIC sexp_pointer_magic(res) = SEXP_POINTER_MAGIC; #endif