Skip to content

Commit

Permalink
Preserve provenance of capability to heap block
Browse files Browse the repository at this point in the history
(a cherry-pick of commits ab69d29, d8ecfa3, c81f06e, 8c8c740, 403baec,
71cc392 partly from capablevms/bdwgc)

Issue #627 (bdwgc).

Original capability should be used to reclaim memory (and during
explicit object free) rather than a computed integer value for the
capability systems.

* allchblk.c (GC_get_first_part): Set rest_hdr->hb_block value (i.e.,
add hblk pointer within header during re-allocation of GC'd memory).
* dbg_mlc.c [!SHORT_DBG_HDRS] (GC_check_heap_block): Add assertion that
p is equal to hhdr->hb_block.
* headers.c (GC_apply_to_all_blocks): Pass hhdr->hb_block (instead of
HBLK_ADDR(bi,j)) to fn().
* headers.c (GC_apply_to_all_blocks, GC_next_block): Add assertion that
HBLK_ADDR(bi,j) is equal to ADDR(hhdr->hb_block).
* headers.c (GC_next_block): Return hhdr->hb_block instead of
HBLK_ADDR(bi,j).
* headers.c (GC_prev_block): Add TODO item to return hhdr->hb_block
and add the corresponding assertion (as in GC_next_block).
* malloc.c (free_internal): Pass hhdr->hb_block (instead of HBLKPTR(p))
to GC_freehblk(); add assertion that ADDR(HBLKPTR(p)) is equal to
ADDR(hhdr->hb_block).
* reclaim.c (GC_reclaim_small_nonempty_block, GC_reclaim_block): Add
assertion that hbp is equal to hhdr->hb_block.

Co-authored-by: Ivan Maidanski <ivmai@mail.ru>
  • Loading branch information
Dejice Jacob and ivmai committed Aug 3, 2024
1 parent 2be5c2a commit c29365b
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 4 deletions.
3 changes: 2 additions & 1 deletion allchblk.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ GC_INNER void GC_unmap_old(unsigned threshold)

/* Check that the interval is not smaller than the threshold. */
/* The truncated counter value wrapping is handled correctly. */
if ((unsigned short)(GC_gc_no - hhdr->hb_last_reclaimed)
if ((unsigned short)(GC_gc_no - hhdr -> hb_last_reclaimed)
>= (unsigned short)threshold) {
# ifdef COUNT_UNMAPPED_REGIONS
/* Continue with unmapping the block only if it will not */
Expand Down Expand Up @@ -629,6 +629,7 @@ STATIC struct hblk * GC_get_first_part(struct hblk *h, hdr *hhdr,
WARN("Header allocation failed: dropping block\n", 0);
return NULL;
}
rest_hdr -> hb_block = rest;
rest_hdr -> hb_sz = total_size - size_needed;
rest_hdr -> hb_flags = 0;
# ifdef GC_ASSERTIONS
Expand Down
1 change: 1 addition & 0 deletions dbg_mlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL
size_t bit_no;

UNUSED_ARG(dummy);
GC_ASSERT((ptr_t)(hhdr -> hb_block) == p);
plim = sz > MAXOBJBYTES ? p : p + HBLKSIZE - sz;
/* Go through all objects in block. */
for (bit_no = 0; ADDR_GE(plim, p);
Expand Down
7 changes: 5 additions & 2 deletions headers.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,8 @@ GC_API void GC_CALL GC_apply_to_all_blocks(GC_walk_hblk_fn fn,
j -= (signed_word)(hhdr != NULL ? ADDR(hhdr) : 1);
} else {
if (!HBLK_IS_FREE(hhdr)) {
fn((struct hblk *)HBLK_ADDR(bi, j), client_data);
GC_ASSERT(HBLK_ADDR(bi, j) == ADDR(hhdr -> hb_block));
fn(hhdr -> hb_block, client_data);
}
j--;
}
Expand Down Expand Up @@ -374,7 +375,8 @@ GC_INNER struct hblk * GC_next_block(struct hblk *h, GC_bool allow_free)
j++;
} else {
if (allow_free || !HBLK_IS_FREE(hhdr)) {
return (struct hblk *)HBLK_ADDR(bi, j);
GC_ASSERT(HBLK_ADDR(bi, j) == ADDR(hhdr -> hb_block));
return hhdr -> hb_block;
}
j += divHBLKSZ(hhdr -> hb_sz);
}
Expand Down Expand Up @@ -408,6 +410,7 @@ GC_INNER struct hblk * GC_prev_block(struct hblk *h)
} else if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
j -= (signed_word)ADDR(hhdr);
} else {
/* TODO: return hhdr -> hb_block instead */
return (struct hblk *)HBLK_ADDR(bi, j);
}
}
Expand Down
3 changes: 2 additions & 1 deletion malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,8 @@ static void free_internal(void *p, const hdr *hhdr)
if (lb > HBLKSIZE) {
GC_large_allocd_bytes -= HBLKSIZE * OBJ_SZ_TO_BLOCKS(lb);
}
GC_freehblk(HBLKPTR(p));
GC_ASSERT(ADDR(HBLKPTR(p)) == ADDR(hhdr -> hb_block));
GC_freehblk(hhdr -> hb_block);
}
}

Expand Down
4 changes: 4 additions & 0 deletions reclaim.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ STATIC void GC_reclaim_small_nonempty_block(struct hblk *hbp, size_t sz,
if (hhdr -> hb_n_marks) {
*flh = flh_next;
} else {
GC_ASSERT(hbp == hhdr -> hb_block);
GC_bytes_found += (signed_word)HBLKSIZE;
GC_freehblk(hbp);
}
Expand Down Expand Up @@ -410,6 +411,7 @@ STATIC void GC_CALLBACK GC_reclaim_block(struct hblk *hbp,
if (sz > MAXOBJBYTES) { /* 1 big object */
if (!mark_bit_from_hdr(hhdr, 0)) {
if (report_if_found) {
GC_ASSERT(hbp == hhdr -> hb_block);
GC_add_leaked((ptr_t)hbp);
} else {
# ifdef ENABLE_DISCLAIM
Expand All @@ -421,6 +423,7 @@ STATIC void GC_CALLBACK GC_reclaim_block(struct hblk *hbp,
}
}
# endif
GC_ASSERT(hbp == hhdr -> hb_block);
if (sz > HBLKSIZE) {
GC_large_allocd_bytes -= HBLKSIZE * OBJ_SZ_TO_BLOCKS(sz);
}
Expand Down Expand Up @@ -468,6 +471,7 @@ STATIC void GC_CALLBACK GC_reclaim_block(struct hblk *hbp,
}
}
# endif
GC_ASSERT(hbp == hhdr -> hb_block);
if (report_if_found) {
GC_reclaim_small_nonempty_block(hbp, sz,
TRUE /* report_if_found */);
Expand Down

0 comments on commit c29365b

Please sign in to comment.