diff --git a/Makefile.config.in b/Makefile.config.in index af505807..f5145e9c 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -114,6 +114,7 @@ CONFIG_FINGER = @CONFIG_FINGER@ CONFIG_FORMHIST = @CONFIG_FORMHIST@ CONFIG_FSP = @CONFIG_FSP@ CONFIG_FTP = @CONFIG_FTP@ +CONFIG_GC = @CONFIG_GC@ CONFIG_GLOBHIST = @CONFIG_GLOBHIST@ CONFIG_GNUTLS = @CONFIG_GNUTLS@ CONFIG_GNUTLS_OPENSSL_COMPAT = @CONFIG_GNUTLS_OPENSSL_COMPAT@ diff --git a/configure.in b/configure.in index 2033ef38..19c73f1c 100644 --- a/configure.in +++ b/configure.in @@ -1253,6 +1253,26 @@ EL_ARG_ENABLE(CONFIG_OWN_LIBC, own-libc, [Own libc stubs], EL_ARG_ENABLE(CONFIG_SMALL, small, [Small binary], [ --enable-small reduce binary size as far as possible (but see the bottom of doc/small.txt!)]) +EL_ARG_ENABLE(CONFIG_GC, gc, [Garbage collector], + [ --enable-gc enable Boehm's garbage collector]) + +EL_SAVE_FLAGS +if test "x${enable_gc}" = xyes; then + CFLAGS="$CFLAGS -I/usr/include/gc" +# -lgc might already be added by SEE + AC_TRY_LINK([#include + ], [void *p = GC_MALLOC(1);], CONFIG_GC=yes, CONFIG_GC=no) + if test "$CONFIG_GC" != yes; then + LIBS="$LIBS -lgc" + AC_TRY_LINK([#include + ], [void *p = GC_MALLOC(1);], CONFIG_GC=yes, CONFIG_GC=no) + fi + if test "$CONFIG_GC" != yes; then + EL_RESTORE_FLAGS + fi +fi +AC_SUBST(CONFIG_GC) + AC_ARG_ENABLE(weehoofooboomookerchoo, [ Also check out the features.conf file for more information about features! diff --git a/src/main/main.c b/src/main/main.c index 5b2bec8e..e85c72cc 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -336,9 +336,21 @@ check_if_root(void) #define check_if_root() #endif +#ifdef CONFIG_GC +static void +gc_warning(char *msg, GC_word arg) +{ +} +#endif + + int main(int argc, char *argv[]) { +#ifdef CONFIG_GC + GC_INIT(); + GC_set_warn_proc(gc_warning); +#endif check_if_root(); program.terminate = 0; diff --git a/src/util/memdebug.c b/src/util/memdebug.c index 44fa9c02..26c65380 100644 --- a/src/util/memdebug.c +++ b/src/util/memdebug.c @@ -319,7 +319,11 @@ debug_mem_alloc(unsigned char *file, int line, size_t size) true_size = SIZE_BASE2AH(size); do { +#ifdef CONFIG_GC + ah = GC_MALLOC(true_size); +#else ah = malloc(true_size); +#endif if (ah) break; } while (patience(file, line, "malloc")); if (!ah) return NULL; @@ -368,7 +372,11 @@ debug_mem_calloc(unsigned char *file, int line, size_t eltcount, size_t eltsize) true_size = SIZE_BASE2AH(size); do { - ah = calloc(1, SIZE_BASE2AH(size)); +#ifdef CONFIG_GC + ah = GC_MALLOC(true_size); +#else + ah = calloc(1, true_size); +#endif if (ah) break; } while (patience(file, line, "calloc")); if (!ah) return NULL; @@ -450,7 +458,11 @@ debug_mem_free(unsigned char *file, int line, void *ptr) if (ah->comment) { mem_stats.true_amount -= strlen(ah->comment) + 1; +#ifdef CONFIG_GC + ah->comment = NULL; +#else free(ah->comment); +#endif } del_from_list(ah); @@ -465,7 +477,11 @@ debug_mem_free(unsigned char *file, int line, void *ptr) ah->magic = AH_FREE_MAGIC; #endif +#ifdef CONFIG_GC + ah = NULL; +#else free(ah); +#endif } void * @@ -502,7 +518,11 @@ debug_mem_realloc(unsigned char *file, int line, void *ptr, size_t size) true_size = SIZE_BASE2AH(size); do { +#ifdef CONFIG_GC + ah2 = GC_REALLOC(ah, true_size); +#else ah2 = realloc(ah, true_size); +#endif if (ah2) { ah = ah2; break; @@ -546,10 +566,17 @@ set_mem_comment(void *ptr, unsigned char *str, int len) if (ah->comment) { mem_stats.true_amount -= strlen(ah->comment) + 1; +#ifdef CONFIG_GC + ah->comment = NULL; +#else free(ah->comment); +#endif } - +#ifdef CONFIG_GC + ah->comment = GC_MALLOC(len + 1); +#else ah->comment = malloc(len + 1); +#endif if (ah->comment) { memcpy(ah->comment, str, len); ah->comment[len] = 0; diff --git a/src/util/memory.c b/src/util/memory.c index c0a2421a..81dfbc82 100644 --- a/src/util/memory.c +++ b/src/util/memory.c @@ -55,8 +55,11 @@ mem_alloc(size_t size) { if (size) do { +#ifdef CONFIG_GC + void *p = GC_MALLOC(size); +#else void *p = malloc(size); - +#endif if (p) return p; } while (patience("malloc")); @@ -68,8 +71,11 @@ mem_calloc(size_t count, size_t eltsize) { if (eltsize && count) do { +#ifdef CONFIG_GC + void *p = GC_MALLOC(count * eltsize); +#else void *p = calloc(count, eltsize); - +#endif if (p) return p; } while (patience("calloc")); @@ -83,8 +89,11 @@ mem_free(void *p) INTERNAL("mem_free(NULL)"); return; } - +#ifdef CONFIG_GC + p = NULL; +#else free(p); +#endif } void * @@ -94,8 +103,11 @@ mem_realloc(void *p, size_t size) if (size) do { +#ifdef CONFIG_GC + void *p2 = GC_REALLOC(p, size); +#else void *p2 = realloc(p, size); - +#endif if (p2) return p2; } while (patience("realloc")); else diff --git a/src/util/memory.h b/src/util/memory.h index cb5927d4..2864408b 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -20,6 +20,10 @@ #include #include +#ifdef CONFIG_GC +#include +#endif + #ifdef HAVE_MMAP void *mem_mmap_alloc(size_t size); void mem_mmap_free(void *p, size_t size); @@ -62,12 +66,20 @@ void *mem_realloc(void *, size_t); * For these we need some replacement functions. * This should not be an issue on most modern systems. */ +#ifdef CONFIG_GC +# define mem_alloc(size) GC_MALLOC(size) +# define mem_calloc(count, size) GC_MALLOC((count) * (size)) +# define mem_free(p) (p) = NULL +# define mem_realloc(p, size) GC_REALLOC(p, size) + +#else # define mem_alloc(size) malloc(size) # define mem_calloc(count, size) calloc(count, size) # define mem_free(p) free(p) # define mem_realloc(p, size) realloc(p, size) +#endif /* fmem_* functions should be use for allocation and freeing of memory * inside a function.