Skip to content

Commit

Permalink
Merge pull request #25 from jacob-hughes/uncollectable_bit
Browse files Browse the repository at this point in the history
Add tag for tracking if object is RAII'd or GC'd
  • Loading branch information
ltratt authored Sep 16, 2024
2 parents a69f8b7 + b75dc0b commit a1b1276
Show file tree
Hide file tree
Showing 3 changed files with 45 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
31 changes: 31 additions & 0 deletions mark.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,37 @@ 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);
}
}

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)) {
clear_uncollectable_bit_from_hdr(hhdr, bit_no);
}
}

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 a1b1276

Please sign in to comment.