0.9.3.17
[sbcl/eslaughter.git] / src / runtime / gc-common.c
blobda410d38e53555ca78cf1b1dfaf761176ddde316
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 * 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>
24 * as
25 * <ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps>.
28 #include <stdio.h>
29 #include <signal.h>
30 #include <string.h>
31 #include "sbcl.h"
32 #include "runtime.h"
33 #include "os.h"
34 #include "interr.h"
35 #include "globals.h"
36 #include "interrupt.h"
37 #include "validate.h"
38 #include "lispregs.h"
39 #include "arch.h"
40 #include "fixnump.h"
41 #include "gc.h"
42 #include "genesis/primitive-objects.h"
43 #include "genesis/static-symbols.h"
44 #include "genesis/layout.h"
45 #include "gc-internal.h"
47 #ifdef LISP_FEATURE_SPARC
48 #define LONG_FLOAT_SIZE 4
49 #else
50 #ifdef LISP_FEATURE_X86
51 #define LONG_FLOAT_SIZE 3
52 #endif
53 #endif
55 inline static boolean
56 forwarding_pointer_p(lispobj *pointer) {
57 lispobj first_word=*pointer;
58 #ifdef LISP_FEATURE_GENCGC
59 return (first_word == 0x01);
60 #else
61 return (is_lisp_pointer(first_word)
62 && new_space_p(first_word));
63 #endif
66 static inline lispobj *
67 forwarding_pointer_value(lispobj *pointer) {
68 #ifdef LISP_FEATURE_GENCGC
69 return (lispobj *) ((pointer_sized_uint_t) pointer[1]);
70 #else
71 return (lispobj *) ((pointer_sized_uint_t) pointer[0]);
72 #endif
74 static inline lispobj
75 set_forwarding_pointer(lispobj * pointer, lispobj newspace_copy) {
76 #ifdef LISP_FEATURE_GENCGC
77 pointer[0]=0x01;
78 pointer[1]=newspace_copy;
79 #else
80 pointer[0]=newspace_copy;
81 #endif
82 return newspace_copy;
85 long (*scavtab[256])(lispobj *where, lispobj object);
86 lispobj (*transother[256])(lispobj object);
87 long (*sizetab[256])(lispobj *where);
88 struct weak_pointer *weak_pointers;
90 unsigned long bytes_consed_between_gcs = 12*1024*1024;
94 * copying objects
97 /* to copy a boxed object */
98 lispobj
99 copy_object(lispobj object, long nwords)
101 int tag;
102 lispobj *new;
104 gc_assert(is_lisp_pointer(object));
105 gc_assert(from_space_p(object));
106 gc_assert((nwords & 0x01) == 0);
108 /* Get tag of object. */
109 tag = lowtag_of(object);
111 /* Allocate space. */
112 new = gc_general_alloc(nwords*N_WORD_BYTES,ALLOC_BOXED,ALLOC_QUICK);
114 /* Copy the object. */
115 memcpy(new,native_pointer(object),nwords*N_WORD_BYTES);
116 return make_lispobj(new,tag);
119 static long scav_lose(lispobj *where, lispobj object); /* forward decl */
121 /* FIXME: Most calls end up going to some trouble to compute an
122 * 'n_words' value for this function. The system might be a little
123 * simpler if this function used an 'end' parameter instead. */
124 void
125 scavenge(lispobj *start, long n_words)
127 lispobj *end = start + n_words;
128 lispobj *object_ptr;
129 long n_words_scavenged;
130 for (object_ptr = start;
132 object_ptr < end;
133 object_ptr += n_words_scavenged) {
135 lispobj object = *object_ptr;
136 #ifdef LISP_FEATURE_GENCGC
137 gc_assert(!forwarding_pointer_p(object_ptr));
138 #endif
139 if (is_lisp_pointer(object)) {
140 if (from_space_p(object)) {
141 /* It currently points to old space. Check for a
142 * forwarding pointer. */
143 lispobj *ptr = native_pointer(object);
144 if (forwarding_pointer_p(ptr)) {
145 /* Yes, there's a forwarding pointer. */
146 *object_ptr = LOW_WORD(forwarding_pointer_value(ptr));
147 n_words_scavenged = 1;
148 } else {
149 /* Scavenge that pointer. */
150 n_words_scavenged =
151 (scavtab[widetag_of(object)])(object_ptr, object);
153 } else {
154 /* It points somewhere other than oldspace. Leave it
155 * alone. */
156 n_words_scavenged = 1;
159 #ifndef LISP_FEATURE_GENCGC
160 /* this workaround is probably not necessary for gencgc; at least, the
161 * behaviour it describes has never been reported */
162 else if (n_words==1) {
163 /* there are some situations where an
164 other-immediate may end up in a descriptor
165 register. I'm not sure whether this is
166 supposed to happen, but if it does then we
167 don't want to (a) barf or (b) scavenge over the
168 data-block, because there isn't one. So, if
169 we're checking a single word and it's anything
170 other than a pointer, just hush it up */
171 int type=widetag_of(object);
172 n_words_scavenged=1;
174 if ((scavtab[type]==scav_lose) ||
175 (((scavtab[type])(start,object))>1)) {
176 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",
177 object,start);
180 #endif
181 else if (fixnump(object)) {
182 /* It's a fixnum: really easy.. */
183 n_words_scavenged = 1;
184 } else {
185 /* It's some sort of header object or another. */
186 n_words_scavenged =
187 (scavtab[widetag_of(object)])(object_ptr, object);
190 gc_assert(object_ptr == end);
193 static lispobj trans_fun_header(lispobj object); /* forward decls */
194 static lispobj trans_boxed(lispobj object);
196 static long
197 scav_fun_pointer(lispobj *where, lispobj object)
199 lispobj *first_pointer;
200 lispobj copy;
202 gc_assert(is_lisp_pointer(object));
204 /* Object is a pointer into from_space - not a FP. */
205 first_pointer = (lispobj *) native_pointer(object);
207 /* must transport object -- object may point to either a function
208 * header, a closure function header, or to a closure header. */
210 switch (widetag_of(*first_pointer)) {
211 case SIMPLE_FUN_HEADER_WIDETAG:
212 copy = trans_fun_header(object);
213 break;
214 default:
215 copy = trans_boxed(object);
216 break;
219 if (copy != object) {
220 /* Set forwarding pointer */
221 set_forwarding_pointer(first_pointer,copy);
224 gc_assert(is_lisp_pointer(copy));
225 gc_assert(!from_space_p(copy));
227 *where = copy;
229 return 1;
233 static struct code *
234 trans_code(struct code *code)
236 struct code *new_code;
237 lispobj first, l_code, l_new_code;
238 long nheader_words, ncode_words, nwords;
239 unsigned long displacement;
240 lispobj fheaderl, *prev_pointer;
242 /* if object has already been transported, just return pointer */
243 first = code->header;
244 if (forwarding_pointer_p((lispobj *)code)) {
245 #ifdef DEBUG_CODE_GC
246 printf("Was already transported\n");
247 #endif
248 return (struct code *) forwarding_pointer_value
249 ((lispobj *)((pointer_sized_uint_t) code));
252 gc_assert(widetag_of(first) == CODE_HEADER_WIDETAG);
254 /* prepare to transport the code vector */
255 l_code = (lispobj) LOW_WORD(code) | OTHER_POINTER_LOWTAG;
257 ncode_words = fixnum_value(code->code_size);
258 nheader_words = HeaderValue(code->header);
259 nwords = ncode_words + nheader_words;
260 nwords = CEILING(nwords, 2);
262 l_new_code = copy_object(l_code, nwords);
263 new_code = (struct code *) native_pointer(l_new_code);
265 #if defined(DEBUG_CODE_GC)
266 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
267 (unsigned long) code, (unsigned long) new_code);
268 printf("Code object is %d words long.\n", nwords);
269 #endif
271 #ifdef LISP_FEATURE_GENCGC
272 if (new_code == code)
273 return new_code;
274 #endif
276 displacement = l_new_code - l_code;
278 set_forwarding_pointer((lispobj *)code, l_new_code);
280 /* set forwarding pointers for all the function headers in the */
281 /* code object. also fix all self pointers */
283 fheaderl = code->entry_points;
284 prev_pointer = &new_code->entry_points;
286 while (fheaderl != NIL) {
287 struct simple_fun *fheaderp, *nfheaderp;
288 lispobj nfheaderl;
290 fheaderp = (struct simple_fun *) native_pointer(fheaderl);
291 gc_assert(widetag_of(fheaderp->header) == SIMPLE_FUN_HEADER_WIDETAG);
293 /* Calculate the new function pointer and the new */
294 /* function header. */
295 nfheaderl = fheaderl + displacement;
296 nfheaderp = (struct simple_fun *) native_pointer(nfheaderl);
298 #ifdef DEBUG_CODE_GC
299 printf("fheaderp->header (at %x) <- %x\n",
300 &(fheaderp->header) , nfheaderl);
301 #endif
302 set_forwarding_pointer((lispobj *)fheaderp, nfheaderl);
304 /* fix self pointer. */
305 nfheaderp->self =
306 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
307 FUN_RAW_ADDR_OFFSET +
308 #endif
309 nfheaderl;
311 *prev_pointer = nfheaderl;
313 fheaderl = fheaderp->next;
314 prev_pointer = &nfheaderp->next;
316 os_flush_icache((os_vm_address_t) (((long *)new_code) + nheader_words),
317 ncode_words * sizeof(long));
318 #ifdef LISP_FEATURE_GENCGC
319 gencgc_apply_code_fixups(code, new_code);
320 #endif
321 return new_code;
324 static long
325 scav_code_header(lispobj *where, lispobj object)
327 struct code *code;
328 long n_header_words, n_code_words, n_words;
329 lispobj entry_point; /* tagged pointer to entry point */
330 struct simple_fun *function_ptr; /* untagged pointer to entry point */
332 code = (struct code *) where;
333 n_code_words = fixnum_value(code->code_size);
334 n_header_words = HeaderValue(object);
335 n_words = n_code_words + n_header_words;
336 n_words = CEILING(n_words, 2);
338 /* Scavenge the boxed section of the code data block. */
339 scavenge(where + 1, n_header_words - 1);
341 /* Scavenge the boxed section of each function object in the
342 * code data block. */
343 for (entry_point = code->entry_points;
344 entry_point != NIL;
345 entry_point = function_ptr->next) {
347 gc_assert(is_lisp_pointer(entry_point));
349 function_ptr = (struct simple_fun *) native_pointer(entry_point);
350 gc_assert(widetag_of(function_ptr->header)==SIMPLE_FUN_HEADER_WIDETAG);
352 scavenge(&function_ptr->name, 1);
353 scavenge(&function_ptr->arglist, 1);
354 scavenge(&function_ptr->type, 1);
357 return n_words;
360 static lispobj
361 trans_code_header(lispobj object)
363 struct code *ncode;
365 ncode = trans_code((struct code *) native_pointer(object));
366 return (lispobj) LOW_WORD(ncode) | OTHER_POINTER_LOWTAG;
370 static long
371 size_code_header(lispobj *where)
373 struct code *code;
374 long nheader_words, ncode_words, nwords;
376 code = (struct code *) where;
378 ncode_words = fixnum_value(code->code_size);
379 nheader_words = HeaderValue(code->header);
380 nwords = ncode_words + nheader_words;
381 nwords = CEILING(nwords, 2);
383 return nwords;
386 #if !defined(LISP_FEATURE_X86) && ! defined(LISP_FEATURE_X86_64)
387 static long
388 scav_return_pc_header(lispobj *where, lispobj object)
390 lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x",
391 (unsigned long) where,
392 (unsigned long) object);
393 return 0; /* bogus return value to satisfy static type checking */
395 #endif /* LISP_FEATURE_X86 */
397 static lispobj
398 trans_return_pc_header(lispobj object)
400 struct simple_fun *return_pc;
401 unsigned long offset;
402 struct code *code, *ncode;
404 return_pc = (struct simple_fun *) native_pointer(object);
405 /* FIXME: was times 4, should it really be N_WORD_BYTES? */
406 offset = HeaderValue(return_pc->header) * N_WORD_BYTES;
408 /* Transport the whole code object */
409 code = (struct code *) ((unsigned long) return_pc - offset);
410 ncode = trans_code(code);
412 return ((lispobj) LOW_WORD(ncode) + offset) | OTHER_POINTER_LOWTAG;
415 /* On the 386, closures hold a pointer to the raw address instead of the
416 * function object, so we can use CALL [$FDEFN+const] to invoke
417 * the function without loading it into a register. Given that code
418 * objects don't move, we don't need to update anything, but we do
419 * have to figure out that the function is still live. */
421 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
422 static long
423 scav_closure_header(lispobj *where, lispobj object)
425 struct closure *closure;
426 lispobj fun;
428 closure = (struct closure *)where;
429 fun = closure->fun - FUN_RAW_ADDR_OFFSET;
430 scavenge(&fun, 1);
431 #ifdef LISP_FEATURE_GENCGC
432 /* The function may have moved so update the raw address. But
433 * don't write unnecessarily. */
434 if (closure->fun != fun + FUN_RAW_ADDR_OFFSET)
435 closure->fun = fun + FUN_RAW_ADDR_OFFSET;
436 #endif
437 return 2;
439 #endif
441 #if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64))
442 static long
443 scav_fun_header(lispobj *where, lispobj object)
445 lose("attempted to scavenge a function header where=0x%08x object=0x%08x",
446 (unsigned long) where,
447 (unsigned long) object);
448 return 0; /* bogus return value to satisfy static type checking */
450 #endif /* LISP_FEATURE_X86 */
452 static lispobj
453 trans_fun_header(lispobj object)
455 struct simple_fun *fheader;
456 unsigned long offset;
457 struct code *code, *ncode;
459 fheader = (struct simple_fun *) native_pointer(object);
460 /* FIXME: was times 4, should it really be N_WORD_BYTES? */
461 offset = HeaderValue(fheader->header) * N_WORD_BYTES;
463 /* Transport the whole code object */
464 code = (struct code *) ((unsigned long) fheader - offset);
465 ncode = trans_code(code);
467 return ((lispobj) LOW_WORD(ncode) + offset) | FUN_POINTER_LOWTAG;
472 * instances
475 static long
476 scav_instance_pointer(lispobj *where, lispobj object)
478 lispobj copy, *first_pointer;
480 /* Object is a pointer into from space - not a FP. */
481 copy = trans_boxed(object);
483 #ifdef LISP_FEATURE_GENCGC
484 gc_assert(copy != object);
485 #endif
487 first_pointer = (lispobj *) native_pointer(object);
488 set_forwarding_pointer(first_pointer,copy);
489 *where = copy;
491 return 1;
496 * lists and conses
499 static lispobj trans_list(lispobj object);
501 static long
502 scav_list_pointer(lispobj *where, lispobj object)
504 lispobj first, *first_pointer;
506 gc_assert(is_lisp_pointer(object));
508 /* Object is a pointer into from space - not FP. */
509 first_pointer = (lispobj *) native_pointer(object);
511 first = trans_list(object);
512 gc_assert(first != object);
514 /* Set forwarding pointer */
515 set_forwarding_pointer(first_pointer, first);
517 gc_assert(is_lisp_pointer(first));
518 gc_assert(!from_space_p(first));
520 *where = first;
521 return 1;
525 static lispobj
526 trans_list(lispobj object)
528 lispobj new_list_pointer;
529 struct cons *cons, *new_cons;
530 lispobj cdr;
532 cons = (struct cons *) native_pointer(object);
534 /* Copy 'object'. */
535 new_cons = (struct cons *)
536 gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK);
537 new_cons->car = cons->car;
538 new_cons->cdr = cons->cdr; /* updated later */
539 new_list_pointer = make_lispobj(new_cons,lowtag_of(object));
541 /* Grab the cdr: set_forwarding_pointer will clobber it in GENCGC */
542 cdr = cons->cdr;
544 set_forwarding_pointer((lispobj *)cons, new_list_pointer);
546 /* Try to linearize the list in the cdr direction to help reduce
547 * paging. */
548 while (1) {
549 lispobj new_cdr;
550 struct cons *cdr_cons, *new_cdr_cons;
552 if(lowtag_of(cdr) != LIST_POINTER_LOWTAG ||
553 !from_space_p(cdr) ||
554 forwarding_pointer_p((lispobj *)native_pointer(cdr)))
555 break;
557 cdr_cons = (struct cons *) native_pointer(cdr);
559 /* Copy 'cdr'. */
560 new_cdr_cons = (struct cons*)
561 gc_general_alloc(sizeof(struct cons),ALLOC_BOXED,ALLOC_QUICK);
562 new_cdr_cons->car = cdr_cons->car;
563 new_cdr_cons->cdr = cdr_cons->cdr;
564 new_cdr = make_lispobj(new_cdr_cons, lowtag_of(cdr));
566 /* Grab the cdr before it is clobbered. */
567 cdr = cdr_cons->cdr;
568 set_forwarding_pointer((lispobj *)cdr_cons, new_cdr);
570 /* Update the cdr of the last cons copied into new space to
571 * keep the newspace scavenge from having to do it. */
572 new_cons->cdr = new_cdr;
574 new_cons = new_cdr_cons;
577 return new_list_pointer;
582 * scavenging and transporting other pointers
585 static long
586 scav_other_pointer(lispobj *where, lispobj object)
588 lispobj first, *first_pointer;
590 gc_assert(is_lisp_pointer(object));
592 /* Object is a pointer into from space - not FP. */
593 first_pointer = (lispobj *) native_pointer(object);
594 first = (transother[widetag_of(*first_pointer)])(object);
596 if (first != object) {
597 set_forwarding_pointer(first_pointer, first);
598 #ifdef LISP_FEATURE_GENCGC
599 *where = first;
600 #endif
602 #ifndef LISP_FEATURE_GENCGC
603 *where = first;
604 #endif
605 gc_assert(is_lisp_pointer(first));
606 gc_assert(!from_space_p(first));
608 return 1;
612 * immediate, boxed, and unboxed objects
615 static long
616 size_pointer(lispobj *where)
618 return 1;
621 static long
622 scav_immediate(lispobj *where, lispobj object)
624 return 1;
627 static lispobj
628 trans_immediate(lispobj object)
630 lose("trying to transport an immediate");
631 return NIL; /* bogus return value to satisfy static type checking */
634 static long
635 size_immediate(lispobj *where)
637 return 1;
641 static long
642 scav_boxed(lispobj *where, lispobj object)
644 return 1;
647 static long
648 scav_instance(lispobj *where, lispobj object)
650 lispobj nuntagged;
651 long ntotal = HeaderValue(object);
652 lispobj layout = ((struct instance *)where)->slots[0];
654 if (!layout)
655 return 1;
656 if (forwarding_pointer_p(native_pointer(layout)))
657 layout = (lispobj) forwarding_pointer_value(native_pointer(layout));
659 nuntagged = ((struct layout *)native_pointer(layout))->n_untagged_slots;
660 scavenge(where + 1, ntotal - fixnum_value(nuntagged));
662 return ntotal + 1;
665 static lispobj
666 trans_boxed(lispobj object)
668 lispobj header;
669 unsigned long length;
671 gc_assert(is_lisp_pointer(object));
673 header = *((lispobj *) native_pointer(object));
674 length = HeaderValue(header) + 1;
675 length = CEILING(length, 2);
677 return copy_object(object, length);
681 static long
682 size_boxed(lispobj *where)
684 lispobj header;
685 unsigned long length;
687 header = *where;
688 length = HeaderValue(header) + 1;
689 length = CEILING(length, 2);
691 return length;
694 /* Note: on the sparc we don't have to do anything special for fdefns, */
695 /* 'cause the raw-addr has a function lowtag. */
696 #ifndef LISP_FEATURE_SPARC
697 static long
698 scav_fdefn(lispobj *where, lispobj object)
700 struct fdefn *fdefn;
702 fdefn = (struct fdefn *)where;
704 /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n",
705 fdefn->fun, fdefn->raw_addr)); */
707 if ((char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET)
708 == (char *)((unsigned long)(fdefn->raw_addr))) {
709 scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1);
711 /* Don't write unnecessarily. */
712 if (fdefn->raw_addr != (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET))
713 fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET);
714 /* gc.c has more casts here, which may be relevant or alternatively
715 may be compiler warning defeaters. try
716 fdefn->raw_addr = ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET;
718 return sizeof(struct fdefn) / sizeof(lispobj);
719 } else {
720 return 1;
723 #endif
725 static long
726 scav_unboxed(lispobj *where, lispobj object)
728 unsigned long length;
730 length = HeaderValue(object) + 1;
731 length = CEILING(length, 2);
733 return length;
736 static lispobj
737 trans_unboxed(lispobj object)
739 lispobj header;
740 unsigned long length;
743 gc_assert(is_lisp_pointer(object));
745 header = *((lispobj *) native_pointer(object));
746 length = HeaderValue(header) + 1;
747 length = CEILING(length, 2);
749 return copy_unboxed_object(object, length);
752 static long
753 size_unboxed(lispobj *where)
755 lispobj header;
756 unsigned long length;
758 header = *where;
759 length = HeaderValue(header) + 1;
760 length = CEILING(length, 2);
762 return length;
766 /* vector-like objects */
767 static long
768 scav_base_string(lispobj *where, lispobj object)
770 struct vector *vector;
771 long length, nwords;
773 /* NOTE: Strings contain one more byte of data than the length */
774 /* slot indicates. */
776 vector = (struct vector *) where;
777 length = fixnum_value(vector->length) + 1;
778 nwords = CEILING(NWORDS(length, 8) + 2, 2);
780 return nwords;
782 static lispobj
783 trans_base_string(lispobj object)
785 struct vector *vector;
786 long length, nwords;
788 gc_assert(is_lisp_pointer(object));
790 /* NOTE: A string contains one more byte of data (a terminating
791 * '\0' to help when interfacing with C functions) than indicated
792 * by the length slot. */
794 vector = (struct vector *) native_pointer(object);
795 length = fixnum_value(vector->length) + 1;
796 nwords = CEILING(NWORDS(length, 8) + 2, 2);
798 return copy_large_unboxed_object(object, nwords);
801 static long
802 size_base_string(lispobj *where)
804 struct vector *vector;
805 long length, nwords;
807 /* NOTE: A string contains one more byte of data (a terminating
808 * '\0' to help when interfacing with C functions) than indicated
809 * by the length slot. */
811 vector = (struct vector *) where;
812 length = fixnum_value(vector->length) + 1;
813 nwords = CEILING(NWORDS(length, 8) + 2, 2);
815 return nwords;
818 static long
819 scav_character_string(lispobj *where, lispobj object)
821 struct vector *vector;
822 int length, nwords;
824 /* NOTE: Strings contain one more byte of data than the length */
825 /* slot indicates. */
827 vector = (struct vector *) where;
828 length = fixnum_value(vector->length) + 1;
829 nwords = CEILING(NWORDS(length, 32) + 2, 2);
831 return nwords;
833 static lispobj
834 trans_character_string(lispobj object)
836 struct vector *vector;
837 int length, nwords;
839 gc_assert(is_lisp_pointer(object));
841 /* NOTE: A string contains one more byte of data (a terminating
842 * '\0' to help when interfacing with C functions) than indicated
843 * by the length slot. */
845 vector = (struct vector *) native_pointer(object);
846 length = fixnum_value(vector->length) + 1;
847 nwords = CEILING(NWORDS(length, 32) + 2, 2);
849 return copy_large_unboxed_object(object, nwords);
852 static long
853 size_character_string(lispobj *where)
855 struct vector *vector;
856 int length, nwords;
858 /* NOTE: A string contains one more byte of data (a terminating
859 * '\0' to help when interfacing with C functions) than indicated
860 * by the length slot. */
862 vector = (struct vector *) where;
863 length = fixnum_value(vector->length) + 1;
864 nwords = CEILING(NWORDS(length, 32) + 2, 2);
866 return nwords;
869 static lispobj
870 trans_vector(lispobj object)
872 struct vector *vector;
873 long length, nwords;
875 gc_assert(is_lisp_pointer(object));
877 vector = (struct vector *) native_pointer(object);
879 length = fixnum_value(vector->length);
880 nwords = CEILING(length + 2, 2);
882 return copy_large_object(object, nwords);
885 static long
886 size_vector(lispobj *where)
888 struct vector *vector;
889 long length, nwords;
891 vector = (struct vector *) where;
892 length = fixnum_value(vector->length);
893 nwords = CEILING(length + 2, 2);
895 return nwords;
898 static long
899 scav_vector_nil(lispobj *where, lispobj object)
901 return 2;
904 static lispobj
905 trans_vector_nil(lispobj object)
907 gc_assert(is_lisp_pointer(object));
908 return copy_unboxed_object(object, 2);
911 static long
912 size_vector_nil(lispobj *where)
914 /* Just the header word and the length word */
915 return 2;
918 static long
919 scav_vector_bit(lispobj *where, lispobj object)
921 struct vector *vector;
922 long length, nwords;
924 vector = (struct vector *) where;
925 length = fixnum_value(vector->length);
926 nwords = CEILING(NWORDS(length, 1) + 2, 2);
928 return nwords;
931 static lispobj
932 trans_vector_bit(lispobj object)
934 struct vector *vector;
935 long length, nwords;
937 gc_assert(is_lisp_pointer(object));
939 vector = (struct vector *) native_pointer(object);
940 length = fixnum_value(vector->length);
941 nwords = CEILING(NWORDS(length, 1) + 2, 2);
943 return copy_large_unboxed_object(object, nwords);
946 static long
947 size_vector_bit(lispobj *where)
949 struct vector *vector;
950 long length, nwords;
952 vector = (struct vector *) where;
953 length = fixnum_value(vector->length);
954 nwords = CEILING(NWORDS(length, 1) + 2, 2);
956 return nwords;
959 static long
960 scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
962 struct vector *vector;
963 long length, nwords;
965 vector = (struct vector *) where;
966 length = fixnum_value(vector->length);
967 nwords = CEILING(NWORDS(length, 2) + 2, 2);
969 return nwords;
972 static lispobj
973 trans_vector_unsigned_byte_2(lispobj object)
975 struct vector *vector;
976 long length, nwords;
978 gc_assert(is_lisp_pointer(object));
980 vector = (struct vector *) native_pointer(object);
981 length = fixnum_value(vector->length);
982 nwords = CEILING(NWORDS(length, 2) + 2, 2);
984 return copy_large_unboxed_object(object, nwords);
987 static long
988 size_vector_unsigned_byte_2(lispobj *where)
990 struct vector *vector;
991 long length, nwords;
993 vector = (struct vector *) where;
994 length = fixnum_value(vector->length);
995 nwords = CEILING(NWORDS(length, 2) + 2, 2);
997 return nwords;
1000 static long
1001 scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
1003 struct vector *vector;
1004 long length, nwords;
1006 vector = (struct vector *) where;
1007 length = fixnum_value(vector->length);
1008 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1010 return nwords;
1013 static lispobj
1014 trans_vector_unsigned_byte_4(lispobj object)
1016 struct vector *vector;
1017 long length, nwords;
1019 gc_assert(is_lisp_pointer(object));
1021 vector = (struct vector *) native_pointer(object);
1022 length = fixnum_value(vector->length);
1023 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1025 return copy_large_unboxed_object(object, nwords);
1027 static long
1028 size_vector_unsigned_byte_4(lispobj *where)
1030 struct vector *vector;
1031 long length, nwords;
1033 vector = (struct vector *) where;
1034 length = fixnum_value(vector->length);
1035 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1037 return nwords;
1041 static long
1042 scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
1044 struct vector *vector;
1045 long length, nwords;
1047 vector = (struct vector *) where;
1048 length = fixnum_value(vector->length);
1049 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1051 return nwords;
1054 /*********************/
1058 static lispobj
1059 trans_vector_unsigned_byte_8(lispobj object)
1061 struct vector *vector;
1062 long length, nwords;
1064 gc_assert(is_lisp_pointer(object));
1066 vector = (struct vector *) native_pointer(object);
1067 length = fixnum_value(vector->length);
1068 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1070 return copy_large_unboxed_object(object, nwords);
1073 static long
1074 size_vector_unsigned_byte_8(lispobj *where)
1076 struct vector *vector;
1077 long length, nwords;
1079 vector = (struct vector *) where;
1080 length = fixnum_value(vector->length);
1081 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1083 return nwords;
1087 static long
1088 scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
1090 struct vector *vector;
1091 long length, nwords;
1093 vector = (struct vector *) where;
1094 length = fixnum_value(vector->length);
1095 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1097 return nwords;
1100 static lispobj
1101 trans_vector_unsigned_byte_16(lispobj object)
1103 struct vector *vector;
1104 long length, nwords;
1106 gc_assert(is_lisp_pointer(object));
1108 vector = (struct vector *) native_pointer(object);
1109 length = fixnum_value(vector->length);
1110 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1112 return copy_large_unboxed_object(object, nwords);
1115 static long
1116 size_vector_unsigned_byte_16(lispobj *where)
1118 struct vector *vector;
1119 long length, nwords;
1121 vector = (struct vector *) where;
1122 length = fixnum_value(vector->length);
1123 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1125 return nwords;
1128 static long
1129 scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
1131 struct vector *vector;
1132 long length, nwords;
1134 vector = (struct vector *) where;
1135 length = fixnum_value(vector->length);
1136 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1138 return nwords;
1141 static lispobj
1142 trans_vector_unsigned_byte_32(lispobj object)
1144 struct vector *vector;
1145 long length, nwords;
1147 gc_assert(is_lisp_pointer(object));
1149 vector = (struct vector *) native_pointer(object);
1150 length = fixnum_value(vector->length);
1151 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1153 return copy_large_unboxed_object(object, nwords);
1156 static long
1157 size_vector_unsigned_byte_32(lispobj *where)
1159 struct vector *vector;
1160 long length, nwords;
1162 vector = (struct vector *) where;
1163 length = fixnum_value(vector->length);
1164 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1166 return nwords;
1169 #if N_WORD_BITS == 64
1170 static long
1171 scav_vector_unsigned_byte_64(lispobj *where, lispobj object)
1173 struct vector *vector;
1174 long length, nwords;
1176 vector = (struct vector *) where;
1177 length = fixnum_value(vector->length);
1178 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1180 return nwords;
1183 static lispobj
1184 trans_vector_unsigned_byte_64(lispobj object)
1186 struct vector *vector;
1187 long length, nwords;
1189 gc_assert(is_lisp_pointer(object));
1191 vector = (struct vector *) native_pointer(object);
1192 length = fixnum_value(vector->length);
1193 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1195 return copy_large_unboxed_object(object, nwords);
1198 static long
1199 size_vector_unsigned_byte_64(lispobj *where)
1201 struct vector *vector;
1202 long length, nwords;
1204 vector = (struct vector *) where;
1205 length = fixnum_value(vector->length);
1206 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1208 return nwords;
1210 #endif
1212 static long
1213 scav_vector_single_float(lispobj *where, lispobj object)
1215 struct vector *vector;
1216 long length, nwords;
1218 vector = (struct vector *) where;
1219 length = fixnum_value(vector->length);
1220 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1222 return nwords;
1225 static lispobj
1226 trans_vector_single_float(lispobj object)
1228 struct vector *vector;
1229 long length, nwords;
1231 gc_assert(is_lisp_pointer(object));
1233 vector = (struct vector *) native_pointer(object);
1234 length = fixnum_value(vector->length);
1235 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1237 return copy_large_unboxed_object(object, nwords);
1240 static long
1241 size_vector_single_float(lispobj *where)
1243 struct vector *vector;
1244 long length, nwords;
1246 vector = (struct vector *) where;
1247 length = fixnum_value(vector->length);
1248 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1250 return nwords;
1253 static long
1254 scav_vector_double_float(lispobj *where, lispobj object)
1256 struct vector *vector;
1257 long length, nwords;
1259 vector = (struct vector *) where;
1260 length = fixnum_value(vector->length);
1261 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1263 return nwords;
1266 static lispobj
1267 trans_vector_double_float(lispobj object)
1269 struct vector *vector;
1270 long length, nwords;
1272 gc_assert(is_lisp_pointer(object));
1274 vector = (struct vector *) native_pointer(object);
1275 length = fixnum_value(vector->length);
1276 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1278 return copy_large_unboxed_object(object, nwords);
1281 static long
1282 size_vector_double_float(lispobj *where)
1284 struct vector *vector;
1285 long length, nwords;
1287 vector = (struct vector *) where;
1288 length = fixnum_value(vector->length);
1289 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1291 return nwords;
1294 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1295 static long
1296 scav_vector_long_float(lispobj *where, lispobj object)
1298 struct vector *vector;
1299 long length, nwords;
1301 vector = (struct vector *) where;
1302 length = fixnum_value(vector->length);
1303 nwords = CEILING(length *
1304 LONG_FLOAT_SIZE
1305 + 2, 2);
1306 return nwords;
1309 static lispobj
1310 trans_vector_long_float(lispobj object)
1312 struct vector *vector;
1313 long length, nwords;
1315 gc_assert(is_lisp_pointer(object));
1317 vector = (struct vector *) native_pointer(object);
1318 length = fixnum_value(vector->length);
1319 nwords = CEILING(length * LONG_FLOAT_SIZE + 2, 2);
1321 return copy_large_unboxed_object(object, nwords);
1324 static long
1325 size_vector_long_float(lispobj *where)
1327 struct vector *vector;
1328 long length, nwords;
1330 vector = (struct vector *) where;
1331 length = fixnum_value(vector->length);
1332 nwords = CEILING(length * LONG_FLOAT_SIZE + 2, 2);
1334 return nwords;
1336 #endif
1339 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1340 static long
1341 scav_vector_complex_single_float(lispobj *where, lispobj object)
1343 struct vector *vector;
1344 long length, nwords;
1346 vector = (struct vector *) where;
1347 length = fixnum_value(vector->length);
1348 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1350 return nwords;
1353 static lispobj
1354 trans_vector_complex_single_float(lispobj object)
1356 struct vector *vector;
1357 long length, nwords;
1359 gc_assert(is_lisp_pointer(object));
1361 vector = (struct vector *) native_pointer(object);
1362 length = fixnum_value(vector->length);
1363 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1365 return copy_large_unboxed_object(object, nwords);
1368 static long
1369 size_vector_complex_single_float(lispobj *where)
1371 struct vector *vector;
1372 long length, nwords;
1374 vector = (struct vector *) where;
1375 length = fixnum_value(vector->length);
1376 nwords = CEILING(NWORDS(length, 64) + 2, 2);
1378 return nwords;
1380 #endif
1382 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1383 static long
1384 scav_vector_complex_double_float(lispobj *where, lispobj object)
1386 struct vector *vector;
1387 long length, nwords;
1389 vector = (struct vector *) where;
1390 length = fixnum_value(vector->length);
1391 nwords = CEILING(NWORDS(length, 128) + 2, 2);
1393 return nwords;
1396 static lispobj
1397 trans_vector_complex_double_float(lispobj object)
1399 struct vector *vector;
1400 long length, nwords;
1402 gc_assert(is_lisp_pointer(object));
1404 vector = (struct vector *) native_pointer(object);
1405 length = fixnum_value(vector->length);
1406 nwords = CEILING(NWORDS(length, 128) + 2, 2);
1408 return copy_large_unboxed_object(object, nwords);
1411 static long
1412 size_vector_complex_double_float(lispobj *where)
1414 struct vector *vector;
1415 long length, nwords;
1417 vector = (struct vector *) where;
1418 length = fixnum_value(vector->length);
1419 nwords = CEILING(NWORDS(length, 128) + 2, 2);
1421 return nwords;
1423 #endif
1426 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1427 static long
1428 scav_vector_complex_long_float(lispobj *where, lispobj object)
1430 struct vector *vector;
1431 long length, nwords;
1433 vector = (struct vector *) where;
1434 length = fixnum_value(vector->length);
1435 nwords = CEILING(length * (2* LONG_FLOAT_SIZE) + 2, 2);
1437 return nwords;
1440 static lispobj
1441 trans_vector_complex_long_float(lispobj object)
1443 struct vector *vector;
1444 long length, nwords;
1446 gc_assert(is_lisp_pointer(object));
1448 vector = (struct vector *) native_pointer(object);
1449 length = fixnum_value(vector->length);
1450 nwords = CEILING(length * (2*LONG_FLOAT_SIZE) + 2, 2);
1452 return copy_large_unboxed_object(object, nwords);
1455 static long
1456 size_vector_complex_long_float(lispobj *where)
1458 struct vector *vector;
1459 long length, nwords;
1461 vector = (struct vector *) where;
1462 length = fixnum_value(vector->length);
1463 nwords = CEILING(length * (2*LONG_FLOAT_SIZE) + 2, 2);
1465 return nwords;
1467 #endif
1469 #define WEAK_POINTER_NWORDS \
1470 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1472 static lispobj
1473 trans_weak_pointer(lispobj object)
1475 lispobj copy;
1476 #ifndef LISP_FEATURE_GENCGC
1477 struct weak_pointer *wp;
1478 #endif
1479 gc_assert(is_lisp_pointer(object));
1481 #if defined(DEBUG_WEAK)
1482 printf("Transporting weak pointer from 0x%08x\n", object);
1483 #endif
1485 /* Need to remember where all the weak pointers are that have */
1486 /* been transported so they can be fixed up in a post-GC pass. */
1488 copy = copy_object(object, WEAK_POINTER_NWORDS);
1489 #ifndef LISP_FEATURE_GENCGC
1490 wp = (struct weak_pointer *) native_pointer(copy);
1492 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
1493 /* Push the weak pointer onto the list of weak pointers. */
1494 wp->next = LOW_WORD(weak_pointers);
1495 weak_pointers = wp;
1496 #endif
1497 return copy;
1500 static long
1501 size_weak_pointer(lispobj *where)
1503 return WEAK_POINTER_NWORDS;
1507 void scan_weak_pointers(void)
1509 struct weak_pointer *wp;
1510 for (wp = weak_pointers; wp != NULL; wp=wp->next) {
1511 lispobj value = wp->value;
1512 lispobj *first_pointer;
1513 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
1514 if (!(is_lisp_pointer(value) && from_space_p(value)))
1515 continue;
1517 /* Now, we need to check whether the object has been forwarded. If
1518 * it has been, the weak pointer is still good and needs to be
1519 * updated. Otherwise, the weak pointer needs to be nil'ed
1520 * out. */
1522 first_pointer = (lispobj *)native_pointer(value);
1524 if (forwarding_pointer_p(first_pointer)) {
1525 wp->value=
1526 (lispobj)LOW_WORD(forwarding_pointer_value(first_pointer));
1527 } else {
1528 /* Break it. */
1529 wp->value = NIL;
1530 wp->broken = T;
1538 * initialization
1541 static long
1542 scav_lose(lispobj *where, lispobj object)
1544 lose("no scavenge function for object 0x%08x (widetag 0x%x)",
1545 (unsigned long)object,
1546 widetag_of(*(lispobj*)native_pointer(object)));
1548 return 0; /* bogus return value to satisfy static type checking */
1551 static lispobj
1552 trans_lose(lispobj object)
1554 lose("no transport function for object 0x%08x (widetag 0x%x)",
1555 (unsigned long)object,
1556 widetag_of(*(lispobj*)native_pointer(object)));
1557 return NIL; /* bogus return value to satisfy static type checking */
1560 static long
1561 size_lose(lispobj *where)
1563 lose("no size function for object at 0x%08x (widetag 0x%x)",
1564 (unsigned long)where,
1565 widetag_of(LOW_WORD(where)));
1566 return 1; /* bogus return value to satisfy static type checking */
1571 * initialization
1574 void
1575 gc_init_tables(void)
1577 long i;
1579 /* Set default value in all slots of scavenge table. FIXME
1580 * replace this gnarly sizeof with something based on
1581 * N_WIDETAG_BITS */
1582 for (i = 0; i < ((sizeof scavtab)/(sizeof scavtab[0])); i++) {
1583 scavtab[i] = scav_lose;
1586 /* For each type which can be selected by the lowtag alone, set
1587 * multiple entries in our widetag scavenge table (one for each
1588 * possible value of the high bits).
1591 for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
1592 scavtab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
1593 scavtab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_fun_pointer;
1594 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1595 scavtab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_list_pointer;
1596 scavtab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
1597 scavtab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_instance_pointer;
1598 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1599 scavtab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_other_pointer;
1602 /* Other-pointer types (those selected by all eight bits of the
1603 * tag) get one entry each in the scavenge table. */
1604 scavtab[BIGNUM_WIDETAG] = scav_unboxed;
1605 scavtab[RATIO_WIDETAG] = scav_boxed;
1606 #if N_WORD_BITS == 64
1607 scavtab[SINGLE_FLOAT_WIDETAG] = scav_immediate;
1608 #else
1609 scavtab[SINGLE_FLOAT_WIDETAG] = scav_unboxed;
1610 #endif
1611 scavtab[DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
1612 #ifdef LONG_FLOAT_WIDETAG
1613 scavtab[LONG_FLOAT_WIDETAG] = scav_unboxed;
1614 #endif
1615 scavtab[COMPLEX_WIDETAG] = scav_boxed;
1616 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1617 scavtab[COMPLEX_SINGLE_FLOAT_WIDETAG] = scav_unboxed;
1618 #endif
1619 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1620 scavtab[COMPLEX_DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
1621 #endif
1622 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1623 scavtab[COMPLEX_LONG_FLOAT_WIDETAG] = scav_unboxed;
1624 #endif
1625 scavtab[SIMPLE_ARRAY_WIDETAG] = scav_boxed;
1626 scavtab[SIMPLE_BASE_STRING_WIDETAG] = scav_base_string;
1627 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1628 scavtab[SIMPLE_CHARACTER_STRING_WIDETAG] = scav_character_string;
1629 #endif
1630 scavtab[SIMPLE_BIT_VECTOR_WIDETAG] = scav_vector_bit;
1631 scavtab[SIMPLE_ARRAY_NIL_WIDETAG] = scav_vector_nil;
1632 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
1633 scav_vector_unsigned_byte_2;
1634 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
1635 scav_vector_unsigned_byte_4;
1636 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
1637 scav_vector_unsigned_byte_8;
1638 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
1639 scav_vector_unsigned_byte_8;
1640 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
1641 scav_vector_unsigned_byte_16;
1642 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
1643 scav_vector_unsigned_byte_16;
1644 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
1645 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
1646 scav_vector_unsigned_byte_32;
1647 #endif
1648 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
1649 scav_vector_unsigned_byte_32;
1650 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
1651 scav_vector_unsigned_byte_32;
1652 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
1653 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
1654 scav_vector_unsigned_byte_64;
1655 #endif
1656 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
1657 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
1658 scav_vector_unsigned_byte_64;
1659 #endif
1660 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
1661 scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
1662 scav_vector_unsigned_byte_64;
1663 #endif
1664 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1665 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = scav_vector_unsigned_byte_8;
1666 #endif
1667 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1668 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
1669 scav_vector_unsigned_byte_16;
1670 #endif
1671 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1672 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
1673 scav_vector_unsigned_byte_32;
1674 #endif
1675 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1676 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
1677 scav_vector_unsigned_byte_32;
1678 #endif
1679 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
1680 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
1681 scav_vector_unsigned_byte_64;
1682 #endif
1683 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
1684 scavtab[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
1685 scav_vector_unsigned_byte_64;
1686 #endif
1687 scavtab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = scav_vector_single_float;
1688 scavtab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = scav_vector_double_float;
1689 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1690 scavtab[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] = scav_vector_long_float;
1691 #endif
1692 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1693 scavtab[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
1694 scav_vector_complex_single_float;
1695 #endif
1696 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1697 scavtab[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
1698 scav_vector_complex_double_float;
1699 #endif
1700 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1701 scavtab[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
1702 scav_vector_complex_long_float;
1703 #endif
1704 scavtab[COMPLEX_BASE_STRING_WIDETAG] = scav_boxed;
1705 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
1706 scavtab[COMPLEX_CHARACTER_STRING_WIDETAG] = scav_boxed;
1707 #endif
1708 scavtab[COMPLEX_VECTOR_NIL_WIDETAG] = scav_boxed;
1709 scavtab[COMPLEX_BIT_VECTOR_WIDETAG] = scav_boxed;
1710 scavtab[COMPLEX_VECTOR_WIDETAG] = scav_boxed;
1711 scavtab[COMPLEX_ARRAY_WIDETAG] = scav_boxed;
1712 scavtab[CODE_HEADER_WIDETAG] = scav_code_header;
1713 #ifndef LISP_FEATURE_GENCGC /* FIXME ..._X86 ? */
1714 scavtab[SIMPLE_FUN_HEADER_WIDETAG] = scav_fun_header;
1715 scavtab[RETURN_PC_HEADER_WIDETAG] = scav_return_pc_header;
1716 #endif
1717 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
1718 scavtab[CLOSURE_HEADER_WIDETAG] = scav_closure_header;
1719 scavtab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = scav_closure_header;
1720 #else
1721 scavtab[CLOSURE_HEADER_WIDETAG] = scav_boxed;
1722 scavtab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = scav_boxed;
1723 #endif
1724 scavtab[VALUE_CELL_HEADER_WIDETAG] = scav_boxed;
1725 scavtab[SYMBOL_HEADER_WIDETAG] = scav_boxed;
1726 scavtab[CHARACTER_WIDETAG] = scav_immediate;
1727 scavtab[SAP_WIDETAG] = scav_unboxed;
1728 scavtab[UNBOUND_MARKER_WIDETAG] = scav_immediate;
1729 scavtab[INSTANCE_HEADER_WIDETAG] = scav_instance;
1730 #ifdef LISP_FEATURE_SPARC
1731 scavtab[FDEFN_WIDETAG] = scav_boxed;
1732 #else
1733 scavtab[FDEFN_WIDETAG] = scav_fdefn;
1734 #endif
1736 /* transport other table, initialized same way as scavtab */
1737 for (i = 0; i < ((sizeof transother)/(sizeof transother[0])); i++)
1738 transother[i] = trans_lose;
1739 transother[BIGNUM_WIDETAG] = trans_unboxed;
1740 transother[RATIO_WIDETAG] = trans_boxed;
1742 #if N_WORD_BITS == 64
1743 transother[SINGLE_FLOAT_WIDETAG] = trans_immediate;
1744 #else
1745 transother[SINGLE_FLOAT_WIDETAG] = trans_unboxed;
1746 #endif
1747 transother[DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
1748 #ifdef LONG_FLOAT_WIDETAG
1749 transother[LONG_FLOAT_WIDETAG] = trans_unboxed;
1750 #endif
1751 transother[COMPLEX_WIDETAG] = trans_boxed;
1752 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1753 transother[COMPLEX_SINGLE_FLOAT_WIDETAG] = trans_unboxed;
1754 #endif
1755 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1756 transother[COMPLEX_DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
1757 #endif
1758 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1759 transother[COMPLEX_LONG_FLOAT_WIDETAG] = trans_unboxed;
1760 #endif
1761 transother[SIMPLE_ARRAY_WIDETAG] = trans_boxed; /* but not GENCGC */
1762 transother[SIMPLE_BASE_STRING_WIDETAG] = trans_base_string;
1763 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1764 transother[SIMPLE_CHARACTER_STRING_WIDETAG] = trans_character_string;
1765 #endif
1766 transother[SIMPLE_BIT_VECTOR_WIDETAG] = trans_vector_bit;
1767 transother[SIMPLE_VECTOR_WIDETAG] = trans_vector;
1768 transother[SIMPLE_ARRAY_NIL_WIDETAG] = trans_vector_nil;
1769 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
1770 trans_vector_unsigned_byte_2;
1771 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
1772 trans_vector_unsigned_byte_4;
1773 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
1774 trans_vector_unsigned_byte_8;
1775 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
1776 trans_vector_unsigned_byte_8;
1777 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
1778 trans_vector_unsigned_byte_16;
1779 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
1780 trans_vector_unsigned_byte_16;
1781 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
1782 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
1783 trans_vector_unsigned_byte_32;
1784 #endif
1785 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
1786 trans_vector_unsigned_byte_32;
1787 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
1788 trans_vector_unsigned_byte_32;
1789 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
1790 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
1791 trans_vector_unsigned_byte_64;
1792 #endif
1793 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
1794 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
1795 trans_vector_unsigned_byte_64;
1796 #endif
1797 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
1798 transother[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
1799 trans_vector_unsigned_byte_64;
1800 #endif
1801 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1802 transother[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] =
1803 trans_vector_unsigned_byte_8;
1804 #endif
1805 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1806 transother[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
1807 trans_vector_unsigned_byte_16;
1808 #endif
1809 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1810 transother[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
1811 trans_vector_unsigned_byte_32;
1812 #endif
1813 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1814 transother[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
1815 trans_vector_unsigned_byte_32;
1816 #endif
1817 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
1818 transother[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
1819 trans_vector_unsigned_byte_64;
1820 #endif
1821 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
1822 transother[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
1823 trans_vector_unsigned_byte_64;
1824 #endif
1825 transother[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] =
1826 trans_vector_single_float;
1827 transother[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] =
1828 trans_vector_double_float;
1829 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1830 transother[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] =
1831 trans_vector_long_float;
1832 #endif
1833 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1834 transother[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
1835 trans_vector_complex_single_float;
1836 #endif
1837 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1838 transother[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
1839 trans_vector_complex_double_float;
1840 #endif
1841 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1842 transother[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
1843 trans_vector_complex_long_float;
1844 #endif
1845 transother[COMPLEX_BASE_STRING_WIDETAG] = trans_boxed;
1846 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
1847 transother[COMPLEX_CHARACTER_STRING_WIDETAG] = trans_boxed;
1848 #endif
1849 transother[COMPLEX_BIT_VECTOR_WIDETAG] = trans_boxed;
1850 transother[COMPLEX_VECTOR_NIL_WIDETAG] = trans_boxed;
1851 transother[COMPLEX_VECTOR_WIDETAG] = trans_boxed;
1852 transother[COMPLEX_ARRAY_WIDETAG] = trans_boxed;
1853 transother[CODE_HEADER_WIDETAG] = trans_code_header;
1854 transother[SIMPLE_FUN_HEADER_WIDETAG] = trans_fun_header;
1855 transother[RETURN_PC_HEADER_WIDETAG] = trans_return_pc_header;
1856 transother[CLOSURE_HEADER_WIDETAG] = trans_boxed;
1857 transother[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = trans_boxed;
1858 transother[VALUE_CELL_HEADER_WIDETAG] = trans_boxed;
1859 transother[SYMBOL_HEADER_WIDETAG] = trans_boxed;
1860 transother[CHARACTER_WIDETAG] = trans_immediate;
1861 transother[SAP_WIDETAG] = trans_unboxed;
1862 transother[UNBOUND_MARKER_WIDETAG] = trans_immediate;
1863 transother[WEAK_POINTER_WIDETAG] = trans_weak_pointer;
1864 transother[INSTANCE_HEADER_WIDETAG] = trans_boxed;
1865 transother[FDEFN_WIDETAG] = trans_boxed;
1867 /* size table, initialized the same way as scavtab */
1868 for (i = 0; i < ((sizeof sizetab)/(sizeof sizetab[0])); i++)
1869 sizetab[i] = size_lose;
1870 for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
1871 sizetab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
1872 sizetab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
1873 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1874 sizetab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
1875 sizetab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
1876 sizetab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
1877 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1878 sizetab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
1880 sizetab[BIGNUM_WIDETAG] = size_unboxed;
1881 sizetab[RATIO_WIDETAG] = size_boxed;
1882 #if N_WORD_BITS == 64
1883 sizetab[SINGLE_FLOAT_WIDETAG] = size_immediate;
1884 #else
1885 sizetab[SINGLE_FLOAT_WIDETAG] = size_unboxed;
1886 #endif
1887 sizetab[DOUBLE_FLOAT_WIDETAG] = size_unboxed;
1888 #ifdef LONG_FLOAT_WIDETAG
1889 sizetab[LONG_FLOAT_WIDETAG] = size_unboxed;
1890 #endif
1891 sizetab[COMPLEX_WIDETAG] = size_boxed;
1892 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1893 sizetab[COMPLEX_SINGLE_FLOAT_WIDETAG] = size_unboxed;
1894 #endif
1895 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1896 sizetab[COMPLEX_DOUBLE_FLOAT_WIDETAG] = size_unboxed;
1897 #endif
1898 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1899 sizetab[COMPLEX_LONG_FLOAT_WIDETAG] = size_unboxed;
1900 #endif
1901 sizetab[SIMPLE_ARRAY_WIDETAG] = size_boxed;
1902 sizetab[SIMPLE_BASE_STRING_WIDETAG] = size_base_string;
1903 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1904 sizetab[SIMPLE_CHARACTER_STRING_WIDETAG] = size_character_string;
1905 #endif
1906 sizetab[SIMPLE_BIT_VECTOR_WIDETAG] = size_vector_bit;
1907 sizetab[SIMPLE_VECTOR_WIDETAG] = size_vector;
1908 sizetab[SIMPLE_ARRAY_NIL_WIDETAG] = size_vector_nil;
1909 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
1910 size_vector_unsigned_byte_2;
1911 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
1912 size_vector_unsigned_byte_4;
1913 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
1914 size_vector_unsigned_byte_8;
1915 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
1916 size_vector_unsigned_byte_8;
1917 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
1918 size_vector_unsigned_byte_16;
1919 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
1920 size_vector_unsigned_byte_16;
1921 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
1922 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
1923 size_vector_unsigned_byte_32;
1924 #endif
1925 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
1926 size_vector_unsigned_byte_32;
1927 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
1928 size_vector_unsigned_byte_32;
1929 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
1930 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
1931 size_vector_unsigned_byte_64;
1932 #endif
1933 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
1934 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
1935 size_vector_unsigned_byte_64;
1936 #endif
1937 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
1938 sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
1939 size_vector_unsigned_byte_64;
1940 #endif
1941 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1942 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = size_vector_unsigned_byte_8;
1943 #endif
1944 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1945 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG] =
1946 size_vector_unsigned_byte_16;
1947 #endif
1948 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1949 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG] =
1950 size_vector_unsigned_byte_32;
1951 #endif
1952 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1953 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
1954 size_vector_unsigned_byte_32;
1955 #endif
1956 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
1957 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
1958 size_vector_unsigned_byte_64;
1959 #endif
1960 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
1961 sizetab[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
1962 size_vector_unsigned_byte_64;
1963 #endif
1964 sizetab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = size_vector_single_float;
1965 sizetab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = size_vector_double_float;
1966 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1967 sizetab[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG] = size_vector_long_float;
1968 #endif
1969 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1970 sizetab[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG] =
1971 size_vector_complex_single_float;
1972 #endif
1973 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1974 sizetab[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG] =
1975 size_vector_complex_double_float;
1976 #endif
1977 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1978 sizetab[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG] =
1979 size_vector_complex_long_float;
1980 #endif
1981 sizetab[COMPLEX_BASE_STRING_WIDETAG] = size_boxed;
1982 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
1983 sizetab[COMPLEX_CHARACTER_STRING_WIDETAG] = size_boxed;
1984 #endif
1985 sizetab[COMPLEX_VECTOR_NIL_WIDETAG] = size_boxed;
1986 sizetab[COMPLEX_BIT_VECTOR_WIDETAG] = size_boxed;
1987 sizetab[COMPLEX_VECTOR_WIDETAG] = size_boxed;
1988 sizetab[COMPLEX_ARRAY_WIDETAG] = size_boxed;
1989 sizetab[CODE_HEADER_WIDETAG] = size_code_header;
1990 #if 0
1991 /* We shouldn't see these, so just lose if it happens. */
1992 sizetab[SIMPLE_FUN_HEADER_WIDETAG] = size_function_header;
1993 sizetab[RETURN_PC_HEADER_WIDETAG] = size_return_pc_header;
1994 #endif
1995 sizetab[CLOSURE_HEADER_WIDETAG] = size_boxed;
1996 sizetab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = size_boxed;
1997 sizetab[VALUE_CELL_HEADER_WIDETAG] = size_boxed;
1998 sizetab[SYMBOL_HEADER_WIDETAG] = size_boxed;
1999 sizetab[CHARACTER_WIDETAG] = size_immediate;
2000 sizetab[SAP_WIDETAG] = size_unboxed;
2001 sizetab[UNBOUND_MARKER_WIDETAG] = size_immediate;
2002 sizetab[WEAK_POINTER_WIDETAG] = size_weak_pointer;
2003 sizetab[INSTANCE_HEADER_WIDETAG] = size_boxed;
2004 sizetab[FDEFN_WIDETAG] = size_boxed;
2008 /* Find the code object for the given pc, or return NULL on
2009 failure. */
2010 lispobj *
2011 component_ptr_from_pc(lispobj *pc)
2013 lispobj *object = NULL;
2015 if ( (object = search_read_only_space(pc)) )
2017 else if ( (object = search_static_space(pc)) )
2019 else
2020 object = search_dynamic_space(pc);
2022 if (object) /* if we found something */
2023 if (widetag_of(*object) == CODE_HEADER_WIDETAG)
2024 return(object);
2026 return (NULL);
2029 /* Scan an area looking for an object which encloses the given pointer.
2030 * Return the object start on success or NULL on failure. */
2031 lispobj *
2032 gc_search_space(lispobj *start, size_t words, lispobj *pointer)
2034 while (words > 0) {
2035 size_t count = 1;
2036 lispobj thing = *start;
2038 /* If thing is an immediate then this is a cons. */
2039 if (is_lisp_pointer(thing)
2040 || (fixnump(thing))
2041 || (widetag_of(thing) == CHARACTER_WIDETAG)
2042 #if N_WORD_BITS == 64
2043 || (widetag_of(thing) == SINGLE_FLOAT_WIDETAG)
2044 #endif
2045 || (widetag_of(thing) == UNBOUND_MARKER_WIDETAG))
2046 count = 2;
2047 else
2048 count = (sizetab[widetag_of(thing)])(start);
2050 /* Check whether the pointer is within this object. */
2051 if ((pointer >= start) && (pointer < (start+count))) {
2052 /* found it! */
2053 /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/
2054 return(start);
2057 /* Round up the count. */
2058 count = CEILING(count,2);
2060 start += count;
2061 words -= count;
2063 return (NULL);