6dabc0c5d35fb71dfcd3149d1633a97f8ffee5ed
[projects/cmucl/cmucl.git] / src / lisp / gencgc.h
1 /* 
2  * Generational Conservative Garbage Collector for CMUCL x86.
3  *
4  * This code was written by Douglas T. Crosher, based on Public Domain
5  * codes from Carnegie Mellon University. This code has been placed in
6  * the public domain, and is provided 'as is'.
7  *
8  * Douglas Crosher, 1996, 1997.
9  *
10  * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.h,v 1.17 2011/01/09 00:12:36 rtoy Exp $
11  *
12  */
13
14 #ifndef _GENCGC_H_
15 #define _GENCGC_H_
16
17 void gc_free_heap(void);
18 int gc_write_barrier(void *);
19 \f
20
21
22 /*
23  * Set when the page is write protected. If it is writen into it is
24  * made writable and this flag is cleared. This should always reflect
25  * the actual write_protect status of a page.
26  */
27
28 #define PAGE_WRITE_PROTECTED_MASK       0x00000010
29 #define PAGE_WRITE_PROTECTED(page) \
30         (page_table[page].flags & PAGE_WRITE_PROTECTED_MASK)
31
32 /*
33  * This flag is set when the above write protect flag is clear by the
34  * sigbus handler. This is useful for re-scavenging pages that are
35  * written during a GC.
36  */
37
38 #define PAGE_WRITE_PROTECT_CLEARED_MASK 0x00000020
39 #define PAGE_WRITE_PROTECT_CLEARED(page) \
40         (page_table[page].flags & PAGE_WRITE_PROTECT_CLEARED_MASK)
41
42 /*
43  * Page allocated flag: 0 for a free page; 1 when allocated. If
44  * the page is free then the following slots are invalid - well
45  * the bytes_used must be 0.
46  */
47
48 #define PAGE_ALLOCATED_MASK     0x00000040
49 #define PAGE_ALLOCATED(page)    (page_table[page].flags & PAGE_ALLOCATED_MASK)
50
51 /*
52  * Unboxed region flag: 1 for unboxed objects, 0 for boxed objects.
53  */
54 #define PAGE_UNBOXED_MASK               0x00000080
55 #define PAGE_UNBOXED_SHIFT              7
56 #define PAGE_UNBOXED(page)      (page_table[page].flags & PAGE_UNBOXED_MASK)
57 #define PAGE_UNBOXED_VAL(page)  (PAGE_UNBOXED(page) >> PAGE_UNBOXED_SHIFT)
58
59 /*
60  * If this page should not be moved during a GC then this flag is
61  * set. It's only valid during a GC for allocated pages.
62  */
63
64 #define PAGE_DONT_MOVE_MASK             0x00000100
65 #define PAGE_DONT_MOVE(page) \
66         (page_table[page].flags & PAGE_DONT_MOVE_MASK)
67
68 /*
69  * If the page is part of a large object then this flag is set. No
70  * other objects should be allocated to these pages. This is only
71  * valid when the page is allocated.
72  */
73
74 #define PAGE_LARGE_OBJECT_MASK          0x00000200
75 #define PAGE_LARGE_OBJECT_SHIFT         9
76 #define PAGE_LARGE_OBJECT(page) \
77         (page_table[page].flags & PAGE_LARGE_OBJECT_MASK)
78 #define PAGE_LARGE_OBJECT_VAL(page) \
79         (PAGE_LARGE_OBJECT(page) >> PAGE_LARGE_OBJECT_SHIFT)
80
81 /*
82  * The generation that this page belongs to. This should be valid for
83  * all pages that may have objects allocated, even current allocation
84  * region pages - this allows the space of an object to be easily
85  * determined.
86  */
87
88 #define PAGE_GENERATION_MASK            0x0000000f
89 #define PAGE_GENERATION(page) \
90         (page_table[page].flags & PAGE_GENERATION_MASK)
91
92 #define PAGE_FLAGS(page, mask) (page_table[page].flags & (mask))
93 #define PAGE_FLAGS_UPDATE(page, mmask, mflags) \
94      (page_table[page].flags = (page_table[page].flags & ~(mmask)) | (mflags))
95
96 struct page {
97     /*
98      * Page flags.
99      */
100
101     unsigned flags;
102
103     /*
104      * It is important to know the offset to the first object in the
105      * page. Currently it's only important to know if an object starts
106      * at the begining of the page in which case the offset would be 0
107      */
108     int first_object_offset;
109
110     /*
111      * The number of bytes of this page that are used. This may be less
112      * than the actual bytes used for pages within the current
113      * allocation regions. It should be 0 for all unallocated pages (not
114      * hard to achieve).
115      */
116     int bytes_used;
117 };
118 \f
119
120
121 /*
122  * The smallest page size that can be independently allocated and
123  * write protected.
124  */
125
126 #if defined(i386)
127 #define GC_PAGE_SIZE 4096
128 #elif defined(sparc)
129 /*
130  * For sparc, the minimum page size (physical page size) is 8K.
131  * However, some experiments indicate that this gives worse
132  * performance in some cases than the non-gencgc version.  By upping
133  * the page size to 32K, we are as good as before, so let us use a 32K
134  * page size.  (I'm assuming the gain is because we do the kernel
135  * allocation trap less often.)
136  */
137 #define GC_PAGE_SIZE (4*8192)
138 #elif defined(DARWIN)
139 /*
140  * The physical page size is 4K.  Like sparc, this appears to be
141  * somewhat slow (but need to verify that), so let's make the page
142  * size 32K so we hit the allocation trap less often.
143  */
144 /*#define GC_PAGE_SIZE 4096*/
145 /*#define GC_PAGE_SIZE (2*4096)*/
146 #define GC_PAGE_SIZE (4*4096)
147 /*#define GC_PAGE_SIZE (8*4096)*/
148 #endif
149
150 extern unsigned dynamic_space_pages;
151 extern struct page *page_table;
152 \f
153
154 /*
155  * Abstract out the data for an allocation region allowing a single
156  * routine to be used for allocation and closing.
157  */
158 struct alloc_region {
159     /* These two are needed for quick allocation */
160     char *free_pointer;
161     char *end_addr;             /* Pointer to the byte after the last usable byte */
162
163     /* Needed when closing the region. */
164     int first_page;
165     int last_page;
166     char *start_addr;
167 };
168
169 extern struct alloc_region boxed_region;
170 extern struct alloc_region unboxed_region;
171 \f
172
173 void gencgc_pickup_dynamic(void);
174
175 #ifdef i386
176 void sniff_code_object(struct code *code, unsigned displacement);
177 #endif
178 lispobj *search_dynamic_space(lispobj * pointer);
179 void update_dynamic_space_free_pointer(void);
180
181 lispobj *component_ptr_from_pc(lispobj * pc);
182
183 void gc_alloc_update_page_tables(int unboxed,
184
185                                  struct alloc_region *alloc_region);
186
187 extern char *alloc(int);
188
189 #endif /* _GENCGC_H_ */