X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fruntime%2Fgencgc.c;h=8fbff436533129d466de13be43e7f94ac1982827;hb=63817d29028c8551cda23f432a3328acd7fdd62f;hp=5914f6f62213e808b2a8d662eb28f06abe955f4a;hpb=60e88923a7610fa2cf6d5917707c149578776da2;p=sbcl.git diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 5914f6f..8fbff43 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -28,8 +28,8 @@ #include #include #include -#include "runtime.h" #include "sbcl.h" +#include "runtime.h" #include "os.h" #include "interr.h" #include "globals.h" @@ -37,6 +37,7 @@ #include "validate.h" #include "lispregs.h" #include "arch.h" +#include "fixnump.h" #include "gc.h" #include "gc-internal.h" #include "thread.h" @@ -49,8 +50,6 @@ void do_pending_interrupt(void); /* forward declarations */ int gc_find_freeish_pages(int *restart_page_ptr, int nbytes, int unboxed); -void gc_set_region_empty(struct alloc_region *region); -void gc_alloc_update_all_page_tables(void); static void gencgc_pickup_dynamic(void); boolean interrupt_maybe_gc_int(int, siginfo_t *, void *); @@ -69,7 +68,7 @@ boolean interrupt_maybe_gc_int(int, siginfo_t *, void *); boolean enable_page_protection = 1; /* Should we unmap a page and re-mmap it to have it zero filled? */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#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. * @@ -94,7 +93,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. */ @@ -274,7 +277,7 @@ count_write_protect_generation_pages(int generation) int count = 0; for (i = 0; i < last_free_page; i++) - if ((page_table[i].allocated != FREE_PAGE) + if ((page_table[i].allocated != FREE_PAGE_FLAG) && (page_table[i].gen == generation) && (page_table[i].write_protected == 1)) count++; @@ -295,7 +298,7 @@ count_generation_pages(int generation) return count; } -/* Count the number of dont_move pages. */ +#ifdef QSHOW static int count_dont_move_pages(void) { @@ -308,6 +311,7 @@ count_dont_move_pages(void) } return count; } +#endif /* QSHOW */ /* Work through the pages and add up the number of bytes used for the * given generation. */ @@ -372,7 +376,7 @@ print_generation_stats(int verbose) /* FIXME: should take FILE argument */ /* Count the number of boxed pages within the given * generation. */ - if (page_table[j].allocated & BOXED_PAGE) { + if (page_table[j].allocated & BOXED_PAGE_FLAG) { if (page_table[j].large_object) large_boxed_cnt++; else @@ -381,7 +385,7 @@ print_generation_stats(int verbose) /* FIXME: should take FILE argument */ if(page_table[j].dont_move) pinned_cnt++; /* Count the number of unboxed pages within the given * generation. */ - if (page_table[j].allocated & UNBOXED_PAGE) { + if (page_table[j].allocated & UNBOXED_PAGE_FLAG) { if (page_table[j].large_object) large_unboxed_cnt++; else @@ -533,35 +537,35 @@ gc_alloc_new_region(int nbytes, int unboxed, struct alloc_region *alloc_region) /* The first page may have already been in use. */ if (page_table[first_page].bytes_used == 0) { if (unboxed) - page_table[first_page].allocated = UNBOXED_PAGE; + page_table[first_page].allocated = UNBOXED_PAGE_FLAG; else - page_table[first_page].allocated = BOXED_PAGE; + page_table[first_page].allocated = BOXED_PAGE_FLAG; page_table[first_page].gen = gc_alloc_generation; page_table[first_page].large_object = 0; page_table[first_page].first_object_offset = 0; } if (unboxed) - gc_assert(page_table[first_page].allocated == UNBOXED_PAGE); + gc_assert(page_table[first_page].allocated == UNBOXED_PAGE_FLAG); else - gc_assert(page_table[first_page].allocated == BOXED_PAGE); - page_table[first_page].allocated |= OPEN_REGION_PAGE; + gc_assert(page_table[first_page].allocated == BOXED_PAGE_FLAG); + page_table[first_page].allocated |= OPEN_REGION_PAGE_FLAG; gc_assert(page_table[first_page].gen == gc_alloc_generation); gc_assert(page_table[first_page].large_object == 0); for (i = first_page+1; i <= last_page; i++) { if (unboxed) - page_table[i].allocated = UNBOXED_PAGE; + page_table[i].allocated = UNBOXED_PAGE_FLAG; else - page_table[i].allocated = BOXED_PAGE; + page_table[i].allocated = BOXED_PAGE_FLAG; page_table[i].gen = gc_alloc_generation; page_table[i].large_object = 0; /* This may not be necessary for unboxed regions (think it was * broken before!) */ page_table[i].first_object_offset = alloc_region->start_addr - page_address(i); - page_table[i].allocated |= OPEN_REGION_PAGE ; + page_table[i].allocated |= OPEN_REGION_PAGE_FLAG ; } /* Bump up last_free_page. */ if (last_page+1 > last_free_page) { @@ -722,12 +726,12 @@ gc_alloc_update_page_tables(int unboxed, struct alloc_region *alloc_region) * first_object_offset. */ if (page_table[first_page].bytes_used == 0) gc_assert(page_table[first_page].first_object_offset == 0); - page_table[first_page].allocated &= ~(OPEN_REGION_PAGE); + page_table[first_page].allocated &= ~(OPEN_REGION_PAGE_FLAG); if (unboxed) - gc_assert(page_table[first_page].allocated == UNBOXED_PAGE); + gc_assert(page_table[first_page].allocated == UNBOXED_PAGE_FLAG); else - gc_assert(page_table[first_page].allocated == BOXED_PAGE); + gc_assert(page_table[first_page].allocated == BOXED_PAGE_FLAG); gc_assert(page_table[first_page].gen == gc_alloc_generation); gc_assert(page_table[first_page].large_object == 0); @@ -748,11 +752,11 @@ gc_alloc_update_page_tables(int unboxed, struct alloc_region *alloc_region) * first_object_offset pointer to the start of the region, and set * the bytes_used. */ while (more) { - page_table[next_page].allocated &= ~(OPEN_REGION_PAGE); + page_table[next_page].allocated &= ~(OPEN_REGION_PAGE_FLAG); if (unboxed) - gc_assert(page_table[next_page].allocated == UNBOXED_PAGE); + gc_assert(page_table[next_page].allocated==UNBOXED_PAGE_FLAG); else - gc_assert(page_table[next_page].allocated == BOXED_PAGE); + gc_assert(page_table[next_page].allocated == BOXED_PAGE_FLAG); gc_assert(page_table[next_page].bytes_used == 0); gc_assert(page_table[next_page].gen == gc_alloc_generation); gc_assert(page_table[next_page].large_object == 0); @@ -800,15 +804,15 @@ gc_alloc_update_page_tables(int unboxed, struct alloc_region *alloc_region) } else { /* There are no bytes allocated. Unallocate the first_page if * there are 0 bytes_used. */ - page_table[first_page].allocated &= ~(OPEN_REGION_PAGE); + page_table[first_page].allocated &= ~(OPEN_REGION_PAGE_FLAG); if (page_table[first_page].bytes_used == 0) - page_table[first_page].allocated = FREE_PAGE; + page_table[first_page].allocated = FREE_PAGE_FLAG; } /* Unallocate any unused pages. */ while (next_page <= alloc_region->last_page) { gc_assert(page_table[next_page].bytes_used == 0); - page_table[next_page].allocated = FREE_PAGE; + page_table[next_page].allocated = FREE_PAGE_FLAG; next_page++; } release_spinlock(&free_pages_lock); @@ -858,18 +862,18 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region) * first_object_offset. */ if (page_table[first_page].bytes_used == 0) { if (unboxed) - page_table[first_page].allocated = UNBOXED_PAGE; + page_table[first_page].allocated = UNBOXED_PAGE_FLAG; else - page_table[first_page].allocated = BOXED_PAGE; + page_table[first_page].allocated = BOXED_PAGE_FLAG; page_table[first_page].gen = gc_alloc_generation; page_table[first_page].first_object_offset = 0; page_table[first_page].large_object = 1; } if (unboxed) - gc_assert(page_table[first_page].allocated == UNBOXED_PAGE); + gc_assert(page_table[first_page].allocated == UNBOXED_PAGE_FLAG); else - gc_assert(page_table[first_page].allocated == BOXED_PAGE); + gc_assert(page_table[first_page].allocated == BOXED_PAGE_FLAG); gc_assert(page_table[first_page].gen == gc_alloc_generation); gc_assert(page_table[first_page].large_object == 1); @@ -891,12 +895,12 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region) * first_object_offset pointer to the start of the region, and * set the bytes_used. */ while (more) { - gc_assert(page_table[next_page].allocated == FREE_PAGE); + gc_assert(page_table[next_page].allocated == FREE_PAGE_FLAG); gc_assert(page_table[next_page].bytes_used == 0); if (unboxed) - page_table[next_page].allocated = UNBOXED_PAGE; + page_table[next_page].allocated = UNBOXED_PAGE_FLAG; else - page_table[next_page].allocated = BOXED_PAGE; + page_table[next_page].allocated = BOXED_PAGE_FLAG; page_table[next_page].gen = gc_alloc_generation; page_table[next_page].large_object = 1; @@ -956,14 +960,14 @@ gc_find_freeish_pages(int *restart_page_ptr, int nbytes, int unboxed) first_page = restart_page; if (large_p) while ((first_page < NUM_PAGES) - && (page_table[first_page].allocated != FREE_PAGE)) + && (page_table[first_page].allocated != FREE_PAGE_FLAG)) first_page++; else while (first_page < NUM_PAGES) { - if(page_table[first_page].allocated == FREE_PAGE) + if(page_table[first_page].allocated == FREE_PAGE_FLAG) break; if((page_table[first_page].allocated == - (unboxed ? UNBOXED_PAGE : BOXED_PAGE)) && + (unboxed ? UNBOXED_PAGE_FLAG : BOXED_PAGE_FLAG)) && (page_table[first_page].large_object == 0) && (page_table[first_page].gen == gc_alloc_generation) && (page_table[first_page].bytes_used < (PAGE_BYTES-32)) && @@ -990,7 +994,7 @@ gc_find_freeish_pages(int *restart_page_ptr, int nbytes, int unboxed) while (((bytes_found < nbytes) || (!large_p && (num_pages < 2))) && (last_page < (NUM_PAGES-1)) - && (page_table[last_page+1].allocated == FREE_PAGE)) { + && (page_table[last_page+1].allocated == FREE_PAGE_FLAG)) { last_page++; num_pages++; bytes_found += PAGE_BYTES; @@ -1147,10 +1151,10 @@ copy_large_object(lispobj object, int nwords) gc_assert(page_table[first_page].first_object_offset == 0); next_page = first_page; - remaining_bytes = nwords*4; + remaining_bytes = nwords*N_WORD_BYTES; while (remaining_bytes > PAGE_BYTES) { gc_assert(page_table[next_page].gen == from_space); - gc_assert(page_table[next_page].allocated == BOXED_PAGE); + gc_assert(page_table[next_page].allocated == BOXED_PAGE_FLAG); gc_assert(page_table[next_page].large_object); gc_assert(page_table[next_page].first_object_offset== -PAGE_BYTES*(next_page-first_page)); @@ -1175,7 +1179,7 @@ copy_large_object(lispobj object, int nwords) gc_assert(page_table[next_page].bytes_used >= remaining_bytes); page_table[next_page].gen = new_space; - gc_assert(page_table[next_page].allocated == BOXED_PAGE); + gc_assert(page_table[next_page].allocated == BOXED_PAGE_FLAG); /* Adjust the bytes_used. */ old_bytes_used = page_table[next_page].bytes_used; @@ -1187,7 +1191,7 @@ copy_large_object(lispobj object, int nwords) next_page++; while ((old_bytes_used == PAGE_BYTES) && (page_table[next_page].gen == from_space) && - (page_table[next_page].allocated == BOXED_PAGE) && + (page_table[next_page].allocated == BOXED_PAGE_FLAG) && page_table[next_page].large_object && (page_table[next_page].first_object_offset == -(next_page - first_page)*PAGE_BYTES)) { @@ -1198,7 +1202,7 @@ copy_large_object(lispobj object, int nwords) gc_assert(page_table[next_page].write_protected == 0); old_bytes_used = page_table[next_page].bytes_used; - page_table[next_page].allocated = FREE_PAGE; + page_table[next_page].allocated = FREE_PAGE_FLAG; page_table[next_page].bytes_used = 0; bytes_freed += old_bytes_used; next_page++; @@ -1209,7 +1213,7 @@ copy_large_object(lispobj object, int nwords) bytes_allocated -= bytes_freed; /* Add the region to the new_areas if requested. */ - add_new_area(first_page,0,nwords*4); + add_new_area(first_page,0,nwords*N_WORD_BYTES); return(object); } else { @@ -1217,9 +1221,9 @@ copy_large_object(lispobj object, int nwords) tag = lowtag_of(object); /* Allocate space. */ - new = gc_quick_alloc_large(nwords*4); + new = gc_quick_alloc_large(nwords*N_WORD_BYTES); - memcpy(new,native_pointer(object),nwords*4); + memcpy(new,native_pointer(object),nwords*N_WORD_BYTES); /* Return Lisp pointer of new object. */ return ((lispobj) new) | tag; @@ -1241,9 +1245,9 @@ copy_unboxed_object(lispobj object, int nwords) tag = lowtag_of(object); /* Allocate space. */ - new = gc_quick_alloc_unboxed(nwords*4); + new = gc_quick_alloc_unboxed(nwords*N_WORD_BYTES); - memcpy(new,native_pointer(object),nwords*4); + memcpy(new,native_pointer(object),nwords*N_WORD_BYTES); /* Return Lisp pointer of new object. */ return ((lispobj) new) | tag; @@ -1265,7 +1269,6 @@ copy_large_unboxed_object(lispobj object, int nwords) { int tag; lispobj *new; - lispobj *source, *dest; int first_page; gc_assert(is_lisp_pointer(object)); @@ -1273,7 +1276,7 @@ copy_large_unboxed_object(lispobj object, int nwords) gc_assert((nwords & 0x01) == 0); if ((nwords > 1024*1024) && gencgc_verbose) - FSHOW((stderr, "/copy_large_unboxed_object: %d bytes\n", nwords*4)); + FSHOW((stderr, "/copy_large_unboxed_object: %d bytes\n", nwords*N_WORD_BYTES)); /* Check whether it's a large object. */ first_page = find_page_index((void *)object); @@ -1291,18 +1294,18 @@ copy_large_unboxed_object(lispobj object, int nwords) gc_assert(page_table[first_page].first_object_offset == 0); next_page = first_page; - remaining_bytes = nwords*4; + remaining_bytes = nwords*N_WORD_BYTES; while (remaining_bytes > PAGE_BYTES) { gc_assert(page_table[next_page].gen == from_space); - gc_assert((page_table[next_page].allocated == UNBOXED_PAGE) - || (page_table[next_page].allocated == BOXED_PAGE)); + gc_assert((page_table[next_page].allocated == UNBOXED_PAGE_FLAG) + || (page_table[next_page].allocated == BOXED_PAGE_FLAG)); gc_assert(page_table[next_page].large_object); gc_assert(page_table[next_page].first_object_offset== -PAGE_BYTES*(next_page-first_page)); gc_assert(page_table[next_page].bytes_used == PAGE_BYTES); page_table[next_page].gen = new_space; - page_table[next_page].allocated = UNBOXED_PAGE; + page_table[next_page].allocated = UNBOXED_PAGE_FLAG; remaining_bytes -= PAGE_BYTES; next_page++; } @@ -1314,7 +1317,7 @@ copy_large_unboxed_object(lispobj object, int nwords) gc_assert(page_table[next_page].bytes_used >= remaining_bytes); page_table[next_page].gen = new_space; - page_table[next_page].allocated = UNBOXED_PAGE; + page_table[next_page].allocated = UNBOXED_PAGE_FLAG; /* Adjust the bytes_used. */ old_bytes_used = page_table[next_page].bytes_used; @@ -1326,8 +1329,8 @@ copy_large_unboxed_object(lispobj object, int nwords) next_page++; while ((old_bytes_used == PAGE_BYTES) && (page_table[next_page].gen == from_space) && - ((page_table[next_page].allocated == UNBOXED_PAGE) - || (page_table[next_page].allocated == BOXED_PAGE)) && + ((page_table[next_page].allocated == UNBOXED_PAGE_FLAG) + || (page_table[next_page].allocated == BOXED_PAGE_FLAG)) && page_table[next_page].large_object && (page_table[next_page].first_object_offset == -(next_page - first_page)*PAGE_BYTES)) { @@ -1338,7 +1341,7 @@ copy_large_unboxed_object(lispobj object, int nwords) gc_assert(page_table[next_page].write_protected == 0); old_bytes_used = page_table[next_page].bytes_used; - page_table[next_page].allocated = FREE_PAGE; + page_table[next_page].allocated = FREE_PAGE_FLAG; page_table[next_page].bytes_used = 0; bytes_freed += old_bytes_used; next_page++; @@ -1349,8 +1352,8 @@ copy_large_unboxed_object(lispobj object, int nwords) "/copy_large_unboxed bytes_freed=%d\n", bytes_freed)); - generations[from_space].bytes_allocated -= 4*nwords + bytes_freed; - generations[new_space].bytes_allocated += 4*nwords; + generations[from_space].bytes_allocated -= nwords*N_WORD_BYTES + bytes_freed; + generations[new_space].bytes_allocated += nwords*N_WORD_BYTES; bytes_allocated -= bytes_freed; return(object); @@ -1360,19 +1363,10 @@ copy_large_unboxed_object(lispobj object, int nwords) tag = lowtag_of(object); /* Allocate space. */ - new = gc_quick_alloc_large_unboxed(nwords*4); - - dest = new; - source = (lispobj *) native_pointer(object); - - /* Copy the object. */ - while (nwords > 0) { - dest[0] = source[0]; - dest[1] = source[1]; - dest += 2; - source += 2; - nwords -= 2; - } + new = gc_quick_alloc_large_unboxed(nwords*N_WORD_BYTES); + + /* Copy the object. */ + memcpy(new,native_pointer(object),nwords*N_WORD_BYTES); /* Return Lisp pointer of new object. */ return ((lispobj) new) | tag; @@ -1416,10 +1410,10 @@ sniff_code_object(struct code *code, unsigned displacement) nheader_words = HeaderValue(*(lispobj *)code); nwords = ncode_words + nheader_words; - constants_start_addr = (void *)code + 5*4; - constants_end_addr = (void *)code + nheader_words*4; - code_start_addr = (void *)code + nheader_words*4; - code_end_addr = (void *)code + nwords*4; + constants_start_addr = (void *)code + 5*N_WORD_BYTES; + constants_end_addr = (void *)code + nheader_words*N_WORD_BYTES; + code_start_addr = (void *)code + nheader_words*N_WORD_BYTES; + code_end_addr = (void *)code + nwords*N_WORD_BYTES; /* Work through the unboxed code. */ for (p = code_start_addr; p < code_end_addr; p++) { @@ -1428,7 +1422,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 @@ -1586,10 +1580,10 @@ gencgc_apply_code_fixups(struct code *old_code, struct code *new_code) /* FSHOW((stderr, "/compiled code object at %x: header words = %d, code words = %d\n", new_code, nheader_words, ncode_words)); */ - constants_start_addr = (void *)new_code + 5*4; - constants_end_addr = (void *)new_code + nheader_words*4; - code_start_addr = (void *)new_code + nheader_words*4; - code_end_addr = (void *)new_code + nwords*4; + constants_start_addr = (void *)new_code + 5*N_WORD_BYTES; + constants_end_addr = (void *)new_code + nheader_words*N_WORD_BYTES; + code_start_addr = (void *)new_code + nheader_words*N_WORD_BYTES; + code_end_addr = (void *)new_code + nwords*N_WORD_BYTES; /* FSHOW((stderr, "/const start = %x, end = %x\n", @@ -1645,7 +1639,7 @@ gencgc_apply_code_fixups(struct code *old_code, struct code *new_code) /* If it's within the old_code object then it must be an * absolute fixup (relative ones are not saved) */ if ((old_value >= (unsigned)old_code) - && (old_value < ((unsigned)old_code + nwords*4))) + && (old_value < ((unsigned)old_code + nwords*N_WORD_BYTES))) /* So add the dispacement. */ *(unsigned *)((unsigned)code_start_addr + offset) = old_value + displacement; @@ -1950,74 +1944,47 @@ 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; /* The address may be invalid, so do some checks. */ - if ((page_index == -1) || (page_table[page_index].allocated == FREE_PAGE)) + if ((page_index == -1) || + (page_table[page_index].allocated == FREE_PAGE_FLAG)) 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 @@ -2089,12 +2056,12 @@ possibly_valid_dynamic_space_pointer(lispobj *pointer) } /* Is it plausible cons? */ if ((is_lisp_pointer(start_addr[0]) - || ((start_addr[0] & 3) == 0) /* fixnum */ - || (widetag_of(start_addr[0]) == BASE_CHAR_WIDETAG) + || (fixnump(start_addr[0])) + || (widetag_of(start_addr[0]) == CHARACTER_WIDETAG) || (widetag_of(start_addr[0]) == UNBOUND_MARKER_WIDETAG)) && (is_lisp_pointer(start_addr[1]) - || ((start_addr[1] & 3) == 0) /* fixnum */ - || (widetag_of(start_addr[1]) == BASE_CHAR_WIDETAG) + || (fixnump(start_addr[1])) + || (widetag_of(start_addr[1]) == CHARACTER_WIDETAG) || (widetag_of(start_addr[1]) == UNBOUND_MARKER_WIDETAG))) break; else { @@ -2140,7 +2107,7 @@ possibly_valid_dynamic_space_pointer(lispobj *pointer) } switch (widetag_of(start_addr[0])) { case UNBOUND_MARKER_WIDETAG: - case BASE_CHAR_WIDETAG: + case CHARACTER_WIDETAG: if (gencgc_verbose) FSHOW((stderr, "*Wo3: %x %x %x\n", @@ -2277,7 +2244,7 @@ maybe_adjust_large_object(lispobj *where) /* Check whether it's a vector or bignum object. */ switch (widetag_of(where[0])) { case SIMPLE_VECTOR_WIDETAG: - boxed = BOXED_PAGE; + boxed = BOXED_PAGE_FLAG; break; case BIGNUM_WIDETAG: case SIMPLE_BASE_STRING_WIDETAG: @@ -2318,7 +2285,7 @@ maybe_adjust_large_object(lispobj *where) #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG: #endif - boxed = UNBOXED_PAGE; + boxed = UNBOXED_PAGE_FLAG; break; default: return; @@ -2339,11 +2306,11 @@ maybe_adjust_large_object(lispobj *where) gc_assert(page_table[first_page].first_object_offset == 0); next_page = first_page; - remaining_bytes = nwords*4; + remaining_bytes = nwords*N_WORD_BYTES; while (remaining_bytes > PAGE_BYTES) { gc_assert(page_table[next_page].gen == from_space); - gc_assert((page_table[next_page].allocated == BOXED_PAGE) - || (page_table[next_page].allocated == UNBOXED_PAGE)); + gc_assert((page_table[next_page].allocated == BOXED_PAGE_FLAG) + || (page_table[next_page].allocated == UNBOXED_PAGE_FLAG)); gc_assert(page_table[next_page].large_object); gc_assert(page_table[next_page].first_object_offset == -PAGE_BYTES*(next_page-first_page)); @@ -2378,8 +2345,8 @@ maybe_adjust_large_object(lispobj *where) next_page++; while ((old_bytes_used == PAGE_BYTES) && (page_table[next_page].gen == from_space) && - ((page_table[next_page].allocated == UNBOXED_PAGE) - || (page_table[next_page].allocated == BOXED_PAGE)) && + ((page_table[next_page].allocated == UNBOXED_PAGE_FLAG) + || (page_table[next_page].allocated == BOXED_PAGE_FLAG)) && page_table[next_page].large_object && (page_table[next_page].first_object_offset == -(next_page - first_page)*PAGE_BYTES)) { @@ -2390,7 +2357,7 @@ maybe_adjust_large_object(lispobj *where) gc_assert(page_table[next_page].write_protected == 0); old_bytes_used = page_table[next_page].bytes_used; - page_table[next_page].allocated = FREE_PAGE; + page_table[next_page].allocated = FREE_PAGE_FLAG; page_table[next_page].bytes_used = 0; bytes_freed += old_bytes_used; next_page++; @@ -2430,13 +2397,13 @@ preserve_pointer(void *addr) /* quick check 1: Address is quite likely to have been invalid. */ if ((addr_page_index == -1) - || (page_table[addr_page_index].allocated == FREE_PAGE) + || (page_table[addr_page_index].allocated == FREE_PAGE_FLAG) || (page_table[addr_page_index].bytes_used == 0) || (page_table[addr_page_index].gen != from_space) /* Skip if already marked dont_move. */ || (page_table[addr_page_index].dont_move != 0)) return; - gc_assert(!(page_table[addr_page_index].allocated & OPEN_REGION_PAGE)); + gc_assert(!(page_table[addr_page_index].allocated&OPEN_REGION_PAGE_FLAG)); /* (Now that we know that addr_page_index is in range, it's * safe to index into page_table[] with it.) */ region_allocation = page_table[addr_page_index].allocated; @@ -2486,7 +2453,7 @@ preserve_pointer(void *addr) * free area in which case it's ignored here. Note it gets * through the valid pointer test above because the tail looks * like conses. */ - if ((page_table[addr_page_index].allocated == FREE_PAGE) + if ((page_table[addr_page_index].allocated == FREE_PAGE_FLAG) || (page_table[addr_page_index].bytes_used == 0) /* Check the offset within the page. */ || (((unsigned)addr & (PAGE_BYTES - 1)) @@ -2525,7 +2492,7 @@ preserve_pointer(void *addr) /* Check whether this is the last page in this contiguous block.. */ if ((page_table[i].bytes_used < PAGE_BYTES) /* ..or it is PAGE_BYTES and is the last in the block */ - || (page_table[i+1].allocated == FREE_PAGE) + || (page_table[i+1].allocated == FREE_PAGE_FLAG) || (page_table[i+1].bytes_used == 0) /* next page free */ || (page_table[i+1].gen != from_space) /* diff. gen */ || (page_table[i+1].first_object_offset == 0)) @@ -2556,16 +2523,16 @@ update_page_write_prot(int page) int j; int wp_it = 1; void **page_addr = (void **)page_address(page); - int num_words = page_table[page].bytes_used / 4; + int num_words = page_table[page].bytes_used / N_WORD_BYTES; /* Shouldn't be a free page. */ - gc_assert(page_table[page].allocated != FREE_PAGE); + gc_assert(page_table[page].allocated != FREE_PAGE_FLAG); gc_assert(page_table[page].bytes_used != 0); /* Skip if it's already write-protected, pinned, or unboxed */ if (page_table[page].write_protected || page_table[page].dont_move - || (page_table[page].allocated & UNBOXED_PAGE)) + || (page_table[page].allocated & UNBOXED_PAGE_FLAG)) return (0); /* Scan the page for pointers to younger generations or the @@ -2578,7 +2545,7 @@ update_page_write_prot(int page) /* Check that it's in the dynamic space */ if (index != -1) if (/* Does it point to a younger or the temp. generation? */ - ((page_table[index].allocated != FREE_PAGE) + ((page_table[index].allocated != FREE_PAGE_FLAG) && (page_table[index].bytes_used != 0) && ((page_table[index].gen < gen) || (page_table[index].gen == NUM_GENERATIONS))) @@ -2653,7 +2620,7 @@ scavenge_generation(int generation) #endif for (i = 0; i < last_free_page; i++) { - if ((page_table[i].allocated & BOXED_PAGE) + if ((page_table[i].allocated & BOXED_PAGE_FLAG) && (page_table[i].bytes_used != 0) && (page_table[i].gen == generation)) { int last_page,j; @@ -2668,7 +2635,7 @@ scavenge_generation(int generation) write_protected && page_table[last_page].write_protected; if ((page_table[last_page].bytes_used < PAGE_BYTES) /* Or it is PAGE_BYTES and is the last in the block */ - || (!(page_table[last_page+1].allocated & BOXED_PAGE)) + || (!(page_table[last_page+1].allocated & BOXED_PAGE_FLAG)) || (page_table[last_page+1].bytes_used == 0) || (page_table[last_page+1].gen != generation) || (page_table[last_page+1].first_object_offset == 0)) @@ -2699,7 +2666,7 @@ scavenge_generation(int generation) /* Check that none of the write_protected pages in this generation * have been written to. */ for (i = 0; i < NUM_PAGES; i++) { - if ((page_table[i].allocation ! =FREE_PAGE) + if ((page_table[i].allocation != FREE_PAGE_FLAG) && (page_table[i].bytes_used != 0) && (page_table[i].gen == generation) && (page_table[i].write_protected_cleared != 0)) { @@ -2752,8 +2719,8 @@ scavenge_newspace_generation_one_scan(int generation) "/starting one full scan of newspace generation %d\n", generation)); for (i = 0; i < last_free_page; i++) { - /* note that this skips over open regions when it encounters them */ - if ((page_table[i].allocated & BOXED_PAGE) + /* Note that this skips over open regions when it encounters them. */ + if ((page_table[i].allocated & BOXED_PAGE_FLAG) && (page_table[i].bytes_used != 0) && (page_table[i].gen == generation) && ((page_table[i].write_protected == 0) @@ -2781,7 +2748,7 @@ scavenge_newspace_generation_one_scan(int generation) * contiguous block */ if ((page_table[last_page].bytes_used < PAGE_BYTES) /* Or it is PAGE_BYTES and is the last in the block */ - || (!(page_table[last_page+1].allocated & BOXED_PAGE)) + || (!(page_table[last_page+1].allocated & BOXED_PAGE_FLAG)) || (page_table[last_page+1].bytes_used == 0) || (page_table[last_page+1].gen != generation) || (page_table[last_page+1].first_object_offset == 0)) @@ -2895,12 +2862,10 @@ scavenge_newspace_generation(int generation) /* Work through previous_new_areas. */ for (i = 0; i < previous_new_areas_index; i++) { - /* FIXME: All these bare *4 and /4 should be something - * like BYTES_PER_WORD or WBYTES. */ int page = (*previous_new_areas)[i].page; int offset = (*previous_new_areas)[i].offset; - int size = (*previous_new_areas)[i].size / 4; - gc_assert((*previous_new_areas)[i].size % 4 == 0); + int size = (*previous_new_areas)[i].size / N_WORD_BYTES; + gc_assert((*previous_new_areas)[i].size % N_WORD_BYTES == 0); scavenge(page_address(page)+offset, size); } @@ -2922,7 +2887,7 @@ scavenge_newspace_generation(int generation) /* Check that none of the write_protected pages in this generation * have been written to. */ for (i = 0; i < NUM_PAGES; i++) { - if ((page_table[i].allocation != FREE_PAGE) + if ((page_table[i].allocation != FREE_PAGE_FLAG) && (page_table[i].bytes_used != 0) && (page_table[i].gen == generation) && (page_table[i].write_protected_cleared != 0) @@ -2945,7 +2910,7 @@ unprotect_oldspace(void) int i; for (i = 0; i < last_free_page; i++) { - if ((page_table[i].allocated != FREE_PAGE) + if ((page_table[i].allocated != FREE_PAGE_FLAG) && (page_table[i].bytes_used != 0) && (page_table[i].gen == from_space)) { void *page_start; @@ -2966,7 +2931,6 @@ unprotect_oldspace(void) * assumes that all objects have been copied or promoted to an older * generation. Bytes_allocated and the generation bytes_allocated * counter are updated. The number of bytes freed is returned. */ -extern void i586_bzero(void *addr, int nbytes); static int free_oldspace(void) { @@ -2978,7 +2942,7 @@ free_oldspace(void) do { /* Find a first page for the next region of pages. */ while ((first_page < last_free_page) - && ((page_table[first_page].allocated == FREE_PAGE) + && ((page_table[first_page].allocated == FREE_PAGE_FLAG) || (page_table[first_page].bytes_used == 0) || (page_table[first_page].gen != from_space))) first_page++; @@ -2994,7 +2958,7 @@ free_oldspace(void) bytes_freed += page_table[last_page].bytes_used; generations[page_table[last_page].gen].bytes_allocated -= page_table[last_page].bytes_used; - page_table[last_page].allocated = FREE_PAGE; + page_table[last_page].allocated = FREE_PAGE_FLAG; page_table[last_page].bytes_used = 0; /* Remove any write-protection. We should be able to rely @@ -3010,7 +2974,7 @@ free_oldspace(void) last_page++; } while ((last_page < last_free_page) - && (page_table[last_page].allocated != FREE_PAGE) + && (page_table[last_page].allocated != FREE_PAGE_FLAG) && (page_table[last_page].bytes_used != 0) && (page_table[last_page].gen == from_space)); @@ -3027,23 +2991,14 @@ free_oldspace(void) 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) { - /* Is this an error condition? I couldn't really tell from - * the old CMU CL code, which fprintf'ed a message with - * an exclamation point at the end. But I've never seen the - * message, so it must at least be unusual.. - * - * (The same condition is also tested for in gc_free_heap.) - * - * -- WHN 19991129 */ - lose("i586_bzero: page moved, 0x%08x ==> 0x%08x", - 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); - i586_bzero(page_start, PAGE_BYTES*(last_page-first_page)); + memset(page_start, 0,PAGE_BYTES*(last_page-first_page)); } first_page = last_page; @@ -3111,7 +3066,7 @@ verify_space(lispobj *start, size_t words) if (page_index != -1) { /* If it's within the dynamic space it should point to a used * page. XX Could check the offset too. */ - if ((page_table[page_index].allocated != FREE_PAGE) + if ((page_table[page_index].allocated != FREE_PAGE_FLAG) && (page_table[page_index].bytes_used == 0)) lose ("Ptr %x @ %x sees free page.", thing, start); /* Check that it doesn't point to a forwarding pointer! */ @@ -3164,7 +3119,7 @@ verify_space(lispobj *start, size_t words) case FUNCALLABLE_INSTANCE_HEADER_WIDETAG: case VALUE_CELL_HEADER_WIDETAG: case SYMBOL_HEADER_WIDETAG: - case BASE_CHAR_WIDETAG: + case CHARACTER_WIDETAG: case UNBOUND_MARKER_WIDETAG: case INSTANCE_HEADER_WIDETAG: case FDEFN_WIDETAG: @@ -3326,7 +3281,7 @@ verify_generation(int generation) int i; for (i = 0; i < last_free_page; i++) { - if ((page_table[i].allocated != FREE_PAGE) + if ((page_table[i].allocated != FREE_PAGE_FLAG) && (page_table[i].bytes_used != 0) && (page_table[i].gen == generation)) { int last_page; @@ -3365,7 +3320,7 @@ verify_zero_fill(void) int page; for (page = 0; page < last_free_page; page++) { - if (page_table[page].allocated == FREE_PAGE) { + if (page_table[page].allocated == FREE_PAGE_FLAG) { /* The whole page should be zero filled. */ int *start_addr = (int *)page_address(page); int size = 1024; @@ -3380,7 +3335,7 @@ verify_zero_fill(void) if (free_bytes > 0) { int *start_addr = (int *)((unsigned)page_address(page) + page_table[page].bytes_used); - int size = free_bytes / 4; + int size = free_bytes / N_WORD_BYTES; int i; for (i = 0; i < size; i++) { if (start_addr[i] != 0) { @@ -3423,7 +3378,7 @@ write_protect_generation_pages(int generation) gc_assert(generation < NUM_GENERATIONS); for (i = 0; i < last_free_page; i++) - if ((page_table[i].allocated == BOXED_PAGE) + if ((page_table[i].allocated == BOXED_PAGE_FLAG) && (page_table[i].bytes_used != 0) && !page_table[i].dont_move && (page_table[i].gen == generation)) { @@ -3517,8 +3472,8 @@ garbage_collect_generation(int generation, int raise) for_each_thread(th) { void **ptr; void **esp=(void **)-1; - int i,free; #ifdef LISP_FEATURE_SB_THREAD + int i,free; if(th==arch_os_get_current_thread()) { esp = (void **) &raise; } else { @@ -3543,7 +3498,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, @@ -3708,7 +3663,7 @@ update_x86_dynamic_space_free_pointer(void) int i; for (i = 0; i < NUM_PAGES; i++) - if ((page_table[i].allocated != FREE_PAGE) + if ((page_table[i].allocated != FREE_PAGE_FLAG) && (page_table[i].bytes_used != 0)) last_page = i; @@ -3859,15 +3814,15 @@ gc_free_heap(void) for (page = 0; page < NUM_PAGES; page++) { /* Skip free pages which should already be zero filled. */ - if (page_table[page].allocated != FREE_PAGE) { + if (page_table[page].allocated != FREE_PAGE_FLAG) { void *page_start, *addr; /* Mark the page free. The other slots are assumed invalid - * when it is a FREE_PAGE and bytes_used is 0 and it + * when it is a FREE_PAGE_FLAG and bytes_used is 0 and it * should not be write-protected -- except that the * generation is used for the current region but it sets * that up. */ - page_table[page].allocated = FREE_PAGE; + page_table[page].allocated = FREE_PAGE_FLAG; page_table[page].bytes_used = 0; /* Zero the page. */ @@ -3887,7 +3842,7 @@ gc_free_heap(void) } else if (gencgc_zero_check_during_free_heap) { /* Double-check that the page is zero filled. */ int *page_start, i; - gc_assert(page_table[page].allocated == FREE_PAGE); + gc_assert(page_table[page].allocated == FREE_PAGE_FLAG); gc_assert(page_table[page].bytes_used == 0); page_start = (int *)page_address(page); for (i=0; i<1024; i++) { @@ -3947,7 +3902,7 @@ gc_init(void) /* Initialize each page structure. */ for (i = 0; i < NUM_PAGES; i++) { /* Initialize all pages as free. */ - page_table[i].allocated = FREE_PAGE; + page_table[i].allocated = FREE_PAGE_FLAG; page_table[i].bytes_used = 0; /* Pages are not write-protected at startup. */ @@ -3997,7 +3952,7 @@ gencgc_pickup_dynamic(void) do { lispobj *first,*ptr= (lispobj *)page_address(page); - page_table[page].allocated = BOXED_PAGE; + page_table[page].allocated = BOXED_PAGE_FLAG; page_table[page].gen = 0; page_table[page].bytes_used = PAGE_BYTES; page_table[page].large_object = 0; @@ -4040,8 +3995,12 @@ char * alloc(int nbytes) { struct thread *th=arch_os_get_current_thread(); - struct alloc_region *region= + struct alloc_region *region= +#ifdef LISP_FEATURE_SB_THREAD th ? &(th->alloc_region) : &boxed_region; +#else + &boxed_region; +#endif void *new_obj; void *new_free_pointer; @@ -4090,29 +4049,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 @@ -4136,7 +4072,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