2 DLLEXPORT void minor_gc(void);
4 /* used during garbage collection only */
8 bool performing_compaction;
11 /* if true, we collecting AGING space for the second time, so if it is still
12 full, we go on to collect TENURED */
13 bool collecting_aging_again;
15 /* in case a generation fills up in the middle of a gc, we jump back
16 up to try collecting the next generation. */
28 F_GC_STATS gc_stats[MAX_GEN_COUNT];
34 /* What generation was being collected when copy_code_heap_roots() was last
35 called? Until the next call to add_code_block(), future
36 collections of younger generations don't have to touch the code
38 CELL last_code_heap_scan;
40 /* sometimes we grow the heap */
41 bool growing_data_heap;
42 F_DATA_HEAP *old_data_heap;
44 INLINE bool collecting_accumulation_gen_p(void)
47 && collecting_gen == AGING
48 && !collecting_aging_again)
49 || collecting_gen == TENURED);
52 /* test if the pointer is in generation being collected, or a younger one. */
53 INLINE bool should_copy(CELL untagged)
55 if(in_zone(newspace,untagged))
57 if(collecting_gen == TENURED)
59 else if(HAVE_AGING_P && collecting_gen == AGING)
60 return !in_zone(&data_heap->generations[TENURED],untagged);
61 else if(collecting_gen == NURSERY)
62 return in_zone(&nursery,untagged);
65 critical_error("Bug in should_copy",untagged);
70 void copy_handle(CELL *handle);
72 void garbage_collection(volatile CELL gen,
73 bool growing_data_heap_,
74 CELL requested_bytes);
76 /* We leave this many bytes free at the top of the nursery so that inline
77 allocation (which does not call GC because of possible roots in volatile
78 registers) does not run out of memory */
79 #define ALLOT_BUFFER_ZONE 1024
81 /* If this is defined, we GC every 100 allocations. This catches missing local roots */
87 * It is up to the caller to fill in the object's fields in a meaningful
91 INLINE void *allot_object(CELL type, CELL a)
96 if(gc_count++ % 1000 == 0)
104 if(nursery.size - ALLOT_BUFFER_ZONE > a)
106 /* If there is insufficient room, collect the nursery */
107 if(nursery.here + ALLOT_BUFFER_ZONE + a > nursery.end)
108 garbage_collection(NURSERY,false,0);
110 CELL h = nursery.here;
111 nursery.here = h + align8(a);
114 /* If the object is bigger than the nursery, allocate it in
118 F_ZONE *tenured = &data_heap->generations[TENURED];
120 /* If tenured space does not have enough room, collect */
121 if(tenured->here + a > tenured->end)
124 tenured = &data_heap->generations[TENURED];
127 /* If it still won't fit, grow the heap */
128 if(tenured->here + a > tenured->end)
130 garbage_collection(TENURED,true,a);
131 tenured = &data_heap->generations[TENURED];
134 object = allot_zone(tenured,a);
136 /* We have to do this */
137 allot_barrier((CELL)object);
139 /* Allows initialization code to store old->new pointers
140 without hitting the write barrier in the common case of
141 a nursery allocation */
142 write_barrier((CELL)object);
145 *object = tag_header(type);
149 void copy_reachable_objects(CELL scan, CELL *end);
151 void primitive_gc(void);
152 void primitive_gc_stats(void);
153 void clear_gc_stats(void);
154 void primitive_clear_gc_stats(void);
155 void primitive_become(void);