2 * Garbage Collection common functions for scavenging, moving and sizing
3 * objects. These are for use with both GC (stop & copy GC) and GENCGC
7 * This software is part of the SBCL system. See the README file for
10 * This software is derived from the CMU CL system, which was
11 * written at Carnegie Mellon University and released into the
12 * public domain. The software is in the public domain and is
13 * provided with absolutely no warranty. See the COPYING and CREDITS
14 * files for more information.
18 * For a review of garbage collection techniques (e.g. generational
19 * GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
20 * "Uniprocessor Garbage Collection Techniques". As of 20000618, this
21 * had been accepted for _ACM Computing Surveys_ and was available
22 * as a PostScript preprint through
23 * <http://www.cs.utexas.edu/users/oops/papers.html>
25 * <ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps>.
36 #include "interrupt.h"
42 #include "genesis/primitive-objects.h"
43 #include "genesis/static-symbols.h"
44 #include "genesis/layout.h"
45 #include "gc-internal.h"
47 #ifdef LISP_FEATURE_SPARC
48 #define LONG_FLOAT_SIZE 4
50 #ifdef LISP_FEATURE_X86
51 #define LONG_FLOAT_SIZE 3
56 forwarding_pointer_p(lispobj
*pointer
) {
57 lispobj first_word
=*pointer
;
58 #ifdef LISP_FEATURE_GENCGC
59 return (first_word
== 0x01);
61 return (is_lisp_pointer(first_word
)
62 && new_space_p(first_word
));
66 static inline lispobj
*
67 forwarding_pointer_value(lispobj
*pointer
) {
68 #ifdef LISP_FEATURE_GENCGC
69 return (lispobj
*) ((pointer_sized_uint_t
) pointer
[1]);
71 return (lispobj
*) ((pointer_sized_uint_t
) pointer
[0]);
75 set_forwarding_pointer(lispobj
* pointer
, lispobj newspace_copy
) {
76 #ifdef LISP_FEATURE_GENCGC
78 pointer
[1]=newspace_copy
;
80 pointer
[0]=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;
97 /* to copy a boxed object */
99 copy_object(lispobj object
, long nwords
)
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. */
125 scavenge(lispobj
*start
, long n_words
)
127 lispobj
*end
= start
+ n_words
;
129 long n_words_scavenged
;
131 for (object_ptr
= start
;
133 object_ptr
+= n_words_scavenged
) {
135 lispobj object
= *object_ptr
;
136 #ifdef LISP_FEATURE_GENCGC
137 gc_assert(!forwarding_pointer_p(object_ptr
));
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;
149 /* Scavenge that pointer. */
151 (scavtab
[widetag_of(object
)])(object_ptr
, object
);
154 /* It points somewhere other than oldspace. Leave it
156 n_words_scavenged
= 1;
159 #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
160 /* This workaround is probably not needed for those ports
161 which don't have a partitioned register set (and therefore
162 scan the stack conservatively for roots). */
163 else if (n_words
== 1) {
164 /* there are some situations where an other-immediate may
165 end up in a descriptor register. I'm not sure whether
166 this is 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 we're
169 checking a single word and it's anything other than a
170 pointer, just hush it up */
171 int widetag
= widetag_of(object
);
172 n_words_scavenged
= 1;
174 if ((scavtab
[widetag
] == scav_lose
) ||
175 (((sizetab
[widetag
])(object_ptr
)) > 1)) {
176 fprintf(stderr
,"warning: \
177 attempted to scavenge non-descriptor value %x at %p.\n\n\
178 If you can reproduce this warning, please send a bug report\n\
179 (see manual page for details).\n",
184 else if (fixnump(object
)) {
185 /* It's a fixnum: really easy.. */
186 n_words_scavenged
= 1;
188 /* It's some sort of header object or another. */
190 (scavtab
[widetag_of(object
)])(object_ptr
, object
);
193 gc_assert_verbose(object_ptr
== end
, "Final object pointer %p, start %p, end %p\n",
194 object_ptr
, start
, end
);
197 static lispobj
trans_fun_header(lispobj object
); /* forward decls */
198 static lispobj
trans_boxed(lispobj object
);
201 scav_fun_pointer(lispobj
*where
, lispobj object
)
203 lispobj
*first_pointer
;
206 gc_assert(is_lisp_pointer(object
));
208 /* Object is a pointer into from_space - not a FP. */
209 first_pointer
= (lispobj
*) native_pointer(object
);
211 /* must transport object -- object may point to either a function
212 * header, a closure function header, or to a closure header. */
214 switch (widetag_of(*first_pointer
)) {
215 case SIMPLE_FUN_HEADER_WIDETAG
:
216 copy
= trans_fun_header(object
);
219 copy
= trans_boxed(object
);
223 if (copy
!= object
) {
224 /* Set forwarding pointer */
225 set_forwarding_pointer(first_pointer
,copy
);
228 gc_assert(is_lisp_pointer(copy
));
229 gc_assert(!from_space_p(copy
));
238 trans_code(struct code
*code
)
240 struct code
*new_code
;
241 lispobj first
, l_code
, l_new_code
;
242 long nheader_words
, ncode_words
, nwords
;
243 unsigned long displacement
;
244 lispobj fheaderl
, *prev_pointer
;
246 /* if object has already been transported, just return pointer */
247 first
= code
->header
;
248 if (forwarding_pointer_p((lispobj
*)code
)) {
250 printf("Was already transported\n");
252 return (struct code
*) forwarding_pointer_value
253 ((lispobj
*)((pointer_sized_uint_t
) code
));
256 gc_assert(widetag_of(first
) == CODE_HEADER_WIDETAG
);
258 /* prepare to transport the code vector */
259 l_code
= (lispobj
) LOW_WORD(code
) | OTHER_POINTER_LOWTAG
;
261 ncode_words
= fixnum_value(code
->code_size
);
262 nheader_words
= HeaderValue(code
->header
);
263 nwords
= ncode_words
+ nheader_words
;
264 nwords
= CEILING(nwords
, 2);
266 l_new_code
= copy_object(l_code
, nwords
);
267 new_code
= (struct code
*) native_pointer(l_new_code
);
269 #if defined(DEBUG_CODE_GC)
270 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
271 (unsigned long) code
, (unsigned long) new_code
);
272 printf("Code object is %d words long.\n", nwords
);
275 #ifdef LISP_FEATURE_GENCGC
276 if (new_code
== code
)
280 displacement
= l_new_code
- l_code
;
282 set_forwarding_pointer((lispobj
*)code
, l_new_code
);
284 /* set forwarding pointers for all the function headers in the */
285 /* code object. also fix all self pointers */
287 fheaderl
= code
->entry_points
;
288 prev_pointer
= &new_code
->entry_points
;
290 while (fheaderl
!= NIL
) {
291 struct simple_fun
*fheaderp
, *nfheaderp
;
294 fheaderp
= (struct simple_fun
*) native_pointer(fheaderl
);
295 gc_assert(widetag_of(fheaderp
->header
) == SIMPLE_FUN_HEADER_WIDETAG
);
297 /* Calculate the new function pointer and the new */
298 /* function header. */
299 nfheaderl
= fheaderl
+ displacement
;
300 nfheaderp
= (struct simple_fun
*) native_pointer(nfheaderl
);
303 printf("fheaderp->header (at %x) <- %x\n",
304 &(fheaderp
->header
) , nfheaderl
);
306 set_forwarding_pointer((lispobj
*)fheaderp
, nfheaderl
);
308 /* fix self pointer. */
310 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
311 FUN_RAW_ADDR_OFFSET
+
315 *prev_pointer
= nfheaderl
;
317 fheaderl
= fheaderp
->next
;
318 prev_pointer
= &nfheaderp
->next
;
320 #ifdef LISP_FEATURE_GENCGC
321 /* Cheneygc doesn't need this os_flush_icache, it flushes the whole
322 spaces once when all copying is done. */
323 os_flush_icache((os_vm_address_t
) (((long *)new_code
) + nheader_words
),
324 ncode_words
* sizeof(long));
328 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
329 gencgc_apply_code_fixups(code
, new_code
);
336 scav_code_header(lispobj
*where
, lispobj object
)
339 long n_header_words
, n_code_words
, n_words
;
340 lispobj entry_point
; /* tagged pointer to entry point */
341 struct simple_fun
*function_ptr
; /* untagged pointer to entry point */
343 code
= (struct code
*) where
;
344 n_code_words
= fixnum_value(code
->code_size
);
345 n_header_words
= HeaderValue(object
);
346 n_words
= n_code_words
+ n_header_words
;
347 n_words
= CEILING(n_words
, 2);
349 /* Scavenge the boxed section of the code data block. */
350 scavenge(where
+ 1, n_header_words
- 1);
352 /* Scavenge the boxed section of each function object in the
353 * code data block. */
354 for (entry_point
= code
->entry_points
;
356 entry_point
= function_ptr
->next
) {
358 gc_assert_verbose(is_lisp_pointer(entry_point
), "Entry point %lx\n",
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);
373 trans_code_header(lispobj object
)
377 ncode
= trans_code((struct code
*) native_pointer(object
));
378 return (lispobj
) LOW_WORD(ncode
) | OTHER_POINTER_LOWTAG
;
383 size_code_header(lispobj
*where
)
386 long 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);
398 #if !defined(LISP_FEATURE_X86) && ! defined(LISP_FEATURE_X86_64)
400 scav_return_pc_header(lispobj
*where
, lispobj object
)
402 lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x\n",
403 (unsigned long) where
,
404 (unsigned long) object
);
405 return 0; /* bogus return value to satisfy static type checking */
407 #endif /* LISP_FEATURE_X86 */
410 trans_return_pc_header(lispobj object
)
412 struct simple_fun
*return_pc
;
413 unsigned long offset
;
414 struct code
*code
, *ncode
;
416 return_pc
= (struct simple_fun
*) native_pointer(object
);
417 /* FIXME: was times 4, should it really be N_WORD_BYTES? */
418 offset
= HeaderValue(return_pc
->header
) * N_WORD_BYTES
;
420 /* Transport the whole code object */
421 code
= (struct code
*) ((unsigned long) return_pc
- offset
);
422 ncode
= trans_code(code
);
424 return ((lispobj
) LOW_WORD(ncode
) + offset
) | OTHER_POINTER_LOWTAG
;
427 /* On the 386, closures hold a pointer to the raw address instead of the
428 * function object, so we can use CALL [$FDEFN+const] to invoke
429 * the function without loading it into a register. Given that code
430 * objects don't move, we don't need to update anything, but we do
431 * have to figure out that the function is still live. */
433 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
435 scav_closure_header(lispobj
*where
, lispobj object
)
437 struct closure
*closure
;
440 closure
= (struct closure
*)where
;
441 fun
= closure
->fun
- FUN_RAW_ADDR_OFFSET
;
443 #ifdef LISP_FEATURE_GENCGC
444 /* The function may have moved so update the raw address. But
445 * don't write unnecessarily. */
446 if (closure
->fun
!= fun
+ FUN_RAW_ADDR_OFFSET
)
447 closure
->fun
= fun
+ FUN_RAW_ADDR_OFFSET
;
453 #if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64))
455 scav_fun_header(lispobj
*where
, lispobj object
)
457 lose("attempted to scavenge a function header where=0x%08x object=0x%08x\n",
458 (unsigned long) where
,
459 (unsigned long) object
);
460 return 0; /* bogus return value to satisfy static type checking */
462 #endif /* LISP_FEATURE_X86 */
465 trans_fun_header(lispobj object
)
467 struct simple_fun
*fheader
;
468 unsigned long offset
;
469 struct code
*code
, *ncode
;
471 fheader
= (struct simple_fun
*) native_pointer(object
);
472 /* FIXME: was times 4, should it really be N_WORD_BYTES? */
473 offset
= HeaderValue(fheader
->header
) * N_WORD_BYTES
;
475 /* Transport the whole code object */
476 code
= (struct code
*) ((unsigned long) fheader
- offset
);
477 ncode
= trans_code(code
);
479 return ((lispobj
) LOW_WORD(ncode
) + offset
) | FUN_POINTER_LOWTAG
;
488 scav_instance_pointer(lispobj
*where
, lispobj object
)
490 lispobj copy
, *first_pointer
;
492 /* Object is a pointer into from space - not a FP. */
493 copy
= trans_boxed(object
);
495 #ifdef LISP_FEATURE_GENCGC
496 gc_assert(copy
!= object
);
499 first_pointer
= (lispobj
*) native_pointer(object
);
500 set_forwarding_pointer(first_pointer
,copy
);
511 static lispobj
trans_list(lispobj object
);
514 scav_list_pointer(lispobj
*where
, lispobj object
)
516 lispobj first
, *first_pointer
;
518 gc_assert(is_lisp_pointer(object
));
520 /* Object is a pointer into from space - not FP. */
521 first_pointer
= (lispobj
*) native_pointer(object
);
523 first
= trans_list(object
);
524 gc_assert(first
!= object
);
526 /* Set forwarding pointer */
527 set_forwarding_pointer(first_pointer
, first
);
529 gc_assert(is_lisp_pointer(first
));
530 gc_assert(!from_space_p(first
));
538 trans_list(lispobj object
)
540 lispobj new_list_pointer
;
541 struct cons
*cons
, *new_cons
;
544 cons
= (struct cons
*) native_pointer(object
);
547 new_cons
= (struct cons
*)
548 gc_general_alloc(sizeof(struct cons
),ALLOC_BOXED
,ALLOC_QUICK
);
549 new_cons
->car
= cons
->car
;
550 new_cons
->cdr
= cons
->cdr
; /* updated later */
551 new_list_pointer
= make_lispobj(new_cons
,lowtag_of(object
));
553 /* Grab the cdr: set_forwarding_pointer will clobber it in GENCGC */
556 set_forwarding_pointer((lispobj
*)cons
, new_list_pointer
);
558 /* Try to linearize the list in the cdr direction to help reduce
562 struct cons
*cdr_cons
, *new_cdr_cons
;
564 if(lowtag_of(cdr
) != LIST_POINTER_LOWTAG
||
565 !from_space_p(cdr
) ||
566 forwarding_pointer_p((lispobj
*)native_pointer(cdr
)))
569 cdr_cons
= (struct cons
*) native_pointer(cdr
);
572 new_cdr_cons
= (struct cons
*)
573 gc_general_alloc(sizeof(struct cons
),ALLOC_BOXED
,ALLOC_QUICK
);
574 new_cdr_cons
->car
= cdr_cons
->car
;
575 new_cdr_cons
->cdr
= cdr_cons
->cdr
;
576 new_cdr
= make_lispobj(new_cdr_cons
, lowtag_of(cdr
));
578 /* Grab the cdr before it is clobbered. */
580 set_forwarding_pointer((lispobj
*)cdr_cons
, new_cdr
);
582 /* Update the cdr of the last cons copied into new space to
583 * keep the newspace scavenge from having to do it. */
584 new_cons
->cdr
= new_cdr
;
586 new_cons
= new_cdr_cons
;
589 return new_list_pointer
;
594 * scavenging and transporting other pointers
598 scav_other_pointer(lispobj
*where
, lispobj object
)
600 lispobj first
, *first_pointer
;
602 gc_assert(is_lisp_pointer(object
));
604 /* Object is a pointer into from space - not FP. */
605 first_pointer
= (lispobj
*) native_pointer(object
);
606 first
= (transother
[widetag_of(*first_pointer
)])(object
);
608 if (first
!= object
) {
609 set_forwarding_pointer(first_pointer
, first
);
610 #ifdef LISP_FEATURE_GENCGC
614 #ifndef LISP_FEATURE_GENCGC
617 gc_assert(is_lisp_pointer(first
));
618 gc_assert(!from_space_p(first
));
624 * immediate, boxed, and unboxed objects
628 size_pointer(lispobj
*where
)
634 scav_immediate(lispobj
*where
, lispobj object
)
640 trans_immediate(lispobj object
)
642 lose("trying to transport an immediate\n");
643 return NIL
; /* bogus return value to satisfy static type checking */
647 size_immediate(lispobj
*where
)
654 scav_boxed(lispobj
*where
, lispobj object
)
660 scav_instance(lispobj
*where
, lispobj object
)
663 long ntotal
= HeaderValue(object
);
664 lispobj layout
= ((struct instance
*)where
)->slots
[0];
668 if (forwarding_pointer_p(native_pointer(layout
)))
669 layout
= (lispobj
) forwarding_pointer_value(native_pointer(layout
));
671 nuntagged
= ((struct layout
*)native_pointer(layout
))->n_untagged_slots
;
672 scavenge(where
+ 1, ntotal
- fixnum_value(nuntagged
));
678 trans_boxed(lispobj object
)
681 unsigned long length
;
683 gc_assert(is_lisp_pointer(object
));
685 header
= *((lispobj
*) native_pointer(object
));
686 length
= HeaderValue(header
) + 1;
687 length
= CEILING(length
, 2);
689 return copy_object(object
, length
);
694 size_boxed(lispobj
*where
)
697 unsigned long length
;
700 length
= HeaderValue(header
) + 1;
701 length
= CEILING(length
, 2);
706 /* Note: on the sparc we don't have to do anything special for fdefns, */
707 /* 'cause the raw-addr has a function lowtag. */
708 #if !defined(LISP_FEATURE_SPARC)
710 scav_fdefn(lispobj
*where
, lispobj object
)
714 fdefn
= (struct fdefn
*)where
;
716 /* FSHOW((stderr, "scav_fdefn, function = %p, raw_addr = %p\n",
717 fdefn->fun, fdefn->raw_addr)); */
719 if ((char *)(fdefn
->fun
+ FUN_RAW_ADDR_OFFSET
)
720 == (char *)((unsigned long)(fdefn
->raw_addr
))) {
721 scavenge(where
+ 1, sizeof(struct fdefn
)/sizeof(lispobj
) - 1);
723 /* Don't write unnecessarily. */
724 if (fdefn
->raw_addr
!= (char *)(fdefn
->fun
+ FUN_RAW_ADDR_OFFSET
))
725 fdefn
->raw_addr
= (char *)(fdefn
->fun
+ FUN_RAW_ADDR_OFFSET
);
726 /* gc.c has more casts here, which may be relevant or alternatively
727 may be compiler warning defeaters. try
728 fdefn->raw_addr = ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET;
730 return sizeof(struct fdefn
) / sizeof(lispobj
);
738 scav_unboxed(lispobj
*where
, lispobj object
)
740 unsigned long length
;
742 length
= HeaderValue(object
) + 1;
743 length
= CEILING(length
, 2);
749 trans_unboxed(lispobj object
)
752 unsigned long length
;
755 gc_assert(is_lisp_pointer(object
));
757 header
= *((lispobj
*) native_pointer(object
));
758 length
= HeaderValue(header
) + 1;
759 length
= CEILING(length
, 2);
761 return copy_unboxed_object(object
, length
);
765 size_unboxed(lispobj
*where
)
768 unsigned long length
;
771 length
= HeaderValue(header
) + 1;
772 length
= CEILING(length
, 2);
778 /* vector-like objects */
780 scav_base_string(lispobj
*where
, lispobj object
)
782 struct vector
*vector
;
785 /* NOTE: Strings contain one more byte of data than the length */
786 /* slot indicates. */
788 vector
= (struct vector
*) where
;
789 length
= fixnum_value(vector
->length
) + 1;
790 nwords
= CEILING(NWORDS(length
, 8) + 2, 2);
795 trans_base_string(lispobj object
)
797 struct vector
*vector
;
800 gc_assert(is_lisp_pointer(object
));
802 /* NOTE: A string contains one more byte of data (a terminating
803 * '\0' to help when interfacing with C functions) than indicated
804 * by the length slot. */
806 vector
= (struct vector
*) native_pointer(object
);
807 length
= fixnum_value(vector
->length
) + 1;
808 nwords
= CEILING(NWORDS(length
, 8) + 2, 2);
810 return copy_large_unboxed_object(object
, nwords
);
814 size_base_string(lispobj
*where
)
816 struct vector
*vector
;
819 /* NOTE: A string contains one more byte of data (a terminating
820 * '\0' to help when interfacing with C functions) than indicated
821 * by the length slot. */
823 vector
= (struct vector
*) where
;
824 length
= fixnum_value(vector
->length
) + 1;
825 nwords
= CEILING(NWORDS(length
, 8) + 2, 2);
831 scav_character_string(lispobj
*where
, lispobj object
)
833 struct vector
*vector
;
836 /* NOTE: Strings contain one more byte of data than the length */
837 /* slot indicates. */
839 vector
= (struct vector
*) where
;
840 length
= fixnum_value(vector
->length
) + 1;
841 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
846 trans_character_string(lispobj object
)
848 struct vector
*vector
;
851 gc_assert(is_lisp_pointer(object
));
853 /* NOTE: A string contains one more byte of data (a terminating
854 * '\0' to help when interfacing with C functions) than indicated
855 * by the length slot. */
857 vector
= (struct vector
*) native_pointer(object
);
858 length
= fixnum_value(vector
->length
) + 1;
859 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
861 return copy_large_unboxed_object(object
, nwords
);
865 size_character_string(lispobj
*where
)
867 struct vector
*vector
;
870 /* NOTE: A string contains one more byte of data (a terminating
871 * '\0' to help when interfacing with C functions) than indicated
872 * by the length slot. */
874 vector
= (struct vector
*) where
;
875 length
= fixnum_value(vector
->length
) + 1;
876 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
882 trans_vector(lispobj object
)
884 struct vector
*vector
;
887 gc_assert(is_lisp_pointer(object
));
889 vector
= (struct vector
*) native_pointer(object
);
891 length
= fixnum_value(vector
->length
);
892 nwords
= CEILING(length
+ 2, 2);
894 return copy_large_object(object
, nwords
);
898 size_vector(lispobj
*where
)
900 struct vector
*vector
;
903 vector
= (struct vector
*) where
;
904 length
= fixnum_value(vector
->length
);
905 nwords
= CEILING(length
+ 2, 2);
911 scav_vector_nil(lispobj
*where
, lispobj object
)
917 trans_vector_nil(lispobj object
)
919 gc_assert(is_lisp_pointer(object
));
920 return copy_unboxed_object(object
, 2);
924 size_vector_nil(lispobj
*where
)
926 /* Just the header word and the length word */
931 scav_vector_bit(lispobj
*where
, lispobj object
)
933 struct vector
*vector
;
936 vector
= (struct vector
*) where
;
937 length
= fixnum_value(vector
->length
);
938 nwords
= CEILING(NWORDS(length
, 1) + 2, 2);
944 trans_vector_bit(lispobj object
)
946 struct vector
*vector
;
949 gc_assert(is_lisp_pointer(object
));
951 vector
= (struct vector
*) native_pointer(object
);
952 length
= fixnum_value(vector
->length
);
953 nwords
= CEILING(NWORDS(length
, 1) + 2, 2);
955 return copy_large_unboxed_object(object
, nwords
);
959 size_vector_bit(lispobj
*where
)
961 struct vector
*vector
;
964 vector
= (struct vector
*) where
;
965 length
= fixnum_value(vector
->length
);
966 nwords
= CEILING(NWORDS(length
, 1) + 2, 2);
972 scav_vector_unsigned_byte_2(lispobj
*where
, lispobj object
)
974 struct vector
*vector
;
977 vector
= (struct vector
*) where
;
978 length
= fixnum_value(vector
->length
);
979 nwords
= CEILING(NWORDS(length
, 2) + 2, 2);
985 trans_vector_unsigned_byte_2(lispobj object
)
987 struct vector
*vector
;
990 gc_assert(is_lisp_pointer(object
));
992 vector
= (struct vector
*) native_pointer(object
);
993 length
= fixnum_value(vector
->length
);
994 nwords
= CEILING(NWORDS(length
, 2) + 2, 2);
996 return copy_large_unboxed_object(object
, nwords
);
1000 size_vector_unsigned_byte_2(lispobj
*where
)
1002 struct vector
*vector
;
1003 long length
, nwords
;
1005 vector
= (struct vector
*) where
;
1006 length
= fixnum_value(vector
->length
);
1007 nwords
= CEILING(NWORDS(length
, 2) + 2, 2);
1013 scav_vector_unsigned_byte_4(lispobj
*where
, lispobj object
)
1015 struct vector
*vector
;
1016 long length
, nwords
;
1018 vector
= (struct vector
*) where
;
1019 length
= fixnum_value(vector
->length
);
1020 nwords
= CEILING(NWORDS(length
, 4) + 2, 2);
1026 trans_vector_unsigned_byte_4(lispobj object
)
1028 struct vector
*vector
;
1029 long length
, nwords
;
1031 gc_assert(is_lisp_pointer(object
));
1033 vector
= (struct vector
*) native_pointer(object
);
1034 length
= fixnum_value(vector
->length
);
1035 nwords
= CEILING(NWORDS(length
, 4) + 2, 2);
1037 return copy_large_unboxed_object(object
, nwords
);
1040 size_vector_unsigned_byte_4(lispobj
*where
)
1042 struct vector
*vector
;
1043 long length
, nwords
;
1045 vector
= (struct vector
*) where
;
1046 length
= fixnum_value(vector
->length
);
1047 nwords
= CEILING(NWORDS(length
, 4) + 2, 2);
1054 scav_vector_unsigned_byte_8(lispobj
*where
, lispobj object
)
1056 struct vector
*vector
;
1057 long length
, nwords
;
1059 vector
= (struct vector
*) where
;
1060 length
= fixnum_value(vector
->length
);
1061 nwords
= CEILING(NWORDS(length
, 8) + 2, 2);
1066 /*********************/
1071 trans_vector_unsigned_byte_8(lispobj object
)
1073 struct vector
*vector
;
1074 long length
, nwords
;
1076 gc_assert(is_lisp_pointer(object
));
1078 vector
= (struct vector
*) native_pointer(object
);
1079 length
= fixnum_value(vector
->length
);
1080 nwords
= CEILING(NWORDS(length
, 8) + 2, 2);
1082 return copy_large_unboxed_object(object
, nwords
);
1086 size_vector_unsigned_byte_8(lispobj
*where
)
1088 struct vector
*vector
;
1089 long length
, nwords
;
1091 vector
= (struct vector
*) where
;
1092 length
= fixnum_value(vector
->length
);
1093 nwords
= CEILING(NWORDS(length
, 8) + 2, 2);
1100 scav_vector_unsigned_byte_16(lispobj
*where
, lispobj object
)
1102 struct vector
*vector
;
1103 long length
, nwords
;
1105 vector
= (struct vector
*) where
;
1106 length
= fixnum_value(vector
->length
);
1107 nwords
= CEILING(NWORDS(length
, 16) + 2, 2);
1113 trans_vector_unsigned_byte_16(lispobj object
)
1115 struct vector
*vector
;
1116 long length
, nwords
;
1118 gc_assert(is_lisp_pointer(object
));
1120 vector
= (struct vector
*) native_pointer(object
);
1121 length
= fixnum_value(vector
->length
);
1122 nwords
= CEILING(NWORDS(length
, 16) + 2, 2);
1124 return copy_large_unboxed_object(object
, nwords
);
1128 size_vector_unsigned_byte_16(lispobj
*where
)
1130 struct vector
*vector
;
1131 long length
, nwords
;
1133 vector
= (struct vector
*) where
;
1134 length
= fixnum_value(vector
->length
);
1135 nwords
= CEILING(NWORDS(length
, 16) + 2, 2);
1141 scav_vector_unsigned_byte_32(lispobj
*where
, lispobj object
)
1143 struct vector
*vector
;
1144 long length
, nwords
;
1146 vector
= (struct vector
*) where
;
1147 length
= fixnum_value(vector
->length
);
1148 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
1154 trans_vector_unsigned_byte_32(lispobj object
)
1156 struct vector
*vector
;
1157 long length
, nwords
;
1159 gc_assert(is_lisp_pointer(object
));
1161 vector
= (struct vector
*) native_pointer(object
);
1162 length
= fixnum_value(vector
->length
);
1163 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
1165 return copy_large_unboxed_object(object
, nwords
);
1169 size_vector_unsigned_byte_32(lispobj
*where
)
1171 struct vector
*vector
;
1172 long length
, nwords
;
1174 vector
= (struct vector
*) where
;
1175 length
= fixnum_value(vector
->length
);
1176 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
1181 #if N_WORD_BITS == 64
1183 scav_vector_unsigned_byte_64(lispobj
*where
, lispobj object
)
1185 struct vector
*vector
;
1186 long length
, nwords
;
1188 vector
= (struct vector
*) where
;
1189 length
= fixnum_value(vector
->length
);
1190 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1196 trans_vector_unsigned_byte_64(lispobj object
)
1198 struct vector
*vector
;
1199 long length
, nwords
;
1201 gc_assert(is_lisp_pointer(object
));
1203 vector
= (struct vector
*) native_pointer(object
);
1204 length
= fixnum_value(vector
->length
);
1205 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1207 return copy_large_unboxed_object(object
, nwords
);
1211 size_vector_unsigned_byte_64(lispobj
*where
)
1213 struct vector
*vector
;
1214 long length
, nwords
;
1216 vector
= (struct vector
*) where
;
1217 length
= fixnum_value(vector
->length
);
1218 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1225 scav_vector_single_float(lispobj
*where
, lispobj object
)
1227 struct vector
*vector
;
1228 long length
, nwords
;
1230 vector
= (struct vector
*) where
;
1231 length
= fixnum_value(vector
->length
);
1232 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
1238 trans_vector_single_float(lispobj object
)
1240 struct vector
*vector
;
1241 long length
, nwords
;
1243 gc_assert(is_lisp_pointer(object
));
1245 vector
= (struct vector
*) native_pointer(object
);
1246 length
= fixnum_value(vector
->length
);
1247 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
1249 return copy_large_unboxed_object(object
, nwords
);
1253 size_vector_single_float(lispobj
*where
)
1255 struct vector
*vector
;
1256 long length
, nwords
;
1258 vector
= (struct vector
*) where
;
1259 length
= fixnum_value(vector
->length
);
1260 nwords
= CEILING(NWORDS(length
, 32) + 2, 2);
1266 scav_vector_double_float(lispobj
*where
, lispobj object
)
1268 struct vector
*vector
;
1269 long length
, nwords
;
1271 vector
= (struct vector
*) where
;
1272 length
= fixnum_value(vector
->length
);
1273 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1279 trans_vector_double_float(lispobj object
)
1281 struct vector
*vector
;
1282 long length
, nwords
;
1284 gc_assert(is_lisp_pointer(object
));
1286 vector
= (struct vector
*) native_pointer(object
);
1287 length
= fixnum_value(vector
->length
);
1288 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1290 return copy_large_unboxed_object(object
, nwords
);
1294 size_vector_double_float(lispobj
*where
)
1296 struct vector
*vector
;
1297 long length
, nwords
;
1299 vector
= (struct vector
*) where
;
1300 length
= fixnum_value(vector
->length
);
1301 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1306 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1308 scav_vector_long_float(lispobj
*where
, lispobj object
)
1310 struct vector
*vector
;
1311 long length
, nwords
;
1313 vector
= (struct vector
*) where
;
1314 length
= fixnum_value(vector
->length
);
1315 nwords
= CEILING(length
*
1322 trans_vector_long_float(lispobj object
)
1324 struct vector
*vector
;
1325 long length
, nwords
;
1327 gc_assert(is_lisp_pointer(object
));
1329 vector
= (struct vector
*) native_pointer(object
);
1330 length
= fixnum_value(vector
->length
);
1331 nwords
= CEILING(length
* LONG_FLOAT_SIZE
+ 2, 2);
1333 return copy_large_unboxed_object(object
, nwords
);
1337 size_vector_long_float(lispobj
*where
)
1339 struct vector
*vector
;
1340 long length
, nwords
;
1342 vector
= (struct vector
*) where
;
1343 length
= fixnum_value(vector
->length
);
1344 nwords
= CEILING(length
* LONG_FLOAT_SIZE
+ 2, 2);
1351 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1353 scav_vector_complex_single_float(lispobj
*where
, lispobj object
)
1355 struct vector
*vector
;
1356 long length
, nwords
;
1358 vector
= (struct vector
*) where
;
1359 length
= fixnum_value(vector
->length
);
1360 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1366 trans_vector_complex_single_float(lispobj object
)
1368 struct vector
*vector
;
1369 long length
, nwords
;
1371 gc_assert(is_lisp_pointer(object
));
1373 vector
= (struct vector
*) native_pointer(object
);
1374 length
= fixnum_value(vector
->length
);
1375 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1377 return copy_large_unboxed_object(object
, nwords
);
1381 size_vector_complex_single_float(lispobj
*where
)
1383 struct vector
*vector
;
1384 long length
, nwords
;
1386 vector
= (struct vector
*) where
;
1387 length
= fixnum_value(vector
->length
);
1388 nwords
= CEILING(NWORDS(length
, 64) + 2, 2);
1394 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1396 scav_vector_complex_double_float(lispobj
*where
, lispobj object
)
1398 struct vector
*vector
;
1399 long length
, nwords
;
1401 vector
= (struct vector
*) where
;
1402 length
= fixnum_value(vector
->length
);
1403 nwords
= CEILING(NWORDS(length
, 128) + 2, 2);
1409 trans_vector_complex_double_float(lispobj object
)
1411 struct vector
*vector
;
1412 long length
, nwords
;
1414 gc_assert(is_lisp_pointer(object
));
1416 vector
= (struct vector
*) native_pointer(object
);
1417 length
= fixnum_value(vector
->length
);
1418 nwords
= CEILING(NWORDS(length
, 128) + 2, 2);
1420 return copy_large_unboxed_object(object
, nwords
);
1424 size_vector_complex_double_float(lispobj
*where
)
1426 struct vector
*vector
;
1427 long length
, nwords
;
1429 vector
= (struct vector
*) where
;
1430 length
= fixnum_value(vector
->length
);
1431 nwords
= CEILING(NWORDS(length
, 128) + 2, 2);
1438 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1440 scav_vector_complex_long_float(lispobj
*where
, lispobj object
)
1442 struct vector
*vector
;
1443 long length
, nwords
;
1445 vector
= (struct vector
*) where
;
1446 length
= fixnum_value(vector
->length
);
1447 nwords
= CEILING(length
* (2* LONG_FLOAT_SIZE
) + 2, 2);
1453 trans_vector_complex_long_float(lispobj object
)
1455 struct vector
*vector
;
1456 long length
, nwords
;
1458 gc_assert(is_lisp_pointer(object
));
1460 vector
= (struct vector
*) native_pointer(object
);
1461 length
= fixnum_value(vector
->length
);
1462 nwords
= CEILING(length
* (2*LONG_FLOAT_SIZE
) + 2, 2);
1464 return copy_large_unboxed_object(object
, nwords
);
1468 size_vector_complex_long_float(lispobj
*where
)
1470 struct vector
*vector
;
1471 long length
, nwords
;
1473 vector
= (struct vector
*) where
;
1474 length
= fixnum_value(vector
->length
);
1475 nwords
= CEILING(length
* (2*LONG_FLOAT_SIZE
) + 2, 2);
1481 #define WEAK_POINTER_NWORDS \
1482 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1485 trans_weak_pointer(lispobj object
)
1488 #ifndef LISP_FEATURE_GENCGC
1489 struct weak_pointer
*wp
;
1491 gc_assert(is_lisp_pointer(object
));
1493 #if defined(DEBUG_WEAK)
1494 printf("Transporting weak pointer from 0x%08x\n", object
);
1497 /* Need to remember where all the weak pointers are that have */
1498 /* been transported so they can be fixed up in a post-GC pass. */
1500 copy
= copy_object(object
, WEAK_POINTER_NWORDS
);
1501 #ifndef LISP_FEATURE_GENCGC
1502 wp
= (struct weak_pointer
*) native_pointer(copy
);
1504 gc_assert(widetag_of(wp
->header
)==WEAK_POINTER_WIDETAG
);
1505 /* Push the weak pointer onto the list of weak pointers. */
1506 wp
->next
= (struct weak_pointer
*)LOW_WORD(weak_pointers
);
1513 size_weak_pointer(lispobj
*where
)
1515 return WEAK_POINTER_NWORDS
;
1519 void scan_weak_pointers(void)
1521 struct weak_pointer
*wp
;
1522 for (wp
= weak_pointers
; wp
!= NULL
; wp
=wp
->next
) {
1523 lispobj value
= wp
->value
;
1524 lispobj
*first_pointer
;
1525 gc_assert(widetag_of(wp
->header
)==WEAK_POINTER_WIDETAG
);
1526 if (!(is_lisp_pointer(value
) && from_space_p(value
)))
1529 /* Now, we need to check whether the object has been forwarded. If
1530 * it has been, the weak pointer is still good and needs to be
1531 * updated. Otherwise, the weak pointer needs to be nil'ed
1534 first_pointer
= (lispobj
*)native_pointer(value
);
1536 if (forwarding_pointer_p(first_pointer
)) {
1538 (lispobj
)LOW_WORD(forwarding_pointer_value(first_pointer
));
1554 scav_lose(lispobj
*where
, lispobj object
)
1556 lose("no scavenge function for object 0x%08x (widetag 0x%x)\n",
1557 (unsigned long)object
,
1558 widetag_of(*(lispobj
*)native_pointer(object
)));
1560 return 0; /* bogus return value to satisfy static type checking */
1564 trans_lose(lispobj object
)
1566 lose("no transport function for object 0x%08x (widetag 0x%x)\n",
1567 (unsigned long)object
,
1568 widetag_of(*(lispobj
*)native_pointer(object
)));
1569 return NIL
; /* bogus return value to satisfy static type checking */
1573 size_lose(lispobj
*where
)
1575 lose("no size function for object at 0x%08x (widetag 0x%x)\n",
1576 (unsigned long)where
,
1577 widetag_of(LOW_WORD(where
)));
1578 return 1; /* bogus return value to satisfy static type checking */
1587 gc_init_tables(void)
1591 /* Set default value in all slots of scavenge table. FIXME
1592 * replace this gnarly sizeof with something based on
1594 for (i
= 0; i
< ((sizeof scavtab
)/(sizeof scavtab
[0])); i
++) {
1595 scavtab
[i
] = scav_lose
;
1598 /* For each type which can be selected by the lowtag alone, set
1599 * multiple entries in our widetag scavenge table (one for each
1600 * possible value of the high bits).
1603 for (i
= 0; i
< (1<<(N_WIDETAG_BITS
-N_LOWTAG_BITS
)); i
++) {
1604 scavtab
[EVEN_FIXNUM_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = scav_immediate
;
1605 scavtab
[FUN_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = scav_fun_pointer
;
1606 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1607 scavtab
[LIST_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = scav_list_pointer
;
1608 scavtab
[ODD_FIXNUM_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = scav_immediate
;
1609 scavtab
[INSTANCE_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = scav_instance_pointer
;
1610 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1611 scavtab
[OTHER_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = scav_other_pointer
;
1614 /* Other-pointer types (those selected by all eight bits of the
1615 * tag) get one entry each in the scavenge table. */
1616 scavtab
[BIGNUM_WIDETAG
] = scav_unboxed
;
1617 scavtab
[RATIO_WIDETAG
] = scav_boxed
;
1618 #if N_WORD_BITS == 64
1619 scavtab
[SINGLE_FLOAT_WIDETAG
] = scav_immediate
;
1621 scavtab
[SINGLE_FLOAT_WIDETAG
] = scav_unboxed
;
1623 scavtab
[DOUBLE_FLOAT_WIDETAG
] = scav_unboxed
;
1624 #ifdef LONG_FLOAT_WIDETAG
1625 scavtab
[LONG_FLOAT_WIDETAG
] = scav_unboxed
;
1627 scavtab
[COMPLEX_WIDETAG
] = scav_boxed
;
1628 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1629 scavtab
[COMPLEX_SINGLE_FLOAT_WIDETAG
] = scav_unboxed
;
1631 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1632 scavtab
[COMPLEX_DOUBLE_FLOAT_WIDETAG
] = scav_unboxed
;
1634 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1635 scavtab
[COMPLEX_LONG_FLOAT_WIDETAG
] = scav_unboxed
;
1637 scavtab
[SIMPLE_ARRAY_WIDETAG
] = scav_boxed
;
1638 scavtab
[SIMPLE_BASE_STRING_WIDETAG
] = scav_base_string
;
1639 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1640 scavtab
[SIMPLE_CHARACTER_STRING_WIDETAG
] = scav_character_string
;
1642 scavtab
[SIMPLE_BIT_VECTOR_WIDETAG
] = scav_vector_bit
;
1643 scavtab
[SIMPLE_ARRAY_NIL_WIDETAG
] = scav_vector_nil
;
1644 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG
] =
1645 scav_vector_unsigned_byte_2
;
1646 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG
] =
1647 scav_vector_unsigned_byte_4
;
1648 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG
] =
1649 scav_vector_unsigned_byte_8
;
1650 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG
] =
1651 scav_vector_unsigned_byte_8
;
1652 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG
] =
1653 scav_vector_unsigned_byte_16
;
1654 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG
] =
1655 scav_vector_unsigned_byte_16
;
1656 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
1657 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
] =
1658 scav_vector_unsigned_byte_32
;
1660 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG
] =
1661 scav_vector_unsigned_byte_32
;
1662 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG
] =
1663 scav_vector_unsigned_byte_32
;
1664 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
1665 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
] =
1666 scav_vector_unsigned_byte_64
;
1668 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
1669 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
] =
1670 scav_vector_unsigned_byte_64
;
1672 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
1673 scavtab
[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
] =
1674 scav_vector_unsigned_byte_64
;
1676 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1677 scavtab
[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
] = scav_vector_unsigned_byte_8
;
1679 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1680 scavtab
[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
] =
1681 scav_vector_unsigned_byte_16
;
1683 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1684 scavtab
[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
] =
1685 scav_vector_unsigned_byte_32
;
1687 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1688 scavtab
[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
] =
1689 scav_vector_unsigned_byte_32
;
1691 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
1692 scavtab
[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
] =
1693 scav_vector_unsigned_byte_64
;
1695 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
1696 scavtab
[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
] =
1697 scav_vector_unsigned_byte_64
;
1699 scavtab
[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG
] = scav_vector_single_float
;
1700 scavtab
[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG
] = scav_vector_double_float
;
1701 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1702 scavtab
[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
] = scav_vector_long_float
;
1704 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1705 scavtab
[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
] =
1706 scav_vector_complex_single_float
;
1708 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1709 scavtab
[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
] =
1710 scav_vector_complex_double_float
;
1712 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1713 scavtab
[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
] =
1714 scav_vector_complex_long_float
;
1716 scavtab
[COMPLEX_BASE_STRING_WIDETAG
] = scav_boxed
;
1717 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
1718 scavtab
[COMPLEX_CHARACTER_STRING_WIDETAG
] = scav_boxed
;
1720 scavtab
[COMPLEX_VECTOR_NIL_WIDETAG
] = scav_boxed
;
1721 scavtab
[COMPLEX_BIT_VECTOR_WIDETAG
] = scav_boxed
;
1722 scavtab
[COMPLEX_VECTOR_WIDETAG
] = scav_boxed
;
1723 scavtab
[COMPLEX_ARRAY_WIDETAG
] = scav_boxed
;
1724 scavtab
[CODE_HEADER_WIDETAG
] = scav_code_header
;
1725 #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
1726 scavtab
[SIMPLE_FUN_HEADER_WIDETAG
] = scav_fun_header
;
1727 scavtab
[RETURN_PC_HEADER_WIDETAG
] = scav_return_pc_header
;
1729 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
1730 scavtab
[CLOSURE_HEADER_WIDETAG
] = scav_closure_header
;
1731 scavtab
[FUNCALLABLE_INSTANCE_HEADER_WIDETAG
] = scav_closure_header
;
1733 scavtab
[CLOSURE_HEADER_WIDETAG
] = scav_boxed
;
1734 scavtab
[FUNCALLABLE_INSTANCE_HEADER_WIDETAG
] = scav_boxed
;
1736 scavtab
[VALUE_CELL_HEADER_WIDETAG
] = scav_boxed
;
1737 scavtab
[SYMBOL_HEADER_WIDETAG
] = scav_boxed
;
1738 scavtab
[CHARACTER_WIDETAG
] = scav_immediate
;
1739 scavtab
[SAP_WIDETAG
] = scav_unboxed
;
1740 scavtab
[UNBOUND_MARKER_WIDETAG
] = scav_immediate
;
1741 scavtab
[NO_TLS_VALUE_MARKER_WIDETAG
] = scav_immediate
;
1742 scavtab
[INSTANCE_HEADER_WIDETAG
] = scav_instance
;
1743 #if defined(LISP_FEATURE_SPARC)
1744 scavtab
[FDEFN_WIDETAG
] = scav_boxed
;
1746 scavtab
[FDEFN_WIDETAG
] = scav_fdefn
;
1749 /* transport other table, initialized same way as scavtab */
1750 for (i
= 0; i
< ((sizeof transother
)/(sizeof transother
[0])); i
++)
1751 transother
[i
] = trans_lose
;
1752 transother
[BIGNUM_WIDETAG
] = trans_unboxed
;
1753 transother
[RATIO_WIDETAG
] = trans_boxed
;
1755 #if N_WORD_BITS == 64
1756 transother
[SINGLE_FLOAT_WIDETAG
] = trans_immediate
;
1758 transother
[SINGLE_FLOAT_WIDETAG
] = trans_unboxed
;
1760 transother
[DOUBLE_FLOAT_WIDETAG
] = trans_unboxed
;
1761 #ifdef LONG_FLOAT_WIDETAG
1762 transother
[LONG_FLOAT_WIDETAG
] = trans_unboxed
;
1764 transother
[COMPLEX_WIDETAG
] = trans_boxed
;
1765 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1766 transother
[COMPLEX_SINGLE_FLOAT_WIDETAG
] = trans_unboxed
;
1768 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1769 transother
[COMPLEX_DOUBLE_FLOAT_WIDETAG
] = trans_unboxed
;
1771 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1772 transother
[COMPLEX_LONG_FLOAT_WIDETAG
] = trans_unboxed
;
1774 transother
[SIMPLE_ARRAY_WIDETAG
] = trans_boxed
; /* but not GENCGC */
1775 transother
[SIMPLE_BASE_STRING_WIDETAG
] = trans_base_string
;
1776 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1777 transother
[SIMPLE_CHARACTER_STRING_WIDETAG
] = trans_character_string
;
1779 transother
[SIMPLE_BIT_VECTOR_WIDETAG
] = trans_vector_bit
;
1780 transother
[SIMPLE_VECTOR_WIDETAG
] = trans_vector
;
1781 transother
[SIMPLE_ARRAY_NIL_WIDETAG
] = trans_vector_nil
;
1782 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG
] =
1783 trans_vector_unsigned_byte_2
;
1784 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG
] =
1785 trans_vector_unsigned_byte_4
;
1786 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG
] =
1787 trans_vector_unsigned_byte_8
;
1788 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG
] =
1789 trans_vector_unsigned_byte_8
;
1790 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG
] =
1791 trans_vector_unsigned_byte_16
;
1792 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG
] =
1793 trans_vector_unsigned_byte_16
;
1794 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
1795 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
] =
1796 trans_vector_unsigned_byte_32
;
1798 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG
] =
1799 trans_vector_unsigned_byte_32
;
1800 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG
] =
1801 trans_vector_unsigned_byte_32
;
1802 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
1803 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
] =
1804 trans_vector_unsigned_byte_64
;
1806 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
1807 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
] =
1808 trans_vector_unsigned_byte_64
;
1810 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
1811 transother
[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
] =
1812 trans_vector_unsigned_byte_64
;
1814 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1815 transother
[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
] =
1816 trans_vector_unsigned_byte_8
;
1818 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1819 transother
[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
] =
1820 trans_vector_unsigned_byte_16
;
1822 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1823 transother
[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
] =
1824 trans_vector_unsigned_byte_32
;
1826 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1827 transother
[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
] =
1828 trans_vector_unsigned_byte_32
;
1830 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
1831 transother
[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
] =
1832 trans_vector_unsigned_byte_64
;
1834 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
1835 transother
[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
] =
1836 trans_vector_unsigned_byte_64
;
1838 transother
[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG
] =
1839 trans_vector_single_float
;
1840 transother
[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG
] =
1841 trans_vector_double_float
;
1842 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1843 transother
[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
] =
1844 trans_vector_long_float
;
1846 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1847 transother
[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
] =
1848 trans_vector_complex_single_float
;
1850 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1851 transother
[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
] =
1852 trans_vector_complex_double_float
;
1854 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1855 transother
[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
] =
1856 trans_vector_complex_long_float
;
1858 transother
[COMPLEX_BASE_STRING_WIDETAG
] = trans_boxed
;
1859 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
1860 transother
[COMPLEX_CHARACTER_STRING_WIDETAG
] = trans_boxed
;
1862 transother
[COMPLEX_BIT_VECTOR_WIDETAG
] = trans_boxed
;
1863 transother
[COMPLEX_VECTOR_NIL_WIDETAG
] = trans_boxed
;
1864 transother
[COMPLEX_VECTOR_WIDETAG
] = trans_boxed
;
1865 transother
[COMPLEX_ARRAY_WIDETAG
] = trans_boxed
;
1866 transother
[CODE_HEADER_WIDETAG
] = trans_code_header
;
1867 transother
[SIMPLE_FUN_HEADER_WIDETAG
] = trans_fun_header
;
1868 transother
[RETURN_PC_HEADER_WIDETAG
] = trans_return_pc_header
;
1869 transother
[CLOSURE_HEADER_WIDETAG
] = trans_boxed
;
1870 transother
[FUNCALLABLE_INSTANCE_HEADER_WIDETAG
] = trans_boxed
;
1871 transother
[VALUE_CELL_HEADER_WIDETAG
] = trans_boxed
;
1872 transother
[SYMBOL_HEADER_WIDETAG
] = trans_boxed
;
1873 transother
[CHARACTER_WIDETAG
] = trans_immediate
;
1874 transother
[SAP_WIDETAG
] = trans_unboxed
;
1875 transother
[UNBOUND_MARKER_WIDETAG
] = trans_immediate
;
1876 transother
[NO_TLS_VALUE_MARKER_WIDETAG
] = trans_immediate
;
1877 transother
[WEAK_POINTER_WIDETAG
] = trans_weak_pointer
;
1878 transother
[INSTANCE_HEADER_WIDETAG
] = trans_boxed
;
1879 transother
[FDEFN_WIDETAG
] = trans_boxed
;
1881 /* size table, initialized the same way as scavtab */
1882 for (i
= 0; i
< ((sizeof sizetab
)/(sizeof sizetab
[0])); i
++)
1883 sizetab
[i
] = size_lose
;
1884 for (i
= 0; i
< (1<<(N_WIDETAG_BITS
-N_LOWTAG_BITS
)); i
++) {
1885 sizetab
[EVEN_FIXNUM_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = size_immediate
;
1886 sizetab
[FUN_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = size_pointer
;
1887 /* skipping OTHER_IMMEDIATE_0_LOWTAG */
1888 sizetab
[LIST_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = size_pointer
;
1889 sizetab
[ODD_FIXNUM_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = size_immediate
;
1890 sizetab
[INSTANCE_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = size_pointer
;
1891 /* skipping OTHER_IMMEDIATE_1_LOWTAG */
1892 sizetab
[OTHER_POINTER_LOWTAG
|(i
<<N_LOWTAG_BITS
)] = size_pointer
;
1894 sizetab
[BIGNUM_WIDETAG
] = size_unboxed
;
1895 sizetab
[RATIO_WIDETAG
] = size_boxed
;
1896 #if N_WORD_BITS == 64
1897 sizetab
[SINGLE_FLOAT_WIDETAG
] = size_immediate
;
1899 sizetab
[SINGLE_FLOAT_WIDETAG
] = size_unboxed
;
1901 sizetab
[DOUBLE_FLOAT_WIDETAG
] = size_unboxed
;
1902 #ifdef LONG_FLOAT_WIDETAG
1903 sizetab
[LONG_FLOAT_WIDETAG
] = size_unboxed
;
1905 sizetab
[COMPLEX_WIDETAG
] = size_boxed
;
1906 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
1907 sizetab
[COMPLEX_SINGLE_FLOAT_WIDETAG
] = size_unboxed
;
1909 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
1910 sizetab
[COMPLEX_DOUBLE_FLOAT_WIDETAG
] = size_unboxed
;
1912 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
1913 sizetab
[COMPLEX_LONG_FLOAT_WIDETAG
] = size_unboxed
;
1915 sizetab
[SIMPLE_ARRAY_WIDETAG
] = size_boxed
;
1916 sizetab
[SIMPLE_BASE_STRING_WIDETAG
] = size_base_string
;
1917 #ifdef SIMPLE_CHARACTER_STRING_WIDETAG
1918 sizetab
[SIMPLE_CHARACTER_STRING_WIDETAG
] = size_character_string
;
1920 sizetab
[SIMPLE_BIT_VECTOR_WIDETAG
] = size_vector_bit
;
1921 sizetab
[SIMPLE_VECTOR_WIDETAG
] = size_vector
;
1922 sizetab
[SIMPLE_ARRAY_NIL_WIDETAG
] = size_vector_nil
;
1923 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG
] =
1924 size_vector_unsigned_byte_2
;
1925 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG
] =
1926 size_vector_unsigned_byte_4
;
1927 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG
] =
1928 size_vector_unsigned_byte_8
;
1929 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG
] =
1930 size_vector_unsigned_byte_8
;
1931 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG
] =
1932 size_vector_unsigned_byte_16
;
1933 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG
] =
1934 size_vector_unsigned_byte_16
;
1935 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
1936 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
] =
1937 size_vector_unsigned_byte_32
;
1939 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG
] =
1940 size_vector_unsigned_byte_32
;
1941 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG
] =
1942 size_vector_unsigned_byte_32
;
1943 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
1944 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
] =
1945 size_vector_unsigned_byte_64
;
1947 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
1948 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
] =
1949 size_vector_unsigned_byte_64
;
1951 #ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
1952 sizetab
[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
] =
1953 size_vector_unsigned_byte_64
;
1955 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1956 sizetab
[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
] = size_vector_unsigned_byte_8
;
1958 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1959 sizetab
[SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
] =
1960 size_vector_unsigned_byte_16
;
1962 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1963 sizetab
[SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
] =
1964 size_vector_unsigned_byte_32
;
1966 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1967 sizetab
[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
] =
1968 size_vector_unsigned_byte_32
;
1970 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
1971 sizetab
[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
] =
1972 size_vector_unsigned_byte_64
;
1974 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
1975 sizetab
[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
] =
1976 size_vector_unsigned_byte_64
;
1978 sizetab
[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG
] = size_vector_single_float
;
1979 sizetab
[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG
] = size_vector_double_float
;
1980 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1981 sizetab
[SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
] = size_vector_long_float
;
1983 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1984 sizetab
[SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
] =
1985 size_vector_complex_single_float
;
1987 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1988 sizetab
[SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
] =
1989 size_vector_complex_double_float
;
1991 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1992 sizetab
[SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
] =
1993 size_vector_complex_long_float
;
1995 sizetab
[COMPLEX_BASE_STRING_WIDETAG
] = size_boxed
;
1996 #ifdef COMPLEX_CHARACTER_STRING_WIDETAG
1997 sizetab
[COMPLEX_CHARACTER_STRING_WIDETAG
] = size_boxed
;
1999 sizetab
[COMPLEX_VECTOR_NIL_WIDETAG
] = size_boxed
;
2000 sizetab
[COMPLEX_BIT_VECTOR_WIDETAG
] = size_boxed
;
2001 sizetab
[COMPLEX_VECTOR_WIDETAG
] = size_boxed
;
2002 sizetab
[COMPLEX_ARRAY_WIDETAG
] = size_boxed
;
2003 sizetab
[CODE_HEADER_WIDETAG
] = size_code_header
;
2005 /* We shouldn't see these, so just lose if it happens. */
2006 sizetab
[SIMPLE_FUN_HEADER_WIDETAG
] = size_function_header
;
2007 sizetab
[RETURN_PC_HEADER_WIDETAG
] = size_return_pc_header
;
2009 sizetab
[CLOSURE_HEADER_WIDETAG
] = size_boxed
;
2010 sizetab
[FUNCALLABLE_INSTANCE_HEADER_WIDETAG
] = size_boxed
;
2011 sizetab
[VALUE_CELL_HEADER_WIDETAG
] = size_boxed
;
2012 sizetab
[SYMBOL_HEADER_WIDETAG
] = size_boxed
;
2013 sizetab
[CHARACTER_WIDETAG
] = size_immediate
;
2014 sizetab
[SAP_WIDETAG
] = size_unboxed
;
2015 sizetab
[UNBOUND_MARKER_WIDETAG
] = size_immediate
;
2016 sizetab
[NO_TLS_VALUE_MARKER_WIDETAG
] = size_immediate
;
2017 sizetab
[WEAK_POINTER_WIDETAG
] = size_weak_pointer
;
2018 sizetab
[INSTANCE_HEADER_WIDETAG
] = size_boxed
;
2019 sizetab
[FDEFN_WIDETAG
] = size_boxed
;
2023 /* Find the code object for the given pc, or return NULL on
2026 component_ptr_from_pc(lispobj
*pc
)
2028 lispobj
*object
= NULL
;
2030 if ( (object
= search_read_only_space(pc
)) )
2032 else if ( (object
= search_static_space(pc
)) )
2035 object
= search_dynamic_space(pc
);
2037 if (object
) /* if we found something */
2038 if (widetag_of(*object
) == CODE_HEADER_WIDETAG
)
2044 /* Scan an area looking for an object which encloses the given pointer.
2045 * Return the object start on success or NULL on failure. */
2047 gc_search_space(lispobj
*start
, size_t words
, lispobj
*pointer
)
2051 lispobj thing
= *start
;
2053 /* If thing is an immediate then this is a cons. */
2054 if (is_lisp_pointer(thing
)
2056 || (widetag_of(thing
) == CHARACTER_WIDETAG
)
2057 #if N_WORD_BITS == 64
2058 || (widetag_of(thing
) == SINGLE_FLOAT_WIDETAG
)
2060 || (widetag_of(thing
) == UNBOUND_MARKER_WIDETAG
))
2063 count
= (sizetab
[widetag_of(thing
)])(start
);
2065 /* Check whether the pointer is within this object. */
2066 if ((pointer
>= start
) && (pointer
< (start
+count
))) {
2068 /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/
2072 /* Round up the count. */
2073 count
= CEILING(count
,2);