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