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);
640 scav_function_pointer(lispobj *where, lispobj object)
642 lispobj *first_pointer;
647 gc_assert(Pointerp(object));
649 /* object is a pointer into from space. Not a FP */
650 first_pointer = (lispobj *) PTR(object);
651 first = *first_pointer;
653 /* must transport object -- object may point */
654 /* to either a function header, a closure */
655 /* function header, or to a closure header. */
657 type = TypeOf(first);
659 case type_FunctionHeader:
660 case type_ClosureFunctionHeader:
661 copy = trans_function_header(object);
664 copy = trans_boxed(object);
668 first = *first_pointer = copy;
670 gc_assert(Pointerp(first));
671 gc_assert(!from_space_p(first));
678 trans_code(struct code *code)
680 struct code *new_code;
681 lispobj first, l_code, l_new_code;
682 int nheader_words, ncode_words, nwords;
683 unsigned long displacement;
684 lispobj fheaderl, *prev_pointer;
686 #if defined(DEBUG_CODE_GC)
687 printf("\nTransporting code object located at 0x%08x.\n",
688 (unsigned long) code);
691 /* if object has already been transported, just return pointer */
692 first = code->header;
693 if (Pointerp(first) && new_space_p(first)) {
695 printf("Was already transported\n");
697 return (struct code *) PTR(first);
700 gc_assert(TypeOf(first) == type_CodeHeader);
702 /* prepare to transport the code vector */
703 l_code = (lispobj) LOW_WORD(code) | type_OtherPointer;
705 ncode_words = fixnum_value(code->code_size);
706 nheader_words = HeaderValue(code->header);
707 nwords = ncode_words + nheader_words;
708 nwords = CEILING(nwords, 2);
710 l_new_code = copy_object(l_code, nwords);
711 new_code = (struct code *) PTR(l_new_code);
713 displacement = l_new_code - l_code;
715 #if defined(DEBUG_CODE_GC)
716 printf("Old code object at 0x%08x, new code object at 0x%08x.\n",
717 (unsigned long) code, (unsigned long) new_code);
718 printf("Code object is %d words long.\n", nwords);
721 /* set forwarding pointer */
722 code->header = l_new_code;
724 /* set forwarding pointers for all the function headers in the */
725 /* code object. also fix all self pointers */
727 fheaderl = code->entry_points;
728 prev_pointer = &new_code->entry_points;
730 while (fheaderl != NIL) {
731 struct function *fheaderp, *nfheaderp;
734 fheaderp = (struct function *) PTR(fheaderl);
735 gc_assert(TypeOf(fheaderp->header) == type_FunctionHeader);
737 /* calcuate the new function pointer and the new */
738 /* function header */
739 nfheaderl = fheaderl + displacement;
740 nfheaderp = (struct function *) PTR(nfheaderl);
742 /* set forwarding pointer */
744 printf("fheaderp->header (at %x) <- %x\n",
745 &(fheaderp->header) , nfheaderl);
747 fheaderp->header = nfheaderl;
749 /* fix self pointer */
750 nfheaderp->self = nfheaderl;
752 *prev_pointer = nfheaderl;
754 fheaderl = fheaderp->next;
755 prev_pointer = &nfheaderp->next;
759 os_flush_icache((os_vm_address_t) (((int *)new_code) + nheader_words),
760 ncode_words * sizeof(int));
766 scav_code_header(lispobj *where, lispobj object)
769 int nheader_words, ncode_words, nwords;
771 struct function *fheaderp;
773 code = (struct code *) where;
774 ncode_words = fixnum_value(code->code_size);
775 nheader_words = HeaderValue(object);
776 nwords = ncode_words + nheader_words;
777 nwords = CEILING(nwords, 2);
779 #if defined(DEBUG_CODE_GC)
780 printf("\nScavening code object at 0x%08x.\n",
781 (unsigned long) where);
782 printf("Code object is %d words long.\n", nwords);
783 printf("Scavenging boxed section of code data block (%d words).\n",
787 /* Scavenge the boxed section of the code data block */
788 scavenge(where + 1, nheader_words - 1);
790 /* Scavenge the boxed section of each function object in the */
791 /* code data block */
792 fheaderl = code->entry_points;
793 while (fheaderl != NIL) {
794 fheaderp = (struct function *) PTR(fheaderl);
795 gc_assert(TypeOf(fheaderp->header) == type_FunctionHeader);
797 #if defined(DEBUG_CODE_GC)
798 printf("Scavenging boxed section of entry point located at 0x%08x.\n",
799 (unsigned long) PTR(fheaderl));
801 scavenge(&fheaderp->name, 1);
802 scavenge(&fheaderp->arglist, 1);
803 scavenge(&fheaderp->type, 1);
805 fheaderl = fheaderp->next;
812 trans_code_header(lispobj object)
816 ncode = trans_code((struct code *) PTR(object));
817 return (lispobj) LOW_WORD(ncode) | type_OtherPointer;
821 size_code_header(lispobj *where)
824 int nheader_words, ncode_words, nwords;
826 code = (struct code *) where;
828 ncode_words = fixnum_value(code->code_size);
829 nheader_words = HeaderValue(code->header);
830 nwords = ncode_words + nheader_words;
831 nwords = CEILING(nwords, 2);
838 scav_return_pc_header(lispobj *where, lispobj object)
840 fprintf(stderr, "GC lossage. Should not be scavenging a ");
841 fprintf(stderr, "Return PC Header.\n");
842 fprintf(stderr, "where = 0x%p, object = 0x%x", where, object);
848 trans_return_pc_header(lispobj object)
850 struct function *return_pc;
851 unsigned long offset;
852 struct code *code, *ncode;
854 return_pc = (struct function *) PTR(object);
855 offset = HeaderValue(return_pc->header) * 4 ;
857 /* Transport the whole code object */
858 code = (struct code *) ((unsigned long) return_pc - offset);
860 printf("trans_return_pc_header object=%x, code=%lx\n",object,code);
862 ncode = trans_code(code);
863 if(object==0x304748d7) {
866 ret= ((lispobj) LOW_WORD(ncode) + offset) | type_OtherPointer;
868 printf("trans_return_pc_header returning %x\n",ret);
873 /* On the 386, closures hold a pointer to the raw address instead of
874 * the function object, so we can use CALL [$FDEFN+const] to invoke
875 * the function without loading it into a register. Given that code
876 * objects don't move, we don't need to update anything, but we do
877 * have to figure out that the function is still live. */
880 scav_closure_header(where, object)
881 lispobj *where, object;
883 struct closure *closure;
886 closure = (struct closure *)where;
887 fun = closure->function - RAW_ADDR_OFFSET;
895 scav_function_header(lispobj *where, lispobj object)
897 fprintf(stderr, "GC lossage. Should not be scavenging a ");
898 fprintf(stderr, "Function Header.\n");
899 fprintf(stderr, "where = 0x%p, object = 0x%08x",
900 where, (unsigned int) object);
906 trans_function_header(lispobj object)
908 struct function *fheader;
909 unsigned long offset;
910 struct code *code, *ncode;
912 fheader = (struct function *) PTR(object);
913 offset = HeaderValue(fheader->header) * 4;
915 /* Transport the whole code object */
916 code = (struct code *) ((unsigned long) fheader - offset);
917 ncode = trans_code(code);
919 return ((lispobj) LOW_WORD(ncode) + offset) | type_FunctionPointer;
927 scav_instance_pointer(lispobj *where, lispobj object)
929 lispobj *first_pointer;
931 /* object is a pointer into from space. Not a FP */
932 first_pointer = (lispobj *) PTR(object);
934 *where = *first_pointer = trans_boxed(object);
939 /* lists and conses */
941 static lispobj trans_list(lispobj object);
944 scav_list_pointer(lispobj *where, lispobj object)
946 lispobj first, *first_pointer;
948 gc_assert(Pointerp(object));
950 /* object is a pointer into from space. Not a FP. */
951 first_pointer = (lispobj *) PTR(object);
953 first = *first_pointer = trans_list(object);
955 gc_assert(Pointerp(first));
956 gc_assert(!from_space_p(first));
963 trans_list(lispobj object)
965 lispobj new_list_pointer;
966 struct cons *cons, *new_cons;
968 cons = (struct cons *) PTR(object);
970 /* ### Don't use copy_object here. */
971 new_list_pointer = copy_object(object, 2);
972 new_cons = (struct cons *) PTR(new_list_pointer);
974 /* Set forwarding pointer. */
975 cons->car = new_list_pointer;
977 /* Try to linearize the list in the cdr direction to help reduce */
981 lispobj cdr, new_cdr, first;
982 struct cons *cdr_cons, *new_cdr_cons;
986 if (LowtagOf(cdr) != type_ListPointer ||
987 !from_space_p(cdr) ||
988 (Pointerp(first = *(lispobj *)PTR(cdr)) &&
992 cdr_cons = (struct cons *) PTR(cdr);
994 /* ### Don't use copy_object here */
995 new_cdr = copy_object(cdr, 2);
996 new_cdr_cons = (struct cons *) PTR(new_cdr);
998 /* Set forwarding pointer */
999 cdr_cons->car = new_cdr;
1001 /* Update the cdr of the last cons copied into new */
1002 /* space to keep the newspace scavenge from having to */
1004 new_cons->cdr = new_cdr;
1007 new_cons = new_cdr_cons;
1010 return new_list_pointer;
1014 /* scavenging and transporting other pointers */
1017 scav_other_pointer(lispobj *where, lispobj object)
1019 lispobj first, *first_pointer;
1021 gc_assert(Pointerp(object));
1023 /* Object is a pointer into from space - not a FP */
1024 first_pointer = (lispobj *) PTR(object);
1025 first = *first_pointer = (transother[TypeOf(*first_pointer)])(object);
1027 gc_assert(Pointerp(first));
1028 gc_assert(!from_space_p(first));
1035 /* immediate, boxed, and unboxed objects */
1038 size_pointer(lispobj *where)
1044 scav_immediate(lispobj *where, lispobj object)
1050 trans_immediate(lispobj object)
1052 fprintf(stderr, "GC lossage. Trying to transport an immediate!?\n");
1058 size_immediate(lispobj *where)
1065 scav_boxed(lispobj *where, lispobj object)
1071 trans_boxed(lispobj object)
1074 unsigned long length;
1076 gc_assert(Pointerp(object));
1078 header = *((lispobj *) PTR(object));
1079 length = HeaderValue(header) + 1;
1080 length = CEILING(length, 2);
1082 return copy_object(object, length);
1086 size_boxed(lispobj *where)
1089 unsigned long length;
1092 length = HeaderValue(header) + 1;
1093 length = CEILING(length, 2);
1098 /* Note: on the sparc we don't have to do anything special for fdefns, */
1099 /* 'cause the raw-addr has a function lowtag. */
1102 scav_fdefn(lispobj *where, lispobj object)
1104 struct fdefn *fdefn;
1106 fdefn = (struct fdefn *)where;
1108 if ((char *)(fdefn->function + RAW_ADDR_OFFSET)
1109 == (char *)((unsigned long)(fdefn->raw_addr))) {
1110 scavenge(where + 1, sizeof(struct fdefn)/sizeof(lispobj) - 1);
1111 fdefn->raw_addr = (u32) ((char *) LOW_WORD(fdefn->function)) + RAW_ADDR_OFFSET;
1112 return sizeof(struct fdefn) / sizeof(lispobj);
1120 scav_unboxed(lispobj *where, lispobj object)
1122 unsigned long length;
1124 length = HeaderValue(object) + 1;
1125 length = CEILING(length, 2);
1131 trans_unboxed(lispobj object)
1134 unsigned long length;
1137 gc_assert(Pointerp(object));
1139 header = *((lispobj *) PTR(object));
1140 length = HeaderValue(header) + 1;
1141 length = CEILING(length, 2);
1143 return copy_object(object, length);
1147 size_unboxed(lispobj *where)
1150 unsigned long length;
1153 length = HeaderValue(header) + 1;
1154 length = CEILING(length, 2);
1160 /* vector-like objects */
1162 #define NWORDS(x,y) (CEILING((x),(y)) / (y))
1165 scav_string(lispobj *where, lispobj object)
1167 struct vector *vector;
1170 /* NOTE: Strings contain one more byte of data than the length */
1171 /* slot indicates. */
1173 vector = (struct vector *) where;
1174 length = fixnum_value(vector->length) + 1;
1175 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1181 trans_string(lispobj object)
1183 struct vector *vector;
1186 gc_assert(Pointerp(object));
1188 /* NOTE: Strings contain one more byte of data than the length */
1189 /* slot indicates. */
1191 vector = (struct vector *) PTR(object);
1192 length = fixnum_value(vector->length) + 1;
1193 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1195 return copy_object(object, nwords);
1199 size_string(lispobj *where)
1201 struct vector *vector;
1204 /* NOTE: Strings contain one more byte of data than the length */
1205 /* slot indicates. */
1207 vector = (struct vector *) where;
1208 length = fixnum_value(vector->length) + 1;
1209 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1215 scav_vector(lispobj *where, lispobj object)
1217 if (HeaderValue(object) == subtype_VectorValidHashing)
1218 *where = (subtype_VectorMustRehash<<type_Bits) | type_SimpleVector;
1225 trans_vector(lispobj object)
1227 struct vector *vector;
1230 gc_assert(Pointerp(object));
1232 vector = (struct vector *) PTR(object);
1234 length = fixnum_value(vector->length);
1235 nwords = CEILING(length + 2, 2);
1237 return copy_object(object, nwords);
1241 size_vector(lispobj *where)
1243 struct vector *vector;
1246 vector = (struct vector *) where;
1247 length = fixnum_value(vector->length);
1248 nwords = CEILING(length + 2, 2);
1255 scav_vector_bit(lispobj *where, lispobj object)
1257 struct vector *vector;
1260 vector = (struct vector *) where;
1261 length = fixnum_value(vector->length);
1262 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1268 trans_vector_bit(lispobj object)
1270 struct vector *vector;
1273 gc_assert(Pointerp(object));
1275 vector = (struct vector *) PTR(object);
1276 length = fixnum_value(vector->length);
1277 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1279 return copy_object(object, nwords);
1283 size_vector_bit(lispobj *where)
1285 struct vector *vector;
1288 vector = (struct vector *) where;
1289 length = fixnum_value(vector->length);
1290 nwords = CEILING(NWORDS(length, 32) + 2, 2);
1297 scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
1299 struct vector *vector;
1302 vector = (struct vector *) where;
1303 length = fixnum_value(vector->length);
1304 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1310 trans_vector_unsigned_byte_2(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, 16) + 2, 2);
1321 return copy_object(object, nwords);
1325 size_vector_unsigned_byte_2(lispobj *where)
1327 struct vector *vector;
1330 vector = (struct vector *) where;
1331 length = fixnum_value(vector->length);
1332 nwords = CEILING(NWORDS(length, 16) + 2, 2);
1339 scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
1341 struct vector *vector;
1344 vector = (struct vector *) where;
1345 length = fixnum_value(vector->length);
1346 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1352 trans_vector_unsigned_byte_4(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, 8) + 2, 2);
1363 return copy_object(object, nwords);
1367 size_vector_unsigned_byte_4(lispobj *where)
1369 struct vector *vector;
1372 vector = (struct vector *) where;
1373 length = fixnum_value(vector->length);
1374 nwords = CEILING(NWORDS(length, 8) + 2, 2);
1381 scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
1383 struct vector *vector;
1386 vector = (struct vector *) where;
1387 length = fixnum_value(vector->length);
1388 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1394 trans_vector_unsigned_byte_8(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, 4) + 2, 2);
1405 return copy_object(object, nwords);
1409 size_vector_unsigned_byte_8(lispobj *where)
1411 struct vector *vector;
1414 vector = (struct vector *) where;
1415 length = fixnum_value(vector->length);
1416 nwords = CEILING(NWORDS(length, 4) + 2, 2);
1423 scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
1425 struct vector *vector;
1428 vector = (struct vector *) where;
1429 length = fixnum_value(vector->length);
1430 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1436 trans_vector_unsigned_byte_16(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, 2) + 2, 2);
1447 return copy_object(object, nwords);
1451 size_vector_unsigned_byte_16(lispobj *where)
1453 struct vector *vector;
1456 vector = (struct vector *) where;
1457 length = fixnum_value(vector->length);
1458 nwords = CEILING(NWORDS(length, 2) + 2, 2);
1465 scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
1467 struct vector *vector;
1470 vector = (struct vector *) where;
1471 length = fixnum_value(vector->length);
1472 nwords = CEILING(length + 2, 2);
1478 trans_vector_unsigned_byte_32(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(length + 2, 2);
1489 return copy_object(object, nwords);
1493 size_vector_unsigned_byte_32(lispobj *where)
1495 struct vector *vector;
1498 vector = (struct vector *) where;
1499 length = fixnum_value(vector->length);
1500 nwords = CEILING(length + 2, 2);
1507 scav_vector_single_float(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_single_float(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_single_float(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_double_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, 2);
1562 trans_vector_double_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, 2);
1573 return copy_object(object, nwords);
1577 size_vector_double_float(lispobj *where)
1579 struct vector *vector;
1582 vector = (struct vector *) where;
1583 length = fixnum_value(vector->length);
1584 nwords = CEILING(length * 2 + 2, 2);
1590 #ifdef type_SimpleArrayLongFloat
1592 scav_vector_long_float(lispobj *where, lispobj object)
1594 struct vector *vector;
1597 vector = (struct vector *) where;
1598 length = fixnum_value(vector->length);
1600 nwords = CEILING(length * 4 + 2, 2);
1607 trans_vector_long_float(lispobj object)
1609 struct vector *vector;
1612 gc_assert(Pointerp(object));
1614 vector = (struct vector *) PTR(object);
1615 length = fixnum_value(vector->length);
1617 nwords = CEILING(length * 4 + 2, 2);
1620 return copy_object(object, nwords);
1624 size_vector_long_float(lispobj *where)
1626 struct vector *vector;
1629 vector = (struct vector *) where;
1630 length = fixnum_value(vector->length);
1632 nwords = CEILING(length * 4 + 2, 2);
1640 #ifdef type_SimpleArrayComplexSingleFloat
1642 scav_vector_complex_single_float(lispobj *where, lispobj object)
1644 struct vector *vector;
1647 vector = (struct vector *) where;
1648 length = fixnum_value(vector->length);
1649 nwords = CEILING(length * 2 + 2, 2);
1655 trans_vector_complex_single_float(lispobj object)
1657 struct vector *vector;
1660 gc_assert(Pointerp(object));
1662 vector = (struct vector *) PTR(object);
1663 length = fixnum_value(vector->length);
1664 nwords = CEILING(length * 2 + 2, 2);
1666 return copy_object(object, nwords);
1670 size_vector_complex_single_float(lispobj *where)
1672 struct vector *vector;
1675 vector = (struct vector *) where;
1676 length = fixnum_value(vector->length);
1677 nwords = CEILING(length * 2 + 2, 2);
1683 #ifdef type_SimpleArrayComplexDoubleFloat
1685 scav_vector_complex_double_float(lispobj *where, lispobj object)
1687 struct vector *vector;
1690 vector = (struct vector *) where;
1691 length = fixnum_value(vector->length);
1692 nwords = CEILING(length * 4 + 2, 2);
1698 trans_vector_complex_double_float(lispobj object)
1700 struct vector *vector;
1703 gc_assert(Pointerp(object));
1705 vector = (struct vector *) PTR(object);
1706 length = fixnum_value(vector->length);
1707 nwords = CEILING(length * 4 + 2, 2);
1709 return copy_object(object, nwords);
1713 size_vector_complex_double_float(lispobj *where)
1715 struct vector *vector;
1718 vector = (struct vector *) where;
1719 length = fixnum_value(vector->length);
1720 nwords = CEILING(length * 4 + 2, 2);
1726 #ifdef type_SimpleArrayComplexLongFloat
1728 scav_vector_complex_long_float(lispobj *where, lispobj object)
1730 struct vector *vector;
1733 vector = (struct vector *) where;
1734 length = fixnum_value(vector->length);
1736 nwords = CEILING(length * 8 + 2, 2);
1743 trans_vector_complex_long_float(lispobj object)
1745 struct vector *vector;
1748 gc_assert(Pointerp(object));
1750 vector = (struct vector *) PTR(object);
1751 length = fixnum_value(vector->length);
1753 nwords = CEILING(length * 8 + 2, 2);
1756 return copy_object(object, nwords);
1760 size_vector_complex_long_float(lispobj *where)
1762 struct vector *vector;
1765 vector = (struct vector *) where;
1766 length = fixnum_value(vector->length);
1768 nwords = CEILING(length * 8 + 2, 2);
1778 #define WEAK_POINTER_NWORDS \
1779 CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
1782 scav_weak_pointer(lispobj *where, lispobj object)
1784 /* Do not let GC scavenge the value slot of the weak pointer */
1785 /* (that is why it is a weak pointer). Note: we could use */
1786 /* the scav_unboxed method here. */
1788 return WEAK_POINTER_NWORDS;
1792 trans_weak_pointer(lispobj object)
1795 struct weak_pointer *wp;
1797 gc_assert(Pointerp(object));
1799 #if defined(DEBUG_WEAK)
1800 printf("Transporting weak pointer from 0x%08x\n", object);
1803 /* Need to remember where all the weak pointers are that have */
1804 /* been transported so they can be fixed up in a post-GC pass. */
1806 copy = copy_object(object, WEAK_POINTER_NWORDS);
1807 wp = (struct weak_pointer *) PTR(copy);
1810 /* Push the weak pointer onto the list of weak pointers. */
1811 wp->next = LOW_WORD(weak_pointers);
1818 size_weak_pointer(lispobj *where)
1820 return WEAK_POINTER_NWORDS;
1823 void scan_weak_pointers(void)
1825 struct weak_pointer *wp;
1827 for (wp = weak_pointers; wp != (struct weak_pointer *) NULL;
1828 wp = (struct weak_pointer *)((unsigned long)wp->next)) {
1830 lispobj first, *first_pointer;
1834 #if defined(DEBUG_WEAK)
1835 printf("Weak pointer at 0x%p\n", wp);
1836 printf("Value: 0x%08x\n", (unsigned int) value);
1839 if (!(Pointerp(value) && from_space_p(value)))
1842 /* Now, we need to check if the object has been */
1843 /* forwarded. If it has been, the weak pointer is */
1844 /* still good and needs to be updated. Otherwise, the */
1845 /* weak pointer needs to be nil'ed out. */
1847 first_pointer = (lispobj *) PTR(value);
1848 first = *first_pointer;
1850 #if defined(DEBUG_WEAK)
1851 printf("First: 0x%08x\n", (unsigned long) first);
1854 if (Pointerp(first) && new_space_p(first))
1865 /* initialization */
1868 scav_lose(lispobj *where, lispobj object)
1870 fprintf(stderr, "GC lossage. No scavenge function for object 0x%08x (at 0x%016lx)\n",
1871 (unsigned int) object, (unsigned long)where);
1877 trans_lose(lispobj object)
1879 fprintf(stderr, "GC lossage. No transport function for object 0x%08x\n",
1880 (unsigned int)object);
1886 size_lose(lispobj *where)
1888 fprintf(stderr, "Size lossage. No size function for object at 0x%p\n",
1890 fprintf(stderr, "First word of object: 0x%08x\n",
1895 /* KLUDGE: SBCL already has two GC implementations, and if someday the
1896 * precise generational GC is revived, it might have three. It would
1897 * be nice to share the scavtab[] data set up here, and perhaps other
1898 * things too, between all of them, rather than trying to maintain
1899 * multiple copies. -- WHN 2001-05-09 */
1905 /* scavenge table */
1906 for (i = 0; i < 256; i++)
1907 scavtab[i] = scav_lose;
1908 /* scavtab[i] = scav_immediate; */
1910 for (i = 0; i < 32; i++) {
1911 scavtab[type_EvenFixnum|(i<<3)] = scav_immediate;
1912 scavtab[type_FunctionPointer|(i<<3)] = scav_function_pointer;
1913 /* OtherImmediate0 */
1914 scavtab[type_ListPointer|(i<<3)] = scav_list_pointer;
1915 scavtab[type_OddFixnum|(i<<3)] = scav_immediate;
1916 scavtab[type_InstancePointer|(i<<3)] = scav_instance_pointer;
1917 /* OtherImmediate1 */
1918 scavtab[type_OtherPointer|(i<<3)] = scav_other_pointer;
1921 scavtab[type_Bignum] = scav_unboxed;
1922 scavtab[type_Ratio] = scav_boxed;
1923 scavtab[type_SingleFloat] = scav_unboxed;
1924 scavtab[type_DoubleFloat] = scav_unboxed;
1925 #ifdef type_LongFloat
1926 scavtab[type_LongFloat] = scav_unboxed;
1928 scavtab[type_Complex] = scav_boxed;
1929 #ifdef type_ComplexSingleFloat
1930 scavtab[type_ComplexSingleFloat] = scav_unboxed;
1932 #ifdef type_ComplexDoubleFloat
1933 scavtab[type_ComplexDoubleFloat] = scav_unboxed;
1935 #ifdef type_ComplexLongFloat
1936 scavtab[type_ComplexLongFloat] = scav_unboxed;
1938 scavtab[type_SimpleArray] = scav_boxed;
1939 scavtab[type_SimpleString] = scav_string;
1940 scavtab[type_SimpleBitVector] = scav_vector_bit;
1941 scavtab[type_SimpleVector] = scav_vector;
1942 scavtab[type_SimpleArrayUnsignedByte2] = scav_vector_unsigned_byte_2;
1943 scavtab[type_SimpleArrayUnsignedByte4] = scav_vector_unsigned_byte_4;
1944 scavtab[type_SimpleArrayUnsignedByte8] = scav_vector_unsigned_byte_8;
1945 scavtab[type_SimpleArrayUnsignedByte16] = scav_vector_unsigned_byte_16;
1946 scavtab[type_SimpleArrayUnsignedByte32] = scav_vector_unsigned_byte_32;
1947 #ifdef type_SimpleArraySignedByte8
1948 scavtab[type_SimpleArraySignedByte8] = scav_vector_unsigned_byte_8;
1950 #ifdef type_SimpleArraySignedByte16
1951 scavtab[type_SimpleArraySignedByte16] = scav_vector_unsigned_byte_16;
1953 #ifdef type_SimpleArraySignedByte30
1954 scavtab[type_SimpleArraySignedByte30] = scav_vector_unsigned_byte_32;
1956 #ifdef type_SimpleArraySignedByte32
1957 scavtab[type_SimpleArraySignedByte32] = scav_vector_unsigned_byte_32;
1959 scavtab[type_SimpleArraySingleFloat] = scav_vector_single_float;
1960 scavtab[type_SimpleArrayDoubleFloat] = scav_vector_double_float;
1961 #ifdef type_SimpleArrayLongFloat
1962 scavtab[type_SimpleArrayLongFloat] = scav_vector_long_float;
1964 #ifdef type_SimpleArrayComplexSingleFloat
1965 scavtab[type_SimpleArrayComplexSingleFloat] = scav_vector_complex_single_float;
1967 #ifdef type_SimpleArrayComplexDoubleFloat
1968 scavtab[type_SimpleArrayComplexDoubleFloat] = scav_vector_complex_double_float;
1970 #ifdef type_SimpleArrayComplexLongFloat
1971 scavtab[type_SimpleArrayComplexLongFloat] = scav_vector_complex_long_float;
1973 scavtab[type_ComplexString] = scav_boxed;
1974 scavtab[type_ComplexBitVector] = scav_boxed;
1975 scavtab[type_ComplexVector] = scav_boxed;
1976 scavtab[type_ComplexArray] = scav_boxed;
1977 scavtab[type_CodeHeader] = scav_code_header;
1978 scavtab[type_FunctionHeader] = scav_function_header;
1979 scavtab[type_ClosureFunctionHeader] = scav_function_header;
1980 scavtab[type_ReturnPcHeader] = scav_return_pc_header;
1982 scavtab[type_ClosureHeader] = scav_closure_header;
1983 scavtab[type_FuncallableInstanceHeader] = scav_closure_header;
1984 scavtab[type_ByteCodeFunction] = scav_closure_header;
1985 scavtab[type_ByteCodeClosure] = scav_closure_header;
1986 /* scavtab[type_DylanFunctionHeader] = scav_closure_header; */
1988 scavtab[type_ClosureHeader] = scav_boxed;
1989 scavtab[type_FuncallableInstanceHeader] = scav_boxed;
1990 scavtab[type_ByteCodeFunction] = scav_boxed;
1991 scavtab[type_ByteCodeClosure] = scav_boxed;
1992 /* scavtab[type_DylanFunctionHeader] = scav_boxed; */
1994 scavtab[type_ValueCellHeader] = scav_boxed;
1995 scavtab[type_SymbolHeader] = scav_boxed;
1996 scavtab[type_BaseChar] = scav_immediate;
1997 scavtab[type_Sap] = scav_unboxed;
1998 scavtab[type_UnboundMarker] = scav_immediate;
1999 scavtab[type_WeakPointer] = scav_weak_pointer;
2000 scavtab[type_InstanceHeader] = scav_boxed;
2002 scavtab[type_Fdefn] = scav_fdefn;
2004 scavtab[type_Fdefn] = scav_boxed;
2007 /* Transport Other Table */
2008 for (i = 0; i < 256; i++)
2009 transother[i] = trans_lose;
2011 transother[type_Bignum] = trans_unboxed;
2012 transother[type_Ratio] = trans_boxed;
2013 transother[type_SingleFloat] = trans_unboxed;
2014 transother[type_DoubleFloat] = trans_unboxed;
2015 #ifdef type_LongFloat
2016 transother[type_LongFloat] = trans_unboxed;
2018 transother[type_Complex] = trans_boxed;
2019 #ifdef type_ComplexSingleFloat
2020 transother[type_ComplexSingleFloat] = trans_unboxed;
2022 #ifdef type_ComplexDoubleFloat
2023 transother[type_ComplexDoubleFloat] = trans_unboxed;
2025 #ifdef type_ComplexLongFloat
2026 transother[type_ComplexLongFloat] = trans_unboxed;
2028 transother[type_SimpleArray] = trans_boxed;
2029 transother[type_SimpleString] = trans_string;
2030 transother[type_SimpleBitVector] = trans_vector_bit;
2031 transother[type_SimpleVector] = trans_vector;
2032 transother[type_SimpleArrayUnsignedByte2] = trans_vector_unsigned_byte_2;
2033 transother[type_SimpleArrayUnsignedByte4] = trans_vector_unsigned_byte_4;
2034 transother[type_SimpleArrayUnsignedByte8] = trans_vector_unsigned_byte_8;
2035 transother[type_SimpleArrayUnsignedByte16] = trans_vector_unsigned_byte_16;
2036 transother[type_SimpleArrayUnsignedByte32] = trans_vector_unsigned_byte_32;
2037 #ifdef type_SimpleArraySignedByte8
2038 transother[type_SimpleArraySignedByte8] = trans_vector_unsigned_byte_8;
2040 #ifdef type_SimpleArraySignedByte16
2041 transother[type_SimpleArraySignedByte16] = trans_vector_unsigned_byte_16;
2043 #ifdef type_SimpleArraySignedByte30
2044 transother[type_SimpleArraySignedByte30] = trans_vector_unsigned_byte_32;
2046 #ifdef type_SimpleArraySignedByte32
2047 transother[type_SimpleArraySignedByte32] = trans_vector_unsigned_byte_32;
2049 transother[type_SimpleArraySingleFloat] = trans_vector_single_float;
2050 transother[type_SimpleArrayDoubleFloat] = trans_vector_double_float;
2051 #ifdef type_SimpleArrayLongFloat
2052 transother[type_SimpleArrayLongFloat] = trans_vector_long_float;
2054 #ifdef type_SimpleArrayComplexSingleFloat
2055 transother[type_SimpleArrayComplexSingleFloat] = trans_vector_complex_single_float;
2057 #ifdef type_SimpleArrayComplexDoubleFloat
2058 transother[type_SimpleArrayComplexDoubleFloat] = trans_vector_complex_double_float;
2060 #ifdef type_SimpleArrayComplexLongFloat
2061 transother[type_SimpleArrayComplexLongFloat] = trans_vector_complex_long_float;
2063 transother[type_ComplexString] = trans_boxed;
2064 transother[type_ComplexBitVector] = trans_boxed;
2065 transother[type_ComplexVector] = trans_boxed;
2066 transother[type_ComplexArray] = trans_boxed;
2067 transother[type_CodeHeader] = trans_code_header;
2068 transother[type_FunctionHeader] = trans_function_header;
2069 transother[type_ClosureFunctionHeader] = trans_function_header;
2070 transother[type_ReturnPcHeader] = trans_return_pc_header;
2071 transother[type_ClosureHeader] = trans_boxed;
2072 transother[type_FuncallableInstanceHeader] = trans_boxed;
2073 transother[type_ByteCodeFunction] = trans_boxed;
2074 transother[type_ByteCodeClosure] = trans_boxed;
2075 transother[type_ValueCellHeader] = trans_boxed;
2076 transother[type_SymbolHeader] = trans_boxed;
2077 transother[type_BaseChar] = trans_immediate;
2078 transother[type_Sap] = trans_unboxed;
2079 transother[type_UnboundMarker] = trans_immediate;
2080 transother[type_WeakPointer] = trans_weak_pointer;
2081 transother[type_InstanceHeader] = trans_boxed;
2082 transother[type_Fdefn] = trans_boxed;
2086 for (i = 0; i < 256; i++)
2087 sizetab[i] = size_lose;
2089 for (i = 0; i < 32; i++) {
2090 sizetab[type_EvenFixnum|(i<<3)] = size_immediate;
2091 sizetab[type_FunctionPointer|(i<<3)] = size_pointer;
2092 /* OtherImmediate0 */
2093 sizetab[type_ListPointer|(i<<3)] = size_pointer;
2094 sizetab[type_OddFixnum|(i<<3)] = size_immediate;
2095 sizetab[type_InstancePointer|(i<<3)] = size_pointer;
2096 /* OtherImmediate1 */
2097 sizetab[type_OtherPointer|(i<<3)] = size_pointer;
2100 sizetab[type_Bignum] = size_unboxed;
2101 sizetab[type_Ratio] = size_boxed;
2102 sizetab[type_SingleFloat] = size_unboxed;
2103 sizetab[type_DoubleFloat] = size_unboxed;
2104 #ifdef type_LongFloat
2105 sizetab[type_LongFloat] = size_unboxed;
2107 sizetab[type_Complex] = size_boxed;
2108 #ifdef type_ComplexSingleFloat
2109 sizetab[type_ComplexSingleFloat] = size_unboxed;
2111 #ifdef type_ComplexDoubleFloat
2112 sizetab[type_ComplexDoubleFloat] = size_unboxed;
2114 #ifdef type_ComplexLongFloat
2115 sizetab[type_ComplexLongFloat] = size_unboxed;
2117 sizetab[type_SimpleArray] = size_boxed;
2118 sizetab[type_SimpleString] = size_string;
2119 sizetab[type_SimpleBitVector] = size_vector_bit;
2120 sizetab[type_SimpleVector] = size_vector;
2121 sizetab[type_SimpleArrayUnsignedByte2] = size_vector_unsigned_byte_2;
2122 sizetab[type_SimpleArrayUnsignedByte4] = size_vector_unsigned_byte_4;
2123 sizetab[type_SimpleArrayUnsignedByte8] = size_vector_unsigned_byte_8;
2124 sizetab[type_SimpleArrayUnsignedByte16] = size_vector_unsigned_byte_16;
2125 sizetab[type_SimpleArrayUnsignedByte32] = size_vector_unsigned_byte_32;
2126 #ifdef type_SimpleArraySignedByte8
2127 sizetab[type_SimpleArraySignedByte8] = size_vector_unsigned_byte_8;
2129 #ifdef type_SimpleArraySignedByte16
2130 sizetab[type_SimpleArraySignedByte16] = size_vector_unsigned_byte_16;
2132 #ifdef type_SimpleArraySignedByte30
2133 sizetab[type_SimpleArraySignedByte30] = size_vector_unsigned_byte_32;
2135 #ifdef type_SimpleArraySignedByte32
2136 sizetab[type_SimpleArraySignedByte32] = size_vector_unsigned_byte_32;
2138 sizetab[type_SimpleArraySingleFloat] = size_vector_single_float;
2139 sizetab[type_SimpleArrayDoubleFloat] = size_vector_double_float;
2140 #ifdef type_SimpleArrayLongFloat
2141 sizetab[type_SimpleArrayLongFloat] = size_vector_long_float;
2143 #ifdef type_SimpleArrayComplexSingleFloat
2144 sizetab[type_SimpleArrayComplexSingleFloat] = size_vector_complex_single_float;
2146 #ifdef type_SimpleArrayComplexDoubleFloat
2147 sizetab[type_SimpleArrayComplexDoubleFloat] = size_vector_complex_double_float;
2149 #ifdef type_SimpleArrayComplexLongFloat
2150 sizetab[type_SimpleArrayComplexLongFloat] = size_vector_complex_long_float;
2152 sizetab[type_ComplexString] = size_boxed;
2153 sizetab[type_ComplexBitVector] = size_boxed;
2154 sizetab[type_ComplexVector] = size_boxed;
2155 sizetab[type_ComplexArray] = size_boxed;
2156 sizetab[type_CodeHeader] = size_code_header;
2158 /* Shouldn't see these so just lose if it happens */
2159 sizetab[type_FunctionHeader] = size_function_header;
2160 sizetab[type_ClosureFunctionHeader] = size_function_header;
2161 sizetab[type_ReturnPcHeader] = size_return_pc_header;
2163 sizetab[type_ClosureHeader] = size_boxed;
2164 sizetab[type_FuncallableInstanceHeader] = size_boxed;
2165 sizetab[type_ValueCellHeader] = size_boxed;
2166 sizetab[type_SymbolHeader] = size_boxed;
2167 sizetab[type_BaseChar] = size_immediate;
2168 sizetab[type_Sap] = size_unboxed;
2169 sizetab[type_UnboundMarker] = size_immediate;
2170 sizetab[type_WeakPointer] = size_weak_pointer;
2171 sizetab[type_InstanceHeader] = size_boxed;
2172 sizetab[type_Fdefn] = size_boxed;
2175 /* noise to manipulate the gc trigger stuff */
2179 void set_auto_gc_trigger(os_vm_size_t dynamic_usage)
2181 os_vm_address_t addr=(os_vm_address_t)current_dynamic_space +
2184 DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr;
2186 if(addr < (os_vm_address_t)dynamic_space_free_pointer) {
2188 "set_auto_gc_trigger: tried to set gc trigger too low! (%d < %p)\n",
2189 (unsigned int)dynamic_usage,
2190 (os_vm_address_t)dynamic_space_free_pointer
2191 - (os_vm_address_t)current_dynamic_space);
2194 else if (length < 0) {
2196 "set_auto_gc_trigger: tried to set gc trigger too high! (%p)\n",
2201 addr=os_round_up_to_page(addr);
2202 length=os_trunc_size_to_page(length);
2204 #if defined(SUNOS) || defined(SOLARIS)
2205 os_invalidate(addr,length);
2207 os_protect(addr, length, 0);
2210 current_auto_gc_trigger = (lispobj *)addr;
2213 void clear_auto_gc_trigger(void)
2215 if(current_auto_gc_trigger!=NULL){
2216 #if defined(SUNOS) || defined(SOLARIS)/* don't want to force whole space into swapping mode... */
2217 os_vm_address_t addr=(os_vm_address_t)current_auto_gc_trigger;
2218 os_vm_size_t length=
2219 DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr;
2221 os_validate(addr,length);
2223 os_protect((os_vm_address_t)current_dynamic_space,
2228 current_auto_gc_trigger = NULL;