X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgencgc.c;h=ea90e342c0687494f3b458d6e00c5d2ea58eb257;hb=ba4659ad35f28a8fefa4a10c3c7012e4ba50d683;hp=47eb8f3e54a86eb5530e6c1e3b45deaa6e1630a4;hpb=28a6fdf5f4ef6c63e1631b27e2650d928b9ba62e;p=sbcl.git diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 47eb8f3..ea90e34 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__) || defined(__NetBSD__) +/* 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; @@ -80,7 +94,11 @@ unsigned large_object_size = 4 * PAGE_BYTES; /* the verbosity level. All non-error messages are disabled at level 0; * and only a few rare messages are printed at level 1. */ -unsigned gencgc_verbose = (QSHOW ? 1 : 0); +#ifdef QSHOW +unsigned gencgc_verbose = 1; +#else +unsigned gencgc_verbose = 0; +#endif /* FIXME: At some point enable the various error-checking things below * and see what they say. */ @@ -139,7 +157,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)); @@ -281,7 +299,7 @@ count_generation_pages(int generation) return count; } -#if QSHOW +#ifdef QSHOW static int count_dont_move_pages(void) { @@ -1415,7 +1433,7 @@ sniff_code_object(struct code *code, unsigned displacement) unsigned d2 = *((unsigned char *)p - 2); unsigned d3 = *((unsigned char *)p - 3); unsigned d4 = *((unsigned char *)p - 4); -#if QSHOW +#ifdef QSHOW unsigned d5 = *((unsigned char *)p - 5); unsigned d6 = *((unsigned char *)p - 6); #endif @@ -1937,64 +1955,34 @@ scav_weak_pointer(lispobj *where, lispobj object) } -/* Scan an area looking for an object which encloses the given pointer. - * Return the object start on success or NULL on failure. */ -static lispobj * -search_space(lispobj *start, size_t words, lispobj *pointer) -{ - while (words > 0) { - size_t count = 1; - lispobj thing = *start; - - /* If thing is an immediate then this is a cons. */ - if (is_lisp_pointer(thing) - || ((thing & 3) == 0) /* fixnum */ - || (widetag_of(thing) == BASE_CHAR_WIDETAG) - || (widetag_of(thing) == UNBOUND_MARKER_WIDETAG)) - count = 2; - else - count = (sizetab[widetag_of(thing)])(start); - - /* Check whether the pointer is within this object. */ - if ((pointer >= start) && (pointer < (start+count))) { - /* found it! */ - /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/ - return(start); - } - - /* Round up the count. */ - count = CEILING(count,2); - - start += count; - words -= count; - } - return (NULL); -} - -lispobj* -search_read_only_space(lispobj *pointer) +lispobj * +search_read_only_space(void *pointer) { - lispobj* start = (lispobj*)READ_ONLY_SPACE_START; - lispobj* end = (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0); - if ((pointer < start) || (pointer >= end)) + lispobj *start = (lispobj *) READ_ONLY_SPACE_START; + lispobj *end = (lispobj *) SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0); + if ((pointer < (void *)start) || (pointer >= (void *)end)) return NULL; - return (search_space(start, (pointer+2)-start, pointer)); + return (search_space(start, + (((lispobj *)pointer)+2)-start, + (lispobj *) pointer)); } lispobj * -search_static_space(lispobj *pointer) +search_static_space(void *pointer) { - lispobj* start = (lispobj*)STATIC_SPACE_START; - lispobj* end = (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER,0); - if ((pointer < start) || (pointer >= end)) + lispobj *start = (lispobj *)STATIC_SPACE_START; + lispobj *end = (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER,0); + if ((pointer < (void *)start) || (pointer >= (void *)end)) return NULL; - return (search_space(start, (pointer+2)-start, pointer)); + return (search_space(start, + (((lispobj *)pointer)+2)-start, + (lispobj *) pointer)); } /* a faster version for searching the dynamic space. This will work even * if the object is in a current allocation region. */ lispobj * -search_dynamic_space(lispobj *pointer) +search_dynamic_space(void *pointer) { int page_index = find_page_index(pointer); lispobj *start; @@ -2005,7 +1993,9 @@ search_dynamic_space(lispobj *pointer) return NULL; start = (lispobj *)((void *)page_address(page_index) + page_table[page_index].first_object_offset); - return (search_space(start, (pointer+2)-start, pointer)); + return (search_space(start, + (((lispobj *)pointer)+2)-start, + (lispobj *)pointer)); } /* Is there any possibility that pointer is a valid Lisp object @@ -3001,8 +2991,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; @@ -3501,7 +3511,7 @@ garbage_collect_generation(int generation, int raise) } } -#if QSHOW +#ifdef QSHOW if (gencgc_verbose > 1) { int num_dont_move_pages = count_dont_move_pages(); fprintf(stderr, @@ -4048,29 +4058,6 @@ alloc(int nbytes) new_obj = gc_alloc_with_region(nbytes,0,region,0); return (new_obj); } - - -/* Find the code object for the given pc, or return NULL on failure. - * - * FIXME: PC shouldn't be lispobj*, should it? Maybe void*? */ -lispobj * -component_ptr_from_pc(lispobj *pc) -{ - lispobj *object = NULL; - - if ( (object = search_read_only_space(pc)) ) - ; - else if ( (object = search_static_space(pc)) ) - ; - else - object = search_dynamic_space(pc); - - if (object) /* if we found something */ - if (widetag_of(*object) == CODE_HEADER_WIDETAG) /* if it's a code object */ - return(object); - - return (NULL); -} /* * shared support for the OS-dependent signal handlers which @@ -4094,7 +4081,7 @@ gencgc_handle_wp_violation(void* fault_addr) { int page_index = find_page_index(fault_addr); -#if defined QSHOW_SIGNALS +#ifdef QSHOW_SIGNALS FSHOW((stderr, "heap WP violation? fault_addr=%x, page_index=%d\n", fault_addr, page_index)); #endif