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