diff --git a/chicken.h b/chicken.h index 6dfefb9..ce725a4 100644 --- a/chicken.h +++ b/chicken.h @@ -1771,6 +1771,7 @@ C_fctexport C_word C_vector(C_word **ptr, int n, ...); C_fctexport C_word C_structure(C_word **ptr, int n, ...); C_fctexport C_word C_fcall C_mutate_slot(C_word *slot, C_word val) C_regparm; C_fctexport C_word C_fcall C_mutate(C_word *slot, C_word val) C_regparm; +C_fctexport C_word C_fcall C_check_heap_consistency(C_word dummy) C_regparm; C_fctexport void C_fcall C_reclaim(void *trampoline, void *proc) C_regparm C_noret; C_fctexport void C_save_and_reclaim(void *trampoline, void *proc, int n, ...) C_noret; C_fctexport void C_fcall C_rereclaim2(C_uword size, int double_plus) C_regparm; diff --git a/library.scm b/library.scm index 59ddc36..961714c 100644 --- a/library.scm +++ b/library.scm @@ -5162,3 +5162,7 @@ EOF (loop (- len 1) (cdr input))) (else input)))) + +;;; + +(define (##sys#check-heap-consistency) (##core#inline "C_check_heap_consistency" #f)) diff --git a/runtime.c b/runtime.c index f68cd09..006b7af 100644 --- a/runtime.c +++ b/runtime.c @@ -3123,6 +3123,69 @@ C_regparm void C_fcall C_reclaim(void *trampoline, void *proc) } +C_regparm C_word C_fcall C_check_heap_consistency(C_word dummy) +{ + C_word n, bytes, *p, x; + C_header h; + int i, f = 0; + C_SCHEME_BLOCK *bp = (C_SCHEME_BLOCK *)fromspace_start; + + while((C_byte *)bp < C_fromspace_top) { + if(*((C_word *)bp) == ALIGNMENT_HOLE_MARKER) + bp = (C_SCHEME_BLOCK *)((C_word *)bp + 1); + + n = C_header_size(bp); + h = bp->header; + bytes = (h & C_BYTEBLOCK_BIT) ? n : n * sizeof(C_word); + p = bp->data; + i = 0; + + if(n > 0 && (h & C_BYTEBLOCK_BIT) == 0) { + if(h & C_SPECIALBLOCK_BIT) { + --n; + ++i; + ++p; + } + + while(n--) { + x = *(p++); + + if(!C_immediatep(x)) { + if((C_block_header(x) & C_GC_FORWARDING_BIT) != 0) { + if(!f) { + C_fputc('\n', C_stderr); + f = 1; + } + + fprintf(C_stderr, C_text("Invalid forwarded object-pointer: [object=" UWORD_FORMAT_STRING + ", header=" UWORD_FORMAT_STRING + ": index=" UWORD_COUNT_FORMAT_STRING ", pointer=" UWORD_FORMAT_STRING "]\n"), + (C_uword)bp, (C_uword)h, i, (C_uword)x); + } + else if(C_in_heapp(x) && !C_in_fromspacep(x)) { + if(!f) { + C_fputc('\n', C_stderr); + f = 1; + } + + fprintf(C_stderr, C_text("Invalid non-heap object-pointer: [object=" UWORD_FORMAT_STRING + ", header=" UWORD_FORMAT_STRING + ": index=" UWORD_COUNT_FORMAT_STRING ", pointer=" UWORD_FORMAT_STRING "]\n"), + (C_uword)bp, (C_uword)h, i, (C_uword)x); + } + } + + ++i; + } + } + + bp = (C_SCHEME_BLOCK *)((C_byte *)bp + C_align(bytes) + sizeof(C_header)); + } + + return C_mk_bool(f); +} + + C_regparm void C_fcall mark_system_globals(void) { mark(&interrupt_hook_symbol); diff --git a/tests/lolevel-tests.scm b/tests/lolevel-tests.scm index 3a1dc70..4c41cbe 100644 --- a/tests/lolevel-tests.scm +++ b/tests/lolevel-tests.scm @@ -217,6 +217,7 @@ (define ev-tstvec (object-evict tstvec)) (assert (not (eq? tstvec ev-tstvec))) (assert (object-evicted? ev-tstvec)) +(set! ev-tstvec #f) (object-release ev-tstvec) ; object-evict-to-location