Skip to content

Instantly share code, notes, and snippets.

@yuga
Created October 18, 2012 05:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuga/3909984 to your computer and use it in GitHub Desktop.
Save yuga/3909984 to your computer and use it in GitHub Desktop.
GHCがpinned objectをどのようにGCで回収するか

山本和彦 ?@kazu_yamamoto 教えて詳しい人:GHC では ByteString が pinned object なんですが、どうやって GC に回収されるんでしょうか?

詳しくはないけど、ざっと追いかけてみる。

GHC 7.4.1 rts/sm/Storage.c:743

// If we don't have a block of pinned objects yet, or the current
// one isn't large enough to hold the new object, allocate a new one.
if (bd == NULL || (bd->free + n) > (bd->start + BLOCK_SIZE_W)) {
    // The pinned_object_block remains attached to the capability
    // until it is full, even if a GC occurs.  We want this
    // behaviour because otherwise the unallocated portion of the
    // block would be forever slop, and under certain workloads
    // (allocating a few ByteStrings per GC) we accumulate a lot
    // of slop.
    //
    // So, the pinned_object_block is initially marked
    // BF_EVACUATED so the GC won't touch it.  When it is full,
    // we place it on the large_objects list, and at the start of
    // the next GC the BF_EVACUATED flag will be cleared, and the
    // block will be promoted as usual (if anything in it is
    // live).
    ACQUIRE_SM_LOCK;
    if (bd != NULL) {
        dbl_link_onto(bd, &g0->large_objects);
        g0->n_large_blocks++;
        g0->n_new_large_words += bd->free - bd->start;
    }
    cap->pinned_object_block = bd = allocBlock();
    RELEASE_SM_LOCK;
    initBdescr(bd, g0, g0);
    bd->flags  = BF_PINNED | BF_LARGE | BF_EVACUATED;
    bd->free   = bd->start;
}

rts/sm/GC.c:1279

// mark the large objects as from-space
for (bd = gen->large_objects; bd; bd = bd->link) {
    bd->flags &= ~BF_EVACUATED;
}

以上をまとめると:

  1. pinned objectはpinned_object_blockに配置してGCがさわらないようにBF_EVACUATEDフラグをたてておく。
  2. pinned_object_blockがいっぱいになったら、ブロックごとlarge_objects listにうつして、新しいpinned_object_blockをつくる。
  3. large_objects listの中身は、GC開始時にBF_EVACUATEDフラグをオフにされるので、GCで回収されるようになる。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment