Skip to content

Commit

Permalink
Add tag for tracking if object is RAII'd or GC'd
Browse files Browse the repository at this point in the history
To support finalizer elison in Alloy, we need a new way to differentiate
between RAII (non-GC'd) and GC'd objects such that this status can be
changed dynamically. Currently in BDWGC, if we use GC_malloc and
GC_malloc_uncollectable for this distinction, there is no way to change
this after an object has been allocated. Using a spare bit in the mark
header is a convenient way for us to tell the sweep phase whether or not
an object should be considered garbage or whether it is uncollectable
while allowing it to be changed in the future.
  • Loading branch information
jacob-hughes committed Sep 11, 2024
1 parent a69f8b7 commit dc594e7
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
4 changes: 4 additions & 0 deletions include/gc/gc_mark.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,10 @@ GC_API int GC_CALL GC_is_marked(const void *) GC_ATTR_NONNULL(1);
GC_API void GC_CALL GC_clear_mark_bit(const void *) GC_ATTR_NONNULL(1);
GC_API void GC_CALL GC_set_mark_bit(const void *) GC_ATTR_NONNULL(1);

GC_API int GC_CALL GC_is_uncollectable(const void *) GC_ATTR_NONNULL(1);
GC_API void GC_CALL GC_set_uncollectable(const void *) GC_ATTR_NONNULL(1);
GC_API void GC_CALL GC_clear_uncollectable(const void *) GC_ATTR_NONNULL(1);

/* Push everything in the given range onto the mark stack. */
/* (GC_push_conditional pushes either all or only dirty pages depending */
/* on the third argument.) GC_push_all_eager also ensures that stack */
Expand Down
13 changes: 10 additions & 3 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1915,9 +1915,16 @@ struct GC_traced_stack_sect_s {
*/

#ifdef USE_MARK_BYTES
# define mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n])
# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] = 1)
# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] = 0)
# define MARK_TAG 0x1
# define UNCOLLECTABLE_TAG 0x1

# define mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] & MARK_TAG)
# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] |= MARK_TAG)
# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] &= ~MARK_TAG)

# define uncollectable_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] & UNCOLLECTABLE_TAG)
# define set_uncollectable_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] |= UNCOLLECTABLE_TAG)
# define clear_uncollectable_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[n] &= ~UNCOLLECTABLE_TAG)
#else
/* Set mark bit correctly, even if mark bits may be concurrently */
/* accessed. */
Expand Down
37 changes: 37 additions & 0 deletions mark.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,43 @@ GC_API int GC_CALL GC_is_marked(const void *p)
return (int)mark_bit_from_hdr(hhdr, bit_no); /* 0 or 1 */
}

GC_API void GC_CALL GC_set_uncollectable(const void *p)
{
struct hblk *h = HBLKPTR(p);
hdr * hhdr = HDR(h);
word bit_no = MARK_BIT_NO((word)((ptr_t)p - (ptr_t)h), hhdr -> hb_sz);

if (!uncollectable_bit_from_hdr(hhdr, bit_no)) {
set_uncollectable_bit_from_hdr(hhdr, bit_no);
INCR_MARKS(hhdr);
}
}

GC_API void GC_CALL GC_clear_uncollectable(const void *p)
{
struct hblk *h = HBLKPTR(p);
hdr * hhdr = HDR(h);
word bit_no = MARK_BIT_NO((word)((ptr_t)p - (ptr_t)h), hhdr -> hb_sz);

if (uncollectable_bit_from_hdr(hhdr, bit_no)) {
size_t n_marks = hhdr -> hb_n_marks;

GC_ASSERT(n_marks != 0);
clear_uncollectable_bit_from_hdr(hhdr, bit_no);
n_marks--;
hhdr -> hb_n_marks = n_marks;
}
}

GC_API int GC_CALL GC_is_uncollectable(const void *p)
{
struct hblk *h = HBLKPTR(p);
hdr * hhdr = HDR(h);
word bit_no = MARK_BIT_NO((word)((ptr_t)p - (ptr_t)h), hhdr -> hb_sz);

return (int)uncollectable_bit_from_hdr(hhdr, bit_no); /* 0 or 1 */
}

/* Clear mark bits in all allocated heap blocks. This invalidates the */
/* marker invariant, and sets GC_mark_state to reflect this. (This */
/* implicitly starts marking to reestablish the invariant.) */
Expand Down

0 comments on commit dc594e7

Please sign in to comment.