X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgc-common.c;h=7add9512717560b3535f0ae2be7c95e9fec85407;hb=debae3c18d31b5222be4d5de8dcb2601336e24a4;hp=3a76955eb7f7512bfc1b3e0a28fcbaba75d98960;hpb=f318d0b1654042ed8f1b887852a9ba1f539208e4;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 3a76955..7add951 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -37,7 +37,6 @@ #include "validate.h" #include "lispregs.h" #include "arch.h" -#include "fixnump.h" #include "gc.h" #include "genesis/primitive-objects.h" #include "genesis/static-symbols.h" @@ -53,7 +52,8 @@ #endif #endif -size_t dynamic_space_size = DEFAULT_DYNAMIC_SPACE_SIZE; +os_vm_size_t dynamic_space_size = DEFAULT_DYNAMIC_SPACE_SIZE; +os_vm_size_t thread_control_stack_size = DEFAULT_CONTROL_STACK_SIZE; inline static boolean forwarding_pointer_p(lispobj *pointer) { @@ -85,59 +85,49 @@ set_forwarding_pointer(lispobj * pointer, lispobj newspace_copy) { return newspace_copy; } -long (*scavtab[256])(lispobj *where, lispobj object); +sword_t (*scavtab[256])(lispobj *where, lispobj object); lispobj (*transother[256])(lispobj object); -long (*sizetab[256])(lispobj *where); +sword_t (*sizetab[256])(lispobj *where); struct weak_pointer *weak_pointers; -unsigned long bytes_consed_between_gcs = 12*1024*1024; - +os_vm_size_t bytes_consed_between_gcs = 12*1024*1024; /* * copying objects */ +/* gc_general_copy_object is inline from gc-internal.h */ + /* to copy a boxed object */ lispobj -copy_object(lispobj object, long nwords) +copy_object(lispobj object, sword_t nwords) { - int tag; - lispobj *new; - - gc_assert(is_lisp_pointer(object)); - gc_assert(from_space_p(object)); - gc_assert((nwords & 0x01) == 0); - - /* Get tag of object. */ - tag = lowtag_of(object); - - /* Allocate space. */ - new = gc_general_alloc(nwords*N_WORD_BYTES,ALLOC_BOXED,ALLOC_QUICK); + return gc_general_copy_object(object, nwords, BOXED_PAGE_FLAG); +} - /* Copy the object. */ - memcpy(new,native_pointer(object),nwords*N_WORD_BYTES); - return make_lispobj(new,tag); +lispobj +copy_code_object(lispobj object, sword_t nwords) +{ + return gc_general_copy_object(object, nwords, CODE_PAGE_FLAG); } -static long scav_lose(lispobj *where, lispobj object); /* forward decl */ +static sword_t 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 * simpler if this function used an 'end' parameter instead. */ void -scavenge(lispobj *start, long n_words) +scavenge(lispobj *start, sword_t n_words) { lispobj *end = start + n_words; lispobj *object_ptr; - long n_words_scavenged; - - for (object_ptr = start; - object_ptr < end; - object_ptr += n_words_scavenged) { + for (object_ptr = start; object_ptr < end;) { lispobj object = *object_ptr; #ifdef LISP_FEATURE_GENCGC - gc_assert(!forwarding_pointer_p(object_ptr)); + if (forwarding_pointer_p(object_ptr)) + lose("unexpect forwarding pointer in scavenge: %p, start=%p, n=%l\n", + object_ptr, start, n_words); #endif if (is_lisp_pointer(object)) { if (from_space_p(object)) { @@ -147,16 +137,16 @@ scavenge(lispobj *start, long n_words) if (forwarding_pointer_p(ptr)) { /* Yes, there's a forwarding pointer. */ *object_ptr = LOW_WORD(forwarding_pointer_value(ptr)); - n_words_scavenged = 1; + object_ptr++; } else { /* Scavenge that pointer. */ - n_words_scavenged = + object_ptr += (scavtab[widetag_of(object)])(object_ptr, object); } } else { /* It points somewhere other than oldspace. Leave it * alone. */ - n_words_scavenged = 1; + object_ptr++; } } #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) @@ -172,7 +162,6 @@ scavenge(lispobj *start, long n_words) checking a single word and it's anything other than a pointer, just hush it up */ int widetag = widetag_of(object); - n_words_scavenged = 1; if ((scavtab[widetag] == scav_lose) || (((sizetab[widetag])(object_ptr)) > 1)) { @@ -182,15 +171,15 @@ If you can reproduce this warning, please send a bug report\n\ (see manual page for details).\n", object, object_ptr); } + object_ptr++; } #endif else if (fixnump(object)) { /* It's a fixnum: really easy.. */ - n_words_scavenged = 1; + object_ptr++; } else { /* It's some sort of header object or another. */ - n_words_scavenged = - (scavtab[widetag_of(object)])(object_ptr, object); + object_ptr += (scavtab[widetag_of(object)])(object_ptr, object); } } gc_assert_verbose(object_ptr == end, "Final object pointer %p, start %p, end %p\n", @@ -200,7 +189,7 @@ If you can reproduce this warning, please send a bug report\n\ static lispobj trans_fun_header(lispobj object); /* forward decls */ static lispobj trans_boxed(lispobj object); -static long +static sword_t scav_fun_pointer(lispobj *where, lispobj object) { lispobj *first_pointer; @@ -242,8 +231,8 @@ trans_code(struct code *code) { struct code *new_code; lispobj first, l_code, l_new_code; - long nheader_words, ncode_words, nwords; - unsigned long displacement; + uword_t nheader_words, ncode_words, nwords; + uword_t displacement; lispobj fheaderl, *prev_pointer; /* if object has already been transported, just return pointer */ @@ -266,12 +255,12 @@ trans_code(struct code *code) nwords = ncode_words + nheader_words; nwords = CEILING(nwords, 2); - l_new_code = copy_object(l_code, nwords); + l_new_code = copy_code_object(l_code, nwords); new_code = (struct code *) native_pointer(l_new_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); + (uword_t) code, (uword_t) new_code); printf("Code object is %d words long.\n", nwords); #endif @@ -323,23 +312,23 @@ trans_code(struct code *code) #ifdef LISP_FEATURE_GENCGC /* Cheneygc doesn't need this os_flush_icache, it flushes the whole spaces once when all copying is done. */ - os_flush_icache((os_vm_address_t) (((long *)new_code) + nheader_words), - ncode_words * sizeof(long)); + os_flush_icache((os_vm_address_t) (((sword_t *)new_code) + nheader_words), + ncode_words * sizeof(sword_t)); #endif -#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) +#ifdef LISP_FEATURE_X86 gencgc_apply_code_fixups(code, new_code); #endif return new_code; } -static long +static sword_t scav_code_header(lispobj *where, lispobj object) { struct code *code; - long n_header_words, n_code_words, n_words; + sword_t 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 */ @@ -360,7 +349,7 @@ scav_code_header(lispobj *where, lispobj object) gc_assert_verbose(is_lisp_pointer(entry_point), "Entry point %lx\n is not a lisp pointer.", - (long)entry_point); + (sword_t)entry_point); function_ptr = (struct simple_fun *) native_pointer(entry_point); gc_assert(widetag_of(function_ptr->header)==SIMPLE_FUN_HEADER_WIDETAG); @@ -368,7 +357,7 @@ scav_code_header(lispobj *where, lispobj object) scavenge(&function_ptr->name, 1); scavenge(&function_ptr->arglist, 1); scavenge(&function_ptr->type, 1); - scavenge(&function_ptr->xrefs, 1); + scavenge(&function_ptr->info, 1); } return n_words; @@ -384,11 +373,11 @@ trans_code_header(lispobj object) } -static long +static sword_t size_code_header(lispobj *where) { struct code *code; - long nheader_words, ncode_words, nwords; + sword_t nheader_words, ncode_words, nwords; code = (struct code *) where; @@ -401,12 +390,12 @@ size_code_header(lispobj *where) } #if !defined(LISP_FEATURE_X86) && ! defined(LISP_FEATURE_X86_64) -static long +static sword_t scav_return_pc_header(lispobj *where, lispobj object) { lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x\n", - (unsigned long) where, - (unsigned long) object); + (uword_t) where, + (uword_t) object); return 0; /* bogus return value to satisfy static type checking */ } #endif /* LISP_FEATURE_X86 */ @@ -415,7 +404,7 @@ static lispobj trans_return_pc_header(lispobj object) { struct simple_fun *return_pc; - unsigned long offset; + uword_t offset; struct code *code, *ncode; return_pc = (struct simple_fun *) native_pointer(object); @@ -423,7 +412,7 @@ trans_return_pc_header(lispobj object) offset = HeaderValue(return_pc->header) * N_WORD_BYTES; /* Transport the whole code object */ - code = (struct code *) ((unsigned long) return_pc - offset); + code = (struct code *) ((uword_t) return_pc - offset); ncode = trans_code(code); return ((lispobj) LOW_WORD(ncode) + offset) | OTHER_POINTER_LOWTAG; @@ -436,7 +425,7 @@ trans_return_pc_header(lispobj object) * have to figure out that the function is still live. */ #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) -static long +static sword_t scav_closure_header(lispobj *where, lispobj object) { struct closure *closure; @@ -456,12 +445,12 @@ scav_closure_header(lispobj *where, lispobj object) #endif #if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)) -static long +static sword_t scav_fun_header(lispobj *where, lispobj object) { lose("attempted to scavenge a function header where=0x%08x object=0x%08x\n", - (unsigned long) where, - (unsigned long) object); + (uword_t) where, + (uword_t) object); return 0; /* bogus return value to satisfy static type checking */ } #endif /* LISP_FEATURE_X86 */ @@ -470,7 +459,7 @@ static lispobj trans_fun_header(lispobj object) { struct simple_fun *fheader; - unsigned long offset; + uword_t offset; struct code *code, *ncode; fheader = (struct simple_fun *) native_pointer(object); @@ -478,7 +467,7 @@ trans_fun_header(lispobj object) offset = HeaderValue(fheader->header) * N_WORD_BYTES; /* Transport the whole code object */ - code = (struct code *) ((unsigned long) fheader - offset); + code = (struct code *) ((uword_t) fheader - offset); ncode = trans_code(code); return ((lispobj) LOW_WORD(ncode) + offset) | FUN_POINTER_LOWTAG; @@ -489,7 +478,7 @@ trans_fun_header(lispobj object) * instances */ -static long +static sword_t scav_instance_pointer(lispobj *where, lispobj object) { lispobj copy, *first_pointer; @@ -515,7 +504,7 @@ scav_instance_pointer(lispobj *where, lispobj object) static lispobj trans_list(lispobj object); -static long +static sword_t scav_list_pointer(lispobj *where, lispobj object) { lispobj first, *first_pointer; @@ -550,7 +539,7 @@ trans_list(lispobj object) /* Copy 'object'. */ new_cons = (struct cons *) - gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK); + gc_general_alloc(sizeof(struct cons), BOXED_PAGE_FLAG, ALLOC_QUICK); new_cons->car = cons->car; new_cons->cdr = cons->cdr; /* updated later */ new_list_pointer = make_lispobj(new_cons,lowtag_of(object)); @@ -575,7 +564,7 @@ trans_list(lispobj object) /* Copy 'cdr'. */ new_cdr_cons = (struct cons*) - gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK); + gc_general_alloc(sizeof(struct cons), BOXED_PAGE_FLAG, 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)); @@ -599,7 +588,7 @@ trans_list(lispobj object) * scavenging and transporting other pointers */ -static long +static sword_t scav_other_pointer(lispobj *where, lispobj object) { lispobj first, *first_pointer; @@ -629,13 +618,13 @@ scav_other_pointer(lispobj *where, lispobj object) * immediate, boxed, and unboxed objects */ -static long +static sword_t size_pointer(lispobj *where) { return 1; } -static long +static sword_t scav_immediate(lispobj *where, lispobj object) { return 1; @@ -648,24 +637,24 @@ trans_immediate(lispobj object) return NIL; /* bogus return value to satisfy static type checking */ } -static long +static sword_t size_immediate(lispobj *where) { return 1; } -static long +static sword_t scav_boxed(lispobj *where, lispobj object) { return 1; } -static long +static sword_t scav_instance(lispobj *where, lispobj object) { lispobj nuntagged; - long ntotal = HeaderValue(object); + sword_t ntotal = HeaderValue(object); lispobj layout = ((struct instance *)where)->slots[0]; if (!layout) @@ -683,7 +672,7 @@ static lispobj trans_boxed(lispobj object) { lispobj header; - unsigned long length; + uword_t length; gc_assert(is_lisp_pointer(object)); @@ -695,11 +684,11 @@ trans_boxed(lispobj object) } -static long +static sword_t size_boxed(lispobj *where) { lispobj header; - unsigned long length; + uword_t length; header = *where; length = HeaderValue(header) + 1; @@ -711,7 +700,7 @@ 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. */ #if !defined(LISP_FEATURE_SPARC) -static long +static sword_t scav_fdefn(lispobj *where, lispobj object) { struct fdefn *fdefn; @@ -721,8 +710,7 @@ scav_fdefn(lispobj *where, lispobj object) /* 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))) { + if ((char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET) == fdefn->raw_addr) { scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1); /* Don't write unnecessarily. */ @@ -739,10 +727,10 @@ scav_fdefn(lispobj *where, lispobj object) } #endif -static long +static sword_t scav_unboxed(lispobj *where, lispobj object) { - unsigned long length; + uword_t length; length = HeaderValue(object) + 1; length = CEILING(length, 2); @@ -754,7 +742,7 @@ static lispobj trans_unboxed(lispobj object) { lispobj header; - unsigned long length; + uword_t length; gc_assert(is_lisp_pointer(object)); @@ -766,11 +754,11 @@ trans_unboxed(lispobj object) return copy_unboxed_object(object, length); } -static long +static sword_t size_unboxed(lispobj *where) { lispobj header; - unsigned long length; + uword_t length; header = *where; length = HeaderValue(header) + 1; @@ -781,11 +769,11 @@ size_unboxed(lispobj *where) /* vector-like objects */ -static long +static sword_t scav_base_string(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; /* NOTE: Strings contain one more byte of data than the length */ /* slot indicates. */ @@ -800,7 +788,7 @@ static lispobj trans_base_string(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -815,11 +803,11 @@ trans_base_string(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_base_string(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; /* NOTE: A string contains one more byte of data (a terminating * '\0' to help when interfacing with C functions) than indicated @@ -832,7 +820,7 @@ size_base_string(lispobj *where) return nwords; } -static long +static sword_t scav_character_string(lispobj *where, lispobj object) { struct vector *vector; @@ -866,7 +854,7 @@ trans_character_string(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_character_string(lispobj *where) { struct vector *vector; @@ -887,7 +875,7 @@ static lispobj trans_vector(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -899,11 +887,11 @@ trans_vector(lispobj object) return copy_large_object(object, nwords); } -static long +static sword_t size_vector(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -912,7 +900,7 @@ size_vector(lispobj *where) return nwords; } -static long +static sword_t scav_vector_nil(lispobj *where, lispobj object) { return 2; @@ -925,18 +913,18 @@ trans_vector_nil(lispobj object) return copy_unboxed_object(object, 2); } -static long +static sword_t size_vector_nil(lispobj *where) { /* Just the header word and the length word */ return 2; } -static long +static sword_t scav_vector_bit(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -949,7 +937,7 @@ static lispobj trans_vector_bit(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -960,11 +948,11 @@ trans_vector_bit(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_bit(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -973,11 +961,11 @@ size_vector_bit(lispobj *where) return nwords; } -static long +static sword_t scav_vector_unsigned_byte_2(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -990,7 +978,7 @@ static lispobj trans_vector_unsigned_byte_2(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1001,11 +989,11 @@ trans_vector_unsigned_byte_2(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_unsigned_byte_2(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1014,11 +1002,11 @@ size_vector_unsigned_byte_2(lispobj *where) return nwords; } -static long +static sword_t scav_vector_unsigned_byte_4(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1031,7 +1019,7 @@ static lispobj trans_vector_unsigned_byte_4(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1041,11 +1029,11 @@ trans_vector_unsigned_byte_4(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_unsigned_byte_4(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1055,11 +1043,11 @@ size_vector_unsigned_byte_4(lispobj *where) } -static long +static sword_t scav_vector_unsigned_byte_8(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1076,7 +1064,7 @@ static lispobj trans_vector_unsigned_byte_8(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1087,11 +1075,11 @@ trans_vector_unsigned_byte_8(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_unsigned_byte_8(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1101,11 +1089,11 @@ size_vector_unsigned_byte_8(lispobj *where) } -static long +static sword_t scav_vector_unsigned_byte_16(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1118,7 +1106,7 @@ static lispobj trans_vector_unsigned_byte_16(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1129,11 +1117,11 @@ trans_vector_unsigned_byte_16(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_unsigned_byte_16(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1142,11 +1130,11 @@ size_vector_unsigned_byte_16(lispobj *where) return nwords; } -static long +static sword_t scav_vector_unsigned_byte_32(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1159,7 +1147,7 @@ static lispobj trans_vector_unsigned_byte_32(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1170,11 +1158,11 @@ trans_vector_unsigned_byte_32(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_unsigned_byte_32(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1184,11 +1172,11 @@ size_vector_unsigned_byte_32(lispobj *where) } #if N_WORD_BITS == 64 -static long +static sword_t scav_vector_unsigned_byte_64(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1201,7 +1189,7 @@ static lispobj trans_vector_unsigned_byte_64(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1212,11 +1200,11 @@ trans_vector_unsigned_byte_64(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_unsigned_byte_64(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1226,11 +1214,11 @@ size_vector_unsigned_byte_64(lispobj *where) } #endif -static long +static sword_t scav_vector_single_float(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1243,7 +1231,7 @@ static lispobj trans_vector_single_float(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1254,11 +1242,11 @@ trans_vector_single_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_single_float(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1267,11 +1255,11 @@ size_vector_single_float(lispobj *where) return nwords; } -static long +static sword_t scav_vector_double_float(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1284,7 +1272,7 @@ static lispobj trans_vector_double_float(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1295,11 +1283,11 @@ trans_vector_double_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_double_float(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1342,7 +1330,7 @@ static long size_vector_long_float(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1354,11 +1342,11 @@ size_vector_long_float(lispobj *where) #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG -static long +static sword_t scav_vector_complex_single_float(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1371,7 +1359,7 @@ static lispobj trans_vector_complex_single_float(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1382,11 +1370,11 @@ trans_vector_complex_single_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_complex_single_float(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1397,11 +1385,11 @@ size_vector_complex_single_float(lispobj *where) #endif #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG -static long +static sword_t scav_vector_complex_double_float(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1414,7 +1402,7 @@ static lispobj trans_vector_complex_double_float(lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; gc_assert(is_lisp_pointer(object)); @@ -1425,11 +1413,11 @@ trans_vector_complex_double_float(lispobj object) return copy_large_unboxed_object(object, nwords); } -static long +static sword_t size_vector_complex_double_float(lispobj *where) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1445,7 +1433,7 @@ static long scav_vector_complex_long_float(lispobj *where, lispobj object) { struct vector *vector; - long length, nwords; + sword_t length, nwords; vector = (struct vector *) where; length = fixnum_value(vector->length); @@ -1514,7 +1502,7 @@ trans_weak_pointer(lispobj object) return copy; } -static long +static sword_t size_weak_pointer(lispobj *where) { return WEAK_POINTER_NWORDS; @@ -1608,7 +1596,7 @@ weak_hash_entry_alivep (lispobj weakness, lispobj key, lispobj value) * length) or NULL if it isn't an array of the specified widetag after * all. */ static inline lispobj * -get_array_data (lispobj array, int widetag, unsigned long *length) +get_array_data (lispobj array, int widetag, uword_t *length) { if (is_lisp_pointer(array) && (widetag_of(*(lispobj *)native_pointer(array)) == widetag)) { @@ -1629,16 +1617,16 @@ static void scav_hash_table_entries (struct hash_table *hash_table) { lispobj *kv_vector; - unsigned long kv_length; + uword_t kv_length; lispobj *index_vector; - unsigned long length; + uword_t length; lispobj *next_vector; - unsigned long next_vector_length; + uword_t next_vector_length; lispobj *hash_vector; - unsigned long hash_vector_length; + uword_t hash_vector_length; lispobj empty_symbol; lispobj weakness = hash_table->weakness; - long i; + uword_t i; kv_vector = get_array_data(hash_table->table, SIMPLE_VECTOR_WIDETAG, &kv_length); @@ -1698,11 +1686,10 @@ scav_hash_table_entries (struct hash_table *hash_table) } } -long +sword_t scav_vector (lispobj *where, lispobj object) { - unsigned long kv_length; - lispobj *kv_vector; + uword_t kv_length; struct hash_table *hash_table; /* SB-VM:VECTOR-VALID-HASHING-SUBTYPE is set for EQ-based and weak @@ -1712,7 +1699,6 @@ scav_vector (lispobj *where, lispobj object) return 1; kv_length = fixnum_value(where[1]); - kv_vector = where + 2; /* Skip the header and length. */ /*FSHOW((stderr,"/kv_length = %d\n", kv_length));*/ /* Scavenge element 0, which may be a hash-table structure. */ @@ -1722,7 +1708,12 @@ scav_vector (lispobj *where, lispobj object) * and fills it with zero, but some other thread simulatenously * sets the header in %%PUTHASH. */ - fprintf(stderr, "Warning: no pointer at %x in hash table: this indicates non-fatal corruption caused by concurrent access to a hash-table from multiple threads. Any accesses to hash-tables shared between threads should be protected by locks.\n", &where[2]); + fprintf(stderr, + "Warning: no pointer at %p in hash table: this indicates " + "non-fatal corruption caused by concurrent access to a " + "hash-table from multiple threads. Any accesses to " + "hash-tables shared between threads should be protected " + "by locks.\n", (uword_t)&where[2]); // We've scavenged three words. return 3; } @@ -1816,13 +1807,13 @@ scan_weak_hash_table (struct hash_table *hash_table) { lispobj *kv_vector; lispobj *index_vector; - unsigned long length = 0; /* prevent warning */ + uword_t length = 0; /* prevent warning */ lispobj *next_vector; - unsigned long next_vector_length = 0; /* prevent warning */ + uword_t next_vector_length = 0; /* prevent warning */ lispobj *hash_vector; lispobj empty_symbol; lispobj weakness = hash_table->weakness; - long i; + uword_t i; kv_vector = get_array_data(hash_table->table, SIMPLE_VECTOR_WIDETAG, NULL); @@ -1862,12 +1853,12 @@ scan_weak_hash_tables (void) * initialization */ -static long +static sword_t scav_lose(lispobj *where, lispobj object) { lose("no scavenge function for object 0x%08x (widetag 0x%x)\n", - (unsigned long)object, - widetag_of(*(lispobj*)native_pointer(object))); + (uword_t)object, + widetag_of(*where)); return 0; /* bogus return value to satisfy static type checking */ } @@ -1876,17 +1867,17 @@ static lispobj trans_lose(lispobj object) { lose("no transport function for object 0x%08x (widetag 0x%x)\n", - (unsigned long)object, + (uword_t)object, widetag_of(*(lispobj*)native_pointer(object))); return NIL; /* bogus return value to satisfy static type checking */ } -static long +static sword_t size_lose(lispobj *where) { lose("no size function for object at 0x%08x (widetag 0x%x)\n", - (unsigned long)where, - widetag_of(LOW_WORD(where))); + (uword_t)where, + widetag_of(*where)); return 1; /* bogus return value to satisfy static type checking */ } @@ -1898,7 +1889,7 @@ size_lose(lispobj *where) void gc_init_tables(void) { - long i; + uword_t i, j; /* Set default value in all slots of scavenge table. FIXME * replace this gnarly sizeof with something based on @@ -1913,12 +1904,16 @@ gc_init_tables(void) */ for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) { - scavtab[EVEN_FIXNUM_LOWTAG|(i<= hard_guard_page_address)) || + (((os_vm_address_t)sp < (guard_page_address + os_vm_page_size)) && + ((os_vm_address_t)sp >= guard_page_address) && + (th->control_stack_guard_page_protected != NIL))) + return; +#ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD + do { + *sp = 0; + } while (((uword_t)sp--) & (BYTES_ZERO_BEFORE_END - 1)); + if ((os_vm_address_t)sp < (hard_guard_page_address + os_vm_page_size)) + return; + do { + if (*sp) + goto scrub; + } while (((uword_t)sp--) & (BYTES_ZERO_BEFORE_END - 1)); +#else + do { + *sp = 0; + } while (((uword_t)++sp) & (BYTES_ZERO_BEFORE_END - 1)); + if ((os_vm_address_t)sp >= hard_guard_page_address) + return; + do { + if (*sp) + goto scrub; + } while (((uword_t)++sp) & (BYTES_ZERO_BEFORE_END - 1)); +#endif +#endif /* LISP_FEATURE_C_STACK_IS_CONTROL_STACK */ +} + +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) + +void +scavenge_control_stack(struct thread *th) +{ + lispobj *object_ptr; + + /* In order to properly support dynamic-extent allocation of + * non-CONS objects, the control stack requires special handling. + * Rather than calling scavenge() directly, grovel over it fixing + * broken hearts, scavenging pointers to oldspace, and pitching a + * fit when encountering unboxed data. This prevents stray object + * headers from causing the scavenger to blow past the end of the + * stack (an error case checked in scavenge()). We don't worry + * about treating unboxed words as boxed or vice versa, because + * the compiler isn't allowed to store unboxed objects on the + * control stack. -- AB, 2011-Dec-02 */ + + for (object_ptr = th->control_stack_start; + object_ptr < access_control_stack_pointer(th); + object_ptr++) { + + lispobj object = *object_ptr; +#ifdef LISP_FEATURE_GENCGC + if (forwarding_pointer_p(object_ptr)) + lose("unexpected forwarding pointer in scavenge_control_stack: %p, start=%p, end=%p\n", + object_ptr, th->control_stack_start, access_control_stack_pointer(th)); +#endif + if (is_lisp_pointer(object) && 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)); + } else { + /* Scavenge that pointer. */ + long n_words_scavenged = + (scavtab[widetag_of(object)])(object_ptr, object); + gc_assert(n_words_scavenged == 1); + } + } else if (scavtab[widetag_of(object)] == scav_lose) { + lose("unboxed object in scavenge_control_stack: %p->%x, start=%p, end=%p\n", + object_ptr, object, th->control_stack_start, access_control_stack_pointer(th)); + } + } +} + +/* Scavenging Interrupt Contexts */ + +static int boxed_registers[] = BOXED_REGISTERS; + +/* The GC has a notion of an "interior pointer" register, an unboxed + * register that typically contains a pointer to inside an object + * referenced by another pointer. The most obvious of these is the + * program counter, although many compiler backends define a "Lisp + * Interior Pointer" register known to the runtime as reg_LIP, and + * various CPU architectures have other registers that also partake of + * the interior-pointer nature. As the code for pairing an interior + * pointer value up with its "base" register, and fixing it up after + * scavenging is complete is horribly repetitive, a few macros paper + * over the monotony. --AB, 2010-Jul-14 */ + +/* These macros are only ever used over a lexical environment which + * defines a pointer to an os_context_t called context, thus we don't + * bother to pass that context in as a parameter. */ + +/* Define how to access a given interior pointer. */ +#define ACCESS_INTERIOR_POINTER_pc \ + *os_context_pc_addr(context) +#define ACCESS_INTERIOR_POINTER_lip \ + *os_context_register_addr(context, reg_LIP) +#define ACCESS_INTERIOR_POINTER_lr \ + *os_context_lr_addr(context) +#define ACCESS_INTERIOR_POINTER_npc \ + *os_context_npc_addr(context) +#define ACCESS_INTERIOR_POINTER_ctr \ + *os_context_ctr_addr(context) + +#define INTERIOR_POINTER_VARS(name) \ + uword_t name##_offset; \ + int name##_register_pair + +#define PAIR_INTERIOR_POINTER(name) \ + pair_interior_pointer(context, \ + ACCESS_INTERIOR_POINTER_##name, \ + &name##_offset, \ + &name##_register_pair) + +/* One complexity here is that if a paired register is not found for + * an interior pointer, then that pointer does not get updated. + * Originally, there was some commentary about using an index of -1 + * when calling os_context_register_addr() on SPARC referring to the + * program counter, but the real reason is to allow an interior + * pointer register to point to the runtime, read-only space, or + * static space without problems. */ +#define FIXUP_INTERIOR_POINTER(name) \ + do { \ + if (name##_register_pair >= 0) { \ + ACCESS_INTERIOR_POINTER_##name = \ + (*os_context_register_addr(context, \ + name##_register_pair) \ + & ~LOWTAG_MASK) \ + + name##_offset; \ + } \ + } while (0) + + +static void +pair_interior_pointer(os_context_t *context, uword_t pointer, + uword_t *saved_offset, int *register_pair) +{ + int i; + + /* + * I (RLT) think this is trying to find the boxed register that is + * closest to the LIP address, without going past it. Usually, it's + * reg_CODE or reg_LRA. But sometimes, nothing can be found. + */ + /* 0x7FFFFFFF on 32-bit platforms; + 0x7FFFFFFFFFFFFFFF on 64-bit platforms */ + *saved_offset = (((uword_t)1) << (N_WORD_BITS - 1)) - 1; + *register_pair = -1; + for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) { + uword_t reg; + sword_t offset; + int index; + + index = boxed_registers[i]; + reg = *os_context_register_addr(context, index); + + /* An interior pointer is never relative to a non-pointer + * register (an oversight in the original implementation). + * The simplest argument for why this is true is to consider + * the fixnum that happens by coincide to be the word-index in + * memory of the header for some object plus two. This is + * happenstance would cause the register containing the fixnum + * to be selected as the register_pair if the interior pointer + * is to anywhere after the first two words of the object. + * The fixnum won't be changed during GC, but the object might + * move, thus destroying the interior pointer. --AB, + * 2010-Jul-14 */ + + if (is_lisp_pointer(reg) && + ((reg & ~LOWTAG_MASK) <= pointer)) { + offset = pointer - (reg & ~LOWTAG_MASK); + if (offset < *saved_offset) { + *saved_offset = offset; + *register_pair = index; + } + } + } +} + +static void +scavenge_interrupt_context(os_context_t * context) +{ + int i; + + /* FIXME: The various #ifdef noise here is precisely that: noise. + * Is it possible to fold it into the macrology so that we have + * one set of #ifdefs and then INTERIOR_POINTER_VARS /et alia/ + * compile out for the registers that don't exist on a given + * platform? */ + + INTERIOR_POINTER_VARS(pc); +#ifdef reg_LIP + INTERIOR_POINTER_VARS(lip); +#endif +#ifdef ARCH_HAS_LINK_REGISTER + INTERIOR_POINTER_VARS(lr); +#endif +#ifdef ARCH_HAS_NPC_REGISTER + INTERIOR_POINTER_VARS(npc); +#endif +#ifdef LISP_FEATURE_PPC + INTERIOR_POINTER_VARS(ctr); +#endif + + PAIR_INTERIOR_POINTER(pc); +#ifdef reg_LIP + PAIR_INTERIOR_POINTER(lip); +#endif +#ifdef ARCH_HAS_LINK_REGISTER + PAIR_INTERIOR_POINTER(lr); +#endif +#ifdef ARCH_HAS_NPC_REGISTER + PAIR_INTERIOR_POINTER(npc); +#endif +#ifdef LISP_FEATURE_PPC + PAIR_INTERIOR_POINTER(ctr); +#endif + + /* Scavenge all boxed registers in the context. */ + for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) { + int index; + lispobj foo; + + index = boxed_registers[i]; + foo = *os_context_register_addr(context, index); + scavenge(&foo, 1); + *os_context_register_addr(context, index) = foo; + + /* this is unlikely to work as intended on bigendian + * 64 bit platforms */ + + scavenge((lispobj *) os_context_register_addr(context, index), 1); + } + + /* Now that the scavenging is done, repair the various interior + * pointers. */ + FIXUP_INTERIOR_POINTER(pc); +#ifdef reg_LIP + FIXUP_INTERIOR_POINTER(lip); +#endif +#ifdef ARCH_HAS_LINK_REGISTER + FIXUP_INTERIOR_POINTER(lr); +#endif +#ifdef ARCH_HAS_NPC_REGISTER + FIXUP_INTERIOR_POINTER(npc); +#endif +#ifdef LISP_FEATURE_PPC + FIXUP_INTERIOR_POINTER(ctr); +#endif +} + +void +scavenge_interrupt_contexts(struct thread *th) +{ + int i, index; + os_context_t *context; + + index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,th)); + +#if defined(DEBUG_PRINT_CONTEXT_INDEX) + printf("Number of active contexts: %d\n", index); +#endif + + for (i = 0; i < index; i++) { + context = th->interrupt_contexts[i]; + scavenge_interrupt_context(context); + } } +#endif /* x86oid targets */