GC: use ofm_malloc() and ofm_free() for admin allocation

Using ofm_....() makes it easier to check that memory allocated for GC
administrtation is itself reclaimed.
This commit is contained in:
Matthew Flatt 2015-08-17 09:39:11 -06:00
parent fea2b1ce5e
commit 693cdc673d
5 changed files with 66 additions and 41 deletions

View File

@ -36,7 +36,7 @@ static intptr_t alloc_cache_free_all_pages(AllocCacheBlock *blockfree);
static intptr_t alloc_cache_free(AllocCacheBlock *ac) { static intptr_t alloc_cache_free(AllocCacheBlock *ac) {
if (ac) { if (ac) {
intptr_t s = alloc_cache_free_all_pages(ac); intptr_t s = alloc_cache_free_all_pages(ac);
free(ac); ofm_free(ac, sizeof(AllocCacheBlock) * BLOCKFREE_CACHE_SIZE);
return s; return s;
} }
return 0; return 0;

View File

@ -80,7 +80,7 @@ static BlockCache* block_cache_create(MMU *mmu) {
static ssize_t block_cache_free(BlockCache* bc) { static ssize_t block_cache_free(BlockCache* bc) {
ssize_t acf = alloc_cache_free(bc->bigBlockCache); ssize_t acf = alloc_cache_free(bc->bigBlockCache);
page_range_free(bc->page_range); page_range_free(bc->page_range);
free(bc); ofm_free(bc, sizeof(BlockCache));
return acf; return acf;
} }
@ -220,7 +220,7 @@ static ssize_t bc_free_std_block(block_desc *b) {
gclist_del(&b->gclist); gclist_del(&b->gclist);
os_free_pages(b->block, b->size); os_free_pages(b->block, b->size);
size_diff -= b->size; size_diff -= b->size;
free(b); ofm_free(b, sizeof(block_desc));
return size_diff; return size_diff;
} }

View File

@ -97,7 +97,7 @@ inline static void clean_up_thread_list(NewGC *gc)
if(prev) prev->next = next; if(prev) prev->next = next;
if(!prev) gc->thread_infos = next; if(!prev) gc->thread_infos = next;
free(work); ofm_free(work, sizeof(GC_Thread_Info));
work = next; work = next;
} }
} }
@ -175,7 +175,7 @@ void BTC_register_root_custodian(void *_c)
if (gc->owner_table) { if (gc->owner_table) {
/* Reset */ /* Reset */
free(gc->owner_table); ofm_free(gc->owner_table, sizeof(OTEntry*) * gc->owner_table_size);
gc->owner_table = NULL; gc->owner_table = NULL;
gc->owner_table_size = 0; gc->owner_table_size = 0;
} }
@ -214,7 +214,7 @@ inline static void free_owner_set(NewGC *gc, int set)
{ {
OTEntry **owner_table = gc->owner_table; OTEntry **owner_table = gc->owner_table;
if(owner_table[set]) { if(owner_table[set]) {
free(owner_table[set]); ofm_free(owner_table[set], sizeof(OTEntry));
} }
owner_table[set] = NULL; owner_table[set] = NULL;
} }
@ -558,7 +558,7 @@ inline static void clean_up_account_hooks(NewGC *gc)
if(prev) prev->next = next; if(prev) prev->next = next;
if(!prev) gc->hooks = next; if(!prev) gc->hooks = next;
free(work); ofm_free(work, sizeof(AccountHook));
work = next; work = next;
} }
} }
@ -615,7 +615,7 @@ inline static void BTC_run_account_hooks(NewGC *gc)
if(prev) prev->next = next; if(prev) prev->next = next;
if(!prev) gc->hooks = next; if(!prev) gc->hooks = next;
scheme_schedule_custodian_close(work->c2); scheme_schedule_custodian_close(work->c2);
free(work); ofm_free(work, sizeof(AccountHook));
work = next; work = next;
} else { } else {
prev = work; prev = work;

View File

@ -322,6 +322,11 @@ void GC_set_post_propagate_hook(GC_Post_Propagate_Hook_Proc func) {
static void garbage_collect(NewGC*, int, int, int, Log_Master_Info*); static void garbage_collect(NewGC*, int, int, int, Log_Master_Info*);
static void collect_now(NewGC*, int, int); static void collect_now(NewGC*, int, int);
#define TRACK_OFM_SIZE 0
#if TRACK_OFM_SIZE
static int total_ofm_size;
#endif
static void out_of_memory() static void out_of_memory()
{ {
if (GC_report_out_of_memory) if (GC_report_out_of_memory)
@ -337,6 +342,9 @@ inline static void out_of_memory_gc(NewGC* gc) {
static void *ofm_malloc(size_t size) { static void *ofm_malloc(size_t size) {
void *ptr = malloc(size); void *ptr = malloc(size);
if (!ptr) out_of_memory(); if (!ptr) out_of_memory();
#if TRACK_OFM_SIZE
total_ofm_size += size;
#endif
return ptr; return ptr;
} }
@ -347,6 +355,13 @@ static void *ofm_malloc_zero(size_t size) {
return ptr; return ptr;
} }
static void ofm_free(void *p, size_t size) {
#if TRACK_OFM_SIZE
total_ofm_size -= size;
#endif
free(p);
}
inline static size_t size_to_apage_count(size_t len) { inline static size_t size_to_apage_count(size_t len) {
return (len / APAGE_SIZE) + (((len % APAGE_SIZE) == 0) ? 0 : 1); return (len / APAGE_SIZE) + (((len % APAGE_SIZE) == 0) ? 0 : 1);
} }
@ -565,15 +580,15 @@ inline static void free_page_maps(PageMap page_maps1) {
for (j=0; j<PAGEMAP64_LEVEL2_SIZE; j++) { for (j=0; j<PAGEMAP64_LEVEL2_SIZE; j++) {
page_maps3 = page_maps2[j]; page_maps3 = page_maps2[j];
if (page_maps3) { if (page_maps3) {
free(page_maps3); ofm_free(page_maps3, PAGEMAP64_LEVEL3_SIZE * sizeof(mpage *));
} }
} }
free(page_maps2); ofm_free(page_maps2, PAGEMAP64_LEVEL2_SIZE * sizeof(mpage *));
} }
} }
free(page_maps1); ofm_free(page_maps1, PAGEMAP64_LEVEL1_SIZE * sizeof (mpage***));
#else #else
free(page_maps1); ofm_free(page_maps1, PAGEMAP32_SIZE * sizeof (mpage***));
#endif #endif
} }
@ -588,13 +603,13 @@ inline static void pagemap_set(PageMap page_maps1, void *p, mpage *value) {
pos = PAGEMAP64_LEVEL1_BITS(p); pos = PAGEMAP64_LEVEL1_BITS(p);
page_maps2 = page_maps1[pos]; page_maps2 = page_maps1[pos];
if (!page_maps2) { if (!page_maps2) {
page_maps2 = (mpage ***)calloc(PAGEMAP64_LEVEL2_SIZE, sizeof(mpage **)); page_maps2 = (mpage ***)ofm_malloc_zero(PAGEMAP64_LEVEL2_SIZE * sizeof(mpage **));
page_maps1[pos] = page_maps2; page_maps1[pos] = page_maps2;
} }
pos = PAGEMAP64_LEVEL2_BITS(p); pos = PAGEMAP64_LEVEL2_BITS(p);
page_maps3 = page_maps2[pos]; page_maps3 = page_maps2[pos];
if (!page_maps3) { if (!page_maps3) {
page_maps3 = (mpage **)calloc(PAGEMAP64_LEVEL3_SIZE, sizeof(mpage *)); page_maps3 = (mpage **)ofm_malloc_zero(PAGEMAP64_LEVEL3_SIZE * sizeof(mpage *));
page_maps2[pos] = page_maps3; page_maps2[pos] = page_maps3;
} }
page_maps3[PAGEMAP64_LEVEL3_BITS(p)] = value; page_maps3[PAGEMAP64_LEVEL3_BITS(p)] = value;
@ -872,7 +887,7 @@ static mpage *malloc_mpage()
static void free_mpage(mpage *page) static void free_mpage(mpage *page)
{ {
free(page); ofm_free(page, sizeof(mpage));
} }
#ifdef NEWGC_BTC_ACCOUNT #ifdef NEWGC_BTC_ACCOUNT
@ -1745,7 +1760,7 @@ void *GC_finish_message_allocator() {
GC_gen0_alloc_page_ptr = a->saved_alloc_page_ptr ; GC_gen0_alloc_page_ptr = a->saved_alloc_page_ptr ;
GC_gen0_alloc_page_end = a->saved_alloc_page_end ; GC_gen0_alloc_page_end = a->saved_alloc_page_end ;
free(a); ofm_free(a, sizeof(Allocator));
gc->saved_allocator = NULL; gc->saved_allocator = NULL;
gc->in_unsafe_allocation_mode = 0; gc->in_unsafe_allocation_mode = 0;
@ -1797,7 +1812,7 @@ void GC_adopt_message_allocator(void *param) {
msgm->pages->prev = gen0end; msgm->pages->prev = gen0end;
} }
} }
free(msgm); ofm_free(msgm, sizeof(MsgMemory));
/* Adopted enough to trigger a GC? */ /* Adopted enough to trigger a GC? */
gc_if_needed_account_alloc_size(gc, 0); gc_if_needed_account_alloc_size(gc, 0);
@ -1836,7 +1851,7 @@ void GC_dispose_short_message_allocator(void *param) {
free_orphaned_page(gc, msgm->pages); free_orphaned_page(gc, msgm->pages);
} }
free(msgm); ofm_free(msgm, sizeof(MsgMemory));
} }
void GC_destroy_orphan_msg_memory(void *param) { void GC_destroy_orphan_msg_memory(void *param) {
@ -1869,7 +1884,7 @@ void GC_destroy_orphan_msg_memory(void *param) {
} }
} }
free(msgm); ofm_free(msgm, sizeof(MsgMemory));
} }
@ -2614,7 +2629,7 @@ inline static void clear_stack_pages(NewGC *gc)
if (!keep) if (!keep)
gc->mark_stack->next = NULL; gc->mark_stack->next = NULL;
} else } else
free(gc->mark_stack); ofm_free(gc->mark_stack, STACK_PART_SIZE);
} }
gc->mark_stack = base; gc->mark_stack = base;
gc->mark_stack->top = MARK_STACK_START(gc->mark_stack); gc->mark_stack->top = MARK_STACK_START(gc->mark_stack);
@ -2631,7 +2646,7 @@ inline static void free_all_stack_pages(NewGC *gc)
/* then go through and clear them out */ /* then go through and clear them out */
for(; gc->mark_stack; gc->mark_stack = temp) { for(; gc->mark_stack; gc->mark_stack = temp) {
temp = gc->mark_stack->next; temp = gc->mark_stack->next;
free(gc->mark_stack); ofm_free(gc->mark_stack, STACK_PART_SIZE);
} }
} }
} }
@ -2797,7 +2812,7 @@ static void NewGCMasterInfo_initialize() {
MASTERGCINFO->size = 32; MASTERGCINFO->size = 32;
MASTERGCINFO->alive = 0; MASTERGCINFO->alive = 0;
MASTERGCINFO->ready = 0; MASTERGCINFO->ready = 0;
MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); MASTERGCINFO->signal_fds = (void **)ofm_malloc(sizeof(void*) * MASTERGCINFO->size);
for (i=0; i < 32; i++ ) { for (i=0; i < 32; i++ ) {
MASTERGCINFO->signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE; MASTERGCINFO->signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE;
} }
@ -2810,8 +2825,8 @@ static void NewGCMasterInfo_initialize() {
/* Not yet used: */ /* Not yet used: */
static void NewGCMasterInfo_cleanup() { static void NewGCMasterInfo_cleanup() {
mzrt_rwlock_destroy(MASTERGCINFO->cangc); mzrt_rwlock_destroy(MASTERGCINFO->cangc);
free(MASTERGCINFO->signal_fds); ofm_free(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size);
free(MASTERGCINFO); ofm_free(MASTERGCINFO, sizeof(NewGCMasterInfo));
MASTERGCINFO = NULL; MASTERGCINFO = NULL;
} }
#endif #endif
@ -2960,23 +2975,33 @@ static void wait_while_master_in_progress(NewGC *gc, Log_Master_Info *lmi) {
/* MUST CALL WITH cangc lock */ /* MUST CALL WITH cangc lock */
static intptr_t NewGCMasterInfo_find_free_id() { static intptr_t NewGCMasterInfo_find_free_id() {
int i, size;
GC_ASSERT(MASTERGCINFO->alive <= MASTERGCINFO->size); GC_ASSERT(MASTERGCINFO->alive <= MASTERGCINFO->size);
if ((MASTERGCINFO->alive + 1) == MASTERGCINFO->size) { if ((MASTERGCINFO->alive + 1) == MASTERGCINFO->size) {
MASTERGCINFO->size++; void **new_signal_fds;
size = MASTERGCINFO->size * 2;
MASTERGCINFO->alive++; MASTERGCINFO->alive++;
MASTERGCINFO->signal_fds = realloc(MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size); new_signal_fds = ofm_malloc(sizeof(void*) * size);
return MASTERGCINFO->size - 1; memcpy(new_signal_fds, MASTERGCINFO->signal_fds, sizeof(void*) * MASTERGCINFO->size);
for (i = MASTERGCINFO->size; i < size; i++ ) {
new_signal_fds[i] = (void *)REAPED_SLOT_AVAILABLE;
}
MASTERGCINFO->signal_fds = new_signal_fds;
MASTERGCINFO->size = size;
} }
else {
int i; size = MASTERGCINFO->size;
int size = MASTERGCINFO->size; for (i = 0; i < size; i++) {
for (i = 0; i < size; i++) { if (MASTERGCINFO->signal_fds[i] == (void*) REAPED_SLOT_AVAILABLE) {
if (MASTERGCINFO->signal_fds[i] == (void*) REAPED_SLOT_AVAILABLE) { MASTERGCINFO->alive++;
MASTERGCINFO->alive++; return i;
return i;
}
} }
} }
printf("Error in MASTERGCINFO table\n"); printf("Error in MASTERGCINFO table\n");
abort(); abort();
return 0; return 0;
@ -5357,7 +5382,7 @@ static void free_child_gc(void)
mmu_flush_freed_pages(gc->mmu); mmu_flush_freed_pages(gc->mmu);
mmu_free(gc->mmu); mmu_free(gc->mmu);
free(gc); ofm_free(gc, sizeof(NewGC));
} }
#endif #endif
@ -5388,12 +5413,12 @@ void GC_free_all(void)
} }
} }
free(gc->mark_table); ofm_free(gc->mark_table, NUMBER_OF_TAGS * sizeof (Mark2_Proc));
free(gc->fixup_table); ofm_free(gc->fixup_table, NUMBER_OF_TAGS * sizeof (Fixup2_Proc));
free_page_maps(gc->page_maps); free_page_maps(gc->page_maps);
free_all_stack_pages(gc); free_all_stack_pages(gc);
mmu_flush_freed_pages(gc->mmu); mmu_flush_freed_pages(gc->mmu);
mmu_free(gc->mmu); mmu_free(gc->mmu);
free(gc); ofm_free(gc, sizeof(NewGC));
} }

View File

@ -178,9 +178,9 @@ void *mzrt_thread_stub(void *data){
} }
#ifdef WIN32 #ifdef WIN32
uintptr_t WINAPI mzrt_win_thread_stub(void *data) DWORD WINAPI mzrt_win_thread_stub(void *data)
{ {
return (uintptr_t)mzrt_thread_stub(data); return (DWORD)mzrt_thread_stub(data);
} }
#endif #endif