Skip to content

Commit e084a40

Browse files
committed
Check if malloc has succeeded before updating GC counters (#51247)
1 parent ae8f9ad commit e084a40

File tree

1 file changed

+36
-30
lines changed

1 file changed

+36
-30
lines changed

src/gc.c

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3639,7 +3639,8 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
36393639
{
36403640
jl_gcframe_t **pgcstack = jl_get_pgcstack();
36413641
jl_task_t *ct = jl_current_task;
3642-
if (pgcstack != NULL && ct->world_age) {
3642+
void *data = malloc(sz);
3643+
if (data != NULL && pgcstack != NULL && ct->world_age) {
36433644
jl_ptls_t ptls = ct->ptls;
36443645
maybe_collect(ptls);
36453646
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
@@ -3654,14 +3655,15 @@ JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz)
36543655
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
36553656
}
36563657
}
3657-
return malloc(sz);
3658+
return data;
36583659
}
36593660

36603661
JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz)
36613662
{
36623663
jl_gcframe_t **pgcstack = jl_get_pgcstack();
36633664
jl_task_t *ct = jl_current_task;
3664-
if (pgcstack != NULL && ct->world_age) {
3665+
void *data = calloc(nm, sz);
3666+
if (data != NULL && pgcstack != NULL && ct->world_age) {
36653667
jl_ptls_t ptls = ct->ptls;
36663668
maybe_collect(ptls);
36673669
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
@@ -3676,7 +3678,7 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz)
36763678
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
36773679
}
36783680
}
3679-
return calloc(nm, sz);
3681+
return data;
36803682
}
36813683

36823684
JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz)
@@ -3700,7 +3702,8 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
37003702
{
37013703
jl_gcframe_t **pgcstack = jl_get_pgcstack();
37023704
jl_task_t *ct = jl_current_task;
3703-
if (pgcstack != NULL && ct->world_age) {
3705+
void *data = realloc(p, sz);
3706+
if (data != NULL && pgcstack != NULL && ct->world_age) {
37043707
jl_ptls_t ptls = ct->ptls;
37053708
maybe_collect(ptls);
37063709
if (!(sz < old))
@@ -3730,7 +3733,7 @@ JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size
37303733
}
37313734
}
37323735
}
3733-
return realloc(p, sz);
3736+
return data;
37343737
}
37353738

37363739
// allocation wrappers that save the size of allocations, to allow using
@@ -3799,6 +3802,15 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz)
37993802
size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT);
38003803
if (allocsz < sz) // overflow in adding offs, size was "negative"
38013804
jl_throw(jl_memory_exception);
3805+
3806+
int last_errno = errno;
3807+
#ifdef _OS_WINDOWS_
3808+
DWORD last_error = GetLastError();
3809+
#endif
3810+
void *b = malloc_cache_align(allocsz);
3811+
if (b == NULL)
3812+
jl_throw(jl_memory_exception);
3813+
38023814
jl_atomic_store_relaxed(&ptls->gc_num.allocd,
38033815
jl_atomic_load_relaxed(&ptls->gc_num.allocd) + allocsz);
38043816
jl_atomic_store_relaxed(&ptls->gc_num.malloc,
@@ -3810,13 +3822,6 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz)
38103822
jl_atomic_fetch_add_relaxed(&gc_heap_stats.heap_size, alloc_acc + allocsz);
38113823
jl_atomic_store_relaxed(&ptls->gc_num.alloc_acc, 0);
38123824
}
3813-
int last_errno = errno;
3814-
#ifdef _OS_WINDOWS_
3815-
DWORD last_error = GetLastError();
3816-
#endif
3817-
void *b = malloc_cache_align(allocsz);
3818-
if (b == NULL)
3819-
jl_throw(jl_memory_exception);
38203825
#ifdef _OS_WINDOWS_
38213826
SetLastError(last_error);
38223827
#endif
@@ -3831,12 +3836,28 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds
38313836
{
38323837
if (can_collect)
38333838
maybe_collect(ptls);
3834-
3839+
int is_old_marked = jl_astaggedvalue(owner)->bits.gc == GC_OLD_MARKED;
38353840
size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT);
38363841
if (allocsz < sz) // overflow in adding offs, size was "negative"
38373842
jl_throw(jl_memory_exception);
38383843

3839-
if (jl_astaggedvalue(owner)->bits.gc == GC_OLD_MARKED) {
3844+
int last_errno = errno;
3845+
#ifdef _OS_WINDOWS_
3846+
DWORD last_error = GetLastError();
3847+
#endif
3848+
void *b;
3849+
if (isaligned)
3850+
b = realloc_cache_align(d, allocsz, oldsz);
3851+
else
3852+
b = realloc(d, allocsz);
3853+
if (b == NULL)
3854+
jl_throw(jl_memory_exception);
3855+
#ifdef _OS_WINDOWS_
3856+
SetLastError(last_error);
3857+
#endif
3858+
errno = last_errno;
3859+
// gc_managed_realloc_ is currently used exclusively for resizing array buffers.
3860+
if (is_old_marked) {
38403861
ptls->gc_cache.perm_scanned_bytes += allocsz - oldsz;
38413862
inc_live_bytes(allocsz - oldsz);
38423863
}
@@ -3867,21 +3888,6 @@ static void *gc_managed_realloc_(jl_ptls_t ptls, void *d, size_t sz, size_t olds
38673888
}
38683889
}
38693890

3870-
int last_errno = errno;
3871-
#ifdef _OS_WINDOWS_
3872-
DWORD last_error = GetLastError();
3873-
#endif
3874-
void *b;
3875-
if (isaligned)
3876-
b = realloc_cache_align(d, allocsz, oldsz);
3877-
else
3878-
b = realloc(d, allocsz);
3879-
if (b == NULL)
3880-
jl_throw(jl_memory_exception);
3881-
#ifdef _OS_WINDOWS_
3882-
SetLastError(last_error);
3883-
#endif
3884-
errno = last_errno;
38853891
maybe_record_alloc_to_profile((jl_value_t*)b, sz, jl_gc_unknown_type_tag);
38863892
return b;
38873893
}

0 commit comments

Comments
 (0)