adding ability to track the alloc source of objects

This commit is contained in:
Alex Shinn 2010-12-29 18:33:37 +09:00
parent 5371a7bad3
commit 7306b55350
4 changed files with 49 additions and 8 deletions

12
gc.c
View file

@ -105,8 +105,15 @@ void sexp_conservative_mark (sexp ctx) {
p = (sexp) (((char*)p) + r->size); p = (sexp) (((char*)p) + r->size);
continue; 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); sexp_mark(ctx, p);
}
p = (sexp) (((char*)p)+sexp_heap_align(sexp_allocated_bytes(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_mark(ctx, ctx);
sexp_conservative_mark(ctx); sexp_conservative_mark(ctx);
#if SEXP_USE_DEBUG_GC #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 "); sexp_sweep_stats(ctx, 2, NULL, "* \x1B[31mFREE:\x1B[0m ");
#endif #endif
#if SEXP_USE_WEAK_REFERENCES #if SEXP_USE_WEAK_REFERENCES

View file

@ -77,6 +77,9 @@
/* uncomment this to add additional native checks to only mark objects in the heap */ /* uncomment this to add additional native checks to only mark objects in the heap */
/* #define SEXP_USE_SAFE_GC_MARK 1 */ /* #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 */ /* uncomment this to add additional native gc checks to verify a magic header */
/* #define SEXP_USE_HEADER_MAGIC 1 */ /* #define SEXP_USE_HEADER_MAGIC 1 */
@ -91,7 +94,7 @@
/* uncomment this to make type definitions common to all contexts */ /* uncomment this to make type definitions common to all contexts */
/* By default types are only global if you don't allow user type */ /* 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 */ /* 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 */ /* #define SEXP_USE_GLOBAL_TYPES 1 */
/* uncomment this to make the symbol table common to all contexts */ /* uncomment this to make the symbol table common to all contexts */
@ -303,7 +306,11 @@
#endif #endif
#ifndef SEXP_USE_CONSERVATIVE_GC #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 #endif
#ifndef SEXP_USE_HEADER_MAGIC #ifndef SEXP_USE_HEADER_MAGIC

View file

@ -232,6 +232,9 @@ struct sexp_struct {
unsigned int freep:1; unsigned int freep:1;
unsigned int brokenp:1; unsigned int brokenp:1;
unsigned int syntacticp:1; unsigned int syntacticp:1;
#if SEXP_USE_TRACK_ALLOC_SOURCE
const char* source;
#endif
#if SEXP_USE_HEADER_MAGIC #if SEXP_USE_HEADER_MAGIC
unsigned int magic; unsigned int magic;
#endif #endif
@ -444,13 +447,19 @@ void *sexp_realloc(sexp ctx, sexp x, size_t size);
#define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \ #define sexp_sizeof(x) (offsetof(struct sexp_struct, value) \
+ sizeof(((sexp)0)->value.x)) + sizeof(((sexp)0)->value.x))
#define sexp_offsetof(type, f) (offsetof(struct sexp_struct, value.type.f)) #define sexp_offsetof(type, f) (offsetof(struct sexp_struct, value.type.f))
#define sexp_offsetof_slot0 (offsetof(struct sexp_struct, value)) #define sexp_offsetof_slot0 (offsetof(struct sexp_struct, value))
#define sexp_sizeof_header (sexp_sizeof(flonum) - sizeof(double)) #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_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) #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_brokenp(x) ((x)->brokenp)
#define sexp_pointer_magic(x) ((x)->magic) #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_check_tag(x,t) (sexp_pointerp(x) && (sexp_pointer_tag(x) == (t)))
#define sexp_slot_ref(x,i) (((sexp*)&((x)->value))[i]) #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_at_eofp(p) (feof(sexp_port_stream(p)))
#define sexp_port_fileno(p) (fileno(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_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_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_list2(sexp ctx, sexp a, sexp b);
SEXP_API sexp sexp_equalp_op (sexp ctx sexp_api_params(self, n), sexp a, sexp b); SEXP_API sexp sexp_equalp_op (sexp ctx sexp_api_params(self, n), sexp a, sexp b);

5
sexp.c
View file

@ -47,10 +47,13 @@ static int is_separator(int c) {
sexp sexp_symbol_table[SEXP_SYMBOL_TABLE_SIZE]; sexp sexp_symbol_table[SEXP_SYMBOL_TABLE_SIZE];
#endif #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); sexp res = (sexp) sexp_alloc(ctx, size);
if (res && ! sexp_exceptionp(res)) { if (res && ! sexp_exceptionp(res)) {
sexp_pointer_tag(res) = tag; sexp_pointer_tag(res) = tag;
#if SEXP_USE_TRACK_ALLOC_SOURCE
sexp_pointer_source(res) = source;
#endif
#if SEXP_USE_HEADER_MAGIC #if SEXP_USE_HEADER_MAGIC
sexp_pointer_magic(res) = SEXP_POINTER_MAGIC; sexp_pointer_magic(res) = SEXP_POINTER_MAGIC;
#endif #endif