X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgencgc.c;h=8fbff436533129d466de13be43e7f94ac1982827;hb=63817d29028c8551cda23f432a3328acd7fdd62f;hp=9400f8c02a7c24aaeb2ed6c7b4890744abc23ff8;hpb=43b4fa80d2db2af986feafc08797917ab591806c;p=sbcl.git diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 9400f8c..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 *); @@ -1152,7 +1151,7 @@ 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_FLAG); @@ -1214,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 { @@ -1222,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; @@ -1246,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; @@ -1270,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)); @@ -1278,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); @@ -1296,7 +1294,7 @@ 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_FLAG) @@ -1354,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); @@ -1365,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; @@ -1421,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++) { @@ -1591,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", @@ -1650,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; @@ -1955,64 +1944,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; @@ -2023,7 +1982,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 @@ -2095,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 { @@ -2146,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", @@ -2345,7 +2306,7 @@ 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_FLAG) @@ -2562,7 +2523,7 @@ 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_FLAG); @@ -2901,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); } @@ -3160,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: @@ -3376,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) { @@ -4036,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; @@ -4086,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