2 * Stop and Copy GC based on Cheney's algorithm.
4 * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gc.c,v 1.26 2007/01/01 11:53:03 cshapiro Rel $
6 * Written by Christopher Hoover.
11 #include <sys/resource.h>
14 #include "internals.h"
18 #include "interrupt.h"
23 static lispobj *from_space;
24 static lispobj *from_space_free_pointer;
26 static lispobj *new_space;
27 static lispobj *new_space_free_pointer;
29 static int (*scavtab[256]) (lispobj * where, lispobj object);
30 static lispobj(*transother[256]) (lispobj object);
31 static int (*sizetab[256]) (lispobj * where);
33 static struct weak_pointer *weak_pointers;
35 static void scavenge(lispobj * start, long nwords);
36 static void scavenge_newspace(void);
37 static void scavenge_interrupt_contexts(void);
38 static void scan_weak_pointers(void);
40 #define gc_abort() lose("GC invariant lost! File \"%s\", line %d\n", \
44 #define gc_assert(ex) do { \
45 if (!(ex)) gc_abort(); \
51 #define CEILING(x,y) (((x) + ((y) - 1)) & (~((y) - 1)))
56 #if defined(DEBUG_SPACE_PREDICATES)
59 from_space_p(lispobj object)
63 ptr = (lispobj *) PTR(object);
65 return ((from_space <= ptr) && (ptr < from_space_free_pointer));
69 new_space_p(lispobj object)
73 gc_assert(Pointerp(object));
75 ptr = (lispobj *) PTR(object);
77 return ((new_space <= ptr) && (ptr < new_space_free_pointer));
82 #define from_space_p(ptr) \
83 ((from_space <= ((lispobj *) ptr)) && \
84 (((lispobj *) ptr) < from_space_free_pointer))
86 #define new_space_p(ptr) \
87 ((new_space <= ((lispobj *) ptr)) && \
88 (((lispobj *) ptr) < new_space_free_pointer))
96 copy_object(lispobj object, int nwords)
100 lispobj *source, *dest;
102 gc_assert(Pointerp(object));
103 gc_assert(from_space_p(object));
104 gc_assert((nwords & 0x01) == 0);
106 /* get tag of object */
107 tag = LowtagOf(object);
110 new = new_space_free_pointer;
111 new_space_free_pointer += nwords;
114 source = (lispobj *) PTR(object);
116 /* copy the object */
125 /* return lisp pointer of new object */
126 return ((lispobj) new) | tag;
130 /* Collect Garbage */
134 tv_diff(struct timeval *x, struct timeval *y)
136 return (((double) x->tv_sec + (double) x->tv_usec * 1.0e-6) -
137 ((double) y->tv_sec + (double) y->tv_usec * 1.0e-6));
141 #define BYTES_ZERO_BEFORE_END (1<<12)
147 unsigned long *ptr = (unsigned long *) current_control_stack_pointer;
149 u32 *ptr = (u32 *) current_control_stack_pointer;
157 } while (((unsigned long) ptr) & (BYTES_ZERO_BEFORE_END - 1));
159 } while (((u32) ptr) & (BYTES_ZERO_BEFORE_END - 1));
167 } while (((unsigned long) ptr) & (BYTES_ZERO_BEFORE_END - 1));
169 } while (((u32) ptr) & (BYTES_ZERO_BEFORE_END - 1));
175 collect_garbage(void)
178 struct timeval start_tv, stop_tv;
179 struct rusage start_rusage, stop_rusage;
180 double real_time, system_time, user_time;
181 double percent_retained, gc_rate;
182 unsigned long size_discarded;
183 unsigned long size_retained;
185 lispobj *current_static_space_free_pointer;
186 unsigned long static_space_size;
187 unsigned long control_stack_size, binding_stack_size;
194 printf("[Collecting garbage ... \n");
196 getrusage(RUSAGE_SELF, &start_rusage);
197 gettimeofday(&start_tv, (struct timezone *) 0);
202 sigprocmask(SIG_BLOCK, &tmp, &old);
204 current_static_space_free_pointer =
205 (lispobj *) SymbolValue(STATIC_SPACE_FREE_POINTER);
208 /* Set up from space and new space pointers. */
210 from_space = current_dynamic_space;
212 from_space_free_pointer = current_dynamic_space_free_pointer;
214 from_space_free_pointer = (lispobj *) SymbolValue(ALLOCATION_POINTER);
217 if (current_dynamic_space == dynamic_0_space)
218 new_space = dynamic_1_space;
219 else if (current_dynamic_space == dynamic_1_space)
220 new_space = dynamic_0_space;
222 lose("GC lossage. Current dynamic space is bogus!\n");
224 new_space_free_pointer = new_space;
227 /* Initialize the weak pointer list. */
228 weak_pointers = (struct weak_pointer *) NULL;
231 /* Scavenge all of the roots. */
233 printf("Scavenging interrupt contexts ...\n");
235 scavenge_interrupt_contexts();
238 printf("Scavenging interrupt handlers (%d bytes) ...\n",
239 sizeof(interrupt_handlers));
241 scavenge((lispobj *) interrupt_handlers,
242 sizeof(interrupt_handlers) / sizeof(lispobj));
244 control_stack_size = current_control_stack_pointer - control_stack;
246 printf("Scavenging the control stack (%d bytes) ...\n",
247 control_stack_size * sizeof(lispobj));
249 scavenge(control_stack, control_stack_size);
252 binding_stack_size = current_binding_stack_pointer - binding_stack;
255 (lispobj *) SymbolValue(BINDING_STACK_POINTER) - binding_stack;
258 printf("Scavenging the binding stack (%d bytes) ...\n",
259 binding_stack_size * sizeof(lispobj));
261 scavenge(binding_stack, binding_stack_size);
263 static_space_size = current_static_space_free_pointer - static_space;
265 printf("Scavenging static space (%d bytes) ...\n",
266 static_space_size * sizeof(lispobj));
268 scavenge(static_space, static_space_size);
271 /* Scavenge newspace. */
273 printf("Scavenging new space (%d bytes) ...\n",
274 (new_space_free_pointer - new_space) * sizeof(lispobj));
279 #if defined(DEBUG_PRINT_GARBAGE)
280 print_garbage(from_space, from_space_free_pointer);
283 /* Scan the weak pointers. */
285 printf("Scanning weak pointers ...\n");
287 scan_weak_pointers();
292 printf("Flipping spaces ...\n");
295 os_zero((os_vm_address_t) current_dynamic_space,
296 (os_vm_size_t) dynamic_space_size);
298 current_dynamic_space = new_space;
300 current_dynamic_space_free_pointer = new_space_free_pointer;
302 SetSymbolValue(ALLOCATION_POINTER, (lispobj) new_space_free_pointer);
306 size_discarded = (from_space_free_pointer - from_space) * sizeof(lispobj);
307 size_retained = (new_space_free_pointer - new_space) * sizeof(lispobj);
312 printf("Zeroing empty part of control stack ...\n");
316 sigprocmask(SIG_SETMASK, &old, 0);
320 gettimeofday(&stop_tv, (struct timezone *) 0);
321 getrusage(RUSAGE_SELF, &stop_rusage);
325 percent_retained = (((float) size_retained) /
326 ((float) size_discarded)) * 100.0;
328 printf("Total of %d bytes out of %d bytes retained (%3.2f%%).\n",
329 size_retained, size_discarded, percent_retained);
331 real_time = tv_diff(&stop_tv, &start_tv);
332 user_time = tv_diff(&stop_rusage.ru_utime, &start_rusage.ru_utime);
333 system_time = tv_diff(&stop_rusage.ru_stime, &start_rusage.ru_stime);
336 printf("Statistics:\n");
337 printf("%10.2f sec of real time\n", real_time);
338 printf("%10.2f sec of user time,\n", user_time);
339 printf("%10.2f sec of system time.\n", system_time);
341 printf("Statistics: %10.2fs real, %10.2fs user, %10.2fs system.\n",
342 real_time, user_time, system_time);
345 gc_rate = ((float) size_retained / (float) (1 << 20)) / real_time;
347 printf("%10.2f M bytes/sec collected.\n", gc_rate);
354 #define DIRECT_SCAV 0
357 scavenge(lispobj * start, long nwords)
361 int type, words_scavenged;
364 type = TypeOf(object);
366 #if defined(DEBUG_SCAVENGE_VERBOSE)
367 printf("Scavenging object at 0x%08x, object = 0x%08x, type = %d\n",
368 (unsigned long) start, (unsigned long) object, type);
372 words_scavenged = (scavtab[type]) (start, object);
374 if (Pointerp(object)) {
375 /* It be a pointer. */
376 if (from_space_p(object)) {
377 /* It currently points to old space. Check for a */
378 /* forwarding pointer. */
381 first_word = *((lispobj *) PTR(object));
382 if (Pointerp(first_word) && new_space_p(first_word)) {
383 /* Yep, there be a forwarding pointer. */
387 /* Scavenge that pointer. */
388 words_scavenged = (scavtab[type]) (start, object);
391 /* It points somewhere other than oldspace. Leave */
395 } else if ((object & 3) == 0) {
396 /* It's a fixnum. Real easy. */
399 /* It's some random header object. */
400 words_scavenged = (scavtab[type]) (start, object);
404 start += words_scavenged;
405 nwords -= words_scavenged;
407 gc_assert(nwords == 0);
411 scavenge_newspace(void)
413 lispobj *here, *next;
416 while (here < new_space_free_pointer) {
417 next = new_space_free_pointer;
418 scavenge(here, next - here);
424 /* Scavenging Interrupt Contexts */
426 static int boxed_registers[] = BOXED_REGISTERS;
429 scavenge_interrupt_context(os_context_t * context)
435 unsigned long lip_offset;
436 int lip_register_pair;
438 unsigned long pc_code_offset;
441 unsigned long npc_code_offset;
444 /* Find the LIP's register pair and calculate it's offset */
445 /* before we scavenge the context. */
447 lip = SC_REG(context, reg_LIP);
448 lip_offset = 0x7FFFFFFF;
449 lip_register_pair = -1;
450 for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
455 index = boxed_registers[i];
456 reg = SC_REG(context, index);
457 if (Pointerp(reg) && PTR(reg) <= lip) {
459 if (offset < lip_offset) {
461 lip_register_pair = index;
467 /* Compute the PC's offset from the start of the CODE */
469 pc_code_offset = SC_PC(context) - SC_REG(context, reg_CODE);
471 npc_code_offset = SC_NPC(context) - SC_REG(context, reg_CODE);
474 /* Scanvenge all boxed registers in the context. */
475 for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
479 index = boxed_registers[i];
480 foo = SC_REG(context, index);
481 scavenge((lispobj *) & foo, 1);
482 SC_REG(context, index) = foo;
484 scavenge((lispobj *) & (SC_REG(context, index)), 1);
489 SC_REG(context, reg_LIP) = SC_REG(context, lip_register_pair) + lip_offset;
492 /* Fix the PC if it was in from space */
493 if (from_space_p(SC_PC(context)))
494 SC_PC(context) = SC_REG(context, reg_CODE) + pc_code_offset;
496 if (from_space_p(SC_NPC(context)))
497 SC_NPC(context) = SC_REG(context, reg_CODE) + npc_code_offset;
502 scavenge_interrupt_contexts(void)
505 os_context_t *context;
507 index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX));
508 #if defined(DEBUG_PRINT_CONTEXT_INDEX)
509 printf("Number of active contexts: %d\n", index);
512 for (i = 0; i < index; i++) {
513 context = lisp_interrupt_contexts[i];
514 scavenge_interrupt_context(context);
522 print_garbage(lispobj * from_space, lispobj * from_space_free_pointer)
525 int total_words_not_copied;
527 printf("Scanning from space ...\n");
529 total_words_not_copied = 0;
531 while (start < from_space_free_pointer) {
533 int forwardp, type, nwords;
537 forwardp = Pointerp(object) && new_space_p(object);
543 tag = LowtagOf(object);
546 case type_ListPointer:
549 case type_InstancePointer:
550 printf("Don't know about instances yet!\n");
553 case type_FunctionPointer:
556 case type_OtherPointer:
557 pointer = (lispobj *) PTR(object);
559 type = TypeOf(header);
560 nwords = (sizetab[type]) (pointer);
563 type = TypeOf(object);
564 nwords = (sizetab[type]) (start);
565 total_words_not_copied += nwords;
566 printf("%4d words not copied at 0x%08x; ",
567 nwords, (unsigned long) start);
568 printf("Header word is 0x%08x\n", (unsigned long) object);
572 printf("%d total words not copied.\n", total_words_not_copied);
576 /* Code and Code-Related Objects */
578 #define RAW_ADDR_OFFSET (6*sizeof(lispobj) - type_FunctionPointer)
580 static lispobj trans_function_header(lispobj object);
581 static lispobj trans_boxed(lispobj object);
585 scav_function_pointer(lispobj * where, lispobj object)
587 gc_assert(Pointerp(object));
589 if (from_space_p(object)) {
590 lispobj first, *first_pointer;
592 /* object is a pointer into from space. check to see */
593 /* if it has been forwarded */
594 first_pointer = (lispobj *) PTR(object);
595 first = *first_pointer;
597 if (!(Pointerp(first) && new_space_p(first))) {
601 /* must transport object -- object may point */
602 /* to either a function header, a closure */
603 /* function header, or to a closure header. */
605 type = TypeOf(first);
607 case type_FunctionHeader:
608 case type_ClosureFunctionHeader:
609 copy = trans_function_header(object);
612 copy = trans_boxed(object);
616 first = *first_pointer = copy;
619 gc_assert(Pointerp(first));
620 gc_assert(!from_space_p(first));
628 scav_function_pointer(lispobj * where, lispobj object)
630 lispobj *first_pointer;
635 gc_assert(Pointerp(object));
637 /* object is a pointer into from space. Not a FP */
638 first_pointer = (lispobj *) PTR(object);
639 first = *first_pointer;
641 /* must transport object -- object may point */
642 /* to either a function header, a closure */
643 /* function header, or to a closure header. */
645 type = TypeOf(first);
647 case type_FunctionHeader:
648 case type_ClosureFunctionHeader:
649 copy = trans_function_header(object);
652 copy = trans_boxed(object);
656 first = *first_pointer = copy;
658 gc_assert(Pointerp(first));
659 gc_assert(!from_space_p(first));
667 trans_code(struct code *code)
669 struct code *new_code;
670 lispobj first, l_code, l_new_code;
671 int nheader_words, ncode_words, nwords;
672 unsigned long displacement;
673 lispobj fheaderl, *prev_pointer;
675 #if defined(DEBUG_CODE_GC)
676 printf("\nTransporting code object located at 0x%08x.\n",
677 (unsigned long) code);
680 /* if object has already been transported, just return pointer */
681 first = code->header;
682 if (Pointerp(first) && new_space_p(first))
683 return (struct code *) PTR(first);
685 gc_assert(TypeOf(first) == type_CodeHeader);
687 /* prepare to transport the code vector */
688 l_code = (lispobj) code | type_OtherPointer;
690 ncode_words = fixnum_value(code->code_size);
691 nheader_words = HeaderValue(code->header);
692 nwords = ncode_words + nheader_words;
693 nwords = CEILING(nwords, 2);
695 l_new_code = copy_object(l_code, nwords);
696 new_code = (struct code *) PTR(l_new_code);
698 displacement = l_new_code - l_code;
700 #if defined(DEBUG_CODE_GC)
701 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
702 (unsigned long) code, (unsigned long) new_code);
703 printf("Code object is %d words long.\n", nwords);
706 /* set forwarding pointer */
707 code->header = l_new_code;
709 /* set forwarding pointers for all the function headers in the */
710 /* code object. also fix all self pointers */
712 fheaderl = code->entry_points;
713 prev_pointer = &new_code->entry_points;
715 while (fheaderl != NIL) {
716 struct function *fheaderp, *nfheaderp;
719 fheaderp = (struct function *) PTR(fheaderl);
720 gc_assert(TypeOf(fheaderp->header) == type_FunctionHeader);
722 /* calcuate the new function pointer and the new */
723 /* function header */
724 nfheaderl = fheaderl + displacement;
725 nfheaderp = (struct function *) PTR(nfheaderl);
727 /* set forwarding pointer */
728 fheaderp->header = nfheaderl;
730 /* fix self pointer */
731 nfheaderp->self = nfheaderl;
733 *prev_pointer = nfheaderl;
735 fheaderl = fheaderp->next;
736 prev_pointer = &nfheaderp->next;
740 os_flush_icache((os_vm_address_t) (((int *) new_code) + nheader_words),
741 ncode_words * sizeof(int));
747 scav_code_header(lispobj * where, lispobj object)
750 int nheader_words, ncode_words, nwords;
752 struct function *fheaderp;
754 code = (struct code *) where;
755 ncode_words = fixnum_value(code->code_size);
756 nheader_words = HeaderValue(object);
757 nwords = ncode_words + nheader_words;
758 nwords = CEILING(nwords, 2);
760 #if defined(DEBUG_CODE_GC)
761 printf("\nScavening code object at 0x%08x.\n", (unsigned long) where);
762 printf("Code object is %d words long.\n", nwords);
763 printf("Scavenging boxed section of code data block (%d words).\n",
767 /* Scavenge the boxed section of the code data block */
768 scavenge(where + 1, nheader_words - 1);
770 /* Scavenge the boxed section of each function object in the */
771 /* code data block */
772 fheaderl = code->entry_points;
773 while (fheaderl != NIL) {
774 fheaderp = (struct function *) PTR(fheaderl);
775 gc_assert(TypeOf(fheaderp->header) == type_FunctionHeader);
777 #if defined(DEBUG_CODE_GC)
778 printf("Scavenging boxed section of entry point located at 0x%08x.\n",
779 (unsigned long) PTR(fheaderl));
781 scavenge(&fheaderp->name, 1);
782 scavenge(&fheaderp->arglist, 1);
783 scavenge(&fheaderp->type, 1);
785 fheaderl = fheaderp->next;
792 trans_code_header(lispobj object)
796 ncode = trans_code((struct code *) PTR(object));
797 return (lispobj) ncode | type_OtherPointer;
801 size_code_header(lispobj * where)
804 int nheader_words, ncode_words, nwords;
806 code = (struct code *) where;
808 ncode_words = fixnum_value(code->code_size);
809 nheader_words = HeaderValue(code->header);
810 nwords = ncode_words + nheader_words;
811 nwords = CEILING(nwords, 2);
818 scav_return_pc_header(lispobj * where, lispobj object)
820 fprintf(stderr, "GC lossage. Should not be scavenging a ");
821 fprintf(stderr, "Return PC Header.\n");
822 fprintf(stderr, "where = 0x%08x, object = 0x%08x",
823 (unsigned long) where, (unsigned long) object);
829 trans_return_pc_header(lispobj object)
831 struct function *return_pc;
832 unsigned long offset;
833 struct code *code, *ncode;
835 return_pc = (struct function *) PTR(object);
836 offset = HeaderValue(return_pc->header) * 4;
838 /* Transport the whole code object */
839 code = (struct code *) ((unsigned long) return_pc - offset);
840 ncode = trans_code(code);
842 return ((lispobj) ncode + offset) | type_OtherPointer;
845 /* On the 386, closures hold a pointer to the raw address instead of the
846 function object, so we can use CALL [$FDEFN+const] to invoke the function
847 without loading it into a register. Given that code objects don't move,
848 we don't need to update anything, but we do have to figure out that the
849 function is still live. */
852 scav_closure_header(where, object)
853 lispobj *where, object;
855 struct closure *closure;
858 closure = (struct closure *) where;
859 fun = closure->function - RAW_ADDR_OFFSET;
867 scav_function_header(lispobj * where, lispobj object)
869 fprintf(stderr, "GC lossage. Should not be scavenging a ");
870 fprintf(stderr, "Function Header.\n");
871 fprintf(stderr, "where = 0x%08x, object = 0x%08x",
872 (unsigned long) where, (unsigned long) object);
878 trans_function_header(lispobj object)
880 struct function *fheader;
881 unsigned long offset;
882 struct code *code, *ncode;
884 fheader = (struct function *) PTR(object);
885 offset = HeaderValue(fheader->header) * 4;
887 /* Transport the whole code object */
888 code = (struct code *) ((unsigned long) fheader - offset);
889 ncode = trans_code(code);
891 return ((lispobj) ncode + offset) | type_FunctionPointer;
900 scav_instance_pointer(lispobj * where, lispobj object)
902 if (from_space_p(object)) {
903 lispobj first, *first_pointer;
905 /* object is a pointer into from space. check to see */
906 /* if it has been forwarded */
907 first_pointer = (lispobj *) PTR(object);
908 first = *first_pointer;
910 if (!(Pointerp(first) && new_space_p(first)))
911 first = *first_pointer = trans_boxed(object);
918 scav_instance_pointer(lispobj * where, lispobj object)
920 lispobj *first_pointer;
922 /* object is a pointer into from space. Not a FP */
923 first_pointer = (lispobj *) PTR(object);
925 *where = *first_pointer = trans_boxed(object);
931 /* Lists and Conses */
933 static lispobj trans_list(lispobj object);
937 scav_list_pointer(lispobj * where, lispobj object)
939 gc_assert(Pointerp(object));
941 if (from_space_p(object)) {
942 lispobj first, *first_pointer;
944 /* object is a pointer into from space. check to see */
945 /* if it has been forwarded */
946 first_pointer = (lispobj *) PTR(object);
947 first = *first_pointer;
949 if (!(Pointerp(first) && new_space_p(first)))
950 first = *first_pointer = trans_list(object);
952 gc_assert(Pointerp(first));
953 gc_assert(!from_space_p(first));
961 scav_list_pointer(lispobj * where, lispobj object)
963 lispobj first, *first_pointer;
965 gc_assert(Pointerp(object));
967 /* object is a pointer into from space. Not a FP. */
968 first_pointer = (lispobj *) PTR(object);
970 first = *first_pointer = trans_list(object);
972 gc_assert(Pointerp(first));
973 gc_assert(!from_space_p(first));
981 trans_list(lispobj object)
983 lispobj new_list_pointer;
984 struct cons *cons, *new_cons;
986 cons = (struct cons *) PTR(object);
988 /* ### Don't use copy_object here. */
989 new_list_pointer = copy_object(object, 2);
990 new_cons = (struct cons *) PTR(new_list_pointer);
992 /* Set forwarding pointer. */
993 cons->car = new_list_pointer;
995 /* Try to linearize the list in the cdr direction to help reduce */
999 lispobj cdr, new_cdr, first;
1000 struct cons *cdr_cons, *new_cdr_cons;
1004 if (LowtagOf(cdr) != type_ListPointer ||
1005 !from_space_p(cdr) ||
1006 (Pointerp(first = *(lispobj *) PTR(cdr)) && new_space_p(first)))
1009 cdr_cons = (struct cons *) PTR(cdr);
1011 /* ### Don't use copy_object here */
1012 new_cdr = copy_object(cdr, 2);
1013 new_cdr_cons = (struct cons *) PTR(new_cdr);
1015 /* Set forwarding pointer */
1016 cdr_cons->car = new_cdr;
1018 /* Update the cdr of the last cons copied into new */
1019 /* space to keep the newspace scavenge from having to */
1021 new_cons->cdr = new_cdr;
1024 new_cons = new_cdr_cons;
1027 return new_list_pointer;
1031 /* Scavenging and Transporting Other Pointers */
1035 scav_other_pointer(lispobj * where, lispobj object)
1037 gc_assert(Pointerp(object));
1039 if (from_space_p(object)) {
1040 lispobj first, *first_pointer;
1042 /* object is a pointer into from space. check to see */
1043 /* if it has been forwarded */
1044 first_pointer = (lispobj *) PTR(object);
1045 first = *first_pointer;
1047 if (!(Pointerp(first) && new_space_p(first)))
1048 first = *first_pointer = (transother[TypeOf(first)]) (object);
1050 gc_assert(Pointerp(first));
1051 gc_assert(!from_space_p(first));
1059 scav_other_pointer(lispobj * where, lispobj object)
1061 lispobj first, *first_pointer;
1063 gc_assert(Pointerp(object));
1065 /* Object is a pointer into from space - not a FP */
1066 first_pointer = (lispobj *) PTR(object);
1067 first = *first_pointer = (transother[TypeOf(*first_pointer)]) (object);
1069 gc_assert(Pointerp(first));
1070 gc_assert(!from_space_p(first));
1078 /* Immediate, Boxed, and Unboxed Objects */
1081 size_pointer(lispobj * where)
1087 scav_immediate(lispobj * where, lispobj object)
1093 trans_immediate(lispobj object)
1095 fprintf(stderr, "GC lossage. Trying to transport an immediate!?\n");
1101 size_immediate(lispobj * where)
1108 scav_boxed(lispobj * where, lispobj object)
1114 trans_boxed(lispobj object)
1117 unsigned long length;
1119 gc_assert(Pointerp(object));
1121 header = *((lispobj *) PTR(object));
1122 length = HeaderValue(header) + 1;
1123 length = CEILING(length, 2);
1125 return copy_object(object, length);
1129 size_boxed(lispobj * where)
1132 unsigned long length;
1135 length = HeaderValue(header) + 1;
1136 length = CEILING(length, 2);
1141 /* Note: on the sparc we don't have to do anything special for fdefns, */
1142 /* cause the raw-addr has a function lowtag. */
1143 #if !(defined(sparc) || defined(DARWIN))
1145 scav_fdefn(lispobj * where, lispobj object)
1147 struct fdefn *fdefn;
1149 fdefn = (struct fdefn *) where;
1151 if ((char *) (fdefn->function + RAW_ADDR_OFFSET) == fdefn->raw_addr) {
1152 scavenge(where + 1, sizeof(struct fdefn) / sizeof(lispobj) - 1);
1154 fdefn->raw_addr = (char *) (fdefn->function + RAW_ADDR_OFFSET);
1155 return sizeof(struct fdefn) / sizeof(lispobj);
1162 scav_unboxed(lispobj * where, lispobj object)
1164 unsigned long length;
1166 length = HeaderValue(object) + 1;
1167 length = CEILING(length, 2);
1173 trans_unboxed(lispobj object)
1176 unsigned long length;
1179 gc_assert(Pointerp(object));
1181 header = *((lispobj *) PTR(object));
1182 length = HeaderValue(header) + 1;
1183 length = CEILING(length, 2);
1185 return copy_object(object, length);
1189 size_unboxed(lispobj * where)
1192 unsigned long length;
1195 length = HeaderValue(header) + 1;
1196 length = CEILING(length, 2);
1202 /* Vector-Like Objects */
1204 #define NWORDS(x,y) (CEILING((x),(y)) / (y))
1207 scav_string(lispobj * where, lispobj object)
1209 struct vector *vector;
1212 /* NOTE: Strings contain one more byte of data than the length */
1213 /* slot indicates. */
1215 vector = (struct vector *) where;
1216 length = fixnum_value(vector->length) + 1;
1217 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1223 trans_string(lispobj object)
1225 struct vector *vector;
1228 gc_assert(Pointerp(object));
1230 /* NOTE: Strings contain one more byte of data than the length */
1231 /* slot indicates. */
1233 vector = (struct vector *) PTR(object);
1234 length = fixnum_value(vector->length) + 1;
1235 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1237 return copy_object(object, nwords);
1241 size_string(lispobj * where)
1243 struct vector *vector;
1246 /* NOTE: Strings contain one more byte of data than the length */
1247 /* slot indicates. */
1249 vector = (struct vector *) where;
1250 length = fixnum_value(vector->length) + 1;
1251 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1257 scav_vector(lispobj * where, lispobj object)
1259 if (HeaderValue(object) == subtype_VectorValidHashing)
1260 *where = (subtype_VectorMustRehash << type_Bits) | type_SimpleVector;
1267 trans_vector(lispobj object)
1269 struct vector *vector;
1272 gc_assert(Pointerp(object));
1274 vector = (struct vector *) PTR(object);
1276 length = fixnum_value(vector->length);
1277 nwords = CEILING(length + 2, 2);
1279 return copy_object(object, nwords);
1283 size_vector(lispobj * where)
1285 struct vector *vector;
1288 vector = (struct vector *) where;
1289 length = fixnum_value(vector->length);
1290 nwords = CEILING(length + 2, 2);
1297 scav_vector_bit(lispobj * where, lispobj object)
1299 struct vector *vector;
1302 vector = (struct vector *) where;
1303 length = fixnum_value(vector->length);
1304 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1310 trans_vector_bit(lispobj object)
1312 struct vector *vector;
1315 gc_assert(Pointerp(object));
1317 vector = (struct vector *) PTR(object);
1318 length = fixnum_value(vector->length);
1319 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1321 return copy_object(object, nwords);
1325 size_vector_bit(lispobj * where)
1327 struct vector *vector;
1330 vector = (struct vector *) where;
1331 length = fixnum_value(vector->length);
1332 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1339 scav_vector_unsigned_byte_2(lispobj * where, lispobj object)
1341 struct vector *vector;
1344 vector = (struct vector *) where;
1345 length = fixnum_value(vector->length);
1346 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1352 trans_vector_unsigned_byte_2(lispobj object)
1354 struct vector *vector;
1357 gc_assert(Pointerp(object));
1359 vector = (struct vector *) PTR(object);
1360 length = fixnum_value(vector->length);
1361 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1363 return copy_object(object, nwords);
1367 size_vector_unsigned_byte_2(lispobj * where)
1369 struct vector *vector;
1372 vector = (struct vector *) where;
1373 length = fixnum_value(vector->length);
1374 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1381 scav_vector_unsigned_byte_4(lispobj * where, lispobj object)
1383 struct vector *vector;
1386 vector = (struct vector *) where;
1387 length = fixnum_value(vector->length);
1388 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1394 trans_vector_unsigned_byte_4(lispobj object)
1396 struct vector *vector;
1399 gc_assert(Pointerp(object));
1401 vector = (struct vector *) PTR(object);
1402 length = fixnum_value(vector->length);
1403 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1405 return copy_object(object, nwords);
1409 size_vector_unsigned_byte_4(lispobj * where)
1411 struct vector *vector;
1414 vector = (struct vector *) where;
1415 length = fixnum_value(vector->length);
1416 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1423 scav_vector_unsigned_byte_8(lispobj * where, lispobj object)
1425 struct vector *vector;
1428 vector = (struct vector *) where;
1429 length = fixnum_value(vector->length);
1430 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1436 trans_vector_unsigned_byte_8(lispobj object)
1438 struct vector *vector;
1441 gc_assert(Pointerp(object));
1443 vector = (struct vector *) PTR(object);
1444 length = fixnum_value(vector->length);
1445 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1447 return copy_object(object, nwords);
1451 size_vector_unsigned_byte_8(lispobj * where)
1453 struct vector *vector;
1456 vector = (struct vector *) where;
1457 length = fixnum_value(vector->length);
1458 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1465 scav_vector_unsigned_byte_16(lispobj * where, lispobj object)
1467 struct vector *vector;
1470 vector = (struct vector *) where;
1471 length = fixnum_value(vector->length);
1472 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1478 trans_vector_unsigned_byte_16(lispobj object)
1480 struct vector *vector;
1483 gc_assert(Pointerp(object));
1485 vector = (struct vector *) PTR(object);
1486 length = fixnum_value(vector->length);
1487 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1489 return copy_object(object, nwords);
1493 size_vector_unsigned_byte_16(lispobj * where)
1495 struct vector *vector;
1498 vector = (struct vector *) where;
1499 length = fixnum_value(vector->length);
1500 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1507 scav_vector_unsigned_byte_32(lispobj * where, lispobj object)
1509 struct vector *vector;
1512 vector = (struct vector *) where;
1513 length = fixnum_value(vector->length);
1514 nwords = CEILING(length + 2, 2);
1520 trans_vector_unsigned_byte_32(lispobj object)
1522 struct vector *vector;
1525 gc_assert(Pointerp(object));
1527 vector = (struct vector *) PTR(object);
1528 length = fixnum_value(vector->length);
1529 nwords = CEILING(length + 2, 2);
1531 return copy_object(object, nwords);
1535 size_vector_unsigned_byte_32(lispobj * where)
1537 struct vector *vector;
1540 vector = (struct vector *) where;
1541 length = fixnum_value(vector->length);
1542 nwords = CEILING(length + 2, 2);
1549 scav_vector_single_float(lispobj * where, lispobj object)
1551 struct vector *vector;
1554 vector = (struct vector *) where;
1555 length = fixnum_value(vector->length);
1556 nwords = CEILING(length + 2, 2);
1562 trans_vector_single_float(lispobj object)
1564 struct vector *vector;
1567 gc_assert(Pointerp(object));
1569 vector = (struct vector *) PTR(object);
1570 length = fixnum_value(vector->length);
1571 nwords = CEILING(length + 2, 2);
1573 return copy_object(object, nwords);
1577 size_vector_single_float(lispobj * where)
1579 struct vector *vector;
1582 vector = (struct vector *) where;
1583 length = fixnum_value(vector->length);
1584 nwords = CEILING(length + 2, 2);
1591 scav_vector_double_float(lispobj * where, lispobj object)
1593 struct vector *vector;
1596 vector = (struct vector *) where;
1597 length = fixnum_value(vector->length);
1598 nwords = CEILING(length * 2 + 2, 2);
1604 trans_vector_double_float(lispobj object)
1606 struct vector *vector;
1609 gc_assert(Pointerp(object));
1611 vector = (struct vector *) PTR(object);
1612 length = fixnum_value(vector->length);
1613 nwords = CEILING(length * 2 + 2, 2);
1615 return copy_object(object, nwords);
1619 size_vector_double_float(lispobj * where)
1621 struct vector *vector;
1624 vector = (struct vector *) where;
1625 length = fixnum_value(vector->length);
1626 nwords = CEILING(length * 2 + 2, 2);
1632 #ifdef type_SimpleArrayLongFloat
1634 scav_vector_long_float(lispobj * where, lispobj object)
1636 struct vector *vector;
1639 vector = (struct vector *) where;
1640 length = fixnum_value(vector->length);
1642 nwords = CEILING(length * 4 + 2, 2);
1649 trans_vector_long_float(lispobj object)
1651 struct vector *vector;
1654 gc_assert(Pointerp(object));
1656 vector = (struct vector *) PTR(object);
1657 length = fixnum_value(vector->length);
1659 nwords = CEILING(length * 4 + 2, 2);
1662 return copy_object(object, nwords);
1666 size_vector_long_float(lispobj * where)
1668 struct vector *vector;
1671 vector = (struct vector *) where;
1672 length = fixnum_value(vector->length);
1674 nwords = CEILING(length * 4 + 2, 2);
1682 #ifdef type_SimpleArrayDoubleDoubleFloat
1684 size_vector_double_double_float(lispobj * where)
1686 struct vector *vector;
1689 vector = (struct vector *) where;
1690 length = fixnum_value(vector->length);
1691 nwords = CEILING(length * 4 + 2, 2);
1697 scav_vector_double_double_float(lispobj * where, lispobj object)
1699 return size_vector_double_double_float(where);
1703 trans_vector_double_double_float(lispobj object)
1705 gc_assert(Pointerp(object));
1706 return copy_object(object, size_vector_double_double_float((lispobj *)
1712 #ifdef type_SimpleArrayComplexSingleFloat
1714 scav_vector_complex_single_float(lispobj * where, lispobj object)
1716 struct vector *vector;
1719 vector = (struct vector *) where;
1720 length = fixnum_value(vector->length);
1721 nwords = CEILING(length * 2 + 2, 2);
1727 trans_vector_complex_single_float(lispobj object)
1729 struct vector *vector;
1732 gc_assert(Pointerp(object));
1734 vector = (struct vector *) PTR(object);
1735 length = fixnum_value(vector->length);
1736 nwords = CEILING(length * 2 + 2, 2);
1738 return copy_object(object, nwords);
1742 size_vector_complex_single_float(lispobj * where)
1744 struct vector *vector;
1747 vector = (struct vector *) where;
1748 length = fixnum_value(vector->length);
1749 nwords = CEILING(length * 2 + 2, 2);
1755 #ifdef type_SimpleArrayComplexDoubleFloat
1757 scav_vector_complex_double_float(lispobj * where, lispobj object)
1759 struct vector *vector;
1762 vector = (struct vector *) where;
1763 length = fixnum_value(vector->length);
1764 nwords = CEILING(length * 4 + 2, 2);
1770 trans_vector_complex_double_float(lispobj object)
1772 struct vector *vector;
1775 gc_assert(Pointerp(object));
1777 vector = (struct vector *) PTR(object);
1778 length = fixnum_value(vector->length);
1779 nwords = CEILING(length * 4 + 2, 2);
1781 return copy_object(object, nwords);
1785 size_vector_complex_double_float(lispobj * where)
1787 struct vector *vector;
1790 vector = (struct vector *) where;
1791 length = fixnum_value(vector->length);
1792 nwords = CEILING(length * 4 + 2, 2);
1798 #ifdef type_SimpleArrayComplexLongFloat
1800 scav_vector_complex_long_float(lispobj * where, lispobj object)
1802 struct vector *vector;
1805 vector = (struct vector *) where;
1806 length = fixnum_value(vector->length);
1808 nwords = CEILING(length * 8 + 2, 2);
1815 trans_vector_complex_long_float(lispobj object)
1817 struct vector *vector;
1820 gc_assert(Pointerp(object));
1822 vector = (struct vector *) PTR(object);
1823 length = fixnum_value(vector->length);
1825 nwords = CEILING(length * 8 + 2, 2);
1828 return copy_object(object, nwords);
1832 size_vector_complex_long_float(lispobj * where)
1834 struct vector *vector;
1837 vector = (struct vector *) where;
1838 length = fixnum_value(vector->length);
1840 nwords = CEILING(length * 8 + 2, 2);
1847 #ifdef type_SimpleArrayComplexDoubleDoubleFloat
1849 size_vector_complex_double_double_float(lispobj * where)
1851 struct vector *vector;
1854 vector = (struct vector *) where;
1855 length = fixnum_value(vector->length);
1856 nwords = length * 8 + 2;
1862 scav_vector_complex_double_double_float(lispobj * where, lispobj object)
1864 return size_vector_complex_double_double_float(where);
1868 trans_vector_complex_double_double_float(lispobj object)
1870 gc_assert(Pointerp(object));
1871 return copy_object(object,
1872 size_vector_complex_double_double_float((lispobj *)
1880 #define WEAK_POINTER_NWORDS \
1881 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1884 scav_weak_pointer(lispobj * where, lispobj object)
1886 /* Do not let GC scavenge the value slot of the weak pointer */
1887 /* (that is why it is a weak pointer). Note: we could use */
1888 /* the scav_unboxed method here. */
1890 return WEAK_POINTER_NWORDS;
1894 trans_weak_pointer(lispobj object)
1897 struct weak_pointer *wp;
1899 gc_assert(Pointerp(object));
1901 #if defined(DEBUG_WEAK)
1902 printf("Transporting weak pointer from 0x%08x\n", object);
1905 /* Need to remember where all the weak pointers are that have */
1906 /* been transported so they can be fixed up in a post-GC pass. */
1908 copy = copy_object(object, WEAK_POINTER_NWORDS);
1909 wp = (struct weak_pointer *) PTR(copy);
1912 /* Push the weak pointer onto the list of weak pointers. */
1913 wp->next = weak_pointers;
1920 size_weak_pointer(lispobj * where)
1922 return WEAK_POINTER_NWORDS;
1926 scan_weak_pointers(void)
1928 struct weak_pointer *wp;
1930 for (wp = weak_pointers; wp != (struct weak_pointer *) NULL; wp = wp->next) {
1932 lispobj first, *first_pointer;
1936 #if defined(DEBUG_WEAK)
1937 printf("Weak pointer at 0x%08x\n", (unsigned long) wp);
1938 printf("Value: 0x%08x\n", (unsigned long) value);
1941 if (!(Pointerp(value) && from_space_p(value)))
1944 /* Now, we need to check if the object has been */
1945 /* forwarded. If it has been, the weak pointer is */
1946 /* still good and needs to be updated. Otherwise, the */
1947 /* weak pointer needs to be nil'ed out. */
1949 first_pointer = (lispobj *) PTR(value);
1950 first = *first_pointer;
1952 #if defined(DEBUG_WEAK)
1953 printf("First: 0x%08x\n", (unsigned long) first);
1956 if (Pointerp(first) && new_space_p(first))
1967 /* Initialization */
1970 scav_lose(lispobj * where, lispobj object)
1972 fprintf(stderr, "GC lossage. No scavenge function for object 0x%08x\n",
1973 (unsigned long) object);
1979 trans_lose(lispobj object)
1981 fprintf(stderr, "GC lossage. No transport function for object 0x%08x\n",
1982 (unsigned long) object);
1988 size_lose(lispobj * where)
1990 fprintf(stderr, "Size lossage. No size function for object at 0x%08x\n",
1991 (unsigned long) where);
1992 fprintf(stderr, "First word of object: 0x%08x\n", (unsigned long) *where);
2001 /* Scavenge Table */
2002 for (i = 0; i < 256; i++)
2003 scavtab[i] = scav_lose;
2005 for (i = 0; i < 32; i++) {
2006 scavtab[type_EvenFixnum | (i << 3)] = scav_immediate;
2007 scavtab[type_FunctionPointer | (i << 3)] = scav_function_pointer;
2008 /* OtherImmediate0 */
2009 scavtab[type_ListPointer | (i << 3)] = scav_list_pointer;
2010 scavtab[type_OddFixnum | (i << 3)] = scav_immediate;
2011 scavtab[type_InstancePointer | (i << 3)] = scav_instance_pointer;
2012 /* OtherImmediate1 */
2013 scavtab[type_OtherPointer | (i << 3)] = scav_other_pointer;
2016 scavtab[type_Bignum] = scav_unboxed;
2017 scavtab[type_Ratio] = scav_boxed;
2018 scavtab[type_SingleFloat] = scav_unboxed;
2019 scavtab[type_DoubleFloat] = scav_unboxed;
2020 #ifdef type_LongFloat
2021 scavtab[type_LongFloat] = scav_unboxed;
2023 #ifdef type_DoubleDoubleFloat
2024 scavtab[type_DoubleDoubleFloat] = scav_unboxed;
2026 scavtab[type_Complex] = scav_boxed;
2027 #ifdef type_ComplexSingleFloat
2028 scavtab[type_ComplexSingleFloat] = scav_unboxed;
2030 #ifdef type_ComplexDoubleFloat
2031 scavtab[type_ComplexDoubleFloat] = scav_unboxed;
2033 #ifdef type_ComplexLongFloat
2034 scavtab[type_ComplexLongFloat] = scav_unboxed;
2036 #ifdef type_ComplexDoubleDoubleFloat
2037 scavtab[type_ComplexDoubleDoubleFloat] = scav_unboxed;
2039 scavtab[type_SimpleArray] = scav_boxed;
2040 scavtab[type_SimpleString] = scav_string;
2041 scavtab[type_SimpleBitVector] = scav_vector_bit;
2042 scavtab[type_SimpleVector] = scav_vector;
2043 scavtab[type_SimpleArrayUnsignedByte2] = scav_vector_unsigned_byte_2;
2044 scavtab[type_SimpleArrayUnsignedByte4] = scav_vector_unsigned_byte_4;
2045 scavtab[type_SimpleArrayUnsignedByte8] = scav_vector_unsigned_byte_8;
2046 scavtab[type_SimpleArrayUnsignedByte16] = scav_vector_unsigned_byte_16;
2047 scavtab[type_SimpleArrayUnsignedByte32] = scav_vector_unsigned_byte_32;
2048 #ifdef type_SimpleArraySignedByte8
2049 scavtab[type_SimpleArraySignedByte8] = scav_vector_unsigned_byte_8;
2051 #ifdef type_SimpleArraySignedByte16
2052 scavtab[type_SimpleArraySignedByte16] = scav_vector_unsigned_byte_16;
2054 #ifdef type_SimpleArraySignedByte30
2055 scavtab[type_SimpleArraySignedByte30] = scav_vector_unsigned_byte_32;
2057 #ifdef type_SimpleArraySignedByte32
2058 scavtab[type_SimpleArraySignedByte32] = scav_vector_unsigned_byte_32;
2060 scavtab[type_SimpleArraySingleFloat] = scav_vector_single_float;
2061 scavtab[type_SimpleArrayDoubleFloat] = scav_vector_double_float;
2062 #ifdef type_SimpleArrayLongFloat
2063 scavtab[type_SimpleArrayLongFloat] = scav_vector_long_float;
2065 #ifdef type_SimpleArrayDoubleDoubleFloat
2066 scavtab[type_SimpleArrayDoubleDoubleFloat] = scav_vector_double_double_float;
2068 #ifdef type_SimpleArrayComplexSingleFloat
2069 scavtab[type_SimpleArrayComplexSingleFloat] =
2070 scav_vector_complex_single_float;
2072 #ifdef type_SimpleArrayComplexDoubleFloat
2073 scavtab[type_SimpleArrayComplexDoubleFloat] =
2074 scav_vector_complex_double_float;
2076 #ifdef type_SimpleArrayComplexLongFloat
2077 scavtab[type_SimpleArrayComplexLongFloat] = scav_vector_complex_long_float;
2079 #ifdef type_SimpleArrayComplexDoubleDoubleFloat
2080 scavtab[type_SimpleArrayComplexDoubleDoubleFloat] =
2081 scav_vector_complex_double_double_float;
2083 scavtab[type_ComplexString] = scav_boxed;
2084 scavtab[type_ComplexBitVector] = scav_boxed;
2085 scavtab[type_ComplexVector] = scav_boxed;
2086 scavtab[type_ComplexArray] = scav_boxed;
2087 scavtab[type_CodeHeader] = scav_code_header;
2088 scavtab[type_FunctionHeader] = scav_function_header;
2089 scavtab[type_ClosureFunctionHeader] = scav_function_header;
2090 scavtab[type_ReturnPcHeader] = scav_return_pc_header;
2092 scavtab[type_ClosureHeader] = scav_closure_header;
2093 scavtab[type_FuncallableInstanceHeader] = scav_closure_header;
2094 scavtab[type_ByteCodeFunction] = scav_closure_header;
2095 scavtab[type_ByteCodeClosure] = scav_closure_header;
2096 scavtab[type_DylanFunctionHeader] = scav_closure_header;
2098 scavtab[type_ClosureHeader] = scav_boxed;
2099 scavtab[type_FuncallableInstanceHeader] = scav_boxed;
2100 scavtab[type_ByteCodeFunction] = scav_boxed;
2101 scavtab[type_ByteCodeClosure] = scav_boxed;
2102 #ifdef type_DylanFunctionHeader
2103 scavtab[type_DylanFunctionHeader] = scav_boxed;
2106 scavtab[type_ValueCellHeader] = scav_boxed;
2107 scavtab[type_SymbolHeader] = scav_boxed;
2108 scavtab[type_BaseChar] = scav_immediate;
2109 scavtab[type_Sap] = scav_unboxed;
2110 scavtab[type_UnboundMarker] = scav_immediate;
2111 scavtab[type_WeakPointer] = scav_weak_pointer;
2112 scavtab[type_InstanceHeader] = scav_boxed;
2113 #if !(defined(sparc) || defined(DARWIN))
2114 scavtab[type_Fdefn] = scav_fdefn;
2116 scavtab[type_Fdefn] = scav_boxed;
2119 /* Transport Other Table */
2120 for (i = 0; i < 256; i++)
2121 transother[i] = trans_lose;
2123 transother[type_Bignum] = trans_unboxed;
2124 transother[type_Ratio] = trans_boxed;
2125 transother[type_SingleFloat] = trans_unboxed;
2126 transother[type_DoubleFloat] = trans_unboxed;
2127 #ifdef type_LongFloat
2128 transother[type_LongFloat] = trans_unboxed;
2130 #ifdef type_DoubleDoubleFloat
2131 transother[type_DoubleDoubleFloat] = trans_unboxed;
2133 transother[type_Complex] = trans_boxed;
2134 #ifdef type_ComplexSingleFloat
2135 transother[type_ComplexSingleFloat] = trans_unboxed;
2137 #ifdef type_ComplexDoubleFloat
2138 transother[type_ComplexDoubleFloat] = trans_unboxed;
2140 #ifdef type_ComplexLongFloat
2141 transother[type_ComplexLongFloat] = trans_unboxed;
2143 #ifdef type_ComplexDoubleDoubleFloat
2144 transother[type_ComplexDoubleDoubleFloat] = trans_unboxed;
2146 transother[type_SimpleArray] = trans_boxed;
2147 transother[type_SimpleString] = trans_string;
2148 transother[type_SimpleBitVector] = trans_vector_bit;
2149 transother[type_SimpleVector] = trans_vector;
2150 transother[type_SimpleArrayUnsignedByte2] = trans_vector_unsigned_byte_2;
2151 transother[type_SimpleArrayUnsignedByte4] = trans_vector_unsigned_byte_4;
2152 transother[type_SimpleArrayUnsignedByte8] = trans_vector_unsigned_byte_8;
2153 transother[type_SimpleArrayUnsignedByte16] = trans_vector_unsigned_byte_16;
2154 transother[type_SimpleArrayUnsignedByte32] = trans_vector_unsigned_byte_32;
2155 #ifdef type_SimpleArraySignedByte8
2156 transother[type_SimpleArraySignedByte8] = trans_vector_unsigned_byte_8;
2158 #ifdef type_SimpleArraySignedByte16
2159 transother[type_SimpleArraySignedByte16] = trans_vector_unsigned_byte_16;
2161 #ifdef type_SimpleArraySignedByte30
2162 transother[type_SimpleArraySignedByte30] = trans_vector_unsigned_byte_32;
2164 #ifdef type_SimpleArraySignedByte32
2165 transother[type_SimpleArraySignedByte32] = trans_vector_unsigned_byte_32;
2167 transother[type_SimpleArraySingleFloat] = trans_vector_single_float;
2168 transother[type_SimpleArrayDoubleFloat] = trans_vector_double_float;
2169 #ifdef type_SimpleArrayLongFloat
2170 transother[type_SimpleArrayLongFloat] = trans_vector_long_float;
2172 #ifdef type_SimpleArrayDoubleDoubleFloat
2173 transother[type_SimpleArrayDoubleDoubleFloat] = trans_vector_double_double_float;
2175 #ifdef type_SimpleArrayComplexSingleFloat
2176 transother[type_SimpleArrayComplexSingleFloat] =
2177 trans_vector_complex_single_float;
2179 #ifdef type_SimpleArrayComplexDoubleFloat
2180 transother[type_SimpleArrayComplexDoubleFloat] =
2181 trans_vector_complex_double_float;
2183 #ifdef type_SimpleArrayComplexLongFloat
2184 transother[type_SimpleArrayComplexLongFloat] =
2185 trans_vector_complex_long_float;
2187 #ifdef type_SimpleArrayComplexDoubleDoubleFloat
2188 transother[type_SimpleArrayComplexDoubleDoubleFloat] =
2189 trans_vector_complex_double_double_float;
2191 transother[type_ComplexString] = trans_boxed;
2192 transother[type_ComplexBitVector] = trans_boxed;
2193 transother[type_ComplexVector] = trans_boxed;
2194 transother[type_ComplexArray] = trans_boxed;
2195 transother[type_CodeHeader] = trans_code_header;
2196 transother[type_FunctionHeader] = trans_function_header;
2197 transother[type_ClosureFunctionHeader] = trans_function_header;
2198 transother[type_ReturnPcHeader] = trans_return_pc_header;
2199 transother[type_ClosureHeader] = trans_boxed;
2200 transother[type_FuncallableInstanceHeader] = trans_boxed;
2201 transother[type_ByteCodeFunction] = trans_boxed;
2202 transother[type_ByteCodeClosure] = trans_boxed;
2203 transother[type_ValueCellHeader] = trans_boxed;
2204 transother[type_SymbolHeader] = trans_boxed;
2205 transother[type_BaseChar] = trans_immediate;
2206 transother[type_Sap] = trans_unboxed;
2207 transother[type_UnboundMarker] = trans_immediate;
2208 transother[type_WeakPointer] = trans_weak_pointer;
2209 transother[type_InstanceHeader] = trans_boxed;
2210 transother[type_Fdefn] = trans_boxed;
2214 for (i = 0; i < 256; i++)
2215 sizetab[i] = size_lose;
2217 for (i = 0; i < 32; i++) {
2218 sizetab[type_EvenFixnum | (i << 3)] = size_immediate;
2219 sizetab[type_FunctionPointer | (i << 3)] = size_pointer;
2220 /* OtherImmediate0 */
2221 sizetab[type_ListPointer | (i << 3)] = size_pointer;
2222 sizetab[type_OddFixnum | (i << 3)] = size_immediate;
2223 sizetab[type_InstancePointer | (i << 3)] = size_pointer;
2224 /* OtherImmediate1 */
2225 sizetab[type_OtherPointer | (i << 3)] = size_pointer;
2228 sizetab[type_Bignum] = size_unboxed;
2229 sizetab[type_Ratio] = size_boxed;
2230 sizetab[type_SingleFloat] = size_unboxed;
2231 sizetab[type_DoubleFloat] = size_unboxed;
2232 #ifdef type_LongFloat
2233 sizetab[type_LongFloat] = size_unboxed;
2235 #ifdef type_DoubleDoubleFloat
2236 sizetab[type_DoubleDoubleFloat] = size_unboxed;
2238 sizetab[type_Complex] = size_boxed;
2239 #ifdef type_ComplexSingleFloat
2240 sizetab[type_ComplexSingleFloat] = size_unboxed;
2242 #ifdef type_ComplexDoubleFloat
2243 sizetab[type_ComplexDoubleFloat] = size_unboxed;
2245 #ifdef type_ComplexLongFloat
2246 sizetab[type_ComplexLongFloat] = size_unboxed;
2248 #ifdef type_ComplexDoubleDoubleFloat
2249 sizetab[type_ComplexDoubleDoubleFloat] = size_unboxed;
2251 sizetab[type_SimpleArray] = size_boxed;
2252 sizetab[type_SimpleString] = size_string;
2253 sizetab[type_SimpleBitVector] = size_vector_bit;
2254 sizetab[type_SimpleVector] = size_vector;
2255 sizetab[type_SimpleArrayUnsignedByte2] = size_vector_unsigned_byte_2;
2256 sizetab[type_SimpleArrayUnsignedByte4] = size_vector_unsigned_byte_4;
2257 sizetab[type_SimpleArrayUnsignedByte8] = size_vector_unsigned_byte_8;
2258 sizetab[type_SimpleArrayUnsignedByte16] = size_vector_unsigned_byte_16;
2259 sizetab[type_SimpleArrayUnsignedByte32] = size_vector_unsigned_byte_32;
2260 #ifdef type_SimpleArraySignedByte8
2261 sizetab[type_SimpleArraySignedByte8] = size_vector_unsigned_byte_8;
2263 #ifdef type_SimpleArraySignedByte16
2264 sizetab[type_SimpleArraySignedByte16] = size_vector_unsigned_byte_16;
2266 #ifdef type_SimpleArraySignedByte30
2267 sizetab[type_SimpleArraySignedByte30] = size_vector_unsigned_byte_32;
2269 #ifdef type_SimpleArraySignedByte32
2270 sizetab[type_SimpleArraySignedByte32] = size_vector_unsigned_byte_32;
2272 sizetab[type_SimpleArraySingleFloat] = size_vector_single_float;
2273 sizetab[type_SimpleArrayDoubleFloat] = size_vector_double_float;
2274 #ifdef type_SimpleArrayLongFloat
2275 sizetab[type_SimpleArrayLongFloat] = size_vector_long_float;
2277 #ifdef type_SimpleArrayDoubleDoubleFloat
2278 sizetab[type_SimpleArrayDoubleDoubleFloat] = size_vector_double_double_float;
2280 #ifdef type_SimpleArrayComplexSingleFloat
2281 sizetab[type_SimpleArrayComplexSingleFloat] =
2282 size_vector_complex_single_float;
2284 #ifdef type_SimpleArrayComplexDoubleFloat
2285 sizetab[type_SimpleArrayComplexDoubleFloat] =
2286 size_vector_complex_double_float;
2288 #ifdef type_SimpleArrayComplexLongFloat
2289 sizetab[type_SimpleArrayComplexLongFloat] = size_vector_complex_long_float;
2291 #ifdef type_SimpleArrayComplexDoubleDoubleFloat
2292 sizetab[type_SimpleArrayComplexDoubleDoubleFloat] =
2293 size_vector_complex_double_double_float;
2295 sizetab[type_ComplexString] = size_boxed;
2296 sizetab[type_ComplexBitVector] = size_boxed;
2297 sizetab[type_ComplexVector] = size_boxed;
2298 sizetab[type_ComplexArray] = size_boxed;
2299 sizetab[type_CodeHeader] = size_code_header;
2301 /* Shouldn't see these so just lose if it happens */
2302 sizetab[type_FunctionHeader] = size_function_header;
2303 sizetab[type_ClosureFunctionHeader] = size_function_header;
2304 sizetab[type_ReturnPcHeader] = size_return_pc_header;
2306 sizetab[type_ClosureHeader] = size_boxed;
2307 sizetab[type_FuncallableInstanceHeader] = size_boxed;
2308 sizetab[type_ValueCellHeader] = size_boxed;
2309 sizetab[type_SymbolHeader] = size_boxed;
2310 sizetab[type_BaseChar] = size_immediate;
2311 sizetab[type_Sap] = size_unboxed;
2312 sizetab[type_UnboundMarker] = size_immediate;
2313 sizetab[type_WeakPointer] = size_weak_pointer;
2314 sizetab[type_InstanceHeader] = size_boxed;
2315 sizetab[type_Fdefn] = size_boxed;
2320 /* Noise to manipulate the gc trigger stuff. */
2325 set_auto_gc_trigger(os_vm_size_t dynamic_usage)
2327 os_vm_address_t addr = (os_vm_address_t) current_dynamic_space +
2332 dynamic_space_size + (os_vm_address_t) current_dynamic_space - addr;
2334 if (addr < (os_vm_address_t) current_dynamic_space_free_pointer) {
2336 "set_auto_gc_trigger: tried to set gc trigger too low! (%d < %d)\n",
2338 (os_vm_address_t) current_dynamic_space_free_pointer
2339 - (os_vm_address_t) current_dynamic_space);
2341 } else if (length < 0) {
2343 "set_auto_gc_trigger: tried to set gc trigger too high! (%d)\n",
2348 addr = os_round_up_to_page(addr);
2349 length = os_trunc_size_to_page(length);
2351 #if defined(SUNOS) || defined(SOLARIS)
2352 os_invalidate(addr, length);
2354 os_protect(addr, length, 0);
2357 current_auto_gc_trigger = (lispobj *) addr;
2360 fprintf(stderr, "current_auto_gc_trigger set to %p\n",
2361 current_auto_gc_trigger);
2367 clear_auto_gc_trigger(void)
2369 if (current_auto_gc_trigger != NULL) {
2370 #if defined(SUNOS) || defined(SOLARIS) /* don't want to force whole space into swapping mode... */
2371 os_vm_address_t addr = (os_vm_address_t) current_auto_gc_trigger;
2372 os_vm_size_t length =
2373 dynamic_space_size + (os_vm_address_t) current_dynamic_space - addr;
2375 os_validate(addr, length);
2377 os_protect((os_vm_address_t) current_dynamic_space,
2378 dynamic_space_size, OS_VM_PROT_ALL);
2381 current_auto_gc_trigger = NULL;