From cbfe8e6242066ed5101bb8266dfa70bd431efa15 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 6 Jul 2003 14:54:07 +0000 Subject: [PATCH] (decrease_mtrigger): new function (increase_mtrigger): new function, separate debug registering and mtrigger administration. (scm_gc_realloc): bugfix: do mtrigger administration before the actual realloc, for the realloc might invalidate a GC-d segment of memory. Thanks to Sam Hocevar for pointing this out. (scm_gc_realloc): use scm_malloc_reregister instead of unregistering and registering in sequence. --- THANKS | 1 + libguile/ChangeLog | 11 ++++++++++ libguile/gc-malloc.c | 48 ++++++++++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/THANKS b/THANKS index bb4a95166..fead9fe58 100644 --- a/THANKS +++ b/THANKS @@ -30,6 +30,7 @@ For fixes or providing information which led to a fix: Mike Gran Sven Hartrumpf Eric Hanchrow + Sam Hocevar Peter Ivanyi Aubrey Jaffer Richard Kim diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 7fa4de5f0..3b432d5fe 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,14 @@ +2003-07-06 Han-Wen Nienhuys + + * gc-malloc.c (decrease_mtrigger): new function + (increase_mtrigger): new function, separate debug registering and + mtrigger administration. + (scm_gc_realloc): bugfix: do mtrigger administration before the + actual realloc, for the realloc might invalidate a GC-d segment of + memory. Thanks to Sam Hocevar for pointing this out. + (scm_gc_realloc): use scm_malloc_reregister instead of + unregistering and registering in sequence. + 2003-07-03 Han-Wen Nienhuys * __scm.h (SCM_ASSERT): change "else" expansion to "do { } while (0)" diff --git a/libguile/gc-malloc.c b/libguile/gc-malloc.c index dd8e683e0..02032adcb 100644 --- a/libguile/gc-malloc.c +++ b/libguile/gc-malloc.c @@ -177,8 +177,16 @@ scm_strdup (const char *str) return scm_strndup (str, strlen (str)); } -void -scm_gc_register_collectable_memory (void *mem, size_t size, const char *what) + +static void +decrease_mtrigger (size_t size, const char * what) +{ + scm_mallocated -= size; + scm_gc_malloc_collected += size; +} + +static void +increase_mtrigger (size_t size, const char *what) { if (ULONG_MAX - size < scm_mallocated) { @@ -187,11 +195,6 @@ scm_gc_register_collectable_memory (void *mem, size_t size, const char *what) scm_mallocated += size; - /* - we could finish the full sweep (without mark) here, but in - practice this turns out to be ineffective. - */ - /* A program that uses a lot of malloced collectable memory (vectors, strings), will use a lot of memory off the cell-heap; it needs to @@ -250,19 +253,23 @@ scm_gc_register_collectable_memory (void *mem, size_t size, const char *what) scm_rec_mutex_unlock (&scm_i_sweep_mutex); } - +} + +void +scm_gc_register_collectable_memory (void *mem, size_t size, const char *what) +{ + increase_mtrigger (size, what); #ifdef GUILE_DEBUG_MALLOC if (mem) scm_malloc_register (mem, what); #endif } + void scm_gc_unregister_collectable_memory (void *mem, size_t size, const char *what) { - scm_mallocated -= size; - scm_gc_malloc_collected += size; - + decrease_mtrigger (size, what); #ifdef GUILE_DEBUG_MALLOC if (mem) scm_malloc_unregister (mem); @@ -302,9 +309,24 @@ scm_gc_realloc (void *mem, size_t old_size, size_t new_size, const char *what) { /* XXX - see scm_gc_malloc. */ + + /* + scm_realloc() may invalidate the block pointed to by WHERE, eg. by + unmapping it from memory or altering the contents. Since + increase_mtrigger() might trigger a GC that would scan + MEM, it is crucial that this call precedes realloc(). + */ + + decrease_mtrigger (old_size, what); + increase_mtrigger (new_size, what); + void *ptr = scm_realloc (mem, new_size); - scm_gc_unregister_collectable_memory (mem, old_size, what); - scm_gc_register_collectable_memory (ptr, new_size, what); + +#ifdef GUILE_DEBUG_MALLOC + if (mem) + scm_malloc_reregister (mem, ptr, what); +#endif + return ptr; }