[Gc] mark bits for uncollectable

Hans Boehm Hans.Boehm at hp.com
Wed Oct 25 20:53:21 PDT 2006


Having looked at it only superficially, I suspect it's fine with
respect to correctness.  The problem is that now every malloc and free
operation has to find and update the mark bit, right?

I would guess that this is noticeably slower ...

Updating all the mark bits at once is relatively cheap, and is less
of an issue.  (At least that's what I would claim until someone
actually measures it.)

Hans

On Thu, 26 Oct 2006, Bruce Hoult wrote:

> Hi,
>
> I'm doing some memory use tuning of a GC'd application and the
> treatment of mark bits for uncollectable (both atomic and otherwise)
> has become really really annoying becuase it is very difficult to
> figure out how many such objects are in use in e.g. the output from
> GC_dump().
>
> What's worse is that I really don't understand the reasons for the
> current system at all.  Why set all the mark bits in the block, not
> just the ones that correspond to the start of an object?  And they
> don't even stay set.  You get blocks with close to, but not actually,
> 256 bits set.
>
> The attached patch (to a modified gc6.7, but I'm sure it will match up
> fine) works perfectly in our very GC-intensive application, and has
> the benefit of the mark bits behaving exactly the same for
> uncollectable objects as for any other ... a mark bit is set if and
> only if it corresponds to the first word of an allocated object.  It's
> just that it stays set from the time the object is allocated until the
> time (if ever) that GC_free() is called on it.
>
> Is there some non-obvious reason that this is a bad idea?  The only
> thing I can think of is if there is a memory-stomper bug that nukes
> the mark bits.  I'll try to avoid those ;-)
>
> Thanks,
> Bruce
>
> p.s. there's a faster implementation of counting mark bits for free too :-)
>
> ------------ patch follows -------------
> Index: mallocx.c
> ===================================================================
> --- mallocx.c   (revision 7081)
> +++ mallocx.c   (working copy)
> @@ -583,9 +583,7 @@
>              *opp = obj_link(op);
>              obj_link(op) = 0;
>              GC_words_allocd += lw;
> -            /* Mark bit ws already set on free list.  It will be       */
> -           /* cleared only temporarily during a collection, as a       */
> -           /* result of the normal free list mark bit clearing.        */
> +            GC_set_mark_bit(op);
>              GC_non_gc_bytes += WORDS_TO_BYTES(lw);
>              FASTUNLOCK();
>              return((GC_PTR) op);
> @@ -687,7 +685,7 @@
>              *opp = obj_link(op);
>              obj_link(op) = 0;
>              GC_words_allocd += lw;
> -           /* Mark bit was already set while object was on free list. */
> +            GC_set_mark_bit(op);
>              GC_non_gc_bytes += WORDS_TO_BYTES(lw);
>              FASTUNLOCK();
>              return((GC_PTR) op);
> Index: malloc.c
> ===================================================================
> --- malloc.c    (revision 7081)
> +++ malloc.c    (working copy)
> @@ -519,9 +519,10 @@
>         /* A signal here can make GC_mem_freed and GC_non_gc_bytes      */
>         /* inconsistent.  We claim this is benign.                      */
>         if (IS_UNCOLLECTABLE(knd)) GC_non_gc_bytes -= WORDS_TO_BYTES(sz);
> -               /* Its unnecessary to clear the mark bit.  If the       */
> -               /* object is reallocated, it doesn't matter.  O.w. the  */
> -               /* collector will do it, since it's on a free list.     */
> +       /* Its unnecessary to clear the mark bit.  But it's tidier to debug
> +          and it is needed to allow the obj to be reallocated before the
> +          next GC? */
> +       GC_clear_mark_bit(p);
>         if (ok -> ok_init) {
>             BZERO((word *)p + 1, WORDS_TO_BYTES(sz-1));
>         }
> @@ -565,6 +566,7 @@
>      if (sz <= MAXOBJSZ) {
>         GC_mem_freed += sz;
>         if (IS_UNCOLLECTABLE(knd)) GC_non_gc_bytes -= WORDS_TO_BYTES(sz);
> +       GC_clear_mark_bit(p);
>         if (ok -> ok_init) {
>             BZERO((word *)p + 1, WORDS_TO_BYTES(sz-1));
>         }
> Index: reclaim.c
> ===================================================================
> --- reclaim.c   (revision 7081)
> +++ reclaim.c   (working copy)
> @@ -733,7 +733,6 @@
>              break;
>        }
>      }
> -    if (IS_UNCOLLECTABLE(hhdr -> hb_obj_kind)) GC_set_hdr_marks(hhdr);
>      return result;
>  }
>
> @@ -865,9 +864,9 @@
>      register word m = n;
>      register int result = 0;
>
> -    while (m > 0) {
> -       if (m & 1) result++;
> -       m >>= 1;
> +    while (m != 0) {
> +       result++;
> +       m &= m - 1;
>      }
>      return(result);
>  }
> Index: new_hblk.c
> ===================================================================
> --- new_hblk.c  (revision 7081)
> +++ new_hblk.c  (working copy)
> @@ -257,9 +257,6 @@
>      h = GC_allochblk(sz, kind, 0);
>      if (h == 0) return;
>
> -  /* Mark all objects if appropriate. */
> -      if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(HDR(h));
> -
>    /* Build the free list */
>        GC_obj_kinds[kind].ok_freelist[sz] =
>         GC_build_fl(h, sz, clear, GC_obj_kinds[kind].ok_freelist[sz]);
> _______________________________________________
> Gc mailing list
> Gc at linux.hpl.hp.com
> http://www.hpl.hp.com/hosted/linux/mail-archives/gc/
>


More information about the Gc mailing list