c4309e24405fc798c45526242209ccc738ba06b2
[sbcl.git] / src / runtime / purify.c
1 /*
2  * C-level stuff to implement Lisp-level PURIFY
3  */
4
5 /*
6  * This software is part of the SBCL system. See the README file for
7  * more information.
8  *
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.
14  */
15
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <stdlib.h>
19 #include <strings.h>
20 #if (defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_LINUX))
21 #include <sys/ptrace.h>
22 #include <linux/user.h>
23 #endif
24 #include <errno.h>
25
26 #include "runtime.h"
27 #include "os.h"
28 #include "sbcl.h"
29 #include "globals.h"
30 #include "validate.h"
31 #include "interrupt.h"
32 #include "purify.h"
33 #include "interr.h"
34 #include "gc.h"
35 #include "gc-internal.h"
36 #include "thread.h"
37 #include "genesis/primitive-objects.h"
38 #include "genesis/static-symbols.h"
39
40 #define PRINTNOISE
41
42 #if defined(__i386__)
43 /* again, what's so special about the x86 that this is differently
44  * visible there than on other platforms? -dan 20010125 
45  */
46 static lispobj *dynamic_space_free_pointer;
47 #endif
48 extern unsigned long bytes_consed_between_gcs;
49
50 #define gc_abort() \
51   lose("GC invariant lost, file \"%s\", line %d", __FILE__, __LINE__)
52
53 #if 1
54 #define gc_assert(ex) do { \
55         if (!(ex)) gc_abort(); \
56 } while (0)
57 #else
58 #define gc_assert(ex)
59 #endif
60
61 \f
62 /* These hold the original end of the read_only and static spaces so
63  * we can tell what are forwarding pointers. */
64
65 static lispobj *read_only_end, *static_end;
66
67 static lispobj *read_only_free, *static_free;
68
69 static lispobj *pscav(lispobj *addr, int nwords, boolean constant);
70
71 #define LATERBLOCKSIZE 1020
72 #define LATERMAXCOUNT 10
73
74 static struct
75 later {
76     struct later *next;
77     union {
78         lispobj *ptr;
79         int count;
80     } u[LATERBLOCKSIZE];
81 } *later_blocks = NULL;
82 static int later_count = 0;
83
84 #define CEILING(x,y) (((x) + ((y) - 1)) & (~((y) - 1)))
85 #define NWORDS(x,y) (CEILING((x),(y)) / (y))
86
87 /* FIXME: Shouldn't this be defined in sbcl.h?  See also notes in
88  * cheneygc.c */
89
90 #ifdef sparc
91 #define FUN_RAW_ADDR_OFFSET 0
92 #else
93 #define FUN_RAW_ADDR_OFFSET (6*sizeof(lispobj) - FUN_POINTER_LOWTAG)
94 #endif
95 \f
96 static boolean
97 forwarding_pointer_p(lispobj obj)
98 {
99     lispobj *ptr = native_pointer(obj);
100
101     return ((static_end <= ptr && ptr <= static_free) ||
102             (read_only_end <= ptr && ptr <= read_only_free));
103 }
104
105 static boolean
106 dynamic_pointer_p(lispobj ptr)
107 {
108 #ifndef __i386__
109     return (ptr >= (lispobj)current_dynamic_space
110             &&
111             ptr < (lispobj)dynamic_space_free_pointer);
112 #else
113     /* Be more conservative, and remember, this is a maybe. */
114     return (ptr >= (lispobj)DYNAMIC_SPACE_START
115             &&
116             ptr < (lispobj)dynamic_space_free_pointer);
117 #endif
118 }
119
120 \f
121 #ifdef __i386__
122
123 #ifdef LISP_FEATURE_GENCGC
124 /*
125  * enhanced x86/GENCGC stack scavenging by Douglas Crosher
126  *
127  * Scavenging the stack on the i386 is problematic due to conservative
128  * roots and raw return addresses. Here it is handled in two passes:
129  * the first pass runs before any objects are moved and tries to
130  * identify valid pointers and return address on the stack, the second
131  * pass scavenges these.
132  */
133
134 static unsigned pointer_filter_verbose = 0;
135
136 /* FIXME: This is substantially the same code as
137  * possibly_valid_dynamic_space_pointer in gencgc.c.  The only
138  * relevant difference seems to be that the gencgc code also checks
139  * for raw pointers into Code objects */
140
141 static int
142 valid_dynamic_space_pointer(lispobj *pointer, lispobj *start_addr)
143 {
144     /* If it's not a return address then it needs to be a valid Lisp
145      * pointer. */
146     if (!is_lisp_pointer((lispobj)pointer))
147         return 0;
148
149     /* Check that the object pointed to is consistent with the pointer
150      * low tag. */
151     switch (lowtag_of((lispobj)pointer)) {
152     case FUN_POINTER_LOWTAG:
153         /* Start_addr should be the enclosing code object, or a closure
154          * header. */
155         switch (widetag_of(*start_addr)) {
156         case CODE_HEADER_WIDETAG:
157             /* This case is probably caught above. */
158             break;
159         case CLOSURE_HEADER_WIDETAG:
160         case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
161             if ((int)pointer != ((int)start_addr+FUN_POINTER_LOWTAG)) {
162                 if (pointer_filter_verbose) {
163                     fprintf(stderr,"*Wf2: %x %x %x\n", (unsigned int) pointer, 
164                             (unsigned int) start_addr, *start_addr);
165                 }
166                 return 0;
167             }
168             break;
169         default:
170             if (pointer_filter_verbose) {
171                 fprintf(stderr,"*Wf3: %x %x %x\n", (unsigned int) pointer, 
172                         (unsigned int) start_addr, *start_addr);
173             }
174             return 0;
175         }
176         break;
177     case LIST_POINTER_LOWTAG:
178         if ((int)pointer != ((int)start_addr+LIST_POINTER_LOWTAG)) {
179             if (pointer_filter_verbose)
180                 fprintf(stderr,"*Wl1: %x %x %x\n", (unsigned int) pointer, 
181                         (unsigned int) start_addr, *start_addr);
182             return 0;
183         }
184         /* Is it plausible cons? */
185         if ((is_lisp_pointer(start_addr[0])
186             || ((start_addr[0] & 3) == 0) /* fixnum */
187             || (widetag_of(start_addr[0]) == BASE_CHAR_WIDETAG)
188             || (widetag_of(start_addr[0]) == UNBOUND_MARKER_WIDETAG))
189            && (is_lisp_pointer(start_addr[1])
190                || ((start_addr[1] & 3) == 0) /* fixnum */
191                || (widetag_of(start_addr[1]) == BASE_CHAR_WIDETAG)
192                || (widetag_of(start_addr[1]) == UNBOUND_MARKER_WIDETAG))) {
193             break;
194         } else {
195             if (pointer_filter_verbose) {
196                 fprintf(stderr,"*Wl2: %x %x %x\n", (unsigned int) pointer, 
197                         (unsigned int) start_addr, *start_addr);
198             }
199             return 0;
200         }
201     case INSTANCE_POINTER_LOWTAG:
202         if ((int)pointer != ((int)start_addr+INSTANCE_POINTER_LOWTAG)) {
203             if (pointer_filter_verbose) {
204                 fprintf(stderr,"*Wi1: %x %x %x\n", (unsigned int) pointer, 
205                         (unsigned int) start_addr, *start_addr);
206             }
207             return 0;
208         }
209         if (widetag_of(start_addr[0]) != INSTANCE_HEADER_WIDETAG) {
210             if (pointer_filter_verbose) {
211                 fprintf(stderr,"*Wi2: %x %x %x\n", (unsigned int) pointer, 
212                         (unsigned int) start_addr, *start_addr);
213             }
214             return 0;
215         }
216         break;
217     case OTHER_POINTER_LOWTAG:
218         if ((int)pointer != ((int)start_addr+OTHER_POINTER_LOWTAG)) {
219             if (pointer_filter_verbose) {
220                 fprintf(stderr,"*Wo1: %x %x %x\n", (unsigned int) pointer, 
221                         (unsigned int) start_addr, *start_addr);
222             }
223             return 0;
224         }
225         /* Is it plausible? Not a cons. XXX should check the headers. */
226         if (is_lisp_pointer(start_addr[0]) || ((start_addr[0] & 3) == 0)) {
227             if (pointer_filter_verbose) {
228                 fprintf(stderr,"*Wo2: %x %x %x\n", (unsigned int) pointer, 
229                         (unsigned int) start_addr, *start_addr);
230             }
231             return 0;
232         }
233         switch (widetag_of(start_addr[0])) {
234         case UNBOUND_MARKER_WIDETAG:
235         case BASE_CHAR_WIDETAG:
236             if (pointer_filter_verbose) {
237                 fprintf(stderr,"*Wo3: %x %x %x\n", (unsigned int) pointer, 
238                         (unsigned int) start_addr, *start_addr);
239             }
240             return 0;
241
242             /* only pointed to by function pointers? */
243         case CLOSURE_HEADER_WIDETAG:
244         case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
245             if (pointer_filter_verbose) {
246                 fprintf(stderr,"*Wo4: %x %x %x\n", (unsigned int) pointer, 
247                         (unsigned int) start_addr, *start_addr);
248             }
249             return 0;
250
251         case INSTANCE_HEADER_WIDETAG:
252             if (pointer_filter_verbose) {
253                 fprintf(stderr,"*Wo5: %x %x %x\n", (unsigned int) pointer, 
254                         (unsigned int) start_addr, *start_addr);
255             }
256             return 0;
257
258             /* the valid other immediate pointer objects */
259         case SIMPLE_VECTOR_WIDETAG:
260         case RATIO_WIDETAG:
261         case COMPLEX_WIDETAG:
262 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
263         case COMPLEX_SINGLE_FLOAT_WIDETAG:
264 #endif
265 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
266         case COMPLEX_DOUBLE_FLOAT_WIDETAG:
267 #endif
268 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
269         case COMPLEX_LONG_FLOAT_WIDETAG:
270 #endif
271         case SIMPLE_ARRAY_WIDETAG:
272         case COMPLEX_BASE_STRING_WIDETAG:
273         case COMPLEX_VECTOR_NIL_WIDETAG:
274         case COMPLEX_BIT_VECTOR_WIDETAG:
275         case COMPLEX_VECTOR_WIDETAG:
276         case COMPLEX_ARRAY_WIDETAG:
277         case VALUE_CELL_HEADER_WIDETAG:
278         case SYMBOL_HEADER_WIDETAG:
279         case FDEFN_WIDETAG:
280         case CODE_HEADER_WIDETAG:
281         case BIGNUM_WIDETAG:
282         case SINGLE_FLOAT_WIDETAG:
283         case DOUBLE_FLOAT_WIDETAG:
284 #ifdef LONG_FLOAT_WIDETAG
285         case LONG_FLOAT_WIDETAG:
286 #endif
287         case SIMPLE_ARRAY_NIL_WIDETAG:
288         case SIMPLE_BASE_STRING_WIDETAG:
289         case SIMPLE_BIT_VECTOR_WIDETAG:
290         case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
291         case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
292         case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
293         case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
294         case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
295 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
296         case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
297 #endif
298 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
299         case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
300 #endif
301 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
302         case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
303 #endif
304 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
305         case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
306 #endif
307         case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
308         case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
309 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
310         case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
311 #endif
312 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
313         case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
314 #endif
315 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
316         case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
317 #endif
318 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
319         case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
320 #endif
321         case SAP_WIDETAG:
322         case WEAK_POINTER_WIDETAG:
323             break;
324
325         default:
326             if (pointer_filter_verbose) {
327                 fprintf(stderr,"*Wo6: %x %x %x\n", (unsigned int) pointer, 
328                         (unsigned int) start_addr, *start_addr);
329             }
330             return 0;
331         }
332         break;
333     default:
334         if (pointer_filter_verbose) {
335             fprintf(stderr,"*W?: %x %x %x\n", (unsigned int) pointer, 
336                     (unsigned int) start_addr, *start_addr);
337         }
338         return 0;
339     }
340
341     /* looks good */
342     return 1;
343 }
344
345 #define MAX_STACK_POINTERS 256
346 lispobj *valid_stack_locations[MAX_STACK_POINTERS];
347 unsigned int num_valid_stack_locations;
348
349 #define MAX_STACK_RETURN_ADDRESSES 128
350 lispobj *valid_stack_ra_locations[MAX_STACK_RETURN_ADDRESSES];
351 lispobj *valid_stack_ra_code_objects[MAX_STACK_RETURN_ADDRESSES];
352 unsigned int num_valid_stack_ra_locations;
353
354 /* Identify valid stack slots. */
355 static void
356 setup_i386_stack_scav(lispobj *lowaddr, lispobj *base)
357 {
358     lispobj *sp = lowaddr;
359     num_valid_stack_locations = 0;
360     num_valid_stack_ra_locations = 0;
361     for (sp = lowaddr; sp < base; sp++) {
362         lispobj thing = *sp;
363         /* Find the object start address */
364         lispobj *start_addr = search_dynamic_space((void *)thing);
365         if (start_addr) {
366             /* We need to allow raw pointers into Code objects for
367              * return addresses. This will also pick up pointers to
368              * functions in code objects. */
369             if (widetag_of(*start_addr) == CODE_HEADER_WIDETAG) {
370                 /* FIXME asserting here is a really dumb thing to do.
371                  * If we've overflowed some arbitrary static limit, we
372                  * should just refuse to purify, instead of killing
373                  * the whole lisp session
374                  */
375                 gc_assert(num_valid_stack_ra_locations <
376                           MAX_STACK_RETURN_ADDRESSES);
377                 valid_stack_ra_locations[num_valid_stack_ra_locations] = sp;
378                 valid_stack_ra_code_objects[num_valid_stack_ra_locations++] =
379                     (lispobj *)((int)start_addr + OTHER_POINTER_LOWTAG);
380             } else {
381                 if (valid_dynamic_space_pointer((void *)thing, start_addr)) {
382                     gc_assert(num_valid_stack_locations < MAX_STACK_POINTERS);
383                     valid_stack_locations[num_valid_stack_locations++] = sp;
384                 }
385             }
386         }
387     }
388     if (pointer_filter_verbose) {
389         fprintf(stderr, "number of valid stack pointers = %d\n",
390                 num_valid_stack_locations);
391         fprintf(stderr, "number of stack return addresses = %d\n",
392                 num_valid_stack_ra_locations);
393     }
394 }
395
396 static void
397 pscav_i386_stack(void)
398 {
399     int i;
400
401     for (i = 0; i < num_valid_stack_locations; i++)
402         pscav(valid_stack_locations[i], 1, 0);
403
404     for (i = 0; i < num_valid_stack_ra_locations; i++) {
405         lispobj code_obj = (lispobj)valid_stack_ra_code_objects[i];
406         pscav(&code_obj, 1, 0);
407         if (pointer_filter_verbose) {
408             fprintf(stderr,"*C moved RA %x to %x; for code object %x to %x\n",
409                     *valid_stack_ra_locations[i],
410                     (int)(*valid_stack_ra_locations[i])
411                     - ((int)valid_stack_ra_code_objects[i] - (int)code_obj),
412                     (unsigned int) valid_stack_ra_code_objects[i], code_obj);
413         }
414         *valid_stack_ra_locations[i] =
415             ((int)(*valid_stack_ra_locations[i])
416              - ((int)valid_stack_ra_code_objects[i] - (int)code_obj));
417     }
418 }
419 #endif
420 #endif
421
422 \f
423 static void
424 pscav_later(lispobj *where, int count)
425 {
426     struct later *new;
427
428     if (count > LATERMAXCOUNT) {
429         while (count > LATERMAXCOUNT) {
430             pscav_later(where, LATERMAXCOUNT);
431             count -= LATERMAXCOUNT;
432             where += LATERMAXCOUNT;
433         }
434     }
435     else {
436         if (later_blocks == NULL || later_count == LATERBLOCKSIZE ||
437             (later_count == LATERBLOCKSIZE-1 && count > 1)) {
438             new  = (struct later *)malloc(sizeof(struct later));
439             new->next = later_blocks;
440             if (later_blocks && later_count < LATERBLOCKSIZE)
441                 later_blocks->u[later_count].ptr = NULL;
442             later_blocks = new;
443             later_count = 0;
444         }
445
446         if (count != 1)
447             later_blocks->u[later_count++].count = count;
448         later_blocks->u[later_count++].ptr = where;
449     }
450 }
451
452 static lispobj
453 ptrans_boxed(lispobj thing, lispobj header, boolean constant)
454 {
455     int nwords;
456     lispobj result, *new, *old;
457
458     nwords = 1 + HeaderValue(header);
459
460     /* Allocate it */
461     old = (lispobj *)native_pointer(thing);
462     if (constant) {
463         new = read_only_free;
464         read_only_free += CEILING(nwords, 2);
465     }
466     else {
467         new = static_free;
468         static_free += CEILING(nwords, 2);
469     }
470
471     /* Copy it. */
472     bcopy(old, new, nwords * sizeof(lispobj));
473
474     /* Deposit forwarding pointer. */
475     result = make_lispobj(new, lowtag_of(thing));
476     *old = result;
477
478     /* Scavenge it. */
479     pscav(new, nwords, constant);
480
481     return result;
482 }
483
484 /* We need to look at the layout to see whether it is a pure structure
485  * class, and only then can we transport as constant. If it is pure,
486  * we can ALWAYS transport as a constant. */
487 static lispobj
488 ptrans_instance(lispobj thing, lispobj header, boolean constant)
489 {
490     lispobj layout = ((struct instance *)native_pointer(thing))->slots[0];
491     lispobj pure = ((struct instance *)native_pointer(layout))->slots[15];
492
493     switch (pure) {
494     case T:
495         return (ptrans_boxed(thing, header, 1));
496     case NIL:
497         return (ptrans_boxed(thing, header, 0));
498     case 0:
499         {
500             /* Substructure: special case for the COMPACT-INFO-ENVs,
501              * where the instance may have a point to the dynamic
502              * space placed into it (e.g. the cache-name slot), but
503              * the lists and arrays at the time of a purify can be
504              * moved to the RO space. */
505             int nwords;
506             lispobj result, *new, *old;
507
508             nwords = 1 + HeaderValue(header);
509
510             /* Allocate it */
511             old = (lispobj *)native_pointer(thing);
512             new = static_free;
513             static_free += CEILING(nwords, 2);
514
515             /* Copy it. */
516             bcopy(old, new, nwords * sizeof(lispobj));
517
518             /* Deposit forwarding pointer. */
519             result = make_lispobj(new, lowtag_of(thing));
520             *old = result;
521
522             /* Scavenge it. */
523             pscav(new, nwords, 1);
524
525             return result;
526         }
527     default:
528         gc_abort();
529         return NIL; /* dummy value: return something ... */
530     }
531 }
532
533 static lispobj
534 ptrans_fdefn(lispobj thing, lispobj header)
535 {
536     int nwords;
537     lispobj result, *new, *old, oldfn;
538     struct fdefn *fdefn;
539
540     nwords = 1 + HeaderValue(header);
541
542     /* Allocate it */
543     old = (lispobj *)native_pointer(thing);
544     new = static_free;
545     static_free += CEILING(nwords, 2);
546
547     /* Copy it. */
548     bcopy(old, new, nwords * sizeof(lispobj));
549
550     /* Deposit forwarding pointer. */
551     result = make_lispobj(new, lowtag_of(thing));
552     *old = result;
553
554     /* Scavenge the function. */
555     fdefn = (struct fdefn *)new;
556     oldfn = fdefn->fun;
557     pscav(&fdefn->fun, 1, 0);
558     if ((char *)oldfn + FUN_RAW_ADDR_OFFSET == fdefn->raw_addr)
559         fdefn->raw_addr = (char *)fdefn->fun + FUN_RAW_ADDR_OFFSET;
560
561     return result;
562 }
563
564 static lispobj
565 ptrans_unboxed(lispobj thing, lispobj header)
566 {
567     int nwords;
568     lispobj result, *new, *old;
569     
570     nwords = 1 + HeaderValue(header);
571     
572     /* Allocate it */
573     old = (lispobj *)native_pointer(thing);
574     new = read_only_free;
575     read_only_free += CEILING(nwords, 2);
576     
577     /* Copy it. */
578     bcopy(old, new, nwords * sizeof(lispobj));
579     
580     /* Deposit forwarding pointer. */
581     result = make_lispobj(new , lowtag_of(thing));
582     *old = result;
583
584     return result;
585 }
586
587 static lispobj
588 ptrans_vector(lispobj thing, int bits, int extra,
589               boolean boxed, boolean constant)
590 {
591     struct vector *vector;
592     int nwords;
593     lispobj result, *new;
594
595     vector = (struct vector *)native_pointer(thing);
596     nwords = 2 + (CEILING((fixnum_value(vector->length)+extra)*bits,32)>>5);
597
598     if (boxed && !constant) {
599         new = static_free;
600         static_free += CEILING(nwords, 2);
601     }
602     else {
603         new = read_only_free;
604         read_only_free += CEILING(nwords, 2);
605     }
606
607     bcopy(vector, new, nwords * sizeof(lispobj));
608
609     result = make_lispobj(new, lowtag_of(thing));
610     vector->header = result;
611
612     if (boxed)
613         pscav(new, nwords, constant);
614
615     return result;
616 }
617
618 #ifdef __i386__
619 static void
620 apply_code_fixups_during_purify(struct code *old_code, struct code *new_code)
621 {
622     int nheader_words, ncode_words, nwords;
623     void  *constants_start_addr, *constants_end_addr;
624     void  *code_start_addr, *code_end_addr;
625     lispobj fixups = NIL;
626     unsigned  displacement = (unsigned)new_code - (unsigned)old_code;
627     struct vector *fixups_vector;
628
629     ncode_words = fixnum_value(new_code->code_size);
630     nheader_words = HeaderValue(*(lispobj *)new_code);
631     nwords = ncode_words + nheader_words;
632
633     constants_start_addr = (void *)new_code + 5*4;
634     constants_end_addr = (void *)new_code + nheader_words*4;
635     code_start_addr = (void *)new_code + nheader_words*4;
636     code_end_addr = (void *)new_code + nwords*4;
637
638     /* The first constant should be a pointer to the fixups for this
639      * code objects. Check. */
640     fixups = new_code->constants[0];
641
642     /* It will be 0 or the unbound-marker if there are no fixups, and
643      * will be an other-pointer to a vector if it is valid. */
644     if ((fixups==0) ||
645         (fixups==UNBOUND_MARKER_WIDETAG) ||
646         !is_lisp_pointer(fixups)) {
647 #ifdef LISP_FEATURE_GENCGC
648         /* Check for a possible errors. */
649         sniff_code_object(new_code,displacement);
650 #endif
651         return;
652     }
653
654     fixups_vector = (struct vector *)native_pointer(fixups);
655
656     /* Could be pointing to a forwarding pointer. */
657     if (is_lisp_pointer(fixups) && (dynamic_pointer_p(fixups))
658         && forwarding_pointer_p(*(lispobj *)fixups_vector)) {
659         /* If so then follow it. */
660         fixups_vector =
661             (struct vector *)native_pointer(*(lispobj *)fixups_vector);
662     }
663
664     if (widetag_of(fixups_vector->header) ==
665         SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG) {
666         /* We got the fixups for the code block. Now work through the
667          * vector, and apply a fixup at each address. */
668         int length = fixnum_value(fixups_vector->length);
669         int i;
670         for (i=0; i<length; i++) {
671             unsigned offset = fixups_vector->data[i];
672             /* Now check the current value of offset. */
673             unsigned old_value =
674                 *(unsigned *)((unsigned)code_start_addr + offset);
675
676             /* If it's within the old_code object then it must be an
677              * absolute fixup (relative ones are not saved) */
678             if ((old_value>=(unsigned)old_code)
679                 && (old_value<((unsigned)old_code + nwords*4)))
680                 /* So add the dispacement. */
681                 *(unsigned *)((unsigned)code_start_addr + offset) = old_value
682                     + displacement;
683             else
684                 /* It is outside the old code object so it must be a relative
685                  * fixup (absolute fixups are not saved). So subtract the
686                  * displacement. */
687                 *(unsigned *)((unsigned)code_start_addr + offset) = old_value
688                     - displacement;
689         }
690     }
691
692     /* No longer need the fixups. */
693     new_code->constants[0] = 0;
694
695 #ifdef LISP_FEATURE_GENCGC
696     /* Check for possible errors. */
697     sniff_code_object(new_code,displacement);
698 #endif
699 }
700 #endif
701
702 static lispobj
703 ptrans_code(lispobj thing)
704 {
705     struct code *code, *new;
706     int nwords;
707     lispobj func, result;
708
709     code = (struct code *)native_pointer(thing);
710     nwords = HeaderValue(code->header) + fixnum_value(code->code_size);
711
712     new = (struct code *)read_only_free;
713     read_only_free += CEILING(nwords, 2);
714
715     bcopy(code, new, nwords * sizeof(lispobj));
716
717 #ifdef LISP_FEATURE_X86
718     apply_code_fixups_during_purify(code,new);
719 #endif
720
721     result = make_lispobj(new, OTHER_POINTER_LOWTAG);
722
723     /* Stick in a forwarding pointer for the code object. */
724     *(lispobj *)code = result;
725
726     /* Put in forwarding pointers for all the functions. */
727     for (func = code->entry_points;
728          func != NIL;
729          func = ((struct simple_fun *)native_pointer(func))->next) {
730
731         gc_assert(lowtag_of(func) == FUN_POINTER_LOWTAG);
732
733         *(lispobj *)native_pointer(func) = result + (func - thing);
734     }
735
736     /* Arrange to scavenge the debug info later. */
737     pscav_later(&new->debug_info, 1);
738
739     if (new->trace_table_offset & 0x3)
740 #if 0
741       pscav(&new->trace_table_offset, 1, 0);
742 #else
743       new->trace_table_offset = NIL; /* limit lifetime */
744 #endif
745
746     /* Scavenge the constants. */
747     pscav(new->constants, HeaderValue(new->header)-5, 1);
748
749     /* Scavenge all the functions. */
750     pscav(&new->entry_points, 1, 1);
751     for (func = new->entry_points;
752          func != NIL;
753          func = ((struct simple_fun *)native_pointer(func))->next) {
754         gc_assert(lowtag_of(func) == FUN_POINTER_LOWTAG);
755         gc_assert(!dynamic_pointer_p(func));
756
757 #ifdef __i386__
758         /* Temporarly convert the self pointer to a real function pointer. */
759         ((struct simple_fun *)native_pointer(func))->self
760             -= FUN_RAW_ADDR_OFFSET;
761 #endif
762         pscav(&((struct simple_fun *)native_pointer(func))->self, 2, 1);
763 #ifdef __i386__
764         ((struct simple_fun *)native_pointer(func))->self
765             += FUN_RAW_ADDR_OFFSET;
766 #endif
767         pscav_later(&((struct simple_fun *)native_pointer(func))->name, 3);
768     }
769
770     return result;
771 }
772
773 static lispobj
774 ptrans_func(lispobj thing, lispobj header)
775 {
776     int nwords;
777     lispobj code, *new, *old, result;
778     struct simple_fun *function;
779
780     /* Thing can either be a function header, a closure function
781      * header, a closure, or a funcallable-instance. If it's a closure
782      * or a funcallable-instance, we do the same as ptrans_boxed.
783      * Otherwise we have to do something strange, 'cause it is buried
784      * inside a code object. */
785
786     if (widetag_of(header) == SIMPLE_FUN_HEADER_WIDETAG ||
787         widetag_of(header) == CLOSURE_FUN_HEADER_WIDETAG) {
788
789         /* We can only end up here if the code object has not been
790          * scavenged, because if it had been scavenged, forwarding pointers
791          * would have been left behind for all the entry points. */
792
793         function = (struct simple_fun *)native_pointer(thing);
794         code =
795             make_lispobj
796             ((native_pointer(thing) -
797               (HeaderValue(function->header))), OTHER_POINTER_LOWTAG);
798         
799         /* This will cause the function's header to be replaced with a 
800          * forwarding pointer. */
801
802         ptrans_code(code);
803
804         /* So we can just return that. */
805         return function->header;
806     }
807     else {
808         /* It's some kind of closure-like thing. */
809         nwords = 1 + HeaderValue(header);
810         old = (lispobj *)native_pointer(thing);
811
812         /* Allocate the new one. */
813         if (widetag_of(header) == FUNCALLABLE_INSTANCE_HEADER_WIDETAG) {
814             /* FINs *must* not go in read_only space. */
815             new = static_free;
816             static_free += CEILING(nwords, 2);
817         }
818         else {
819             /* Closures can always go in read-only space, 'cause they
820              * never change. */
821
822             new = read_only_free;
823             read_only_free += CEILING(nwords, 2);
824         }
825         /* Copy it. */
826         bcopy(old, new, nwords * sizeof(lispobj));
827
828         /* Deposit forwarding pointer. */
829         result = make_lispobj(new, lowtag_of(thing));
830         *old = result;
831
832         /* Scavenge it. */
833         pscav(new, nwords, 0);
834
835         return result;
836     }
837 }
838
839 static lispobj
840 ptrans_returnpc(lispobj thing, lispobj header)
841 {
842     lispobj code, new;
843
844     /* Find the corresponding code object. */
845     code = thing - HeaderValue(header)*sizeof(lispobj);
846
847     /* Make sure it's been transported. */
848     new = *(lispobj *)native_pointer(code);
849     if (!forwarding_pointer_p(new))
850         new = ptrans_code(code);
851
852     /* Maintain the offset: */
853     return new + (thing - code);
854 }
855
856 #define WORDS_PER_CONS CEILING(sizeof(struct cons) / sizeof(lispobj), 2)
857
858 static lispobj
859 ptrans_list(lispobj thing, boolean constant)
860 {
861     struct cons *old, *new, *orig;
862     int length;
863
864     if (constant)
865         orig = (struct cons *)read_only_free;
866     else
867         orig = (struct cons *)static_free;
868     length = 0;
869
870     do {
871         /* Allocate a new cons cell. */
872         old = (struct cons *)native_pointer(thing);
873         if (constant) {
874             new = (struct cons *)read_only_free;
875             read_only_free += WORDS_PER_CONS;
876         }
877         else {
878             new = (struct cons *)static_free;
879             static_free += WORDS_PER_CONS;
880         }
881
882         /* Copy the cons cell and keep a pointer to the cdr. */
883         new->car = old->car;
884         thing = new->cdr = old->cdr;
885
886         /* Set up the forwarding pointer. */
887         *(lispobj *)old = make_lispobj(new, LIST_POINTER_LOWTAG);
888
889         /* And count this cell. */
890         length++;
891     } while (lowtag_of(thing) == LIST_POINTER_LOWTAG &&
892              dynamic_pointer_p(thing) &&
893              !(forwarding_pointer_p(*(lispobj *)native_pointer(thing))));
894
895     /* Scavenge the list we just copied. */
896     pscav((lispobj *)orig, length * WORDS_PER_CONS, constant);
897
898     return make_lispobj(orig, LIST_POINTER_LOWTAG);
899 }
900
901 static lispobj
902 ptrans_otherptr(lispobj thing, lispobj header, boolean constant)
903 {
904     switch (widetag_of(header)) {
905         /* FIXME: this needs a reindent */
906       case BIGNUM_WIDETAG:
907       case SINGLE_FLOAT_WIDETAG:
908       case DOUBLE_FLOAT_WIDETAG:
909 #ifdef LONG_FLOAT_WIDETAG
910       case LONG_FLOAT_WIDETAG:
911 #endif
912 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
913       case COMPLEX_SINGLE_FLOAT_WIDETAG:
914 #endif
915 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
916       case COMPLEX_DOUBLE_FLOAT_WIDETAG:
917 #endif
918 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
919       case COMPLEX_LONG_FLOAT_WIDETAG:
920 #endif
921       case SAP_WIDETAG:
922           return ptrans_unboxed(thing, header);
923
924       case RATIO_WIDETAG:
925       case COMPLEX_WIDETAG:
926       case SIMPLE_ARRAY_WIDETAG:
927       case COMPLEX_BASE_STRING_WIDETAG:
928       case COMPLEX_BIT_VECTOR_WIDETAG:
929       case COMPLEX_VECTOR_NIL_WIDETAG:
930       case COMPLEX_VECTOR_WIDETAG:
931       case COMPLEX_ARRAY_WIDETAG:
932         return ptrans_boxed(thing, header, constant);
933         
934       case VALUE_CELL_HEADER_WIDETAG:
935       case WEAK_POINTER_WIDETAG:
936         return ptrans_boxed(thing, header, 0);
937
938       case SYMBOL_HEADER_WIDETAG:
939         return ptrans_boxed(thing, header, 0);
940
941       case SIMPLE_ARRAY_NIL_WIDETAG:
942         return ptrans_vector(thing, 0, 0, 0, constant);
943
944       case SIMPLE_BASE_STRING_WIDETAG:
945         return ptrans_vector(thing, 8, 1, 0, constant);
946
947       case SIMPLE_BIT_VECTOR_WIDETAG:
948         return ptrans_vector(thing, 1, 0, 0, constant);
949
950       case SIMPLE_VECTOR_WIDETAG:
951         return ptrans_vector(thing, 32, 0, 1, constant);
952
953       case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
954         return ptrans_vector(thing, 2, 0, 0, constant);
955
956       case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
957         return ptrans_vector(thing, 4, 0, 0, constant);
958
959       case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
960 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
961       case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
962 #endif
963         return ptrans_vector(thing, 8, 0, 0, constant);
964
965       case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
966 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
967       case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
968 #endif
969         return ptrans_vector(thing, 16, 0, 0, constant);
970
971       case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
972 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
973       case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
974 #endif
975 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
976       case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
977 #endif
978         return ptrans_vector(thing, 32, 0, 0, constant);
979
980       case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
981         return ptrans_vector(thing, 32, 0, 0, constant);
982
983       case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
984         return ptrans_vector(thing, 64, 0, 0, constant);
985
986 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
987       case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
988 #ifdef __i386__
989         return ptrans_vector(thing, 96, 0, 0, constant);
990 #endif
991 #ifdef sparc
992         return ptrans_vector(thing, 128, 0, 0, constant);
993 #endif
994 #endif
995
996 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
997       case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
998         return ptrans_vector(thing, 64, 0, 0, constant);
999 #endif
1000
1001 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1002       case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
1003         return ptrans_vector(thing, 128, 0, 0, constant);
1004 #endif
1005
1006 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1007       case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
1008 #ifdef __i386__
1009         return ptrans_vector(thing, 192, 0, 0, constant);
1010 #endif
1011 #ifdef sparc
1012         return ptrans_vector(thing, 256, 0, 0, constant);
1013 #endif
1014 #endif
1015
1016       case CODE_HEADER_WIDETAG:
1017         return ptrans_code(thing);
1018
1019       case RETURN_PC_HEADER_WIDETAG:
1020         return ptrans_returnpc(thing, header);
1021
1022       case FDEFN_WIDETAG:
1023         return ptrans_fdefn(thing, header);
1024
1025       default:
1026         /* Should only come across other pointers to the above stuff. */
1027         gc_abort();
1028         return NIL;
1029     }
1030 }
1031
1032 static int
1033 pscav_fdefn(struct fdefn *fdefn)
1034 {
1035     boolean fix_func;
1036
1037     fix_func = ((char *)(fdefn->fun+FUN_RAW_ADDR_OFFSET) == fdefn->raw_addr);
1038     pscav(&fdefn->name, 1, 1);
1039     pscav(&fdefn->fun, 1, 0);
1040     if (fix_func)
1041         fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET);
1042     return sizeof(struct fdefn) / sizeof(lispobj);
1043 }
1044
1045 #ifdef __i386__
1046 /* now putting code objects in static space */
1047 static int
1048 pscav_code(struct code*code)
1049 {
1050     int nwords;
1051     lispobj func;
1052     nwords = HeaderValue(code->header) + fixnum_value(code->code_size);
1053
1054     /* Arrange to scavenge the debug info later. */
1055     pscav_later(&code->debug_info, 1);
1056
1057     /* Scavenge the constants. */
1058     pscav(code->constants, HeaderValue(code->header)-5, 1);
1059
1060     /* Scavenge all the functions. */
1061     pscav(&code->entry_points, 1, 1);
1062     for (func = code->entry_points;
1063          func != NIL;
1064          func = ((struct simple_fun *)native_pointer(func))->next) {
1065         gc_assert(lowtag_of(func) == FUN_POINTER_LOWTAG);
1066         gc_assert(!dynamic_pointer_p(func));
1067
1068 #ifdef __i386__
1069         /* Temporarily convert the self pointer to a real function
1070          * pointer. */
1071         ((struct simple_fun *)native_pointer(func))->self
1072             -= FUN_RAW_ADDR_OFFSET;
1073 #endif
1074         pscav(&((struct simple_fun *)native_pointer(func))->self, 2, 1);
1075 #ifdef __i386__
1076         ((struct simple_fun *)native_pointer(func))->self
1077             += FUN_RAW_ADDR_OFFSET;
1078 #endif
1079         pscav_later(&((struct simple_fun *)native_pointer(func))->name, 3);
1080     }
1081
1082     return CEILING(nwords,2);
1083 }
1084 #endif
1085
1086 static lispobj *
1087 pscav(lispobj *addr, int nwords, boolean constant)
1088 {
1089     lispobj thing, *thingp, header;
1090     int count = 0; /* (0 = dummy init value to stop GCC warning) */
1091     struct vector *vector;
1092
1093     while (nwords > 0) {
1094         thing = *addr;
1095         if (is_lisp_pointer(thing)) {
1096             /* It's a pointer. Is it something we might have to move? */
1097             if (dynamic_pointer_p(thing)) {
1098                 /* Maybe. Have we already moved it? */
1099                 thingp = (lispobj *)native_pointer(thing);
1100                 header = *thingp;
1101                 if (is_lisp_pointer(header) && forwarding_pointer_p(header))
1102                     /* Yep, so just copy the forwarding pointer. */
1103                     thing = header;
1104                 else {
1105                     /* Nope, copy the object. */
1106                     switch (lowtag_of(thing)) {
1107                       case FUN_POINTER_LOWTAG:
1108                         thing = ptrans_func(thing, header);
1109                         break;
1110
1111                       case LIST_POINTER_LOWTAG:
1112                         thing = ptrans_list(thing, constant);
1113                         break;
1114
1115                       case INSTANCE_POINTER_LOWTAG:
1116                         thing = ptrans_instance(thing, header, constant);
1117                         break;
1118
1119                       case OTHER_POINTER_LOWTAG:
1120                         thing = ptrans_otherptr(thing, header, constant);
1121                         break;
1122
1123                       default:
1124                         /* It was a pointer, but not one of them? */
1125                         gc_abort();
1126                     }
1127                 }
1128                 *addr = thing;
1129             }
1130             count = 1;
1131         }
1132         else if (thing & 3) {
1133             /* It's an other immediate. Maybe the header for an unboxed */
1134             /* object. */
1135             switch (widetag_of(thing)) {
1136               case BIGNUM_WIDETAG:
1137               case SINGLE_FLOAT_WIDETAG:
1138               case DOUBLE_FLOAT_WIDETAG:
1139 #ifdef LONG_FLOAT_WIDETAG
1140               case LONG_FLOAT_WIDETAG:
1141 #endif
1142               case SAP_WIDETAG:
1143                 /* It's an unboxed simple object. */
1144                 count = HeaderValue(thing)+1;
1145                 break;
1146
1147               case SIMPLE_VECTOR_WIDETAG:
1148                   if (HeaderValue(thing) == subtype_VectorValidHashing) {
1149                     *addr = (subtype_VectorMustRehash << N_WIDETAG_BITS) |
1150                         SIMPLE_VECTOR_WIDETAG;
1151                   }
1152                 count = 1;
1153                 break;
1154
1155               case SIMPLE_ARRAY_NIL_WIDETAG:
1156                 count = 2;
1157                 break;
1158
1159               case SIMPLE_BASE_STRING_WIDETAG:
1160                 vector = (struct vector *)addr;
1161                 count = CEILING(NWORDS(fixnum_value(vector->length)+1,4)+2,2);
1162                 break;
1163
1164               case SIMPLE_BIT_VECTOR_WIDETAG:
1165                 vector = (struct vector *)addr;
1166                 count = CEILING(NWORDS(fixnum_value(vector->length),32)+2,2);
1167                 break;
1168
1169               case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
1170                 vector = (struct vector *)addr;
1171                 count = CEILING(NWORDS(fixnum_value(vector->length),16)+2,2);
1172                 break;
1173
1174               case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
1175                 vector = (struct vector *)addr;
1176                 count = CEILING(NWORDS(fixnum_value(vector->length),8)+2,2);
1177                 break;
1178
1179               case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
1180 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
1181               case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
1182 #endif
1183                 vector = (struct vector *)addr;
1184                 count = CEILING(NWORDS(fixnum_value(vector->length),4)+2,2);
1185                 break;
1186
1187               case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
1188 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
1189               case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
1190 #endif
1191                 vector = (struct vector *)addr;
1192                 count = CEILING(NWORDS(fixnum_value(vector->length),2)+2,2);
1193                 break;
1194
1195               case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
1196 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
1197               case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
1198 #endif
1199 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
1200               case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
1201 #endif
1202                 vector = (struct vector *)addr;
1203                 count = CEILING(fixnum_value(vector->length)+2,2);
1204                 break;
1205
1206               case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
1207                 vector = (struct vector *)addr;
1208                 count = CEILING(fixnum_value(vector->length)+2,2);
1209                 break;
1210
1211               case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
1212 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
1213               case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
1214 #endif
1215                 vector = (struct vector *)addr;
1216                 count = fixnum_value(vector->length)*2+2;
1217                 break;
1218
1219 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
1220               case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
1221                 vector = (struct vector *)addr;
1222 #ifdef __i386__
1223                 count = fixnum_value(vector->length)*3+2;
1224 #endif
1225 #ifdef sparc
1226                 count = fixnum_value(vector->length)*4+2;
1227 #endif
1228                 break;
1229 #endif
1230
1231 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
1232               case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
1233                 vector = (struct vector *)addr;
1234                 count = fixnum_value(vector->length)*4+2;
1235                 break;
1236 #endif
1237
1238 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
1239               case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
1240                 vector = (struct vector *)addr;
1241 #ifdef __i386__
1242                 count = fixnum_value(vector->length)*6+2;
1243 #endif
1244 #ifdef sparc
1245                 count = fixnum_value(vector->length)*8+2;
1246 #endif
1247                 break;
1248 #endif
1249
1250               case CODE_HEADER_WIDETAG:
1251 #ifndef __i386__
1252                 gc_abort(); /* no code headers in static space */
1253 #else
1254                 count = pscav_code((struct code*)addr);
1255 #endif
1256                 break;
1257
1258               case SIMPLE_FUN_HEADER_WIDETAG:
1259               case CLOSURE_FUN_HEADER_WIDETAG:
1260               case RETURN_PC_HEADER_WIDETAG:
1261                 /* We should never hit any of these, 'cause they occur
1262                  * buried in the middle of code objects. */
1263                 gc_abort();
1264                 break;
1265
1266 #ifdef __i386__
1267               case CLOSURE_HEADER_WIDETAG:
1268               case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
1269                 /* The function self pointer needs special care on the
1270                  * x86 because it is the real entry point. */
1271                 {
1272                   lispobj fun = ((struct closure *)addr)->fun
1273                     - FUN_RAW_ADDR_OFFSET;
1274                   pscav(&fun, 1, constant);
1275                   ((struct closure *)addr)->fun = fun + FUN_RAW_ADDR_OFFSET;
1276                 }
1277                 count = 2;
1278                 break;
1279 #endif
1280
1281               case WEAK_POINTER_WIDETAG:
1282                 /* Weak pointers get preserved during purify, 'cause I
1283                  * don't feel like figuring out how to break them. */
1284                 pscav(addr+1, 2, constant);
1285                 count = 4;
1286                 break;
1287
1288               case FDEFN_WIDETAG:
1289                 /* We have to handle fdefn objects specially, so we
1290                  * can fix up the raw function address. */
1291                 count = pscav_fdefn((struct fdefn *)addr);
1292                 break;
1293
1294               default:
1295                 count = 1;
1296                 break;
1297             }
1298         }
1299         else {
1300             /* It's a fixnum. */
1301             count = 1;
1302         }
1303
1304         addr += count;
1305         nwords -= count;
1306     }
1307
1308     return addr;
1309 }
1310
1311 int
1312 purify(lispobj static_roots, lispobj read_only_roots)
1313 {
1314     lispobj *clean;
1315     int count, i;
1316     struct later *laters, *next;
1317     struct thread *thread;
1318
1319 #ifdef PRINTNOISE
1320     printf("[doing purification:");
1321     fflush(stdout);
1322 #endif
1323 #ifdef LISP_FEATURE_GENCGC
1324     gc_alloc_update_all_page_tables();
1325 #endif
1326     for_each_thread(thread)
1327         if (fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX,thread)) != 0) {
1328         /* FIXME: 1. What does this mean? 2. It shouldn't be reporting
1329          * its error simply by a. printing a string b. to stdout instead
1330          * of stderr. */
1331         printf(" Ack! Can't purify interrupt contexts. ");
1332         fflush(stdout);
1333         return 0;
1334     }
1335
1336 #if defined(__i386__)
1337     dynamic_space_free_pointer =
1338       (lispobj*)SymbolValue(ALLOCATION_POINTER,0);
1339 #endif
1340
1341     read_only_end = read_only_free =
1342         (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0);
1343     static_end = static_free =
1344         (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER,0);
1345
1346 #ifdef PRINTNOISE
1347     printf(" roots");
1348     fflush(stdout);
1349 #endif
1350
1351 #if (defined(LISP_FEATURE_GENCGC) && defined(LISP_FEATURE_X86))
1352 #if 0
1353     /* This is what we should do, but can't unless the threads in
1354      * question are suspended with ptrace.  That's right, purify is not
1355      * threadsafe
1356      */
1357     for_each_thread(thread) {
1358         void **ptr;
1359         struct user_regs_struct regs;
1360         if(ptrace(PTRACE_GETREGS,thread->pid,0,&regs)){
1361             fprintf(stderr,"child pid %d, %s\n",thread->pid,strerror(errno));
1362             lose("PTRACE_GETREGS");
1363         }
1364         setup_i386_stack_scav(regs.ebp,
1365                               ((void *)thread->control_stack_end));
1366     }
1367 #endif /* 0 */
1368     /* stopgap until we can set things up as in preceding comment */
1369     setup_i386_stack_scav(((&static_roots)-2),
1370                           ((void *)all_threads->control_stack_end));
1371 #endif
1372
1373     pscav(&static_roots, 1, 0);
1374     pscav(&read_only_roots, 1, 1);
1375
1376 #ifdef PRINTNOISE
1377     printf(" handlers");
1378     fflush(stdout);
1379 #endif
1380     pscav((lispobj *) all_threads->interrupt_data->interrupt_handlers,
1381           sizeof(all_threads->interrupt_data->interrupt_handlers)
1382           / sizeof(lispobj),
1383           0);
1384
1385 #ifdef PRINTNOISE
1386     printf(" stack");
1387     fflush(stdout);
1388 #endif
1389 #ifndef __i386__
1390     pscav((lispobj *)all_threads->control_stack_start,
1391           current_control_stack_pointer - 
1392           all_threads->control_stack_start,
1393           0);
1394 #else
1395 #ifdef LISP_FEATURE_GENCGC
1396     pscav_i386_stack();
1397 #endif
1398 #endif
1399
1400 #ifdef PRINTNOISE
1401     printf(" bindings");
1402     fflush(stdout);
1403 #endif
1404 #if !defined(__i386__)
1405     pscav( (lispobj *)all_threads->binding_stack_start,
1406           (lispobj *)current_binding_stack_pointer -
1407            all_threads->binding_stack_start,
1408           0);
1409 #else
1410     for_each_thread(thread) {
1411         pscav( (lispobj *)thread->binding_stack_start,
1412                (lispobj *)SymbolValue(BINDING_STACK_POINTER,thread) -
1413                (lispobj *)thread->binding_stack_start,
1414           0);
1415         pscav( (lispobj *) (thread+1),
1416                fixnum_value(SymbolValue(FREE_TLS_INDEX,0)) -
1417                (sizeof (struct thread))/(sizeof (lispobj)),
1418           0);
1419     }
1420
1421
1422 #endif
1423
1424     /* The original CMU CL code had scavenge-read-only-space code
1425      * controlled by the Lisp-level variable
1426      * *SCAVENGE-READ-ONLY-SPACE*. It was disabled by default, and it
1427      * wasn't documented under what circumstances it was useful or
1428      * safe to turn it on, so it's been turned off in SBCL. If you
1429      * want/need this functionality, and can test and document it,
1430      * please submit a patch. */
1431 #if 0
1432     if (SymbolValue(SCAVENGE_READ_ONLY_SPACE) != UNBOUND_MARKER_WIDETAG
1433         && SymbolValue(SCAVENGE_READ_ONLY_SPACE) != NIL) {
1434       unsigned  read_only_space_size =
1435           (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER) -
1436           (lispobj *)READ_ONLY_SPACE_START;
1437       fprintf(stderr,
1438               "scavenging read only space: %d bytes\n",
1439               read_only_space_size * sizeof(lispobj));
1440       pscav( (lispobj *)READ_ONLY_SPACE_START, read_only_space_size, 0);
1441     }
1442 #endif
1443
1444 #ifdef PRINTNOISE
1445     printf(" static");
1446     fflush(stdout);
1447 #endif
1448     clean = (lispobj *)STATIC_SPACE_START;
1449     do {
1450         while (clean != static_free)
1451             clean = pscav(clean, static_free - clean, 0);
1452         laters = later_blocks;
1453         count = later_count;
1454         later_blocks = NULL;
1455         later_count = 0;
1456         while (laters != NULL) {
1457             for (i = 0; i < count; i++) {
1458                 if (laters->u[i].count == 0) {
1459                     ;
1460                 } else if (laters->u[i].count <= LATERMAXCOUNT) {
1461                     pscav(laters->u[i+1].ptr, laters->u[i].count, 1);
1462                     i++;
1463                 } else {
1464                     pscav(laters->u[i].ptr, 1, 1);
1465                 }
1466             }
1467             next = laters->next;
1468             free(laters);
1469             laters = next;
1470             count = LATERBLOCKSIZE;
1471         }
1472     } while (clean != static_free || later_blocks != NULL);
1473
1474 #ifdef PRINTNOISE
1475     printf(" cleanup");
1476     fflush(stdout);
1477 #endif
1478
1479     os_zero((os_vm_address_t) current_dynamic_space,
1480             (os_vm_size_t) DYNAMIC_SPACE_SIZE);
1481
1482     /* Zero the stack. Note that the stack is also zeroed by SUB-GC
1483      * calling SCRUB-CONTROL-STACK - this zeros the stack on the x86. */
1484 #ifndef __i386__
1485     os_zero((os_vm_address_t) current_control_stack_pointer,
1486             (os_vm_size_t)
1487             ((all_threads->control_stack_end -
1488               current_control_stack_pointer) * sizeof(lispobj)));
1489 #endif
1490
1491     /* It helps to update the heap free pointers so that free_heap can
1492      * verify after it's done. */
1493     SetSymbolValue(READ_ONLY_SPACE_FREE_POINTER, (lispobj)read_only_free,0);
1494     SetSymbolValue(STATIC_SPACE_FREE_POINTER, (lispobj)static_free,0);
1495
1496 #if !defined(__i386__)
1497     dynamic_space_free_pointer = current_dynamic_space;
1498     set_auto_gc_trigger(bytes_consed_between_gcs);
1499 #else
1500 #if defined LISP_FEATURE_GENCGC
1501     gc_free_heap();
1502 #else
1503 #error unsupported case /* in CMU CL, was "ibmrt using GC" */
1504 #endif
1505 #endif
1506
1507 #ifdef PRINTNOISE
1508     printf(" done]\n");
1509     fflush(stdout);
1510 #endif
1511     return 0;
1512 }