diff --git a/src/block_allocator.c b/src/block_allocator.c index 734bab8de1fd14a4b821c3fcbf17aa0ef12a35af..26b8572f7084019cfe6ef1be9552caa77371d086 100644 --- a/src/block_allocator.c +++ b/src/block_allocator.c @@ -55,7 +55,19 @@ struct ba_block_header { static struct ba_page * ba_alloc_page(struct block_allocator * a, int i) { struct ba_layout l = ba_get_layout(a, i); size_t n = l.offset + l.block_size + sizeof(struct ba_page); - struct ba_page * p = (struct ba_page*)xalloc(n); + struct ba_page * p; +#ifdef DEBUG_MALLOC + /* In debug malloc mode, calling xalloc from the block alloc may result + * in a deadlock, since xalloc will call ba_alloc, which in turn may call xalloc. + */ + p = (struct ba_page*)system_malloc(n); + if (!p) { + fprintf(stderr, "Fatal: Out of memory.\n"); + exit(17); + } +#else + p = (struct ba_page*)xalloc(n); +#endif p->h.first = BA_BLOCKN(a->l, p, 0); p->h.first->next = BA_ONE; p->h.used = 0; @@ -84,7 +96,11 @@ PMOD_EXPORT void ba_destroy(struct block_allocator * a) { int i; for (i = 0; i < a->size; i++) { if (a->pages[i]) { +#ifdef DEBUG_MALLOC + system_free(a->pages[i]); +#else free(a->pages[i]); +#endif a->pages[i] = NULL; } } @@ -207,7 +223,11 @@ found: #endif if (!(--p->h.used) && i+1 == a->size) { while (i >= 0 && !(p->h.used)) { +#ifdef DEBUG_MALLOC + system_free(p); +#else free(p); +#endif a->pages[i] = NULL; p = a->pages[--i]; diff --git a/src/pike_memory.c b/src/pike_memory.c index 5dac54491ca97d34bedd4c872628b8f4275e78d4..7448b1317476b301f3fdce00e15a4e6e19472ae1 100644 --- a/src/pike_memory.c +++ b/src/pike_memory.c @@ -11,6 +11,7 @@ #include "gc.h" #include "fd_control.h" #include "dmalloc.h" +#include "block_allocator.h" #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> @@ -1501,13 +1502,6 @@ void *fake_calloc(size_t x, size_t y) static struct memhdr *my_find_memhdr(void *, int); static void dump_location_bt (LOCATION l, int indent, const char *prefix); -#include "block_alloc_h.h" - -BLOCK_ALLOC_FILL_PAGES(memloc, n/a); -BLOCK_ALLOC_FILL_PAGES(memory_map, n/a); -BLOCK_ALLOC_FILL_PAGES(memory_map_entry, n/a); - -#include "block_alloc.h" int verbose_debug_malloc = 0; int debug_malloc_check_all = 0; @@ -1579,7 +1573,19 @@ struct memloc #define MEM_TRACE 64 #define MEM_SCANNED 128 -BLOCK_ALLOC_FILL_PAGES(memloc, 64) +static struct block_allocator memloc_allocator = BA_INIT_PAGES(sizeof(struct memloc), 64); + +static struct memloc * alloc_memloc() { + return ba_alloc(&memloc_allocator); +} + +static void really_free_memloc(struct memloc * ml) { + ba_free(&memloc_allocator, ml); +} + +void count_memory_in_memlocs(size_t * n, size_t * s) { + ba_count_all(&memloc_allocator, n, s); +} struct memhdr { @@ -1776,6 +1782,8 @@ static INLINE unsigned long lhash(struct memhdr *m, LOCATION location) return l; } +#include "block_alloc.h" + #undef INIT_BLOCK #undef EXIT_BLOCK @@ -1829,6 +1837,7 @@ static INLINE unsigned long lhash(struct memhdr *m, LOCATION location) #undef BLOCK_ALLOC_HSIZE_SHIFT #define BLOCK_ALLOC_HSIZE_SHIFT 1 + PTR_HASH_ALLOC_FILL_PAGES(memhdr, 128) #undef INIT_BLOCK @@ -2218,6 +2227,15 @@ static void flush_blocks_to_free(void) } } +MALLOC_FUNCTION +PMOD_EXPORT void * system_malloc(size_t n) { + return real_malloc(n); +} + +PMOD_EXPORT void system_free(void * p) { + real_free(p); +} + PMOD_EXPORT void *debug_malloc(size_t s, LOCATION location) { char *m; @@ -3003,9 +3021,6 @@ static void initialize_dmalloc(void) #ifdef DMALLOC_REMEMBER_LAST_LOCATION th_key_create(&dmalloc_last_seen_location, 0); #endif - init_memloc_blocks(); - init_memory_map_blocks(); - init_memory_map_entry_blocks(); init_memhdr_hash(); MEMSET(mlhash, 0, sizeof(mlhash)); @@ -3357,8 +3372,34 @@ struct memory_map_entry struct memory_map *recur; }; -BLOCK_ALLOC_FILL_PAGES(memory_map, 8) -BLOCK_ALLOC_FILL_PAGES(memory_map_entry, 16) +static struct block_allocator memory_map_allocator = BA_INIT_PAGES(sizeof(struct memory_map), 8); + +static struct memory_map * alloc_memory_map() { + return ba_alloc(&memory_map_allocator); +} + +static void really_free_memory_map(struct memory_map * m) { + ba_free(&memory_map_allocator, m); +} + +void count_memory_in_memory_maps(size_t * n, size_t * s) { + ba_count_all(&memory_map_allocator, n, s); +} + +static struct block_allocator memory_map_entry_allocator + = BA_INIT_PAGES(sizeof(struct memory_map_entry), 16); + +static struct memory_map_entry * alloc_memory_map_entry() { + return ba_alloc(&memory_map_entry_allocator); +} + +static void really_free_memory_map_entry(struct memory_map_entry * m) { + ba_free(&memory_map_entry_allocator, m); +} + +void count_memory_in_memory_map_entrys(size_t * n, size_t * s) { + ba_count_all(&memory_map_entry_allocator, n, s); +} void dmalloc_set_mmap(void *ptr, struct memory_map *m) { @@ -3505,10 +3546,9 @@ static void cleanup_debug_malloc(void) { size_t i; - free_all_memloc_blocks(); + ba_destroy(&memloc_allocator); + ba_destroy(&memory_map_allocator); exit_memhdr_hash(); - free_all_memory_map_blocks(); - free_all_memory_map_entry_blocks(); for (i = 0; i < DSTRHSIZE; i++) { struct dmalloc_string *str = dstrhash[i], *next; diff --git a/src/pike_memory.h b/src/pike_memory.h index c593bdccfee1bf42857a86f9ae91fdf280c05b42..1bef877baadbb37f0e6e773d1ecd3601ea5146b2 100644 --- a/src/pike_memory.h +++ b/src/pike_memory.h @@ -189,6 +189,11 @@ PMOD_EXPORT void mexec_free(void *ptr); void init_pike_memory (void); void exit_pike_memory (void); +#ifdef DEBUG_MALLOC +PMOD_EXPORT void * system_malloc(size_t) MALLOC_FUNCTION; +PMOD_EXPORT void system_free(void *); +#endif + #undef BLOCK_ALLOC #ifdef HANDLES_UNALIGNED_MEMORY_ACCESS