Skip to content

Commit

Permalink
Assume argument of GC_set_fl_marks is non-null
Browse files Browse the repository at this point in the history
(refactoring)

* alloc.c (GC_set_fl_marks): Remove comment; assume the argument is
not null (add assertion); use "ifdef MARK_BIT_PER_OBJ" instead of
IF_PER_OBJ().
* alloc.c (GC_set_fl_marks, GC_clear_fl_marks): Use EXPECT(FALSE) for
h!=last_h.
* alloc.c (GC_clear_fl_marks): Refine comment.
* alloc.c (GC_finish_collection): Move size and q local variables to
the nested scope.
* include/private/gc_priv.h (IF_PER_OBJ): Remove.
* include/private/gc_priv.h (GC_set_fl_marks): Remove argument name.
  • Loading branch information
ivmai committed Mar 4, 2024
1 parent 0e3cf6d commit 0c88daa
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 33 deletions.
67 changes: 37 additions & 30 deletions alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,32 +978,35 @@ STATIC GC_bool GC_stopped_mark(GC_stop_func stop_func)
return TRUE;
}

/* Set all mark bits for the free list whose first entry is q */
GC_INNER void GC_set_fl_marks(ptr_t q)
{
if (q /* != NULL */) { /* CPPCHECK */
# ifdef GC_ASSERTIONS
# ifdef GC_ASSERTIONS
ptr_t q2;
# endif
struct hblk *h = HBLKPTR(q);
struct hblk *last_h = h;
hdr *hhdr = HDR(h);
IF_PER_OBJ(word sz = hhdr->hb_sz;)
# endif
struct hblk *h = HBLKPTR(q);
struct hblk *last_h = h;
hdr *hhdr;
# ifdef MARK_BIT_PER_OBJ
word sz;
# endif

# ifdef GC_ASSERTIONS
GC_ASSERT(q != NULL);
hhdr = HDR(h);
# ifdef MARK_BIT_PER_OBJ
sz = hhdr -> hb_sz;
# endif
# ifdef GC_ASSERTIONS
q2 = (ptr_t)obj_link(q);
# endif
for (;;) {
# endif
for (;;) {
word bit_no = MARK_BIT_NO((ptr_t)q - (ptr_t)h, sz);

if (!mark_bit_from_hdr(hhdr, bit_no)) {
set_mark_bit_from_hdr(hhdr, bit_no);
INCR_MARKS(hhdr);
}

q = (ptr_t)obj_link(q);
if (q == NULL)
break;
if (NULL == q) break;
# ifdef GC_ASSERTIONS
/* Detect a cycle in the freelist. The algorithm is to */
/* have a second "twice faster" iterator over the list - */
Expand All @@ -1020,12 +1023,14 @@ GC_INNER void GC_set_fl_marks(ptr_t q)
# endif

h = HBLKPTR(q);
if (h != last_h) {
if (EXPECT(h != last_h, FALSE)) {
last_h = h;
/* Update hhdr and sz. */
hhdr = HDR(h);
IF_PER_OBJ(sz = hhdr->hb_sz;)
# ifdef MARK_BIT_PER_OBJ
sz = hhdr -> hb_sz;
# endif
}
}
}
}

Expand Down Expand Up @@ -1074,14 +1079,14 @@ GC_INNER void GC_set_fl_marks(ptr_t q)
}
#endif /* GC_ASSERTIONS && THREAD_LOCAL_ALLOC */

/* Clear all mark bits for the free list whose first entry is q */
/* Decrement GC_bytes_found by number of bytes on free list. */
/* Clear all mark bits for the free list (specified by the first */
/* entry). Decrement GC_bytes_found by number of bytes on free list. */
STATIC void GC_clear_fl_marks(ptr_t q)
{
struct hblk *h = HBLKPTR(q);
struct hblk *last_h = h;
hdr *hhdr = HDR(h);
word sz = hhdr->hb_sz; /* Normally set only once. */
word sz = hhdr -> hb_sz; /* Normally set only once. */

for (;;) {
word bit_no = MARK_BIT_NO((ptr_t)q - (ptr_t)h, sz);
Expand All @@ -1104,14 +1109,14 @@ STATIC void GC_clear_fl_marks(ptr_t q)
GC_bytes_found -= (signed_word)sz;

q = (ptr_t)obj_link(q);
if (q == NULL)
break;
if (NULL == q) break;

h = HBLKPTR(q);
if (h != last_h) {
if (EXPECT(h != last_h, FALSE)) {
last_h = h;
/* Update hhdr and sz. */
hhdr = HDR(h);
sz = hhdr->hb_sz;
sz = hhdr -> hb_sz;
}
}
}
Expand Down Expand Up @@ -1181,13 +1186,14 @@ STATIC void GC_finish_collection(void)
if (GC_find_leak) {
/* Mark all objects on the free list. All objects should be */
/* marked when we're done. */
word size; /* current object size */
unsigned kind;
ptr_t q;

for (kind = 0; kind < GC_n_kinds; kind++) {
word size; /* current object size */

for (size = 1; size <= MAXOBJGRANULES; size++) {
q = (ptr_t)GC_obj_kinds[kind].ok_freelist[size];
ptr_t q = (ptr_t)GC_obj_kinds[kind].ok_freelist[size];

if (q != NULL)
GC_set_fl_marks(q);
}
Expand Down Expand Up @@ -1220,13 +1226,14 @@ STATIC void GC_finish_collection(void)
/* Thus accidentally marking a free list is not a problem; only */
/* objects on the list itself will be marked, and that's fixed here. */
{
word size; /* current object size */
ptr_t q; /* pointer to current object */
unsigned kind;

for (kind = 0; kind < GC_n_kinds; kind++) {
word size; /* current object size */

for (size = 1; size <= MAXOBJGRANULES; size++) {
q = (ptr_t)GC_obj_kinds[kind].ok_freelist[size];
ptr_t q = (ptr_t)GC_obj_kinds[kind].ok_freelist[size];

if (q != NULL)
GC_clear_fl_marks(q);
}
Expand Down
4 changes: 1 addition & 3 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1920,13 +1920,11 @@ struct GC_traced_stack_sect_s {
/* offset and size (in bytes). */
# define MARK_BIT_OFFSET(sz) 1
/* Spacing between useful mark bits. */
# define IF_PER_OBJ(x) x
# define FINAL_MARK_BIT(sz) ((sz) > MAXOBJBYTES? 1 : HBLK_OBJS(sz))
/* Position of final, always set, mark bit. */
#else
# define MARK_BIT_NO(offset, sz) BYTES_TO_GRANULES((word)(offset))
# define MARK_BIT_OFFSET(sz) BYTES_TO_GRANULES(sz)
# define IF_PER_OBJ(x)
# define FINAL_MARK_BIT(sz) \
((sz) > MAXOBJBYTES ? MARK_BITS_PER_HBLK \
: BYTES_TO_GRANULES((sz) * HBLK_OBJS(sz)))
Expand Down Expand Up @@ -2168,7 +2166,7 @@ GC_INNER void GC_clear_hdr_marks(hdr * hhdr);
/* Clear the mark bits in a header */
GC_INNER void GC_set_hdr_marks(hdr * hhdr);
/* Set the mark bits in a header */
GC_INNER void GC_set_fl_marks(ptr_t p);
GC_INNER void GC_set_fl_marks(ptr_t);
/* Set all mark bits associated with */
/* a free list. */
#if defined(GC_ASSERTIONS) && defined(THREAD_LOCAL_ALLOC)
Expand Down

0 comments on commit 0c88daa

Please sign in to comment.