1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 2001-2008
5 * Compacting garbage collector
7 * Documentation on the architecture of the Garbage Collector can be
8 * found in the online commentary:
10 * http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
12 * ---------------------------------------------------------------------------*/
14 #include "PosixSource.h"
19 #include "BlockAlloc.h"
29 // Turn off inlining when debugging - it obfuscates things
32 # define STATIC_INLINE static
35 /* ----------------------------------------------------------------------------
36 Threading / unthreading pointers.
38 The basic idea here is to chain together all the fields pointing at
39 a particular object, with the root of the chain in the object's
40 info table field. The original contents of the info pointer goes
41 at the end of the chain.
43 Adding a new field to the chain is a matter of swapping the
44 contents of the field with the contents of the object's info table
47 To unthread the chain, we walk down it updating all the fields on
48 the chain with the new location of the object. We stop when we
49 reach the info pointer at the end.
51 The main difficulty here is that we need to be able to identify the
52 info pointer at the end of the chain. We can't use the low bits of
53 the pointer for this; they are already being used for
54 pointer-tagging. What's more, we need to retain the
55 pointer-tagging tag bits on each pointer during the
56 threading/unthreading process.
58 Our solution is as follows:
59 - an info pointer (chain length zero) is identified by having tag 0
60 - in a threaded chain of length > 0:
61 - the pointer-tagging tag bits are attached to the info pointer
62 - the first entry in the chain has tag 1
63 - second and subsequent entries in the chain have tag 2
65 This exploits the fact that the tag on each pointer to a given
66 closure is normally the same (if they are not the same, then
67 presumably the tag is not essential and it therefore doesn't matter
68 if we throw away some of the tags).
69 ------------------------------------------------------------------------- */
72 thread (StgClosure **p)
80 q = (StgPtr)UNTAG_CLOSURE(q0);
82 // It doesn't look like a closure at the moment, because the info
83 // ptr is possibly threaded:
84 // ASSERT(LOOKS_LIKE_CLOSURE_PTR(q));
86 if (HEAP_ALLOCED(q)) {
89 if (bd->flags & BF_MARKED)
92 switch (GET_CLOSURE_TAG((StgClosure *)iptr))
95 // this is the info pointer; we are creating a new chain.
96 // save the original tag at the end of the chain.
97 *p = (StgClosure *)((StgWord)iptr + GET_CLOSURE_TAG(q0));
102 // this is a chain of length 1 or more
103 *p = (StgClosure *)iptr;
112 thread_root (void *user STG_UNUSED, StgClosure **p)
117 // This version of thread() takes a (void *), used to circumvent
118 // warnings from gcc about pointer punning and strict aliasing.
119 STATIC_INLINE void thread_ (void *p) { thread((StgClosure **)p); }
122 unthread( StgPtr p, StgWord free )
129 switch (GET_CLOSURE_TAG((StgClosure *)q))
132 // nothing to do; the chain is length zero
136 r = *q0; // r is the info ptr, tagged with the pointer-tag
138 *p = (StgWord)UNTAG_CLOSURE((StgClosure *)r);
151 // Traverse a threaded chain and pull out the info pointer at the end.
152 // The info pointer is also tagged with the appropriate pointer tag
153 // for this closure, which should be attached to the pointer
154 // subsequently passed to unthread().
155 STATIC_INLINE StgWord
156 get_threaded_info( StgPtr p )
160 q = (W_)GET_INFO(UNTAG_CLOSURE((StgClosure *)p));
163 switch (GET_CLOSURE_TAG((StgClosure *)q))
166 ASSERT(LOOKS_LIKE_INFO_PTR(q));
170 StgWord r = *(StgPtr)(q-1);
171 ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)UNTAG_CLOSURE((StgClosure *)r)));
178 barf("get_threaded_info");
182 // A word-aligned memmove will be faster for small objects than libc's or gcc's.
183 // Remember, the two regions *might* overlap, but: to <= from.
185 move(StgPtr to, StgPtr from, nat size)
187 for(; size > 0; --size) {
193 thread_static( StgClosure* p )
195 const StgInfoTable *info;
197 // keep going until we've threaded all the objects on the linked
199 while (p != END_OF_STATIC_LIST) {
202 switch (info->type) {
205 thread(&((StgInd *)p)->indirectee);
206 p = *IND_STATIC_LINK(p);
210 p = *THUNK_STATIC_LINK(p);
213 p = *FUN_STATIC_LINK(p);
216 p = *STATIC_LINK(info,p);
220 barf("thread_static: strange closure %d", (int)(info->type));
227 thread_large_bitmap( StgPtr p, StgLargeBitmap *large_bitmap, nat size )
233 bitmap = large_bitmap->bitmap[b];
234 for (i = 0; i < size; ) {
235 if ((bitmap & 1) == 0) {
236 thread((StgClosure **)p);
240 if (i % BITS_IN(W_) == 0) {
242 bitmap = large_bitmap->bitmap[b];
244 bitmap = bitmap >> 1;
250 thread_arg_block (StgFunInfoTable *fun_info, StgClosure **args)
257 switch (fun_info->f.fun_type) {
259 bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
260 size = BITMAP_SIZE(fun_info->f.b.bitmap);
263 size = GET_FUN_LARGE_BITMAP(fun_info)->size;
264 thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
268 bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
269 size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]);
272 if ((bitmap & 1) == 0) {
273 thread((StgClosure **)p);
276 bitmap = bitmap >> 1;
285 thread_stack(StgPtr p, StgPtr stack_end)
287 const StgRetInfoTable* info;
291 // highly similar to scavenge_stack, but we do pointer threading here.
293 while (p < stack_end) {
295 // *p must be the info pointer of an activation
296 // record. All activation records have 'bitmap' style layout
299 info = get_ret_itbl((StgClosure *)p);
301 switch (info->i.type) {
303 // Dynamic bitmap: the mask is stored on the stack
307 dyn = ((StgRetDyn *)p)->liveness;
309 // traverse the bitmap first
310 bitmap = RET_DYN_LIVENESS(dyn);
311 p = (P_)&((StgRetDyn *)p)->payload[0];
312 size = RET_DYN_BITMAP_SIZE;
314 if ((bitmap & 1) == 0) {
315 thread((StgClosure **)p);
318 bitmap = bitmap >> 1;
322 // skip over the non-ptr words
323 p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
325 // follow the ptr words
326 for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
327 thread((StgClosure **)p);
333 // small bitmap (<= 32 entries, or 64 on a 64-bit machine)
334 case CATCH_RETRY_FRAME:
335 case CATCH_STM_FRAME:
336 case ATOMICALLY_FRAME:
338 case UNDERFLOW_FRAME:
342 bitmap = BITMAP_BITS(info->i.layout.bitmap);
343 size = BITMAP_SIZE(info->i.layout.bitmap);
345 // NOTE: the payload starts immediately after the info-ptr, we
346 // don't have an StgHeader in the same sense as a heap closure.
348 if ((bitmap & 1) == 0) {
349 thread((StgClosure **)p);
352 bitmap = bitmap >> 1;
363 thread((StgClosure **)p);
365 size = BCO_BITMAP_SIZE(bco);
366 thread_large_bitmap(p, BCO_BITMAP(bco), size);
371 // large bitmap (> 32 entries, or 64 on a 64-bit machine)
374 size = GET_LARGE_BITMAP(&info->i)->size;
375 thread_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size);
381 StgRetFun *ret_fun = (StgRetFun *)p;
382 StgFunInfoTable *fun_info;
384 fun_info = FUN_INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure *)
385 get_threaded_info((StgPtr)ret_fun->fun)));
386 // *before* threading it!
387 thread(&ret_fun->fun);
388 p = thread_arg_block(fun_info, ret_fun->payload);
393 barf("thread_stack: weird activation record found on stack: %d",
394 (int)(info->i.type));
400 thread_PAP_payload (StgClosure *fun, StgClosure **payload, StgWord size)
404 StgFunInfoTable *fun_info;
406 fun_info = FUN_INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure *)
407 get_threaded_info((StgPtr)fun)));
408 ASSERT(fun_info->i.type != PAP);
412 switch (fun_info->f.fun_type) {
414 bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
417 thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
421 thread_large_bitmap((StgPtr)payload, BCO_BITMAP(fun), size);
425 bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
428 if ((bitmap & 1) == 0) {
429 thread((StgClosure **)p);
432 bitmap = bitmap >> 1;
442 thread_PAP (StgPAP *pap)
445 p = thread_PAP_payload(pap->fun, pap->payload, pap->n_args);
451 thread_AP (StgAP *ap)
454 p = thread_PAP_payload(ap->fun, ap->payload, ap->n_args);
460 thread_AP_STACK (StgAP_STACK *ap)
463 thread_stack((P_)ap->payload, (P_)ap->payload + ap->size);
464 return (P_)ap + sizeofW(StgAP_STACK) + ap->size;
468 thread_TSO (StgTSO *tso)
470 thread_(&tso->_link);
471 thread_(&tso->global_link);
473 if ( tso->why_blocked == BlockedOnMVar
474 || tso->why_blocked == BlockedOnBlackHole
475 || tso->why_blocked == BlockedOnMsgThrowTo
477 thread_(&tso->block_info.closure);
479 thread_(&tso->blocked_exceptions);
484 thread_(&tso->stackobj);
485 return (StgPtr)tso + sizeofW(StgTSO);
490 update_fwd_large( bdescr *bd )
493 const StgInfoTable* info;
495 for (; bd != NULL; bd = bd->link) {
497 // nothing to do in a pinned block; it might not even have an object
499 if (bd->flags & BF_PINNED) continue;
502 info = get_itbl((StgClosure *)p);
504 switch (info->type) {
510 case MUT_ARR_PTRS_CLEAN:
511 case MUT_ARR_PTRS_DIRTY:
512 case MUT_ARR_PTRS_FROZEN:
513 case MUT_ARR_PTRS_FROZEN0:
518 a = (StgMutArrPtrs*)p;
519 for (p = (P_)a->payload; p < (P_)&a->payload[a->ptrs]; p++) {
520 thread((StgClosure **)p);
527 StgStack *stack = (StgStack*)p;
528 thread_stack(stack->sp, stack->stack + stack->stack_size);
533 thread_AP_STACK((StgAP_STACK *)p);
537 thread_PAP((StgPAP *)p);
543 StgTRecChunk *tc = (StgTRecChunk *)p;
544 TRecEntry *e = &(tc -> entries[0]);
545 thread_(&tc->prev_chunk);
546 for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
548 thread(&e->expected_value);
549 thread(&e->new_value);
555 barf("update_fwd_large: unknown/strange object %d", (int)(info->type));
560 // ToDo: too big to inline
561 static /* STATIC_INLINE */ StgPtr
562 thread_obj (StgInfoTable *info, StgPtr p)
564 switch (info->type) {
566 return p + sizeofW(StgThunk) + 1;
570 return p + sizeofW(StgHeader) + 1;
574 thread(&((StgClosure *)p)->payload[0]);
575 return p + sizeofW(StgHeader) + 1;
578 thread(&((StgThunk *)p)->payload[0]);
579 return p + sizeofW(StgThunk) + 1;
582 return p + sizeofW(StgThunk) + 2;
586 return p + sizeofW(StgHeader) + 2;
589 thread(&((StgThunk *)p)->payload[0]);
590 return p + sizeofW(StgThunk) + 2;
594 thread(&((StgClosure *)p)->payload[0]);
595 return p + sizeofW(StgHeader) + 2;
598 thread(&((StgThunk *)p)->payload[0]);
599 thread(&((StgThunk *)p)->payload[1]);
600 return p + sizeofW(StgThunk) + 2;
604 thread(&((StgClosure *)p)->payload[0]);
605 thread(&((StgClosure *)p)->payload[1]);
606 return p + sizeofW(StgHeader) + 2;
609 StgBCO *bco = (StgBCO *)p;
610 thread_(&bco->instrs);
611 thread_(&bco->literals);
613 return p + bco_sizeW(bco);
620 end = (P_)((StgThunk *)p)->payload +
621 info->layout.payload.ptrs;
622 for (p = (P_)((StgThunk *)p)->payload; p < end; p++) {
623 thread((StgClosure **)p);
625 return p + info->layout.payload.nptrs;
639 end = (P_)((StgClosure *)p)->payload +
640 info->layout.payload.ptrs;
641 for (p = (P_)((StgClosure *)p)->payload; p < end; p++) {
642 thread((StgClosure **)p);
644 return p + info->layout.payload.nptrs;
649 StgWeak *w = (StgWeak *)p;
650 thread(&w->cfinalizer);
653 thread(&w->finalizer);
654 if (w->link != NULL) {
657 return p + sizeofW(StgWeak);
663 StgMVar *mvar = (StgMVar *)p;
664 thread_(&mvar->head);
665 thread_(&mvar->tail);
666 thread(&mvar->value);
667 return p + sizeofW(StgMVar);
672 thread(&((StgInd *)p)->indirectee);
673 return p + sizeofW(StgInd);
677 StgSelector *s = (StgSelector *)p;
678 thread(&s->selectee);
679 return p + THUNK_SELECTOR_sizeW();
683 return thread_AP_STACK((StgAP_STACK *)p);
686 return thread_PAP((StgPAP *)p);
689 return thread_AP((StgAP *)p);
692 return p + arr_words_sizeW((StgArrWords *)p);
694 case MUT_ARR_PTRS_CLEAN:
695 case MUT_ARR_PTRS_DIRTY:
696 case MUT_ARR_PTRS_FROZEN:
697 case MUT_ARR_PTRS_FROZEN0:
702 a = (StgMutArrPtrs *)p;
703 for (p = (P_)a->payload; p < (P_)&a->payload[a->ptrs]; p++) {
704 thread((StgClosure **)p);
707 return (StgPtr)a + mut_arr_ptrs_sizeW(a);
711 return thread_TSO((StgTSO *)p);
715 StgStack *stack = (StgStack*)p;
716 thread_stack(stack->sp, stack->stack + stack->stack_size);
717 return p + stack_sizeW(stack);
723 StgTRecChunk *tc = (StgTRecChunk *)p;
724 TRecEntry *e = &(tc -> entries[0]);
725 thread_(&tc->prev_chunk);
726 for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
728 thread(&e->expected_value);
729 thread(&e->new_value);
731 return p + sizeofW(StgTRecChunk);
735 barf("update_fwd: unknown/strange object %d", (int)(info->type));
741 update_fwd( bdescr *blocks )
749 // cycle through all the blocks in the step
750 for (; bd != NULL; bd = bd->link) {
753 // linearly scan the objects in this block
754 while (p < bd->free) {
755 ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
756 info = get_itbl((StgClosure *)p);
757 p = thread_obj(info, p);
763 update_fwd_compact( bdescr *blocks )
769 bdescr *bd, *free_bd;
776 free = free_bd->start;
778 // cycle through all the blocks in the step
779 for (; bd != NULL; bd = bd->link) {
782 while (p < bd->free ) {
784 while ( p < bd->free && !is_marked(p,bd) ) {
793 m = * ((StgPtr)bd->u.bitmap + ((p - bd->start) / (BITS_IN(StgWord))));
794 m >>= ((p - bd->start) & (BITS_IN(StgWord) - 1));
796 while ( p < bd->free ) {
801 if (((StgWord)p & (sizeof(W_) * BITS_IN(StgWord))) == 0) {
809 // Problem: we need to know the destination for this cell
810 // in order to unthread its info pointer. But we can't
811 // know the destination without the size, because we may
812 // spill into the next block. So we have to run down the
813 // threaded list and get the info ptr first.
815 // ToDo: one possible avenue of attack is to use the fact
816 // that if (p&BLOCK_MASK) >= (free&BLOCK_MASK), then we
817 // definitely have enough room. Also see bug #1147.
818 iptr = get_threaded_info(p);
819 info = INFO_PTR_TO_STRUCT(UNTAG_CLOSURE((StgClosure *)iptr));
823 p = thread_obj(info, p);
826 if (free + size > free_bd->start + BLOCK_SIZE_W) {
827 // set the next bit in the bitmap to indicate that
828 // this object needs to be pushed into the next
829 // block. This saves us having to run down the
830 // threaded info pointer list twice during the next pass.
832 free_bd = free_bd->link;
833 free = free_bd->start;
835 ASSERT(!is_marked(q+1,bd));
838 unthread(q,(StgWord)free + GET_CLOSURE_TAG((StgClosure *)iptr));
848 update_bkwd_compact( generation *gen )
854 bdescr *bd, *free_bd;
856 nat size, free_blocks;
859 bd = free_bd = gen->old_blocks;
860 free = free_bd->start;
863 // cycle through all the blocks in the step
864 for (; bd != NULL; bd = bd->link) {
867 while (p < bd->free ) {
869 while ( p < bd->free && !is_marked(p,bd) ) {
878 m = * ((StgPtr)bd->u.bitmap + ((p - bd->start) / (BITS_IN(StgWord))));
879 m >>= ((p - bd->start) & (BITS_IN(StgWord) - 1));
881 while ( p < bd->free ) {
886 if (((StgWord)p & (sizeof(W_) * BITS_IN(StgWord))) == 0) {
894 if (is_marked(p+1,bd)) {
895 // don't forget to update the free ptr in the block desc.
896 free_bd->free = free;
897 free_bd = free_bd->link;
898 free = free_bd->start;
902 iptr = get_threaded_info(p);
903 unthread(p, (StgWord)free + GET_CLOSURE_TAG((StgClosure *)iptr));
904 ASSERT(LOOKS_LIKE_INFO_PTR((StgWord)((StgClosure *)p)->header.info));
905 info = get_itbl((StgClosure *)p);
906 size = closure_sizeW_((StgClosure *)p,info);
913 if (info->type == STACK) {
914 move_STACK((StgStack *)p, (StgStack *)free);
925 // free the remaining blocks and count what's left.
926 free_bd->free = free;
927 if (free_bd->link != NULL) {
928 freeChain(free_bd->link);
929 free_bd->link = NULL;
936 compact(StgClosure *static_objects)
941 // 1. thread the roots
942 markCapabilities((evac_fn)thread_root, NULL);
944 // the weak pointer lists...
945 if (weak_ptr_list != NULL) {
946 thread((void *)&weak_ptr_list);
948 if (old_weak_ptr_list != NULL) {
949 thread((void *)&old_weak_ptr_list); // tmp
953 for (g = 1; g < RtsFlags.GcFlags.generations; g++) {
957 for (bd = generations[g].mut_list; bd != NULL; bd = bd->link) {
958 for (p = bd->start; p < bd->free; p++) {
959 thread((StgClosure **)p);
962 for (n = 0; n < n_capabilities; n++) {
963 for (bd = capabilities[n].mut_lists[g];
964 bd != NULL; bd = bd->link) {
965 for (p = bd->start; p < bd->free; p++) {
966 thread((StgClosure **)p);
972 // the global thread list
973 for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
974 thread((void *)&generations[g].threads);
977 // any threads resurrected during this GC
978 thread((void *)&resurrected_threads);
984 for (task = all_tasks; task != NULL; task = task->all_link) {
985 for (incall = task->incall; incall != NULL;
986 incall = incall->prev_stack) {
988 thread_(&incall->tso);
994 // the static objects
995 thread_static(static_objects /* ToDo: ok? */);
997 // the stable pointer table
998 threadStablePtrTable((evac_fn)thread_root, NULL);
1000 // the CAF list (used by GHCi)
1001 markCAFs((evac_fn)thread_root, NULL);
1003 // 2. update forward ptrs
1004 for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
1005 gen = &generations[g];
1006 debugTrace(DEBUG_gc, "update_fwd: %d", g);
1008 update_fwd(gen->blocks);
1009 update_fwd_large(gen->scavenged_large_objects);
1010 if (g == RtsFlags.GcFlags.generations-1 && gen->old_blocks != NULL) {
1011 debugTrace(DEBUG_gc, "update_fwd: %d (compact)", g);
1012 update_fwd_compact(gen->old_blocks);
1016 // 3. update backward ptrs
1018 if (gen->old_blocks != NULL) {
1019 blocks = update_bkwd_compact(gen);
1020 debugTrace(DEBUG_gc,
1021 "update_bkwd: %d (compact, old: %d blocks, now %d blocks)",
1022 gen->no, gen->n_old_blocks, blocks);
1023 gen->n_old_blocks = blocks;