From 3169528be99df0860cd86ebd821b04c5018bf014 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Tue, 6 Apr 2004 22:21:19 +0000 Subject: [PATCH] 0.8.9.24 Restore the unmap/remap-to-zero-pages behaviour that was in versions prior to 0.8.9.20; it works a lot better on machines without Far Too Much Memory --- src/runtime/gencgc.c | 40 +++++++++++++++++++++++++++++++++++++--- src/runtime/os-common.c | 31 +++++++++++++++++++++++++++++-- version.lisp-expr | 2 +- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 47eb8f3..189a3b1 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -68,6 +68,20 @@ boolean interrupt_maybe_gc_int(int, siginfo_t *, void *); * that don't have pointers to younger generations? */ boolean enable_page_protection = 1; +/* Should we unmap a page and re-mmap it to have it zero filled? */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +/* comment from cmucl-2.4.8: This can waste a lot of swap on FreeBSD + * so don't unmap there. + * + * The CMU CL comment didn't specify a version, but was probably an + * old version of FreeBSD (pre-4.0), so this might no longer be true. + * OTOH, if it is true, this behavior might exist on OpenBSD too, so + * for now we don't unmap there either. -- WHN 2001-04-07 */ +boolean gencgc_unmap_zero = 0; +#else +boolean gencgc_unmap_zero = 1; +#endif + /* the minimum size (in bytes) for a large object*/ unsigned large_object_size = 4 * PAGE_BYTES; @@ -139,7 +153,7 @@ static void *heap_base = NULL; /* Calculate the start address for the given page number. */ -static inline void * +inline void * page_address(int page_num) { return (heap_base + (page_num * PAGE_BYTES)); @@ -3001,8 +3015,28 @@ free_oldspace(void) && (page_table[last_page].bytes_used != 0) && (page_table[last_page].gen == from_space)); - /* Zero pages from first_page to (last_page-1). */ - memset(page_address(first_page), 0, PAGE_BYTES*(last_page-first_page)); + /* Zero pages from first_page to (last_page-1). + * + * FIXME: Why not use os_zero(..) function instead of + * hand-coding this again? (Check other gencgc_unmap_zero + * stuff too. */ + if (gencgc_unmap_zero) { + void *page_start, *addr; + + page_start = (void *)page_address(first_page); + + os_invalidate(page_start, PAGE_BYTES*(last_page-first_page)); + addr = os_validate(page_start, PAGE_BYTES*(last_page-first_page)); + if (addr == NULL || addr != page_start) { + lose("free_oldspace: page moved, 0x%08x ==> 0x%08x",page_start, + addr); + } + } else { + int *page_start; + + page_start = (int *)page_address(first_page); + memset(page_start, 0,PAGE_BYTES*(last_page-first_page)); + } first_page = last_page; diff --git a/src/runtime/os-common.c b/src/runtime/os-common.c index 842781a..bb09a24 100644 --- a/src/runtime/os-common.c +++ b/src/runtime/os-common.c @@ -22,11 +22,38 @@ * instead. See hpux-os.c for some useful restrictions on actual * usage. */ -/* FIXME: this should be turned into a pure inline memset where it is used. */ void os_zero(os_vm_address_t addr, os_vm_size_t length) { - memset(addr, 0, length); + os_vm_address_t block_start; + os_vm_size_t block_size; + +#ifdef DEBUG + fprintf(stderr,";;; os_zero: addr: 0x%08x, len: 0x%08x\n",addr,length); +#endif + + block_start = os_round_up_to_page(addr); + + length -= block_start-addr; + block_size = os_trunc_size_to_page(length); + + if (block_start > addr) + bzero((char *)addr, block_start-addr); + if (block_size < length) + bzero((char *)block_start+block_size, length-block_size); + + if (block_size != 0) { + /* Now deallocate and allocate the block so that it faults in + * zero-filled. */ + + os_invalidate(block_start, block_size); + addr = os_validate(block_start, block_size); + + if (addr == NULL || addr != block_start) + lose("os_zero: block moved! 0x%08x ==> 0x%08x", + block_start, + addr); + } } os_vm_address_t diff --git a/version.lisp-expr b/version.lisp-expr index 0915947..9979de3 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.8.9.23" +"0.8.9.24" -- 1.7.10.4