2 * Garbage Collection common functions for scavenging, moving and sizing
3 * objects. These are for use with both GC (stop & copy GC) and GENCGC
7 * This software is part of the SBCL system. See the README file for
10 * This software is derived from the CMU CL system, which was
11 * written at Carnegie Mellon University and released into the
12 * public domain. The software is in the public domain and is
13 * provided with absolutely no warranty. See the COPYING and CREDITS
14 * files for more information.
18 * For a review of garbage collection techniques (e.g. generational
19 * GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
20 * "Uniprocessor Garbage Collection Techniques". As of 20000618, this
21 * had been accepted for _ACM Computing Surveys_ and was available
22 * as a PostScript preprint through
23 * <http://www.cs.utexas.edu/users/oops/papers.html>
25 * <ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps>.
36 #include "interrupt.h"
42 #include "genesis/primitive-objects.h"
43 #include "genesis/static-symbols.h"
44 #include "genesis/layout.h"
45 #include "genesis/hash-table.h"
46 #include "gc-internal.h"
48 #ifdef LISP_FEATURE_SPARC
49 #define LONG_FLOAT_SIZE 4
51 #ifdef LISP_FEATURE_X86
52 #define LONG_FLOAT_SIZE 3
56 size_t dynamic_space_size = DEFAULT_DYNAMIC_SPACE_SIZE;
59 forwarding_pointer_p(lispobj *pointer) {
60 lispobj first_word=*pointer;
61 #ifdef LISP_FEATURE_GENCGC
62 return (first_word == 0x01);
64 return (is_lisp_pointer(first_word)
65 && new_space_p(first_word));
69 static inline lispobj *
70 forwarding_pointer_value(lispobj *pointer) {
71 #ifdef LISP_FEATURE_GENCGC
72 return (lispobj *) ((pointer_sized_uint_t) pointer[1]);
74 return (lispobj *) ((pointer_sized_uint_t) pointer[0]);
78 set_forwarding_pointer(lispobj * pointer, lispobj newspace_copy) {
79 #ifdef LISP_FEATURE_GENCGC
81 pointer[1]=newspace_copy;
83 pointer[0]=newspace_copy;
88 long (*scavtab[256])(lispobj *where, lispobj object);
89 lispobj (*transother[256])(lispobj object);
90 long (*sizetab[256])(lispobj *where);
91 struct weak_pointer *weak_pointers;
93 unsigned long bytes_consed_between_gcs = 12*1024*1024;
100 /* to copy a boxed object */
102 copy_object(lispobj object, long nwords)
107 gc_assert(is_lisp_pointer(object));
108 gc_assert(from_space_p(object));
109 gc_assert((nwords & 0x01) == 0);
111 /* Get tag of object. */
112 tag = lowtag_of(object);
114 /* Allocate space. */
115 new = gc_general_alloc(nwords*N_WORD_BYTES,ALLOC_BOXED,ALLOC_QUICK);
117 /* Copy the object. */
118 memcpy(new,native_pointer(object),nwords*N_WORD_BYTES);
119 return make_lispobj(new,tag);
122 static long scav_lose(lispobj *where, lispobj object); /* forward decl */
124 /* FIXME: Most calls end up going to some trouble to compute an
125 * 'n_words' value for this function. The system might be a little
126 * simpler if this function used an 'end' parameter instead. */
128 scavenge(lispobj *start, long n_words)
130 lispobj *end = start + n_words;
132 long n_words_scavenged;
134 for (object_ptr = start;
136 object_ptr += n_words_scavenged) {
138 lispobj object = *object_ptr;
139 #ifdef LISP_FEATURE_GENCGC
140 gc_assert(!forwarding_pointer_p(object_ptr));
142 if (is_lisp_pointer(object)) {
143 if (from_space_p(object)) {
144 /* It currently points to old space. Check for a
145 * forwarding pointer. */
146 lispobj *ptr = native_pointer(object);
147 if (forwarding_pointer_p(ptr)) {
148 /* Yes, there's a forwarding pointer. */
149 *object_ptr = LOW_WORD(forwarding_pointer_value(ptr));
150 n_words_scavenged = 1;
152 /* Scavenge that pointer. */
154 (scavtab[widetag_of(object)])(object_ptr, object);
157 /* It points somewhere other than oldspace. Leave it
159 n_words_scavenged = 1;
162 #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
163 /* This workaround is probably not needed for those ports
164 which don't have a partitioned register set (and therefore
165 scan the stack conservatively for roots). */
166 else if (n_words == 1) {
167 /* there are some situations where an other-immediate may
168 end up in a descriptor register. I'm not sure whether
169 this is supposed to happen, but if it does then we
170 don't want to (a) barf or (b) scavenge over the
171 data-block, because there isn't one. So, if we're
172 checking a single word and it's anything other than a
173 pointer, just hush it up */
174 int widetag = widetag_of(object);
175 n_words_scavenged = 1;
177 if ((scavtab[widetag] == scav_lose) ||
178 (((sizetab[widetag])(object_ptr)) > 1)) {
179 fprintf(stderr,"warning: \
180 attempted to scavenge non-descriptor value %x at %p.\n\n\
181 If you can reproduce this warning, please send a bug report\n\
182 (see manual page for details).\n",
187 else if (fixnump(object)) {
188 /* It's a fixnum: really easy.. */
189 n_words_scavenged = 1;
191 /* It's some sort of header object or another. */
193 (scavtab[widetag_of(object)])(object_ptr, object);
196 gc_assert_verbose(object_ptr == end, "Final object pointer %p, start %p, end %p\n",
197 object_ptr, start, end);
200 static lispobj trans_fun_header(lispobj object); /* forward decls */
201 static lispobj trans_boxed(lispobj object);
204 scav_fun_pointer(lispobj *where, lispobj object)
206 lispobj *first_pointer;
209 gc_assert(is_lisp_pointer(object));
211 /* Object is a pointer into from_space - not a FP. */
212 first_pointer = (lispobj *) native_pointer(object);
214 /* must transport object -- object may point to either a function
215 * header, a closure function header, or to a closure header. */
217 switch (widetag_of(*first_pointer)) {
218 case SIMPLE_FUN_HEADER_WIDETAG:
219 copy = trans_fun_header(object);
222 copy = trans_boxed(object);
226 if (copy != object) {
227 /* Set forwarding pointer */
228 set_forwarding_pointer(first_pointer,copy);
231 gc_assert(is_lisp_pointer(copy));
232 gc_assert(!from_space_p(copy));
241 trans_code(struct code *code)
243 struct code *new_code;
244 lispobj first, l_code, l_new_code;
245 long nheader_words, ncode_words, nwords;
246 unsigned long displacement;
247 lispobj fheaderl, *prev_pointer;
249 /* if object has already been transported, just return pointer */
250 first = code->header;
251 if (forwarding_pointer_p((lispobj *)code)) {
253 printf("Was already transported\n");
255 return (struct code *) forwarding_pointer_value
256 ((lispobj *)((pointer_sized_uint_t) code));
259 gc_assert(widetag_of(first) == CODE_HEADER_WIDETAG);
261 /* prepare to transport the code vector */
262 l_code = (lispobj) LOW_WORD(code) | OTHER_POINTER_LOWTAG;
264 ncode_words = fixnum_value(code->code_size);
265 nheader_words = HeaderValue(code->header);
266 nwords = ncode_words + nheader_words;
267 nwords = CEILING(nwords, 2);
269 l_new_code = copy_object(l_code, nwords);
270 new_code = (struct code *) native_pointer(l_new_code);
272 #if defined(DEBUG_CODE_GC)
273 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
274 (unsigned long) code, (unsigned long) new_code);
275 printf("Code object is %d words long.\n", nwords);
278 #ifdef LISP_FEATURE_GENCGC
279 if (new_code == code)
283 displacement = l_new_code - l_code;
285 set_forwarding_pointer((lispobj *)code, l_new_code);
287 /* set forwarding pointers for all the function headers in the */
288 /* code object. also fix all self pointers */
290 fheaderl = code->entry_points;
291 prev_pointer = &new_code->entry_points;
293 while (fheaderl != NIL) {
294 struct simple_fun *fheaderp, *nfheaderp;
297 fheaderp = (struct simple_fun *) native_pointer(fheaderl);
298 gc_assert(widetag_of(fheaderp->header) == SIMPLE_FUN_HEADER_WIDETAG);
300 /* Calculate the new function pointer and the new */
301 /* function header. */
302 nfheaderl = fheaderl + displacement;
303 nfheaderp = (struct simple_fun *) native_pointer(nfheaderl);
306 printf("fheaderp->header (at %x) <- %x\n",
307 &(fheaderp->header) , nfheaderl);
309 set_forwarding_pointer((lispobj *)fheaderp, nfheaderl);
311 /* fix self pointer. */
313 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
314 FUN_RAW_ADDR_OFFSET +
318 *prev_pointer = nfheaderl;
320 fheaderl = fheaderp->next;
321 prev_pointer = &nfheaderp->next;
323 #ifdef LISP_FEATURE_GENCGC
324 /* Cheneygc doesn't need this os_flush_icache, it flushes the whole
325 spaces once when all copying is done. */
326 os_flush_icache((os_vm_address_t) (((long *)new_code) + nheader_words),
327 ncode_words * sizeof(long));
331 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
332 gencgc_apply_code_fixups(code, new_code);
339 scav_code_header(lispobj *where, lispobj object)
342 long n_header_words, n_code_words, n_words;
343 lispobj entry_point; /* tagged pointer to entry point */
344 struct simple_fun *function_ptr; /* untagged pointer to entry point */
346 code = (struct code *) where;
347 n_code_words = fixnum_value(code->code_size);
348 n_header_words = HeaderValue(object);
349 n_words = n_code_words + n_header_words;
350 n_words = CEILING(n_words, 2);
352 /* Scavenge the boxed section of the code data block. */
353 scavenge(where + 1, n_header_words - 1);
355 /* Scavenge the boxed section of each function object in the
356 * code data block. */
357 for (entry_point = code->entry_points;
359 entry_point = function_ptr->next) {
361 gc_assert_verbose(is_lisp_pointer(entry_point), "Entry point %lx\n",
364 function_ptr = (struct simple_fun *) native_pointer(entry_point);
365 gc_assert(widetag_of(function_ptr->header)==SIMPLE_FUN_HEADER_WIDETAG);
367 scavenge(&function_ptr->name, 1);
368 scavenge(&function_ptr->arglist, 1);
369 scavenge(&function_ptr->type, 1);
370 scavenge(&function_ptr->xrefs, 1);
377 trans_code_header(lispobj object)
381 ncode = trans_code((struct code *) native_pointer(object));
382 return (lispobj) LOW_WORD(ncode) | OTHER_POINTER_LOWTAG;
387 size_code_header(lispobj *where)
390 long nheader_words, ncode_words, nwords;
392 code = (struct code *) where;
394 ncode_words = fixnum_value(code->code_size);
395 nheader_words = HeaderValue(code->header);
396 nwords = ncode_words + nheader_words;
397 nwords = CEILING(nwords, 2);
402 #if !defined(LISP_FEATURE_X86) && ! defined(LISP_FEATURE_X86_64)
404 scav_return_pc_header(lispobj *where, lispobj object)
406 lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x\n",
407 (unsigned long) where,
408 (unsigned long) object);
409 return 0; /* bogus return value to satisfy static type checking */
411 #endif /* LISP_FEATURE_X86 */
414 trans_return_pc_header(lispobj object)
416 struct simple_fun *return_pc;
417 unsigned long offset;
418 struct code *code, *ncode;
420 return_pc = (struct simple_fun *) native_pointer(object);
421 /* FIXME: was times 4, should it really be N_WORD_BYTES? */
422 offset = HeaderValue(return_pc->header) * N_WORD_BYTES;
424 /* Transport the whole code object */
425 code = (struct code *) ((unsigned long) return_pc - offset);
426 ncode = trans_code(code);
428 return ((lispobj) LOW_WORD(ncode) + offset) | OTHER_POINTER_LOWTAG;
431 /* On the 386, closures hold a pointer to the raw address instead of the
432 * function object, so we can use CALL [$FDEFN+const] to invoke
433 * the function without loading it into a register. Given that code
434 * objects don't move, we don't need to update anything, but we do
435 * have to figure out that the function is still live. */
437 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
439 scav_closure_header(lispobj *where, lispobj object)
441 struct closure *closure;
444 closure = (struct closure *)where;
445 fun = closure->fun - FUN_RAW_ADDR_OFFSET;
447 #ifdef LISP_FEATURE_GENCGC
448 /* The function may have moved so update the raw address. But
449 * don't write unnecessarily. */
450 if (closure->fun != fun + FUN_RAW_ADDR_OFFSET)
451 closure->fun = fun + FUN_RAW_ADDR_OFFSET;
457 #if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64))
459 scav_fun_header(lispobj *where, lispobj object)
461 lose("attempted to scavenge a function header where=0x%08x object=0x%08x\n",
462 (unsigned long) where,
463 (unsigned long) object);
464 return 0; /* bogus return value to satisfy static type checking */
466 #endif /* LISP_FEATURE_X86 */
469 trans_fun_header(lispobj object)
471 struct simple_fun *fheader;
472 unsigned long offset;
473 struct code *code, *ncode;
475 fheader = (struct simple_fun *) native_pointer(object);
476 /* FIXME: was times 4, should it really be N_WORD_BYTES? */
477 offset = HeaderValue(fheader->header) * N_WORD_BYTES;
479 /* Transport the whole code object */
480 code = (struct code *) ((unsigned long) fheader - offset);
481 ncode = trans_code(code);
483 return ((lispobj) LOW_WORD(ncode) + offset) | FUN_POINTER_LOWTAG;
492 scav_instance_pointer(lispobj *where, lispobj object)
494 lispobj copy, *first_pointer;
496 /* Object is a pointer into from space - not a FP. */
497 copy = trans_boxed(object);
499 #ifdef LISP_FEATURE_GENCGC
500 gc_assert(copy != object);
503 first_pointer = (lispobj *) native_pointer(object);
504 set_forwarding_pointer(first_pointer,copy);
515 static lispobj trans_list(lispobj object);
518 scav_list_pointer(lispobj *where, lispobj object)
520 lispobj first, *first_pointer;
522 gc_assert(is_lisp_pointer(object));
524 /* Object is a pointer into from space - not FP. */
525 first_pointer = (lispobj *) native_pointer(object);
527 first = trans_list(object);
528 gc_assert(first != object);
530 /* Set forwarding pointer */
531 set_forwarding_pointer(first_pointer, first);
533 gc_assert(is_lisp_pointer(first));
534 gc_assert(!from_space_p(first));
542 trans_list(lispobj object)
544 lispobj new_list_pointer;
545 struct cons *cons, *new_cons;
548 cons = (struct cons *) native_pointer(object);
551 new_cons = (struct cons *)
552 gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK);
553 new_cons->car = cons->car;
554 new_cons->cdr = cons->cdr; /* updated later */
555 new_list_pointer = make_lispobj(new_cons,lowtag_of(object));
557 /* Grab the cdr: set_forwarding_pointer will clobber it in GENCGC */
560 set_forwarding_pointer((lispobj *)cons, new_list_pointer);
562 /* Try to linearize the list in the cdr direction to help reduce
566 struct cons *cdr_cons, *new_cdr_cons;
568 if(lowtag_of(cdr) != LIST_POINTER_LOWTAG ||
569 !from_space_p(cdr) ||
570 forwarding_pointer_p((lispobj *)native_pointer(cdr)))
573 cdr_cons = (struct cons *) native_pointer(cdr);
576 new_cdr_cons = (struct cons*)
577 gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK);
578 new_cdr_cons->car = cdr_cons->car;
579 new_cdr_cons->cdr = cdr_cons->cdr;
580 new_cdr = make_lispobj(new_cdr_cons, lowtag_of(cdr));
582 /* Grab the cdr before it is clobbered. */
584 set_forwarding_pointer((lispobj *)cdr_cons, new_cdr);
586 /* Update the cdr of the last cons copied into new space to
587 * keep the newspace scavenge from having to do it. */
588 new_cons->cdr = new_cdr;
590 new_cons = new_cdr_cons;
593 return new_list_pointer;
598 * scavenging and transporting other pointers
602 scav_other_pointer(lispobj *where, lispobj object)
604 lispobj first, *first_pointer;
606 gc_assert(is_lisp_pointer(object));
608 /* Object is a pointer into from space - not FP. */
609 first_pointer = (lispobj *) native_pointer(object);
610 first = (transother[widetag_of(*first_pointer)])(object);
612 if (first != object) {
613 set_forwarding_pointer(first_pointer, first);
614 #ifdef LISP_FEATURE_GENCGC
618 #ifndef LISP_FEATURE_GENCGC
621 gc_assert(is_lisp_pointer(first));
622 gc_assert(!from_space_p(first));
628 * immediate, boxed, and unboxed objects
632 size_pointer(lispobj *where)
638 scav_immediate(lispobj *where, lispobj object)
644 trans_immediate(lispobj object)
646 lose("trying to transport an immediate\n");
647 return NIL; /* bogus return value to satisfy static type checking */
651 size_immediate(lispobj *where)
658 scav_boxed(lispobj *where, lispobj object)
664 scav_instance(lispobj *where, lispobj object)
667 long ntotal = HeaderValue(object);
668 lispobj layout = ((struct instance *)where)->slots[0];
672 if (forwarding_pointer_p(native_pointer(layout)))
673 layout = (lispobj) forwarding_pointer_value(native_pointer(layout));
675 nuntagged = ((struct layout *)native_pointer(layout))->n_untagged_slots;
676 scavenge(where + 1, ntotal - fixnum_value(nuntagged));
682 trans_boxed(lispobj object)
685 unsigned long length;
687 gc_assert(is_lisp_pointer(object));
689 header = *((lispobj *) native_pointer(object));
690 length = HeaderValue(header) + 1;
691 length = CEILING(length, 2);
693 return copy_object(object, length);
698 size_boxed(lispobj *where)
701 unsigned long length;
704 length = HeaderValue(header) + 1;
705 length = CEILING(length, 2);
710 /* Note: on the sparc we don't have to do anything special for fdefns, */
711 /* 'cause the raw-addr has a function lowtag. */
712 #if !defined(LISP_FEATURE_SPARC)
714 scav_fdefn(lispobj *where, lispobj object)
718 fdefn = (struct fdefn *)where;
720 /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n",
721 fdefn->fun, fdefn->raw_addr)); */
723 if ((char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET)
724 == (char *)((unsigned long)(fdefn->raw_addr))) {
725 scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1);
727 /* Don't write unnecessarily. */
728 if (fdefn->raw_addr != (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET))
729 fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET);
730 /* gc.c has more casts here, which may be relevant or alternatively
731 may be compiler warning defeaters. try
732 fdefn->raw_addr = ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET;
734 return sizeof(struct fdefn) / sizeof(lispobj);
742 scav_unboxed(lispobj *where, lispobj object)
744 unsigned long length;
746 length = HeaderValue(object) + 1;
747 length = CEILING(length, 2);
753 trans_unboxed(lispobj object)
756 unsigned long length;
759 gc_assert(is_lisp_pointer(object));
761 header = *((lispobj *) native_pointer(object));
762 length = HeaderValue(header) + 1;
763 length = CEILING(length, 2);
765 return copy_unboxed_object(object, length);
769 size_unboxed(lispobj *where)
772 unsigned long length;
775 length = HeaderValue(header) + 1;
776 length = CEILING(length, 2);
782 /* vector-like objects */
784 scav_base_string(lispobj *where, lispobj object)
786 struct vector *vector;
789 /* NOTE: Strings contain one more byte of data than the length */
790 /* slot indicates. */
792 vector = (struct vector *) where;
793 length = fixnum_value(vector->length) + 1;
794 nwords = CEILING(NWORDS(length, 8) + 2, 2);
799 trans_base_string(lispobj object)
801 struct vector *vector;
804 gc_assert(is_lisp_pointer(object));
806 /* NOTE: A string contains one more byte of data (a terminating
807 * '\0' to help when interfacing with C functions) than indicated
808 * by the length slot. */
810 vector = (struct vector *) native_pointer(object);
811 length = fixnum_value(vector->length) + 1;
812 nwords = CEILING(NWORDS(length, 8) + 2, 2);
814 return copy_large_unboxed_object(object, nwords);
818 size_base_string(lispobj *where)
820 struct vector *vector;
823 /* NOTE: A string contains one more byte of data (a terminating
824 * '\0' to help when interfacing with C functions) than indicated
825 * by the length slot. */
827 vector = (struct vector *) where;
828 length = fixnum_value(vector->length) + 1;
829 nwords = CEILING(NWORDS(length, 8) + 2, 2);
835 scav_character_string(lispobj *where, lispobj object)
837 struct vector *vector;
840 /* NOTE: Strings contain one more byte of data than the length */
841 /* slot indicates. */
843 vector = (struct vector *) where;
844 length = fixnum_value(vector->length) + 1;
845 nwords = CEILING(NWORDS(length, 32) + 2, 2);
850 trans_character_string(lispobj object)
852 struct vector *vector;
855 gc_assert(is_lisp_pointer(object));
857 /* NOTE: A string contains one more byte of data (a terminating
858 * '\0' to help when interfacing with C functions) than indicated
859 * by the length slot. */
861 vector = (struct vector *) native_pointer(object);
862 length = fixnum_value(vector->length) + 1;
863 nwords = CEILING(NWORDS(length, 32) + 2, 2);
865 return copy_large_unboxed_object(object, nwords);
869 size_character_string(lispobj *where)
871 struct vector *vector;
874 /* NOTE: A string contains one more byte of data (a terminating
875 * '\0' to help when interfacing with C functions) than indicated
876 * by the length slot. */
878 vector = (struct vector *) where;
879 length = fixnum_value(vector->length) + 1;
880 nwords = CEILING(NWORDS(length, 32) + 2, 2);
886 trans_vector(lispobj object)
888 struct vector *vector;
891 gc_assert(is_lisp_pointer(object));
893 vector = (struct vector *) native_pointer(object);
895 length = fixnum_value(vector->length);
896 nwords = CEILING(length + 2, 2);
898 return copy_large_object(object, nwords);
902 size_vector(lispobj *where)
904 struct vector *vector;
907 vector = (struct vector *) where;
908 length = fixnum_value(vector->length);
909 nwords = CEILING(length + 2, 2);
915 scav_vector_nil(lispobj *where, lispobj object)
921 trans_vector_nil(lispobj object)
923 gc_assert(is_lisp_pointer(object));
924 return copy_unboxed_object(object, 2);
928 size_vector_nil(lispobj *where)
930 /* Just the header word and the length word */
935 scav_vector_bit(lispobj *where, lispobj object)
937 struct vector *vector;
940 vector = (struct vector *) where;
941 length = fixnum_value(vector->length);
942 nwords = CEILING(NWORDS(length, 1) + 2, 2);
948 trans_vector_bit(lispobj object)
950 struct vector *vector;
953 gc_assert(is_lisp_pointer(object));
955 vector = (struct vector *) native_pointer(object);
956 length = fixnum_value(vector->length);
957 nwords = CEILING(NWORDS(length, 1) + 2, 2);
959 return copy_large_unboxed_object(object, nwords);
963 size_vector_bit(lispobj *where)
965 struct vector *vector;
968 vector = (struct vector *) where;
969 length = fixnum_value(vector->length);
970 nwords = CEILING(NWORDS(length, 1) + 2, 2);
976 scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
978 struct vector *vector;
981 vector = (struct vector *) where;
982 length = fixnum_value(vector->length);
983 nwords = CEILING(NWORDS(length, 2) + 2, 2);
989 trans_vector_unsigned_byte_2(lispobj object)
991 struct vector *vector;
994 gc_assert(is_lisp_pointer(object));
996 vector = (struct vector *) native_pointer(object);
997 length = fixnum_value(vector->length);
998 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1000 return copy_large_unboxed_object(object, nwords);
1004 size_vector_unsigned_byte_2(lispobj *where)
1006 struct vector *vector;
1007 long length, nwords;
1009 vector = (struct vector *) where;
1010 length = fixnum_value(vector->length);
1011 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1017 scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
1019 struct vector *vector;
1020 long length, nwords;
1022 vector = (struct vector *) where;
1023 length = fixnum_value(vector->length);
1024 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1030 trans_vector_unsigned_byte_4(lispobj object)
1032 struct vector *vector;
1033 long length, nwords;
1035 gc_assert(is_lisp_pointer(object));
1037 vector = (struct vector *) native_pointer(object);
1038 length = fixnum_value(vector->length);
1039 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1041 return copy_large_unboxed_object(object, nwords);
1044 size_vector_unsigned_byte_4(lispobj *where)
1046 struct vector *vector;
1047 long length, nwords;
1049 vector = (struct vector *) where;
1050 length = fixnum_value(vector->length);
1051 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1058 scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
1060 struct vector *vector;
1061 long length, nwords;
1063 vector = (struct vector *) where;
1064 length = fixnum_value(vector->length);
1065 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1070 /*********************/
1075 trans_vector_unsigned_byte_8(lispobj object)
1077 struct vector *vector;
1078 long length, nwords;
1080 gc_assert(is_lisp_pointer(object));
1082 vector = (struct vector *) native_pointer(object);
1083 length = fixnum_value(vector->length);
1084 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1086 return copy_large_unboxed_object(object, nwords);
1090 size_vector_unsigned_byte_8(lispobj *where)
1092 struct vector *vector;
1093 long length, nwords;
1095 vector = (struct vector *) where;
1096 length = fixnum_value(vector->length);
1097 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1104 scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
1106 struct vector *vector;
1107 long length, nwords;
1109 vector = (struct vector *) where;
1110 length = fixnum_value(vector->length);
1111 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1117 trans_vector_unsigned_byte_16(lispobj object)
1119 struct vector *vector;
1120 long length, nwords;
1122 gc_assert(is_lisp_pointer(object));
1124 vector = (struct vector *) native_pointer(object);
1125 length = fixnum_value(vector->length);
1126 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1128 return copy_large_unboxed_object(object, nwords);
1132 size_vector_unsigned_byte_16(lispobj *where)
1134 struct vector *vector;
1135 long length, nwords;
1137 vector = (struct vector *) where;
1138 length = fixnum_value(vector->length);
1139 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1145 scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
1147 struct vector *vector;
1148 long length, nwords;
1150 vector = (struct vector *) where;
1151 length = fixnum_value(vector->length);
1152 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1158 trans_vector_unsigned_byte_32(lispobj object)
1160 struct vector *vector;
1161 long length, nwords;
1163 gc_assert(is_lisp_pointer(object));
1165 vector = (struct vector *) native_pointer(object);
1166 length = fixnum_value(vector->length);
1167 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1169 return copy_large_unboxed_object(object, nwords);
1173 size_vector_unsigned_byte_32(lispobj *where)
1175 struct vector *vector;
1176 long length, nwords;
1178 vector = (struct vector *) where;
1179 length = fixnum_value(vector->length);
1180 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1185 #if N_WORD_BITS == 64
1187 scav_vector_unsigned_byte_64(lispobj *where, lispobj object)
1189 struct vector *vector;
1190 long length, nwords;
1192 vector = (struct vector *) where;
1193 length = fixnum_value(vector->length);
1194 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1200 trans_vector_unsigned_byte_64(lispobj object)
1202 struct vector *vector;
1203 long length, nwords;
1205 gc_assert(is_lisp_pointer(object));
1207 vector = (struct vector *) native_pointer(object);
1208 length = fixnum_value(vector->length);
1209 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1211 return copy_large_unboxed_object(object, nwords);
1215 size_vector_unsigned_byte_64(lispobj *where)
1217 struct vector *vector;
1218 long length, nwords;
1220 vector = (struct vector *) where;
1221 length = fixnum_value(vector->length);
1222 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1229 scav_vector_single_float(lispobj *where, lispobj object)
1231 struct vector *vector;
1232 long length, nwords;
1234 vector = (struct vector *) where;
1235 length = fixnum_value(vector->length);
1236 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1242 trans_vector_single_float(lispobj object)
1244 struct vector *vector;
1245 long length, nwords;
1247 gc_assert(is_lisp_pointer(object));
1249 vector = (struct vector *) native_pointer(object);
1250 length = fixnum_value(vector->length);
1251 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1253 return copy_large_unboxed_object(object, nwords);
1257 size_vector_single_float(lispobj *where)
1259 struct vector *vector;
1260 long length, nwords;
1262 vector = (struct vector *) where;
1263 length = fixnum_value(vector->length);
1264 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1270 scav_vector_double_float(lispobj *where, lispobj object)
1272 struct vector *vector;
1273 long length, nwords;
1275 vector = (struct vector *) where;
1276 length = fixnum_value(vector->length);
1277 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1283 trans_vector_double_float(lispobj object)
1285 struct vector *vector;
1286 long length, nwords;
1288 gc_assert(is_lisp_pointer(object));
1290 vector = (struct vector *) native_pointer(object);
1291 length = fixnum_value(vector->length);
1292 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1294 return copy_large_unboxed_object(object, nwords);
1298 size_vector_double_float(lispobj *where)
1300 struct vector *vector;
1301 long length, nwords;
1303 vector = (struct vector *) where;
1304 length = fixnum_value(vector->length);
1305 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1310 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1312 scav_vector_long_float(lispobj *where, lispobj object)
1314 struct vector *vector;
1315 long length, nwords;
1317 vector = (struct vector *) where;
1318 length = fixnum_value(vector->length);
1319 nwords = CEILING(length *
1326 trans_vector_long_float(lispobj object)
1328 struct vector *vector;
1329 long length, nwords;
1331 gc_assert(is_lisp_pointer(object));
1333 vector = (struct vector *) native_pointer(object);
1334 length = fixnum_value(vector->length);
1335 nwords = CEILING(length * LONG_FLOAT_SIZE + 2, 2);
1337 return copy_large_unboxed_object(object, nwords);
1341 size_vector_long_float(lispobj *where)
1343 struct vector *vector;
1344 long length, nwords;
1346 vector = (struct vector *) where;
1347 length = fixnum_value(vector->length);
1348 nwords = CEILING(length * LONG_FLOAT_SIZE + 2, 2);
1355 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1357 scav_vector_complex_single_float(lispobj *where, lispobj object)
1359 struct vector *vector;
1360 long length, nwords;
1362 vector = (struct vector *) where;
1363 length = fixnum_value(vector->length);
1364 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1370 trans_vector_complex_single_float(lispobj object)
1372 struct vector *vector;
1373 long length, nwords;
1375 gc_assert(is_lisp_pointer(object));
1377 vector = (struct vector *) native_pointer(object);
1378 length = fixnum_value(vector->length);
1379 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1381 return copy_large_unboxed_object(object, nwords);
1385 size_vector_complex_single_float(lispobj *where)
1387 struct vector *vector;
1388 long length, nwords;
1390 vector = (struct vector *) where;
1391 length = fixnum_value(vector->length);
1392 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1398 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1400 scav_vector_complex_double_float(lispobj *where, lispobj object)
1402 struct vector *vector;
1403 long length, nwords;
1405 vector = (struct vector *) where;
1406 length = fixnum_value(vector->length);
1407 nwords = CEILING(NWORDS(length, 128) + 2, 2);
1413 trans_vector_complex_double_float(lispobj object)
1415 struct vector *vector;
1416 long length, nwords;
1418 gc_assert(is_lisp_pointer(object));
1420 vector = (struct vector *) native_pointer(object);
1421 length = fixnum_value(vector->length);
1422 nwords = CEILING(NWORDS(length, 128) + 2, 2);
1424 return copy_large_unboxed_object(object, nwords);
1428 size_vector_complex_double_float(lispobj *where)
1430 struct vector *vector;
1431 long length, nwords;
1433 vector = (struct vector *) where;
1434 length = fixnum_value(vector->length);
1435 nwords = CEILING(NWORDS(length, 128) + 2, 2);
1442 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1444 scav_vector_complex_long_float(lispobj *where, lispobj object)
1446 struct vector *vector;
1447 long length, nwords;
1449 vector = (struct vector *) where;
1450 length = fixnum_value(vector->length);
1451 nwords = CEILING(length * (2* LONG_FLOAT_SIZE) + 2, 2);
1457 trans_vector_complex_long_float(lispobj object)
1459 struct vector *vector;
1460 long length, nwords;
1462 gc_assert(is_lisp_pointer(object));
1464 vector = (struct vector *) native_pointer(object);
1465 length = fixnum_value(vector->length);
1466 nwords = CEILING(length * (2*LONG_FLOAT_SIZE) + 2, 2);
1468 return copy_large_unboxed_object(object, nwords);
1472 size_vector_complex_long_float(lispobj *where)
1474 struct vector *vector;
1475 long length, nwords;
1477 vector = (struct vector *) where;
1478 length = fixnum_value(vector->length);
1479 nwords = CEILING(length * (2*LONG_FLOAT_SIZE) + 2, 2);
1485 #define WEAK_POINTER_NWORDS \
1486 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1489 trans_weak_pointer(lispobj object)
1492 #ifndef LISP_FEATURE_GENCGC
1493 struct weak_pointer *wp;
1495 gc_assert(is_lisp_pointer(object));
1497 #if defined(DEBUG_WEAK)
1498 printf("Transporting weak pointer from 0x%08x\n", object);
1501 /* Need to remember where all the weak pointers are that have */
1502 /* been transported so they can be fixed up in a post-GC pass. */
1504 copy = copy_object(object, WEAK_POINTER_NWORDS);
1505 #ifndef LISP_FEATURE_GENCGC
1506 wp = (struct weak_pointer *) native_pointer(copy);
1508 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
1509 /* Push the weak pointer onto the list of weak pointers. */
1510 wp->next = (struct weak_pointer *)LOW_WORD(weak_pointers);
1517 size_weak_pointer(lispobj *where)
1519 return WEAK_POINTER_NWORDS;
1523 void scan_weak_pointers(void)
1525 struct weak_pointer *wp;
1526 for (wp = weak_pointers; wp != NULL; wp=wp->next) {
1527 lispobj value = wp->value;
1528 lispobj *first_pointer;
1529 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
1530 if (!(is_lisp_pointer(value) && from_space_p(value)))
1533 /* Now, we need to check whether the object has been forwarded. If
1534 * it has been, the weak pointer is still good and needs to be
1535 * updated. Otherwise, the weak pointer needs to be nil'ed
1538 first_pointer = (lispobj *)native_pointer(value);
1540 if (forwarding_pointer_p(first_pointer)) {
1542 (lispobj)LOW_WORD(forwarding_pointer_value(first_pointer));
1554 #if N_WORD_BITS == 32
1555 #define EQ_HASH_MASK 0x1fffffff
1556 #elif N_WORD_BITS == 64
1557 #define EQ_HASH_MASK 0x1fffffffffffffff
1560 /* Compute the EQ-hash of KEY. This must match POINTER-HASH in
1561 * target-hash-table.lisp. */
1562 #define EQ_HASH(key) ((key) & EQ_HASH_MASK)
1564 /* List of weak hash tables chained through their NEXT-WEAK-HASH-TABLE
1565 * slot. Set to NULL at the end of a collection.
1567 * This is not optimal because, when a table is tenured, it won't be
1568 * processed automatically; only the yougest generation is GC'd by
1569 * default. On the other hand, all applications will need an
1570 * occasional full GC anyway, so it's not that bad either. */
1571 struct hash_table *weak_hash_tables = NULL;
1573 /* Return true if OBJ has already survived the current GC. */
1575 survived_gc_yet (lispobj obj)
1577 return (!is_lisp_pointer(obj) || !from_space_p(obj) ||
1578 forwarding_pointer_p(native_pointer(obj)));
1582 weak_hash_entry_alivep (lispobj weakness, lispobj key, lispobj value)
1586 return survived_gc_yet(key);
1588 return survived_gc_yet(value);
1590 return (survived_gc_yet(key) || survived_gc_yet(value));
1592 return (survived_gc_yet(key) && survived_gc_yet(value));
1595 /* Shut compiler up. */
1600 /* Return the beginning of data in ARRAY (skipping the header and the
1601 * length) or NULL if it isn't an array of the specified widetag after
1603 static inline lispobj *
1604 get_array_data (lispobj array, int widetag, unsigned long *length)
1606 if (is_lisp_pointer(array) &&
1607 (widetag_of(*(lispobj *)native_pointer(array)) == widetag)) {
1609 *length = fixnum_value(((lispobj *)native_pointer(array))[1]);
1610 return ((lispobj *)native_pointer(array)) + 2;
1616 /* Only need to worry about scavenging the _real_ entries in the
1617 * table. Phantom entries such as the hash table itself at index 0 and
1618 * the empty marker at index 1 were scavenged by scav_vector that
1619 * either called this function directly or arranged for it to be
1620 * called later by pushing the hash table onto weak_hash_tables. */
1622 scav_hash_table_entries (struct hash_table *hash_table)
1625 unsigned long kv_length;
1626 lispobj *index_vector;
1627 unsigned long length;
1628 lispobj *next_vector;
1629 unsigned long next_vector_length;
1630 lispobj *hash_vector;
1631 unsigned long hash_vector_length;
1632 lispobj empty_symbol;
1633 lispobj weakness = hash_table->weakness;
1636 kv_vector = get_array_data(hash_table->table,
1637 SIMPLE_VECTOR_WIDETAG, &kv_length);
1638 if (kv_vector == NULL)
1639 lose("invalid kv_vector %x\n", hash_table->table);
1641 index_vector = get_array_data(hash_table->index_vector,
1642 SIMPLE_ARRAY_WORD_WIDETAG, &length);
1643 if (index_vector == NULL)
1644 lose("invalid index_vector %x\n", hash_table->index_vector);
1646 next_vector = get_array_data(hash_table->next_vector,
1647 SIMPLE_ARRAY_WORD_WIDETAG,
1648 &next_vector_length);
1649 if (next_vector == NULL)
1650 lose("invalid next_vector %x\n", hash_table->next_vector);
1652 hash_vector = get_array_data(hash_table->hash_vector,
1653 SIMPLE_ARRAY_WORD_WIDETAG,
1654 &hash_vector_length);
1655 if (hash_vector != NULL)
1656 gc_assert(hash_vector_length == next_vector_length);
1658 /* These lengths could be different as the index_vector can be a
1659 * different length from the others, a larger index_vector could
1660 * help reduce collisions. */
1661 gc_assert(next_vector_length*2 == kv_length);
1663 empty_symbol = kv_vector[1];
1664 /* fprintf(stderr,"* empty_symbol = %x\n", empty_symbol);*/
1665 if (widetag_of(*(lispobj *)native_pointer(empty_symbol)) !=
1666 SYMBOL_HEADER_WIDETAG) {
1667 lose("not a symbol where empty-hash-table-slot symbol expected: %x\n",
1668 *(lispobj *)native_pointer(empty_symbol));
1671 /* Work through the KV vector. */
1672 for (i = 1; i < next_vector_length; i++) {
1673 lispobj old_key = kv_vector[2*i];
1674 lispobj value = kv_vector[2*i+1];
1675 if ((weakness == NIL) ||
1676 weak_hash_entry_alivep(weakness, old_key, value)) {
1678 /* Scavenge the key and value. */
1679 scavenge(&kv_vector[2*i],2);
1681 /* Rehashing of EQ based keys. */
1682 if ((!hash_vector) ||
1683 (hash_vector[i] == MAGIC_HASH_VECTOR_VALUE)) {
1684 #ifndef LISP_FEATURE_GENCGC
1685 /* For GENCGC scav_hash_table_entries only rehashes
1686 * the entries whose keys were moved. Cheneygc always
1687 * moves the objects so here we let the lisp side know
1688 * that rehashing is needed for the whole table. */
1689 *(kv_vector - 2) = (subtype_VectorMustRehash<<N_WIDETAG_BITS) |
1690 SIMPLE_VECTOR_WIDETAG;
1692 unsigned long old_index = EQ_HASH(old_key)%length;
1693 lispobj new_key = kv_vector[2*i];
1694 unsigned long new_index = EQ_HASH(new_key)%length;
1695 /* Check whether the key has moved. */
1696 if ((old_index != new_index) &&
1697 (new_key != empty_symbol)) {
1698 gc_assert(kv_vector[2*i+1] != empty_symbol);
1701 "* EQ key %d moved from %x to %x; index %d to %d\n",
1702 i, old_key, new_key, old_index, new_index));*/
1704 /* Unlink the key from the old_index chain. */
1705 if (!index_vector[old_index]) {
1706 /* It's not here, must be on the
1707 * needing_rehash chain. */
1708 } else if (index_vector[old_index] == i) {
1709 /*FSHOW((stderr, "/P2a %d\n", next_vector[i]));*/
1710 index_vector[old_index] = next_vector[i];
1711 /* Link it into the needing rehash chain. */
1713 fixnum_value(hash_table->needing_rehash);
1714 hash_table->needing_rehash = make_fixnum(i);
1717 unsigned long prior = index_vector[old_index];
1718 unsigned long next = next_vector[prior];
1720 /*FSHOW((stderr, "/P3a %d %d\n", prior, next));*/
1723 /*FSHOW((stderr, "/P3b %d %d\n", prior, next));*/
1726 next_vector[prior] = next_vector[next];
1727 /* Link it into the needing rehash
1730 fixnum_value(hash_table->needing_rehash);
1731 hash_table->needing_rehash = make_fixnum(next);
1736 next = next_vector[next];
1747 scav_vector (lispobj *where, lispobj object)
1749 unsigned long kv_length;
1751 struct hash_table *hash_table;
1753 /* SB-VM:VECTOR-VALID-HASHING-SUBTYPE is set for EQ-based and weak
1754 * hash tables in the Lisp HASH-TABLE code to indicate need for
1755 * special GC support. */
1756 if (HeaderValue(object) == subtype_VectorNormal)
1759 kv_length = fixnum_value(where[1]);
1760 kv_vector = where + 2; /* Skip the header and length. */
1761 /*FSHOW((stderr,"/kv_length = %d\n", kv_length));*/
1763 /* Scavenge element 0, which may be a hash-table structure. */
1764 scavenge(where+2, 1);
1765 if (!is_lisp_pointer(where[2])) {
1766 lose("no pointer at %x in hash table\n", where[2]);
1768 hash_table = (struct hash_table *)native_pointer(where[2]);
1769 /*FSHOW((stderr,"/hash_table = %x\n", hash_table));*/
1770 if (widetag_of(hash_table->header) != INSTANCE_HEADER_WIDETAG) {
1771 lose("hash table not instance (%x at %x)\n",
1776 /* Scavenge element 1, which should be some internal symbol that
1777 * the hash table code reserves for marking empty slots. */
1778 scavenge(where+3, 1);
1779 if (!is_lisp_pointer(where[3])) {
1780 lose("not empty-hash-table-slot symbol pointer: %x\n", where[3]);
1783 /* Scavenge hash table, which will fix the positions of the other
1784 * needed objects. */
1785 scavenge((lispobj *)hash_table,
1786 sizeof(struct hash_table) / sizeof(lispobj));
1788 /* Cross-check the kv_vector. */
1789 if (where != (lispobj *)native_pointer(hash_table->table)) {
1790 lose("hash_table table!=this table %x\n", hash_table->table);
1793 if (hash_table->weakness == NIL) {
1794 scav_hash_table_entries(hash_table);
1796 /* Delay scavenging of this table by pushing it onto
1797 * weak_hash_tables (if it's not there already) for the weak
1799 if (hash_table->next_weak_hash_table == NIL) {
1800 hash_table->next_weak_hash_table = (lispobj)weak_hash_tables;
1801 weak_hash_tables = hash_table;
1805 return (CEILING(kv_length + 2, 2));
1809 scav_weak_hash_tables (void)
1811 struct hash_table *table;
1813 /* Scavenge entries whose triggers are known to survive. */
1814 for (table = weak_hash_tables; table != NULL;
1815 table = (struct hash_table *)table->next_weak_hash_table) {
1816 scav_hash_table_entries(table);
1820 /* Walk through the chain whose first element is *FIRST and remove
1821 * dead weak entries. */
1823 scan_weak_hash_table_chain (struct hash_table *hash_table, lispobj *prev,
1824 lispobj *kv_vector, lispobj *index_vector,
1825 lispobj *next_vector, lispobj *hash_vector,
1826 lispobj empty_symbol, lispobj weakness)
1828 unsigned index = *prev;
1830 unsigned next = next_vector[index];
1831 lispobj key = kv_vector[2 * index];
1832 lispobj value = kv_vector[2 * index + 1];
1833 gc_assert(key != empty_symbol);
1834 gc_assert(value != empty_symbol);
1835 if (!weak_hash_entry_alivep(weakness, key, value)) {
1836 unsigned count = fixnum_value(hash_table->number_entries);
1837 gc_assert(count > 0);
1839 hash_table->number_entries = make_fixnum(count - 1);
1840 next_vector[index] = fixnum_value(hash_table->next_free_kv);
1841 hash_table->next_free_kv = make_fixnum(index);
1842 kv_vector[2 * index] = empty_symbol;
1843 kv_vector[2 * index + 1] = empty_symbol;
1845 hash_vector[index] = MAGIC_HASH_VECTOR_VALUE;
1847 prev = &next_vector[index];
1854 scan_weak_hash_table (struct hash_table *hash_table)
1857 lispobj *index_vector;
1858 unsigned long length = 0; /* prevent warning */
1859 lispobj *next_vector;
1860 unsigned long next_vector_length = 0; /* prevent warning */
1861 lispobj *hash_vector;
1862 lispobj empty_symbol;
1863 lispobj weakness = hash_table->weakness;
1866 kv_vector = get_array_data(hash_table->table,
1867 SIMPLE_VECTOR_WIDETAG, NULL);
1868 index_vector = get_array_data(hash_table->index_vector,
1869 SIMPLE_ARRAY_WORD_WIDETAG, &length);
1870 next_vector = get_array_data(hash_table->next_vector,
1871 SIMPLE_ARRAY_WORD_WIDETAG,
1872 &next_vector_length);
1873 hash_vector = get_array_data(hash_table->hash_vector,
1874 SIMPLE_ARRAY_WORD_WIDETAG, NULL);
1875 empty_symbol = kv_vector[1];
1877 for (i = 0; i < length; i++) {
1878 scan_weak_hash_table_chain(hash_table, &index_vector[i],
1879 kv_vector, index_vector, next_vector,
1880 hash_vector, empty_symbol, weakness);
1883 lispobj first = fixnum_value(hash_table->needing_rehash);
1884 scan_weak_hash_table_chain(hash_table, &first,
1885 kv_vector, index_vector, next_vector,
1886 hash_vector, empty_symbol, weakness);
1887 hash_table->needing_rehash = make_fixnum(first);
1891 /* Remove dead entries from weak hash tables. */
1893 scan_weak_hash_tables (void)
1895 struct hash_table *table, *next;
1897 for (table = weak_hash_tables; table != NULL; table = next) {
1898 next = (struct hash_table *)table->next_weak_hash_table;
1899 table->next_weak_hash_table = NIL;
1900 scan_weak_hash_table(table);
1903 weak_hash_tables = NULL;
1912 scav_lose(lispobj *where, lispobj object)
1914 lose("no scavenge function for object 0x%08x (widetag 0x%x)\n",
1915 (unsigned long)object,
1916 widetag_of(*(lispobj*)native_pointer(object)));
1918 return 0; /* bogus return value to satisfy static type checking */
1922 trans_lose(lispobj object)
1924 lose("no transport function for object 0x%08x (widetag 0x%x)\n",
1925 (unsigned long)object,
1926 widetag_of(*(lispobj*)native_pointer(object)));
1927 return NIL; /* bogus return value to satisfy static type checking */
1931 size_lose(lispobj *where)
1933 lose("no size function for object at 0x%08x (widetag 0x%x)\n",
1934 (unsigned long)where,
1935 widetag_of(LOW_WORD(where)));
1936 return 1; /* bogus return value to satisfy static type checking */
1945 gc_init_tables(void)
1949 /* Set default value in all slots of scavenge table. FIXME
1950 * replace this gnarly sizeof with something based on
1952 for (i = 0; i < ((sizeof scavtab)/(sizeof scavtab[0])); i++) {
1953 scavtab[i] = scav_lose;
1956 /* For each type which can be selected by the lowtag alone, set
1957 * multiple entries in our widetag scavenge table (one for each
1958 * possible value of the high bits).
1961 for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
1962 scavtab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
1963 scavtab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_fun_pointer;
1964 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1965 scavtab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_list_pointer;
1966 scavtab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
1967 scavtab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_instance_pointer;
1968 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1969 scavtab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_other_pointer;
1972 /* Other-pointer types (those selected by all eight bits of the
1973 * tag) get one entry each in the scavenge table. */
1974 scavtab[BIGNUM_WIDETAG] = scav_unboxed;
1975 scavtab[RATIO_WIDETAG] = scav_boxed;
1976 #if N_WORD_BITS == 64
1977 scavtab[SINGLE_FLOAT_WIDETAG] = scav_immediate;
1979 scavtab[SINGLE_FLOAT_WIDETAG] = scav_unboxed;
1981 scavtab[DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
1982 #ifdef LONG_FLOAT_WIDETAG
1983 scavtab[LONG_FLOAT_WIDETAG] = scav_unboxed;
1985 scavtab[COMPLEX_WIDETAG] = scav_boxed;
1986 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1987 scavtab[COMPLEX_SINGLE_FLOAT_WIDETAG] = scav_unboxed;
1989 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1990 scavtab[COMPLEX_DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
1992 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1993 scavtab[COMPLEX_LONG_FLOAT_WIDETAG] = scav_unboxed;
1995 scavtab[SIMPLE_ARRAY_WIDETAG] = scav_boxed;
1996 scavtab[SIMPLE_BASE_STRING_WIDETAG] = scav_base_string;
1997 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1998 scavtab[SIMPLE_CHARACTER_STRING_WIDETAG] = scav_character_string;
2000 scavtab[SIMPLE_BIT_VECTOR_WIDETAG] = scav_vector_bit;
2001 scavtab[SIMPLE_ARRAY_NIL_WIDETAG] = scav_vector_nil;
2002 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
2003 scav_vector_unsigned_byte_2;
2004 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
2005 scav_vector_unsigned_byte_4;
2006 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
2007 scav_vector_unsigned_byte_8;
2008 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
2009 scav_vector_unsigned_byte_8;
2010 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
2011 scav_vector_unsigned_byte_16;
2012 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
2013 scav_vector_unsigned_byte_16;
2014 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
2015 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
2016 scav_vector_unsigned_byte_32;
2018 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
2019 scav_vector_unsigned_byte_32;
2020 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
2021 scav_vector_unsigned_byte_32;
2022 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
2023 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
2024 scav_vector_unsigned_byte_64;
2026 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
2027 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
2028 scav_vector_unsigned_byte_64;
2030 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
2031 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
2032 scav_vector_unsigned_byte_64;
2034 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
2035 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = scav_vector_unsigned_byte_8;
2037 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
2038 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
2039 scav_vector_unsigned_byte_16;
2041 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
2042 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
2043 scav_vector_unsigned_byte_32;
2045 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
2046 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
2047 scav_vector_unsigned_byte_32;
2049 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
2050 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
2051 scav_vector_unsigned_byte_64;
2053 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
2054 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
2055 scav_vector_unsigned_byte_64;
2057 scavtab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = scav_vector_single_float;
2058 scavtab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = scav_vector_double_float;
2059 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
2060 scavtab[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] = scav_vector_long_float;
2062 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
2063 scavtab[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
2064 scav_vector_complex_single_float;
2066 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
2067 scavtab[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
2068 scav_vector_complex_double_float;
2070 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
2071 scavtab[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
2072 scav_vector_complex_long_float;
2074 scavtab[COMPLEX_BASE_STRING_WIDETAG] = scav_boxed;
2075 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
2076 scavtab[COMPLEX_CHARACTER_STRING_WIDETAG] = scav_boxed;
2078 scavtab[COMPLEX_VECTOR_NIL_WIDETAG] = scav_boxed;
2079 scavtab[COMPLEX_BIT_VECTOR_WIDETAG] = scav_boxed;
2080 scavtab[COMPLEX_VECTOR_WIDETAG] = scav_boxed;
2081 scavtab[COMPLEX_ARRAY_WIDETAG] = scav_boxed;
2082 scavtab[CODE_HEADER_WIDETAG] = scav_code_header;
2083 #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
2084 scavtab[SIMPLE_FUN_HEADER_WIDETAG] = scav_fun_header;
2085 scavtab[RETURN_PC_HEADER_WIDETAG] = scav_return_pc_header;
2087 scavtab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = scav_boxed;
2088 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
2089 scavtab[CLOSURE_HEADER_WIDETAG] = scav_closure_header;
2091 scavtab[CLOSURE_HEADER_WIDETAG] = scav_boxed;
2093 scavtab[VALUE_CELL_HEADER_WIDETAG] = scav_boxed;
2094 scavtab[SYMBOL_HEADER_WIDETAG] = scav_boxed;
2095 scavtab[CHARACTER_WIDETAG] = scav_immediate;
2096 scavtab[SAP_WIDETAG] = scav_unboxed;
2097 scavtab[UNBOUND_MARKER_WIDETAG] = scav_immediate;
2098 scavtab[NO_TLS_VALUE_MARKER_WIDETAG] = scav_immediate;
2099 scavtab[INSTANCE_HEADER_WIDETAG] = scav_instance;
2100 #if defined(LISP_FEATURE_SPARC)
2101 scavtab[FDEFN_WIDETAG] = scav_boxed;
2103 scavtab[FDEFN_WIDETAG] = scav_fdefn;
2105 scavtab[SIMPLE_VECTOR_WIDETAG] = scav_vector;
2107 /* transport other table, initialized same way as scavtab */
2108 for (i = 0; i < ((sizeof transother)/(sizeof transother[0])); i++)
2109 transother[i] = trans_lose;
2110 transother[BIGNUM_WIDETAG] = trans_unboxed;
2111 transother[RATIO_WIDETAG] = trans_boxed;
2113 #if N_WORD_BITS == 64
2114 transother[SINGLE_FLOAT_WIDETAG] = trans_immediate;
2116 transother[SINGLE_FLOAT_WIDETAG] = trans_unboxed;
2118 transother[DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
2119 #ifdef LONG_FLOAT_WIDETAG
2120 transother[LONG_FLOAT_WIDETAG] = trans_unboxed;
2122 transother[COMPLEX_WIDETAG] = trans_boxed;
2123 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
2124 transother[COMPLEX_SINGLE_FLOAT_WIDETAG] = trans_unboxed;
2126 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
2127 transother[COMPLEX_DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
2129 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
2130 transother[COMPLEX_LONG_FLOAT_WIDETAG] = trans_unboxed;
2132 transother[SIMPLE_ARRAY_WIDETAG] = trans_boxed; /* but not GENCGC */
2133 transother[SIMPLE_BASE_STRING_WIDETAG] = trans_base_string;
2134 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
2135 transother[SIMPLE_CHARACTER_STRING_WIDETAG] = trans_character_string;
2137 transother[SIMPLE_BIT_VECTOR_WIDETAG] = trans_vector_bit;
2138 transother[SIMPLE_VECTOR_WIDETAG] = trans_vector;
2139 transother[SIMPLE_ARRAY_NIL_WIDETAG] = trans_vector_nil;
2140 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
2141 trans_vector_unsigned_byte_2;
2142 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
2143 trans_vector_unsigned_byte_4;
2144 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
2145 trans_vector_unsigned_byte_8;
2146 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
2147 trans_vector_unsigned_byte_8;
2148 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
2149 trans_vector_unsigned_byte_16;
2150 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
2151 trans_vector_unsigned_byte_16;
2152 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
2153 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
2154 trans_vector_unsigned_byte_32;
2156 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
2157 trans_vector_unsigned_byte_32;
2158 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
2159 trans_vector_unsigned_byte_32;
2160 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
2161 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
2162 trans_vector_unsigned_byte_64;
2164 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
2165 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
2166 trans_vector_unsigned_byte_64;
2168 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
2169 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
2170 trans_vector_unsigned_byte_64;
2172 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
2173 transother[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] =
2174 trans_vector_unsigned_byte_8;
2176 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
2177 transother[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
2178 trans_vector_unsigned_byte_16;
2180 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
2181 transother[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
2182 trans_vector_unsigned_byte_32;
2184 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
2185 transother[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
2186 trans_vector_unsigned_byte_32;
2188 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
2189 transother[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
2190 trans_vector_unsigned_byte_64;
2192 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
2193 transother[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
2194 trans_vector_unsigned_byte_64;
2196 transother[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] =
2197 trans_vector_single_float;
2198 transother[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] =
2199 trans_vector_double_float;
2200 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
2201 transother[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] =
2202 trans_vector_long_float;
2204 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
2205 transother[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
2206 trans_vector_complex_single_float;
2208 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
2209 transother[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
2210 trans_vector_complex_double_float;
2212 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
2213 transother[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
2214 trans_vector_complex_long_float;
2216 transother[COMPLEX_BASE_STRING_WIDETAG] = trans_boxed;
2217 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
2218 transother[COMPLEX_CHARACTER_STRING_WIDETAG] = trans_boxed;
2220 transother[COMPLEX_BIT_VECTOR_WIDETAG] = trans_boxed;
2221 transother[COMPLEX_VECTOR_NIL_WIDETAG] = trans_boxed;
2222 transother[COMPLEX_VECTOR_WIDETAG] = trans_boxed;
2223 transother[COMPLEX_ARRAY_WIDETAG] = trans_boxed;
2224 transother[CODE_HEADER_WIDETAG] = trans_code_header;
2225 transother[SIMPLE_FUN_HEADER_WIDETAG] = trans_fun_header;
2226 transother[RETURN_PC_HEADER_WIDETAG] = trans_return_pc_header;
2227 transother[CLOSURE_HEADER_WIDETAG] = trans_boxed;
2228 transother[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = trans_boxed;
2229 transother[VALUE_CELL_HEADER_WIDETAG] = trans_boxed;
2230 transother[SYMBOL_HEADER_WIDETAG] = trans_boxed;
2231 transother[CHARACTER_WIDETAG] = trans_immediate;
2232 transother[SAP_WIDETAG] = trans_unboxed;
2233 transother[UNBOUND_MARKER_WIDETAG] = trans_immediate;
2234 transother[NO_TLS_VALUE_MARKER_WIDETAG] = trans_immediate;
2235 transother[WEAK_POINTER_WIDETAG] = trans_weak_pointer;
2236 transother[INSTANCE_HEADER_WIDETAG] = trans_boxed;
2237 transother[FDEFN_WIDETAG] = trans_boxed;
2239 /* size table, initialized the same way as scavtab */
2240 for (i = 0; i < ((sizeof sizetab)/(sizeof sizetab[0])); i++)
2241 sizetab[i] = size_lose;
2242 for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
2243 sizetab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
2244 sizetab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
2245 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
2246 sizetab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
2247 sizetab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
2248 sizetab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
2249 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
2250 sizetab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
2252 sizetab[BIGNUM_WIDETAG] = size_unboxed;
2253 sizetab[RATIO_WIDETAG] = size_boxed;
2254 #if N_WORD_BITS == 64
2255 sizetab[SINGLE_FLOAT_WIDETAG] = size_immediate;
2257 sizetab[SINGLE_FLOAT_WIDETAG] = size_unboxed;
2259 sizetab[DOUBLE_FLOAT_WIDETAG] = size_unboxed;
2260 #ifdef LONG_FLOAT_WIDETAG
2261 sizetab[LONG_FLOAT_WIDETAG] = size_unboxed;
2263 sizetab[COMPLEX_WIDETAG] = size_boxed;
2264 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
2265 sizetab[COMPLEX_SINGLE_FLOAT_WIDETAG] = size_unboxed;
2267 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
2268 sizetab[COMPLEX_DOUBLE_FLOAT_WIDETAG] = size_unboxed;
2270 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
2271 sizetab[COMPLEX_LONG_FLOAT_WIDETAG] = size_unboxed;
2273 sizetab[SIMPLE_ARRAY_WIDETAG] = size_boxed;
2274 sizetab[SIMPLE_BASE_STRING_WIDETAG] = size_base_string;
2275 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
2276 sizetab[SIMPLE_CHARACTER_STRING_WIDETAG] = size_character_string;
2278 sizetab[SIMPLE_BIT_VECTOR_WIDETAG] = size_vector_bit;
2279 sizetab[SIMPLE_VECTOR_WIDETAG] = size_vector;
2280 sizetab[SIMPLE_ARRAY_NIL_WIDETAG] = size_vector_nil;
2281 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
2282 size_vector_unsigned_byte_2;
2283 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
2284 size_vector_unsigned_byte_4;
2285 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
2286 size_vector_unsigned_byte_8;
2287 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
2288 size_vector_unsigned_byte_8;
2289 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
2290 size_vector_unsigned_byte_16;
2291 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
2292 size_vector_unsigned_byte_16;
2293 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
2294 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
2295 size_vector_unsigned_byte_32;
2297 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
2298 size_vector_unsigned_byte_32;
2299 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
2300 size_vector_unsigned_byte_32;
2301 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
2302 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
2303 size_vector_unsigned_byte_64;
2305 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
2306 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
2307 size_vector_unsigned_byte_64;
2309 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
2310 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
2311 size_vector_unsigned_byte_64;
2313 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
2314 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = size_vector_unsigned_byte_8;
2316 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
2317 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
2318 size_vector_unsigned_byte_16;
2320 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
2321 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
2322 size_vector_unsigned_byte_32;
2324 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
2325 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
2326 size_vector_unsigned_byte_32;
2328 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
2329 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
2330 size_vector_unsigned_byte_64;
2332 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
2333 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
2334 size_vector_unsigned_byte_64;
2336 sizetab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = size_vector_single_float;
2337 sizetab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = size_vector_double_float;
2338 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
2339 sizetab[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] = size_vector_long_float;
2341 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
2342 sizetab[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
2343 size_vector_complex_single_float;
2345 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
2346 sizetab[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
2347 size_vector_complex_double_float;
2349 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
2350 sizetab[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
2351 size_vector_complex_long_float;
2353 sizetab[COMPLEX_BASE_STRING_WIDETAG] = size_boxed;
2354 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
2355 sizetab[COMPLEX_CHARACTER_STRING_WIDETAG] = size_boxed;
2357 sizetab[COMPLEX_VECTOR_NIL_WIDETAG] = size_boxed;
2358 sizetab[COMPLEX_BIT_VECTOR_WIDETAG] = size_boxed;
2359 sizetab[COMPLEX_VECTOR_WIDETAG] = size_boxed;
2360 sizetab[COMPLEX_ARRAY_WIDETAG] = size_boxed;
2361 sizetab[CODE_HEADER_WIDETAG] = size_code_header;
2363 /* We shouldn't see these, so just lose if it happens. */
2364 sizetab[SIMPLE_FUN_HEADER_WIDETAG] = size_function_header;
2365 sizetab[RETURN_PC_HEADER_WIDETAG] = size_return_pc_header;
2367 sizetab[CLOSURE_HEADER_WIDETAG] = size_boxed;
2368 sizetab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = size_boxed;
2369 sizetab[VALUE_CELL_HEADER_WIDETAG] = size_boxed;
2370 sizetab[SYMBOL_HEADER_WIDETAG] = size_boxed;
2371 sizetab[CHARACTER_WIDETAG] = size_immediate;
2372 sizetab[SAP_WIDETAG] = size_unboxed;
2373 sizetab[UNBOUND_MARKER_WIDETAG] = size_immediate;
2374 sizetab[NO_TLS_VALUE_MARKER_WIDETAG] = size_immediate;
2375 sizetab[WEAK_POINTER_WIDETAG] = size_weak_pointer;
2376 sizetab[INSTANCE_HEADER_WIDETAG] = size_boxed;
2377 sizetab[FDEFN_WIDETAG] = size_boxed;
2381 /* Find the code object for the given pc, or return NULL on
2384 component_ptr_from_pc(lispobj *pc)
2386 lispobj *object = NULL;
2388 if ( (object = search_read_only_space(pc)) )
2390 else if ( (object = search_static_space(pc)) )
2393 object = search_dynamic_space(pc);
2395 if (object) /* if we found something */
2396 if (widetag_of(*object) == CODE_HEADER_WIDETAG)
2402 /* Scan an area looking for an object which encloses the given pointer.
2403 * Return the object start on success or NULL on failure. */
2405 gc_search_space(lispobj *start, size_t words, lispobj *pointer)
2409 lispobj thing = *start;
2411 /* If thing is an immediate then this is a cons. */
2412 if (is_lisp_pointer(thing)
2414 || (widetag_of(thing) == CHARACTER_WIDETAG)
2415 #if N_WORD_BITS == 64
2416 || (widetag_of(thing) == SINGLE_FLOAT_WIDETAG)
2418 || (widetag_of(thing) == UNBOUND_MARKER_WIDETAG))
2421 count = (sizetab[widetag_of(thing)])(start);
2423 /* Check whether the pointer is within this object. */
2424 if ((pointer >= start) && (pointer < (start+count))) {
2426 /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/
2430 /* Round up the count. */
2431 count = CEILING(count,2);
2440 maybe_gc(os_context_t *context)
2442 #ifndef LISP_FEATURE_WIN32
2443 struct thread *thread = arch_os_get_current_thread();
2446 fake_foreign_function_call(context);
2447 /* SUB-GC may return without GCing if *GC-INHIBIT* is set, in
2448 * which case we will be running with no gc trigger barrier
2449 * thing for a while. But it shouldn't be long until the end
2452 * FIXME: It would be good to protect the end of dynamic space for
2453 * CheneyGC and signal a storage condition from there.
2456 /* Restore the signal mask from the interrupted context before
2457 * calling into Lisp if interrupts are enabled. Why not always?
2459 * Suppose there is a WITHOUT-INTERRUPTS block far, far out. If an
2460 * interrupt hits while in SUB-GC, it is deferred and the
2461 * os_context_sigmask of that interrupt is set to block further
2462 * deferrable interrupts (until the first one is
2463 * handled). Unfortunately, that context refers to this place and
2464 * when we return from here the signals will not be blocked.
2466 * A kludgy alternative is to propagate the sigmask change to the
2469 #ifndef LISP_FEATURE_WIN32
2470 if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) {
2471 sigset_t *context_sigmask = os_context_sigmask_addr(context);
2472 #ifdef LISP_FEATURE_SB_THREAD
2473 /* What if the context we'd like to restore has GC signals
2474 * blocked? Just skip the GC: we can't set GC_PENDING, because
2475 * that would block the next attempt, and we don't know when
2476 * we'd next check for it -- and it's hard to be sure that
2477 * unblocking would be safe. */
2478 if (sigismember(context_sigmask,SIG_STOP_FOR_GC)) {
2479 undo_fake_foreign_function_call(context);
2483 thread_sigmask(SIG_SETMASK, context_sigmask, 0);
2486 unblock_gc_signals();
2488 /* SIG_STOP_FOR_GC needs to be enabled before we can call lisp:
2489 * otherwise two threads racing here may deadlock: the other will
2490 * wait on the GC lock, and the other cannot stop the first one... */
2491 funcall0(SymbolFunction(SUB_GC));
2492 undo_fake_foreign_function_call(context);