0.8.7.11:
[sbcl/lichteblau.git] / src / runtime / gc-common.c
blob26bc938b8a803ecd4d31d8eaa5a8496362b6ac06
1 /*
2 * Garbage Collection common functions for scavenging, moving and sizing
3 * objects. These are for use with both GC (stop & copy GC) and GENCGC
4 */
6 /*
7 * This software is part of the SBCL system. See the README file for
8 * more information.
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 * GENerational Conservative Garbage Collector for SBCL x86
22 * This software is part of the SBCL system. See the README file for
23 * more information.
25 * This software is derived from the CMU CL system, which was
26 * written at Carnegie Mellon University and released into the
27 * public domain. The software is in the public domain and is
28 * provided with absolutely no warranty. See the COPYING and CREDITS
29 * files for more information.
33 * For a review of garbage collection techniques (e.g. generational
34 * GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
35 * "Uniprocessor Garbage Collection Techniques". As of 20000618, this
36 * had been accepted for _ACM Computing Surveys_ and was available
37 * as a PostScript preprint through
38 * <http://www.cs.utexas.edu/users/oops/papers.html>
39 * as
40 * <ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps>.
43 #include <stdio.h>
44 #include <signal.h>
45 #include <string.h>
46 #include "runtime.h"
47 #include "sbcl.h"
48 #include "os.h"
49 #include "interr.h"
50 #include "globals.h"
51 #include "interrupt.h"
52 #include "validate.h"
53 #include "lispregs.h"
54 #include "arch.h"
55 #include "gc.h"
56 #include "genesis/primitive-objects.h"
57 #include "genesis/static-symbols.h"
58 #include "gc-internal.h"
60 #ifdef LISP_FEATURE_SPARC
61 #define LONG_FLOAT_SIZE 4
62 #else
63 #ifdef LISP_FEATURE_X86
64 #define LONG_FLOAT_SIZE 3
65 #endif
66 #endif
68 inline static boolean
69 forwarding_pointer_p(lispobj *pointer) {
70 lispobj first_word=*pointer;
71 #ifdef LISP_FEATURE_GENCGC
72 return (first_word == 0x01);
73 #else
74 return (is_lisp_pointer(first_word)
75 && new_space_p(first_word));
76 #endif
79 static inline lispobj *
80 forwarding_pointer_value(lispobj *pointer) {
81 #ifdef LISP_FEATURE_GENCGC
82 return (lispobj *) ((pointer_sized_uint_t) pointer[1]);
83 #else
84 return (lispobj *) ((pointer_sized_uint_t) pointer[0]);
85 #endif
87 static inline lispobj
88 set_forwarding_pointer(lispobj * pointer, lispobj newspace_copy) {
89 #ifdef LISP_FEATURE_GENCGC
90 pointer[0]=0x01;
91 pointer[1]=newspace_copy;
92 #else
93 pointer[0]=newspace_copy;
94 #endif
95 return newspace_copy;
98 int (*scavtab[256])(lispobj *where, lispobj object);
99 lispobj (*transother[256])(lispobj object);
100 int (*sizetab[256])(lispobj *where);
101 struct weak_pointer *weak_pointers;
103 unsigned long bytes_consed_between_gcs = 12*1024*1024;
107 * copying objects
110 /* to copy a boxed object */
111 lispobj
112 copy_object(lispobj object, int nwords)
114 int tag;
115 lispobj *new;
117 gc_assert(is_lisp_pointer(object));
118 gc_assert(from_space_p(object));
119 gc_assert((nwords & 0x01) == 0);
121 /* Get tag of object. */
122 tag = lowtag_of(object);
124 /* Allocate space. */
125 new = gc_general_alloc(nwords*4,ALLOC_BOXED,ALLOC_QUICK);
127 /* Copy the object. */
128 memcpy(new,native_pointer(object),nwords*4);
129 return make_lispobj(new,tag);
132 static int scav_lose(lispobj *where, lispobj object); /* forward decl */
134 /* FIXME: Most calls end up going to some trouble to compute an
135 * 'n_words' value for this function. The system might be a little
136 * simpler if this function used an 'end' parameter instead. */
137 void
138 scavenge(lispobj *start, long n_words)
140 lispobj *end = start + n_words;
141 lispobj *object_ptr;
142 int n_words_scavenged;
143 for (object_ptr = start;
144 object_ptr < end;
145 object_ptr += n_words_scavenged) {
147 lispobj object = *object_ptr;
148 #ifdef LISP_FEATURE_GENCGC
149 gc_assert(!forwarding_pointer_p(object_ptr));
150 #endif
151 if (is_lisp_pointer(object)) {
152 if (from_space_p(object)) {
153 /* It currently points to old space. Check for a
154 * forwarding pointer. */
155 lispobj *ptr = native_pointer(object);
156 if (forwarding_pointer_p(ptr)) {
157 /* Yes, there's a forwarding pointer. */
158 *object_ptr = LOW_WORD(forwarding_pointer_value(ptr));
159 n_words_scavenged = 1;
160 } else {
161 /* Scavenge that pointer. */
162 n_words_scavenged =
163 (scavtab[widetag_of(object)])(object_ptr, object);
165 } else {
166 /* It points somewhere other than oldspace. Leave it
167 * alone. */
168 n_words_scavenged = 1;
171 #ifndef LISP_FEATURE_GENCGC
172 /* this workaround is probably not necessary for gencgc; at least, the
173 * behaviour it describes has never been reported */
174 else if (n_words==1) {
175 /* there are some situations where an
176 other-immediate may end up in a descriptor
177 register. I'm not sure whether this is
178 supposed to happen, but if it does then we
179 don't want to (a) barf or (b) scavenge over the
180 data-block, because there isn't one. So, if
181 we're checking a single word and it's anything
182 other than a pointer, just hush it up */
183 int type=widetag_of(object);
184 n_words_scavenged=1;
186 if ((scavtab[type]==scav_lose) ||
187 (((scavtab[type])(start,object))>1)) {
188 fprintf(stderr,"warning: attempted to scavenge non-descriptor value %x at %p. If you can\nreproduce this warning, send a bug report (see manual page for details)\n",
189 object,start);
192 #endif
193 else if ((object & 3) == 0) {
194 /* It's a fixnum: really easy.. */
195 n_words_scavenged = 1;
196 } else {
197 /* It's some sort of header object or another. */
198 n_words_scavenged =
199 (scavtab[widetag_of(object)])(object_ptr, object);
202 gc_assert(object_ptr == end);
205 static lispobj trans_fun_header(lispobj object); /* forward decls */
206 static lispobj trans_boxed(lispobj object);
208 static int
209 scav_fun_pointer(lispobj *where, lispobj object)
211 lispobj *first_pointer;
212 lispobj copy;
214 gc_assert(is_lisp_pointer(object));
216 /* Object is a pointer into from_space - not a FP. */
217 first_pointer = (lispobj *) native_pointer(object);
219 /* must transport object -- object may point to either a function
220 * header, a closure function header, or to a closure header. */
222 switch (widetag_of(*first_pointer)) {
223 case SIMPLE_FUN_HEADER_WIDETAG:
224 copy = trans_fun_header(object);
225 break;
226 default:
227 copy = trans_boxed(object);
228 break;
231 if (copy != object) {
232 /* Set forwarding pointer */
233 set_forwarding_pointer(first_pointer,copy);
236 gc_assert(is_lisp_pointer(copy));
237 gc_assert(!from_space_p(copy));
239 *where = copy;
241 return 1;
245 static struct code *
246 trans_code(struct code *code)
248 struct code *new_code;
249 lispobj first, l_code, l_new_code;
250 int nheader_words, ncode_words, nwords;
251 unsigned long displacement;
252 lispobj fheaderl, *prev_pointer;
254 /* if object has already been transported, just return pointer */
255 first = code->header;
256 if (forwarding_pointer_p((lispobj *)code)) {
257 #ifdef DEBUG_CODE_GC
258 printf("Was already transported\n");
259 #endif
260 return (struct code *) forwarding_pointer_value
261 ((lispobj *)((pointer_sized_uint_t) code));
264 gc_assert(widetag_of(first) == CODE_HEADER_WIDETAG);
266 /* prepare to transport the code vector */
267 l_code = (lispobj) LOW_WORD(code) | OTHER_POINTER_LOWTAG;
269 ncode_words = fixnum_value(code->code_size);
270 nheader_words = HeaderValue(code->header);
271 nwords = ncode_words + nheader_words;
272 nwords = CEILING(nwords, 2);
274 l_new_code = copy_object(l_code, nwords);
275 new_code = (struct code *) native_pointer(l_new_code);
277 #if defined(DEBUG_CODE_GC)
278 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
279 (unsigned long) code, (unsigned long) new_code);
280 printf("Code object is %d words long.\n", nwords);
281 #endif
283 #ifdef LISP_FEATURE_GENCGC
284 if (new_code == code)
285 return new_code;
286 #endif
288 displacement = l_new_code - l_code;
290 set_forwarding_pointer((lispobj *)code, l_new_code);
292 /* set forwarding pointers for all the function headers in the */
293 /* code object. also fix all self pointers */
295 fheaderl = code->entry_points;
296 prev_pointer = &new_code->entry_points;
298 while (fheaderl != NIL) {
299 struct simple_fun *fheaderp, *nfheaderp;
300 lispobj nfheaderl;
302 fheaderp = (struct simple_fun *) native_pointer(fheaderl);
303 gc_assert(widetag_of(fheaderp->header) == SIMPLE_FUN_HEADER_WIDETAG);
305 /* Calculate the new function pointer and the new */
306 /* function header. */
307 nfheaderl = fheaderl + displacement;
308 nfheaderp = (struct simple_fun *) native_pointer(nfheaderl);
310 #ifdef DEBUG_CODE_GC
311 printf("fheaderp->header (at %x) <- %x\n",
312 &(fheaderp->header) , nfheaderl);
313 #endif
314 set_forwarding_pointer((lispobj *)fheaderp, nfheaderl);
316 /* fix self pointer. */
317 nfheaderp->self =
318 #ifdef LISP_FEATURE_X86
319 FUN_RAW_ADDR_OFFSET +
320 #endif
321 nfheaderl;
323 *prev_pointer = nfheaderl;
325 fheaderl = fheaderp->next;
326 prev_pointer = &nfheaderp->next;
328 os_flush_icache((os_vm_address_t) (((int *)new_code) + nheader_words),
329 ncode_words * sizeof(int));
330 #ifdef LISP_FEATURE_GENCGC
331 gencgc_apply_code_fixups(code, new_code);
332 #endif
333 return new_code;
336 static int
337 scav_code_header(lispobj *where, lispobj object)
339 struct code *code;
340 int n_header_words, n_code_words, n_words;
341 lispobj entry_point; /* tagged pointer to entry point */
342 struct simple_fun *function_ptr; /* untagged pointer to entry point */
344 code = (struct code *) where;
345 n_code_words = fixnum_value(code->code_size);
346 n_header_words = HeaderValue(object);
347 n_words = n_code_words + n_header_words;
348 n_words = CEILING(n_words, 2);
350 /* Scavenge the boxed section of the code data block. */
351 scavenge(where + 1, n_header_words - 1);
353 /* Scavenge the boxed section of each function object in the
354 * code data block. */
355 for (entry_point = code->entry_points;
356 entry_point != NIL;
357 entry_point = function_ptr->next) {
359 gc_assert(is_lisp_pointer(entry_point));
361 function_ptr = (struct simple_fun *) native_pointer(entry_point);
362 gc_assert(widetag_of(function_ptr->header)==SIMPLE_FUN_HEADER_WIDETAG);
364 scavenge(&function_ptr->name, 1);
365 scavenge(&function_ptr->arglist, 1);
366 scavenge(&function_ptr->type, 1);
369 return n_words;
372 static lispobj
373 trans_code_header(lispobj object)
375 struct code *ncode;
377 ncode = trans_code((struct code *) native_pointer(object));
378 return (lispobj) LOW_WORD(ncode) | OTHER_POINTER_LOWTAG;
382 static int
383 size_code_header(lispobj *where)
385 struct code *code;
386 int nheader_words, ncode_words, nwords;
388 code = (struct code *) where;
390 ncode_words = fixnum_value(code->code_size);
391 nheader_words = HeaderValue(code->header);
392 nwords = ncode_words + nheader_words;
393 nwords = CEILING(nwords, 2);
395 return nwords;
398 static int
399 scav_return_pc_header(lispobj *where, lispobj object)
401 lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x",
402 (unsigned long) where,
403 (unsigned long) object);
404 return 0; /* bogus return value to satisfy static type checking */
407 static lispobj
408 trans_return_pc_header(lispobj object)
410 struct simple_fun *return_pc;
411 unsigned long offset;
412 struct code *code, *ncode;
414 return_pc = (struct simple_fun *) native_pointer(object);
415 offset = HeaderValue(return_pc->header) * 4 ;
417 /* Transport the whole code object */
418 code = (struct code *) ((unsigned long) return_pc - offset);
419 ncode = trans_code(code);
421 return ((lispobj) LOW_WORD(ncode) + offset) | OTHER_POINTER_LOWTAG;
424 /* On the 386, closures hold a pointer to the raw address instead of the
425 * function object, so we can use CALL [$FDEFN+const] to invoke
426 * the function without loading it into a register. Given that code
427 * objects don't move, we don't need to update anything, but we do
428 * have to figure out that the function is still live. */
430 #ifdef LISP_FEATURE_X86
431 static int
432 scav_closure_header(lispobj *where, lispobj object)
434 struct closure *closure;
435 lispobj fun;
437 closure = (struct closure *)where;
438 fun = closure->fun - FUN_RAW_ADDR_OFFSET;
439 scavenge(&fun, 1);
440 #ifdef LISP_FEATURE_GENCGC
441 /* The function may have moved so update the raw address. But
442 * don't write unnecessarily. */
443 if (closure->fun != fun + FUN_RAW_ADDR_OFFSET)
444 closure->fun = fun + FUN_RAW_ADDR_OFFSET;
445 #endif
446 return 2;
448 #endif
450 static int
451 scav_fun_header(lispobj *where, lispobj object)
453 lose("attempted to scavenge a function header where=0x%08x object=0x%08x",
454 (unsigned long) where,
455 (unsigned long) object);
456 return 0; /* bogus return value to satisfy static type checking */
459 static lispobj
460 trans_fun_header(lispobj object)
462 struct simple_fun *fheader;
463 unsigned long offset;
464 struct code *code, *ncode;
466 fheader = (struct simple_fun *) native_pointer(object);
467 offset = HeaderValue(fheader->header) * 4;
469 /* Transport the whole code object */
470 code = (struct code *) ((unsigned long) fheader - offset);
471 ncode = trans_code(code);
473 return ((lispobj) LOW_WORD(ncode) + offset) | FUN_POINTER_LOWTAG;
478 * instances
481 static int
482 scav_instance_pointer(lispobj *where, lispobj object)
484 lispobj copy, *first_pointer;
486 /* Object is a pointer into from space - not a FP. */
487 copy = trans_boxed(object);
489 #ifdef LISP_FEATURE_GENCGC
490 gc_assert(copy != object);
491 #endif
493 first_pointer = (lispobj *) native_pointer(object);
494 set_forwarding_pointer(first_pointer,copy);
495 *where = copy;
497 return 1;
502 * lists and conses
505 static lispobj trans_list(lispobj object);
507 static int
508 scav_list_pointer(lispobj *where, lispobj object)
510 lispobj first, *first_pointer;
512 gc_assert(is_lisp_pointer(object));
514 /* Object is a pointer into from space - not FP. */
515 first_pointer = (lispobj *) native_pointer(object);
517 first = trans_list(object);
518 gc_assert(first != object);
520 /* Set forwarding pointer */
521 set_forwarding_pointer(first_pointer, first);
523 gc_assert(is_lisp_pointer(first));
524 gc_assert(!from_space_p(first));
526 *where = first;
527 return 1;
531 static lispobj
532 trans_list(lispobj object)
534 lispobj new_list_pointer;
535 struct cons *cons, *new_cons;
536 lispobj cdr;
538 cons = (struct cons *) native_pointer(object);
540 /* Copy 'object'. */
541 new_cons = (struct cons *)
542 gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK);
543 new_cons->car = cons->car;
544 new_cons->cdr = cons->cdr; /* updated later */
545 new_list_pointer = make_lispobj(new_cons,lowtag_of(object));
547 /* Grab the cdr: set_forwarding_pointer will clobber it in GENCGC */
548 cdr = cons->cdr;
550 set_forwarding_pointer((lispobj *)cons, new_list_pointer);
552 /* Try to linearize the list in the cdr direction to help reduce
553 * paging. */
554 while (1) {
555 lispobj new_cdr;
556 struct cons *cdr_cons, *new_cdr_cons;
558 if(lowtag_of(cdr) != LIST_POINTER_LOWTAG ||
559 !from_space_p(cdr) ||
560 forwarding_pointer_p((lispobj *)native_pointer(cdr)))
561 break;
563 cdr_cons = (struct cons *) native_pointer(cdr);
565 /* Copy 'cdr'. */
566 new_cdr_cons = (struct cons*)
567 gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK);
568 new_cdr_cons->car = cdr_cons->car;
569 new_cdr_cons->cdr = cdr_cons->cdr;
570 new_cdr = make_lispobj(new_cdr_cons, lowtag_of(cdr));
572 /* Grab the cdr before it is clobbered. */
573 cdr = cdr_cons->cdr;
574 set_forwarding_pointer((lispobj *)cdr_cons, new_cdr);
576 /* Update the cdr of the last cons copied into new space to
577 * keep the newspace scavenge from having to do it. */
578 new_cons->cdr = new_cdr;
580 new_cons = new_cdr_cons;
583 return new_list_pointer;
588 * scavenging and transporting other pointers
591 static int
592 scav_other_pointer(lispobj *where, lispobj object)
594 lispobj first, *first_pointer;
596 gc_assert(is_lisp_pointer(object));
598 /* Object is a pointer into from space - not FP. */
599 first_pointer = (lispobj *) native_pointer(object);
600 first = (transother[widetag_of(*first_pointer)])(object);
602 if (first != object) {
603 set_forwarding_pointer(first_pointer, first);
604 #ifdef LISP_FEATURE_GENCGC
605 *where = first;
606 #endif
608 #ifndef LISP_FEATURE_GENCGC
609 *where = first;
610 #endif
611 gc_assert(is_lisp_pointer(first));
612 gc_assert(!from_space_p(first));
614 return 1;
618 * immediate, boxed, and unboxed objects
621 static int
622 size_pointer(lispobj *where)
624 return 1;
627 static int
628 scav_immediate(lispobj *where, lispobj object)
630 return 1;
633 static lispobj
634 trans_immediate(lispobj object)
636 lose("trying to transport an immediate");
637 return NIL; /* bogus return value to satisfy static type checking */
640 static int
641 size_immediate(lispobj *where)
643 return 1;
647 static int
648 scav_boxed(lispobj *where, lispobj object)
650 return 1;
653 static lispobj
654 trans_boxed(lispobj object)
656 lispobj header;
657 unsigned long length;
659 gc_assert(is_lisp_pointer(object));
661 header = *((lispobj *) native_pointer(object));
662 length = HeaderValue(header) + 1;
663 length = CEILING(length, 2);
665 return copy_object(object, length);
669 static int
670 size_boxed(lispobj *where)
672 lispobj header;
673 unsigned long length;
675 header = *where;
676 length = HeaderValue(header) + 1;
677 length = CEILING(length, 2);
679 return length;
682 /* Note: on the sparc we don't have to do anything special for fdefns, */
683 /* 'cause the raw-addr has a function lowtag. */
684 #ifndef LISP_FEATURE_SPARC
685 static int
686 scav_fdefn(lispobj *where, lispobj object)
688 struct fdefn *fdefn;
690 fdefn = (struct fdefn *)where;
692 /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n",
693 fdefn->fun, fdefn->raw_addr)); */
695 if ((char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET)
696 == (char *)((unsigned long)(fdefn->raw_addr))) {
697 scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1);
699 /* Don't write unnecessarily. */
700 if (fdefn->raw_addr != (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET))
701 fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET);
702 /* gc.c has more casts here, which may be relevant or alternatively
703 may be compiler warning defeaters. try
704 fdefn->raw_addr =
705 (u32) ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET;
707 return sizeof(struct fdefn) / sizeof(lispobj);
708 } else {
709 return 1;
712 #endif
714 static int
715 scav_unboxed(lispobj *where, lispobj object)
717 unsigned long length;
719 length = HeaderValue(object) + 1;
720 length = CEILING(length, 2);
722 return length;
725 static lispobj
726 trans_unboxed(lispobj object)
728 lispobj header;
729 unsigned long length;
732 gc_assert(is_lisp_pointer(object));
734 header = *((lispobj *) native_pointer(object));
735 length = HeaderValue(header) + 1;
736 length = CEILING(length, 2);
738 return copy_unboxed_object(object, length);
741 static int
742 size_unboxed(lispobj *where)
744 lispobj header;
745 unsigned long length;
747 header = *where;
748 length = HeaderValue(header) + 1;
749 length = CEILING(length, 2);
751 return length;
754 static int\f
755 /* vector-like objects */
757 #define NWORDS(x,y) (CEILING((x),(y)) / (y))
759 scav_base_string(lispobj *where, lispobj object)
761 struct vector *vector;
762 int length, nwords;
764 /* NOTE: Strings contain one more byte of data than the length */
765 /* slot indicates. */
767 vector = (struct vector *) where;
768 length = fixnum_value(vector->length) + 1;
769 nwords = CEILING(NWORDS(length, 4) + 2, 2);
771 return nwords;
773 static lispobj
774 trans_base_string(lispobj object)
776 struct vector *vector;
777 int length, nwords;
779 gc_assert(is_lisp_pointer(object));
781 /* NOTE: A string contains one more byte of data (a terminating
782 * '\0' to help when interfacing with C functions) than indicated
783 * by the length slot. */
785 vector = (struct vector *) native_pointer(object);
786 length = fixnum_value(vector->length) + 1;
787 nwords = CEILING(NWORDS(length, 4) + 2, 2);
789 return copy_large_unboxed_object(object, nwords);
792 static int
793 size_base_string(lispobj *where)
795 struct vector *vector;
796 int length, nwords;
798 /* NOTE: A string contains one more byte of data (a terminating
799 * '\0' to help when interfacing with C functions) than indicated
800 * by the length slot. */
802 vector = (struct vector *) where;
803 length = fixnum_value(vector->length) + 1;
804 nwords = CEILING(NWORDS(length, 4) + 2, 2);
806 return nwords;
809 static lispobj
810 trans_vector(lispobj object)
812 struct vector *vector;
813 int length, nwords;
815 gc_assert(is_lisp_pointer(object));
817 vector = (struct vector *) native_pointer(object);
819 length = fixnum_value(vector->length);
820 nwords = CEILING(length + 2, 2);
822 return copy_large_object(object, nwords);
825 static int
826 size_vector(lispobj *where)
828 struct vector *vector;
829 int length, nwords;
831 vector = (struct vector *) where;
832 length = fixnum_value(vector->length);
833 nwords = CEILING(length + 2, 2);
835 return nwords;
838 static int
839 scav_vector_nil(lispobj *where, lispobj object)
841 return 2;
844 static lispobj
845 trans_vector_nil(lispobj object)
847 gc_assert(is_lisp_pointer(object));
848 return copy_unboxed_object(object, 2);
851 static int
852 size_vector_nil(lispobj *where)
854 /* Just the header word and the length word */
855 return 2;
858 static int
859 scav_vector_bit(lispobj *where, lispobj object)
861 struct vector *vector;
862 int length, nwords;
864 vector = (struct vector *) where;
865 length = fixnum_value(vector->length);
866 nwords = CEILING(NWORDS(length, 32) + 2, 2);
868 return nwords;
871 static lispobj
872 trans_vector_bit(lispobj object)
874 struct vector *vector;
875 int length, nwords;
877 gc_assert(is_lisp_pointer(object));
879 vector = (struct vector *) native_pointer(object);
880 length = fixnum_value(vector->length);
881 nwords = CEILING(NWORDS(length, 32) + 2, 2);
883 return copy_large_unboxed_object(object, nwords);
886 static int
887 size_vector_bit(lispobj *where)
889 struct vector *vector;
890 int length, nwords;
892 vector = (struct vector *) where;
893 length = fixnum_value(vector->length);
894 nwords = CEILING(NWORDS(length, 32) + 2, 2);
896 return nwords;
899 static int
900 scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
902 struct vector *vector;
903 int length, nwords;
905 vector = (struct vector *) where;
906 length = fixnum_value(vector->length);
907 nwords = CEILING(NWORDS(length, 16) + 2, 2);
909 return nwords;
912 static lispobj
913 trans_vector_unsigned_byte_2(lispobj object)
915 struct vector *vector;
916 int length, nwords;
918 gc_assert(is_lisp_pointer(object));
920 vector = (struct vector *) native_pointer(object);
921 length = fixnum_value(vector->length);
922 nwords = CEILING(NWORDS(length, 16) + 2, 2);
924 return copy_large_unboxed_object(object, nwords);
927 static int
928 size_vector_unsigned_byte_2(lispobj *where)
930 struct vector *vector;
931 int length, nwords;
933 vector = (struct vector *) where;
934 length = fixnum_value(vector->length);
935 nwords = CEILING(NWORDS(length, 16) + 2, 2);
937 return nwords;
940 static int
941 scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
943 struct vector *vector;
944 int length, nwords;
946 vector = (struct vector *) where;
947 length = fixnum_value(vector->length);
948 nwords = CEILING(NWORDS(length, 8) + 2, 2);
950 return nwords;
953 static lispobj
954 trans_vector_unsigned_byte_4(lispobj object)
956 struct vector *vector;
957 int length, nwords;
959 gc_assert(is_lisp_pointer(object));
961 vector = (struct vector *) native_pointer(object);
962 length = fixnum_value(vector->length);
963 nwords = CEILING(NWORDS(length, 8) + 2, 2);
965 return copy_large_unboxed_object(object, nwords);
967 static int
968 size_vector_unsigned_byte_4(lispobj *where)
970 struct vector *vector;
971 int length, nwords;
973 vector = (struct vector *) where;
974 length = fixnum_value(vector->length);
975 nwords = CEILING(NWORDS(length, 8) + 2, 2);
977 return nwords;
981 static int
982 scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
984 struct vector *vector;
985 int length, nwords;
987 vector = (struct vector *) where;
988 length = fixnum_value(vector->length);
989 nwords = CEILING(NWORDS(length, 4) + 2, 2);
991 return nwords;
994 /*********************/
998 static lispobj
999 trans_vector_unsigned_byte_8(lispobj object)
1001 struct vector *vector;
1002 int length, nwords;
1004 gc_assert(is_lisp_pointer(object));
1006 vector = (struct vector *) native_pointer(object);
1007 length = fixnum_value(vector->length);
1008 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1010 return copy_large_unboxed_object(object, nwords);
1013 static int
1014 size_vector_unsigned_byte_8(lispobj *where)
1016 struct vector *vector;
1017 int length, nwords;
1019 vector = (struct vector *) where;
1020 length = fixnum_value(vector->length);
1021 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1023 return nwords;
1027 static int
1028 scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
1030 struct vector *vector;
1031 int length, nwords;
1033 vector = (struct vector *) where;
1034 length = fixnum_value(vector->length);
1035 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1037 return nwords;
1040 static lispobj
1041 trans_vector_unsigned_byte_16(lispobj object)
1043 struct vector *vector;
1044 int length, nwords;
1046 gc_assert(is_lisp_pointer(object));
1048 vector = (struct vector *) native_pointer(object);
1049 length = fixnum_value(vector->length);
1050 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1052 return copy_large_unboxed_object(object, nwords);
1055 static int
1056 size_vector_unsigned_byte_16(lispobj *where)
1058 struct vector *vector;
1059 int length, nwords;
1061 vector = (struct vector *) where;
1062 length = fixnum_value(vector->length);
1063 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1065 return nwords;
1068 static int
1069 scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
1071 struct vector *vector;
1072 int length, nwords;
1074 vector = (struct vector *) where;
1075 length = fixnum_value(vector->length);
1076 nwords = CEILING(length + 2, 2);
1078 return nwords;
1081 static lispobj
1082 trans_vector_unsigned_byte_32(lispobj object)
1084 struct vector *vector;
1085 int length, nwords;
1087 gc_assert(is_lisp_pointer(object));
1089 vector = (struct vector *) native_pointer(object);
1090 length = fixnum_value(vector->length);
1091 nwords = CEILING(length + 2, 2);
1093 return copy_large_unboxed_object(object, nwords);
1096 static int
1097 size_vector_unsigned_byte_32(lispobj *where)
1099 struct vector *vector;
1100 int length, nwords;
1102 vector = (struct vector *) where;
1103 length = fixnum_value(vector->length);
1104 nwords = CEILING(length + 2, 2);
1106 return nwords;
1109 static int
1110 scav_vector_single_float(lispobj *where, lispobj object)
1112 struct vector *vector;
1113 int length, nwords;
1115 vector = (struct vector *) where;
1116 length = fixnum_value(vector->length);
1117 nwords = CEILING(length + 2, 2);
1119 return nwords;
1122 static lispobj
1123 trans_vector_single_float(lispobj object)
1125 struct vector *vector;
1126 int length, nwords;
1128 gc_assert(is_lisp_pointer(object));
1130 vector = (struct vector *) native_pointer(object);
1131 length = fixnum_value(vector->length);
1132 nwords = CEILING(length + 2, 2);
1134 return copy_large_unboxed_object(object, nwords);
1137 static int
1138 size_vector_single_float(lispobj *where)
1140 struct vector *vector;
1141 int length, nwords;
1143 vector = (struct vector *) where;
1144 length = fixnum_value(vector->length);
1145 nwords = CEILING(length + 2, 2);
1147 return nwords;
1150 static int
1151 scav_vector_double_float(lispobj *where, lispobj object)
1153 struct vector *vector;
1154 int length, nwords;
1156 vector = (struct vector *) where;
1157 length = fixnum_value(vector->length);
1158 nwords = CEILING(length * 2 + 2, 2);
1160 return nwords;
1163 static lispobj
1164 trans_vector_double_float(lispobj object)
1166 struct vector *vector;
1167 int length, nwords;
1169 gc_assert(is_lisp_pointer(object));
1171 vector = (struct vector *) native_pointer(object);
1172 length = fixnum_value(vector->length);
1173 nwords = CEILING(length * 2 + 2, 2);
1175 return copy_large_unboxed_object(object, nwords);
1178 static int
1179 size_vector_double_float(lispobj *where)
1181 struct vector *vector;
1182 int length, nwords;
1184 vector = (struct vector *) where;
1185 length = fixnum_value(vector->length);
1186 nwords = CEILING(length * 2 + 2, 2);
1188 return nwords;
1191 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1192 static int
1193 scav_vector_long_float(lispobj *where, lispobj object)
1195 struct vector *vector;
1196 int length, nwords;
1198 vector = (struct vector *) where;
1199 length = fixnum_value(vector->length);
1200 nwords = CEILING(length *
1201 LONG_FLOAT_SIZE
1202 + 2, 2);
1203 return nwords;
1206 static lispobj
1207 trans_vector_long_float(lispobj object)
1209 struct vector *vector;
1210 int length, nwords;
1212 gc_assert(is_lisp_pointer(object));
1214 vector = (struct vector *) native_pointer(object);
1215 length = fixnum_value(vector->length);
1216 nwords = CEILING(length * LONG_FLOAT_SIZE + 2, 2);
1218 return copy_large_unboxed_object(object, nwords);
1221 static int
1222 size_vector_long_float(lispobj *where)
1224 struct vector *vector;
1225 int length, nwords;
1227 vector = (struct vector *) where;
1228 length = fixnum_value(vector->length);
1229 nwords = CEILING(length * LONG_FLOAT_SIZE + 2, 2);
1231 return nwords;
1233 #endif
1236 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1237 static int
1238 scav_vector_complex_single_float(lispobj *where, lispobj object)
1240 struct vector *vector;
1241 int length, nwords;
1243 vector = (struct vector *) where;
1244 length = fixnum_value(vector->length);
1245 nwords = CEILING(length * 2 + 2, 2);
1247 return nwords;
1250 static lispobj
1251 trans_vector_complex_single_float(lispobj object)
1253 struct vector *vector;
1254 int length, nwords;
1256 gc_assert(is_lisp_pointer(object));
1258 vector = (struct vector *) native_pointer(object);
1259 length = fixnum_value(vector->length);
1260 nwords = CEILING(length * 2 + 2, 2);
1262 return copy_large_unboxed_object(object, nwords);
1265 static int
1266 size_vector_complex_single_float(lispobj *where)
1268 struct vector *vector;
1269 int length, nwords;
1271 vector = (struct vector *) where;
1272 length = fixnum_value(vector->length);
1273 nwords = CEILING(length * 2 + 2, 2);
1275 return nwords;
1277 #endif
1279 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1280 static int
1281 scav_vector_complex_double_float(lispobj *where, lispobj object)
1283 struct vector *vector;
1284 int length, nwords;
1286 vector = (struct vector *) where;
1287 length = fixnum_value(vector->length);
1288 nwords = CEILING(length * 4 + 2, 2);
1290 return nwords;
1293 static lispobj
1294 trans_vector_complex_double_float(lispobj object)
1296 struct vector *vector;
1297 int length, nwords;
1299 gc_assert(is_lisp_pointer(object));
1301 vector = (struct vector *) native_pointer(object);
1302 length = fixnum_value(vector->length);
1303 nwords = CEILING(length * 4 + 2, 2);
1305 return copy_large_unboxed_object(object, nwords);
1308 static int
1309 size_vector_complex_double_float(lispobj *where)
1311 struct vector *vector;
1312 int length, nwords;
1314 vector = (struct vector *) where;
1315 length = fixnum_value(vector->length);
1316 nwords = CEILING(length * 4 + 2, 2);
1318 return nwords;
1320 #endif
1323 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1324 static int
1325 scav_vector_complex_long_float(lispobj *where, lispobj object)
1327 struct vector *vector;
1328 int length, nwords;
1330 vector = (struct vector *) where;
1331 length = fixnum_value(vector->length);
1332 nwords = CEILING(length * (2* LONG_FLOAT_SIZE) + 2, 2);
1334 return nwords;
1337 static lispobj
1338 trans_vector_complex_long_float(lispobj object)
1340 struct vector *vector;
1341 int length, nwords;
1343 gc_assert(is_lisp_pointer(object));
1345 vector = (struct vector *) native_pointer(object);
1346 length = fixnum_value(vector->length);
1347 nwords = CEILING(length * (2*LONG_FLOAT_SIZE) + 2, 2);
1349 return copy_large_unboxed_object(object, nwords);
1352 static int
1353 size_vector_complex_long_float(lispobj *where)
1355 struct vector *vector;
1356 int length, nwords;
1358 vector = (struct vector *) where;
1359 length = fixnum_value(vector->length);
1360 nwords = CEILING(length * (2*LONG_FLOAT_SIZE) + 2, 2);
1362 return nwords;
1364 #endif
1366 #define WEAK_POINTER_NWORDS \
1367 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1369 static lispobj
1370 trans_weak_pointer(lispobj object)
1372 lispobj copy;
1373 #ifndef LISP_FEATURE_GENCGC
1374 struct weak_pointer *wp;
1375 #endif
1376 gc_assert(is_lisp_pointer(object));
1378 #if defined(DEBUG_WEAK)
1379 printf("Transporting weak pointer from 0x%08x\n", object);
1380 #endif
1382 /* Need to remember where all the weak pointers are that have */
1383 /* been transported so they can be fixed up in a post-GC pass. */
1385 copy = copy_object(object, WEAK_POINTER_NWORDS);
1386 #ifndef LISP_FEATURE_GENCGC
1387 wp = (struct weak_pointer *) native_pointer(copy);
1389 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
1390 /* Push the weak pointer onto the list of weak pointers. */
1391 wp->next = LOW_WORD(weak_pointers);
1392 weak_pointers = wp;
1393 #endif
1394 return copy;
1397 static int
1398 size_weak_pointer(lispobj *where)
1400 return WEAK_POINTER_NWORDS;
1404 void scan_weak_pointers(void)
1406 struct weak_pointer *wp;
1407 for (wp = weak_pointers; wp != NULL;
1408 wp=(struct weak_pointer *)native_pointer(wp->next)) {
1409 lispobj value = wp->value;
1410 lispobj *first_pointer;
1411 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
1412 if (!(is_lisp_pointer(value) && from_space_p(value)))
1413 continue;
1415 /* Now, we need to check whether the object has been forwarded. If
1416 * it has been, the weak pointer is still good and needs to be
1417 * updated. Otherwise, the weak pointer needs to be nil'ed
1418 * out. */
1420 first_pointer = (lispobj *)native_pointer(value);
1422 if (forwarding_pointer_p(first_pointer)) {
1423 wp->value=
1424 (lispobj)LOW_WORD(forwarding_pointer_value(first_pointer));
1425 } else {
1426 /* Break it. */
1427 wp->value = NIL;
1428 wp->broken = T;
1436 * initialization
1439 static int
1440 scav_lose(lispobj *where, lispobj object)
1442 lose("no scavenge function for object 0x%08x (widetag 0x%x)",
1443 (unsigned long)object,
1444 widetag_of(*(lispobj*)native_pointer(object)));
1445 return 0; /* bogus return value to satisfy static type checking */
1448 static lispobj
1449 trans_lose(lispobj object)
1451 lose("no transport function for object 0x%08x (widetag 0x%x)",
1452 (unsigned long)object,
1453 widetag_of(*(lispobj*)native_pointer(object)));
1454 return NIL; /* bogus return value to satisfy static type checking */
1457 static int
1458 size_lose(lispobj *where)
1460 lose("no size function for object at 0x%08x (widetag 0x%x)",
1461 (unsigned long)where,
1462 widetag_of(LOW_WORD(where)));
1463 return 1; /* bogus return value to satisfy static type checking */
1468 * initialization
1471 void
1472 gc_init_tables(void)
1474 int i;
1476 /* Set default value in all slots of scavenge table. FIXME
1477 * replace this gnarly sizeof with something based on
1478 * N_WIDETAG_BITS */
1479 for (i = 0; i < ((sizeof scavtab)/(sizeof scavtab[0])); i++) {
1480 scavtab[i] = scav_lose;
1483 /* For each type which can be selected by the lowtag alone, set
1484 * multiple entries in our widetag scavenge table (one for each
1485 * possible value of the high bits).
1488 for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
1489 scavtab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
1490 scavtab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_fun_pointer;
1491 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1492 scavtab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_list_pointer;
1493 scavtab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
1494 scavtab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_instance_pointer;
1495 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1496 scavtab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_other_pointer;
1499 /* Other-pointer types (those selected by all eight bits of the
1500 * tag) get one entry each in the scavenge table. */
1501 scavtab[BIGNUM_WIDETAG] = scav_unboxed;
1502 scavtab[RATIO_WIDETAG] = scav_boxed;
1503 scavtab[SINGLE_FLOAT_WIDETAG] = scav_unboxed;
1504 scavtab[DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
1505 #ifdef LONG_FLOAT_WIDETAG
1506 scavtab[LONG_FLOAT_WIDETAG] = scav_unboxed;
1507 #endif
1508 scavtab[COMPLEX_WIDETAG] = scav_boxed;
1509 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1510 scavtab[COMPLEX_SINGLE_FLOAT_WIDETAG] = scav_unboxed;
1511 #endif
1512 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1513 scavtab[COMPLEX_DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
1514 #endif
1515 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1516 scavtab[COMPLEX_LONG_FLOAT_WIDETAG] = scav_unboxed;
1517 #endif
1518 scavtab[SIMPLE_ARRAY_WIDETAG] = scav_boxed;
1519 scavtab[SIMPLE_BASE_STRING_WIDETAG] = scav_base_string;
1520 scavtab[SIMPLE_BIT_VECTOR_WIDETAG] = scav_vector_bit;
1521 scavtab[SIMPLE_ARRAY_NIL_WIDETAG] = scav_vector_nil;
1522 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
1523 scav_vector_unsigned_byte_2;
1524 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
1525 scav_vector_unsigned_byte_4;
1526 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
1527 scav_vector_unsigned_byte_8;
1528 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
1529 scav_vector_unsigned_byte_8;
1530 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
1531 scav_vector_unsigned_byte_16;
1532 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
1533 scav_vector_unsigned_byte_16;
1534 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
1535 scav_vector_unsigned_byte_32;
1536 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
1537 scav_vector_unsigned_byte_32;
1538 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
1539 scav_vector_unsigned_byte_32;
1540 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1541 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = scav_vector_unsigned_byte_8;
1542 #endif
1543 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1544 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
1545 scav_vector_unsigned_byte_16;
1546 #endif
1547 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1548 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
1549 scav_vector_unsigned_byte_32;
1550 #endif
1551 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1552 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
1553 scav_vector_unsigned_byte_32;
1554 #endif
1555 scavtab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = scav_vector_single_float;
1556 scavtab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = scav_vector_double_float;
1557 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1558 scavtab[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] = scav_vector_long_float;
1559 #endif
1560 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1561 scavtab[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
1562 scav_vector_complex_single_float;
1563 #endif
1564 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1565 scavtab[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
1566 scav_vector_complex_double_float;
1567 #endif
1568 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1569 scavtab[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
1570 scav_vector_complex_long_float;
1571 #endif
1572 scavtab[COMPLEX_BASE_STRING_WIDETAG] = scav_boxed;
1573 scavtab[COMPLEX_VECTOR_NIL_WIDETAG] = scav_boxed;
1574 scavtab[COMPLEX_BIT_VECTOR_WIDETAG] = scav_boxed;
1575 scavtab[COMPLEX_VECTOR_WIDETAG] = scav_boxed;
1576 scavtab[COMPLEX_ARRAY_WIDETAG] = scav_boxed;
1577 scavtab[CODE_HEADER_WIDETAG] = scav_code_header;
1578 #ifndef LISP_FEATURE_GENCGC /* FIXME ..._X86 ? */
1579 scavtab[SIMPLE_FUN_HEADER_WIDETAG] = scav_fun_header;
1580 scavtab[RETURN_PC_HEADER_WIDETAG] = scav_return_pc_header;
1581 #endif
1582 #ifdef LISP_FEATURE_X86
1583 scavtab[CLOSURE_HEADER_WIDETAG] = scav_closure_header;
1584 scavtab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = scav_closure_header;
1585 #else
1586 scavtab[CLOSURE_HEADER_WIDETAG] = scav_boxed;
1587 scavtab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = scav_boxed;
1588 #endif
1589 scavtab[VALUE_CELL_HEADER_WIDETAG] = scav_boxed;
1590 scavtab[SYMBOL_HEADER_WIDETAG] = scav_boxed;
1591 scavtab[BASE_CHAR_WIDETAG] = scav_immediate;
1592 scavtab[SAP_WIDETAG] = scav_unboxed;
1593 scavtab[UNBOUND_MARKER_WIDETAG] = scav_immediate;
1594 scavtab[INSTANCE_HEADER_WIDETAG] = scav_boxed;
1595 #ifdef LISP_FEATURE_SPARC
1596 scavtab[FDEFN_WIDETAG] = scav_boxed;
1597 #else
1598 scavtab[FDEFN_WIDETAG] = scav_fdefn;
1599 #endif
1601 /* transport other table, initialized same way as scavtab */
1602 for (i = 0; i < ((sizeof transother)/(sizeof transother[0])); i++)
1603 transother[i] = trans_lose;
1604 transother[BIGNUM_WIDETAG] = trans_unboxed;
1605 transother[RATIO_WIDETAG] = trans_boxed;
1606 transother[SINGLE_FLOAT_WIDETAG] = trans_unboxed;
1607 transother[DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
1608 #ifdef LONG_FLOAT_WIDETAG
1609 transother[LONG_FLOAT_WIDETAG] = trans_unboxed;
1610 #endif
1611 transother[COMPLEX_WIDETAG] = trans_boxed;
1612 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1613 transother[COMPLEX_SINGLE_FLOAT_WIDETAG] = trans_unboxed;
1614 #endif
1615 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1616 transother[COMPLEX_DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
1617 #endif
1618 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1619 transother[COMPLEX_LONG_FLOAT_WIDETAG] = trans_unboxed;
1620 #endif
1621 transother[SIMPLE_ARRAY_WIDETAG] = trans_boxed; /* but not GENCGC */
1622 transother[SIMPLE_BASE_STRING_WIDETAG] = trans_base_string;
1623 transother[SIMPLE_BIT_VECTOR_WIDETAG] = trans_vector_bit;
1624 transother[SIMPLE_VECTOR_WIDETAG] = trans_vector;
1625 transother[SIMPLE_ARRAY_NIL_WIDETAG] = trans_vector_nil;
1626 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
1627 trans_vector_unsigned_byte_2;
1628 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
1629 trans_vector_unsigned_byte_4;
1630 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
1631 trans_vector_unsigned_byte_8;
1632 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
1633 trans_vector_unsigned_byte_8;
1634 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
1635 trans_vector_unsigned_byte_16;
1636 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
1637 trans_vector_unsigned_byte_16;
1638 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
1639 trans_vector_unsigned_byte_32;
1640 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
1641 trans_vector_unsigned_byte_32;
1642 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
1643 trans_vector_unsigned_byte_32;
1644 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1645 transother[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] =
1646 trans_vector_unsigned_byte_8;
1647 #endif
1648 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1649 transother[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
1650 trans_vector_unsigned_byte_16;
1651 #endif
1652 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1653 transother[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
1654 trans_vector_unsigned_byte_32;
1655 #endif
1656 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1657 transother[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
1658 trans_vector_unsigned_byte_32;
1659 #endif
1660 transother[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] =
1661 trans_vector_single_float;
1662 transother[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] =
1663 trans_vector_double_float;
1664 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1665 transother[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] =
1666 trans_vector_long_float;
1667 #endif
1668 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1669 transother[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
1670 trans_vector_complex_single_float;
1671 #endif
1672 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1673 transother[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
1674 trans_vector_complex_double_float;
1675 #endif
1676 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1677 transother[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
1678 trans_vector_complex_long_float;
1679 #endif
1680 transother[COMPLEX_BASE_STRING_WIDETAG] = trans_boxed;
1681 transother[COMPLEX_BIT_VECTOR_WIDETAG] = trans_boxed;
1682 transother[COMPLEX_VECTOR_NIL_WIDETAG] = trans_boxed;
1683 transother[COMPLEX_VECTOR_WIDETAG] = trans_boxed;
1684 transother[COMPLEX_ARRAY_WIDETAG] = trans_boxed;
1685 transother[CODE_HEADER_WIDETAG] = trans_code_header;
1686 transother[SIMPLE_FUN_HEADER_WIDETAG] = trans_fun_header;
1687 transother[RETURN_PC_HEADER_WIDETAG] = trans_return_pc_header;
1688 transother[CLOSURE_HEADER_WIDETAG] = trans_boxed;
1689 transother[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = trans_boxed;
1690 transother[VALUE_CELL_HEADER_WIDETAG] = trans_boxed;
1691 transother[SYMBOL_HEADER_WIDETAG] = trans_boxed;
1692 transother[BASE_CHAR_WIDETAG] = trans_immediate;
1693 transother[SAP_WIDETAG] = trans_unboxed;
1694 transother[UNBOUND_MARKER_WIDETAG] = trans_immediate;
1695 transother[WEAK_POINTER_WIDETAG] = trans_weak_pointer;
1696 transother[INSTANCE_HEADER_WIDETAG] = trans_boxed;
1697 transother[FDEFN_WIDETAG] = trans_boxed;
1699 /* size table, initialized the same way as scavtab */
1700 for (i = 0; i < ((sizeof sizetab)/(sizeof sizetab[0])); i++)
1701 sizetab[i] = size_lose;
1702 for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
1703 sizetab[EVEN_FIXNUM_LOWTAG|(i<<3)] = size_immediate;
1704 sizetab[FUN_POINTER_LOWTAG|(i<<3)] = size_pointer;
1705 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1706 sizetab[LIST_POINTER_LOWTAG|(i<<3)] = size_pointer;
1707 sizetab[ODD_FIXNUM_LOWTAG|(i<<3)] = size_immediate;
1708 sizetab[INSTANCE_POINTER_LOWTAG|(i<<3)] = size_pointer;
1709 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1710 sizetab[OTHER_POINTER_LOWTAG|(i<<3)] = size_pointer;
1712 sizetab[BIGNUM_WIDETAG] = size_unboxed;
1713 sizetab[RATIO_WIDETAG] = size_boxed;
1714 sizetab[SINGLE_FLOAT_WIDETAG] = size_unboxed;
1715 sizetab[DOUBLE_FLOAT_WIDETAG] = size_unboxed;
1716 #ifdef LONG_FLOAT_WIDETAG
1717 sizetab[LONG_FLOAT_WIDETAG] = size_unboxed;
1718 #endif
1719 sizetab[COMPLEX_WIDETAG] = size_boxed;
1720 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1721 sizetab[COMPLEX_SINGLE_FLOAT_WIDETAG] = size_unboxed;
1722 #endif
1723 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1724 sizetab[COMPLEX_DOUBLE_FLOAT_WIDETAG] = size_unboxed;
1725 #endif
1726 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1727 sizetab[COMPLEX_LONG_FLOAT_WIDETAG] = size_unboxed;
1728 #endif
1729 sizetab[SIMPLE_ARRAY_WIDETAG] = size_boxed;
1730 sizetab[SIMPLE_BASE_STRING_WIDETAG] = size_base_string;
1731 sizetab[SIMPLE_BIT_VECTOR_WIDETAG] = size_vector_bit;
1732 sizetab[SIMPLE_VECTOR_WIDETAG] = size_vector;
1733 sizetab[SIMPLE_ARRAY_NIL_WIDETAG] = size_vector_nil;
1734 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
1735 size_vector_unsigned_byte_2;
1736 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
1737 size_vector_unsigned_byte_4;
1738 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
1739 size_vector_unsigned_byte_8;
1740 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
1741 size_vector_unsigned_byte_8;
1742 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
1743 size_vector_unsigned_byte_16;
1744 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
1745 size_vector_unsigned_byte_16;
1746 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
1747 size_vector_unsigned_byte_32;
1748 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
1749 size_vector_unsigned_byte_32;
1750 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
1751 size_vector_unsigned_byte_32;
1752 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1753 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = size_vector_unsigned_byte_8;
1754 #endif
1755 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1756 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
1757 size_vector_unsigned_byte_16;
1758 #endif
1759 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1760 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
1761 size_vector_unsigned_byte_32;
1762 #endif
1763 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1764 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
1765 size_vector_unsigned_byte_32;
1766 #endif
1767 sizetab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = size_vector_single_float;
1768 sizetab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = size_vector_double_float;
1769 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1770 sizetab[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] = size_vector_long_float;
1771 #endif
1772 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1773 sizetab[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
1774 size_vector_complex_single_float;
1775 #endif
1776 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1777 sizetab[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
1778 size_vector_complex_double_float;
1779 #endif
1780 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1781 sizetab[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
1782 size_vector_complex_long_float;
1783 #endif
1784 sizetab[COMPLEX_BASE_STRING_WIDETAG] = size_boxed;
1785 sizetab[COMPLEX_VECTOR_NIL_WIDETAG] = size_boxed;
1786 sizetab[COMPLEX_BIT_VECTOR_WIDETAG] = size_boxed;
1787 sizetab[COMPLEX_VECTOR_WIDETAG] = size_boxed;
1788 sizetab[COMPLEX_ARRAY_WIDETAG] = size_boxed;
1789 sizetab[CODE_HEADER_WIDETAG] = size_code_header;
1790 #if 0
1791 /* We shouldn't see these, so just lose if it happens. */
1792 sizetab[SIMPLE_FUN_HEADER_WIDETAG] = size_function_header;
1793 sizetab[RETURN_PC_HEADER_WIDETAG] = size_return_pc_header;
1794 #endif
1795 sizetab[CLOSURE_HEADER_WIDETAG] = size_boxed;
1796 sizetab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = size_boxed;
1797 sizetab[VALUE_CELL_HEADER_WIDETAG] = size_boxed;
1798 sizetab[SYMBOL_HEADER_WIDETAG] = size_boxed;
1799 sizetab[BASE_CHAR_WIDETAG] = size_immediate;
1800 sizetab[SAP_WIDETAG] = size_unboxed;
1801 sizetab[UNBOUND_MARKER_WIDETAG] = size_immediate;
1802 sizetab[WEAK_POINTER_WIDETAG] = size_weak_pointer;
1803 sizetab[INSTANCE_HEADER_WIDETAG] = size_boxed;
1804 sizetab[FDEFN_WIDETAG] = size_boxed;