0.7.13.21:
[sbcl.git] / src / runtime / gencgc.c
1 /*
2  * GENerational Conservative Garbage Collector for SBCL x86
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 /*
17  * For a review of garbage collection techniques (e.g. generational
18  * GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
19  * "Uniprocessor Garbage Collection Techniques". As of 20000618, this
20  * had been accepted for _ACM Computing Surveys_ and was available
21  * as a PostScript preprint through
22  *   <http://www.cs.utexas.edu/users/oops/papers.html>
23  * as
24  *   <ftp://ftp.cs.utexas.edu/pub/garbage/bigsurv.ps>.
25  */
26
27 #include <stdio.h>
28 #include <signal.h>
29 #include <errno.h>
30 #include "runtime.h"
31 #include "sbcl.h"
32 #include "os.h"
33 #include "interr.h"
34 #include "globals.h"
35 #include "interrupt.h"
36 #include "validate.h"
37 #include "lispregs.h"
38 #include "arch.h"
39 #include "gc.h"
40 #include "gc-internal.h"
41 #include "genesis/vector.h"
42 #include "genesis/weak-pointer.h"
43 #include "genesis/simple-fun.h"
44 #include "genesis/static-symbols.h"
45 #include "genesis/symbol.h"
46 /* assembly language stub that executes trap_PendingInterrupt */
47 void do_pending_interrupt(void);
48
49 \f
50 /*
51  * GC parameters
52  */
53
54 /* the number of actual generations. (The number of 'struct
55  * generation' objects is one more than this, because one object
56  * serves as scratch when GC'ing.) */
57 #define NUM_GENERATIONS 6
58
59 /* Should we use page protection to help avoid the scavenging of pages
60  * that don't have pointers to younger generations? */
61 boolean enable_page_protection = 1;
62
63 /* Should we unmap a page and re-mmap it to have it zero filled? */
64 #if defined(__FreeBSD__) || defined(__OpenBSD__)
65 /* comment from cmucl-2.4.8: This can waste a lot of swap on FreeBSD
66  * so don't unmap there.
67  *
68  * The CMU CL comment didn't specify a version, but was probably an
69  * old version of FreeBSD (pre-4.0), so this might no longer be true.
70  * OTOH, if it is true, this behavior might exist on OpenBSD too, so
71  * for now we don't unmap there either. -- WHN 2001-04-07 */
72 boolean gencgc_unmap_zero = 0;
73 #else
74 boolean gencgc_unmap_zero = 1;
75 #endif
76
77 /* the minimum size (in bytes) for a large object*/
78 unsigned large_object_size = 4 * 4096;
79 \f
80 /*
81  * debugging
82  */
83
84
85
86 /* the verbosity level. All non-error messages are disabled at level 0;
87  * and only a few rare messages are printed at level 1. */
88 unsigned gencgc_verbose = (QSHOW ? 1 : 0);
89
90 /* FIXME: At some point enable the various error-checking things below
91  * and see what they say. */
92
93 /* We hunt for pointers to old-space, when GCing generations >= verify_gen.
94  * Set verify_gens to NUM_GENERATIONS to disable this kind of check. */
95 int verify_gens = NUM_GENERATIONS;
96
97 /* Should we do a pre-scan verify of generation 0 before it's GCed? */
98 boolean pre_verify_gen_0 = 0;
99
100 /* Should we check for bad pointers after gc_free_heap is called
101  * from Lisp PURIFY? */
102 boolean verify_after_free_heap = 0;
103
104 /* Should we print a note when code objects are found in the dynamic space
105  * during a heap verify? */
106 boolean verify_dynamic_code_check = 0;
107
108 /* Should we check code objects for fixup errors after they are transported? */
109 boolean check_code_fixups = 0;
110
111 /* Should we check that newly allocated regions are zero filled? */
112 boolean gencgc_zero_check = 0;
113
114 /* Should we check that the free space is zero filled? */
115 boolean gencgc_enable_verify_zero_fill = 0;
116
117 /* Should we check that free pages are zero filled during gc_free_heap
118  * called after Lisp PURIFY? */
119 boolean gencgc_zero_check_during_free_heap = 0;
120 \f
121 /*
122  * GC structures and variables
123  */
124
125 /* the total bytes allocated. These are seen by Lisp DYNAMIC-USAGE. */
126 unsigned long bytes_allocated = 0;
127 static unsigned long auto_gc_trigger = 0;
128
129 /* the source and destination generations. These are set before a GC starts
130  * scavenging. */
131 int from_space;
132 int new_space;
133
134
135 /* FIXME: It would be nice to use this symbolic constant instead of
136  * bare 4096 almost everywhere. We could also use an assertion that
137  * it's equal to getpagesize(). */
138
139 #define PAGE_BYTES 4096
140
141 /* An array of page structures is statically allocated.
142  * This helps quickly map between an address its page structure.
143  * NUM_PAGES is set from the size of the dynamic space. */
144 struct page page_table[NUM_PAGES];
145
146 /* To map addresses to page structures the address of the first page
147  * is needed. */
148 static void *heap_base = NULL;
149
150
151 /* Calculate the start address for the given page number. */
152 inline void *
153 page_address(int page_num)
154 {
155     return (heap_base + (page_num * 4096));
156 }
157
158 /* Find the page index within the page_table for the given
159  * address. Return -1 on failure. */
160 inline int
161 find_page_index(void *addr)
162 {
163     int index = addr-heap_base;
164
165     if (index >= 0) {
166         index = ((unsigned int)index)/4096;
167         if (index < NUM_PAGES)
168             return (index);
169     }
170
171     return (-1);
172 }
173
174 /* a structure to hold the state of a generation */
175 struct generation {
176
177     /* the first page that gc_alloc() checks on its next call */
178     int alloc_start_page;
179
180     /* the first page that gc_alloc_unboxed() checks on its next call */
181     int alloc_unboxed_start_page;
182
183     /* the first page that gc_alloc_large (boxed) considers on its next
184      * call. (Although it always allocates after the boxed_region.) */
185     int alloc_large_start_page;
186
187     /* the first page that gc_alloc_large (unboxed) considers on its
188      * next call. (Although it always allocates after the
189      * current_unboxed_region.) */
190     int alloc_large_unboxed_start_page;
191
192     /* the bytes allocated to this generation */
193     int bytes_allocated;
194
195     /* the number of bytes at which to trigger a GC */
196     int gc_trigger;
197
198     /* to calculate a new level for gc_trigger */
199     int bytes_consed_between_gc;
200
201     /* the number of GCs since the last raise */
202     int num_gc;
203
204     /* the average age after which a GC will raise objects to the
205      * next generation */
206     int trigger_age;
207
208     /* the cumulative sum of the bytes allocated to this generation. It is
209      * cleared after a GC on this generations, and update before new
210      * objects are added from a GC of a younger generation. Dividing by
211      * the bytes_allocated will give the average age of the memory in
212      * this generation since its last GC. */
213     int cum_sum_bytes_allocated;
214
215     /* a minimum average memory age before a GC will occur helps
216      * prevent a GC when a large number of new live objects have been
217      * added, in which case a GC could be a waste of time */
218     double min_av_mem_age;
219 };
220 /* the number of actual generations. (The number of 'struct
221  * generation' objects is one more than this, because one object
222  * serves as scratch when GC'ing.) */
223 #define NUM_GENERATIONS 6
224
225 /* an array of generation structures. There needs to be one more
226  * generation structure than actual generations as the oldest
227  * generation is temporarily raised then lowered. */
228 struct generation generations[NUM_GENERATIONS+1];
229
230 /* the oldest generation that is will currently be GCed by default.
231  * Valid values are: 0, 1, ... (NUM_GENERATIONS-1)
232  *
233  * The default of (NUM_GENERATIONS-1) enables GC on all generations.
234  *
235  * Setting this to 0 effectively disables the generational nature of
236  * the GC. In some applications generational GC may not be useful
237  * because there are no long-lived objects.
238  *
239  * An intermediate value could be handy after moving long-lived data
240  * into an older generation so an unnecessary GC of this long-lived
241  * data can be avoided. */
242 unsigned int  gencgc_oldest_gen_to_gc = NUM_GENERATIONS-1;
243
244 /* The maximum free page in the heap is maintained and used to update
245  * ALLOCATION_POINTER which is used by the room function to limit its
246  * search of the heap. XX Gencgc obviously needs to be better
247  * integrated with the Lisp code. */
248 static int  last_free_page;
249 \f
250 /*
251  * miscellaneous heap functions
252  */
253
254 /* Count the number of pages which are write-protected within the
255  * given generation. */
256 static int
257 count_write_protect_generation_pages(int generation)
258 {
259     int i;
260     int count = 0;
261
262     for (i = 0; i < last_free_page; i++)
263         if ((page_table[i].allocated != FREE_PAGE)
264             && (page_table[i].gen == generation)
265             && (page_table[i].write_protected == 1))
266             count++;
267     return count;
268 }
269
270 /* Count the number of pages within the given generation. */
271 static int
272 count_generation_pages(int generation)
273 {
274     int i;
275     int count = 0;
276
277     for (i = 0; i < last_free_page; i++)
278         if ((page_table[i].allocated != 0)
279             && (page_table[i].gen == generation))
280             count++;
281     return count;
282 }
283
284 /* Count the number of dont_move pages. */
285 static int
286 count_dont_move_pages(void)
287 {
288     int i;
289     int count = 0;
290     for (i = 0; i < last_free_page; i++) {
291         if ((page_table[i].allocated != 0) && (page_table[i].dont_move != 0)) {
292             ++count;
293         }
294     }
295     return count;
296 }
297
298 /* Work through the pages and add up the number of bytes used for the
299  * given generation. */
300 static int
301 count_generation_bytes_allocated (int gen)
302 {
303     int i;
304     int result = 0;
305     for (i = 0; i < last_free_page; i++) {
306         if ((page_table[i].allocated != 0) && (page_table[i].gen == gen))
307             result += page_table[i].bytes_used;
308     }
309     return result;
310 }
311
312 /* Return the average age of the memory in a generation. */
313 static double
314 gen_av_mem_age(int gen)
315 {
316     if (generations[gen].bytes_allocated == 0)
317         return 0.0;
318
319     return
320         ((double)generations[gen].cum_sum_bytes_allocated)
321         / ((double)generations[gen].bytes_allocated);
322 }
323
324 /* The verbose argument controls how much to print: 0 for normal
325  * level of detail; 1 for debugging. */
326 static void
327 print_generation_stats(int verbose) /* FIXME: should take FILE argument */
328 {
329     int i, gens;
330     int fpu_state[27];
331
332     /* This code uses the FP instructions which may be set up for Lisp
333      * so they need to be saved and reset for C. */
334     fpu_save(fpu_state);
335
336     /* number of generations to print */
337     if (verbose)
338         gens = NUM_GENERATIONS+1;
339     else
340         gens = NUM_GENERATIONS;
341
342     /* Print the heap stats. */
343     fprintf(stderr,
344             "   Generation Boxed Unboxed LB   LUB    Alloc  Waste   Trig    WP  GCs Mem-age\n");
345
346     for (i = 0; i < gens; i++) {
347         int j;
348         int boxed_cnt = 0;
349         int unboxed_cnt = 0;
350         int large_boxed_cnt = 0;
351         int large_unboxed_cnt = 0;
352
353         for (j = 0; j < last_free_page; j++)
354             if (page_table[j].gen == i) {
355
356                 /* Count the number of boxed pages within the given
357                  * generation. */
358                 if (page_table[j].allocated & BOXED_PAGE) {
359                     if (page_table[j].large_object)
360                         large_boxed_cnt++;
361                     else
362                         boxed_cnt++;
363                 }
364
365                 /* Count the number of unboxed pages within the given
366                  * generation. */
367                 if (page_table[j].allocated & UNBOXED_PAGE) {
368                     if (page_table[j].large_object)
369                         large_unboxed_cnt++;
370                     else
371                         unboxed_cnt++;
372                 }
373             }
374
375         gc_assert(generations[i].bytes_allocated
376                   == count_generation_bytes_allocated(i));
377         fprintf(stderr,
378                 "   %8d: %5d %5d %5d %5d %8d %5d %8d %4d %3d %7.4f\n",
379                 i,
380                 boxed_cnt, unboxed_cnt, large_boxed_cnt, large_unboxed_cnt,
381                 generations[i].bytes_allocated,
382                 (count_generation_pages(i)*4096
383                  - generations[i].bytes_allocated),
384                 generations[i].gc_trigger,
385                 count_write_protect_generation_pages(i),
386                 generations[i].num_gc,
387                 gen_av_mem_age(i));
388     }
389     fprintf(stderr,"   Total bytes allocated=%ld\n", bytes_allocated);
390
391     fpu_restore(fpu_state);
392 }
393 \f
394 /*
395  * allocation routines
396  */
397
398 /*
399  * To support quick and inline allocation, regions of memory can be
400  * allocated and then allocated from with just a free pointer and a
401  * check against an end address.
402  *
403  * Since objects can be allocated to spaces with different properties
404  * e.g. boxed/unboxed, generation, ages; there may need to be many
405  * allocation regions.
406  *
407  * Each allocation region may be start within a partly used page. Many
408  * features of memory use are noted on a page wise basis, e.g. the
409  * generation; so if a region starts within an existing allocated page
410  * it must be consistent with this page.
411  *
412  * During the scavenging of the newspace, objects will be transported
413  * into an allocation region, and pointers updated to point to this
414  * allocation region. It is possible that these pointers will be
415  * scavenged again before the allocation region is closed, e.g. due to
416  * trans_list which jumps all over the place to cleanup the list. It
417  * is important to be able to determine properties of all objects
418  * pointed to when scavenging, e.g to detect pointers to the oldspace.
419  * Thus it's important that the allocation regions have the correct
420  * properties set when allocated, and not just set when closed. The
421  * region allocation routines return regions with the specified
422  * properties, and grab all the pages, setting their properties
423  * appropriately, except that the amount used is not known.
424  *
425  * These regions are used to support quicker allocation using just a
426  * free pointer. The actual space used by the region is not reflected
427  * in the pages tables until it is closed. It can't be scavenged until
428  * closed.
429  *
430  * When finished with the region it should be closed, which will
431  * update the page tables for the actual space used returning unused
432  * space. Further it may be noted in the new regions which is
433  * necessary when scavenging the newspace.
434  *
435  * Large objects may be allocated directly without an allocation
436  * region, the page tables are updated immediately.
437  *
438  * Unboxed objects don't contain pointers to other objects and so
439  * don't need scavenging. Further they can't contain pointers to
440  * younger generations so WP is not needed. By allocating pages to
441  * unboxed objects the whole page never needs scavenging or
442  * write-protecting. */
443
444 /* We are only using two regions at present. Both are for the current
445  * newspace generation. */
446 struct alloc_region boxed_region;
447 struct alloc_region unboxed_region;
448
449 /* The generation currently being allocated to. */
450 static int gc_alloc_generation;
451
452 /* Find a new region with room for at least the given number of bytes.
453  *
454  * It starts looking at the current generation's alloc_start_page. So
455  * may pick up from the previous region if there is enough space. This
456  * keeps the allocation contiguous when scavenging the newspace.
457  *
458  * The alloc_region should have been closed by a call to
459  * gc_alloc_update_page_tables(), and will thus be in an empty state.
460  *
461  * To assist the scavenging functions write-protected pages are not
462  * used. Free pages should not be write-protected.
463  *
464  * It is critical to the conservative GC that the start of regions be
465  * known. To help achieve this only small regions are allocated at a
466  * time.
467  *
468  * During scavenging, pointers may be found to within the current
469  * region and the page generation must be set so that pointers to the
470  * from space can be recognized. Therefore the generation of pages in
471  * the region are set to gc_alloc_generation. To prevent another
472  * allocation call using the same pages, all the pages in the region
473  * are allocated, although they will initially be empty.
474  */
475 static void
476 gc_alloc_new_region(int nbytes, int unboxed, struct alloc_region *alloc_region)
477 {
478     int first_page;
479     int last_page;
480     int bytes_found;
481     int i;
482
483     /*
484     FSHOW((stderr,
485            "/alloc_new_region for %d bytes from gen %d\n",
486            nbytes, gc_alloc_generation));
487     */
488
489     /* Check that the region is in a reset state. */
490     gc_assert((alloc_region->first_page == 0)
491               && (alloc_region->last_page == -1)
492               && (alloc_region->free_pointer == alloc_region->end_addr));
493
494     if (unboxed) {
495         first_page =
496             generations[gc_alloc_generation].alloc_unboxed_start_page;
497     } else {
498         first_page =
499             generations[gc_alloc_generation].alloc_start_page;
500     }
501     last_page=gc_find_freeish_pages(&first_page,nbytes,unboxed,alloc_region);
502     bytes_found=(4096 - page_table[first_page].bytes_used)
503             + 4096*(last_page-first_page);
504
505     /* Set up the alloc_region. */
506     alloc_region->first_page = first_page;
507     alloc_region->last_page = last_page;
508     alloc_region->start_addr = page_table[first_page].bytes_used
509         + page_address(first_page);
510     alloc_region->free_pointer = alloc_region->start_addr;
511     alloc_region->end_addr = alloc_region->start_addr + bytes_found;
512
513     if (gencgc_zero_check) {
514         int *p;
515         for (p = (int *)alloc_region->start_addr;
516             p < (int *)alloc_region->end_addr; p++) {
517             if (*p != 0) {
518                 /* KLUDGE: It would be nice to use %lx and explicit casts
519                  * (long) in code like this, so that it is less likely to
520                  * break randomly when running on a machine with different
521                  * word sizes. -- WHN 19991129 */
522                 lose("The new region at %x is not zero.", p);
523             }
524         }
525     }
526
527     /* Set up the pages. */
528
529     /* The first page may have already been in use. */
530     if (page_table[first_page].bytes_used == 0) {
531         if (unboxed)
532             page_table[first_page].allocated = UNBOXED_PAGE;
533         else
534             page_table[first_page].allocated = BOXED_PAGE;
535         page_table[first_page].gen = gc_alloc_generation;
536         page_table[first_page].large_object = 0;
537         page_table[first_page].first_object_offset = 0;
538     }
539
540     if (unboxed)
541         gc_assert(page_table[first_page].allocated == UNBOXED_PAGE);
542     else
543         gc_assert(page_table[first_page].allocated == BOXED_PAGE);
544     page_table[first_page].allocated |= OPEN_REGION_PAGE; 
545
546     gc_assert(page_table[first_page].gen == gc_alloc_generation);
547     gc_assert(page_table[first_page].large_object == 0);
548
549     for (i = first_page+1; i <= last_page; i++) {
550         if (unboxed)
551             page_table[i].allocated = UNBOXED_PAGE;
552         else
553             page_table[i].allocated = BOXED_PAGE;
554         page_table[i].gen = gc_alloc_generation;
555         page_table[i].large_object = 0;
556         /* This may not be necessary for unboxed regions (think it was
557          * broken before!) */
558         page_table[i].first_object_offset =
559             alloc_region->start_addr - page_address(i);
560         page_table[i].allocated |= OPEN_REGION_PAGE ;
561     }
562
563     /* Bump up last_free_page. */
564     if (last_page+1 > last_free_page) {
565         last_free_page = last_page+1;
566         SetSymbolValue(ALLOCATION_POINTER,
567                        (lispobj)(((char *)heap_base) + last_free_page*4096));
568     }
569 }
570
571 /* If the record_new_objects flag is 2 then all new regions created
572  * are recorded.
573  *
574  * If it's 1 then then it is only recorded if the first page of the
575  * current region is <= new_areas_ignore_page. This helps avoid
576  * unnecessary recording when doing full scavenge pass.
577  *
578  * The new_object structure holds the page, byte offset, and size of
579  * new regions of objects. Each new area is placed in the array of
580  * these structures pointer to by new_areas. new_areas_index holds the
581  * offset into new_areas.
582  *
583  * If new_area overflows NUM_NEW_AREAS then it stops adding them. The
584  * later code must detect this and handle it, probably by doing a full
585  * scavenge of a generation. */
586 #define NUM_NEW_AREAS 512
587 static int record_new_objects = 0;
588 static int new_areas_ignore_page;
589 struct new_area {
590     int  page;
591     int  offset;
592     int  size;
593 };
594 static struct new_area (*new_areas)[];
595 static int new_areas_index;
596 int max_new_areas;
597
598 /* Add a new area to new_areas. */
599 static void
600 add_new_area(int first_page, int offset, int size)
601 {
602     unsigned new_area_start,c;
603     int i;
604
605     /* Ignore if full. */
606     if (new_areas_index >= NUM_NEW_AREAS)
607         return;
608
609     switch (record_new_objects) {
610     case 0:
611         return;
612     case 1:
613         if (first_page > new_areas_ignore_page)
614             return;
615         break;
616     case 2:
617         break;
618     default:
619         gc_abort();
620     }
621
622     new_area_start = 4096*first_page + offset;
623
624     /* Search backwards for a prior area that this follows from. If
625        found this will save adding a new area. */
626     for (i = new_areas_index-1, c = 0; (i >= 0) && (c < 8); i--, c++) {
627         unsigned area_end =
628             4096*((*new_areas)[i].page)
629             + (*new_areas)[i].offset
630             + (*new_areas)[i].size;
631         /*FSHOW((stderr,
632                "/add_new_area S1 %d %d %d %d\n",
633                i, c, new_area_start, area_end));*/
634         if (new_area_start == area_end) {
635             /*FSHOW((stderr,
636                    "/adding to [%d] %d %d %d with %d %d %d:\n",
637                    i,
638                    (*new_areas)[i].page,
639                    (*new_areas)[i].offset,
640                    (*new_areas)[i].size,
641                    first_page,
642                    offset,
643                     size);*/
644             (*new_areas)[i].size += size;
645             return;
646         }
647     }
648
649     (*new_areas)[new_areas_index].page = first_page;
650     (*new_areas)[new_areas_index].offset = offset;
651     (*new_areas)[new_areas_index].size = size;
652     /*FSHOW((stderr,
653            "/new_area %d page %d offset %d size %d\n",
654            new_areas_index, first_page, offset, size));*/
655     new_areas_index++;
656
657     /* Note the max new_areas used. */
658     if (new_areas_index > max_new_areas)
659         max_new_areas = new_areas_index;
660 }
661
662 /* Update the tables for the alloc_region. The region maybe added to
663  * the new_areas.
664  *
665  * When done the alloc_region is set up so that the next quick alloc
666  * will fail safely and thus a new region will be allocated. Further
667  * it is safe to try to re-update the page table of this reset
668  * alloc_region. */
669 void
670 gc_alloc_update_page_tables(int unboxed, struct alloc_region *alloc_region)
671 {
672     int more;
673     int first_page;
674     int next_page;
675     int bytes_used;
676     int orig_first_page_bytes_used;
677     int region_size;
678     int byte_cnt;
679
680     /*
681     FSHOW((stderr,
682            "/gc_alloc_update_page_tables() to gen %d:\n",
683            gc_alloc_generation));
684     */
685
686     first_page = alloc_region->first_page;
687
688     /* Catch an unused alloc_region. */
689     if ((first_page == 0) && (alloc_region->last_page == -1))
690         return;
691
692     next_page = first_page+1;
693
694     /* Skip if no bytes were allocated. */
695     if (alloc_region->free_pointer != alloc_region->start_addr) {
696         orig_first_page_bytes_used = page_table[first_page].bytes_used;
697
698         gc_assert(alloc_region->start_addr == (page_address(first_page) + page_table[first_page].bytes_used));
699
700         /* All the pages used need to be updated */
701
702         /* Update the first page. */
703
704         /* If the page was free then set up the gen, and
705          * first_object_offset. */
706         if (page_table[first_page].bytes_used == 0)
707             gc_assert(page_table[first_page].first_object_offset == 0);
708         page_table[first_page].allocated &= ~(OPEN_REGION_PAGE);
709
710         if (unboxed)
711             gc_assert(page_table[first_page].allocated == UNBOXED_PAGE);
712         else
713             gc_assert(page_table[first_page].allocated == BOXED_PAGE);
714         gc_assert(page_table[first_page].gen == gc_alloc_generation);
715         gc_assert(page_table[first_page].large_object == 0);
716
717         byte_cnt = 0;
718
719         /* Calculate the number of bytes used in this page. This is not
720          * always the number of new bytes, unless it was free. */
721         more = 0;
722         if ((bytes_used = (alloc_region->free_pointer - page_address(first_page)))>4096) {
723             bytes_used = 4096;
724             more = 1;
725         }
726         page_table[first_page].bytes_used = bytes_used;
727         byte_cnt += bytes_used;
728
729
730         /* All the rest of the pages should be free. We need to set their
731          * first_object_offset pointer to the start of the region, and set
732          * the bytes_used. */
733         while (more) {
734             page_table[next_page].allocated &= ~(OPEN_REGION_PAGE);
735             if (unboxed)
736                 gc_assert(page_table[next_page].allocated == UNBOXED_PAGE);
737             else
738                 gc_assert(page_table[next_page].allocated == BOXED_PAGE);
739             gc_assert(page_table[next_page].bytes_used == 0);
740             gc_assert(page_table[next_page].gen == gc_alloc_generation);
741             gc_assert(page_table[next_page].large_object == 0);
742
743             gc_assert(page_table[next_page].first_object_offset ==
744                       alloc_region->start_addr - page_address(next_page));
745
746             /* Calculate the number of bytes used in this page. */
747             more = 0;
748             if ((bytes_used = (alloc_region->free_pointer
749                                - page_address(next_page)))>4096) {
750                 bytes_used = 4096;
751                 more = 1;
752             }
753             page_table[next_page].bytes_used = bytes_used;
754             byte_cnt += bytes_used;
755
756             next_page++;
757         }
758
759         region_size = alloc_region->free_pointer - alloc_region->start_addr;
760         bytes_allocated += region_size;
761         generations[gc_alloc_generation].bytes_allocated += region_size;
762
763         gc_assert((byte_cnt- orig_first_page_bytes_used) == region_size);
764
765         /* Set the generations alloc restart page to the last page of
766          * the region. */
767         if (unboxed)
768             generations[gc_alloc_generation].alloc_unboxed_start_page =
769                 next_page-1;
770         else
771             generations[gc_alloc_generation].alloc_start_page = next_page-1;
772
773         /* Add the region to the new_areas if requested. */
774         if (!unboxed)
775             add_new_area(first_page,orig_first_page_bytes_used, region_size);
776
777         /*
778         FSHOW((stderr,
779                "/gc_alloc_update_page_tables update %d bytes to gen %d\n",
780                region_size,
781                gc_alloc_generation));
782         */
783     } else {
784         /* There are no bytes allocated. Unallocate the first_page if
785          * there are 0 bytes_used. */
786         page_table[first_page].allocated &= ~(OPEN_REGION_PAGE);
787         if (page_table[first_page].bytes_used == 0)
788             page_table[first_page].allocated = FREE_PAGE;
789     }
790
791     /* Unallocate any unused pages. */
792     while (next_page <= alloc_region->last_page) {
793         gc_assert(page_table[next_page].bytes_used == 0);
794         page_table[next_page].allocated = FREE_PAGE;
795         next_page++;
796     }
797
798     gc_set_region_empty(alloc_region);
799 }
800
801 static inline void *gc_quick_alloc(int nbytes);
802
803 /* Allocate a possibly large object. */
804 void *
805 gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
806 {
807     int first_page;
808     int last_page;
809     int orig_first_page_bytes_used;
810     int byte_cnt;
811     int more;
812     int bytes_used;
813     int next_page;
814     int large = (nbytes >= large_object_size);
815
816     /*
817     if (nbytes > 200000)
818         FSHOW((stderr, "/alloc_large %d\n", nbytes));
819     */
820
821     /*
822     FSHOW((stderr,
823            "/gc_alloc_large() for %d bytes from gen %d\n",
824            nbytes, gc_alloc_generation));
825     */
826
827     /* If the object is small, and there is room in the current region
828        then allocate it in the current region. */
829     if (!large
830         && ((alloc_region->end_addr-alloc_region->free_pointer) >= nbytes))
831         return gc_quick_alloc(nbytes);
832
833     /* To allow the allocation of small objects without the danger of
834        using a page in the current boxed region, the search starts after
835        the current boxed free region. XX could probably keep a page
836        index ahead of the current region and bumped up here to save a
837        lot of re-scanning. */
838
839     if (unboxed) {
840         first_page =
841             generations[gc_alloc_generation].alloc_large_unboxed_start_page;
842     } else {
843         first_page = generations[gc_alloc_generation].alloc_large_start_page;
844     }
845     if (first_page <= alloc_region->last_page) {
846         first_page = alloc_region->last_page+1;
847     }
848
849     last_page=gc_find_freeish_pages(&first_page,nbytes,unboxed,0);
850
851     gc_assert(first_page > alloc_region->last_page);
852     if (unboxed)
853         generations[gc_alloc_generation].alloc_large_unboxed_start_page =
854             last_page;
855     else
856         generations[gc_alloc_generation].alloc_large_start_page = last_page;
857
858     /* Set up the pages. */
859     orig_first_page_bytes_used = page_table[first_page].bytes_used;
860
861     /* If the first page was free then set up the gen, and
862      * first_object_offset. */
863     if (page_table[first_page].bytes_used == 0) {
864         if (unboxed)
865             page_table[first_page].allocated = UNBOXED_PAGE;
866         else
867             page_table[first_page].allocated = BOXED_PAGE;
868         page_table[first_page].gen = gc_alloc_generation;
869         page_table[first_page].first_object_offset = 0;
870         page_table[first_page].large_object = large;
871     }
872
873     if (unboxed)
874         gc_assert(page_table[first_page].allocated == UNBOXED_PAGE);
875     else
876         gc_assert(page_table[first_page].allocated == BOXED_PAGE);
877     gc_assert(page_table[first_page].gen == gc_alloc_generation);
878     gc_assert(page_table[first_page].large_object == large);
879
880     byte_cnt = 0;
881
882     /* Calc. the number of bytes used in this page. This is not
883      * always the number of new bytes, unless it was free. */
884     more = 0;
885     if ((bytes_used = nbytes+orig_first_page_bytes_used) > 4096) {
886         bytes_used = 4096;
887         more = 1;
888     }
889     page_table[first_page].bytes_used = bytes_used;
890     byte_cnt += bytes_used;
891
892     next_page = first_page+1;
893
894     /* All the rest of the pages should be free. We need to set their
895      * first_object_offset pointer to the start of the region, and
896      * set the bytes_used. */
897     while (more) {
898         gc_assert(page_table[next_page].allocated == FREE_PAGE);
899         gc_assert(page_table[next_page].bytes_used == 0);
900         if (unboxed)
901             page_table[next_page].allocated = UNBOXED_PAGE;
902         else
903             page_table[next_page].allocated = BOXED_PAGE;
904         page_table[next_page].gen = gc_alloc_generation;
905         page_table[next_page].large_object = large;
906
907         page_table[next_page].first_object_offset =
908             orig_first_page_bytes_used - 4096*(next_page-first_page);
909
910         /* Calculate the number of bytes used in this page. */
911         more = 0;
912         if ((bytes_used=(nbytes+orig_first_page_bytes_used)-byte_cnt) > 4096) {
913             bytes_used = 4096;
914             more = 1;
915         }
916         page_table[next_page].bytes_used = bytes_used;
917         byte_cnt += bytes_used;
918
919         next_page++;
920     }
921
922     gc_assert((byte_cnt-orig_first_page_bytes_used) == nbytes);
923
924     bytes_allocated += nbytes;
925     generations[gc_alloc_generation].bytes_allocated += nbytes;
926
927     /* Add the region to the new_areas if requested. */
928     if (!unboxed)
929         add_new_area(first_page,orig_first_page_bytes_used,nbytes);
930
931     /* Bump up last_free_page */
932     if (last_page+1 > last_free_page) {
933         last_free_page = last_page+1;
934         SetSymbolValue(ALLOCATION_POINTER,
935                        (lispobj)(((char *)heap_base) + last_free_page*4096));
936     }
937
938     return((void *)(page_address(first_page)+orig_first_page_bytes_used));
939 }
940
941 int
942 gc_find_freeish_pages(int *restart_page_ptr, int nbytes, int unboxed, struct alloc_region *alloc_region)
943 {
944     /* if alloc_region is 0, we assume this is for a potentially large
945        object */
946     int first_page;
947     int last_page;
948     int region_size;
949     int restart_page=*restart_page_ptr;
950     int bytes_found;
951     int num_pages;
952     int large = !alloc_region && (nbytes >= large_object_size);
953
954     /* Search for a contiguous free space of at least nbytes. If it's a
955        large object then align it on a page boundary by searching for a
956        free page. */
957
958     /* To allow the allocation of small objects without the danger of
959        using a page in the current boxed region, the search starts after
960        the current boxed free region. XX could probably keep a page
961        index ahead of the current region and bumped up here to save a
962        lot of re-scanning. */
963
964     do {
965         first_page = restart_page;
966         if (large)              
967             while ((first_page < NUM_PAGES)
968                    && (page_table[first_page].allocated != FREE_PAGE))
969                 first_page++;
970         else
971             while (first_page < NUM_PAGES) {
972                 if(page_table[first_page].allocated == FREE_PAGE)
973                     break;
974                 /* I don't know why we need the gen=0 test, but it
975                  * breaks randomly if that's omitted -dan 2003.02.26
976                  */
977                 if((page_table[first_page].allocated ==
978                     (unboxed ? UNBOXED_PAGE : BOXED_PAGE)) &&
979                    (page_table[first_page].large_object == 0) &&
980                    (gc_alloc_generation == 0) &&
981                    (page_table[first_page].gen == gc_alloc_generation) &&
982                    (page_table[first_page].bytes_used < (4096-32)) &&
983                    (page_table[first_page].write_protected == 0) &&
984                    (page_table[first_page].dont_move == 0))
985                     break;
986                 first_page++;
987             }
988         
989         if (first_page >= NUM_PAGES) {
990             fprintf(stderr,
991                     "Argh! gc_find_free_space failed (first_page), nbytes=%d.\n",
992                     nbytes);
993             print_generation_stats(1);
994             lose(NULL);
995         }
996
997         gc_assert(page_table[first_page].write_protected == 0);
998
999         last_page = first_page;
1000         bytes_found = 4096 - page_table[first_page].bytes_used;
1001         num_pages = 1;
1002         while (((bytes_found < nbytes) 
1003                 || (alloc_region && (num_pages < 2)))
1004                && (last_page < (NUM_PAGES-1))
1005                && (page_table[last_page+1].allocated == FREE_PAGE)) {
1006             last_page++;
1007             num_pages++;
1008             bytes_found += 4096;
1009             gc_assert(page_table[last_page].write_protected == 0);
1010         }
1011
1012         region_size = (4096 - page_table[first_page].bytes_used)
1013             + 4096*(last_page-first_page);
1014
1015         gc_assert(bytes_found == region_size);
1016         restart_page = last_page + 1;
1017     } while ((restart_page < NUM_PAGES) && (bytes_found < nbytes));
1018
1019     /* Check for a failure */
1020     if ((restart_page >= NUM_PAGES) && (bytes_found < nbytes)) {
1021         fprintf(stderr,
1022                 "Argh! gc_find_freeish_pages failed (restart_page), nbytes=%d.\n",
1023                 nbytes);
1024         print_generation_stats(1);
1025         lose(NULL);
1026     }
1027     *restart_page_ptr=first_page;
1028     return last_page;
1029 }
1030
1031 /* Allocate bytes.  All the rest of the special-purpose allocation
1032  * functions will eventually call this (instead of just duplicating
1033  * parts of its code) */
1034
1035 void *
1036 gc_alloc_with_region(int nbytes,int unboxed_p, struct alloc_region *my_region,
1037                      int quick_p)
1038 {
1039     void *new_free_pointer;
1040
1041     /* FSHOW((stderr, "/gc_alloc %d\n", nbytes)); */
1042
1043     /* Check whether there is room in the current alloc region. */
1044     new_free_pointer = my_region->free_pointer + nbytes;
1045
1046     if (new_free_pointer <= my_region->end_addr) {
1047         /* If so then allocate from the current alloc region. */
1048         void *new_obj = my_region->free_pointer;
1049         my_region->free_pointer = new_free_pointer;
1050
1051         /* Unless a `quick' alloc was requested, check whether the
1052            alloc region is almost empty. */
1053         if (!quick_p &&
1054             (my_region->end_addr - my_region->free_pointer) <= 32) {
1055             /* If so, finished with the current region. */
1056             gc_alloc_update_page_tables(unboxed_p, my_region);
1057             /* Set up a new region. */
1058             gc_alloc_new_region(32 /*bytes*/, unboxed_p, my_region);
1059         }
1060
1061         return((void *)new_obj);
1062     }
1063
1064     /* Else not enough free space in the current region. */
1065
1066     /* If there some room left in the current region, enough to be worth
1067      * saving, then allocate a large object. */
1068     /* FIXME: "32" should be a named parameter. */
1069     if ((my_region->end_addr-my_region->free_pointer) > 32)
1070         return gc_alloc_large(nbytes, unboxed_p, my_region);
1071
1072     /* Else find a new region. */
1073
1074     /* Finished with the current region. */
1075     gc_alloc_update_page_tables(unboxed_p, my_region);
1076
1077     /* Set up a new region. */
1078     gc_alloc_new_region(nbytes, unboxed_p, my_region);
1079
1080     /* Should now be enough room. */
1081
1082     /* Check whether there is room in the current region. */
1083     new_free_pointer = my_region->free_pointer + nbytes;
1084
1085     if (new_free_pointer <= my_region->end_addr) {
1086         /* If so then allocate from the current region. */
1087         void *new_obj = my_region->free_pointer;
1088         my_region->free_pointer = new_free_pointer;
1089         /* Check whether the current region is almost empty. */
1090         if ((my_region->end_addr - my_region->free_pointer) <= 32) {
1091             /* If so find, finished with the current region. */
1092             gc_alloc_update_page_tables(unboxed_p, my_region);
1093
1094             /* Set up a new region. */
1095             gc_alloc_new_region(32, unboxed_p, my_region);
1096         }
1097
1098         return((void *)new_obj);
1099     }
1100
1101     /* shouldn't happen */
1102     gc_assert(0);
1103     return((void *) NIL); /* dummy value: return something ... */
1104 }
1105
1106 void *
1107 gc_general_alloc(int nbytes,int unboxed_p,int quick_p)
1108 {
1109     struct alloc_region *my_region = 
1110       unboxed_p ? &unboxed_region : &boxed_region;
1111     return gc_alloc_with_region(nbytes,unboxed_p, my_region,quick_p);
1112 }
1113
1114
1115
1116 static void *
1117 gc_alloc(int nbytes,int unboxed_p)
1118 {
1119     /* this is the only function that the external interface to
1120      * allocation presently knows how to call: Lisp code will never
1121      * allocate large objects, or to unboxed space, or `quick'ly.
1122      * Any of that stuff will only ever happen inside of GC */
1123     return gc_general_alloc(nbytes,unboxed_p,0);
1124 }
1125
1126 /* Allocate space from the boxed_region. If there is not enough free
1127  * space then call gc_alloc to do the job. A pointer to the start of
1128  * the object is returned. */
1129 static inline void *
1130 gc_quick_alloc(int nbytes)
1131 {
1132     return gc_general_alloc(nbytes,ALLOC_BOXED,ALLOC_QUICK);
1133 }
1134
1135 /* Allocate space for the possibly large boxed object. If it is a
1136  * large object then do a large alloc else use gc_quick_alloc.  Note
1137  * that gc_quick_alloc will eventually fall through to
1138  * gc_general_alloc which may allocate the object in a large way
1139  * anyway, but based on decisions about the free space in the current
1140  * region, not the object size itself */
1141
1142 static inline void *
1143 gc_quick_alloc_large(int nbytes)
1144 {
1145     if (nbytes >= large_object_size)
1146         return gc_alloc_large(nbytes, ALLOC_BOXED, &boxed_region);
1147     else
1148         return gc_general_alloc(nbytes,ALLOC_BOXED,ALLOC_QUICK);
1149 }
1150
1151 static inline void *
1152 gc_alloc_unboxed(int nbytes)
1153 {
1154     return gc_general_alloc(nbytes,ALLOC_UNBOXED,0);
1155 }
1156
1157 static inline void *
1158 gc_quick_alloc_unboxed(int nbytes)
1159 {
1160     return gc_general_alloc(nbytes,ALLOC_UNBOXED,ALLOC_QUICK);
1161 }
1162
1163 /* Allocate space for the object. If it is a large object then do a
1164  * large alloc else allocate from the current region. If there is not
1165  * enough free space then call general gc_alloc_unboxed() to do the job.
1166  *
1167  * A pointer to the start of the object is returned. */
1168 static inline void *
1169 gc_quick_alloc_large_unboxed(int nbytes)
1170 {
1171     if (nbytes >= large_object_size)
1172         return gc_alloc_large(nbytes,ALLOC_UNBOXED,&unboxed_region);
1173     else
1174         return gc_quick_alloc_unboxed(nbytes);
1175 }
1176 \f
1177 /*
1178  * scavenging/transporting routines derived from gc.c in CMU CL ca. 18b
1179  */
1180
1181 extern int (*scavtab[256])(lispobj *where, lispobj object);
1182 extern lispobj (*transother[256])(lispobj object);
1183 extern int (*sizetab[256])(lispobj *where);
1184
1185 /* Copy a large boxed object. If the object is in a large object
1186  * region then it is simply promoted, else it is copied. If it's large
1187  * enough then it's copied to a large object region.
1188  *
1189  * Vectors may have shrunk. If the object is not copied the space
1190  * needs to be reclaimed, and the page_tables corrected. */
1191 lispobj
1192 copy_large_object(lispobj object, int nwords)
1193 {
1194     int tag;
1195     lispobj *new;
1196     lispobj *source, *dest;
1197     int first_page;
1198
1199     gc_assert(is_lisp_pointer(object));
1200     gc_assert(from_space_p(object));
1201     gc_assert((nwords & 0x01) == 0);
1202
1203
1204     /* Check whether it's a large object. */
1205     first_page = find_page_index((void *)object);
1206     gc_assert(first_page >= 0);
1207
1208     if (page_table[first_page].large_object) {
1209
1210         /* Promote the object. */
1211
1212         int remaining_bytes;
1213         int next_page;
1214         int bytes_freed;
1215         int old_bytes_used;
1216
1217         /* Note: Any page write-protection must be removed, else a
1218          * later scavenge_newspace may incorrectly not scavenge these
1219          * pages. This would not be necessary if they are added to the
1220          * new areas, but let's do it for them all (they'll probably
1221          * be written anyway?). */
1222
1223         gc_assert(page_table[first_page].first_object_offset == 0);
1224
1225         next_page = first_page;
1226         remaining_bytes = nwords*4;
1227         while (remaining_bytes > 4096) {
1228             gc_assert(page_table[next_page].gen == from_space);
1229             gc_assert(page_table[next_page].allocated == BOXED_PAGE);
1230             gc_assert(page_table[next_page].large_object);
1231             gc_assert(page_table[next_page].first_object_offset==
1232                       -4096*(next_page-first_page));
1233             gc_assert(page_table[next_page].bytes_used == 4096);
1234
1235             page_table[next_page].gen = new_space;
1236
1237             /* Remove any write-protection. We should be able to rely
1238              * on the write-protect flag to avoid redundant calls. */
1239             if (page_table[next_page].write_protected) {
1240                 os_protect(page_address(next_page), 4096, OS_VM_PROT_ALL);
1241                 page_table[next_page].write_protected = 0;
1242             }
1243             remaining_bytes -= 4096;
1244             next_page++;
1245         }
1246
1247         /* Now only one page remains, but the object may have shrunk
1248          * so there may be more unused pages which will be freed. */
1249
1250         /* The object may have shrunk but shouldn't have grown. */
1251         gc_assert(page_table[next_page].bytes_used >= remaining_bytes);
1252
1253         page_table[next_page].gen = new_space;
1254         gc_assert(page_table[next_page].allocated == BOXED_PAGE);
1255
1256         /* Adjust the bytes_used. */
1257         old_bytes_used = page_table[next_page].bytes_used;
1258         page_table[next_page].bytes_used = remaining_bytes;
1259
1260         bytes_freed = old_bytes_used - remaining_bytes;
1261
1262         /* Free any remaining pages; needs care. */
1263         next_page++;
1264         while ((old_bytes_used == 4096) &&
1265                (page_table[next_page].gen == from_space) &&
1266                (page_table[next_page].allocated == BOXED_PAGE) &&
1267                page_table[next_page].large_object &&
1268                (page_table[next_page].first_object_offset ==
1269                 -(next_page - first_page)*4096)) {
1270             /* Checks out OK, free the page. Don't need to bother zeroing
1271              * pages as this should have been done before shrinking the
1272              * object. These pages shouldn't be write-protected as they
1273              * should be zero filled. */
1274             gc_assert(page_table[next_page].write_protected == 0);
1275
1276             old_bytes_used = page_table[next_page].bytes_used;
1277             page_table[next_page].allocated = FREE_PAGE;
1278             page_table[next_page].bytes_used = 0;
1279             bytes_freed += old_bytes_used;
1280             next_page++;
1281         }
1282
1283         generations[from_space].bytes_allocated -= 4*nwords + bytes_freed;
1284         generations[new_space].bytes_allocated += 4*nwords;
1285         bytes_allocated -= bytes_freed;
1286
1287         /* Add the region to the new_areas if requested. */
1288         add_new_area(first_page,0,nwords*4);
1289
1290         return(object);
1291     } else {
1292         /* Get tag of object. */
1293         tag = lowtag_of(object);
1294
1295         /* Allocate space. */
1296         new = gc_quick_alloc_large(nwords*4);
1297
1298         dest = new;
1299         source = (lispobj *) native_pointer(object);
1300
1301         /* Copy the object. */
1302         while (nwords > 0) {
1303             dest[0] = source[0];
1304             dest[1] = source[1];
1305             dest += 2;
1306             source += 2;
1307             nwords -= 2;
1308         }
1309
1310         /* Return Lisp pointer of new object. */
1311         return ((lispobj) new) | tag;
1312     }
1313 }
1314
1315 /* to copy unboxed objects */
1316 lispobj
1317 copy_unboxed_object(lispobj object, int nwords)
1318 {
1319     int tag;
1320     lispobj *new;
1321     lispobj *source, *dest;
1322
1323     gc_assert(is_lisp_pointer(object));
1324     gc_assert(from_space_p(object));
1325     gc_assert((nwords & 0x01) == 0);
1326
1327     /* Get tag of object. */
1328     tag = lowtag_of(object);
1329
1330     /* Allocate space. */
1331     new = gc_quick_alloc_unboxed(nwords*4);
1332
1333     dest = new;
1334     source = (lispobj *) native_pointer(object);
1335
1336     /* Copy the object. */
1337     while (nwords > 0) {
1338         dest[0] = source[0];
1339         dest[1] = source[1];
1340         dest += 2;
1341         source += 2;
1342         nwords -= 2;
1343     }
1344
1345     /* Return Lisp pointer of new object. */
1346     return ((lispobj) new) | tag;
1347 }
1348
1349 /* to copy large unboxed objects
1350  *
1351  * If the object is in a large object region then it is simply
1352  * promoted, else it is copied. If it's large enough then it's copied
1353  * to a large object region.
1354  *
1355  * Bignums and vectors may have shrunk. If the object is not copied
1356  * the space needs to be reclaimed, and the page_tables corrected.
1357  *
1358  * KLUDGE: There's a lot of cut-and-paste duplication between this
1359  * function and copy_large_object(..). -- WHN 20000619 */
1360 lispobj
1361 copy_large_unboxed_object(lispobj object, int nwords)
1362 {
1363     int tag;
1364     lispobj *new;
1365     lispobj *source, *dest;
1366     int first_page;
1367
1368     gc_assert(is_lisp_pointer(object));
1369     gc_assert(from_space_p(object));
1370     gc_assert((nwords & 0x01) == 0);
1371
1372     if ((nwords > 1024*1024) && gencgc_verbose)
1373         FSHOW((stderr, "/copy_large_unboxed_object: %d bytes\n", nwords*4));
1374
1375     /* Check whether it's a large object. */
1376     first_page = find_page_index((void *)object);
1377     gc_assert(first_page >= 0);
1378
1379     if (page_table[first_page].large_object) {
1380         /* Promote the object. Note: Unboxed objects may have been
1381          * allocated to a BOXED region so it may be necessary to
1382          * change the region to UNBOXED. */
1383         int remaining_bytes;
1384         int next_page;
1385         int bytes_freed;
1386         int old_bytes_used;
1387
1388         gc_assert(page_table[first_page].first_object_offset == 0);
1389
1390         next_page = first_page;
1391         remaining_bytes = nwords*4;
1392         while (remaining_bytes > 4096) {
1393             gc_assert(page_table[next_page].gen == from_space);
1394             gc_assert((page_table[next_page].allocated == UNBOXED_PAGE)
1395                       || (page_table[next_page].allocated == BOXED_PAGE));
1396             gc_assert(page_table[next_page].large_object);
1397             gc_assert(page_table[next_page].first_object_offset==
1398                       -4096*(next_page-first_page));
1399             gc_assert(page_table[next_page].bytes_used == 4096);
1400
1401             page_table[next_page].gen = new_space;
1402             page_table[next_page].allocated = UNBOXED_PAGE;
1403             remaining_bytes -= 4096;
1404             next_page++;
1405         }
1406
1407         /* Now only one page remains, but the object may have shrunk so
1408          * there may be more unused pages which will be freed. */
1409
1410         /* Object may have shrunk but shouldn't have grown - check. */
1411         gc_assert(page_table[next_page].bytes_used >= remaining_bytes);
1412
1413         page_table[next_page].gen = new_space;
1414         page_table[next_page].allocated = UNBOXED_PAGE;
1415
1416         /* Adjust the bytes_used. */
1417         old_bytes_used = page_table[next_page].bytes_used;
1418         page_table[next_page].bytes_used = remaining_bytes;
1419
1420         bytes_freed = old_bytes_used - remaining_bytes;
1421
1422         /* Free any remaining pages; needs care. */
1423         next_page++;
1424         while ((old_bytes_used == 4096) &&
1425                (page_table[next_page].gen == from_space) &&
1426                ((page_table[next_page].allocated == UNBOXED_PAGE)
1427                 || (page_table[next_page].allocated == BOXED_PAGE)) &&
1428                page_table[next_page].large_object &&
1429                (page_table[next_page].first_object_offset ==
1430                 -(next_page - first_page)*4096)) {
1431             /* Checks out OK, free the page. Don't need to both zeroing
1432              * pages as this should have been done before shrinking the
1433              * object. These pages shouldn't be write-protected, even if
1434              * boxed they should be zero filled. */
1435             gc_assert(page_table[next_page].write_protected == 0);
1436
1437             old_bytes_used = page_table[next_page].bytes_used;
1438             page_table[next_page].allocated = FREE_PAGE;
1439             page_table[next_page].bytes_used = 0;
1440             bytes_freed += old_bytes_used;
1441             next_page++;
1442         }
1443
1444         if ((bytes_freed > 0) && gencgc_verbose)
1445             FSHOW((stderr,
1446                    "/copy_large_unboxed bytes_freed=%d\n",
1447                    bytes_freed));
1448
1449         generations[from_space].bytes_allocated -= 4*nwords + bytes_freed;
1450         generations[new_space].bytes_allocated += 4*nwords;
1451         bytes_allocated -= bytes_freed;
1452
1453         return(object);
1454     }
1455     else {
1456         /* Get tag of object. */
1457         tag = lowtag_of(object);
1458
1459         /* Allocate space. */
1460         new = gc_quick_alloc_large_unboxed(nwords*4);
1461
1462         dest = new;
1463         source = (lispobj *) native_pointer(object);
1464
1465         /* Copy the object. */
1466         while (nwords > 0) {
1467             dest[0] = source[0];
1468             dest[1] = source[1];
1469             dest += 2;
1470             source += 2;
1471             nwords -= 2;
1472         }
1473
1474         /* Return Lisp pointer of new object. */
1475         return ((lispobj) new) | tag;
1476     }
1477 }
1478
1479
1480
1481 \f
1482
1483 /*
1484  * code and code-related objects
1485  */
1486 /*
1487 static lispobj trans_fun_header(lispobj object);
1488 static lispobj trans_boxed(lispobj object);
1489 */
1490
1491 /* Scan a x86 compiled code object, looking for possible fixups that
1492  * have been missed after a move.
1493  *
1494  * Two types of fixups are needed:
1495  * 1. Absolute fixups to within the code object.
1496  * 2. Relative fixups to outside the code object.
1497  *
1498  * Currently only absolute fixups to the constant vector, or to the
1499  * code area are checked. */
1500 void
1501 sniff_code_object(struct code *code, unsigned displacement)
1502 {
1503     int nheader_words, ncode_words, nwords;
1504     void *p;
1505     void *constants_start_addr, *constants_end_addr;
1506     void *code_start_addr, *code_end_addr;
1507     int fixup_found = 0;
1508
1509     if (!check_code_fixups)
1510         return;
1511
1512     ncode_words = fixnum_value(code->code_size);
1513     nheader_words = HeaderValue(*(lispobj *)code);
1514     nwords = ncode_words + nheader_words;
1515
1516     constants_start_addr = (void *)code + 5*4;
1517     constants_end_addr = (void *)code + nheader_words*4;
1518     code_start_addr = (void *)code + nheader_words*4;
1519     code_end_addr = (void *)code + nwords*4;
1520
1521     /* Work through the unboxed code. */
1522     for (p = code_start_addr; p < code_end_addr; p++) {
1523         void *data = *(void **)p;
1524         unsigned d1 = *((unsigned char *)p - 1);
1525         unsigned d2 = *((unsigned char *)p - 2);
1526         unsigned d3 = *((unsigned char *)p - 3);
1527         unsigned d4 = *((unsigned char *)p - 4);
1528 #if QSHOW
1529         unsigned d5 = *((unsigned char *)p - 5);
1530         unsigned d6 = *((unsigned char *)p - 6);
1531 #endif
1532
1533         /* Check for code references. */
1534         /* Check for a 32 bit word that looks like an absolute
1535            reference to within the code adea of the code object. */
1536         if ((data >= (code_start_addr-displacement))
1537             && (data < (code_end_addr-displacement))) {
1538             /* function header */
1539             if ((d4 == 0x5e)
1540                 && (((unsigned)p - 4 - 4*HeaderValue(*((unsigned *)p-1))) == (unsigned)code)) {
1541                 /* Skip the function header */
1542                 p += 6*4 - 4 - 1;
1543                 continue;
1544             }
1545             /* the case of PUSH imm32 */
1546             if (d1 == 0x68) {
1547                 fixup_found = 1;
1548                 FSHOW((stderr,
1549                        "/code ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1550                        p, d6, d5, d4, d3, d2, d1, data));
1551                 FSHOW((stderr, "/PUSH $0x%.8x\n", data));
1552             }
1553             /* the case of MOV [reg-8],imm32 */
1554             if ((d3 == 0xc7)
1555                 && (d2==0x40 || d2==0x41 || d2==0x42 || d2==0x43
1556                     || d2==0x45 || d2==0x46 || d2==0x47)
1557                 && (d1 == 0xf8)) {
1558                 fixup_found = 1;
1559                 FSHOW((stderr,
1560                        "/code ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1561                        p, d6, d5, d4, d3, d2, d1, data));
1562                 FSHOW((stderr, "/MOV [reg-8],$0x%.8x\n", data));
1563             }
1564             /* the case of LEA reg,[disp32] */
1565             if ((d2 == 0x8d) && ((d1 & 0xc7) == 5)) {
1566                 fixup_found = 1;
1567                 FSHOW((stderr,
1568                        "/code ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1569                        p, d6, d5, d4, d3, d2, d1, data));
1570                 FSHOW((stderr,"/LEA reg,[$0x%.8x]\n", data));
1571             }
1572         }
1573
1574         /* Check for constant references. */
1575         /* Check for a 32 bit word that looks like an absolute
1576            reference to within the constant vector. Constant references
1577            will be aligned. */
1578         if ((data >= (constants_start_addr-displacement))
1579             && (data < (constants_end_addr-displacement))
1580             && (((unsigned)data & 0x3) == 0)) {
1581             /*  Mov eax,m32 */
1582             if (d1 == 0xa1) {
1583                 fixup_found = 1;
1584                 FSHOW((stderr,
1585                        "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1586                        p, d6, d5, d4, d3, d2, d1, data));
1587                 FSHOW((stderr,"/MOV eax,0x%.8x\n", data));
1588             }
1589
1590             /*  the case of MOV m32,EAX */
1591             if (d1 == 0xa3) {
1592                 fixup_found = 1;
1593                 FSHOW((stderr,
1594                        "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1595                        p, d6, d5, d4, d3, d2, d1, data));
1596                 FSHOW((stderr, "/MOV 0x%.8x,eax\n", data));
1597             }
1598
1599             /* the case of CMP m32,imm32 */             
1600             if ((d1 == 0x3d) && (d2 == 0x81)) {
1601                 fixup_found = 1;
1602                 FSHOW((stderr,
1603                        "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1604                        p, d6, d5, d4, d3, d2, d1, data));
1605                 /* XX Check this */
1606                 FSHOW((stderr, "/CMP 0x%.8x,immed32\n", data));
1607             }
1608
1609             /* Check for a mod=00, r/m=101 byte. */
1610             if ((d1 & 0xc7) == 5) {
1611                 /* Cmp m32,reg */
1612                 if (d2 == 0x39) {
1613                     fixup_found = 1;
1614                     FSHOW((stderr,
1615                            "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1616                            p, d6, d5, d4, d3, d2, d1, data));
1617                     FSHOW((stderr,"/CMP 0x%.8x,reg\n", data));
1618                 }
1619                 /* the case of CMP reg32,m32 */
1620                 if (d2 == 0x3b) {
1621                     fixup_found = 1;
1622                     FSHOW((stderr,
1623                            "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1624                            p, d6, d5, d4, d3, d2, d1, data));
1625                     FSHOW((stderr, "/CMP reg32,0x%.8x\n", data));
1626                 }
1627                 /* the case of MOV m32,reg32 */
1628                 if (d2 == 0x89) {
1629                     fixup_found = 1;
1630                     FSHOW((stderr,
1631                            "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1632                            p, d6, d5, d4, d3, d2, d1, data));
1633                     FSHOW((stderr, "/MOV 0x%.8x,reg32\n", data));
1634                 }
1635                 /* the case of MOV reg32,m32 */
1636                 if (d2 == 0x8b) {
1637                     fixup_found = 1;
1638                     FSHOW((stderr,
1639                            "/abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1640                            p, d6, d5, d4, d3, d2, d1, data));
1641                     FSHOW((stderr, "/MOV reg32,0x%.8x\n", data));
1642                 }
1643                 /* the case of LEA reg32,m32 */
1644                 if (d2 == 0x8d) {
1645                     fixup_found = 1;
1646                     FSHOW((stderr,
1647                            "abs const ref @%x: %.2x %.2x %.2x %.2x %.2x %.2x (%.8x)\n",
1648                            p, d6, d5, d4, d3, d2, d1, data));
1649                     FSHOW((stderr, "/LEA reg32,0x%.8x\n", data));
1650                 }
1651             }
1652         }
1653     }
1654
1655     /* If anything was found, print some information on the code
1656      * object. */
1657     if (fixup_found) {
1658         FSHOW((stderr,
1659                "/compiled code object at %x: header words = %d, code words = %d\n",
1660                code, nheader_words, ncode_words));
1661         FSHOW((stderr,
1662                "/const start = %x, end = %x\n",
1663                constants_start_addr, constants_end_addr));
1664         FSHOW((stderr,
1665                "/code start = %x, end = %x\n",
1666                code_start_addr, code_end_addr));
1667     }
1668 }
1669
1670 void
1671 gencgc_apply_code_fixups(struct code *old_code, struct code *new_code)
1672 {
1673     int nheader_words, ncode_words, nwords;
1674     void *constants_start_addr, *constants_end_addr;
1675     void *code_start_addr, *code_end_addr;
1676     lispobj fixups = NIL;
1677     unsigned displacement = (unsigned)new_code - (unsigned)old_code;
1678     struct vector *fixups_vector;
1679
1680     ncode_words = fixnum_value(new_code->code_size);
1681     nheader_words = HeaderValue(*(lispobj *)new_code);
1682     nwords = ncode_words + nheader_words;
1683     /* FSHOW((stderr,
1684              "/compiled code object at %x: header words = %d, code words = %d\n",
1685              new_code, nheader_words, ncode_words)); */
1686     constants_start_addr = (void *)new_code + 5*4;
1687     constants_end_addr = (void *)new_code + nheader_words*4;
1688     code_start_addr = (void *)new_code + nheader_words*4;
1689     code_end_addr = (void *)new_code + nwords*4;
1690     /*
1691     FSHOW((stderr,
1692            "/const start = %x, end = %x\n",
1693            constants_start_addr,constants_end_addr));
1694     FSHOW((stderr,
1695            "/code start = %x; end = %x\n",
1696            code_start_addr,code_end_addr));
1697     */
1698
1699     /* The first constant should be a pointer to the fixups for this
1700        code objects. Check. */
1701     fixups = new_code->constants[0];
1702
1703     /* It will be 0 or the unbound-marker if there are no fixups, and
1704      * will be an other pointer if it is valid. */
1705     if ((fixups == 0) || (fixups == UNBOUND_MARKER_WIDETAG) ||
1706         !is_lisp_pointer(fixups)) {
1707         /* Check for possible errors. */
1708         if (check_code_fixups)
1709             sniff_code_object(new_code, displacement);
1710
1711         /*fprintf(stderr,"Fixups for code object not found!?\n");
1712           fprintf(stderr,"*** Compiled code object at %x: header_words=%d code_words=%d .\n",
1713           new_code, nheader_words, ncode_words);
1714           fprintf(stderr,"*** Const. start = %x; end= %x; Code start = %x; end = %x\n",
1715           constants_start_addr,constants_end_addr,
1716           code_start_addr,code_end_addr);*/
1717         return;
1718     }
1719
1720     fixups_vector = (struct vector *)native_pointer(fixups);
1721
1722     /* Could be pointing to a forwarding pointer. */
1723     if (is_lisp_pointer(fixups) &&
1724         (find_page_index((void*)fixups_vector) != -1) &&
1725         (fixups_vector->header == 0x01)) {
1726         /* If so, then follow it. */
1727         /*SHOW("following pointer to a forwarding pointer");*/
1728         fixups_vector = (struct vector *)native_pointer((lispobj)fixups_vector->length);
1729     }
1730
1731     /*SHOW("got fixups");*/
1732
1733     if (widetag_of(fixups_vector->header) ==
1734         SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG) {
1735         /* Got the fixups for the code block. Now work through the vector,
1736            and apply a fixup at each address. */
1737         int length = fixnum_value(fixups_vector->length);
1738         int i;
1739         for (i = 0; i < length; i++) {
1740             unsigned offset = fixups_vector->data[i];
1741             /* Now check the current value of offset. */
1742             unsigned old_value =
1743                 *(unsigned *)((unsigned)code_start_addr + offset);
1744
1745             /* If it's within the old_code object then it must be an
1746              * absolute fixup (relative ones are not saved) */
1747             if ((old_value >= (unsigned)old_code)
1748                 && (old_value < ((unsigned)old_code + nwords*4)))
1749                 /* So add the dispacement. */
1750                 *(unsigned *)((unsigned)code_start_addr + offset) =
1751                     old_value + displacement;
1752             else
1753                 /* It is outside the old code object so it must be a
1754                  * relative fixup (absolute fixups are not saved). So
1755                  * subtract the displacement. */
1756                 *(unsigned *)((unsigned)code_start_addr + offset) =
1757                     old_value - displacement;
1758         }
1759     }
1760
1761     /* Check for possible errors. */
1762     if (check_code_fixups) {
1763         sniff_code_object(new_code,displacement);
1764     }
1765 }
1766
1767
1768 static lispobj
1769 trans_boxed_large(lispobj object)
1770 {
1771     lispobj header;
1772     unsigned long length;
1773
1774     gc_assert(is_lisp_pointer(object));
1775
1776     header = *((lispobj *) native_pointer(object));
1777     length = HeaderValue(header) + 1;
1778     length = CEILING(length, 2);
1779
1780     return copy_large_object(object, length);
1781 }
1782
1783
1784 static lispobj
1785 trans_unboxed_large(lispobj object)
1786 {
1787     lispobj header;
1788     unsigned long length;
1789
1790
1791     gc_assert(is_lisp_pointer(object));
1792
1793     header = *((lispobj *) native_pointer(object));
1794     length = HeaderValue(header) + 1;
1795     length = CEILING(length, 2);
1796
1797     return copy_large_unboxed_object(object, length);
1798 }
1799
1800 \f
1801 /*
1802  * vector-like objects
1803  */
1804
1805
1806 /* FIXME: What does this mean? */
1807 int gencgc_hash = 1;
1808
1809 static int
1810 scav_vector(lispobj *where, lispobj object)
1811 {
1812     unsigned int kv_length;
1813     lispobj *kv_vector;
1814     unsigned int length = 0; /* (0 = dummy to stop GCC warning) */
1815     lispobj *hash_table;
1816     lispobj empty_symbol;
1817     unsigned int *index_vector = NULL; /* (NULL = dummy to stop GCC warning) */
1818     unsigned int *next_vector = NULL; /* (NULL = dummy to stop GCC warning) */
1819     unsigned int *hash_vector = NULL; /* (NULL = dummy to stop GCC warning) */
1820     lispobj weak_p_obj;
1821     unsigned next_vector_length = 0;
1822
1823     /* FIXME: A comment explaining this would be nice. It looks as
1824      * though SB-VM:VECTOR-VALID-HASHING-SUBTYPE is set for EQ-based
1825      * hash tables in the Lisp HASH-TABLE code, and nowhere else. */
1826     if (HeaderValue(object) != subtype_VectorValidHashing)
1827         return 1;
1828
1829     if (!gencgc_hash) {
1830         /* This is set for backward compatibility. FIXME: Do we need
1831          * this any more? */
1832         *where =
1833             (subtype_VectorMustRehash<<N_WIDETAG_BITS) | SIMPLE_VECTOR_WIDETAG;
1834         return 1;
1835     }
1836
1837     kv_length = fixnum_value(where[1]);
1838     kv_vector = where + 2;  /* Skip the header and length. */
1839     /*FSHOW((stderr,"/kv_length = %d\n", kv_length));*/
1840
1841     /* Scavenge element 0, which may be a hash-table structure. */
1842     scavenge(where+2, 1);
1843     if (!is_lisp_pointer(where[2])) {
1844         lose("no pointer at %x in hash table", where[2]);
1845     }
1846     hash_table = (lispobj *)native_pointer(where[2]);
1847     /*FSHOW((stderr,"/hash_table = %x\n", hash_table));*/
1848     if (widetag_of(hash_table[0]) != INSTANCE_HEADER_WIDETAG) {
1849         lose("hash table not instance (%x at %x)", hash_table[0], hash_table);
1850     }
1851
1852     /* Scavenge element 1, which should be some internal symbol that
1853      * the hash table code reserves for marking empty slots. */
1854     scavenge(where+3, 1);
1855     if (!is_lisp_pointer(where[3])) {
1856         lose("not empty-hash-table-slot symbol pointer: %x", where[3]);
1857     }
1858     empty_symbol = where[3];
1859     /* fprintf(stderr,"* empty_symbol = %x\n", empty_symbol);*/
1860     if (widetag_of(*(lispobj *)native_pointer(empty_symbol)) !=
1861         SYMBOL_HEADER_WIDETAG) {
1862         lose("not a symbol where empty-hash-table-slot symbol expected: %x",
1863              *(lispobj *)native_pointer(empty_symbol));
1864     }
1865
1866     /* Scavenge hash table, which will fix the positions of the other
1867      * needed objects. */
1868     scavenge(hash_table, 16);
1869
1870     /* Cross-check the kv_vector. */
1871     if (where != (lispobj *)native_pointer(hash_table[9])) {
1872         lose("hash_table table!=this table %x", hash_table[9]);
1873     }
1874
1875     /* WEAK-P */
1876     weak_p_obj = hash_table[10];
1877
1878     /* index vector */
1879     {
1880         lispobj index_vector_obj = hash_table[13];
1881
1882         if (is_lisp_pointer(index_vector_obj) &&
1883             (widetag_of(*(lispobj *)native_pointer(index_vector_obj)) ==
1884              SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
1885             index_vector = ((unsigned int *)native_pointer(index_vector_obj)) + 2;
1886             /*FSHOW((stderr, "/index_vector = %x\n",index_vector));*/
1887             length = fixnum_value(((unsigned int *)native_pointer(index_vector_obj))[1]);
1888             /*FSHOW((stderr, "/length = %d\n", length));*/
1889         } else {
1890             lose("invalid index_vector %x", index_vector_obj);
1891         }
1892     }
1893
1894     /* next vector */
1895     {
1896         lispobj next_vector_obj = hash_table[14];
1897
1898         if (is_lisp_pointer(next_vector_obj) &&
1899             (widetag_of(*(lispobj *)native_pointer(next_vector_obj)) ==
1900              SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
1901             next_vector = ((unsigned int *)native_pointer(next_vector_obj)) + 2;
1902             /*FSHOW((stderr, "/next_vector = %x\n", next_vector));*/
1903             next_vector_length = fixnum_value(((unsigned int *)native_pointer(next_vector_obj))[1]);
1904             /*FSHOW((stderr, "/next_vector_length = %d\n", next_vector_length));*/
1905         } else {
1906             lose("invalid next_vector %x", next_vector_obj);
1907         }
1908     }
1909
1910     /* maybe hash vector */
1911     {
1912         /* FIXME: This bare "15" offset should become a symbolic
1913          * expression of some sort. And all the other bare offsets
1914          * too. And the bare "16" in scavenge(hash_table, 16). And
1915          * probably other stuff too. Ugh.. */
1916         lispobj hash_vector_obj = hash_table[15];
1917
1918         if (is_lisp_pointer(hash_vector_obj) &&
1919             (widetag_of(*(lispobj *)native_pointer(hash_vector_obj))
1920              == SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG)) {
1921             hash_vector = ((unsigned int *)native_pointer(hash_vector_obj)) + 2;
1922             /*FSHOW((stderr, "/hash_vector = %x\n", hash_vector));*/
1923             gc_assert(fixnum_value(((unsigned int *)native_pointer(hash_vector_obj))[1])
1924                       == next_vector_length);
1925         } else {
1926             hash_vector = NULL;
1927             /*FSHOW((stderr, "/no hash_vector: %x\n", hash_vector_obj));*/
1928         }
1929     }
1930
1931     /* These lengths could be different as the index_vector can be a
1932      * different length from the others, a larger index_vector could help
1933      * reduce collisions. */
1934     gc_assert(next_vector_length*2 == kv_length);
1935
1936     /* now all set up.. */
1937
1938     /* Work through the KV vector. */
1939     {
1940         int i;
1941         for (i = 1; i < next_vector_length; i++) {
1942             lispobj old_key = kv_vector[2*i];
1943             unsigned int  old_index = (old_key & 0x1fffffff)%length;
1944
1945             /* Scavenge the key and value. */
1946             scavenge(&kv_vector[2*i],2);
1947
1948             /* Check whether the key has moved and is EQ based. */
1949             {
1950                 lispobj new_key = kv_vector[2*i];
1951                 unsigned int new_index = (new_key & 0x1fffffff)%length;
1952
1953                 if ((old_index != new_index) &&
1954                     ((!hash_vector) || (hash_vector[i] == 0x80000000)) &&
1955                     ((new_key != empty_symbol) ||
1956                      (kv_vector[2*i] != empty_symbol))) {
1957
1958                     /*FSHOW((stderr,
1959                            "* EQ key %d moved from %x to %x; index %d to %d\n",
1960                            i, old_key, new_key, old_index, new_index));*/
1961
1962                     if (index_vector[old_index] != 0) {
1963                         /*FSHOW((stderr, "/P1 %d\n", index_vector[old_index]));*/
1964
1965                         /* Unlink the key from the old_index chain. */
1966                         if (index_vector[old_index] == i) {
1967                             /*FSHOW((stderr, "/P2a %d\n", next_vector[i]));*/
1968                             index_vector[old_index] = next_vector[i];
1969                             /* Link it into the needing rehash chain. */
1970                             next_vector[i] = fixnum_value(hash_table[11]);
1971                             hash_table[11] = make_fixnum(i);
1972                             /*SHOW("P2");*/
1973                         } else {
1974                             unsigned prior = index_vector[old_index];
1975                             unsigned next = next_vector[prior];
1976
1977                             /*FSHOW((stderr, "/P3a %d %d\n", prior, next));*/
1978
1979                             while (next != 0) {
1980                                 /*FSHOW((stderr, "/P3b %d %d\n", prior, next));*/
1981                                 if (next == i) {
1982                                     /* Unlink it. */
1983                                     next_vector[prior] = next_vector[next];
1984                                     /* Link it into the needing rehash
1985                                      * chain. */
1986                                     next_vector[next] =
1987                                         fixnum_value(hash_table[11]);
1988                                     hash_table[11] = make_fixnum(next);
1989                                     /*SHOW("/P3");*/
1990                                     break;
1991                                 }
1992                                 prior = next;
1993                                 next = next_vector[next];
1994                             }
1995                         }
1996                     }
1997                 }
1998             }
1999         }
2000     }
2001     return (CEILING(kv_length + 2, 2));
2002 }
2003
2004
2005 \f
2006 /*
2007  * weak pointers
2008  */
2009
2010 /* XX This is a hack adapted from cgc.c. These don't work too
2011  * efficiently with the gencgc as a list of the weak pointers is
2012  * maintained within the objects which causes writes to the pages. A
2013  * limited attempt is made to avoid unnecessary writes, but this needs
2014  * a re-think. */
2015 #define WEAK_POINTER_NWORDS \
2016     CEILING((sizeof(struct weak_pointer) / sizeof(lispobj)), 2)
2017
2018 static int
2019 scav_weak_pointer(lispobj *where, lispobj object)
2020 {
2021     struct weak_pointer *wp = weak_pointers;
2022     /* Push the weak pointer onto the list of weak pointers.
2023      * Do I have to watch for duplicates? Originally this was
2024      * part of trans_weak_pointer but that didn't work in the
2025      * case where the WP was in a promoted region.
2026      */
2027
2028     /* Check whether it's already in the list. */
2029     while (wp != NULL) {
2030         if (wp == (struct weak_pointer*)where) {
2031             break;
2032         }
2033         wp = wp->next;
2034     }
2035     if (wp == NULL) {
2036         /* Add it to the start of the list. */
2037         wp = (struct weak_pointer*)where;
2038         if (wp->next != weak_pointers) {
2039             wp->next = weak_pointers;
2040         } else {
2041             /*SHOW("avoided write to weak pointer");*/
2042         }
2043         weak_pointers = wp;
2044     }
2045
2046     /* Do not let GC scavenge the value slot of the weak pointer.
2047      * (That is why it is a weak pointer.) */
2048
2049     return WEAK_POINTER_NWORDS;
2050 }
2051
2052 \f
2053 /* Scan an area looking for an object which encloses the given pointer.
2054  * Return the object start on success or NULL on failure. */
2055 static lispobj *
2056 search_space(lispobj *start, size_t words, lispobj *pointer)
2057 {
2058     while (words > 0) {
2059         size_t count = 1;
2060         lispobj thing = *start;
2061
2062         /* If thing is an immediate then this is a cons. */
2063         if (is_lisp_pointer(thing)
2064             || ((thing & 3) == 0) /* fixnum */
2065             || (widetag_of(thing) == BASE_CHAR_WIDETAG)
2066             || (widetag_of(thing) == UNBOUND_MARKER_WIDETAG))
2067             count = 2;
2068         else
2069             count = (sizetab[widetag_of(thing)])(start);
2070
2071         /* Check whether the pointer is within this object. */
2072         if ((pointer >= start) && (pointer < (start+count))) {
2073             /* found it! */
2074             /*FSHOW((stderr,"/found %x in %x %x\n", pointer, start, thing));*/
2075             return(start);
2076         }
2077
2078         /* Round up the count. */
2079         count = CEILING(count,2);
2080
2081         start += count;
2082         words -= count;
2083     }
2084     return (NULL);
2085 }
2086
2087 static lispobj*
2088 search_read_only_space(lispobj *pointer)
2089 {
2090     lispobj* start = (lispobj*)READ_ONLY_SPACE_START;
2091     lispobj* end = (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER);
2092     if ((pointer < start) || (pointer >= end))
2093         return NULL;
2094     return (search_space(start, (pointer+2)-start, pointer));
2095 }
2096
2097 static lispobj *
2098 search_static_space(lispobj *pointer)
2099 {
2100     lispobj* start = (lispobj*)STATIC_SPACE_START;
2101     lispobj* end = (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER);
2102     if ((pointer < start) || (pointer >= end))
2103         return NULL;
2104     return (search_space(start, (pointer+2)-start, pointer));
2105 }
2106
2107 /* a faster version for searching the dynamic space. This will work even
2108  * if the object is in a current allocation region. */
2109 lispobj *
2110 search_dynamic_space(lispobj *pointer)
2111 {
2112     int  page_index = find_page_index(pointer);
2113     lispobj *start;
2114
2115     /* The address may be invalid, so do some checks. */
2116     if ((page_index == -1) || (page_table[page_index].allocated == FREE_PAGE))
2117         return NULL;
2118     start = (lispobj *)((void *)page_address(page_index)
2119                         + page_table[page_index].first_object_offset);
2120     return (search_space(start, (pointer+2)-start, pointer));
2121 }
2122
2123 /* Is there any possibility that pointer is a valid Lisp object
2124  * reference, and/or something else (e.g. subroutine call return
2125  * address) which should prevent us from moving the referred-to thing? */
2126 static int
2127 possibly_valid_dynamic_space_pointer(lispobj *pointer)
2128 {
2129     lispobj *start_addr;
2130
2131     /* Find the object start address. */
2132     if ((start_addr = search_dynamic_space(pointer)) == NULL) {
2133         return 0;
2134     }
2135
2136     /* We need to allow raw pointers into Code objects for return
2137      * addresses. This will also pick up pointers to functions in code
2138      * objects. */
2139     if (widetag_of(*start_addr) == CODE_HEADER_WIDETAG) {
2140         /* XXX could do some further checks here */
2141         return 1;
2142     }
2143
2144     /* If it's not a return address then it needs to be a valid Lisp
2145      * pointer. */
2146     if (!is_lisp_pointer((lispobj)pointer)) {
2147         return 0;
2148     }
2149
2150     /* Check that the object pointed to is consistent with the pointer
2151      * low tag.
2152      *
2153      * FIXME: It's not safe to rely on the result from this check
2154      * before an object is initialized. Thus, if we were interrupted
2155      * just as an object had been allocated but not initialized, the
2156      * GC relying on this result could bogusly reclaim the memory.
2157      * However, we can't really afford to do without this check. So
2158      * we should make it safe somehow. 
2159      *   (1) Perhaps just review the code to make sure
2160      *       that WITHOUT-GCING or WITHOUT-INTERRUPTS or some such
2161      *       thing is wrapped around critical sections where allocated
2162      *       memory type bits haven't been set.
2163      *   (2) Perhaps find some other hack to protect against this, e.g.
2164      *       recording the result of the last call to allocate-lisp-memory,
2165      *       and returning true from this function when *pointer is
2166      *       a reference to that result. */
2167     switch (lowtag_of((lispobj)pointer)) {
2168     case FUN_POINTER_LOWTAG:
2169         /* Start_addr should be the enclosing code object, or a closure
2170          * header. */
2171         switch (widetag_of(*start_addr)) {
2172         case CODE_HEADER_WIDETAG:
2173             /* This case is probably caught above. */
2174             break;
2175         case CLOSURE_HEADER_WIDETAG:
2176         case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
2177             if ((unsigned)pointer !=
2178                 ((unsigned)start_addr+FUN_POINTER_LOWTAG)) {
2179                 if (gencgc_verbose)
2180                     FSHOW((stderr,
2181                            "/Wf2: %x %x %x\n",
2182                            pointer, start_addr, *start_addr));
2183                 return 0;
2184             }
2185             break;
2186         default:
2187             if (gencgc_verbose)
2188                 FSHOW((stderr,
2189                        "/Wf3: %x %x %x\n",
2190                        pointer, start_addr, *start_addr));
2191             return 0;
2192         }
2193         break;
2194     case LIST_POINTER_LOWTAG:
2195         if ((unsigned)pointer !=
2196             ((unsigned)start_addr+LIST_POINTER_LOWTAG)) {
2197             if (gencgc_verbose)
2198                 FSHOW((stderr,
2199                        "/Wl1: %x %x %x\n",
2200                        pointer, start_addr, *start_addr));
2201             return 0;
2202         }
2203         /* Is it plausible cons? */
2204         if ((is_lisp_pointer(start_addr[0])
2205             || ((start_addr[0] & 3) == 0) /* fixnum */
2206             || (widetag_of(start_addr[0]) == BASE_CHAR_WIDETAG)
2207             || (widetag_of(start_addr[0]) == UNBOUND_MARKER_WIDETAG))
2208            && (is_lisp_pointer(start_addr[1])
2209                || ((start_addr[1] & 3) == 0) /* fixnum */
2210                || (widetag_of(start_addr[1]) == BASE_CHAR_WIDETAG)
2211                || (widetag_of(start_addr[1]) == UNBOUND_MARKER_WIDETAG)))
2212             break;
2213         else {
2214             if (gencgc_verbose)
2215                 FSHOW((stderr,
2216                        "/Wl2: %x %x %x\n",
2217                        pointer, start_addr, *start_addr));
2218             return 0;
2219         }
2220     case INSTANCE_POINTER_LOWTAG:
2221         if ((unsigned)pointer !=
2222             ((unsigned)start_addr+INSTANCE_POINTER_LOWTAG)) {
2223             if (gencgc_verbose)
2224                 FSHOW((stderr,
2225                        "/Wi1: %x %x %x\n",
2226                        pointer, start_addr, *start_addr));
2227             return 0;
2228         }
2229         if (widetag_of(start_addr[0]) != INSTANCE_HEADER_WIDETAG) {
2230             if (gencgc_verbose)
2231                 FSHOW((stderr,
2232                        "/Wi2: %x %x %x\n",
2233                        pointer, start_addr, *start_addr));
2234             return 0;
2235         }
2236         break;
2237     case OTHER_POINTER_LOWTAG:
2238         if ((unsigned)pointer !=
2239             ((int)start_addr+OTHER_POINTER_LOWTAG)) {
2240             if (gencgc_verbose)
2241                 FSHOW((stderr,
2242                        "/Wo1: %x %x %x\n",
2243                        pointer, start_addr, *start_addr));
2244             return 0;
2245         }
2246         /* Is it plausible?  Not a cons. XXX should check the headers. */
2247         if (is_lisp_pointer(start_addr[0]) || ((start_addr[0] & 3) == 0)) {
2248             if (gencgc_verbose)
2249                 FSHOW((stderr,
2250                        "/Wo2: %x %x %x\n",
2251                        pointer, start_addr, *start_addr));
2252             return 0;
2253         }
2254         switch (widetag_of(start_addr[0])) {
2255         case UNBOUND_MARKER_WIDETAG:
2256         case BASE_CHAR_WIDETAG:
2257             if (gencgc_verbose)
2258                 FSHOW((stderr,
2259                        "*Wo3: %x %x %x\n",
2260                        pointer, start_addr, *start_addr));
2261             return 0;
2262
2263             /* only pointed to by function pointers? */
2264         case CLOSURE_HEADER_WIDETAG:
2265         case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
2266             if (gencgc_verbose)
2267                 FSHOW((stderr,
2268                        "*Wo4: %x %x %x\n",
2269                        pointer, start_addr, *start_addr));
2270             return 0;
2271
2272         case INSTANCE_HEADER_WIDETAG:
2273             if (gencgc_verbose)
2274                 FSHOW((stderr,
2275                        "*Wo5: %x %x %x\n",
2276                        pointer, start_addr, *start_addr));
2277             return 0;
2278
2279             /* the valid other immediate pointer objects */
2280         case SIMPLE_VECTOR_WIDETAG:
2281         case RATIO_WIDETAG:
2282         case COMPLEX_WIDETAG:
2283 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
2284         case COMPLEX_SINGLE_FLOAT_WIDETAG:
2285 #endif
2286 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
2287         case COMPLEX_DOUBLE_FLOAT_WIDETAG:
2288 #endif
2289 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
2290         case COMPLEX_LONG_FLOAT_WIDETAG:
2291 #endif
2292         case SIMPLE_ARRAY_WIDETAG:
2293         case COMPLEX_STRING_WIDETAG:
2294         case COMPLEX_BIT_VECTOR_WIDETAG:
2295         case COMPLEX_VECTOR_WIDETAG:
2296         case COMPLEX_ARRAY_WIDETAG:
2297         case VALUE_CELL_HEADER_WIDETAG:
2298         case SYMBOL_HEADER_WIDETAG:
2299         case FDEFN_WIDETAG:
2300         case CODE_HEADER_WIDETAG:
2301         case BIGNUM_WIDETAG:
2302         case SINGLE_FLOAT_WIDETAG:
2303         case DOUBLE_FLOAT_WIDETAG:
2304 #ifdef LONG_FLOAT_WIDETAG
2305         case LONG_FLOAT_WIDETAG:
2306 #endif
2307         case SIMPLE_STRING_WIDETAG:
2308         case SIMPLE_BIT_VECTOR_WIDETAG:
2309         case SIMPLE_ARRAY_NIL_WIDETAG:
2310         case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
2311         case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
2312         case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
2313         case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
2314         case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
2315 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
2316         case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
2317 #endif
2318 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
2319         case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
2320 #endif
2321 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
2322         case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
2323 #endif
2324 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
2325         case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
2326 #endif
2327         case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
2328         case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
2329 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
2330         case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
2331 #endif
2332 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
2333         case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
2334 #endif
2335 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
2336         case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
2337 #endif
2338 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
2339         case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
2340 #endif
2341         case SAP_WIDETAG:
2342         case WEAK_POINTER_WIDETAG:
2343             break;
2344
2345         default:
2346             if (gencgc_verbose)
2347                 FSHOW((stderr,
2348                        "/Wo6: %x %x %x\n",
2349                        pointer, start_addr, *start_addr));
2350             return 0;
2351         }
2352         break;
2353     default:
2354         if (gencgc_verbose)
2355             FSHOW((stderr,
2356                    "*W?: %x %x %x\n",
2357                    pointer, start_addr, *start_addr));
2358         return 0;
2359     }
2360
2361     /* looks good */
2362     return 1;
2363 }
2364
2365 /* Adjust large bignum and vector objects. This will adjust the
2366  * allocated region if the size has shrunk, and move unboxed objects
2367  * into unboxed pages. The pages are not promoted here, and the
2368  * promoted region is not added to the new_regions; this is really
2369  * only designed to be called from preserve_pointer(). Shouldn't fail
2370  * if this is missed, just may delay the moving of objects to unboxed
2371  * pages, and the freeing of pages. */
2372 static void
2373 maybe_adjust_large_object(lispobj *where)
2374 {
2375     int first_page;
2376     int nwords;
2377
2378     int remaining_bytes;
2379     int next_page;
2380     int bytes_freed;
2381     int old_bytes_used;
2382
2383     int boxed;
2384
2385     /* Check whether it's a vector or bignum object. */
2386     switch (widetag_of(where[0])) {
2387     case SIMPLE_VECTOR_WIDETAG:
2388         boxed = BOXED_PAGE;
2389         break;
2390     case BIGNUM_WIDETAG:
2391     case SIMPLE_STRING_WIDETAG:
2392     case SIMPLE_BIT_VECTOR_WIDETAG:
2393     case SIMPLE_ARRAY_NIL_WIDETAG:
2394     case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
2395     case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
2396     case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
2397     case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
2398     case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
2399 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
2400     case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
2401 #endif
2402 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
2403     case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
2404 #endif
2405 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
2406     case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
2407 #endif
2408 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
2409     case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
2410 #endif
2411     case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
2412     case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
2413 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
2414     case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
2415 #endif
2416 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
2417     case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
2418 #endif
2419 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
2420     case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
2421 #endif
2422 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
2423     case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
2424 #endif
2425         boxed = UNBOXED_PAGE;
2426         break;
2427     default:
2428         return;
2429     }
2430
2431     /* Find its current size. */
2432     nwords = (sizetab[widetag_of(where[0])])(where);
2433
2434     first_page = find_page_index((void *)where);
2435     gc_assert(first_page >= 0);
2436
2437     /* Note: Any page write-protection must be removed, else a later
2438      * scavenge_newspace may incorrectly not scavenge these pages.
2439      * This would not be necessary if they are added to the new areas,
2440      * but lets do it for them all (they'll probably be written
2441      * anyway?). */
2442
2443     gc_assert(page_table[first_page].first_object_offset == 0);
2444
2445     next_page = first_page;
2446     remaining_bytes = nwords*4;
2447     while (remaining_bytes > 4096) {
2448         gc_assert(page_table[next_page].gen == from_space);
2449         gc_assert((page_table[next_page].allocated == BOXED_PAGE)
2450                   || (page_table[next_page].allocated == UNBOXED_PAGE));
2451         gc_assert(page_table[next_page].large_object);
2452         gc_assert(page_table[next_page].first_object_offset ==
2453                   -4096*(next_page-first_page));
2454         gc_assert(page_table[next_page].bytes_used == 4096);
2455
2456         page_table[next_page].allocated = boxed;
2457
2458         /* Shouldn't be write-protected at this stage. Essential that the
2459          * pages aren't. */
2460         gc_assert(!page_table[next_page].write_protected);
2461         remaining_bytes -= 4096;
2462         next_page++;
2463     }
2464
2465     /* Now only one page remains, but the object may have shrunk so
2466      * there may be more unused pages which will be freed. */
2467
2468     /* Object may have shrunk but shouldn't have grown - check. */
2469     gc_assert(page_table[next_page].bytes_used >= remaining_bytes);
2470
2471     page_table[next_page].allocated = boxed;
2472     gc_assert(page_table[next_page].allocated ==
2473               page_table[first_page].allocated);
2474
2475     /* Adjust the bytes_used. */
2476     old_bytes_used = page_table[next_page].bytes_used;
2477     page_table[next_page].bytes_used = remaining_bytes;
2478
2479     bytes_freed = old_bytes_used - remaining_bytes;
2480
2481     /* Free any remaining pages; needs care. */
2482     next_page++;
2483     while ((old_bytes_used == 4096) &&
2484            (page_table[next_page].gen == from_space) &&
2485            ((page_table[next_page].allocated == UNBOXED_PAGE)
2486             || (page_table[next_page].allocated == BOXED_PAGE)) &&
2487            page_table[next_page].large_object &&
2488            (page_table[next_page].first_object_offset ==
2489             -(next_page - first_page)*4096)) {
2490         /* It checks out OK, free the page. We don't need to both zeroing
2491          * pages as this should have been done before shrinking the
2492          * object. These pages shouldn't be write protected as they
2493          * should be zero filled. */
2494         gc_assert(page_table[next_page].write_protected == 0);
2495
2496         old_bytes_used = page_table[next_page].bytes_used;
2497         page_table[next_page].allocated = FREE_PAGE;
2498         page_table[next_page].bytes_used = 0;
2499         bytes_freed += old_bytes_used;
2500         next_page++;
2501     }
2502
2503     if ((bytes_freed > 0) && gencgc_verbose) {
2504         FSHOW((stderr,
2505                "/maybe_adjust_large_object() freed %d\n",
2506                bytes_freed));
2507     }
2508
2509     generations[from_space].bytes_allocated -= bytes_freed;
2510     bytes_allocated -= bytes_freed;
2511
2512     return;
2513 }
2514
2515 /* Take a possible pointer to a Lisp object and mark its page in the
2516  * page_table so that it will not be relocated during a GC.
2517  *
2518  * This involves locating the page it points to, then backing up to
2519  * the first page that has its first object start at offset 0, and
2520  * then marking all pages dont_move from the first until a page that
2521  * ends by being full, or having free gen.
2522  *
2523  * This ensures that objects spanning pages are not broken.
2524  *
2525  * It is assumed that all the page static flags have been cleared at
2526  * the start of a GC.
2527  *
2528  * It is also assumed that the current gc_alloc() region has been
2529  * flushed and the tables updated. */
2530 static void
2531 preserve_pointer(void *addr)
2532 {
2533     int addr_page_index = find_page_index(addr);
2534     int first_page;
2535     int i;
2536     unsigned region_allocation;
2537
2538     /* quick check 1: Address is quite likely to have been invalid. */
2539     if ((addr_page_index == -1)
2540         || (page_table[addr_page_index].allocated == FREE_PAGE)
2541         || (page_table[addr_page_index].bytes_used == 0)
2542         || (page_table[addr_page_index].gen != from_space)
2543         /* Skip if already marked dont_move. */
2544         || (page_table[addr_page_index].dont_move != 0))
2545         return;
2546     gc_assert(!(page_table[addr_page_index].allocated & OPEN_REGION_PAGE));
2547     /* (Now that we know that addr_page_index is in range, it's
2548      * safe to index into page_table[] with it.) */
2549     region_allocation = page_table[addr_page_index].allocated;
2550
2551     /* quick check 2: Check the offset within the page.
2552      *
2553      * FIXME: The mask should have a symbolic name, and ideally should
2554      * be derived from page size instead of hardwired to 0xfff.
2555      * (Also fix other uses of 0xfff, elsewhere.) */
2556     if (((unsigned)addr & 0xfff) > page_table[addr_page_index].bytes_used)
2557         return;
2558
2559     /* Filter out anything which can't be a pointer to a Lisp object
2560      * (or, as a special case which also requires dont_move, a return
2561      * address referring to something in a CodeObject). This is
2562      * expensive but important, since it vastly reduces the
2563      * probability that random garbage will be bogusly interpreter as
2564      * a pointer which prevents a page from moving. */
2565     if (!(possibly_valid_dynamic_space_pointer(addr)))
2566         return;
2567     first_page = addr_page_index;
2568
2569     /* Work backwards to find a page with a first_object_offset of 0.
2570      * The pages should be contiguous with all bytes used in the same
2571      * gen. Assumes the first_object_offset is negative or zero. */
2572
2573     /* this is probably needlessly conservative.  The first object in
2574      * the page may not even be the one we were passed a pointer to:
2575      * if this is the case, we will write-protect all the previous
2576      * object's pages too.
2577      */
2578
2579     while (page_table[first_page].first_object_offset != 0) {
2580         --first_page;
2581         /* Do some checks. */
2582         gc_assert(page_table[first_page].bytes_used == 4096);
2583         gc_assert(page_table[first_page].gen == from_space);
2584         gc_assert(page_table[first_page].allocated == region_allocation);
2585     }
2586
2587     /* Adjust any large objects before promotion as they won't be
2588      * copied after promotion. */
2589     if (page_table[first_page].large_object) {
2590         maybe_adjust_large_object(page_address(first_page));
2591         /* If a large object has shrunk then addr may now point to a
2592          * free area in which case it's ignored here. Note it gets
2593          * through the valid pointer test above because the tail looks
2594          * like conses. */
2595         if ((page_table[addr_page_index].allocated == FREE_PAGE)
2596             || (page_table[addr_page_index].bytes_used == 0)
2597             /* Check the offset within the page. */
2598             || (((unsigned)addr & 0xfff)
2599                 > page_table[addr_page_index].bytes_used)) {
2600             FSHOW((stderr,
2601                    "weird? ignore ptr 0x%x to freed area of large object\n",
2602                    addr));
2603             return;
2604         }
2605         /* It may have moved to unboxed pages. */
2606         region_allocation = page_table[first_page].allocated;
2607     }
2608
2609     /* Now work forward until the end of this contiguous area is found,
2610      * marking all pages as dont_move. */
2611     for (i = first_page; ;i++) {
2612         gc_assert(page_table[i].allocated == region_allocation);
2613
2614         /* Mark the page static. */
2615         page_table[i].dont_move = 1;
2616
2617         /* Move the page to the new_space. XX I'd rather not do this
2618          * but the GC logic is not quite able to copy with the static
2619          * pages remaining in the from space. This also requires the
2620          * generation bytes_allocated counters be updated. */
2621         page_table[i].gen = new_space;
2622         generations[new_space].bytes_allocated += page_table[i].bytes_used;
2623         generations[from_space].bytes_allocated -= page_table[i].bytes_used;
2624
2625         /* It is essential that the pages are not write protected as
2626          * they may have pointers into the old-space which need
2627          * scavenging. They shouldn't be write protected at this
2628          * stage. */
2629         gc_assert(!page_table[i].write_protected);
2630
2631         /* Check whether this is the last page in this contiguous block.. */
2632         if ((page_table[i].bytes_used < 4096)
2633             /* ..or it is 4096 and is the last in the block */
2634             || (page_table[i+1].allocated == FREE_PAGE)
2635             || (page_table[i+1].bytes_used == 0) /* next page free */
2636             || (page_table[i+1].gen != from_space) /* diff. gen */
2637             || (page_table[i+1].first_object_offset == 0))
2638             break;
2639     }
2640
2641     /* Check that the page is now static. */
2642     gc_assert(page_table[addr_page_index].dont_move != 0);
2643 }
2644 \f
2645 /* If the given page is not write-protected, then scan it for pointers
2646  * to younger generations or the top temp. generation, if no
2647  * suspicious pointers are found then the page is write-protected.
2648  *
2649  * Care is taken to check for pointers to the current gc_alloc()
2650  * region if it is a younger generation or the temp. generation. This
2651  * frees the caller from doing a gc_alloc_update_page_tables(). Actually
2652  * the gc_alloc_generation does not need to be checked as this is only
2653  * called from scavenge_generation() when the gc_alloc generation is
2654  * younger, so it just checks if there is a pointer to the current
2655  * region.
2656  *
2657  * We return 1 if the page was write-protected, else 0. */
2658 static int
2659 update_page_write_prot(int page)
2660 {
2661     int gen = page_table[page].gen;
2662     int j;
2663     int wp_it = 1;
2664     void **page_addr = (void **)page_address(page);
2665     int num_words = page_table[page].bytes_used / 4;
2666
2667     /* Shouldn't be a free page. */
2668     gc_assert(page_table[page].allocated != FREE_PAGE);
2669     gc_assert(page_table[page].bytes_used != 0);
2670
2671     /* Skip if it's already write-protected or an unboxed page. */
2672     if (page_table[page].write_protected
2673         || (page_table[page].allocated & UNBOXED_PAGE))
2674         return (0);
2675
2676     /* Scan the page for pointers to younger generations or the
2677      * top temp. generation. */
2678
2679     for (j = 0; j < num_words; j++) {
2680         void *ptr = *(page_addr+j);
2681         int index = find_page_index(ptr);
2682
2683         /* Check that it's in the dynamic space */
2684         if (index != -1)
2685             if (/* Does it point to a younger or the temp. generation? */
2686                 ((page_table[index].allocated != FREE_PAGE)
2687                  && (page_table[index].bytes_used != 0)
2688                  && ((page_table[index].gen < gen)
2689                      || (page_table[index].gen == NUM_GENERATIONS)))
2690
2691                 /* Or does it point within a current gc_alloc() region? */
2692                 || ((boxed_region.start_addr <= ptr)
2693                     && (ptr <= boxed_region.free_pointer))
2694                 || ((unboxed_region.start_addr <= ptr)
2695                     && (ptr <= unboxed_region.free_pointer))) {
2696                 wp_it = 0;
2697                 break;
2698             }
2699     }
2700
2701     if (wp_it == 1) {
2702         /* Write-protect the page. */
2703         /*FSHOW((stderr, "/write-protecting page %d gen %d\n", page, gen));*/
2704
2705         os_protect((void *)page_addr,
2706                    4096,
2707                    OS_VM_PROT_READ|OS_VM_PROT_EXECUTE);
2708
2709         /* Note the page as protected in the page tables. */
2710         page_table[page].write_protected = 1;
2711     }
2712
2713     return (wp_it);
2714 }
2715
2716 /* Scavenge a generation.
2717  *
2718  * This will not resolve all pointers when generation is the new
2719  * space, as new objects may be added which are not check here - use
2720  * scavenge_newspace generation.
2721  *
2722  * Write-protected pages should not have any pointers to the
2723  * from_space so do need scavenging; thus write-protected pages are
2724  * not always scavenged. There is some code to check that these pages
2725  * are not written; but to check fully the write-protected pages need
2726  * to be scavenged by disabling the code to skip them.
2727  *
2728  * Under the current scheme when a generation is GCed the younger
2729  * generations will be empty. So, when a generation is being GCed it
2730  * is only necessary to scavenge the older generations for pointers
2731  * not the younger. So a page that does not have pointers to younger
2732  * generations does not need to be scavenged.
2733  *
2734  * The write-protection can be used to note pages that don't have
2735  * pointers to younger pages. But pages can be written without having
2736  * pointers to younger generations. After the pages are scavenged here
2737  * they can be scanned for pointers to younger generations and if
2738  * there are none the page can be write-protected.
2739  *
2740  * One complication is when the newspace is the top temp. generation.
2741  *
2742  * Enabling SC_GEN_CK scavenges the write-protected pages and checks
2743  * that none were written, which they shouldn't be as they should have
2744  * no pointers to younger generations. This breaks down for weak
2745  * pointers as the objects contain a link to the next and are written
2746  * if a weak pointer is scavenged. Still it's a useful check. */
2747 static void
2748 scavenge_generation(int generation)
2749 {
2750     int i;
2751     int num_wp = 0;
2752
2753 #define SC_GEN_CK 0
2754 #if SC_GEN_CK
2755     /* Clear the write_protected_cleared flags on all pages. */
2756     for (i = 0; i < NUM_PAGES; i++)
2757         page_table[i].write_protected_cleared = 0;
2758 #endif
2759
2760     for (i = 0; i < last_free_page; i++) {
2761         if ((page_table[i].allocated & BOXED_PAGE)
2762             && (page_table[i].bytes_used != 0)
2763             && (page_table[i].gen == generation)) {
2764             int last_page;
2765
2766             /* This should be the start of a contiguous block. */
2767             gc_assert(page_table[i].first_object_offset == 0);
2768
2769             /* We need to find the full extent of this contiguous
2770              * block in case objects span pages. */
2771
2772             /* Now work forward until the end of this contiguous area
2773              * is found. A small area is preferred as there is a
2774              * better chance of its pages being write-protected. */
2775             for (last_page = i; ; last_page++)
2776                 /* Check whether this is the last page in this contiguous
2777                  * block. */
2778                 if ((page_table[last_page].bytes_used < 4096)
2779                     /* Or it is 4096 and is the last in the block */
2780                     || (!(page_table[last_page+1].allocated & BOXED_PAGE))
2781                     || (page_table[last_page+1].bytes_used == 0)
2782                     || (page_table[last_page+1].gen != generation)
2783                     || (page_table[last_page+1].first_object_offset == 0))
2784                     break;
2785
2786             /* Do a limited check for write_protected pages. If all pages
2787              * are write_protected then there is no need to scavenge. */
2788             {
2789                 int j, all_wp = 1;
2790                 for (j = i; j <= last_page; j++)
2791                     if (page_table[j].write_protected == 0) {
2792                         all_wp = 0;
2793                         break;
2794                     }
2795 #if !SC_GEN_CK
2796                 if (all_wp == 0)
2797 #endif
2798                     {
2799                         scavenge(page_address(i), (page_table[last_page].bytes_used
2800                                                    + (last_page-i)*4096)/4);
2801
2802                         /* Now scan the pages and write protect those
2803                          * that don't have pointers to younger
2804                          * generations. */
2805                         if (enable_page_protection) {
2806                             for (j = i; j <= last_page; j++) {
2807                                 num_wp += update_page_write_prot(j);
2808                             }
2809                         }
2810                     }
2811             }
2812             i = last_page;
2813         }
2814     }
2815
2816     if ((gencgc_verbose > 1) && (num_wp != 0)) {
2817         FSHOW((stderr,
2818                "/write protected %d pages within generation %d\n",
2819                num_wp, generation));
2820     }
2821
2822 #if SC_GEN_CK
2823     /* Check that none of the write_protected pages in this generation
2824      * have been written to. */
2825     for (i = 0; i < NUM_PAGES; i++) {
2826         if ((page_table[i].allocation ! =FREE_PAGE)
2827             && (page_table[i].bytes_used != 0)
2828             && (page_table[i].gen == generation)
2829             && (page_table[i].write_protected_cleared != 0)) {
2830             FSHOW((stderr, "/scavenge_generation() %d\n", generation));
2831             FSHOW((stderr,
2832                    "/page bytes_used=%d first_object_offset=%d dont_move=%d\n",
2833                     page_table[i].bytes_used,
2834                     page_table[i].first_object_offset,
2835                     page_table[i].dont_move));
2836             lose("write to protected page %d in scavenge_generation()", i);
2837         }
2838     }
2839 #endif
2840 }
2841
2842 \f
2843 /* Scavenge a newspace generation. As it is scavenged new objects may
2844  * be allocated to it; these will also need to be scavenged. This
2845  * repeats until there are no more objects unscavenged in the
2846  * newspace generation.
2847  *
2848  * To help improve the efficiency, areas written are recorded by
2849  * gc_alloc() and only these scavenged. Sometimes a little more will be
2850  * scavenged, but this causes no harm. An easy check is done that the
2851  * scavenged bytes equals the number allocated in the previous
2852  * scavenge.
2853  *
2854  * Write-protected pages are not scanned except if they are marked
2855  * dont_move in which case they may have been promoted and still have
2856  * pointers to the from space.
2857  *
2858  * Write-protected pages could potentially be written by alloc however
2859  * to avoid having to handle re-scavenging of write-protected pages
2860  * gc_alloc() does not write to write-protected pages.
2861  *
2862  * New areas of objects allocated are recorded alternatively in the two
2863  * new_areas arrays below. */
2864 static struct new_area new_areas_1[NUM_NEW_AREAS];
2865 static struct new_area new_areas_2[NUM_NEW_AREAS];
2866
2867 /* Do one full scan of the new space generation. This is not enough to
2868  * complete the job as new objects may be added to the generation in
2869  * the process which are not scavenged. */
2870 static void
2871 scavenge_newspace_generation_one_scan(int generation)
2872 {
2873     int i;
2874
2875     FSHOW((stderr,
2876            "/starting one full scan of newspace generation %d\n",
2877            generation));
2878     for (i = 0; i < last_free_page; i++) {
2879         /* note that this skips over open regions when it encounters them */
2880         if ((page_table[i].allocated == BOXED_PAGE)
2881             && (page_table[i].bytes_used != 0)
2882             && (page_table[i].gen == generation)
2883             && ((page_table[i].write_protected == 0)
2884                 /* (This may be redundant as write_protected is now
2885                  * cleared before promotion.) */
2886                 || (page_table[i].dont_move == 1))) {
2887             int last_page;
2888
2889             /* The scavenge will start at the first_object_offset of page i.
2890              *
2891              * We need to find the full extent of this contiguous
2892              * block in case objects span pages.
2893              *
2894              * Now work forward until the end of this contiguous area
2895              * is found. A small area is preferred as there is a
2896              * better chance of its pages being write-protected. */
2897             for (last_page = i; ;last_page++) {
2898                 /* Check whether this is the last page in this
2899                  * contiguous block */
2900                 if ((page_table[last_page].bytes_used < 4096)
2901                     /* Or it is 4096 and is the last in the block */
2902                     || (!(page_table[last_page+1].allocated & BOXED_PAGE))
2903                     || (page_table[last_page+1].bytes_used == 0)
2904                     || (page_table[last_page+1].gen != generation)
2905                     || (page_table[last_page+1].first_object_offset == 0))
2906                     break;
2907             }
2908
2909             /* Do a limited check for write-protected pages. If all
2910              * pages are write-protected then no need to scavenge,
2911              * except if the pages are marked dont_move. */
2912             {
2913                 int j, all_wp = 1;
2914                 for (j = i; j <= last_page; j++)
2915                     if ((page_table[j].write_protected == 0)
2916                         || (page_table[j].dont_move != 0)) {
2917                         all_wp = 0;
2918                         break;
2919                     }
2920
2921                 if (!all_wp) {
2922                     int size;
2923
2924                     /* Calculate the size. */
2925                     if (last_page == i)
2926                         size = (page_table[last_page].bytes_used
2927                                 - page_table[i].first_object_offset)/4;
2928                     else
2929                         size = (page_table[last_page].bytes_used
2930                                 + (last_page-i)*4096
2931                                 - page_table[i].first_object_offset)/4;
2932                     
2933                     {
2934                         new_areas_ignore_page = last_page;
2935                         
2936                         scavenge(page_address(i) +
2937                                  page_table[i].first_object_offset,
2938                                  size);
2939
2940                     }
2941                 }
2942             }
2943
2944             i = last_page;
2945         }
2946     }
2947     FSHOW((stderr,
2948            "/done with one full scan of newspace generation %d\n",
2949            generation));
2950 }
2951
2952 /* Do a complete scavenge of the newspace generation. */
2953 static void
2954 scavenge_newspace_generation(int generation)
2955 {
2956     int i;
2957
2958     /* the new_areas array currently being written to by gc_alloc() */
2959     struct new_area (*current_new_areas)[] = &new_areas_1;
2960     int current_new_areas_index;
2961
2962     /* the new_areas created but the previous scavenge cycle */
2963     struct new_area (*previous_new_areas)[] = NULL;
2964     int previous_new_areas_index;
2965
2966     /* Flush the current regions updating the tables. */
2967     gc_alloc_update_all_page_tables();
2968
2969     /* Turn on the recording of new areas by gc_alloc(). */
2970     new_areas = current_new_areas;
2971     new_areas_index = 0;
2972
2973     /* Don't need to record new areas that get scavenged anyway during
2974      * scavenge_newspace_generation_one_scan. */
2975     record_new_objects = 1;
2976
2977     /* Start with a full scavenge. */
2978     scavenge_newspace_generation_one_scan(generation);
2979
2980     /* Record all new areas now. */
2981     record_new_objects = 2;
2982
2983     /* Flush the current regions updating the tables. */
2984     gc_alloc_update_all_page_tables();
2985
2986     /* Grab new_areas_index. */
2987     current_new_areas_index = new_areas_index;
2988
2989     /*FSHOW((stderr,
2990              "The first scan is finished; current_new_areas_index=%d.\n",
2991              current_new_areas_index));*/
2992
2993     while (current_new_areas_index > 0) {
2994         /* Move the current to the previous new areas */
2995         previous_new_areas = current_new_areas;
2996         previous_new_areas_index = current_new_areas_index;
2997
2998         /* Scavenge all the areas in previous new areas. Any new areas
2999          * allocated are saved in current_new_areas. */
3000
3001         /* Allocate an array for current_new_areas; alternating between
3002          * new_areas_1 and 2 */
3003         if (previous_new_areas == &new_areas_1)
3004             current_new_areas = &new_areas_2;
3005         else
3006             current_new_areas = &new_areas_1;
3007
3008         /* Set up for gc_alloc(). */
3009         new_areas = current_new_areas;
3010         new_areas_index = 0;
3011
3012         /* Check whether previous_new_areas had overflowed. */
3013         if (previous_new_areas_index >= NUM_NEW_AREAS) {
3014
3015             /* New areas of objects allocated have been lost so need to do a
3016              * full scan to be sure! If this becomes a problem try
3017              * increasing NUM_NEW_AREAS. */
3018             if (gencgc_verbose)
3019                 SHOW("new_areas overflow, doing full scavenge");
3020
3021             /* Don't need to record new areas that get scavenge anyway
3022              * during scavenge_newspace_generation_one_scan. */
3023             record_new_objects = 1;
3024
3025             scavenge_newspace_generation_one_scan(generation);
3026
3027             /* Record all new areas now. */
3028             record_new_objects = 2;
3029
3030             /* Flush the current regions updating the tables. */
3031             gc_alloc_update_all_page_tables();
3032
3033         } else {
3034
3035             /* Work through previous_new_areas. */
3036             for (i = 0; i < previous_new_areas_index; i++) {
3037                 /* FIXME: All these bare *4 and /4 should be something
3038                  * like BYTES_PER_WORD or WBYTES. */
3039                 int page = (*previous_new_areas)[i].page;
3040                 int offset = (*previous_new_areas)[i].offset;
3041                 int size = (*previous_new_areas)[i].size / 4;
3042                 gc_assert((*previous_new_areas)[i].size % 4 == 0);
3043                 scavenge(page_address(page)+offset, size);
3044             }
3045
3046             /* Flush the current regions updating the tables. */
3047             gc_alloc_update_all_page_tables();
3048         }
3049
3050         current_new_areas_index = new_areas_index;
3051
3052         /*FSHOW((stderr,
3053                  "The re-scan has finished; current_new_areas_index=%d.\n",
3054                  current_new_areas_index));*/
3055     }
3056
3057     /* Turn off recording of areas allocated by gc_alloc(). */
3058     record_new_objects = 0;
3059
3060 #if SC_NS_GEN_CK
3061     /* Check that none of the write_protected pages in this generation
3062      * have been written to. */
3063     for (i = 0; i < NUM_PAGES; i++) {
3064         if ((page_table[i].allocation != FREE_PAGE)
3065             && (page_table[i].bytes_used != 0)
3066             && (page_table[i].gen == generation)
3067             && (page_table[i].write_protected_cleared != 0)
3068             && (page_table[i].dont_move == 0)) {
3069             lose("write protected page %d written to in scavenge_newspace_generation\ngeneration=%d dont_move=%d",
3070                  i, generation, page_table[i].dont_move);
3071         }
3072     }
3073 #endif
3074 }
3075 \f
3076 /* Un-write-protect all the pages in from_space. This is done at the
3077  * start of a GC else there may be many page faults while scavenging
3078  * the newspace (I've seen drive the system time to 99%). These pages
3079  * would need to be unprotected anyway before unmapping in
3080  * free_oldspace; not sure what effect this has on paging.. */
3081 static void
3082 unprotect_oldspace(void)
3083 {
3084     int i;
3085
3086     for (i = 0; i < last_free_page; i++) {
3087         if ((page_table[i].allocated != FREE_PAGE)
3088             && (page_table[i].bytes_used != 0)
3089             && (page_table[i].gen == from_space)) {
3090             void *page_start;
3091
3092             page_start = (void *)page_address(i);
3093
3094             /* Remove any write-protection. We should be able to rely
3095              * on the write-protect flag to avoid redundant calls. */
3096             if (page_table[i].write_protected) {
3097                 os_protect(page_start, 4096, OS_VM_PROT_ALL);
3098                 page_table[i].write_protected = 0;
3099             }
3100         }
3101     }
3102 }
3103
3104 /* Work through all the pages and free any in from_space. This
3105  * assumes that all objects have been copied or promoted to an older
3106  * generation. Bytes_allocated and the generation bytes_allocated
3107  * counter are updated. The number of bytes freed is returned. */
3108 extern void i586_bzero(void *addr, int nbytes);
3109 static int
3110 free_oldspace(void)
3111 {
3112     int bytes_freed = 0;
3113     int first_page, last_page;
3114
3115     first_page = 0;
3116
3117     do {
3118         /* Find a first page for the next region of pages. */
3119         while ((first_page < last_free_page)
3120                && ((page_table[first_page].allocated == FREE_PAGE)
3121                    || (page_table[first_page].bytes_used == 0)
3122                    || (page_table[first_page].gen != from_space)))
3123             first_page++;
3124
3125         if (first_page >= last_free_page)
3126             break;
3127
3128         /* Find the last page of this region. */
3129         last_page = first_page;
3130
3131         do {
3132             /* Free the page. */
3133             bytes_freed += page_table[last_page].bytes_used;
3134             generations[page_table[last_page].gen].bytes_allocated -=
3135                 page_table[last_page].bytes_used;
3136             page_table[last_page].allocated = FREE_PAGE;
3137             page_table[last_page].bytes_used = 0;
3138
3139             /* Remove any write-protection. We should be able to rely
3140              * on the write-protect flag to avoid redundant calls. */
3141             {
3142                 void  *page_start = (void *)page_address(last_page);
3143         
3144                 if (page_table[last_page].write_protected) {
3145                     os_protect(page_start, 4096, OS_VM_PROT_ALL);
3146                     page_table[last_page].write_protected = 0;
3147                 }
3148             }
3149             last_page++;
3150         }
3151         while ((last_page < last_free_page)
3152                && (page_table[last_page].allocated != FREE_PAGE)
3153                && (page_table[last_page].bytes_used != 0)
3154                && (page_table[last_page].gen == from_space));
3155
3156         /* Zero pages from first_page to (last_page-1).
3157          *
3158          * FIXME: Why not use os_zero(..) function instead of
3159          * hand-coding this again? (Check other gencgc_unmap_zero
3160          * stuff too. */
3161         if (gencgc_unmap_zero) {
3162             void *page_start, *addr;
3163
3164             page_start = (void *)page_address(first_page);
3165
3166             os_invalidate(page_start, 4096*(last_page-first_page));
3167             addr = os_validate(page_start, 4096*(last_page-first_page));
3168             if (addr == NULL || addr != page_start) {
3169                 /* Is this an error condition? I couldn't really tell from
3170                  * the old CMU CL code, which fprintf'ed a message with
3171                  * an exclamation point at the end. But I've never seen the
3172                  * message, so it must at least be unusual..
3173                  *
3174                  * (The same condition is also tested for in gc_free_heap.)
3175                  *
3176                  * -- WHN 19991129 */
3177                 lose("i586_bzero: page moved, 0x%08x ==> 0x%08x",
3178                      page_start,
3179                      addr);
3180             }
3181         } else {
3182             int *page_start;
3183
3184             page_start = (int *)page_address(first_page);
3185             i586_bzero(page_start, 4096*(last_page-first_page));
3186         }
3187
3188         first_page = last_page;
3189
3190     } while (first_page < last_free_page);
3191
3192     bytes_allocated -= bytes_freed;
3193     return bytes_freed;
3194 }
3195 \f
3196 #if 0
3197 /* Print some information about a pointer at the given address. */
3198 static void
3199 print_ptr(lispobj *addr)
3200 {
3201     /* If addr is in the dynamic space then out the page information. */
3202     int pi1 = find_page_index((void*)addr);
3203
3204     if (pi1 != -1)
3205         fprintf(stderr,"  %x: page %d  alloc %d  gen %d  bytes_used %d  offset %d  dont_move %d\n",
3206                 (unsigned int) addr,
3207                 pi1,
3208                 page_table[pi1].allocated,
3209                 page_table[pi1].gen,
3210                 page_table[pi1].bytes_used,
3211                 page_table[pi1].first_object_offset,
3212                 page_table[pi1].dont_move);
3213     fprintf(stderr,"  %x %x %x %x (%x) %x %x %x %x\n",
3214             *(addr-4),
3215             *(addr-3),
3216             *(addr-2),
3217             *(addr-1),
3218             *(addr-0),
3219             *(addr+1),
3220             *(addr+2),
3221             *(addr+3),
3222             *(addr+4));
3223 }
3224 #endif
3225
3226 extern int undefined_tramp;
3227
3228 static void
3229 verify_space(lispobj *start, size_t words)
3230 {
3231     int is_in_dynamic_space = (find_page_index((void*)start) != -1);
3232     int is_in_readonly_space =
3233         (READ_ONLY_SPACE_START <= (unsigned)start &&
3234          (unsigned)start < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
3235
3236     while (words > 0) {
3237         size_t count = 1;
3238         lispobj thing = *(lispobj*)start;
3239
3240         if (is_lisp_pointer(thing)) {
3241             int page_index = find_page_index((void*)thing);
3242             int to_readonly_space =
3243                 (READ_ONLY_SPACE_START <= thing &&
3244                  thing < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
3245             int to_static_space =
3246                 (STATIC_SPACE_START <= thing &&
3247                  thing < SymbolValue(STATIC_SPACE_FREE_POINTER));
3248
3249             /* Does it point to the dynamic space? */
3250             if (page_index != -1) {
3251                 /* If it's within the dynamic space it should point to a used
3252                  * page. XX Could check the offset too. */
3253                 if ((page_table[page_index].allocated != FREE_PAGE)
3254                     && (page_table[page_index].bytes_used == 0))
3255                     lose ("Ptr %x @ %x sees free page.", thing, start);
3256                 /* Check that it doesn't point to a forwarding pointer! */
3257                 if (*((lispobj *)native_pointer(thing)) == 0x01) {
3258                     lose("Ptr %x @ %x sees forwarding ptr.", thing, start);
3259                 }
3260                 /* Check that its not in the RO space as it would then be a
3261                  * pointer from the RO to the dynamic space. */
3262                 if (is_in_readonly_space) {
3263                     lose("ptr to dynamic space %x from RO space %x",
3264                          thing, start);
3265                 }
3266                 /* Does it point to a plausible object? This check slows
3267                  * it down a lot (so it's commented out).
3268                  *
3269                  * "a lot" is serious: it ate 50 minutes cpu time on
3270                  * my duron 950 before I came back from lunch and
3271                  * killed it.
3272                  *
3273                  *   FIXME: Add a variable to enable this
3274                  * dynamically. */
3275                 /*
3276                 if (!possibly_valid_dynamic_space_pointer((lispobj *)thing)) {
3277                     lose("ptr %x to invalid object %x", thing, start); 
3278                 }
3279                 */
3280             } else {
3281                 /* Verify that it points to another valid space. */
3282                 if (!to_readonly_space && !to_static_space
3283                     && (thing != (unsigned)&undefined_tramp)) {
3284                     lose("Ptr %x @ %x sees junk.", thing, start);
3285                 }
3286             }
3287         } else {
3288             if (thing & 0x3) { /* Skip fixnums. FIXME: There should be an
3289                                 * is_fixnum for this. */
3290
3291                 switch(widetag_of(*start)) {
3292
3293                     /* boxed objects */
3294                 case SIMPLE_VECTOR_WIDETAG:
3295                 case RATIO_WIDETAG:
3296                 case COMPLEX_WIDETAG:
3297                 case SIMPLE_ARRAY_WIDETAG:
3298                 case COMPLEX_STRING_WIDETAG:
3299                 case COMPLEX_BIT_VECTOR_WIDETAG:
3300                 case COMPLEX_VECTOR_WIDETAG:
3301                 case COMPLEX_ARRAY_WIDETAG:
3302                 case CLOSURE_HEADER_WIDETAG:
3303                 case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
3304                 case VALUE_CELL_HEADER_WIDETAG:
3305                 case SYMBOL_HEADER_WIDETAG:
3306                 case BASE_CHAR_WIDETAG:
3307                 case UNBOUND_MARKER_WIDETAG:
3308                 case INSTANCE_HEADER_WIDETAG:
3309                 case FDEFN_WIDETAG:
3310                     count = 1;
3311                     break;
3312
3313                 case CODE_HEADER_WIDETAG:
3314                     {
3315                         lispobj object = *start;
3316                         struct code *code;
3317                         int nheader_words, ncode_words, nwords;
3318                         lispobj fheaderl;
3319                         struct simple_fun *fheaderp;
3320
3321                         code = (struct code *) start;
3322
3323                         /* Check that it's not in the dynamic space.
3324                          * FIXME: Isn't is supposed to be OK for code
3325                          * objects to be in the dynamic space these days? */
3326                         if (is_in_dynamic_space
3327                             /* It's ok if it's byte compiled code. The trace
3328                              * table offset will be a fixnum if it's x86
3329                              * compiled code - check.
3330                              *
3331                              * FIXME: #^#@@! lack of abstraction here..
3332                              * This line can probably go away now that
3333                              * there's no byte compiler, but I've got
3334                              * too much to worry about right now to try
3335                              * to make sure. -- WHN 2001-10-06 */
3336                             && !(code->trace_table_offset & 0x3)
3337                             /* Only when enabled */
3338                             && verify_dynamic_code_check) {
3339                             FSHOW((stderr,
3340                                    "/code object at %x in the dynamic space\n",
3341                                    start));
3342                         }
3343
3344                         ncode_words = fixnum_value(code->code_size);
3345                         nheader_words = HeaderValue(object);
3346                         nwords = ncode_words + nheader_words;
3347                         nwords = CEILING(nwords, 2);
3348                         /* Scavenge the boxed section of the code data block */
3349                         verify_space(start + 1, nheader_words - 1);
3350
3351                         /* Scavenge the boxed section of each function
3352                          * object in the code data block. */
3353                         fheaderl = code->entry_points;
3354                         while (fheaderl != NIL) {
3355                             fheaderp =
3356                                 (struct simple_fun *) native_pointer(fheaderl);
3357                             gc_assert(widetag_of(fheaderp->header) == SIMPLE_FUN_HEADER_WIDETAG);
3358                             verify_space(&fheaderp->name, 1);
3359                             verify_space(&fheaderp->arglist, 1);
3360                             verify_space(&fheaderp->type, 1);
3361                             fheaderl = fheaderp->next;
3362                         }
3363                         count = nwords;
3364                         break;
3365                     }
3366         
3367                     /* unboxed objects */
3368                 case BIGNUM_WIDETAG:
3369                 case SINGLE_FLOAT_WIDETAG:
3370                 case DOUBLE_FLOAT_WIDETAG:
3371 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
3372                 case LONG_FLOAT_WIDETAG:
3373 #endif
3374 #ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
3375                 case COMPLEX_SINGLE_FLOAT_WIDETAG:
3376 #endif
3377 #ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
3378                 case COMPLEX_DOUBLE_FLOAT_WIDETAG:
3379 #endif
3380 #ifdef COMPLEX_LONG_FLOAT_WIDETAG
3381                 case COMPLEX_LONG_FLOAT_WIDETAG:
3382 #endif
3383                 case SIMPLE_STRING_WIDETAG:
3384                 case SIMPLE_BIT_VECTOR_WIDETAG:
3385                 case SIMPLE_ARRAY_NIL_WIDETAG:
3386                 case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
3387                 case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
3388                 case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
3389                 case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
3390                 case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
3391 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
3392                 case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
3393 #endif
3394 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
3395                 case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
3396 #endif
3397 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG
3398                 case SIMPLE_ARRAY_SIGNED_BYTE_30_WIDETAG:
3399 #endif
3400 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
3401                 case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
3402 #endif
3403                 case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
3404                 case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
3405 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
3406                 case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
3407 #endif
3408 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
3409                 case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
3410 #endif
3411 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
3412                 case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
3413 #endif
3414 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
3415                 case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
3416 #endif
3417                 case SAP_WIDETAG:
3418                 case WEAK_POINTER_WIDETAG:
3419                     count = (sizetab[widetag_of(*start)])(start);
3420                     break;
3421
3422                 default:
3423                     gc_abort();
3424                 }
3425             }
3426         }
3427         start += count;
3428         words -= count;
3429     }
3430 }
3431
3432 static void
3433 verify_gc(void)
3434 {
3435     /* FIXME: It would be nice to make names consistent so that
3436      * foo_size meant size *in* *bytes* instead of size in some
3437      * arbitrary units. (Yes, this caused a bug, how did you guess?:-)
3438      * Some counts of lispobjs are called foo_count; it might be good
3439      * to grep for all foo_size and rename the appropriate ones to
3440      * foo_count. */
3441     int read_only_space_size =
3442         (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)
3443         - (lispobj*)READ_ONLY_SPACE_START;
3444     int static_space_size =
3445         (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER)
3446         - (lispobj*)STATIC_SPACE_START;
3447     int binding_stack_size =
3448         (lispobj*)SymbolValue(BINDING_STACK_POINTER)
3449         - (lispobj*)BINDING_STACK_START;
3450
3451     verify_space((lispobj*)READ_ONLY_SPACE_START, read_only_space_size);
3452     verify_space((lispobj*)STATIC_SPACE_START   , static_space_size);
3453     verify_space((lispobj*)BINDING_STACK_START  , binding_stack_size);
3454 }
3455
3456 static void
3457 verify_generation(int  generation)
3458 {
3459     int i;
3460
3461     for (i = 0; i < last_free_page; i++) {
3462         if ((page_table[i].allocated != FREE_PAGE)
3463             && (page_table[i].bytes_used != 0)
3464             && (page_table[i].gen == generation)) {
3465             int last_page;
3466             int region_allocation = page_table[i].allocated;
3467
3468             /* This should be the start of a contiguous block */
3469             gc_assert(page_table[i].first_object_offset == 0);
3470
3471             /* Need to find the full extent of this contiguous block in case
3472                objects span pages. */
3473
3474             /* Now work forward until the end of this contiguous area is
3475                found. */
3476             for (last_page = i; ;last_page++)
3477                 /* Check whether this is the last page in this contiguous
3478                  * block. */
3479                 if ((page_table[last_page].bytes_used < 4096)
3480                     /* Or it is 4096 and is the last in the block */
3481                     || (page_table[last_page+1].allocated != region_allocation)
3482                     || (page_table[last_page+1].bytes_used == 0)
3483                     || (page_table[last_page+1].gen != generation)
3484                     || (page_table[last_page+1].first_object_offset == 0))
3485                     break;
3486
3487             verify_space(page_address(i), (page_table[last_page].bytes_used
3488                                            + (last_page-i)*4096)/4);
3489             i = last_page;
3490         }
3491     }
3492 }
3493
3494 /* Check that all the free space is zero filled. */
3495 static void
3496 verify_zero_fill(void)
3497 {
3498     int page;
3499
3500     for (page = 0; page < last_free_page; page++) {
3501         if (page_table[page].allocated == FREE_PAGE) {
3502             /* The whole page should be zero filled. */
3503             int *start_addr = (int *)page_address(page);
3504             int size = 1024;
3505             int i;
3506             for (i = 0; i < size; i++) {
3507                 if (start_addr[i] != 0) {
3508                     lose("free page not zero at %x", start_addr + i);
3509                 }
3510             }
3511         } else {
3512             int free_bytes = 4096 - page_table[page].bytes_used;
3513             if (free_bytes > 0) {
3514                 int *start_addr = (int *)((unsigned)page_address(page)
3515                                           + page_table[page].bytes_used);
3516                 int size = free_bytes / 4;
3517                 int i;
3518                 for (i = 0; i < size; i++) {
3519                     if (start_addr[i] != 0) {
3520                         lose("free region not zero at %x", start_addr + i);
3521                     }
3522                 }
3523             }
3524         }
3525     }
3526 }
3527
3528 /* External entry point for verify_zero_fill */
3529 void
3530 gencgc_verify_zero_fill(void)
3531 {
3532     /* Flush the alloc regions updating the tables. */
3533     gc_alloc_update_all_page_tables();
3534     SHOW("verifying zero fill");
3535     verify_zero_fill();
3536 }
3537
3538 static void
3539 verify_dynamic_space(void)
3540 {
3541     int i;
3542
3543     for (i = 0; i < NUM_GENERATIONS; i++)
3544         verify_generation(i);
3545
3546     if (gencgc_enable_verify_zero_fill)
3547         verify_zero_fill();
3548 }
3549 \f
3550 /* Write-protect all the dynamic boxed pages in the given generation. */
3551 static void
3552 write_protect_generation_pages(int generation)
3553 {
3554     int i;
3555
3556     gc_assert(generation < NUM_GENERATIONS);
3557
3558     for (i = 0; i < last_free_page; i++)
3559         if ((page_table[i].allocated == BOXED_PAGE)
3560             && (page_table[i].bytes_used != 0)
3561             && (page_table[i].gen == generation))  {
3562             void *page_start;
3563
3564             page_start = (void *)page_address(i);
3565
3566             os_protect(page_start,
3567                        4096,
3568                        OS_VM_PROT_READ | OS_VM_PROT_EXECUTE);
3569
3570             /* Note the page as protected in the page tables. */
3571             page_table[i].write_protected = 1;
3572         }
3573
3574     if (gencgc_verbose > 1) {
3575         FSHOW((stderr,
3576                "/write protected %d of %d pages in generation %d\n",
3577                count_write_protect_generation_pages(generation),
3578                count_generation_pages(generation),
3579                generation));
3580     }
3581 }
3582
3583 /* Garbage collect a generation. If raise is 0 then the remains of the
3584  * generation are not raised to the next generation. */
3585 static void
3586 garbage_collect_generation(int generation, int raise)
3587 {
3588     unsigned long bytes_freed;
3589     unsigned long i;
3590     unsigned long static_space_size;
3591
3592     gc_assert(generation <= (NUM_GENERATIONS-1));
3593
3594     /* The oldest generation can't be raised. */
3595     gc_assert((generation != (NUM_GENERATIONS-1)) || (raise == 0));
3596
3597     /* Initialize the weak pointer list. */
3598     weak_pointers = NULL;
3599
3600     /* When a generation is not being raised it is transported to a
3601      * temporary generation (NUM_GENERATIONS), and lowered when
3602      * done. Set up this new generation. There should be no pages
3603      * allocated to it yet. */
3604     if (!raise)
3605         gc_assert(generations[NUM_GENERATIONS].bytes_allocated == 0);
3606
3607     /* Set the global src and dest. generations */
3608     from_space = generation;
3609     if (raise)
3610         new_space = generation+1;
3611     else
3612         new_space = NUM_GENERATIONS;
3613
3614     /* Change to a new space for allocation, resetting the alloc_start_page */
3615     gc_alloc_generation = new_space;
3616     generations[new_space].alloc_start_page = 0;
3617     generations[new_space].alloc_unboxed_start_page = 0;
3618     generations[new_space].alloc_large_start_page = 0;
3619     generations[new_space].alloc_large_unboxed_start_page = 0;
3620
3621     /* Before any pointers are preserved, the dont_move flags on the
3622      * pages need to be cleared. */
3623     for (i = 0; i < last_free_page; i++)
3624         page_table[i].dont_move = 0;
3625
3626     /* Un-write-protect the old-space pages. This is essential for the
3627      * promoted pages as they may contain pointers into the old-space
3628      * which need to be scavenged. It also helps avoid unnecessary page
3629      * faults as forwarding pointers are written into them. They need to
3630      * be un-protected anyway before unmapping later. */
3631     unprotect_oldspace();
3632
3633     /* Scavenge the stack's conservative roots. */
3634     {
3635         void **ptr;
3636         for (ptr = (void **)CONTROL_STACK_END - 1;
3637              ptr > (void **)&raise;
3638              ptr--) {
3639             preserve_pointer(*ptr);
3640         }
3641     }
3642
3643 #if QSHOW
3644     if (gencgc_verbose > 1) {
3645         int num_dont_move_pages = count_dont_move_pages();
3646         fprintf(stderr,
3647                 "/non-movable pages due to conservative pointers = %d (%d bytes)\n",
3648                 num_dont_move_pages,
3649                 /* FIXME: 4096 should be symbolic constant here and
3650                  * prob'ly elsewhere too. */
3651                 num_dont_move_pages * 4096);
3652     }
3653 #endif
3654
3655     /* Scavenge all the rest of the roots. */
3656
3657     /* Scavenge the Lisp functions of the interrupt handlers, taking
3658      * care to avoid SIG_DFL and SIG_IGN. */
3659     for (i = 0; i < NSIG; i++) {
3660         union interrupt_handler handler = interrupt_handlers[i];
3661         if (!ARE_SAME_HANDLER(handler.c, SIG_IGN) &&
3662             !ARE_SAME_HANDLER(handler.c, SIG_DFL)) {
3663             scavenge((lispobj *)(interrupt_handlers + i), 1);
3664         }
3665     }
3666
3667     /* Scavenge the binding stack. */
3668     scavenge((lispobj *) BINDING_STACK_START,
3669              (lispobj *)SymbolValue(BINDING_STACK_POINTER) -
3670              (lispobj *)BINDING_STACK_START);
3671
3672     /* The original CMU CL code had scavenge-read-only-space code
3673      * controlled by the Lisp-level variable
3674      * *SCAVENGE-READ-ONLY-SPACE*. It was disabled by default, and it
3675      * wasn't documented under what circumstances it was useful or
3676      * safe to turn it on, so it's been turned off in SBCL. If you
3677      * want/need this functionality, and can test and document it,
3678      * please submit a patch. */
3679 #if 0
3680     if (SymbolValue(SCAVENGE_READ_ONLY_SPACE) != NIL) {
3681         unsigned long read_only_space_size =
3682             (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER) -
3683             (lispobj*)READ_ONLY_SPACE_START;
3684         FSHOW((stderr,
3685                "/scavenge read only space: %d bytes\n",
3686                read_only_space_size * sizeof(lispobj)));
3687         scavenge( (lispobj *) READ_ONLY_SPACE_START, read_only_space_size);
3688     }
3689 #endif
3690
3691     /* Scavenge static space. */
3692     static_space_size =
3693         (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER) -
3694         (lispobj *)STATIC_SPACE_START;
3695     if (gencgc_verbose > 1) {
3696         FSHOW((stderr,
3697                "/scavenge static space: %d bytes\n",
3698                static_space_size * sizeof(lispobj)));
3699     }
3700     scavenge( (lispobj *) STATIC_SPACE_START, static_space_size);
3701
3702     /* All generations but the generation being GCed need to be
3703      * scavenged. The new_space generation needs special handling as
3704      * objects may be moved in - it is handled separately below. */
3705     for (i = 0; i < NUM_GENERATIONS; i++) {
3706         if ((i != generation) && (i != new_space)) {
3707             scavenge_generation(i);
3708         }
3709     }
3710
3711     /* Finally scavenge the new_space generation. Keep going until no
3712      * more objects are moved into the new generation */
3713     scavenge_newspace_generation(new_space);
3714
3715     /* FIXME: I tried reenabling this check when debugging unrelated
3716      * GC weirdness ca. sbcl-0.6.12.45, and it failed immediately.
3717      * Since the current GC code seems to work well, I'm guessing that
3718      * this debugging code is just stale, but I haven't tried to
3719      * figure it out. It should be figured out and then either made to
3720      * work or just deleted. */
3721 #define RESCAN_CHECK 0
3722 #if RESCAN_CHECK
3723     /* As a check re-scavenge the newspace once; no new objects should
3724      * be found. */
3725     {
3726         int old_bytes_allocated = bytes_allocated;
3727         int bytes_allocated;
3728
3729         /* Start with a full scavenge. */
3730         scavenge_newspace_generation_one_scan(new_space);
3731
3732         /* Flush the current regions, updating the tables. */
3733         gc_alloc_update_all_page_tables();
3734
3735         bytes_allocated = bytes_allocated - old_bytes_allocated;
3736
3737         if (bytes_allocated != 0) {
3738             lose("Rescan of new_space allocated %d more bytes.",
3739                  bytes_allocated);
3740         }
3741     }
3742 #endif
3743
3744     scan_weak_pointers();
3745
3746     /* Flush the current regions, updating the tables. */
3747     gc_alloc_update_all_page_tables();
3748
3749     /* Free the pages in oldspace, but not those marked dont_move. */
3750     bytes_freed = free_oldspace();
3751
3752     /* If the GC is not raising the age then lower the generation back
3753      * to its normal generation number */
3754     if (!raise) {
3755         for (i = 0; i < last_free_page; i++)
3756             if ((page_table[i].bytes_used != 0)
3757                 && (page_table[i].gen == NUM_GENERATIONS))
3758                 page_table[i].gen = generation;
3759         gc_assert(generations[generation].bytes_allocated == 0);
3760         generations[generation].bytes_allocated =
3761             generations[NUM_GENERATIONS].bytes_allocated;
3762         generations[NUM_GENERATIONS].bytes_allocated = 0;
3763     }
3764
3765     /* Reset the alloc_start_page for generation. */
3766     generations[generation].alloc_start_page = 0;
3767     generations[generation].alloc_unboxed_start_page = 0;
3768     generations[generation].alloc_large_start_page = 0;
3769     generations[generation].alloc_large_unboxed_start_page = 0;
3770
3771     if (generation >= verify_gens) {
3772         if (gencgc_verbose)
3773             SHOW("verifying");
3774         verify_gc();
3775         verify_dynamic_space();
3776     }
3777
3778     /* Set the new gc trigger for the GCed generation. */
3779     generations[generation].gc_trigger =
3780         generations[generation].bytes_allocated
3781         + generations[generation].bytes_consed_between_gc;
3782
3783     if (raise)
3784         generations[generation].num_gc = 0;
3785     else
3786         ++generations[generation].num_gc;
3787 }
3788
3789 /* Update last_free_page, then SymbolValue(ALLOCATION_POINTER). */
3790 int
3791 update_x86_dynamic_space_free_pointer(void)
3792 {
3793     int last_page = -1;
3794     int i;
3795
3796     for (i = 0; i < NUM_PAGES; i++)
3797         if ((page_table[i].allocated != FREE_PAGE)
3798             && (page_table[i].bytes_used != 0))
3799             last_page = i;
3800
3801     last_free_page = last_page+1;
3802
3803     SetSymbolValue(ALLOCATION_POINTER,
3804                    (lispobj)(((char *)heap_base) + last_free_page*4096));
3805     return 0; /* dummy value: return something ... */
3806 }
3807
3808 /* GC all generations newer than last_gen, raising the objects in each
3809  * to the next older generation - we finish when all generations below
3810  * last_gen are empty.  Then if last_gen is due for a GC, or if
3811  * last_gen==NUM_GENERATIONS (the scratch generation?  eh?) we GC that
3812  * too.  The valid range for last_gen is: 0,1,...,NUM_GENERATIONS.
3813  *
3814  * We stop collecting at gencgc_oldest_gen_to_gc, even if this is less than
3815  * last_gen (oh, and note that by default it is NUM_GENERATIONS-1) */
3816  
3817 void
3818 collect_garbage(unsigned last_gen)
3819 {
3820     int gen = 0;
3821     int raise;
3822     int gen_to_wp;
3823     int i;
3824
3825     FSHOW((stderr, "/entering collect_garbage(%d)\n", last_gen));
3826
3827     if (last_gen > NUM_GENERATIONS) {
3828         FSHOW((stderr,
3829                "/collect_garbage: last_gen = %d, doing a level 0 GC\n",
3830                last_gen));
3831         last_gen = 0;
3832     }
3833
3834     /* Flush the alloc regions updating the tables. */
3835     gc_alloc_update_all_page_tables();
3836
3837     /* Verify the new objects created by Lisp code. */
3838     if (pre_verify_gen_0) {
3839         FSHOW((stderr, "pre-checking generation 0\n"));
3840         verify_generation(0);
3841     }
3842
3843     if (gencgc_verbose > 1)
3844         print_generation_stats(0);
3845
3846     do {
3847         /* Collect the generation. */
3848
3849         if (gen >= gencgc_oldest_gen_to_gc) {
3850             /* Never raise the oldest generation. */
3851             raise = 0;
3852         } else {
3853             raise =
3854                 (gen < last_gen)
3855                 || (generations[gen].num_gc >= generations[gen].trigger_age);
3856         }
3857
3858         if (gencgc_verbose > 1) {
3859             FSHOW((stderr,
3860                    "starting GC of generation %d with raise=%d alloc=%d trig=%d GCs=%d\n",
3861                    gen,
3862                    raise,
3863                    generations[gen].bytes_allocated,
3864                    generations[gen].gc_trigger,
3865                    generations[gen].num_gc));
3866         }
3867
3868         /* If an older generation is being filled, then update its
3869          * memory age. */
3870         if (raise == 1) {
3871             generations[gen+1].cum_sum_bytes_allocated +=
3872                 generations[gen+1].bytes_allocated;
3873         }
3874
3875         garbage_collect_generation(gen, raise);
3876
3877         /* Reset the memory age cum_sum. */
3878         generations[gen].cum_sum_bytes_allocated = 0;
3879
3880         if (gencgc_verbose > 1) {
3881             FSHOW((stderr, "GC of generation %d finished:\n", gen));
3882             print_generation_stats(0);
3883         }
3884
3885         gen++;
3886     } while ((gen <= gencgc_oldest_gen_to_gc)
3887              && ((gen < last_gen)
3888                  || ((gen <= gencgc_oldest_gen_to_gc)
3889                      && raise
3890                      && (generations[gen].bytes_allocated
3891                          > generations[gen].gc_trigger)
3892                      && (gen_av_mem_age(gen)
3893                          > generations[gen].min_av_mem_age))));
3894
3895     /* Now if gen-1 was raised all generations before gen are empty.
3896      * If it wasn't raised then all generations before gen-1 are empty.
3897      *
3898      * Now objects within this gen's pages cannot point to younger
3899      * generations unless they are written to. This can be exploited
3900      * by write-protecting the pages of gen; then when younger
3901      * generations are GCed only the pages which have been written
3902      * need scanning. */
3903     if (raise)
3904         gen_to_wp = gen;
3905     else
3906         gen_to_wp = gen - 1;
3907
3908     /* There's not much point in WPing pages in generation 0 as it is
3909      * never scavenged (except promoted pages). */
3910     if ((gen_to_wp > 0) && enable_page_protection) {
3911         /* Check that they are all empty. */
3912         for (i = 0; i < gen_to_wp; i++) {
3913             if (generations[i].bytes_allocated)
3914                 lose("trying to write-protect gen. %d when gen. %d nonempty",
3915                      gen_to_wp, i);
3916         }
3917         write_protect_generation_pages(gen_to_wp);
3918     }
3919
3920     /* Set gc_alloc() back to generation 0. The current regions should
3921      * be flushed after the above GCs. */
3922     gc_assert((boxed_region.free_pointer - boxed_region.start_addr) == 0);
3923     gc_alloc_generation = 0;
3924
3925     update_x86_dynamic_space_free_pointer();
3926
3927     SHOW("returning from collect_garbage");
3928 }
3929
3930 /* This is called by Lisp PURIFY when it is finished. All live objects
3931  * will have been moved to the RO and Static heaps. The dynamic space
3932  * will need a full re-initialization. We don't bother having Lisp
3933  * PURIFY flush the current gc_alloc() region, as the page_tables are
3934  * re-initialized, and every page is zeroed to be sure. */
3935 void
3936 gc_free_heap(void)
3937 {
3938     int page;
3939
3940     if (gencgc_verbose > 1)
3941         SHOW("entering gc_free_heap");
3942
3943     for (page = 0; page < NUM_PAGES; page++) {
3944         /* Skip free pages which should already be zero filled. */
3945         if (page_table[page].allocated != FREE_PAGE) {
3946             void *page_start, *addr;
3947
3948             /* Mark the page free. The other slots are assumed invalid
3949              * when it is a FREE_PAGE and bytes_used is 0 and it
3950              * should not be write-protected -- except that the
3951              * generation is used for the current region but it sets
3952              * that up. */
3953             page_table[page].allocated = FREE_PAGE;
3954             page_table[page].bytes_used = 0;
3955
3956             /* Zero the page. */
3957             page_start = (void *)page_address(page);
3958
3959             /* First, remove any write-protection. */
3960             os_protect(page_start, 4096, OS_VM_PROT_ALL);
3961             page_table[page].write_protected = 0;
3962
3963             os_invalidate(page_start,4096);
3964             addr = os_validate(page_start,4096);
3965             if (addr == NULL || addr != page_start) {
3966                 lose("gc_free_heap: page moved, 0x%08x ==> 0x%08x",
3967                      page_start,
3968                      addr);
3969             }
3970         } else if (gencgc_zero_check_during_free_heap) {
3971             /* Double-check that the page is zero filled. */
3972             int *page_start, i;
3973             gc_assert(page_table[page].allocated == FREE_PAGE);
3974             gc_assert(page_table[page].bytes_used == 0);
3975             page_start = (int *)page_address(page);
3976             for (i=0; i<1024; i++) {
3977                 if (page_start[i] != 0) {
3978                     lose("free region not zero at %x", page_start + i);
3979                 }
3980             }
3981         }
3982     }
3983
3984     bytes_allocated = 0;
3985
3986     /* Initialize the generations. */
3987     for (page = 0; page < NUM_GENERATIONS; page++) {
3988         generations[page].alloc_start_page = 0;
3989         generations[page].alloc_unboxed_start_page = 0;
3990         generations[page].alloc_large_start_page = 0;
3991         generations[page].alloc_large_unboxed_start_page = 0;
3992         generations[page].bytes_allocated = 0;
3993         generations[page].gc_trigger = 2000000;
3994         generations[page].num_gc = 0;
3995         generations[page].cum_sum_bytes_allocated = 0;
3996     }
3997
3998     if (gencgc_verbose > 1)
3999         print_generation_stats(0);
4000
4001     /* Initialize gc_alloc(). */
4002     gc_alloc_generation = 0;
4003
4004     gc_set_region_empty(&boxed_region);
4005     gc_set_region_empty(&unboxed_region);
4006
4007     last_free_page = 0;
4008     SetSymbolValue(ALLOCATION_POINTER, (lispobj)((char *)heap_base));
4009
4010     if (verify_after_free_heap) {
4011         /* Check whether purify has left any bad pointers. */
4012         if (gencgc_verbose)
4013             SHOW("checking after free_heap\n");
4014         verify_gc();
4015     }
4016 }
4017 \f
4018 void
4019 gc_init(void)
4020 {
4021     int i;
4022
4023     gc_init_tables();
4024     scavtab[SIMPLE_VECTOR_WIDETAG] = scav_vector;
4025     scavtab[WEAK_POINTER_WIDETAG] = scav_weak_pointer;
4026     transother[SIMPLE_ARRAY_WIDETAG] = trans_boxed_large;
4027
4028     heap_base = (void*)DYNAMIC_SPACE_START;
4029
4030     /* Initialize each page structure. */
4031     for (i = 0; i < NUM_PAGES; i++) {
4032         /* Initialize all pages as free. */
4033         page_table[i].allocated = FREE_PAGE;
4034         page_table[i].bytes_used = 0;
4035
4036         /* Pages are not write-protected at startup. */
4037         page_table[i].write_protected = 0;
4038     }
4039
4040     bytes_allocated = 0;
4041
4042     /* Initialize the generations.
4043      *
4044      * FIXME: very similar to code in gc_free_heap(), should be shared */
4045     for (i = 0; i < NUM_GENERATIONS; i++) {
4046         generations[i].alloc_start_page = 0;
4047         generations[i].alloc_unboxed_start_page = 0;
4048         generations[i].alloc_large_start_page = 0;
4049         generations[i].alloc_large_unboxed_start_page = 0;
4050         generations[i].bytes_allocated = 0;
4051         generations[i].gc_trigger = 2000000;
4052         generations[i].num_gc = 0;
4053         generations[i].cum_sum_bytes_allocated = 0;
4054         /* the tune-able parameters */
4055         generations[i].bytes_consed_between_gc = 2000000;
4056         generations[i].trigger_age = 1;
4057         generations[i].min_av_mem_age = 0.75;
4058     }
4059
4060     /* Initialize gc_alloc. */
4061     gc_alloc_generation = 0;
4062     gc_set_region_empty(&boxed_region);
4063     gc_set_region_empty(&unboxed_region);
4064
4065     last_free_page = 0;
4066
4067 }
4068
4069 /*  Pick up the dynamic space from after a core load.
4070  *
4071  *  The ALLOCATION_POINTER points to the end of the dynamic space.
4072  *
4073  *  XX A scan is needed to identify the closest first objects for pages. */
4074 static void
4075 gencgc_pickup_dynamic(void)
4076 {
4077     int page = 0;
4078     int addr = DYNAMIC_SPACE_START;
4079     int alloc_ptr = SymbolValue(ALLOCATION_POINTER);
4080
4081     /* Initialize the first region. */
4082     do {
4083         page_table[page].allocated = BOXED_PAGE;
4084         page_table[page].gen = 0;
4085         page_table[page].bytes_used = 4096;
4086         page_table[page].large_object = 0;
4087         page_table[page].first_object_offset =
4088             (void *)DYNAMIC_SPACE_START - page_address(page);
4089         addr += 4096;
4090         page++;
4091     } while (addr < alloc_ptr);
4092
4093     generations[0].bytes_allocated = 4096*page;
4094     bytes_allocated = 4096*page;
4095
4096 }
4097
4098 void
4099 gc_initialize_pointers(void)
4100 {
4101     gencgc_pickup_dynamic();
4102 }
4103
4104
4105 \f
4106
4107 extern boolean maybe_gc_pending ;
4108 /* alloc(..) is the external interface for memory allocation. It
4109  * allocates to generation 0. It is not called from within the garbage
4110  * collector as it is only external uses that need the check for heap
4111  * size (GC trigger) and to disable the interrupts (interrupts are
4112  * always disabled during a GC).
4113  *
4114  * The vops that call alloc(..) assume that the returned space is zero-filled.
4115  * (E.g. the most significant word of a 2-word bignum in MOVE-FROM-UNSIGNED.)
4116  *
4117  * The check for a GC trigger is only performed when the current
4118  * region is full, so in most cases it's not needed. */
4119
4120 char *
4121 alloc(int nbytes)
4122 {
4123     struct alloc_region *region=  &boxed_region; 
4124     void *new_obj;
4125     void *new_free_pointer;
4126
4127     /* Check for alignment allocation problems. */
4128     gc_assert((((unsigned)region->free_pointer & 0x7) == 0)
4129               && ((nbytes & 0x7) == 0));
4130     /* At this point we should either be in pseudo-atomic, or early
4131      * enough in cold initn that interrupts are not yet enabled anyway.
4132      * It would be nice to assert same.
4133      */
4134     gc_assert(SymbolValue(PSEUDO_ATOMIC_ATOMIC));
4135
4136     /* maybe we can do this quickly ... */
4137     new_free_pointer = region->free_pointer + nbytes;
4138     if (new_free_pointer <= region->end_addr) {
4139         new_obj = (void*)(region->free_pointer);
4140         region->free_pointer = new_free_pointer;
4141         return(new_obj);        /* yup */
4142     }
4143     
4144     /* we have to go the long way around, it seems.  Check whether 
4145      * we should GC in the near future
4146      */
4147     if (auto_gc_trigger && bytes_allocated > auto_gc_trigger) {
4148         auto_gc_trigger *= 2;
4149         /* set things up so that GC happens when we finish the PA
4150          * section.  */
4151         maybe_gc_pending=1;
4152         SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, make_fixnum(1));
4153     }
4154     new_obj = gc_alloc_with_region(nbytes,0,region,0);
4155     return (new_obj);
4156 }
4157
4158 \f
4159 /*
4160  * noise to manipulate the gc trigger stuff
4161  */
4162
4163 void
4164 set_auto_gc_trigger(os_vm_size_t dynamic_usage)
4165 {
4166     auto_gc_trigger += dynamic_usage;
4167 }
4168
4169 void
4170 clear_auto_gc_trigger(void)
4171 {
4172     auto_gc_trigger = 0;
4173 }
4174 \f
4175 /* Find the code object for the given pc, or return NULL on failure.
4176  *
4177  * FIXME: PC shouldn't be lispobj*, should it? Maybe void*? */
4178 lispobj *
4179 component_ptr_from_pc(lispobj *pc)
4180 {
4181     lispobj *object = NULL;
4182
4183     if ( (object = search_read_only_space(pc)) )
4184         ;
4185     else if ( (object = search_static_space(pc)) )
4186         ;
4187     else
4188         object = search_dynamic_space(pc);
4189
4190     if (object) /* if we found something */
4191         if (widetag_of(*object) == CODE_HEADER_WIDETAG) /* if it's a code object */
4192             return(object);
4193
4194     return (NULL);
4195 }
4196 \f
4197 /*
4198  * shared support for the OS-dependent signal handlers which
4199  * catch GENCGC-related write-protect violations
4200  */
4201
4202 void unhandled_sigmemoryfault(void);
4203
4204 /* Depending on which OS we're running under, different signals might
4205  * be raised for a violation of write protection in the heap. This
4206  * function factors out the common generational GC magic which needs
4207  * to invoked in this case, and should be called from whatever signal
4208  * handler is appropriate for the OS we're running under.
4209  *
4210  * Return true if this signal is a normal generational GC thing that
4211  * we were able to handle, or false if it was abnormal and control
4212  * should fall through to the general SIGSEGV/SIGBUS/whatever logic. */
4213
4214 int
4215 gencgc_handle_wp_violation(void* fault_addr)
4216 {
4217     int  page_index = find_page_index(fault_addr);
4218
4219 #if defined QSHOW_SIGNALS
4220     FSHOW((stderr, "heap WP violation? fault_addr=%x, page_index=%d\n",
4221            fault_addr, page_index));
4222 #endif
4223
4224     /* Check whether the fault is within the dynamic space. */
4225     if (page_index == (-1)) {
4226
4227         /* It can be helpful to be able to put a breakpoint on this
4228          * case to help diagnose low-level problems. */
4229         unhandled_sigmemoryfault();
4230
4231         /* not within the dynamic space -- not our responsibility */
4232         return 0;
4233
4234     } else {
4235
4236         /* The only acceptable reason for an signal like this from the
4237          * heap is that the generational GC write-protected the page. */
4238         if (page_table[page_index].write_protected != 1) {
4239             lose("access failure in heap page not marked as write-protected");
4240         }
4241         
4242         /* Unprotect the page. */
4243         os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
4244         page_table[page_index].write_protected = 0;
4245         page_table[page_index].write_protected_cleared = 1;
4246
4247         /* Don't worry, we can handle it. */
4248         return 1;
4249     }
4250 }
4251
4252 /* This is to be called when we catch a SIGSEGV/SIGBUS, determine that
4253  * it's not just a case of the program hitting the write barrier, and
4254  * are about to let Lisp deal with it. It's basically just a
4255  * convenient place to set a gdb breakpoint. */
4256 void
4257 unhandled_sigmemoryfault()
4258 {}
4259
4260 gc_alloc_update_all_page_tables(void)
4261 {
4262     /* Flush the alloc regions updating the tables. */
4263     gc_alloc_update_page_tables(1, &unboxed_region);
4264     gc_alloc_update_page_tables(0, &boxed_region);
4265 }
4266 void 
4267 gc_set_region_empty(struct alloc_region *region)
4268 {
4269     region->first_page = 0;
4270     region->last_page = -1;
4271     region->start_addr = page_address(0);
4272     region->free_pointer = page_address(0);
4273     region->end_addr = page_address(0);
4274 }
4275