From 6ca5297b489f6fba84f919e3a04b0b1857a7f6ec Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Sun, 5 May 2024 21:36:09 -0300 Subject: [PATCH] correctly track freed bytes in jl_genericmemory_to_string (#54331) Master version of https://github.com/JuliaLang/julia/pull/54309. Should fix https://github.com/JuliaLang/julia/issues/54275. --------- Co-authored-by: Jameson Nash (cherry picked from commit 92ccc7429fbdcd413a684e0bf02eb16e7a6c27e9) --- src/gc.c | 6 ++++++ src/gc.h | 2 -- src/genericmemory.c | 7 +++++-- src/julia.h | 4 ++-- src/julia_internal.h | 2 ++ 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gc.c b/src/gc.c index 94edc0bb015d4..bb63a1725af2e 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1139,6 +1139,12 @@ void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT jl_atomic_load_relaxed(&ptls->gc_num.allocd) + sz); jl_batch_accum_heap_size(ptls, sz); } + +void jl_gc_count_freed(size_t sz) JL_NOTSAFEPOINT +{ + jl_batch_accum_free_size(jl_current_task->ptls, sz); +} + // Only safe to update the heap inside the GC static void combine_thread_gc_counts(jl_gc_num_t *dest, int update_heap) JL_NOTSAFEPOINT { diff --git a/src/gc.h b/src/gc.h index 4bb8828910e6c..4df6aceb80734 100644 --- a/src/gc.h +++ b/src/gc.h @@ -723,8 +723,6 @@ void gc_stats_big_obj(void); // For debugging void gc_count_pool(void); -size_t jl_genericmemory_nbytes(jl_genericmemory_t *a) JL_NOTSAFEPOINT; - JL_DLLEXPORT void jl_enable_gc_logging(int enable); JL_DLLEXPORT int jl_is_gc_logging_enabled(void); JL_DLLEXPORT uint32_t jl_get_num_stack_mappings(void); diff --git a/src/genericmemory.c b/src/genericmemory.c index f0e7b695f1122..ea52fca66ba48 100644 --- a/src/genericmemory.c +++ b/src/genericmemory.c @@ -161,9 +161,9 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void m = (jl_genericmemory_t*)jl_gc_alloc(ct->ptls, tsz, mtype); m->ptr = data; m->length = nel; - jl_genericmemory_data_owner_field(m) = NULL; - int isaligned = 0; // TODO: allow passing memalign'd buffers + jl_genericmemory_data_owner_field(m) = own_buffer ? (jl_value_t*)m : NULL; if (own_buffer) { + int isaligned = 0; // TODO: allow passing memalign'd buffers jl_gc_track_malloced_genericmemory(ct->ptls, m, isaligned); jl_gc_count_allocd(nel*elsz); } @@ -208,8 +208,11 @@ JL_DLLEXPORT jl_value_t *jl_genericmemory_to_string(jl_genericmemory_t *m, size_ JL_GC_PUSH1(&o); jl_value_t *str = jl_pchar_to_string((const char*)m->ptr, len); JL_GC_POP(); + if (how == 1) // TODO: we might like to early-call jl_gc_free_memory here instead actually, but hopefully `m` will die soon + jl_gc_count_freed(mlength); return str; } + // n.b. how == 0 is always pool-allocated, so the freed bytes are computed from the pool not the object return jl_pchar_to_string((const char*)m->ptr, len); } diff --git a/src/julia.h b/src/julia.h index 5d8e2b1d3a143..1e3aed6e5c3fa 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1148,8 +1148,8 @@ STATIC_INLINE jl_value_t *jl_svecset( /* how - allocation style 0 = data is inlined - 1 = owns the gc-managed data, exclusively - 2 = malloc-allocated pointer (may or may not own it) + 1 = owns the gc-managed data, exclusively (will free it) + 2 = malloc-allocated pointer (does not own it) 3 = has a pointer to the object that owns the data pointer */ STATIC_INLINE int jl_genericmemory_how(jl_genericmemory_t *m) JL_NOTSAFEPOINT diff --git a/src/julia_internal.h b/src/julia_internal.h index 2ea23216b00c1..3e9294bd0b1d6 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -616,7 +616,9 @@ JL_DLLEXPORT int64_t jl_gc_diff_total_bytes(void) JL_NOTSAFEPOINT; JL_DLLEXPORT int64_t jl_gc_sync_total_bytes(int64_t offset) JL_NOTSAFEPOINT; void jl_gc_track_malloced_array(jl_ptls_t ptls, jl_array_t *a) JL_NOTSAFEPOINT; void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT; +size_t jl_genericmemory_nbytes(jl_genericmemory_t *a) JL_NOTSAFEPOINT; void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT; +void jl_gc_count_freed(size_t sz) JL_NOTSAFEPOINT; void jl_gc_run_all_finalizers(jl_task_t *ct); void jl_release_task_stack(jl_ptls_t ptls, jl_task_t *task); void jl_gc_add_finalizer_(jl_ptls_t ptls, void *v, void *f) JL_NOTSAFEPOINT;