X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgc-common.c;h=7add9512717560b3535f0ae2be7c95e9fec85407;hb=debae3c18d31b5222be4d5de8dcb2601336e24a4;hp=96de1729b7fed83ad965c6c1d2b441ab7fbf970d;hpb=a7a9b1029e8b9e45a5b66d62e161cc476cb7b60c;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 96de172..7add951 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -52,8 +52,8 @@ #endif #endif -size_t dynamic_space_size = DEFAULT_DYNAMIC_SPACE_SIZE; -size_t thread_control_stack_size = DEFAULT_CONTROL_STACK_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,68 +85,44 @@ 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 */ -static -lispobj -gc_general_copy_object(lispobj object, long nwords, int page_type_flag) -{ - 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, page_type_flag, ALLOC_QUICK); - - /* Copy the object. */ - memcpy(new,native_pointer(object),nwords*N_WORD_BYTES); - return make_lispobj(new,tag); -} +/* 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) { return gc_general_copy_object(object, nwords, BOXED_PAGE_FLAG); } lispobj -copy_code_object(lispobj object, long nwords) +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 if (forwarding_pointer_p(object_ptr)) @@ -161,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) @@ -186,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)) { @@ -196,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", @@ -214,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; @@ -256,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 */ @@ -285,7 +260,7 @@ 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); + (uword_t) code, (uword_t) new_code); printf("Code object is %d words long.\n", nwords); #endif @@ -337,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 */ @@ -374,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); @@ -398,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; @@ -415,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 */ @@ -429,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); @@ -437,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; @@ -450,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; @@ -470,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 */ @@ -484,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); @@ -492,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; @@ -503,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; @@ -529,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; @@ -613,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; @@ -643,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; @@ -662,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) @@ -697,7 +672,7 @@ static lispobj trans_boxed(lispobj object) { lispobj header; - unsigned long length; + uword_t length; gc_assert(is_lisp_pointer(object)); @@ -709,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; @@ -725,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; @@ -752,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); @@ -767,7 +742,7 @@ static lispobj trans_unboxed(lispobj object) { lispobj header; - unsigned long length; + uword_t length; gc_assert(is_lisp_pointer(object)); @@ -779,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; @@ -794,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. */ @@ -813,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)); @@ -828,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 @@ -845,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; @@ -879,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; @@ -900,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)); @@ -912,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); @@ -925,7 +900,7 @@ size_vector(lispobj *where) return nwords; } -static long +static sword_t scav_vector_nil(lispobj *where, lispobj object) { return 2; @@ -938,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); @@ -962,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)); @@ -973,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); @@ -986,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); @@ -1003,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)); @@ -1014,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); @@ -1027,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); @@ -1044,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)); @@ -1054,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); @@ -1068,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); @@ -1089,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)); @@ -1100,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); @@ -1114,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); @@ -1131,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)); @@ -1142,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); @@ -1155,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); @@ -1172,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)); @@ -1183,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); @@ -1197,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); @@ -1214,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)); @@ -1225,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); @@ -1239,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); @@ -1256,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)); @@ -1267,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); @@ -1280,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); @@ -1297,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)); @@ -1308,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); @@ -1355,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); @@ -1367,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); @@ -1384,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)); @@ -1395,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); @@ -1410,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); @@ -1427,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)); @@ -1438,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); @@ -1458,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); @@ -1527,7 +1502,7 @@ trans_weak_pointer(lispobj object) return copy; } -static long +static sword_t size_weak_pointer(lispobj *where) { return WEAK_POINTER_NWORDS; @@ -1621,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)) { @@ -1642,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; - unsigned long i; + uword_t i; kv_vector = get_array_data(hash_table->table, SIMPLE_VECTOR_WIDETAG, &kv_length); @@ -1711,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 @@ -1725,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. */ @@ -1736,11 +1709,11 @@ scav_vector (lispobj *where, lispobj object) * sets the header in %%PUTHASH. */ fprintf(stderr, - "Warning: no pointer at %lx in hash table: this indicates " + "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", (unsigned long)&where[2]); + "by locks.\n", (uword_t)&where[2]); // We've scavenged three words. return 3; } @@ -1834,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; - unsigned long i; + uword_t i; kv_vector = get_array_data(hash_table->table, SIMPLE_VECTOR_WIDETAG, NULL); @@ -1880,11 +1853,11 @@ 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, + (uword_t)object, widetag_of(*where)); return 0; /* bogus return value to satisfy static type checking */ @@ -1894,16 +1867,16 @@ 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, + (uword_t)where, widetag_of(*where)); return 1; /* bogus return value to satisfy static type checking */ } @@ -1916,7 +1889,7 @@ size_lose(lispobj *where) void gc_init_tables(void) { - unsigned long i, j; + uword_t i, j; /* Set default value in all slots of scavenge table. FIXME * replace this gnarly sizeof with something based on @@ -1968,6 +1941,9 @@ gc_init_tables(void) #ifdef COMPLEX_LONG_FLOAT_WIDETAG scavtab[COMPLEX_LONG_FLOAT_WIDETAG] = scav_unboxed; #endif +#ifdef SIMD_PACK_WIDETAG + scavtab[SIMD_PACK_WIDETAG] = scav_unboxed; +#endif scavtab[SIMPLE_ARRAY_WIDETAG] = scav_boxed; scavtab[SIMPLE_BASE_STRING_WIDETAG] = scav_base_string; #ifdef SIMPLE_CHARACTER_STRING_WIDETAG @@ -2206,6 +2182,9 @@ gc_init_tables(void) transother[SYMBOL_HEADER_WIDETAG] = trans_boxed; transother[CHARACTER_WIDETAG] = trans_immediate; transother[SAP_WIDETAG] = trans_unboxed; +#ifdef SIMD_PACK_WIDETAG + transother[SIMD_PACK_WIDETAG] = trans_unboxed; +#endif transother[UNBOUND_MARKER_WIDETAG] = trans_immediate; transother[NO_TLS_VALUE_MARKER_WIDETAG] = trans_immediate; transother[WEAK_POINTER_WIDETAG] = trans_weak_pointer; @@ -2349,6 +2328,9 @@ gc_init_tables(void) sizetab[SYMBOL_HEADER_WIDETAG] = size_boxed; sizetab[CHARACTER_WIDETAG] = size_immediate; sizetab[SAP_WIDETAG] = size_unboxed; +#ifdef SIMD_PACK_WIDETAG + sizetab[SIMD_PACK_WIDETAG] = size_unboxed; +#endif sizetab[UNBOUND_MARKER_WIDETAG] = size_immediate; sizetab[NO_TLS_VALUE_MARKER_WIDETAG] = size_immediate; sizetab[WEAK_POINTER_WIDETAG] = size_weak_pointer; @@ -2416,30 +2398,29 @@ gc_search_space(lispobj *start, size_t words, lispobj *pointer) * of the enclosing object. */ int -looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr) +looks_like_valid_lisp_pointer_p(lispobj pointer, lispobj *start_addr) { - if (!is_lisp_pointer((lispobj)pointer)) { + if (!is_lisp_pointer(pointer)) { return 0; } /* Check that the object pointed to is consistent with the pointer * low tag. */ - switch (lowtag_of((lispobj)pointer)) { + switch (lowtag_of(pointer)) { case FUN_POINTER_LOWTAG: /* Start_addr should be the enclosing code object, or a closure * header. */ switch (widetag_of(*start_addr)) { case CODE_HEADER_WIDETAG: - /* Make sure we actually point to a function in the code object, - * as opposed to a random point there. */ - if (SIMPLE_FUN_HEADER_WIDETAG==widetag_of(*((lispobj *)(((unsigned long)pointer)-FUN_POINTER_LOWTAG)))) - return 1; - else - return 0; + /* Make sure we actually point to a function in the code object, + * as opposed to a random point there. */ + if (SIMPLE_FUN_HEADER_WIDETAG==widetag_of(native_pointer(pointer)[0])) + return 1; + else + return 0; case CLOSURE_HEADER_WIDETAG: case FUNCALLABLE_INSTANCE_HEADER_WIDETAG: - if ((unsigned long)pointer != - ((unsigned long)start_addr+FUN_POINTER_LOWTAG)) { + if (pointer != make_lispobj(start_addr, FUN_POINTER_LOWTAG)) { return 0; } break; @@ -2448,8 +2429,7 @@ looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr) } break; case LIST_POINTER_LOWTAG: - if ((unsigned long)pointer != - ((unsigned long)start_addr+LIST_POINTER_LOWTAG)) { + if (pointer != make_lispobj(start_addr, LIST_POINTER_LOWTAG)) { return 0; } /* Is it plausible cons? */ @@ -2462,8 +2442,7 @@ looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr) return 0; } case INSTANCE_POINTER_LOWTAG: - if ((unsigned long)pointer != - ((unsigned long)start_addr+INSTANCE_POINTER_LOWTAG)) { + if (pointer != make_lispobj(start_addr, INSTANCE_POINTER_LOWTAG)) { return 0; } if (widetag_of(start_addr[0]) != INSTANCE_HEADER_WIDETAG) { @@ -2479,8 +2458,7 @@ looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr) * cannot be found by simply walking the heap, therefore we * need to check for it. -- AB, 2010-Jun-04 */ if ((widetag_of(start_addr[0]) == CODE_HEADER_WIDETAG)) { - lispobj *potential_lra = - (lispobj *)(((unsigned long)pointer) - OTHER_POINTER_LOWTAG); + lispobj *potential_lra = native_pointer(pointer); if ((widetag_of(potential_lra[0]) == RETURN_PC_HEADER_WIDETAG) && ((potential_lra - HeaderValue(potential_lra[0])) == start_addr)) { return 1; /* It's as good as we can verify. */ @@ -2488,8 +2466,7 @@ looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr) } #endif - if ((unsigned long)pointer != - ((unsigned long)start_addr+OTHER_POINTER_LOWTAG)) { + if (pointer != make_lispobj(start_addr, OTHER_POINTER_LOWTAG)) { return 0; } /* Is it plausible? Not a cons. XXX should check the headers. */ @@ -2526,6 +2503,9 @@ looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr) #ifdef COMPLEX_LONG_FLOAT_WIDETAG case COMPLEX_LONG_FLOAT_WIDETAG: #endif +#ifdef SIMD_PACK_WIDETAG + case SIMD_PACK_WIDETAG: +#endif case SIMPLE_ARRAY_WIDETAG: case COMPLEX_BASE_STRING_WIDETAG: #ifdef COMPLEX_CHARACTER_STRING_WIDETAG @@ -2634,7 +2614,7 @@ valid_lisp_pointer_p(lispobj *pointer) if (((start=search_dynamic_space(pointer))!=NULL) || ((start=search_static_space(pointer))!=NULL) || ((start=search_read_only_space(pointer))!=NULL)) - return looks_like_valid_lisp_pointer_p(pointer, start); + return looks_like_valid_lisp_pointer_p((lispobj)pointer, start); else return 0; } @@ -2668,7 +2648,7 @@ maybe_gc(os_context_t *context) * A kludgy alternative is to propagate the sigmask change to the * outer context. */ -#ifndef LISP_FEATURE_WIN32 +#if !(defined(LISP_FEATURE_WIN32) || defined(LISP_FEATURE_SB_SAFEPOINT)) check_gc_signals_unblocked_or_lose(os_context_sigmask_addr(context)); unblock_gc_signals(0, 0); #endif @@ -2681,8 +2661,24 @@ maybe_gc(os_context_t *context) * we may even be in a WITHOUT-INTERRUPTS. */ gc_happened = funcall0(StaticSymbolFunction(SUB_GC)); FSHOW((stderr, "/maybe_gc: gc_happened=%s\n", - (gc_happened == NIL) ? "NIL" : "T")); - if ((gc_happened != NIL) && + (gc_happened == NIL) + ? "NIL" + : ((gc_happened == T) + ? "T" + : "0"))); + /* gc_happened can take three values: T, NIL, 0. + * + * T means that the thread managed to trigger a GC, and post-gc + * must be called. + * + * NIL means that the thread is within without-gcing, and no GC + * has occurred. + * + * Finally, 0 means that *a* GC has occurred, but it wasn't + * triggered by this thread; success, but post-gc doesn't have + * to be called. + */ + if ((gc_happened == T) && /* See if interrupts are enabled or it's possible to enable * them. POST-GC has a similar check, but we don't want to * unlock deferrables in that case and get a pending interrupt @@ -2693,8 +2689,10 @@ maybe_gc(os_context_t *context) sigset_t *context_sigmask = os_context_sigmask_addr(context); if (!deferrables_blocked_p(context_sigmask)) { thread_sigmask(SIG_SETMASK, context_sigmask, 0); +#ifndef LISP_FEATURE_SB_SAFEPOINT check_gc_signals_unblocked_or_lose(0); #endif +#endif FSHOW((stderr, "/maybe_gc: calling POST_GC\n")); funcall0(StaticSymbolFunction(POST_GC)); #ifndef LISP_FEATURE_WIN32 @@ -2741,17 +2739,23 @@ maybe_gc(os_context_t *context) * may be what the "lame" adjective in the above comment is for. In * this case, exact gc may lose badly. */ void -scrub_control_stack(void) +scrub_control_stack() +{ + scrub_thread_control_stack(arch_os_get_current_thread()); +} + +void +scrub_thread_control_stack(struct thread *th) { - struct thread *th = arch_os_get_current_thread(); os_vm_address_t guard_page_address = CONTROL_STACK_GUARD_PAGE(th); os_vm_address_t hard_guard_page_address = CONTROL_STACK_HARD_GUARD_PAGE(th); - lispobj *sp; #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK - sp = (lispobj *)&sp - 1; + /* On these targets scrubbing from C is a bad idea, so we punt to + * a routine in $ARCH-assem.S. */ + extern void arch_scrub_control_stack(struct thread *, os_vm_address_t, os_vm_address_t); + arch_scrub_control_stack(th, guard_page_address, hard_guard_page_address); #else - sp = access_control_stack_pointer(th); -#endif + lispobj *sp = access_control_stack_pointer(th); scrub: if ((((os_vm_address_t)sp < (hard_guard_page_address + os_vm_page_size)) && ((os_vm_address_t)sp >= hard_guard_page_address)) || @@ -2762,28 +2766,75 @@ scrub_control_stack(void) #ifdef LISP_FEATURE_STACK_GROWS_DOWNWARD_NOT_UPWARD do { *sp = 0; - } while (((unsigned long)sp--) & (BYTES_ZERO_BEFORE_END - 1)); + } 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 (((unsigned long)sp--) & (BYTES_ZERO_BEFORE_END - 1)); + } while (((uword_t)sp--) & (BYTES_ZERO_BEFORE_END - 1)); #else do { *sp = 0; - } while (((unsigned long)++sp) & (BYTES_ZERO_BEFORE_END - 1)); + } 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 (((unsigned long)++sp) & (BYTES_ZERO_BEFORE_END - 1)); + } 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; @@ -2816,7 +2867,7 @@ static int boxed_registers[] = BOXED_REGISTERS; *os_context_ctr_addr(context) #define INTERIOR_POINTER_VARS(name) \ - unsigned long name##_offset; \ + uword_t name##_offset; \ int name##_register_pair #define PAIR_INTERIOR_POINTER(name) \ @@ -2845,8 +2896,8 @@ static int boxed_registers[] = BOXED_REGISTERS; static void -pair_interior_pointer(os_context_t *context, unsigned long pointer, - unsigned long *saved_offset, int *register_pair) +pair_interior_pointer(os_context_t *context, uword_t pointer, + uword_t *saved_offset, int *register_pair) { int i; @@ -2857,11 +2908,11 @@ pair_interior_pointer(os_context_t *context, unsigned long pointer, */ /* 0x7FFFFFFF on 32-bit platforms; 0x7FFFFFFFFFFFFFFF on 64-bit platforms */ - *saved_offset = (((unsigned long)1) << (N_WORD_BITS - 1)) - 1; + *saved_offset = (((uword_t)1) << (N_WORD_BITS - 1)) - 1; *register_pair = -1; for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) { - unsigned long reg; - long offset; + uword_t reg; + sword_t offset; int index; index = boxed_registers[i];