From 5bdc1b34cf29db9261a540faecea97ebd941885f Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Thu, 5 Oct 2023 11:04:23 -0300 Subject: [PATCH] correctly track element pointer in heap snapshot (#51592) Fixes https://github.com/JuliaLang/julia/issues/51576 on a simple snapshot I collected on my machine. --- src/gc.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/gc.c b/src/gc.c index 190b9810010e9..1b5247b208429 100644 --- a/src/gc.c +++ b/src/gc.c @@ -2064,7 +2064,8 @@ STATIC_INLINE void gc_mark_objarray(jl_ptls_t ptls, jl_value_t *obj_parent, jl_v // the first young object before starting this chunk // (this also would be valid for young objects, but probably less beneficial) for (; obj_begin < obj_end; obj_begin += step) { - new_obj = *obj_begin; + jl_value_t **slot = obj_begin; + new_obj = *slot; if (new_obj != NULL) { verify_parent2("obj array", obj_parent, obj_begin, "elem(%d)", gc_slot_to_arrayidx(obj_parent, obj_begin)); @@ -2073,7 +2074,7 @@ STATIC_INLINE void gc_mark_objarray(jl_ptls_t ptls, jl_value_t *obj_parent, jl_v nptr |= 1; if (!gc_marked(o->header)) break; - gc_heap_snapshot_record_array_edge(obj_parent, &new_obj); + gc_heap_snapshot_record_array_edge(obj_parent, slot); } } } @@ -2095,13 +2096,14 @@ STATIC_INLINE void gc_mark_objarray(jl_ptls_t ptls, jl_value_t *obj_parent, jl_v } } for (; obj_begin < scan_end; obj_begin += step) { + jl_value_t **slot = obj_begin; new_obj = *obj_begin; if (new_obj != NULL) { verify_parent2("obj array", obj_parent, obj_begin, "elem(%d)", gc_slot_to_arrayidx(obj_parent, obj_begin)); gc_assert_parent_validity(obj_parent, new_obj); gc_try_claim_and_push(mq, new_obj, &nptr); - gc_heap_snapshot_record_array_edge(obj_parent, &new_obj); + gc_heap_snapshot_record_array_edge(obj_parent, slot); } } if (too_big) { @@ -2132,7 +2134,8 @@ STATIC_INLINE void gc_mark_array8(jl_ptls_t ptls, jl_value_t *ary8_parent, jl_va for (; ary8_begin < ary8_end; ary8_begin += elsize) { int early_end = 0; for (uint8_t *pindex = elem_begin; pindex < elem_end; pindex++) { - new_obj = ary8_begin[*pindex]; + jl_value_t **slot = &ary8_begin[*pindex]; + new_obj = *slot; if (new_obj != NULL) { verify_parent2("array", ary8_parent, &new_obj, "elem(%d)", gc_slot_to_arrayidx(ary8_parent, ary8_begin)); @@ -2143,7 +2146,7 @@ STATIC_INLINE void gc_mark_array8(jl_ptls_t ptls, jl_value_t *ary8_parent, jl_va early_end = 1; break; } - gc_heap_snapshot_record_array_edge(ary8_parent, &new_obj); + gc_heap_snapshot_record_array_edge(ary8_parent, slot); } } if (early_end) @@ -2169,13 +2172,14 @@ STATIC_INLINE void gc_mark_array8(jl_ptls_t ptls, jl_value_t *ary8_parent, jl_va } for (; ary8_begin < ary8_end; ary8_begin += elsize) { for (uint8_t *pindex = elem_begin; pindex < elem_end; pindex++) { - new_obj = ary8_begin[*pindex]; + jl_value_t **slot = &ary8_begin[*pindex]; + new_obj = *slot; if (new_obj != NULL) { verify_parent2("array", ary8_parent, &new_obj, "elem(%d)", gc_slot_to_arrayidx(ary8_parent, ary8_begin)); gc_assert_parent_validity(ary8_parent, new_obj); gc_try_claim_and_push(mq, new_obj, &nptr); - gc_heap_snapshot_record_array_edge(ary8_parent, &new_obj); + gc_heap_snapshot_record_array_edge(ary8_parent, slot); } } } @@ -2207,7 +2211,8 @@ STATIC_INLINE void gc_mark_array16(jl_ptls_t ptls, jl_value_t *ary16_parent, jl_ for (; ary16_begin < ary16_end; ary16_begin += elsize) { int early_end = 0; for (uint16_t *pindex = elem_begin; pindex < elem_end; pindex++) { - new_obj = ary16_begin[*pindex]; + jl_value_t **slot = &ary16_begin[*pindex]; + new_obj = *slot; if (new_obj != NULL) { verify_parent2("array", ary16_parent, &new_obj, "elem(%d)", gc_slot_to_arrayidx(ary16_parent, ary16_begin)); @@ -2218,7 +2223,7 @@ STATIC_INLINE void gc_mark_array16(jl_ptls_t ptls, jl_value_t *ary16_parent, jl_ early_end = 1; break; } - gc_heap_snapshot_record_array_edge(ary16_parent, &new_obj); + gc_heap_snapshot_record_array_edge(ary16_parent, slot); } } if (early_end) @@ -2244,13 +2249,14 @@ STATIC_INLINE void gc_mark_array16(jl_ptls_t ptls, jl_value_t *ary16_parent, jl_ } for (; ary16_begin < scan_end; ary16_begin += elsize) { for (uint16_t *pindex = elem_begin; pindex < elem_end; pindex++) { - new_obj = ary16_begin[*pindex]; + jl_value_t **slot = &ary16_begin[*pindex]; + new_obj = *slot; if (new_obj != NULL) { verify_parent2("array", ary16_parent, &new_obj, "elem(%d)", gc_slot_to_arrayidx(ary16_parent, ary16_begin)); gc_assert_parent_validity(ary16_parent, new_obj); gc_try_claim_and_push(mq, new_obj, &nptr); - gc_heap_snapshot_record_array_edge(ary16_parent, &new_obj); + gc_heap_snapshot_record_array_edge(ary16_parent, slot); } } }