Optionally be less noisy during build
[sbcl.git] / src / runtime / fullcgc.c
blobfafc1596ad5667ea0915ae88e45d28e51b0dd497
1 /*
2 * This software is part of the SBCL system. See the README file for
3 * more information.
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
12 #include "gc.h"
13 #include "gc-internal.h"
14 #include "gc-private.h"
15 #include "genesis/gc-tables.h"
16 #include "genesis/closure.h"
17 #include "genesis/layout.h"
18 #include "genesis/hash-table.h"
19 #include "queue.h"
21 #include <stdio.h>
22 #ifndef LISP_FEATURE_WIN32
23 #define HAVE_GETRUSAGE 1
24 #endif
25 #if HAVE_GETRUSAGE
26 #include <sys/resource.h> // for getrusage()
27 #endif
30 /* Most headered objects use MARK_BIT to record liveness.
31 * Bignums always use the leftmost bit regardless of word size */
32 #define MARK_BIT ((uword_t)1 << 31)
33 #ifdef LISP_FEATURE_64_BIT
34 #define BIGNUM_MARK_BIT ((uword_t)1 << 63)
35 #else
36 #define BIGNUM_MARK_BIT MARK_BIT
37 #endif
39 #define interesting_pointer_p(x) \
40 (find_page_index((void*)x) >= 0 || immobile_space_p(x))
42 #ifdef DEBUG
43 # define dprintf(arg) printf arg
44 FILE * logfile;
45 #else
46 # define dprintf(arg)
47 #endif
49 struct unbounded_queue {
50 struct Qblock* head_block;
51 struct Qblock* tail_block;
52 struct Qblock* recycler;
53 long tot_count; // Not used
54 } scav_queue;
56 /* Initialized to number of pages in page table
57 * and decremented before use. */
58 static page_index_t free_page;
60 /* The whole-page allocator works backwards from the end of dynamic space.
61 * If it collides with 'last_free_page', then you lose. */
62 static void* get_free_page() {
63 --free_page;
64 if (free_page < last_free_page)
65 lose("Needed more space to GC\n");
66 char* mem = page_address(free_page);
67 if (page_need_to_zero(free_page))
68 memset(mem, 0, GENCGC_CARD_BYTES);
69 set_page_need_to_zero(free_page, 1);
70 return mem;
73 /* The suballocator doles out blocks of bits for marking conses live.
74 * Example: If pages are 32768 bytes, and Lisp words are 8 bytes,
75 * then one GC page can hold 2K cons cells.
76 * One byte marks 8 conses (1 bit per cons), 256 bytes mark 2048 conses.
77 * 128 blocks of 256 bytes fit on a 32K GC page. */
78 char *suballocator_free_ptr, *suballocator_end_ptr;
80 static void* allocate_cons_mark_bits() {
81 int nbytes = GENCGC_CARD_BYTES / (2 * N_WORD_BYTES) / 8;
82 if (suballocator_free_ptr + nbytes > suballocator_end_ptr) {
83 suballocator_free_ptr = get_free_page();
84 suballocator_end_ptr = suballocator_free_ptr + GENCGC_CARD_BYTES;
86 void* mem = suballocator_free_ptr;
87 suballocator_free_ptr += nbytes;
88 return mem;
91 static void gc_enqueue(lispobj object)
93 gc_dcheck(is_lisp_pointer(object));
94 struct Qblock* block = scav_queue.tail_block;
95 if (block->count == QBLOCK_CAPACITY) {
96 struct Qblock* next;
97 next = scav_queue.recycler;
98 if (next) {
99 scav_queue.recycler = next->next;
100 next->next = 0;
101 dprintf(("Popped recycle list\n"));
102 } else {
103 next = (struct Qblock*)get_free_page();
104 dprintf(("Alloc'd new block\n"));
106 block = block->next = next;
107 scav_queue.tail_block = block;
109 block->elements[block->tail] = object;
110 if (++block->tail == QBLOCK_CAPACITY) block->tail = 0;
111 ++block->count;
114 static lispobj gc_dequeue()
116 struct Qblock* block = scav_queue.head_block;
117 gc_assert(block->count);
118 int index = block->tail - block->count;
119 lispobj object = block->elements[index + (index<0 ? QBLOCK_CAPACITY : 0)];
120 if (--block->count == 0) {
121 struct Qblock* next = block->next;
122 if (next) {
123 scav_queue.head_block = next;
124 block->next = scav_queue.recycler;
125 scav_queue.recycler = block;
126 dprintf(("Qblock emptied - returned to recycle list\n"));
127 } else {
128 dprintf(("Qblock emptied - NOT returned to recycle list\n"));
131 return object;
134 /* The 'mark_bits' hashtable maps a page address to a block of mark bits
135 * for headerless objects (conses) */
136 struct hopscotch_table mark_bits;
138 static inline uword_t compute_page_key(lispobj cons) {
139 return ALIGN_DOWN(cons, GENCGC_CARD_BYTES);
141 static inline int compute_dword_number(lispobj cons) {
142 return (cons & (GENCGC_CARD_BYTES - 1)) >> (1+WORD_SHIFT);
145 static inline int cons_markedp(lispobj pointer) {
146 unsigned char* bits = (unsigned char*)
147 hopscotch_get(&mark_bits, compute_page_key(pointer), 0);
148 if (!bits) return 0;
149 int index = compute_dword_number(pointer);
150 return (bits[index / 8] >> (index % 8)) & 1;
153 #ifdef RETURN_PC_WIDETAG
154 #define embedded_obj_p(tag) tag==RETURN_PC_WIDETAG || tag==SIMPLE_FUN_WIDETAG
155 #else
156 #define embedded_obj_p(tag) tag==SIMPLE_FUN_WIDETAG
157 #endif
159 /* Return true if OBJ has already survived the current GC. */
160 static inline int pointer_survived_gc_yet(lispobj pointer)
162 if (!interesting_pointer_p(pointer))
163 return 1;
164 if (lowtag_of(pointer) == LIST_POINTER_LOWTAG)
165 return cons_markedp(pointer);
166 lispobj header = *native_pointer(pointer);
167 if (widetag_of(header) == BIGNUM_WIDETAG)
168 return (header & BIGNUM_MARK_BIT) != 0;
169 if (embedded_obj_p(widetag_of(header)))
170 header = *fun_code_header(native_pointer(pointer));
171 return (header & MARK_BIT) != 0;
174 void __mark_obj(lispobj pointer)
176 gc_dcheck(is_lisp_pointer(pointer));
177 if (!interesting_pointer_p(pointer))
178 return;
179 if (lowtag_of(pointer) != LIST_POINTER_LOWTAG) {
180 lispobj* base = native_pointer(pointer);
181 lispobj header = *base;
182 if (widetag_of(header) == BIGNUM_WIDETAG) {
183 *base |= BIGNUM_MARK_BIT;
184 return; // don't enqueue - no pointers
185 } else {
186 if (embedded_obj_p(widetag_of(header))) {
187 base = fun_code_header(base);
188 pointer = make_lispobj(base, OTHER_POINTER_LOWTAG);
189 header = *base;
191 // Bit 31 of the header is the mark bit for all remaining object types.
192 // This avoids clash with the layout pointer of instances and functions,
193 // TLS index of symbols, and various other bits.
194 // The mark bit occupies the same byte as the generation number
195 // in immobile space, but doesn't conflict with that usage.
196 if (header & MARK_BIT)
197 return; // already marked
198 *base |= MARK_BIT;
200 if (unboxed_obj_widetag_p(widetag_of(header)))
201 return;
202 } else {
203 uword_t key = compute_page_key(pointer);
204 int index = compute_dword_number(pointer);
205 unsigned char* bits = (unsigned char*)hopscotch_get(&mark_bits, key, 0);
206 if (!bits) {
207 bits = allocate_cons_mark_bits();
208 hopscotch_insert(&mark_bits, key, (sword_t)bits);
209 } else if (bits[index / 8] & (1 << (index % 8))) {
210 return;
212 // Mark the cons
213 bits[index / 8] |= 1 << (index % 8);
215 gc_enqueue(pointer);
218 inline void gc_mark_obj(lispobj thing) {
219 if (is_lisp_pointer(thing))
220 __mark_obj(thing);
223 static inline void mark_pair(lispobj* where)
225 gc_mark_obj(where[0]);
226 gc_mark_obj(where[1]);
229 void gc_mark_range(lispobj* where, long count) {
230 long i;
231 for(i=0; i<count; ++i)
232 gc_mark_obj(where[i]);
235 #define HT_ENTRY_LIVENESS_FUN_ARRAY_NAME alivep_funs
236 #include "weak-hash-pred.inc"
238 static void trace_object(lispobj* where)
240 lispobj header = *where;
241 int widetag = widetag_of(header);
242 sword_t scan_from = 1;
243 sword_t scan_to = sizetab[widetag](where);
244 sword_t i;
245 struct weak_pointer *weakptr;
246 lispobj layout, bitmap;
248 /* If the C compiler emits this switch as a jump table, order doesn't matter.
249 * But if as consecutive tests, instance and vector should be tested first
250 * as they are the most freequent */
251 switch (widetag) {
252 case INSTANCE_WIDETAG:
253 #ifdef LISP_FEATURE_COMPACT_INSTANCE_HEADER
254 /* No need to deal with FINs for non-compact header, because the layout
255 pointer isn't in the header word, the trampoline pointer can only point
256 to readonly space, and all slots are tagged. */
257 case FUNCALLABLE_INSTANCE_WIDETAG:
258 layout = instance_layout(where);
259 gc_mark_obj(layout);
260 #else
261 layout = instance_layout(where); // will be marked as where[1]
262 #endif
263 if (!layout) break; // fall into general case
264 // mixed boxed/unboxed objects
265 bitmap = ((struct layout*)native_pointer(layout))->bitmap;
266 // If no raw slots, just scan without use of the bitmap.
267 if (bitmap == make_fixnum(-1)) break;
268 for(i=1; i<scan_to; ++i)
269 if (layout_bitmap_logbitp(i-1, bitmap) && is_lisp_pointer(where[i]))
270 __mark_obj(where[i]);
271 return; // do not scan slots
272 case SIMPLE_VECTOR_WIDETAG:
273 if (is_vector_subtype(header, VectorValidHashing)) {
274 lispobj lhash_table = where[2];
275 gc_dcheck(is_lisp_pointer(lhash_table));
276 __mark_obj(lhash_table);
277 struct hash_table* hash_table
278 = (struct hash_table *)native_pointer(lhash_table);
279 if (!hash_table->_weakness) {
280 scav_hash_table_entries(hash_table, alivep_funs, mark_pair);
281 } else {
282 // An object can only be removed from the queue once.
283 // Therefore the 'next' pointer has got to be nil.
284 gc_assert(hash_table->next_weak_hash_table == NIL);
285 hash_table->next_weak_hash_table = (lispobj)weak_hash_tables;
286 weak_hash_tables = hash_table;
288 return;
290 break;
291 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
292 /* on x86[-64], closure->fun is a fixnum-qua-pointer. Convert it to a lisp
293 * pointer to mark it, but not on platforms where it's already a descriptor */
294 case CLOSURE_WIDETAG:
295 gc_mark_obj(((struct closure*)where)->fun - FUN_RAW_ADDR_OFFSET);
296 scan_from = 2;
297 break; // scan slots normally
298 #endif
299 case CODE_HEADER_WIDETAG:
300 for_each_simple_fun(i, fun, (struct code*)where, 0, {
301 gc_mark_range(SIMPLE_FUN_SCAV_START(fun),
302 SIMPLE_FUN_SCAV_NWORDS(fun));
304 scan_to = code_header_words(header);
305 break;
306 case FDEFN_WIDETAG:
307 gc_mark_obj(fdefn_callee_lispobj((struct fdefn*)where));
308 scan_to = 3;
309 break;
310 case WEAK_POINTER_WIDETAG:
311 weakptr = (struct weak_pointer*)where;
312 if (is_lisp_pointer(weakptr->value) && interesting_pointer_p(weakptr->value))
313 add_to_weak_pointer_list(weakptr);
314 return;
315 default:
316 if (unboxed_obj_widetag_p(widetag)) return;
318 for(i=scan_from; i<scan_to; ++i)
319 gc_mark_obj(where[i]);
322 void prepare_for_full_mark_phase()
324 // FIXME: Estimate how large to create mark_bits based on dynamic space size.
325 // Guess 8 words per object, and X% of the objects are conses.
326 // The problem is guessing how localized the conses are: guess that N conses
327 // will reside on fraction*N different pages, which guides us as to how many
328 // hash table entries are needed.
329 hopscotch_create(&mark_bits, HOPSCOTCH_HASH_FUN_DEFAULT,
330 N_WORD_BYTES, /* table values are machine words */
331 65536, /* initial size */
334 free_page = page_table_pages;
335 suballocator_free_ptr = suballocator_end_ptr = 0;
336 struct Qblock* block = (struct Qblock*)get_free_page();
337 dprintf(("Queue block holds %d objects\n", (int)QBLOCK_CAPACITY));
338 scav_queue.head_block = block;
339 scav_queue.tail_block = block;
340 scav_queue.recycler = 0;
341 gc_assert(!scav_queue.head_block->count);
344 void execute_full_mark_phase()
346 #if HAVE_GETRUSAGE
347 struct rusage before, after;
348 getrusage(RUSAGE_SELF, &before);
349 #endif
350 lispobj* where = (lispobj*)STATIC_SPACE_START;
351 lispobj* end = static_space_free_pointer;
352 while (where < end) {
353 lispobj obj = compute_lispobj(where);
354 gc_enqueue(obj);
355 where += lowtag_of(obj) != LIST_POINTER_LOWTAG
356 ? sizetab[widetag_of(*where)](where) : 2;
358 again:
359 while (scav_queue.head_block->count) {
360 lispobj ptr = gc_dequeue();
361 gc_dcheck(ptr != 0);
362 if (lowtag_of(ptr) != LIST_POINTER_LOWTAG)
363 trace_object(native_pointer(ptr));
364 else
365 mark_pair((lispobj*)(ptr - LIST_POINTER_LOWTAG));
367 if (weak_hash_tables) {
368 scav_weak_hash_tables(alivep_funs, mark_pair);
369 if (scav_queue.head_block->count) {
370 dprintf(("looping due to weak objects\n"));
371 goto again;
374 #if HAVE_GETRUSAGE
375 getrusage(RUSAGE_SELF, &after);
376 #define timediff(b,a,field) \
377 (double)((a.field.tv_sec-b.field.tv_sec)*1000000 + \
378 (a.field.tv_usec-b.field.tv_usec)) / 1000000.0
379 if (gencgc_verbose)
380 fprintf(stderr,
381 "[Mark phase: %d pages used, HT-count=%d, ET=%f+%f sys+usr]\n",
382 (int)(page_table_pages - free_page), mark_bits.count,
383 timediff(before, after, ru_stime), timediff(before, after, ru_utime));
384 #endif
387 static void smash_weak_pointers()
389 struct weak_pointer *wp, *next_wp;
390 for (wp = weak_pointers, next_wp = NULL; wp != NULL; wp = next_wp) {
391 gc_assert(widetag_of(wp->header)==WEAK_POINTER_WIDETAG);
393 next_wp = wp->next;
394 wp->next = NULL;
395 if (next_wp == wp) /* gencgc uses a ref to self for end of list */
396 next_wp = NULL;
398 lispobj pointee = wp->value;
399 gc_assert(is_lisp_pointer(pointee));
400 if (!pointer_survived_gc_yet(pointee))
401 wp->value = UNBOUND_MARKER_WIDETAG;
405 __attribute__((unused)) static char *fillerp(lispobj* where)
407 page_index_t page;
408 if (where[0] | where[1])
409 return "cons";
410 if ((page = find_page_index(where)) >= 0 && page_table[page].large_object)
411 return "cons (largeobj filler)";
412 return "cons (filler)";
415 FILE *sweeplog;
417 #ifdef LOG_SWEEP_ACTIONS
418 # define NOTE_GARBAGE(gen,addr,nwords,tally) \
419 { tally[gen] += nwords; \
420 if (sweeplog) \
421 fprintf(sweeplog, "%5d %d #x%"OBJ_FMTX": %"OBJ_FMTX" %"OBJ_FMTX"\n", \
422 (int)nwords, gen, compute_lispobj(addr), \
423 addr[0], addr[1]); }
424 #else
425 # define NOTE_GARBAGE(gen,addr,nwords,tally) tally[gen] += nwords
426 #endif
428 #ifndef LISP_FEATURE_IMMOBILE_SPACE
429 #define __immobile_obj_gen_bits(x) (lose("No page index?"),0)
430 #else
431 static void sweep_fixedobj_pages(long *zeroed)
433 low_page_index_t page;
435 for (page = 0 ; ; ++page) {
436 lispobj *obj = (lispobj*)((char*)IMMOBILE_SPACE_START + page * IMMOBILE_CARD_BYTES);
437 if (obj >= immobile_fixedobj_free_pointer)
438 break;
439 int obj_spacing = fixedobj_page_obj_align(page);
440 if (!obj_spacing)
441 continue;
442 int nwords = fixedobj_page_obj_size(page);
443 lispobj *limit = (lispobj*)((char*)obj + IMMOBILE_CARD_BYTES - obj_spacing);
444 for ( ; obj <= limit ; obj = (lispobj*)((char*)obj + obj_spacing) ) {
445 lispobj header = *obj;
446 if (fixnump(header)) { // is a hole
447 } else if (header & MARK_BIT) { // live object
448 *obj = header ^ MARK_BIT;
449 } else {
450 NOTE_GARBAGE(__immobile_obj_gen_bits(obj), obj, nwords, zeroed);
451 memset(obj, 0, nwords * N_WORD_BYTES);
456 #endif
458 static uword_t sweep(lispobj* where, lispobj* end, uword_t arg)
460 long *zeroed = (long*)arg; // one count per generation
461 sword_t nwords;
463 // TODO: consecutive dead objects on same page should be merged.
464 for ( ; where < end ; where += nwords ) {
465 lispobj header = *where;
466 if (is_cons_half(header)) {
467 nwords = 2;
468 if (!cons_markedp((lispobj)where)) {
469 if (where[0] | where[1]) {
470 cons:
471 gc_dcheck(!immobile_space_p((lispobj)where));
472 NOTE_GARBAGE(page_table[find_page_index(where)].gen,
473 where, 2, zeroed);
474 where[0] = where[1] = 0;
477 } else {
478 nwords = sizetab[widetag_of(header)](where);
479 lispobj markbit =
480 widetag_of(header) != BIGNUM_WIDETAG ? MARK_BIT : BIGNUM_MARK_BIT;
481 if (header & markbit)
482 *where = header ^ markbit;
483 else {
484 // Turn the object into either a (0 . 0) cons
485 // or an unboxed filler depending on size.
486 if (nwords <= 2) // could be SAP, SIMPLE-ARRAY-NIL, 1-word bignum, etc
487 goto cons;
488 struct code* code = (struct code*)where;
489 lispobj header = 2<<N_WIDETAG_BITS | CODE_HEADER_WIDETAG;
490 if (code->header != header) {
491 page_index_t page = find_page_index(where);
492 int gen = page >= 0 ? page_table[page].gen
493 : __immobile_obj_gen_bits(where);
494 NOTE_GARBAGE(gen, where, nwords, zeroed);
495 code->header = header;
496 code->code_size = make_fixnum((nwords - 2) * N_WORD_BYTES);
497 memset(where+2, 0, (nwords - 2) * N_WORD_BYTES);
502 return 0;
505 void execute_full_sweep_phase()
507 long words_zeroed[1+PSEUDO_STATIC_GENERATION]; // One count per generation
509 scan_weak_hash_tables(alivep_funs);
510 smash_weak_pointers();
512 #ifdef LOG_SWEEP_ACTIONS
513 sweeplog = fopen("/tmp/sweep.log", "a");
514 fprintf(sweeplog, "-- begin sweep --\n");
515 #endif
517 memset(words_zeroed, 0, sizeof words_zeroed);
518 #ifdef LISP_FEATURE_IMMOBILE_SPACE
519 sweep_fixedobj_pages(words_zeroed);
520 if (sweeplog) fprintf(sweeplog, "-- varyobj pages --\n");
521 sweep((lispobj*)IMMOBILE_VARYOBJ_SUBSPACE_START, immobile_space_free_pointer,
522 (uword_t)words_zeroed);
523 #endif
524 if (sweeplog) fprintf(sweeplog, "-- dynamic space --\n");
525 walk_generation(sweep, -1, (uword_t)words_zeroed);
526 if (gencgc_verbose) {
527 fprintf(stderr, "[Sweep phase: ");
528 int i;
529 for(i=6;i>=0;--i)
530 fprintf(stderr, "%ld%s", words_zeroed[i], i?"+":"");
531 fprintf(stderr, " words zeroed]\n");
533 hopscotch_destroy(&mark_bits);
534 #ifdef LOG_SWEEP_ACTIONS
535 fclose(sweeplog);
536 sweeplog = 0;
537 #endif
539 page_index_t first_page, last_page;
540 for (first_page = 0; first_page < last_free_page; ++first_page)
541 if (page_table[first_page].write_protected) {
542 last_page = first_page;
543 while (page_table[last_page+1].write_protected)
544 ++last_page;
545 os_protect(page_address(first_page),
546 (last_page - first_page + 1) * GENCGC_CARD_BYTES,
547 OS_VM_PROT_READ | OS_VM_PROT_EXECUTE);
548 first_page = last_page;