Hi all Attached is a patch to libgc that will allow it to actually unmap memory when USE_MUNMAP is defined. Currently, the unmap code just sets the mmap flags on a region to 'no access'. The patch unlinks blocks from the gc free list larger than a defined min size (currently 4k bytes), that haven't been used for several collections, and unmaps the memory.
It may or may not fix https://bugzilla.novell.com/show_bug.cgi?id=495486 - the reporter forgot to attach his test case. Comments? - Dick
Index: include/private/gc_priv.h =================================================================== --- include/private/gc_priv.h (revision 137556) +++ include/private/gc_priv.h (working copy) @@ -253,6 +253,8 @@ /* the block risks unreasonable immediate */ /* heap growth. */ +# define REALLY_FREE_MIN 4096 + /*********************************/ /* */ /* Stack saving for debugging */ @@ -908,6 +910,7 @@ # endif # ifdef USE_MUNMAP word _unmapped_bytes; + word _really_unmapped_bytes; # endif # ifdef MERGE_SIZES unsigned _size_map[WORDS_TO_BYTES(MAXOBJSZ+1)]; @@ -1054,6 +1057,7 @@ # define GC_last_stack GC_arrays._last_stack # ifdef USE_MUNMAP # define GC_unmapped_bytes GC_arrays._unmapped_bytes +# define GC_really_unmapped_bytes GC_arrays._really_unmapped_bytes # endif # if defined(MSWIN32) || defined(MSWINCE) # define GC_heap_bases GC_arrays._heap_bases @@ -1780,6 +1784,7 @@ void GC_unmap(ptr_t start, word bytes); void GC_remap(ptr_t start, word bytes); void GC_unmap_gap(ptr_t start1, word bytes1, ptr_t start2, word bytes2); + void GC_really_unmap(ptr_t start, word bytes); #endif /* Virtual dirty bit implementation: */ Index: ChangeLog =================================================================== --- ChangeLog (revision 137556) +++ ChangeLog (working copy) @@ -1,3 +1,8 @@ +2009-08-13 Dick Porter <dpor...@codicesoftware.com> + + * include/private/gc_priv.h, allchblk.c, os_dep.c: Cause libgc to + return unused memory to the system in some cases. + 2009-04-28 Zoltan Varga <var...@gmail.com> * misc.c (GC_init): Avoid casting an lvalue. Fixes part of #498692. Index: allchblk.c =================================================================== --- allchblk.c (revision 137556) +++ allchblk.c (working copy) @@ -364,7 +364,7 @@ /* way blocks are ever unmapped. */ void GC_unmap_old(void) { - struct hblk * h; + struct hblk * h, * next; hdr * hhdr; word sz; unsigned short last_rec, threshold; @@ -372,8 +372,9 @@ # define UNMAP_THRESHOLD 6 for (i = 0; i <= N_HBLK_FLS; ++i) { - for (h = GC_hblkfreelist[i]; 0 != h; h = hhdr -> hb_next) { + for (h = GC_hblkfreelist[i]; 0 != h; h = next) { hhdr = HDR(h); + next = hhdr -> hb_next; if (!IS_MAPPED(hhdr)) continue; threshold = (unsigned short)(GC_gc_no - UNMAP_THRESHOLD); last_rec = hhdr -> hb_last_reclaimed; @@ -382,6 +383,16 @@ sz = hhdr -> hb_sz; GC_unmap((ptr_t)h, sz); hhdr -> hb_flags |= WAS_UNMAPPED; + +#if !defined(MSWIN32) && !defined(MSWINCE) + if (sz > REALLY_FREE_MIN) { + GC_remove_from_fl(hhdr, i); + GC_remove_header(h); + + /* Now really unmap the block */ + GC_really_unmap ((ptr_t)h, sz); + } +#endif } } } @@ -412,6 +423,7 @@ /* make both consistent, so that we can merge */ if (size > nextsize) { GC_remap((ptr_t)next, nextsize); + nexthdr -> hb_flags &= ~WAS_UNMAPPED; } else { GC_unmap((ptr_t)h, size); hhdr -> hb_flags |= WAS_UNMAPPED; Index: os_dep.c =================================================================== --- os_dep.c (revision 137556) +++ os_dep.c (working copy) @@ -1966,6 +1966,23 @@ # endif } +void GC_really_unmap(ptr_t start, word bytes) +{ + ptr_t start_addr = GC_unmap_start(start, bytes); + ptr_t end_addr = GC_unmap_end(start, bytes); + word len = end_addr - start_addr; + if (0 == start_addr) return; +# if defined(MSWIN32) || defined(MSWINCE) + /* No idea what to do here */ +# else + { + int result; + result = munmap(start_addr, len); + if (result != 0) ABORT("munmap() failed"); + } + GC_really_unmapped_bytes += len; +# endif +} #endif /* USE_MUNMAP */ /* Routine for pushing any additional roots. In THREADS */
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list