Skip to content

Commit

Permalink
Fix handling of page-unaligned boundaries in soft_set_grungy_pages
Browse files Browse the repository at this point in the history
(a cherry-pick of commit 6601eec from 'master')

Issue #544 (bdwgc).

* os_dep.c [SOFT_VDB] (soft_set_grungy_pages): Rename vaddr argument to
start; define vaddr and next_fpos_hint local variables; change type of
vaddr and next_vaddr from ptr_t to word; initialize vaddr to start
rounded down to page granularity; add assertion that start is
hblk-aligned; enforce next_vaddr is not greater than limit; enforce
h is not smaller than start.
* os_dep.c [SOFT_VDB] (GC_soft_read_dirty): Rename vaddr local variable
to start.
* os_dep.c [SOFT_VDB && !NO_VDB_FOR_STATIC_ROOTS] (GC_soft_read_dirty):
Round start argument of soft_set_grungy_pages() down to block
granularity.
  • Loading branch information
ivmai committed Mar 4, 2024
1 parent 6f3efd1 commit 18fdd57
Showing 1 changed file with 24 additions and 15 deletions.
39 changes: 24 additions & 15 deletions os_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -4094,19 +4094,24 @@ GC_INLINE void GC_proc_read_dirty(GC_bool output_unneeded)
return &soft_vdb_buf[ofs / sizeof(pagemap_elem_t)];
}

static void soft_set_grungy_pages(ptr_t vaddr /* start */, ptr_t limit,
static void soft_set_grungy_pages(ptr_t start, ptr_t limit,
ptr_t next_start_hint)
{
word vaddr = (word)start & ~(word)(GC_page_size-1);
off_t next_fpos_hint;

GC_ASSERT(modHBLKSZ((word)start) == 0);
GC_ASSERT(GC_page_size != 0);
while ((word)vaddr < (word)limit) {
next_fpos_hint = (off_t)((word)next_start_hint / GC_page_size
* sizeof(pagemap_elem_t));
while (vaddr < (word)limit) {
size_t res;
word limit_buf;
const pagemap_elem_t *bufp = pagemap_buffered_read(&res,
(off_t)((word)vaddr / GC_page_size * sizeof(pagemap_elem_t)),
(size_t)((((word)limit - (word)vaddr + GC_page_size-1)
/ GC_page_size) * sizeof(pagemap_elem_t)),
(off_t)((word)next_start_hint / GC_page_size
* sizeof(pagemap_elem_t)));
(off_t)(vaddr / GC_page_size * sizeof(pagemap_elem_t)),
(size_t)(((word)limit - vaddr + GC_page_size-1) / GC_page_size
* sizeof(pagemap_elem_t)),
next_fpos_hint);

if (res % sizeof(pagemap_elem_t) != 0) {
/* Punt: */
Expand All @@ -4115,19 +4120,23 @@ GC_INLINE void GC_proc_read_dirty(GC_bool output_unneeded)
break;
}

limit_buf = ((word)vaddr & ~(word)(GC_page_size-1))
+ (res / sizeof(pagemap_elem_t)) * GC_page_size;
for (; (word)vaddr < limit_buf; vaddr += GC_page_size, bufp++)
limit_buf = vaddr + (res / sizeof(pagemap_elem_t)) * GC_page_size;
for (; vaddr < limit_buf; vaddr += GC_page_size, bufp++)
if ((*bufp & PM_SOFTDIRTY_MASK) != 0) {
struct hblk * h;
ptr_t next_vaddr = vaddr + GC_page_size;
word next_vaddr = vaddr + GC_page_size;

if (EXPECT(next_vaddr > (word)limit, FALSE))
next_vaddr = (word)limit;
/* If the bit is set, the respective PTE was written to */
/* since clearing the soft-dirty bits. */
# ifdef DEBUG_DIRTY_BITS
GC_log_printf("dirty page at: %p\n", (void *)vaddr);
# endif
for (h = (struct hblk *)vaddr; (word)h < (word)next_vaddr; h++) {
h = (struct hblk *)vaddr;
if (EXPECT(vaddr < (word)start, FALSE))
h = (struct hblk *)start;
for (; (word)h < next_vaddr; h++) {
word index = PHT_HASH(h);
set_pht_entry_from_index(GC_grungy_pages, index);
}
Expand Down Expand Up @@ -4163,9 +4172,9 @@ GC_INLINE void GC_proc_read_dirty(GC_bool output_unneeded)
pagemap_buf_len = 0; /* invalidate soft_vdb_buf */

for (i = 0; i != GC_n_heap_sects; ++i) {
ptr_t vaddr = GC_heap_sects[i].hs_start;
ptr_t start = GC_heap_sects[i].hs_start;

soft_set_grungy_pages(vaddr, vaddr + GC_heap_sects[i].hs_bytes,
soft_set_grungy_pages(start, start + GC_heap_sects[i].hs_bytes,
i < GC_n_heap_sects-1 ?
GC_heap_sects[i+1].hs_start : NULL);
}
Expand All @@ -4175,7 +4184,7 @@ GC_INLINE void GC_proc_read_dirty(GC_bool output_unneeded)

# ifndef NO_VDB_FOR_STATIC_ROOTS
for (i = 0; (int)i < n_root_sets; ++i) {
soft_set_grungy_pages(GC_static_roots[i].r_start,
soft_set_grungy_pages((ptr_t)HBLKPTR(GC_static_roots[i].r_start),
GC_static_roots[i].r_end,
(int)i < n_root_sets-1 ?
GC_static_roots[i+1].r_start : NULL);
Expand Down

0 comments on commit 18fdd57

Please sign in to comment.