X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgc-common.c;h=251aa6a7b2394ec0b1b2324748c9882a0ad71176;hb=be7adb92bf0012ab07adac2943e73772dfad7911;hp=a7d203417a93a4c76517f6a8f45a72f362917ce1;hpb=457d80803848ccd73b28508177f1888ff66bc72f;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index a7d2034..251aa6a 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -1,5 +1,5 @@ /* - * Garbage Collection common functions for scavenging, moving and sizing + * Garbage Collection common functions for scavenging, moving and sizing * objects. These are for use with both GC (stop & copy GC) and GENCGC */ @@ -41,6 +41,7 @@ #include "gc.h" #include "genesis/primitive-objects.h" #include "genesis/static-symbols.h" +#include "genesis/layout.h" #include "gc-internal.h" #ifdef LISP_FEATURE_SPARC @@ -51,14 +52,14 @@ #endif #endif -inline static boolean +inline static boolean forwarding_pointer_p(lispobj *pointer) { - lispobj first_word=*pointer; + lispobj first_word=*pointer; #ifdef LISP_FEATURE_GENCGC return (first_word == 0x01); #else return (is_lisp_pointer(first_word) - && new_space_p(first_word)); + && new_space_p(first_word)); #endif } @@ -81,9 +82,9 @@ set_forwarding_pointer(lispobj * pointer, lispobj newspace_copy) { return newspace_copy; } -int (*scavtab[256])(lispobj *where, lispobj object); +long (*scavtab[256])(lispobj *where, lispobj object); lispobj (*transother[256])(lispobj object); -int (*sizetab[256])(lispobj *where); +long (*sizetab[256])(lispobj *where); struct weak_pointer *weak_pointers; unsigned long bytes_consed_between_gcs = 12*1024*1024; @@ -95,7 +96,7 @@ unsigned long bytes_consed_between_gcs = 12*1024*1024; /* to copy a boxed object */ lispobj -copy_object(lispobj object, int nwords) +copy_object(lispobj object, long nwords) { int tag; lispobj *new; @@ -115,7 +116,7 @@ copy_object(lispobj object, int nwords) return make_lispobj(new,tag); } -static int scav_lose(lispobj *where, lispobj object); /* forward decl */ +static long scav_lose(lispobj *where, lispobj object); /* forward decl */ /* FIXME: Most calls end up going to some trouble to compute an * 'n_words' value for this function. The system might be a little @@ -125,65 +126,66 @@ scavenge(lispobj *start, long n_words) { lispobj *end = start + n_words; lispobj *object_ptr; - int n_words_scavenged; + long n_words_scavenged; for (object_ptr = start; - object_ptr < end; - object_ptr += n_words_scavenged) { - lispobj object = *object_ptr; + object_ptr < end; + object_ptr += n_words_scavenged) { + + lispobj object = *object_ptr; #ifdef LISP_FEATURE_GENCGC - gc_assert(!forwarding_pointer_p(object_ptr)); -#endif - if (is_lisp_pointer(object)) { - if (from_space_p(object)) { - /* It currently points to old space. Check for a - * forwarding pointer. */ - lispobj *ptr = native_pointer(object); - if (forwarding_pointer_p(ptr)) { - /* Yes, there's a forwarding pointer. */ - *object_ptr = LOW_WORD(forwarding_pointer_value(ptr)); - n_words_scavenged = 1; - } else { - /* Scavenge that pointer. */ - n_words_scavenged = - (scavtab[widetag_of(object)])(object_ptr, object); - } - } else { - /* It points somewhere other than oldspace. Leave it - * alone. */ - n_words_scavenged = 1; - } - } + gc_assert(!forwarding_pointer_p(object_ptr)); +#endif + if (is_lisp_pointer(object)) { + if (from_space_p(object)) { + /* It currently points to old space. Check for a + * forwarding pointer. */ + lispobj *ptr = native_pointer(object); + if (forwarding_pointer_p(ptr)) { + /* Yes, there's a forwarding pointer. */ + *object_ptr = LOW_WORD(forwarding_pointer_value(ptr)); + n_words_scavenged = 1; + } else { + /* Scavenge that pointer. */ + n_words_scavenged = + (scavtab[widetag_of(object)])(object_ptr, object); + } + } else { + /* It points somewhere other than oldspace. Leave it + * alone. */ + n_words_scavenged = 1; + } + } #ifndef LISP_FEATURE_GENCGC - /* this workaround is probably not necessary for gencgc; at least, the - * behaviour it describes has never been reported */ - else if (n_words==1) { - /* there are some situations where an - other-immediate may end up in a descriptor - register. I'm not sure whether this is - supposed to happen, but if it does then we - don't want to (a) barf or (b) scavenge over the - data-block, because there isn't one. So, if - we're checking a single word and it's anything - other than a pointer, just hush it up */ - int type=widetag_of(object); - n_words_scavenged=1; - - if ((scavtab[type]==scav_lose) || - (((scavtab[type])(start,object))>1)) { - fprintf(stderr,"warning: attempted to scavenge non-descriptor value %x at %p. If you can\nreproduce this warning, send a bug report (see manual page for details)\n", - object,start); - } - } -#endif - else if (fixnump(object)) { - /* It's a fixnum: really easy.. */ - n_words_scavenged = 1; - } else { - /* It's some sort of header object or another. */ - n_words_scavenged = - (scavtab[widetag_of(object)])(object_ptr, object); - } + /* this workaround is probably not necessary for gencgc; at least, the + * behaviour it describes has never been reported */ + else if (n_words==1) { + /* there are some situations where an + other-immediate may end up in a descriptor + register. I'm not sure whether this is + supposed to happen, but if it does then we + don't want to (a) barf or (b) scavenge over the + data-block, because there isn't one. So, if + we're checking a single word and it's anything + other than a pointer, just hush it up */ + int type=widetag_of(object); + n_words_scavenged=1; + + if ((scavtab[type]==scav_lose) || + (((scavtab[type])(start,object))>1)) { + fprintf(stderr,"warning: attempted to scavenge non-descriptor value %x at %p. If you can\nreproduce this warning, send a bug report (see manual page for details)\n", + object,start); + } + } +#endif + else if (fixnump(object)) { + /* It's a fixnum: really easy.. */ + n_words_scavenged = 1; + } else { + /* It's some sort of header object or another. */ + n_words_scavenged = + (scavtab[widetag_of(object)])(object_ptr, object); + } } gc_assert(object_ptr == end); } @@ -191,7 +193,7 @@ scavenge(lispobj *start, long n_words) static lispobj trans_fun_header(lispobj object); /* forward decls */ static lispobj trans_boxed(lispobj object); -static int +static long scav_fun_pointer(lispobj *where, lispobj object) { lispobj *first_pointer; @@ -207,16 +209,16 @@ scav_fun_pointer(lispobj *where, lispobj object) switch (widetag_of(*first_pointer)) { case SIMPLE_FUN_HEADER_WIDETAG: - copy = trans_fun_header(object); - break; + copy = trans_fun_header(object); + break; default: - copy = trans_boxed(object); - break; + copy = trans_boxed(object); + break; } if (copy != object) { - /* Set forwarding pointer */ - set_forwarding_pointer(first_pointer,copy); + /* Set forwarding pointer */ + set_forwarding_pointer(first_pointer,copy); } gc_assert(is_lisp_pointer(copy)); @@ -233,7 +235,7 @@ trans_code(struct code *code) { struct code *new_code; lispobj first, l_code, l_new_code; - int nheader_words, ncode_words, nwords; + long nheader_words, ncode_words, nwords; unsigned long displacement; lispobj fheaderl, *prev_pointer; @@ -241,12 +243,12 @@ trans_code(struct code *code) first = code->header; if (forwarding_pointer_p((lispobj *)code)) { #ifdef DEBUG_CODE_GC - printf("Was already transported\n"); + printf("Was already transported\n"); #endif - return (struct code *) forwarding_pointer_value - ((lispobj *)((pointer_sized_uint_t) code)); + return (struct code *) forwarding_pointer_value + ((lispobj *)((pointer_sized_uint_t) code)); } - + gc_assert(widetag_of(first) == CODE_HEADER_WIDETAG); /* prepare to transport the code vector */ @@ -262,19 +264,19 @@ trans_code(struct code *code) #if defined(DEBUG_CODE_GC) printf("Old code object at 0x%08x, new code object at 0x%08x.\n", - (unsigned long) code, (unsigned long) new_code); + (unsigned long) code, (unsigned long) new_code); printf("Code object is %d words long.\n", nwords); #endif #ifdef LISP_FEATURE_GENCGC if (new_code == code) - return new_code; + return new_code; #endif displacement = l_new_code - l_code; set_forwarding_pointer((lispobj *)code, l_new_code); - + /* set forwarding pointers for all the function headers in the */ /* code object. also fix all self pointers */ @@ -282,49 +284,49 @@ trans_code(struct code *code) prev_pointer = &new_code->entry_points; while (fheaderl != NIL) { - struct simple_fun *fheaderp, *nfheaderp; - lispobj nfheaderl; - - fheaderp = (struct simple_fun *) native_pointer(fheaderl); - gc_assert(widetag_of(fheaderp->header) == SIMPLE_FUN_HEADER_WIDETAG); + struct simple_fun *fheaderp, *nfheaderp; + lispobj nfheaderl; + + fheaderp = (struct simple_fun *) native_pointer(fheaderl); + gc_assert(widetag_of(fheaderp->header) == SIMPLE_FUN_HEADER_WIDETAG); - /* Calculate the new function pointer and the new */ - /* function header. */ - nfheaderl = fheaderl + displacement; - nfheaderp = (struct simple_fun *) native_pointer(nfheaderl); + /* Calculate the new function pointer and the new */ + /* function header. */ + nfheaderl = fheaderl + displacement; + nfheaderp = (struct simple_fun *) native_pointer(nfheaderl); #ifdef DEBUG_CODE_GC - printf("fheaderp->header (at %x) <- %x\n", - &(fheaderp->header) , nfheaderl); + printf("fheaderp->header (at %x) <- %x\n", + &(fheaderp->header) , nfheaderl); #endif - set_forwarding_pointer((lispobj *)fheaderp, nfheaderl); - - /* fix self pointer. */ - nfheaderp->self = -#ifdef LISP_FEATURE_X86 - FUN_RAW_ADDR_OFFSET + + set_forwarding_pointer((lispobj *)fheaderp, nfheaderl); + + /* fix self pointer. */ + nfheaderp->self = +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) + FUN_RAW_ADDR_OFFSET + #endif - nfheaderl; - - *prev_pointer = nfheaderl; + nfheaderl; + + *prev_pointer = nfheaderl; - fheaderl = fheaderp->next; - prev_pointer = &nfheaderp->next; + fheaderl = fheaderp->next; + prev_pointer = &nfheaderp->next; } - os_flush_icache((os_vm_address_t) (((int *)new_code) + nheader_words), - ncode_words * sizeof(int)); + os_flush_icache((os_vm_address_t) (((long *)new_code) + nheader_words), + ncode_words * sizeof(long)); #ifdef LISP_FEATURE_GENCGC gencgc_apply_code_fixups(code, new_code); #endif return new_code; } -static int +static long scav_code_header(lispobj *where, lispobj object) { struct code *code; - int n_header_words, n_code_words, n_words; - lispobj entry_point; /* tagged pointer to entry point */ + long n_header_words, n_code_words, n_words; + lispobj entry_point; /* tagged pointer to entry point */ struct simple_fun *function_ptr; /* untagged pointer to entry point */ code = (struct code *) where; @@ -339,19 +341,19 @@ scav_code_header(lispobj *where, lispobj object) /* Scavenge the boxed section of each function object in the * code data block. */ for (entry_point = code->entry_points; - entry_point != NIL; - entry_point = function_ptr->next) { + entry_point != NIL; + entry_point = function_ptr->next) { - gc_assert(is_lisp_pointer(entry_point)); + gc_assert(is_lisp_pointer(entry_point)); - function_ptr = (struct simple_fun *) native_pointer(entry_point); - gc_assert(widetag_of(function_ptr->header)==SIMPLE_FUN_HEADER_WIDETAG); + function_ptr = (struct simple_fun *) native_pointer(entry_point); + gc_assert(widetag_of(function_ptr->header)==SIMPLE_FUN_HEADER_WIDETAG); - scavenge(&function_ptr->name, 1); - scavenge(&function_ptr->arglist, 1); - scavenge(&function_ptr->type, 1); + scavenge(&function_ptr->name, 1); + scavenge(&function_ptr->arglist, 1); + scavenge(&function_ptr->type, 1); } - + return n_words; } @@ -365,14 +367,14 @@ trans_code_header(lispobj object) } -static int +static long size_code_header(lispobj *where) { struct code *code; - int nheader_words, ncode_words, nwords; + long nheader_words, ncode_words, nwords; code = (struct code *) where; - + ncode_words = fixnum_value(code->code_size); nheader_words = HeaderValue(code->header); nwords = ncode_words + nheader_words; @@ -381,13 +383,13 @@ size_code_header(lispobj *where) return nwords; } -#ifndef LISP_FEATURE_X86 -static int +#if !defined(LISP_FEATURE_X86) && ! defined(LISP_FEATURE_X86_64) +static long scav_return_pc_header(lispobj *where, lispobj object) { lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x", - (unsigned long) where, - (unsigned long) object); + (unsigned long) where, + (unsigned long) object); return 0; /* bogus return value to satisfy static type checking */ } #endif /* LISP_FEATURE_X86 */ @@ -416,8 +418,8 @@ trans_return_pc_header(lispobj object) * objects don't move, we don't need to update anything, but we do * have to figure out that the function is still live. */ -#ifdef LISP_FEATURE_X86 -static int +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) +static long scav_closure_header(lispobj *where, lispobj object) { struct closure *closure; @@ -430,19 +432,19 @@ scav_closure_header(lispobj *where, lispobj object) /* The function may have moved so update the raw address. But * don't write unnecessarily. */ if (closure->fun != fun + FUN_RAW_ADDR_OFFSET) - closure->fun = fun + FUN_RAW_ADDR_OFFSET; + closure->fun = fun + FUN_RAW_ADDR_OFFSET; #endif return 2; } #endif -#ifndef LISP_FEATURE_X86 -static int +#if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)) +static long scav_fun_header(lispobj *where, lispobj object) { lose("attempted to scavenge a function header where=0x%08x object=0x%08x", - (unsigned long) where, - (unsigned long) object); + (unsigned long) where, + (unsigned long) object); return 0; /* bogus return value to satisfy static type checking */ } #endif /* LISP_FEATURE_X86 */ @@ -453,7 +455,7 @@ trans_fun_header(lispobj object) struct simple_fun *fheader; unsigned long offset; struct code *code, *ncode; - + fheader = (struct simple_fun *) native_pointer(object); /* FIXME: was times 4, should it really be N_WORD_BYTES? */ offset = HeaderValue(fheader->header) * N_WORD_BYTES; @@ -470,7 +472,7 @@ trans_fun_header(lispobj object) * instances */ -static int +static long scav_instance_pointer(lispobj *where, lispobj object) { lispobj copy, *first_pointer; @@ -496,7 +498,7 @@ scav_instance_pointer(lispobj *where, lispobj object) static lispobj trans_list(lispobj object); -static int +static long scav_list_pointer(lispobj *where, lispobj object) { lispobj first, *first_pointer; @@ -530,8 +532,8 @@ trans_list(lispobj object) cons = (struct cons *) native_pointer(object); /* Copy 'object'. */ - new_cons = (struct cons *) - gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK); + new_cons = (struct cons *) + gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK); new_cons->car = cons->car; new_cons->cdr = cons->cdr; /* updated later */ new_list_pointer = make_lispobj(new_cons,lowtag_of(object)); @@ -544,32 +546,32 @@ trans_list(lispobj object) /* Try to linearize the list in the cdr direction to help reduce * paging. */ while (1) { - lispobj new_cdr; - struct cons *cdr_cons, *new_cdr_cons; - - if(lowtag_of(cdr) != LIST_POINTER_LOWTAG || - !from_space_p(cdr) || - forwarding_pointer_p((lispobj *)native_pointer(cdr))) - break; - - cdr_cons = (struct cons *) native_pointer(cdr); - - /* Copy 'cdr'. */ - new_cdr_cons = (struct cons*) - gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK); - new_cdr_cons->car = cdr_cons->car; - new_cdr_cons->cdr = cdr_cons->cdr; - new_cdr = make_lispobj(new_cdr_cons, lowtag_of(cdr)); - - /* Grab the cdr before it is clobbered. */ - cdr = cdr_cons->cdr; - set_forwarding_pointer((lispobj *)cdr_cons, new_cdr); - - /* Update the cdr of the last cons copied into new space to - * keep the newspace scavenge from having to do it. */ - new_cons->cdr = new_cdr; - - new_cons = new_cdr_cons; + lispobj new_cdr; + struct cons *cdr_cons, *new_cdr_cons; + + if(lowtag_of(cdr) != LIST_POINTER_LOWTAG || + !from_space_p(cdr) || + forwarding_pointer_p((lispobj *)native_pointer(cdr))) + break; + + cdr_cons = (struct cons *) native_pointer(cdr); + + /* Copy 'cdr'. */ + new_cdr_cons = (struct cons*) + gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK); + new_cdr_cons->car = cdr_cons->car; + new_cdr_cons->cdr = cdr_cons->cdr; + new_cdr = make_lispobj(new_cdr_cons, lowtag_of(cdr)); + + /* Grab the cdr before it is clobbered. */ + cdr = cdr_cons->cdr; + set_forwarding_pointer((lispobj *)cdr_cons, new_cdr); + + /* Update the cdr of the last cons copied into new space to + * keep the newspace scavenge from having to do it. */ + new_cons->cdr = new_cdr; + + new_cons = new_cdr_cons; } return new_list_pointer; @@ -580,7 +582,7 @@ trans_list(lispobj object) * scavenging and transporting other pointers */ -static int +static long scav_other_pointer(lispobj *where, lispobj object) { lispobj first, *first_pointer; @@ -592,9 +594,9 @@ scav_other_pointer(lispobj *where, lispobj object) first = (transother[widetag_of(*first_pointer)])(object); if (first != object) { - set_forwarding_pointer(first_pointer, first); + set_forwarding_pointer(first_pointer, first); #ifdef LISP_FEATURE_GENCGC - *where = first; + *where = first; #endif } #ifndef LISP_FEATURE_GENCGC @@ -610,13 +612,13 @@ scav_other_pointer(lispobj *where, lispobj object) * immediate, boxed, and unboxed objects */ -static int +static long size_pointer(lispobj *where) { return 1; } -static int +static long scav_immediate(lispobj *where, lispobj object) { return 1; @@ -629,19 +631,37 @@ trans_immediate(lispobj object) return NIL; /* bogus return value to satisfy static type checking */ } -static int +static long size_immediate(lispobj *where) { return 1; } -static int +static long scav_boxed(lispobj *where, lispobj object) { return 1; } +static long +scav_instance(lispobj *where, lispobj object) +{ + lispobj nuntagged; + long ntotal = HeaderValue(object); + lispobj layout = ((struct instance *)where)->slots[0]; + + if (!layout) + return 1; + if (forwarding_pointer_p(native_pointer(layout))) + layout = (lispobj) forwarding_pointer_value(native_pointer(layout)); + + nuntagged = ((struct layout *)native_pointer(layout))->n_untagged_slots; + scavenge(where + 1, ntotal - fixnum_value(nuntagged)); + + return ntotal + 1; +} + static lispobj trans_boxed(lispobj object) { @@ -658,7 +678,7 @@ trans_boxed(lispobj object) } -static int +static long size_boxed(lispobj *where) { lispobj header; @@ -674,35 +694,35 @@ size_boxed(lispobj *where) /* Note: on the sparc we don't have to do anything special for fdefns, */ /* 'cause the raw-addr has a function lowtag. */ #ifndef LISP_FEATURE_SPARC -static int +static long scav_fdefn(lispobj *where, lispobj object) { struct fdefn *fdefn; fdefn = (struct fdefn *)where; - /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n", + /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n", fdefn->fun, fdefn->raw_addr)); */ - if ((char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET) - == (char *)((unsigned long)(fdefn->raw_addr))) { - scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1); + if ((char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET) + == (char *)((unsigned long)(fdefn->raw_addr))) { + scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1); - /* Don't write unnecessarily. */ - if (fdefn->raw_addr != (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET)) - fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET); - /* gc.c has more casts here, which may be relevant or alternatively - may be compiler warning defeaters. try + /* Don't write unnecessarily. */ + if (fdefn->raw_addr != (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET)) + fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET); + /* gc.c has more casts here, which may be relevant or alternatively + may be compiler warning defeaters. try fdefn->raw_addr = ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET; - */ - return sizeof(struct fdefn) / sizeof(lispobj); + */ + return sizeof(struct fdefn) / sizeof(lispobj); } else { - return 1; + return 1; } } #endif -static int +static long scav_unboxed(lispobj *where, lispobj object) { unsigned long length; @@ -729,7 +749,7 @@ trans_unboxed(lispobj object) return copy_unboxed_object(object, length); } -static int +static long size_unboxed(lispobj *where) { lispobj header; @@ -742,13 +762,13 @@ size_unboxed(lispobj *where) return length; } -static int + /* vector-like objects */ - +static long scav_base_string(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; /* NOTE: Strings contain one more byte of data than the length */ /* slot indicates. */ @@ -763,7 +783,7 @@ static lispobj trans_base_string(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -778,11 +798,11 @@ trans_base_string(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int -size_character_string(lispobj *where) +static long +size_base_string(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; /* NOTE: A string contains one more byte of data (a terminating * '\0' to help when interfacing with C functions) than indicated @@ -790,11 +810,12 @@ size_character_string(lispobj *where) vector = (struct vector *) where; length = fixnum_value(vector->length) + 1; - nwords = CEILING(NWORDS(length, 32) + 2, 2); + nwords = CEILING(NWORDS(length, 8) + 2, 2); return nwords; } +static long scav_character_string(lispobj *where, lispobj object) { struct vector *vector; @@ -828,8 +849,8 @@ trans_character_string(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int -size_base_string(lispobj *where) +static long +size_character_string(lispobj *where) { struct vector *vector; int length, nwords; @@ -840,7 +861,7 @@ size_base_string(lispobj *where) vector = (struct vector *) where; length = fixnum_value(vector->length) + 1; - nwords = CEILING(NWORDS(length, 8) + 2, 2); + nwords = CEILING(NWORDS(length, 32) + 2, 2); return nwords; } @@ -849,7 +870,7 @@ static lispobj trans_vector(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -861,11 +882,11 @@ trans_vector(lispobj object) return copy_large_object(object, nwords); } -static int +static long size_vector(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -874,7 +895,7 @@ size_vector(lispobj *where) return nwords; } -static int +static long scav_vector_nil(lispobj *where, lispobj object) { return 2; @@ -887,18 +908,18 @@ trans_vector_nil(lispobj object) return copy_unboxed_object(object, 2); } -static int +static long size_vector_nil(lispobj *where) { /* Just the header word and the length word */ return 2; } -static int +static long scav_vector_bit(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -911,7 +932,7 @@ static lispobj trans_vector_bit(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -922,11 +943,11 @@ trans_vector_bit(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_bit(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -935,11 +956,11 @@ size_vector_bit(lispobj *where) return nwords; } -static int +static long scav_vector_unsigned_byte_2(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -952,7 +973,7 @@ static lispobj trans_vector_unsigned_byte_2(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -963,11 +984,11 @@ trans_vector_unsigned_byte_2(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_unsigned_byte_2(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -976,11 +997,11 @@ size_vector_unsigned_byte_2(lispobj *where) return nwords; } -static int +static long scav_vector_unsigned_byte_4(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -993,7 +1014,7 @@ static lispobj trans_vector_unsigned_byte_4(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1003,11 +1024,11 @@ trans_vector_unsigned_byte_4(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_unsigned_byte_4(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1017,11 +1038,11 @@ size_vector_unsigned_byte_4(lispobj *where) } -static int +static long scav_vector_unsigned_byte_8(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1038,7 +1059,7 @@ static lispobj trans_vector_unsigned_byte_8(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1049,11 +1070,11 @@ trans_vector_unsigned_byte_8(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_unsigned_byte_8(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1063,11 +1084,11 @@ size_vector_unsigned_byte_8(lispobj *where) } -static int +static long scav_vector_unsigned_byte_16(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1080,7 +1101,7 @@ static lispobj trans_vector_unsigned_byte_16(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1091,11 +1112,11 @@ trans_vector_unsigned_byte_16(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_unsigned_byte_16(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1104,11 +1125,11 @@ size_vector_unsigned_byte_16(lispobj *where) return nwords; } -static int +static long scav_vector_unsigned_byte_32(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1121,7 +1142,7 @@ static lispobj trans_vector_unsigned_byte_32(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1132,11 +1153,11 @@ trans_vector_unsigned_byte_32(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_unsigned_byte_32(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1146,11 +1167,11 @@ size_vector_unsigned_byte_32(lispobj *where) } #if N_WORD_BITS == 64 -static int +static long scav_vector_unsigned_byte_64(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1163,7 +1184,7 @@ static lispobj trans_vector_unsigned_byte_64(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1174,11 +1195,11 @@ trans_vector_unsigned_byte_64(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_unsigned_byte_64(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1188,11 +1209,11 @@ size_vector_unsigned_byte_64(lispobj *where) } #endif -static int +static long scav_vector_single_float(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1205,7 +1226,7 @@ static lispobj trans_vector_single_float(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1216,11 +1237,11 @@ trans_vector_single_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_single_float(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1229,11 +1250,11 @@ size_vector_single_float(lispobj *where) return nwords; } -static int +static long scav_vector_double_float(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1246,7 +1267,7 @@ static lispobj trans_vector_double_float(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1257,11 +1278,11 @@ trans_vector_double_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_double_float(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1271,17 +1292,17 @@ size_vector_double_float(lispobj *where) } #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG -static int +static long scav_vector_long_float(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); - nwords = CEILING(length * - LONG_FLOAT_SIZE - + 2, 2); + nwords = CEILING(length * + LONG_FLOAT_SIZE + + 2, 2); return nwords; } @@ -1289,7 +1310,7 @@ static lispobj trans_vector_long_float(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1300,11 +1321,11 @@ trans_vector_long_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_long_float(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1316,11 +1337,11 @@ size_vector_long_float(lispobj *where) #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG -static int +static long scav_vector_complex_single_float(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1333,7 +1354,7 @@ static lispobj trans_vector_complex_single_float(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1344,11 +1365,11 @@ trans_vector_complex_single_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_complex_single_float(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1359,11 +1380,11 @@ size_vector_complex_single_float(lispobj *where) #endif #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG -static int +static long scav_vector_complex_double_float(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1376,7 +1397,7 @@ static lispobj trans_vector_complex_double_float(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1387,11 +1408,11 @@ trans_vector_complex_double_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_complex_double_float(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1403,11 +1424,11 @@ size_vector_complex_double_float(lispobj *where) #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG -static int +static long scav_vector_complex_long_float(lispobj *where, lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1420,7 +1441,7 @@ static lispobj trans_vector_complex_long_float(lispobj object) { struct vector *vector; - int length, nwords; + long length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1431,11 +1452,11 @@ trans_vector_complex_long_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static int +static long size_vector_complex_long_float(lispobj *where) { struct vector *vector; - int length, nwords; + long length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1446,7 +1467,7 @@ size_vector_complex_long_float(lispobj *where) #endif #define WEAK_POINTER_NWORDS \ - CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2) + CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2) static lispobj trans_weak_pointer(lispobj object) @@ -1467,16 +1488,16 @@ trans_weak_pointer(lispobj object) copy = copy_object(object, WEAK_POINTER_NWORDS); #ifndef LISP_FEATURE_GENCGC wp = (struct weak_pointer *) native_pointer(copy); - + gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG); /* Push the weak pointer onto the list of weak pointers. */ - wp->next = LOW_WORD(weak_pointers); + wp->next = (struct weak_pointer *)LOW_WORD(weak_pointers); weak_pointers = wp; #endif return copy; } -static int +static long size_weak_pointer(lispobj *where) { return WEAK_POINTER_NWORDS; @@ -1486,29 +1507,28 @@ size_weak_pointer(lispobj *where) void scan_weak_pointers(void) { struct weak_pointer *wp; - for (wp = weak_pointers; wp != NULL; - wp=(struct weak_pointer *)native_pointer(wp->next)) { - lispobj value = wp->value; - lispobj *first_pointer; - gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG); - if (!(is_lisp_pointer(value) && from_space_p(value))) - continue; - - /* Now, we need to check whether the object has been forwarded. If - * it has been, the weak pointer is still good and needs to be - * updated. Otherwise, the weak pointer needs to be nil'ed - * out. */ - - first_pointer = (lispobj *)native_pointer(value); - - if (forwarding_pointer_p(first_pointer)) { - wp->value= - (lispobj)LOW_WORD(forwarding_pointer_value(first_pointer)); - } else { - /* Break it. */ - wp->value = NIL; - wp->broken = T; - } + for (wp = weak_pointers; wp != NULL; wp=wp->next) { + lispobj value = wp->value; + lispobj *first_pointer; + gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG); + if (!(is_lisp_pointer(value) && from_space_p(value))) + continue; + + /* Now, we need to check whether the object has been forwarded. If + * it has been, the weak pointer is still good and needs to be + * updated. Otherwise, the weak pointer needs to be nil'ed + * out. */ + + first_pointer = (lispobj *)native_pointer(value); + + if (forwarding_pointer_p(first_pointer)) { + wp->value= + (lispobj)LOW_WORD(forwarding_pointer_value(first_pointer)); + } else { + /* Break it. */ + wp->value = NIL; + wp->broken = T; + } } } @@ -1518,7 +1538,7 @@ void scan_weak_pointers(void) * initialization */ -static int +static long scav_lose(lispobj *where, lispobj object) { lose("no scavenge function for object 0x%08x (widetag 0x%x)", @@ -1532,17 +1552,17 @@ static lispobj trans_lose(lispobj object) { lose("no transport function for object 0x%08x (widetag 0x%x)", - (unsigned long)object, - widetag_of(*(lispobj*)native_pointer(object))); + (unsigned long)object, + widetag_of(*(lispobj*)native_pointer(object))); return NIL; /* bogus return value to satisfy static type checking */ } -static int +static long size_lose(lispobj *where) { lose("no size function for object at 0x%08x (widetag 0x%x)", - (unsigned long)where, - widetag_of(LOW_WORD(where))); + (unsigned long)where, + widetag_of(LOW_WORD(where))); return 1; /* bogus return value to satisfy static type checking */ } @@ -1554,13 +1574,13 @@ size_lose(lispobj *where) void gc_init_tables(void) { - int i; + long i; /* Set default value in all slots of scavenge table. FIXME * replace this gnarly sizeof with something based on * N_WIDETAG_BITS */ - for (i = 0; i < ((sizeof scavtab)/(sizeof scavtab[0])); i++) { - scavtab[i] = scav_lose; + for (i = 0; i < ((sizeof scavtab)/(sizeof scavtab[0])); i++) { + scavtab[i] = scav_lose; } /* For each type which can be selected by the lowtag alone, set @@ -1569,21 +1589,25 @@ gc_init_tables(void) */ for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) { - scavtab[EVEN_FIXNUM_LOWTAG|(i< 0) { + size_t count = 1; + lispobj thing = *start; + + /* If thing is an immediate then this is a cons. */ + if (is_lisp_pointer(thing) + || (fixnump(thing)) + || (widetag_of(thing) == CHARACTER_WIDETAG) +#if N_WORD_BITS == 64 + || (widetag_of(thing) == SINGLE_FLOAT_WIDETAG) +#endif + || (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); +}