diff --git a/alloc.c b/alloc.c index 85a4c98b9..579f4e317 100644 --- a/alloc.c +++ b/alloc.c @@ -978,36 +978,32 @@ STATIC GC_bool GC_stopped_mark(GC_stop_func stop_func) return TRUE; } -GC_INNER void GC_set_fl_marks(void **fl) +/* Set all mark bits for the free list whose first entry is q */ +GC_INNER void GC_set_fl_marks(ptr_t q) { - ptr_t q = (ptr_t)fl; -# ifdef GC_ASSERTIONS + if (q /* != NULL */) { /* CPPCHECK */ +# ifdef GC_ASSERTIONS ptr_t q2; -# endif - struct hblk *h = HBLKPTR(q); - struct hblk *last_h = h; - hdr *hhdr; -# ifdef MARK_BIT_PER_OBJ - word sz; -# endif +# endif + struct hblk *h = HBLKPTR(q); + struct hblk *last_h = h; + hdr *hhdr = HDR(h); + IF_PER_OBJ(word sz = hhdr->hb_sz;) - GC_ASSERT(fl != NULL); - hhdr = HDR(h); -# ifdef MARK_BIT_PER_OBJ - sz = hhdr -> hb_sz; -# endif -# ifdef GC_ASSERTIONS +# 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 (NULL == q) break; + if (q == NULL) + break; # ifdef GC_ASSERTIONS /* Detect a cycle in the freelist. The algorithm is to */ /* have a second "twice faster" iterator over the list - */ @@ -1024,14 +1020,12 @@ GC_INNER void GC_set_fl_marks(void **fl) # endif h = HBLKPTR(q); - if (EXPECT(h != last_h, FALSE)) { + if (h != last_h) { last_h = h; - /* Update hhdr and sz. */ hhdr = HDR(h); -# ifdef MARK_BIT_PER_OBJ - sz = hhdr -> hb_sz; -# endif + IF_PER_OBJ(sz = hhdr->hb_sz;) } + } } } @@ -1080,15 +1074,14 @@ GC_INNER void GC_set_fl_marks(void **fl) } #endif /* GC_ASSERTIONS && THREAD_LOCAL_ALLOC */ -/* 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(void **fl) +/* Clear all mark bits for the free list whose first entry is q */ +/* Decrement GC_bytes_found by number of bytes on free list. */ +STATIC void GC_clear_fl_marks(ptr_t q) { - ptr_t q = (ptr_t)fl; 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); @@ -1111,14 +1104,14 @@ STATIC void GC_clear_fl_marks(void **fl) GC_bytes_found -= (signed_word)sz; q = (ptr_t)obj_link(q); - if (NULL == q) break; + if (q == NULL) + break; h = HBLKPTR(q); - if (EXPECT(h != last_h, FALSE)) { + if (h != last_h) { last_h = h; - /* Update hhdr and sz. */ hhdr = HDR(h); - sz = hhdr -> hb_sz; + sz = hhdr->hb_sz; } } } @@ -1188,16 +1181,15 @@ 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++) { - void **fl = GC_obj_kinds[kind].ok_freelist[size]; - - if (fl != NULL) - GC_set_fl_marks(fl); + q = (ptr_t)GC_obj_kinds[kind].ok_freelist[size]; + if (q != NULL) + GC_set_fl_marks(q); } } GC_start_reclaim(TRUE); @@ -1228,16 +1220,15 @@ 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++) { - void **fl = GC_obj_kinds[kind].ok_freelist[size]; - - if (fl != NULL) - GC_clear_fl_marks(fl); + q = (ptr_t)GC_obj_kinds[kind].ok_freelist[size]; + if (q != NULL) + GC_clear_fl_marks(q); } } } diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index c1e6ced90..416601b3b 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1920,11 +1920,13 @@ 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))) @@ -2166,7 +2168,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(void **fl); +GC_INNER void GC_set_fl_marks(ptr_t p); /* Set all mark bits associated with */ /* a free list. */ #if defined(GC_ASSERTIONS) && defined(THREAD_LOCAL_ALLOC) diff --git a/thread_local_alloc.c b/thread_local_alloc.c index 1453acd46..8c810a40c 100644 --- a/thread_local_alloc.c +++ b/thread_local_alloc.c @@ -266,25 +266,22 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_malloc(size_t lb, /* we take care of an individual thread freelist structure. */ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p) { - int j; + ptr_t q; + int k, j; for (j = 0; j < GC_TINY_FREELISTS; ++j) { - int k; - for (k = 0; k < THREAD_FREELISTS_KINDS; ++k) { - void **fl = (void **)AO_load((volatile AO_t *)&p->_freelists[k][j]); - /* Load the pointer atomically as it might be updated */ - /* concurrently by GC_FAST_MALLOC_GRANS. */ - - if ((word)fl > HBLKSIZE) - GC_set_fl_marks(fl); + /* Load the pointer atomically as it might be updated */ + /* concurrently by GC_FAST_MALLOC_GRANS. */ + q = (ptr_t)AO_load((volatile AO_t *)&p->_freelists[k][j]); + if ((word)q > HBLKSIZE) + GC_set_fl_marks(q); } # ifdef GC_GCJ_SUPPORT if (EXPECT(j > 0, TRUE)) { - void **fl = (void **)AO_load((volatile AO_t *)&p->gcj_freelists[j]); - - if ((word)fl > HBLKSIZE) - GC_set_fl_marks(fl); + q = (ptr_t)AO_load((volatile AO_t *)&p->gcj_freelists[j]); + if ((word)q > HBLKSIZE) + GC_set_fl_marks(q); } # endif }