2 * stop and copy GC based on Cheney's algorithm
6 * This software is part of the SBCL system. See the README file for
9 * This software is derived from the CMU CL system, which was
10 * written at Carnegie Mellon University and released into the
11 * public domain. The software is in the public domain and is
12 * provided with absolutely no warranty. See the COPYING and CREDITS
13 * files for more information.
18 #include <sys/resource.h>
25 #include "interrupt.h"
30 /* So you need to debug? */
33 #define DEBUG_SPACE_PREDICATES
34 #define DEBUG_SCAVENGE_VERBOSE
35 #define DEBUG_COPY_VERBOSE
39 static lispobj *from_space;
40 static lispobj *from_space_free_pointer;
42 static lispobj *new_space;
43 static lispobj *new_space_free_pointer;
45 static int (*scavtab[256])(lispobj *where, lispobj object);
46 static lispobj (*transother[256])(lispobj object);
47 static int (*sizetab[256])(lispobj *where);
49 static struct weak_pointer *weak_pointers;
51 static void scavenge(lispobj *start, u32 nwords);
52 static void scavenge_newspace(void);
53 static void scavenge_interrupt_contexts(void);
54 static void scan_weak_pointers(void);
55 static int scav_lose(lispobj *where, lispobj object);
57 #define gc_abort() lose("GC invariant lost! File \"%s\", line %d\n", \
61 #define gc_assert(ex) do { \
62 if (!(ex)) gc_abort(); \
68 #define CEILING(x,y) (((x) + ((y) - 1)) & (~((y) - 1)))
73 #if defined(DEBUG_SPACE_PREDICATES)
76 from_space_p(lispobj object)
80 /* this can be called for untagged pointers as well as for
81 descriptors, so this assertion's not applicable
82 gc_assert(Pointerp(object));
84 ptr = (lispobj *) PTR(object);
86 return ((from_space <= ptr) &&
87 (ptr < from_space_free_pointer));
91 new_space_p(lispobj object)
95 gc_assert(Pointerp(object));
97 ptr = (lispobj *) PTR(object);
99 return ((new_space <= ptr) &&
100 (ptr < new_space_free_pointer));
105 #define from_space_p(ptr) \
106 ((from_space <= ((lispobj *) ptr)) && \
107 (((lispobj *) ptr) < from_space_free_pointer))
109 #define new_space_p(ptr) \
110 ((new_space <= ((lispobj *) ptr)) && \
111 (((lispobj *) ptr) < new_space_free_pointer))
116 /* copying objects */
119 copy_object(lispobj object, int nwords)
123 lispobj *source, *dest;
125 gc_assert(Pointerp(object));
126 gc_assert(from_space_p(object));
127 gc_assert((nwords & 0x01) == 0);
129 /* get tag of object */
130 tag = LowtagOf(object);
133 new = new_space_free_pointer;
134 new_space_free_pointer += nwords;
137 source = (lispobj *) PTR(object);
139 #ifdef DEBUG_COPY_VERBOSE
140 fprintf(stderr,"Copying %d words from %p to %p\n", nwords,source,new);
143 /* copy the object */
151 /* return lisp pointer of new object */
152 return (lispobj)(LOW_WORD(new) | tag);
156 /* collecting garbage */
160 tv_diff(struct timeval *x, struct timeval *y)
162 return (((double) x->tv_sec + (double) x->tv_usec * 1.0e-6) -
163 ((double) y->tv_sec + (double) y->tv_usec * 1.0e-6));
167 #define BYTES_ZERO_BEFORE_END (1<<12)
172 #define U32 unsigned long
177 U32 *ptr = (U32 *)current_control_stack_pointer;
183 } while (((unsigned long)ptr) & (BYTES_ZERO_BEFORE_END-1));
188 } while (((unsigned long)ptr) & (BYTES_ZERO_BEFORE_END-1));
195 /* Note: The generic GC interface we're implementing passes us a
196 * last_generation argument. That's meaningless for us, since we're
197 * not a generational GC. So we ignore it. */
199 collect_garbage(unsigned ignore)
202 struct timeval start_tv, stop_tv;
203 struct rusage start_rusage, stop_rusage;
204 double real_time, system_time, user_time;
205 double percent_retained, gc_rate;
206 unsigned long size_discarded;
207 unsigned long size_retained;
209 lispobj *current_static_space_free_pointer;
210 unsigned long static_space_size;
211 unsigned long control_stack_size, binding_stack_size;
215 printf("[Collecting garbage ... \n");
217 getrusage(RUSAGE_SELF, &start_rusage);
218 gettimeofday(&start_tv, (struct timezone *) 0);
222 sigaddset_blockable(&tmp);
223 sigprocmask(SIG_BLOCK, &tmp, &old);
225 current_static_space_free_pointer =
226 (lispobj *) ((unsigned long)
227 SymbolValue(STATIC_SPACE_FREE_POINTER));
230 /* Set up from space and new space pointers. */
232 from_space = current_dynamic_space;
234 from_space_free_pointer = dynamic_space_free_pointer;
236 from_space_free_pointer = (lispobj *)SymbolValue(ALLOCATION_POINTER);
240 fprintf(stderr,"from_space = %lx\n",
241 (unsigned long) current_dynamic_space);
243 if (current_dynamic_space == (lispobj *) DYNAMIC_0_SPACE_START)
244 new_space = (lispobj *)DYNAMIC_1_SPACE_START;
245 else if (current_dynamic_space == (lispobj *) DYNAMIC_1_SPACE_START)
246 new_space = (lispobj *) DYNAMIC_0_SPACE_START;
248 lose("GC lossage. Current dynamic space is bogus!\n");
250 new_space_free_pointer = new_space;
253 /* Initialize the weak pointer list. */
254 weak_pointers = (struct weak_pointer *) NULL;
257 /* Scavenge all of the roots. */
259 printf("Scavenging interrupt contexts ...\n");
261 scavenge_interrupt_contexts();
264 printf("Scavenging interrupt handlers (%d bytes) ...\n",
265 (int)sizeof(interrupt_handlers));
267 scavenge((lispobj *) interrupt_handlers,
268 sizeof(interrupt_handlers) / sizeof(lispobj));
270 /* _size quantities are in units of sizeof(lispobj) - i.e. 4 */
272 current_control_stack_pointer-
273 (lispobj *)CONTROL_STACK_START;
275 printf("Scavenging the control stack at %p (%ld words) ...\n",
276 ((lispobj *)CONTROL_STACK_START),
279 scavenge(((lispobj *)CONTROL_STACK_START), control_stack_size);
284 (lispobj *)SymbolValue(BINDING_STACK_POINTER) - binding_stack;
287 current_binding_stack_pointer -
288 (lispobj *)BINDING_STACK_START;
291 printf("Scavenging the binding stack %x - %x (%d words) ...\n",
292 BINDING_STACK_START,current_binding_stack_pointer,
293 (int)(binding_stack_size));
295 scavenge(((lispobj *)BINDING_STACK_START), binding_stack_size);
298 current_static_space_free_pointer - (lispobj *) STATIC_SPACE_START;
300 printf("Scavenging static space %x - %x (%d words) ...\n",
301 STATIC_SPACE_START,current_static_space_free_pointer,
302 (int)(static_space_size));
304 scavenge(((lispobj *)STATIC_SPACE_START), static_space_size);
306 /* Scavenge newspace. */
308 printf("Scavenging new space (%d bytes) ...\n",
309 (int)((new_space_free_pointer - new_space) * sizeof(lispobj)));
314 #if defined(DEBUG_PRINT_GARBAGE)
315 print_garbage(from_space, from_space_free_pointer);
318 /* Scan the weak pointers. */
320 printf("Scanning weak pointers ...\n");
322 scan_weak_pointers();
327 printf("Flipping spaces ...\n");
330 os_zero((os_vm_address_t) current_dynamic_space,
331 (os_vm_size_t) DYNAMIC_SPACE_SIZE);
333 current_dynamic_space = new_space;
335 dynamic_space_free_pointer = new_space_free_pointer;
337 SetSymbolValue(ALLOCATION_POINTER, (lispobj)new_space_free_pointer);
341 size_discarded = (from_space_free_pointer - from_space) * sizeof(lispobj);
342 size_retained = (new_space_free_pointer - new_space) * sizeof(lispobj);
347 printf("Zeroing empty part of control stack ...\n");
351 sigprocmask(SIG_SETMASK, &old, 0);
355 gettimeofday(&stop_tv, (struct timezone *) 0);
356 getrusage(RUSAGE_SELF, &stop_rusage);
360 percent_retained = (((float) size_retained) /
361 ((float) size_discarded)) * 100.0;
363 printf("Total of %ld bytes out of %ld bytes retained (%3.2f%%).\n",
364 size_retained, size_discarded, percent_retained);
366 real_time = tv_diff(&stop_tv, &start_tv);
367 user_time = tv_diff(&stop_rusage.ru_utime, &start_rusage.ru_utime);
368 system_time = tv_diff(&stop_rusage.ru_stime, &start_rusage.ru_stime);
371 printf("Statistics:\n");
372 printf("%10.2f sec of real time\n", real_time);
373 printf("%10.2f sec of user time,\n", user_time);
374 printf("%10.2f sec of system time.\n", system_time);
376 printf("Statistics: %10.2fs real, %10.2fs user, %10.2fs system.\n",
377 real_time, user_time, system_time);
380 gc_rate = ((float) size_retained / (float) (1<<20)) / real_time;
382 printf("%10.2f M bytes/sec collected.\n", gc_rate);
390 scavenge(lispobj *start, u32 nwords)
394 int type, words_scavenged;
397 type = TypeOf(object);
399 #if defined(DEBUG_SCAVENGE_VERBOSE)
400 fprintf(stderr,"Scavenging object at 0x%08x, object = 0x%08x, type = %d\n",
401 (unsigned long) start, (unsigned long) object, type);
404 if (Pointerp(object)) {
405 /* It be a pointer. */
406 if (from_space_p(object)) {
407 /* It currently points to old space. Check for a */
408 /* forwarding pointer. */
411 first_word = *((lispobj *)PTR(object));
412 if (Pointerp(first_word) && new_space_p(first_word)) {
413 /* Yep, there be a forwarding pointer. */
418 /* Scavenge that pointer. */
419 words_scavenged = (scavtab[type])(start, object);
423 /* It points somewhere other than oldspace. Leave */
429 /* there are some situations where an
430 other-immediate may end up in a descriptor
431 register. I'm not sure whether this is
432 supposed to happen, but if it does then we
433 don't want to (a) barf or (b) scavenge over the
434 data-block, because there isn't one. So, if
435 we're checking a single word and it's anything
436 other than a pointer, just hush it up */
439 if((scavtab[type]==scav_lose) ||
440 (((scavtab[type])(start,object))>1)) {
441 fprintf(stderr,"warning: attempted to scavenge non-descriptor value %x at %p. If you can\nreproduce this warning, send a test case to sbcl-devel@lists.sourceforge.net\n",
445 else if ((object & 3) == 0) {
446 /* It's a fixnum. Real easy. */
450 /* It's some random header object. */
451 words_scavenged = (scavtab[type])(start, object);
455 start += words_scavenged;
456 nwords -= words_scavenged;
458 gc_assert(nwords == 0);
462 scavenge_newspace(void)
464 lispobj *here, *next;
467 while (here < new_space_free_pointer) {
468 /* printf("here=%lx, new_space_free_pointer=%lx\n",
469 here,new_space_free_pointer); */
470 next = new_space_free_pointer;
471 scavenge(here, next - here);
474 /* printf("done with newspace\n"); */
477 /* scavenging interrupt contexts */
479 static int boxed_registers[] = BOXED_REGISTERS;
482 scavenge_interrupt_context(os_context_t *context)
487 unsigned long lip_offset;
488 int lip_register_pair;
490 unsigned long pc_code_offset;
492 unsigned long npc_code_offset;
495 /* Find the LIP's register pair and calculate its offset */
496 /* before we scavenge the context. */
498 lip = *os_context_register_addr(context, reg_LIP);
499 /* 0x7FFFFFFF or 0x7FFFFFFFFFFFFFFF ? */
500 lip_offset = 0x7FFFFFFF;
501 lip_register_pair = -1;
502 for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
507 index = boxed_registers[i];
508 reg = *os_context_register_addr(context, index);
509 /* would be using PTR if not for integer length issues */
510 if ((reg & ~((1L<<lowtag_Bits)-1)) <= lip) {
512 if (offset < lip_offset) {
514 lip_register_pair = index;
520 /* Compute the PC's offset from the start of the CODE */
522 pc_code_offset = *os_context_pc_addr(context) -
523 *os_context_register_addr(context, reg_CODE);
525 npc_code_offset = SC_NPC(context) - SC_REG(context, reg_CODE);
528 /* Scanvenge all boxed registers in the context. */
529 for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
533 index = boxed_registers[i];
534 foo = *os_context_register_addr(context,index);
535 scavenge((lispobj *) &foo, 1);
536 *os_context_register_addr(context,index) = foo;
538 /* this is unlikely to work as intended on bigendian
539 * 64 bit platforms */
542 os_context_register_addr(context, index), 1);
547 *os_context_register_addr(context, reg_LIP) =
548 *os_context_register_addr(context, lip_register_pair) + lip_offset;
551 /* Fix the PC if it was in from space */
552 if (from_space_p(*os_context_pc_addr(context)))
553 *os_context_pc_addr(context) =
554 *os_context_register_addr(context, reg_CODE) + pc_code_offset;
556 if (from_space_p(SC_NPC(context)))
557 SC_NPC(context) = SC_REG(context, reg_CODE) + npc_code_offset;
561 void scavenge_interrupt_contexts(void)
564 os_context_t *context;
566 index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX));
568 for (i = 0; i < index; i++) {
569 context = lisp_interrupt_contexts[i];
570 scavenge_interrupt_context(context);
578 print_garbage(lispobj *from_space, lispobj *from_space_free_pointer)
581 int total_words_not_copied;
583 printf("Scanning from space ...\n");
585 total_words_not_copied = 0;
587 while (start < from_space_free_pointer) {
589 int forwardp, type, nwords;
593 forwardp = Pointerp(object) && new_space_p(object);
599 tag = LowtagOf(object);
602 case type_ListPointer:
605 case type_InstancePointer:
606 printf("Don't know about instances yet!\n");
609 case type_FunctionPointer:
612 case type_OtherPointer:
613 pointer = (lispobj *) PTR(object);
615 type = TypeOf(header);
616 nwords = (sizetab[type])(pointer);
619 type = TypeOf(object);
620 nwords = (sizetab[type])(start);
621 total_words_not_copied += nwords;
622 printf("%4d words not copied at 0x%16lx; ",
623 nwords, (unsigned long) start);
624 printf("Header word is 0x%08x\n",
625 (unsigned int) object);
629 printf("%d total words not copied.\n", total_words_not_copied);
633 /* code and code-related objects */
635 #define RAW_ADDR_OFFSET (6*sizeof(lispobj) - type_FunctionPointer)
637 static lispobj trans_function_header(lispobj object);
638 static lispobj trans_boxed(lispobj object);
641 scav_function_pointer(lispobj *where, lispobj object)
643 lispobj *first_pointer;
648 gc_assert(Pointerp(object));
650 /* object is a pointer into from space. Not a FP */
651 first_pointer = (lispobj *) PTR(object);
652 first = *first_pointer;
654 /* must transport object -- object may point */
655 /* to either a function header, a closure */
656 /* function header, or to a closure header. */
658 type = TypeOf(first);
660 case type_FunctionHeader:
661 case type_ClosureFunctionHeader:
662 copy = trans_function_header(object);
665 copy = trans_boxed(object);
669 first = *first_pointer = copy;
671 gc_assert(Pointerp(first));
672 gc_assert(!from_space_p(first));
679 trans_code(struct code *code)
681 struct code *new_code;
682 lispobj first, l_code, l_new_code;
683 int nheader_words, ncode_words, nwords;
684 unsigned long displacement;
685 lispobj fheaderl, *prev_pointer;
687 #if defined(DEBUG_CODE_GC)
688 printf("\nTransporting code object located at 0x%08x.\n",
689 (unsigned long) code);
692 /* if object has already been transported, just return pointer */
693 first = code->header;
694 if (Pointerp(first) && new_space_p(first)) {
696 printf("Was already transported\n");
698 return (struct code *) PTR(first);
701 gc_assert(TypeOf(first) == type_CodeHeader);
703 /* prepare to transport the code vector */
704 l_code = (lispobj) LOW_WORD(code) | type_OtherPointer;
706 ncode_words = fixnum_value(code->code_size);
707 nheader_words = HeaderValue(code->header);
708 nwords = ncode_words + nheader_words;
709 nwords = CEILING(nwords, 2);
711 l_new_code = copy_object(l_code, nwords);
712 new_code = (struct code *) PTR(l_new_code);
714 displacement = l_new_code - l_code;
716 #if defined(DEBUG_CODE_GC)
717 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
718 (unsigned long) code, (unsigned long) new_code);
719 printf("Code object is %d words long.\n", nwords);
722 /* set forwarding pointer */
723 code->header = l_new_code;
725 /* set forwarding pointers for all the function headers in the */
726 /* code object. also fix all self pointers */
728 fheaderl = code->entry_points;
729 prev_pointer = &new_code->entry_points;
731 while (fheaderl != NIL) {
732 struct function *fheaderp, *nfheaderp;
735 fheaderp = (struct function *) PTR(fheaderl);
736 gc_assert(TypeOf(fheaderp->header) == type_FunctionHeader);
738 /* calcuate the new function pointer and the new */
739 /* function header */
740 nfheaderl = fheaderl + displacement;
741 nfheaderp = (struct function *) PTR(nfheaderl);
743 /* set forwarding pointer */
745 printf("fheaderp->header (at %x) <- %x\n",
746 &(fheaderp->header) , nfheaderl);
748 fheaderp->header = nfheaderl;
750 /* fix self pointer */
751 nfheaderp->self = nfheaderl;
753 *prev_pointer = nfheaderl;
755 fheaderl = fheaderp->next;
756 prev_pointer = &nfheaderp->next;
760 os_flush_icache((os_vm_address_t) (((int *)new_code) + nheader_words),
761 ncode_words * sizeof(int));
767 scav_code_header(lispobj *where, lispobj object)
770 int nheader_words, ncode_words, nwords;
772 struct function *fheaderp;
774 code = (struct code *) where;
775 ncode_words = fixnum_value(code->code_size);
776 nheader_words = HeaderValue(object);
777 nwords = ncode_words + nheader_words;
778 nwords = CEILING(nwords, 2);
780 #if defined(DEBUG_CODE_GC)
781 printf("\nScavening code object at 0x%08x.\n",
782 (unsigned long) where);
783 printf("Code object is %d words long.\n", nwords);
784 printf("Scavenging boxed section of code data block (%d words).\n",
788 /* Scavenge the boxed section of the code data block */
789 scavenge(where + 1, nheader_words - 1);
791 /* Scavenge the boxed section of each function object in the */
792 /* code data block */
793 fheaderl = code->entry_points;
794 while (fheaderl != NIL) {
795 fheaderp = (struct function *) PTR(fheaderl);
796 gc_assert(TypeOf(fheaderp->header) == type_FunctionHeader);
798 #if defined(DEBUG_CODE_GC)
799 printf("Scavenging boxed section of entry point located at 0x%08x.\n",
800 (unsigned long) PTR(fheaderl));
802 scavenge(&fheaderp->name, 1);
803 scavenge(&fheaderp->arglist, 1);
804 scavenge(&fheaderp->type, 1);
806 fheaderl = fheaderp->next;
813 trans_code_header(lispobj object)
817 ncode = trans_code((struct code *) PTR(object));
818 return (lispobj) LOW_WORD(ncode) | type_OtherPointer;
822 size_code_header(lispobj *where)
825 int nheader_words, ncode_words, nwords;
827 code = (struct code *) where;
829 ncode_words = fixnum_value(code->code_size);
830 nheader_words = HeaderValue(code->header);
831 nwords = ncode_words + nheader_words;
832 nwords = CEILING(nwords, 2);
839 scav_return_pc_header(lispobj *where, lispobj object)
841 fprintf(stderr, "GC lossage. Should not be scavenging a ");
842 fprintf(stderr, "Return PC Header.\n");
843 fprintf(stderr, "where = 0x%p, object = 0x%x", where, object);
849 trans_return_pc_header(lispobj object)
851 struct function *return_pc;
852 unsigned long offset;
853 struct code *code, *ncode;
855 return_pc = (struct function *) PTR(object);
856 offset = HeaderValue(return_pc->header) * 4 ;
858 /* Transport the whole code object */
859 code = (struct code *) ((unsigned long) return_pc - offset);
861 printf("trans_return_pc_header object=%x, code=%lx\n",object,code);
863 ncode = trans_code(code);
864 if(object==0x304748d7) {
867 ret= ((lispobj) LOW_WORD(ncode) + offset) | type_OtherPointer;
869 printf("trans_return_pc_header returning %x\n",ret);
874 /* On the 386, closures hold a pointer to the raw address instead of
875 * the function object, so we can use CALL [$FDEFN+const] to invoke
876 * the function without loading it into a register. Given that code
877 * objects don't move, we don't need to update anything, but we do
878 * have to figure out that the function is still live. */
881 scav_closure_header(where, object)
882 lispobj *where, object;
884 struct closure *closure;
887 closure = (struct closure *)where;
888 fun = closure->function - RAW_ADDR_OFFSET;
896 scav_function_header(lispobj *where, lispobj object)
898 fprintf(stderr, "GC lossage. Should not be scavenging a ");
899 fprintf(stderr, "Function Header.\n");
900 fprintf(stderr, "where = 0x%p, object = 0x%08x",
901 where, (unsigned int) object);
907 trans_function_header(lispobj object)
909 struct function *fheader;
910 unsigned long offset;
911 struct code *code, *ncode;
913 fheader = (struct function *) PTR(object);
914 offset = HeaderValue(fheader->header) * 4;
916 /* Transport the whole code object */
917 code = (struct code *) ((unsigned long) fheader - offset);
918 ncode = trans_code(code);
920 return ((lispobj) LOW_WORD(ncode) + offset) | type_FunctionPointer;
928 scav_instance_pointer(lispobj *where, lispobj object)
930 lispobj *first_pointer;
932 /* object is a pointer into from space. Not a FP */
933 first_pointer = (lispobj *) PTR(object);
935 *where = *first_pointer = trans_boxed(object);
940 /* lists and conses */
942 static lispobj trans_list(lispobj object);
945 scav_list_pointer(lispobj *where, lispobj object)
947 lispobj first, *first_pointer;
949 gc_assert(Pointerp(object));
951 /* object is a pointer into from space. Not a FP. */
952 first_pointer = (lispobj *) PTR(object);
954 first = *first_pointer = trans_list(object);
956 gc_assert(Pointerp(first));
957 gc_assert(!from_space_p(first));
964 trans_list(lispobj object)
966 lispobj new_list_pointer;
967 struct cons *cons, *new_cons;
969 cons = (struct cons *) PTR(object);
971 /* ### Don't use copy_object here. */
972 new_list_pointer = copy_object(object, 2);
973 new_cons = (struct cons *) PTR(new_list_pointer);
975 /* Set forwarding pointer. */
976 cons->car = new_list_pointer;
978 /* Try to linearize the list in the cdr direction to help reduce */
982 lispobj cdr, new_cdr, first;
983 struct cons *cdr_cons, *new_cdr_cons;
987 if (LowtagOf(cdr) != type_ListPointer ||
988 !from_space_p(cdr) ||
989 (Pointerp(first = *(lispobj *)PTR(cdr)) &&
993 cdr_cons = (struct cons *) PTR(cdr);
995 /* ### Don't use copy_object here */
996 new_cdr = copy_object(cdr, 2);
997 new_cdr_cons = (struct cons *) PTR(new_cdr);
999 /* Set forwarding pointer */
1000 cdr_cons->car = new_cdr;
1002 /* Update the cdr of the last cons copied into new */
1003 /* space to keep the newspace scavenge from having to */
1005 new_cons->cdr = new_cdr;
1008 new_cons = new_cdr_cons;
1011 return new_list_pointer;
1015 /* scavenging and transporting other pointers */
1018 scav_other_pointer(lispobj *where, lispobj object)
1020 lispobj first, *first_pointer;
1022 gc_assert(Pointerp(object));
1024 /* Object is a pointer into from space - not a FP */
1025 first_pointer = (lispobj *) PTR(object);
1026 first = *first_pointer = (transother[TypeOf(*first_pointer)])(object);
1028 gc_assert(Pointerp(first));
1029 gc_assert(!from_space_p(first));
1036 /* immediate, boxed, and unboxed objects */
1039 size_pointer(lispobj *where)
1045 scav_immediate(lispobj *where, lispobj object)
1051 trans_immediate(lispobj object)
1053 fprintf(stderr, "GC lossage. Trying to transport an immediate!?\n");
1059 size_immediate(lispobj *where)
1066 scav_boxed(lispobj *where, lispobj object)
1072 trans_boxed(lispobj object)
1075 unsigned long length;
1077 gc_assert(Pointerp(object));
1079 header = *((lispobj *) PTR(object));
1080 length = HeaderValue(header) + 1;
1081 length = CEILING(length, 2);
1083 return copy_object(object, length);
1087 size_boxed(lispobj *where)
1090 unsigned long length;
1093 length = HeaderValue(header) + 1;
1094 length = CEILING(length, 2);
1099 /* Note: on the sparc we don't have to do anything special for fdefns, */
1100 /* 'cause the raw-addr has a function lowtag. */
1103 scav_fdefn(lispobj *where, lispobj object)
1105 struct fdefn *fdefn;
1107 fdefn = (struct fdefn *)where;
1109 if ((char *)(fdefn->function + RAW_ADDR_OFFSET)
1110 == (char *)((unsigned long)(fdefn->raw_addr))) {
1111 scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1);
1112 fdefn->raw_addr = (u32) ((char *) LOW_WORD(fdefn->function)) + RAW_ADDR_OFFSET;
1113 return sizeof(struct fdefn) / sizeof(lispobj);
1121 scav_unboxed(lispobj *where, lispobj object)
1123 unsigned long length;
1125 length = HeaderValue(object) + 1;
1126 length = CEILING(length, 2);
1132 trans_unboxed(lispobj object)
1135 unsigned long length;
1138 gc_assert(Pointerp(object));
1140 header = *((lispobj *) PTR(object));
1141 length = HeaderValue(header) + 1;
1142 length = CEILING(length, 2);
1144 return copy_object(object, length);
1148 size_unboxed(lispobj *where)
1151 unsigned long length;
1154 length = HeaderValue(header) + 1;
1155 length = CEILING(length, 2);
1161 /* vector-like objects */
1163 #define NWORDS(x,y) (CEILING((x),(y)) / (y))
1166 scav_string(lispobj *where, lispobj object)
1168 struct vector *vector;
1171 /* NOTE: Strings contain one more byte of data than the length */
1172 /* slot indicates. */
1174 vector = (struct vector *) where;
1175 length = fixnum_value(vector->length) + 1;
1176 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1182 trans_string(lispobj object)
1184 struct vector *vector;
1187 gc_assert(Pointerp(object));
1189 /* NOTE: Strings contain one more byte of data than the length */
1190 /* slot indicates. */
1192 vector = (struct vector *) PTR(object);
1193 length = fixnum_value(vector->length) + 1;
1194 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1196 return copy_object(object, nwords);
1200 size_string(lispobj *where)
1202 struct vector *vector;
1205 /* NOTE: Strings contain one more byte of data than the length */
1206 /* slot indicates. */
1208 vector = (struct vector *) where;
1209 length = fixnum_value(vector->length) + 1;
1210 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1216 scav_vector(lispobj *where, lispobj object)
1218 if (HeaderValue(object) == subtype_VectorValidHashing)
1219 *where = (subtype_VectorMustRehash<<type_Bits) | type_SimpleVector;
1226 trans_vector(lispobj object)
1228 struct vector *vector;
1231 gc_assert(Pointerp(object));
1233 vector = (struct vector *) PTR(object);
1235 length = fixnum_value(vector->length);
1236 nwords = CEILING(length + 2, 2);
1238 return copy_object(object, nwords);
1242 size_vector(lispobj *where)
1244 struct vector *vector;
1247 vector = (struct vector *) where;
1248 length = fixnum_value(vector->length);
1249 nwords = CEILING(length + 2, 2);
1256 scav_vector_bit(lispobj *where, lispobj object)
1258 struct vector *vector;
1261 vector = (struct vector *) where;
1262 length = fixnum_value(vector->length);
1263 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1269 trans_vector_bit(lispobj object)
1271 struct vector *vector;
1274 gc_assert(Pointerp(object));
1276 vector = (struct vector *) PTR(object);
1277 length = fixnum_value(vector->length);
1278 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1280 return copy_object(object, nwords);
1284 size_vector_bit(lispobj *where)
1286 struct vector *vector;
1289 vector = (struct vector *) where;
1290 length = fixnum_value(vector->length);
1291 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1298 scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
1300 struct vector *vector;
1303 vector = (struct vector *) where;
1304 length = fixnum_value(vector->length);
1305 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1311 trans_vector_unsigned_byte_2(lispobj object)
1313 struct vector *vector;
1316 gc_assert(Pointerp(object));
1318 vector = (struct vector *) PTR(object);
1319 length = fixnum_value(vector->length);
1320 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1322 return copy_object(object, nwords);
1326 size_vector_unsigned_byte_2(lispobj *where)
1328 struct vector *vector;
1331 vector = (struct vector *) where;
1332 length = fixnum_value(vector->length);
1333 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1340 scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
1342 struct vector *vector;
1345 vector = (struct vector *) where;
1346 length = fixnum_value(vector->length);
1347 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1353 trans_vector_unsigned_byte_4(lispobj object)
1355 struct vector *vector;
1358 gc_assert(Pointerp(object));
1360 vector = (struct vector *) PTR(object);
1361 length = fixnum_value(vector->length);
1362 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1364 return copy_object(object, nwords);
1368 size_vector_unsigned_byte_4(lispobj *where)
1370 struct vector *vector;
1373 vector = (struct vector *) where;
1374 length = fixnum_value(vector->length);
1375 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1382 scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
1384 struct vector *vector;
1387 vector = (struct vector *) where;
1388 length = fixnum_value(vector->length);
1389 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1395 trans_vector_unsigned_byte_8(lispobj object)
1397 struct vector *vector;
1400 gc_assert(Pointerp(object));
1402 vector = (struct vector *) PTR(object);
1403 length = fixnum_value(vector->length);
1404 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1406 return copy_object(object, nwords);
1410 size_vector_unsigned_byte_8(lispobj *where)
1412 struct vector *vector;
1415 vector = (struct vector *) where;
1416 length = fixnum_value(vector->length);
1417 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1424 scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
1426 struct vector *vector;
1429 vector = (struct vector *) where;
1430 length = fixnum_value(vector->length);
1431 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1437 trans_vector_unsigned_byte_16(lispobj object)
1439 struct vector *vector;
1442 gc_assert(Pointerp(object));
1444 vector = (struct vector *) PTR(object);
1445 length = fixnum_value(vector->length);
1446 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1448 return copy_object(object, nwords);
1452 size_vector_unsigned_byte_16(lispobj *where)
1454 struct vector *vector;
1457 vector = (struct vector *) where;
1458 length = fixnum_value(vector->length);
1459 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1466 scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
1468 struct vector *vector;
1471 vector = (struct vector *) where;
1472 length = fixnum_value(vector->length);
1473 nwords = CEILING(length + 2, 2);
1479 trans_vector_unsigned_byte_32(lispobj object)
1481 struct vector *vector;
1484 gc_assert(Pointerp(object));
1486 vector = (struct vector *) PTR(object);
1487 length = fixnum_value(vector->length);
1488 nwords = CEILING(length + 2, 2);
1490 return copy_object(object, nwords);
1494 size_vector_unsigned_byte_32(lispobj *where)
1496 struct vector *vector;
1499 vector = (struct vector *) where;
1500 length = fixnum_value(vector->length);
1501 nwords = CEILING(length + 2, 2);
1508 scav_vector_single_float(lispobj *where, lispobj object)
1510 struct vector *vector;
1513 vector = (struct vector *) where;
1514 length = fixnum_value(vector->length);
1515 nwords = CEILING(length + 2, 2);
1521 trans_vector_single_float(lispobj object)
1523 struct vector *vector;
1526 gc_assert(Pointerp(object));
1528 vector = (struct vector *) PTR(object);
1529 length = fixnum_value(vector->length);
1530 nwords = CEILING(length + 2, 2);
1532 return copy_object(object, nwords);
1536 size_vector_single_float(lispobj *where)
1538 struct vector *vector;
1541 vector = (struct vector *) where;
1542 length = fixnum_value(vector->length);
1543 nwords = CEILING(length + 2, 2);
1550 scav_vector_double_float(lispobj *where, lispobj object)
1552 struct vector *vector;
1555 vector = (struct vector *) where;
1556 length = fixnum_value(vector->length);
1557 nwords = CEILING(length * 2 + 2, 2);
1563 trans_vector_double_float(lispobj object)
1565 struct vector *vector;
1568 gc_assert(Pointerp(object));
1570 vector = (struct vector *) PTR(object);
1571 length = fixnum_value(vector->length);
1572 nwords = CEILING(length * 2 + 2, 2);
1574 return copy_object(object, nwords);
1578 size_vector_double_float(lispobj *where)
1580 struct vector *vector;
1583 vector = (struct vector *) where;
1584 length = fixnum_value(vector->length);
1585 nwords = CEILING(length * 2 + 2, 2);
1591 #ifdef type_SimpleArrayLongFloat
1593 scav_vector_long_float(lispobj *where, lispobj object)
1595 struct vector *vector;
1598 vector = (struct vector *) where;
1599 length = fixnum_value(vector->length);
1601 nwords = CEILING(length * 4 + 2, 2);
1608 trans_vector_long_float(lispobj object)
1610 struct vector *vector;
1613 gc_assert(Pointerp(object));
1615 vector = (struct vector *) PTR(object);
1616 length = fixnum_value(vector->length);
1618 nwords = CEILING(length * 4 + 2, 2);
1621 return copy_object(object, nwords);
1625 size_vector_long_float(lispobj *where)
1627 struct vector *vector;
1630 vector = (struct vector *) where;
1631 length = fixnum_value(vector->length);
1633 nwords = CEILING(length * 4 + 2, 2);
1641 #ifdef type_SimpleArrayComplexSingleFloat
1643 scav_vector_complex_single_float(lispobj *where, lispobj object)
1645 struct vector *vector;
1648 vector = (struct vector *) where;
1649 length = fixnum_value(vector->length);
1650 nwords = CEILING(length * 2 + 2, 2);
1656 trans_vector_complex_single_float(lispobj object)
1658 struct vector *vector;
1661 gc_assert(Pointerp(object));
1663 vector = (struct vector *) PTR(object);
1664 length = fixnum_value(vector->length);
1665 nwords = CEILING(length * 2 + 2, 2);
1667 return copy_object(object, nwords);
1671 size_vector_complex_single_float(lispobj *where)
1673 struct vector *vector;
1676 vector = (struct vector *) where;
1677 length = fixnum_value(vector->length);
1678 nwords = CEILING(length * 2 + 2, 2);
1684 #ifdef type_SimpleArrayComplexDoubleFloat
1686 scav_vector_complex_double_float(lispobj *where, lispobj object)
1688 struct vector *vector;
1691 vector = (struct vector *) where;
1692 length = fixnum_value(vector->length);
1693 nwords = CEILING(length * 4 + 2, 2);
1699 trans_vector_complex_double_float(lispobj object)
1701 struct vector *vector;
1704 gc_assert(Pointerp(object));
1706 vector = (struct vector *) PTR(object);
1707 length = fixnum_value(vector->length);
1708 nwords = CEILING(length * 4 + 2, 2);
1710 return copy_object(object, nwords);
1714 size_vector_complex_double_float(lispobj *where)
1716 struct vector *vector;
1719 vector = (struct vector *) where;
1720 length = fixnum_value(vector->length);
1721 nwords = CEILING(length * 4 + 2, 2);
1727 #ifdef type_SimpleArrayComplexLongFloat
1729 scav_vector_complex_long_float(lispobj *where, lispobj object)
1731 struct vector *vector;
1734 vector = (struct vector *) where;
1735 length = fixnum_value(vector->length);
1737 nwords = CEILING(length * 8 + 2, 2);
1744 trans_vector_complex_long_float(lispobj object)
1746 struct vector *vector;
1749 gc_assert(Pointerp(object));
1751 vector = (struct vector *) PTR(object);
1752 length = fixnum_value(vector->length);
1754 nwords = CEILING(length * 8 + 2, 2);
1757 return copy_object(object, nwords);
1761 size_vector_complex_long_float(lispobj *where)
1763 struct vector *vector;
1766 vector = (struct vector *) where;
1767 length = fixnum_value(vector->length);
1769 nwords = CEILING(length * 8 + 2, 2);
1779 #define WEAK_POINTER_NWORDS \
1780 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1783 scav_weak_pointer(lispobj *where, lispobj object)
1785 /* Do not let GC scavenge the value slot of the weak pointer */
1786 /* (that is why it is a weak pointer). Note: we could use */
1787 /* the scav_unboxed method here. */
1789 return WEAK_POINTER_NWORDS;
1793 trans_weak_pointer(lispobj object)
1796 struct weak_pointer *wp;
1798 gc_assert(Pointerp(object));
1800 #if defined(DEBUG_WEAK)
1801 printf("Transporting weak pointer from 0x%08x\n", object);
1804 /* Need to remember where all the weak pointers are that have */
1805 /* been transported so they can be fixed up in a post-GC pass. */
1807 copy = copy_object(object, WEAK_POINTER_NWORDS);
1808 wp = (struct weak_pointer *) PTR(copy);
1811 /* Push the weak pointer onto the list of weak pointers. */
1812 wp->next = LOW_WORD(weak_pointers);
1819 size_weak_pointer(lispobj *where)
1821 return WEAK_POINTER_NWORDS;
1824 void scan_weak_pointers(void)
1826 struct weak_pointer *wp;
1828 for (wp = weak_pointers; wp != (struct weak_pointer *) NULL;
1829 wp = (struct weak_pointer *)((unsigned long)wp->next)) {
1831 lispobj first, *first_pointer;
1835 #if defined(DEBUG_WEAK)
1836 printf("Weak pointer at 0x%p\n", wp);
1837 printf("Value: 0x%08x\n", (unsigned int) value);
1840 if (!(Pointerp(value) && from_space_p(value)))
1843 /* Now, we need to check if the object has been */
1844 /* forwarded. If it has been, the weak pointer is */
1845 /* still good and needs to be updated. Otherwise, the */
1846 /* weak pointer needs to be nil'ed out. */
1848 first_pointer = (lispobj *) PTR(value);
1849 first = *first_pointer;
1851 #if defined(DEBUG_WEAK)
1852 printf("First: 0x%08x\n", (unsigned long) first);
1855 if (Pointerp(first) && new_space_p(first))
1866 /* initialization */
1869 scav_lose(lispobj *where, lispobj object)
1871 fprintf(stderr, "GC lossage. No scavenge function for object 0x%08x (at 0x%016lx)\n",
1872 (unsigned int) object, (unsigned long)where);
1878 trans_lose(lispobj object)
1880 fprintf(stderr, "GC lossage. No transport function for object 0x%08x\n",
1881 (unsigned int)object);
1887 size_lose(lispobj *where)
1889 fprintf(stderr, "Size lossage. No size function for object at 0x%p\n",
1891 fprintf(stderr, "First word of object: 0x%08x\n",
1896 /* KLUDGE: SBCL already has two GC implementations, and if someday the
1897 * precise generational GC is revived, it might have three. It would
1898 * be nice to share the scavtab[] data set up here, and perhaps other
1899 * things too, between all of them, rather than trying to maintain
1900 * multiple copies. -- WHN 2001-05-09 */
1906 /* scavenge table */
1907 for (i = 0; i < 256; i++)
1908 scavtab[i] = scav_lose;
1909 /* scavtab[i] = scav_immediate; */
1911 for (i = 0; i < 32; i++) {
1912 scavtab[type_EvenFixnum|(i<<3)] = scav_immediate;
1913 scavtab[type_FunctionPointer|(i<<3)] = scav_function_pointer;
1914 /* OtherImmediate0 */
1915 scavtab[type_ListPointer|(i<<3)] = scav_list_pointer;
1916 scavtab[type_OddFixnum|(i<<3)] = scav_immediate;
1917 scavtab[type_InstancePointer|(i<<3)] = scav_instance_pointer;
1918 /* OtherImmediate1 */
1919 scavtab[type_OtherPointer|(i<<3)] = scav_other_pointer;
1922 scavtab[type_Bignum] = scav_unboxed;
1923 scavtab[type_Ratio] = scav_boxed;
1924 scavtab[type_SingleFloat] = scav_unboxed;
1925 scavtab[type_DoubleFloat] = scav_unboxed;
1926 #ifdef type_LongFloat
1927 scavtab[type_LongFloat] = scav_unboxed;
1929 scavtab[type_Complex] = scav_boxed;
1930 #ifdef type_ComplexSingleFloat
1931 scavtab[type_ComplexSingleFloat] = scav_unboxed;
1933 #ifdef type_ComplexDoubleFloat
1934 scavtab[type_ComplexDoubleFloat] = scav_unboxed;
1936 #ifdef type_ComplexLongFloat
1937 scavtab[type_ComplexLongFloat] = scav_unboxed;
1939 scavtab[type_SimpleArray] = scav_boxed;
1940 scavtab[type_SimpleString] = scav_string;
1941 scavtab[type_SimpleBitVector] = scav_vector_bit;
1942 scavtab[type_SimpleVector] = scav_vector;
1943 scavtab[type_SimpleArrayUnsignedByte2] = scav_vector_unsigned_byte_2;
1944 scavtab[type_SimpleArrayUnsignedByte4] = scav_vector_unsigned_byte_4;
1945 scavtab[type_SimpleArrayUnsignedByte8] = scav_vector_unsigned_byte_8;
1946 scavtab[type_SimpleArrayUnsignedByte16] = scav_vector_unsigned_byte_16;
1947 scavtab[type_SimpleArrayUnsignedByte32] = scav_vector_unsigned_byte_32;
1948 #ifdef type_SimpleArraySignedByte8
1949 scavtab[type_SimpleArraySignedByte8] = scav_vector_unsigned_byte_8;
1951 #ifdef type_SimpleArraySignedByte16
1952 scavtab[type_SimpleArraySignedByte16] = scav_vector_unsigned_byte_16;
1954 #ifdef type_SimpleArraySignedByte30
1955 scavtab[type_SimpleArraySignedByte30] = scav_vector_unsigned_byte_32;
1957 #ifdef type_SimpleArraySignedByte32
1958 scavtab[type_SimpleArraySignedByte32] = scav_vector_unsigned_byte_32;
1960 scavtab[type_SimpleArraySingleFloat] = scav_vector_single_float;
1961 scavtab[type_SimpleArrayDoubleFloat] = scav_vector_double_float;
1962 #ifdef type_SimpleArrayLongFloat
1963 scavtab[type_SimpleArrayLongFloat] = scav_vector_long_float;
1965 #ifdef type_SimpleArrayComplexSingleFloat
1966 scavtab[type_SimpleArrayComplexSingleFloat] = scav_vector_complex_single_float;
1968 #ifdef type_SimpleArrayComplexDoubleFloat
1969 scavtab[type_SimpleArrayComplexDoubleFloat] = scav_vector_complex_double_float;
1971 #ifdef type_SimpleArrayComplexLongFloat
1972 scavtab[type_SimpleArrayComplexLongFloat] = scav_vector_complex_long_float;
1974 scavtab[type_ComplexString] = scav_boxed;
1975 scavtab[type_ComplexBitVector] = scav_boxed;
1976 scavtab[type_ComplexVector] = scav_boxed;
1977 scavtab[type_ComplexArray] = scav_boxed;
1978 scavtab[type_CodeHeader] = scav_code_header;
1979 scavtab[type_FunctionHeader] = scav_function_header;
1980 scavtab[type_ClosureFunctionHeader] = scav_function_header;
1981 scavtab[type_ReturnPcHeader] = scav_return_pc_header;
1983 scavtab[type_ClosureHeader] = scav_closure_header;
1984 scavtab[type_FuncallableInstanceHeader] = scav_closure_header;
1985 scavtab[type_ByteCodeFunction] = scav_closure_header;
1986 scavtab[type_ByteCodeClosure] = scav_closure_header;
1987 /* scavtab[type_DylanFunctionHeader] = scav_closure_header; */
1989 scavtab[type_ClosureHeader] = scav_boxed;
1990 scavtab[type_FuncallableInstanceHeader] = scav_boxed;
1991 scavtab[type_ByteCodeFunction] = scav_boxed;
1992 scavtab[type_ByteCodeClosure] = scav_boxed;
1993 /* scavtab[type_DylanFunctionHeader] = scav_boxed; */
1995 scavtab[type_ValueCellHeader] = scav_boxed;
1996 scavtab[type_SymbolHeader] = scav_boxed;
1997 scavtab[type_BaseChar] = scav_immediate;
1998 scavtab[type_Sap] = scav_unboxed;
1999 scavtab[type_UnboundMarker] = scav_immediate;
2000 scavtab[type_WeakPointer] = scav_weak_pointer;
2001 scavtab[type_InstanceHeader] = scav_boxed;
2003 scavtab[type_Fdefn] = scav_fdefn;
2005 scavtab[type_Fdefn] = scav_boxed;
2008 /* Transport Other Table */
2009 for (i = 0; i < 256; i++)
2010 transother[i] = trans_lose;
2012 transother[type_Bignum] = trans_unboxed;
2013 transother[type_Ratio] = trans_boxed;
2014 transother[type_SingleFloat] = trans_unboxed;
2015 transother[type_DoubleFloat] = trans_unboxed;
2016 #ifdef type_LongFloat
2017 transother[type_LongFloat] = trans_unboxed;
2019 transother[type_Complex] = trans_boxed;
2020 #ifdef type_ComplexSingleFloat
2021 transother[type_ComplexSingleFloat] = trans_unboxed;
2023 #ifdef type_ComplexDoubleFloat
2024 transother[type_ComplexDoubleFloat] = trans_unboxed;
2026 #ifdef type_ComplexLongFloat
2027 transother[type_ComplexLongFloat] = trans_unboxed;
2029 transother[type_SimpleArray] = trans_boxed;
2030 transother[type_SimpleString] = trans_string;
2031 transother[type_SimpleBitVector] = trans_vector_bit;
2032 transother[type_SimpleVector] = trans_vector;
2033 transother[type_SimpleArrayUnsignedByte2] = trans_vector_unsigned_byte_2;
2034 transother[type_SimpleArrayUnsignedByte4] = trans_vector_unsigned_byte_4;
2035 transother[type_SimpleArrayUnsignedByte8] = trans_vector_unsigned_byte_8;
2036 transother[type_SimpleArrayUnsignedByte16] = trans_vector_unsigned_byte_16;
2037 transother[type_SimpleArrayUnsignedByte32] = trans_vector_unsigned_byte_32;
2038 #ifdef type_SimpleArraySignedByte8
2039 transother[type_SimpleArraySignedByte8] = trans_vector_unsigned_byte_8;
2041 #ifdef type_SimpleArraySignedByte16
2042 transother[type_SimpleArraySignedByte16] = trans_vector_unsigned_byte_16;
2044 #ifdef type_SimpleArraySignedByte30
2045 transother[type_SimpleArraySignedByte30] = trans_vector_unsigned_byte_32;
2047 #ifdef type_SimpleArraySignedByte32
2048 transother[type_SimpleArraySignedByte32] = trans_vector_unsigned_byte_32;
2050 transother[type_SimpleArraySingleFloat] = trans_vector_single_float;
2051 transother[type_SimpleArrayDoubleFloat] = trans_vector_double_float;
2052 #ifdef type_SimpleArrayLongFloat
2053 transother[type_SimpleArrayLongFloat] = trans_vector_long_float;
2055 #ifdef type_SimpleArrayComplexSingleFloat
2056 transother[type_SimpleArrayComplexSingleFloat] = trans_vector_complex_single_float;
2058 #ifdef type_SimpleArrayComplexDoubleFloat
2059 transother[type_SimpleArrayComplexDoubleFloat] = trans_vector_complex_double_float;
2061 #ifdef type_SimpleArrayComplexLongFloat
2062 transother[type_SimpleArrayComplexLongFloat] = trans_vector_complex_long_float;
2064 transother[type_ComplexString] = trans_boxed;
2065 transother[type_ComplexBitVector] = trans_boxed;
2066 transother[type_ComplexVector] = trans_boxed;
2067 transother[type_ComplexArray] = trans_boxed;
2068 transother[type_CodeHeader] = trans_code_header;
2069 transother[type_FunctionHeader] = trans_function_header;
2070 transother[type_ClosureFunctionHeader] = trans_function_header;
2071 transother[type_ReturnPcHeader] = trans_return_pc_header;
2072 transother[type_ClosureHeader] = trans_boxed;
2073 transother[type_FuncallableInstanceHeader] = trans_boxed;
2074 transother[type_ByteCodeFunction] = trans_boxed;
2075 transother[type_ByteCodeClosure] = trans_boxed;
2076 transother[type_ValueCellHeader] = trans_boxed;
2077 transother[type_SymbolHeader] = trans_boxed;
2078 transother[type_BaseChar] = trans_immediate;
2079 transother[type_Sap] = trans_unboxed;
2080 transother[type_UnboundMarker] = trans_immediate;
2081 transother[type_WeakPointer] = trans_weak_pointer;
2082 transother[type_InstanceHeader] = trans_boxed;
2083 transother[type_Fdefn] = trans_boxed;
2087 for (i = 0; i < 256; i++)
2088 sizetab[i] = size_lose;
2090 for (i = 0; i < 32; i++) {
2091 sizetab[type_EvenFixnum|(i<<3)] = size_immediate;
2092 sizetab[type_FunctionPointer|(i<<3)] = size_pointer;
2093 /* OtherImmediate0 */
2094 sizetab[type_ListPointer|(i<<3)] = size_pointer;
2095 sizetab[type_OddFixnum|(i<<3)] = size_immediate;
2096 sizetab[type_InstancePointer|(i<<3)] = size_pointer;
2097 /* OtherImmediate1 */
2098 sizetab[type_OtherPointer|(i<<3)] = size_pointer;
2101 sizetab[type_Bignum] = size_unboxed;
2102 sizetab[type_Ratio] = size_boxed;
2103 sizetab[type_SingleFloat] = size_unboxed;
2104 sizetab[type_DoubleFloat] = size_unboxed;
2105 #ifdef type_LongFloat
2106 sizetab[type_LongFloat] = size_unboxed;
2108 sizetab[type_Complex] = size_boxed;
2109 #ifdef type_ComplexSingleFloat
2110 sizetab[type_ComplexSingleFloat] = size_unboxed;
2112 #ifdef type_ComplexDoubleFloat
2113 sizetab[type_ComplexDoubleFloat] = size_unboxed;
2115 #ifdef type_ComplexLongFloat
2116 sizetab[type_ComplexLongFloat] = size_unboxed;
2118 sizetab[type_SimpleArray] = size_boxed;
2119 sizetab[type_SimpleString] = size_string;
2120 sizetab[type_SimpleBitVector] = size_vector_bit;
2121 sizetab[type_SimpleVector] = size_vector;
2122 sizetab[type_SimpleArrayUnsignedByte2] = size_vector_unsigned_byte_2;
2123 sizetab[type_SimpleArrayUnsignedByte4] = size_vector_unsigned_byte_4;
2124 sizetab[type_SimpleArrayUnsignedByte8] = size_vector_unsigned_byte_8;
2125 sizetab[type_SimpleArrayUnsignedByte16] = size_vector_unsigned_byte_16;
2126 sizetab[type_SimpleArrayUnsignedByte32] = size_vector_unsigned_byte_32;
2127 #ifdef type_SimpleArraySignedByte8
2128 sizetab[type_SimpleArraySignedByte8] = size_vector_unsigned_byte_8;
2130 #ifdef type_SimpleArraySignedByte16
2131 sizetab[type_SimpleArraySignedByte16] = size_vector_unsigned_byte_16;
2133 #ifdef type_SimpleArraySignedByte30
2134 sizetab[type_SimpleArraySignedByte30] = size_vector_unsigned_byte_32;
2136 #ifdef type_SimpleArraySignedByte32
2137 sizetab[type_SimpleArraySignedByte32] = size_vector_unsigned_byte_32;
2139 sizetab[type_SimpleArraySingleFloat] = size_vector_single_float;
2140 sizetab[type_SimpleArrayDoubleFloat] = size_vector_double_float;
2141 #ifdef type_SimpleArrayLongFloat
2142 sizetab[type_SimpleArrayLongFloat] = size_vector_long_float;
2144 #ifdef type_SimpleArrayComplexSingleFloat
2145 sizetab[type_SimpleArrayComplexSingleFloat] = size_vector_complex_single_float;
2147 #ifdef type_SimpleArrayComplexDoubleFloat
2148 sizetab[type_SimpleArrayComplexDoubleFloat] = size_vector_complex_double_float;
2150 #ifdef type_SimpleArrayComplexLongFloat
2151 sizetab[type_SimpleArrayComplexLongFloat] = size_vector_complex_long_float;
2153 sizetab[type_ComplexString] = size_boxed;
2154 sizetab[type_ComplexBitVector] = size_boxed;
2155 sizetab[type_ComplexVector] = size_boxed;
2156 sizetab[type_ComplexArray] = size_boxed;
2157 sizetab[type_CodeHeader] = size_code_header;
2159 /* Shouldn't see these so just lose if it happens */
2160 sizetab[type_FunctionHeader] = size_function_header;
2161 sizetab[type_ClosureFunctionHeader] = size_function_header;
2162 sizetab[type_ReturnPcHeader] = size_return_pc_header;
2164 sizetab[type_ClosureHeader] = size_boxed;
2165 sizetab[type_FuncallableInstanceHeader] = size_boxed;
2166 sizetab[type_ValueCellHeader] = size_boxed;
2167 sizetab[type_SymbolHeader] = size_boxed;
2168 sizetab[type_BaseChar] = size_immediate;
2169 sizetab[type_Sap] = size_unboxed;
2170 sizetab[type_UnboundMarker] = size_immediate;
2171 sizetab[type_WeakPointer] = size_weak_pointer;
2172 sizetab[type_InstanceHeader] = size_boxed;
2173 sizetab[type_Fdefn] = size_boxed;
2176 /* noise to manipulate the gc trigger stuff */
2180 void set_auto_gc_trigger(os_vm_size_t dynamic_usage)
2182 os_vm_address_t addr=(os_vm_address_t)current_dynamic_space +
2185 DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr;
2187 if(addr < (os_vm_address_t)dynamic_space_free_pointer) {
2189 "set_auto_gc_trigger: tried to set gc trigger too low! (%d < %p)\n",
2190 (unsigned int)dynamic_usage,
2191 (os_vm_address_t)dynamic_space_free_pointer
2192 - (os_vm_address_t)current_dynamic_space);
2195 else if (length < 0) {
2197 "set_auto_gc_trigger: tried to set gc trigger too high! (%p)\n",
2202 addr=os_round_up_to_page(addr);
2203 length=os_trunc_size_to_page(length);
2205 #if defined(SUNOS) || defined(SOLARIS)
2206 os_invalidate(addr,length);
2208 os_protect(addr, length, 0);
2211 current_auto_gc_trigger = (lispobj *)addr;
2214 void clear_auto_gc_trigger(void)
2216 if(current_auto_gc_trigger!=NULL){
2217 #if defined(SUNOS) || defined(SOLARIS)/* don't want to force whole space into swapping mode... */
2218 os_vm_address_t addr=(os_vm_address_t)current_auto_gc_trigger;
2219 os_vm_size_t length=
2220 DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr;
2222 os_validate(addr,length);
2224 os_protect((os_vm_address_t)current_dynamic_space,
2229 current_auto_gc_trigger = NULL;