Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if malloc has succeeded before incrementing gc stats #51247

Merged
merged 2 commits into from
Sep 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3650,7 +3650,8 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
{
jl_gcframe_t **pgcstack = jl_get_pgcstack();
jl_task_t *ct = jl_current_task;
if (pgcstack != NULL && ct->world_age) {
void *data = malloc(sz);
if (data != NULL && pgcstack != NULL && ct->world_age) {
jl_ptls_t ptls = ct->ptls;
maybe_collect(ptls);
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
Expand All @@ -3665,14 +3666,15 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
}
}
return malloc(sz);
return data;
}

JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz)
{
jl_gcframe_t **pgcstack = jl_get_pgcstack();
jl_task_t *ct = jl_current_task;
if (pgcstack != NULL && ct->world_age) {
void *data = calloc(nm, sz);
if (data != NULL && pgcstack != NULL && ct->world_age) {
jl_ptls_t ptls = ct->ptls;
maybe_collect(ptls);
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
Expand All @@ -3687,7 +3689,7 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz)
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
}
}
return calloc(nm, sz);
return data;
}

JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz)
Expand All @@ -3711,7 +3713,8 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
{
jl_gcframe_t **pgcstack = jl_get_pgcstack();
jl_task_t *ct = jl_current_task;
if (pgcstack != NULL && ct->world_age) {
void *data = realloc(p, sz);
if (data != NULL && pgcstack != NULL && ct->world_age) {
jl_ptls_t ptls = ct->ptls;
maybe_collect(ptls);
if (!(sz < old))
Expand Down Expand Up @@ -3741,7 +3744,7 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
}
}
}
return realloc(p, sz);
return data;
}

// allocation wrappers that save the size of allocations, to allow using
Expand Down Expand Up @@ -3810,6 +3813,15 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz)
size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT);
if (allocsz < sz) // overflow in adding offs, size was "negative"
jl_throw(jl_memory_exception);

int last_errno = errno;
#ifdef _OS_WINDOWS_
DWORD last_error = GetLastError();
#endif
void *b = malloc_cache_align(allocsz);
if (b == NULL)
jl_throw(jl_memory_exception);

jl_atomic_store_relaxed(&ptls->gc_num.allocd,
jl_atomic_load_relaxed(&ptls->gc_num.allocd) + allocsz);
jl_atomic_store_relaxed(&ptls->gc_num.malloc,
Expand All @@ -3821,13 +3833,6 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz)
jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, alloc_acc + allocsz);
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
}
int last_errno = errno;
#ifdef _OS_WINDOWS_
DWORD last_error = GetLastError();
#endif
void *b = malloc_cache_align(allocsz);
if (b == NULL)
jl_throw(jl_memory_exception);
#ifdef _OS_WINDOWS_
SetLastError(last_error);
#endif
Expand All @@ -3842,12 +3847,28 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds
{
if (can_collect)
maybe_collect(ptls);

int is_old_marked = jl_astaggedvalue(owner)->bits.gc == GC_OLD_MARKED;
size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT);
if (allocsz < sz) // overflow in adding offs, size was "negative"
jl_throw(jl_memory_exception);

if (jl_astaggedvalue(owner)->bits.gc == GC_OLD_MARKED) {
int last_errno = errno;
#ifdef _OS_WINDOWS_
DWORD last_error = GetLastError();
#endif
void *b;
if (isaligned)
b = realloc_cache_align(d, allocsz, oldsz);
else
b = realloc(d, allocsz);
if (b == NULL)
jl_throw(jl_memory_exception);
#ifdef _OS_WINDOWS_
SetLastError(last_error);
#endif
errno = last_errno;
// gc_managed_realloc_ is currently used exclusively for resizing array buffers.
if (is_old_marked) {
ptls->gc_cache.perm_scanned_bytes += allocsz - oldsz;
inc_live_bytes(allocsz - oldsz);
}
Expand Down Expand Up @@ -3877,23 +3898,6 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
}
}

int last_errno = errno;
#ifdef _OS_WINDOWS_
DWORD last_error = GetLastError();
#endif
void *b;
if (isaligned)
b = realloc_cache_align(d, allocsz, oldsz);
else
b = realloc(d, allocsz);
if (b == NULL)
jl_throw(jl_memory_exception);
#ifdef _OS_WINDOWS_
SetLastError(last_error);
#endif
errno = last_errno;
// gc_managed_realloc_ is currently used exclusively for resizing array buffers.
if (allocsz > oldsz) {
maybe_record_alloc_to_profile((jl_value_t*)b, allocsz - oldsz, (jl_datatype_t*)jl_buff_tag);
}
Expand Down