Skip to content

Commit b5331da

Browse files
NHDalyvilterp
andcommitted
Instrument jl_gc_big_alloc() when called from generated code for Allocations Profiler (#44043)
* Instrument jl_gc_big_alloc() when called from generated code for Allocations Profiler Add _maybe_record_alloc_to_profile() call into jl_gc_big_alloc() to allow us to instrument it in the Allocations Profiler. Followup to #43868 Finishes fixing #43688 (gets the stacks, though not the types, of big allocs). ----- - Rename jl_gc_big_alloc to jl_gc_big_alloc_inner, make it inlined - add jl_gc_pool_alloc_noinline that calls jl_gc_big_alloc_inner - replace all internal calls to jl_gc_big_alloc to call this instead - add a new jl_gc_pool_alloc that calls jl_gc_big_alloc_inner - This one is instrumented, and is meant to be called by generated code. Co-authored-by: Pete Vilter <7341+vilterp@users.noreply.github.com>
1 parent 46b692e commit b5331da

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/gc.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ static void sweep_weak_refs(void)
942942
// big value list
943943

944944
// Size includes the tag and the tag is not cleared!!
945-
JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t sz)
945+
static inline jl_value_t *jl_gc_big_alloc_inner(jl_ptls_t ptls, size_t sz)
946946
{
947947
maybe_collect(ptls);
948948
size_t offs = offsetof(bigval_t, header);
@@ -970,6 +970,22 @@ JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t sz)
970970
return jl_valueof(&v->header);
971971
}
972972

973+
// Instrumented version of jl_gc_big_alloc_inner, called into by LLVM-generated code.
974+
JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t sz)
975+
{
976+
jl_value_t *val = jl_gc_big_alloc_inner(ptls, sz);
977+
978+
maybe_record_alloc_to_profile(val, sz, jl_gc_unknown_type_tag);
979+
return val;
980+
}
981+
982+
// This wrapper exists only to prevent `jl_gc_big_alloc_inner` from being inlined into
983+
// its callers. We provide an external-facing interface for callers, and inline `jl_gc_big_alloc_inner`
984+
// into this. (See https://github.com/JuliaLang/julia/pull/43868 for more details.)
985+
jl_value_t *jl_gc_big_alloc_noinline(jl_ptls_t ptls, size_t sz) {
986+
return jl_gc_big_alloc_inner(ptls, sz);
987+
}
988+
973989
// Sweep list rooted at *pv, removing and freeing any unmarked objects.
974990
// Return pointer to last `next` field in the culled list.
975991
static bigval_t **sweep_big_list(int sweep_full, bigval_t **pv) JL_NOTSAFEPOINT

src/julia_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ JL_DLLEXPORT extern const char *jl_filename;
228228

229229
jl_value_t *jl_gc_pool_alloc_noinline(jl_ptls_t ptls, int pool_offset,
230230
int osize);
231-
JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t allocsz);
231+
jl_value_t *jl_gc_big_alloc_noinline(jl_ptls_t ptls, size_t allocsz);
232232
int jl_gc_classify_pools(size_t sz, int *osize);
233233
extern jl_mutex_t gc_perm_lock;
234234
void *jl_gc_perm_alloc_nolock(size_t sz, int zero,
@@ -344,7 +344,7 @@ STATIC_INLINE jl_value_t *jl_gc_alloc_(jl_ptls_t ptls, size_t sz, void *ty)
344344
else {
345345
if (allocsz < sz) // overflow in adding offs, size was "negative"
346346
jl_throw(jl_memory_exception);
347-
v = jl_gc_big_alloc(ptls, allocsz);
347+
v = jl_gc_big_alloc_noinline(ptls, allocsz);
348348
}
349349
jl_set_typeof(v, ty);
350350
maybe_record_alloc_to_profile(v, sz, (jl_datatype_t*)ty);

0 commit comments

Comments
 (0)