Skip to content

Commit 285f0ed

Browse files
d-nettovtjnash
authored andcommitted
count bytes allocated through malloc more precisely
1 parent 9af0dea commit 285f0ed

File tree

5 files changed

+50
-19
lines changed

5 files changed

+50
-19
lines changed

src/gc-common.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
#include "julia_gcext.h"
77
#include "julia_assert.h"
88
#include "threading.h"
9-
#ifdef __GLIBC__
10-
#include <malloc.h> // for malloc_trim
11-
#endif
129

1310
#ifdef __cplusplus
1411
extern "C" {
@@ -120,6 +117,37 @@ JL_DLLEXPORT void jl_gc_set_cb_notify_gc_pressure(jl_gc_cb_notify_gc_pressure_t
120117
jl_gc_deregister_callback(&gc_cblist_notify_gc_pressure, (jl_gc_cb_func_t)cb);
121118
}
122119

120+
// =========================================================================== //
121+
// malloc wrappers, aligned allocation
122+
// =========================================================================== //
123+
124+
#if defined(_OS_WINDOWS_)
125+
// helper function based partly on wine msvcrt80+ heap.c
126+
// but with several bugfixes to include offset and remove off-by-one mistake in computation
127+
// and removed unnecessary parameters
128+
#define SAVED_PTR(x) ((void *)((DWORD_PTR)((char *)x - sizeof(void *)) & \
129+
~(sizeof(void *) - 1)))
130+
static size_t _aligned_msize(void *p)
131+
{
132+
void *alloc_ptr = *(void**)SAVED_PTR(p);
133+
return _msize(alloc_ptr) - ((char*)p - (char*)alloc_ptr);
134+
}
135+
#endif
136+
137+
size_t memory_block_usable_size(void *p, int isaligned) JL_NOTSAFEPOINT
138+
{
139+
#if defined(_OS_WINDOWS_)
140+
if (isaligned)
141+
return _aligned_msize(p);
142+
else
143+
return _msize(p);
144+
#elif defined(_OS_DARWIN_)
145+
return malloc_size(p);
146+
#else
147+
return malloc_usable_size(p);
148+
#endif
149+
}
150+
123151
// =========================================================================== //
124152
// Finalization
125153
// =========================================================================== //

src/gc-common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
#endif
1313
#endif
1414

15+
#include <stdlib.h>
16+
17+
#if defined(_OS_DARWIN_)
18+
#include <malloc/malloc.h>
19+
#else
20+
#include <malloc.h> // for malloc_trim
21+
#endif
22+
1523
#ifdef __cplusplus
1624
extern "C" {
1725
#endif

src/gc-stock.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
#include "julia_atomics.h"
1010
#include "julia_gcext.h"
1111
#include "julia_assert.h"
12-
#ifdef __GLIBC__
13-
#include <malloc.h> // for malloc_trim
14-
#endif
1512

1613
#ifdef __cplusplus
1714
extern "C" {
@@ -569,11 +566,6 @@ void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT
569566
jl_batch_accum_heap_size(ptls, sz);
570567
}
571568

572-
void jl_gc_count_freed(size_t sz) JL_NOTSAFEPOINT
573-
{
574-
jl_batch_accum_free_size(jl_current_task->ptls, sz);
575-
}
576-
577569
// Only safe to update the heap inside the GC
578570
static void combine_thread_gc_counts(jl_gc_num_t *dest, int update_heap) JL_NOTSAFEPOINT
579571
{
@@ -643,13 +635,15 @@ static void jl_gc_free_memory(jl_value_t *v, int isaligned) JL_NOTSAFEPOINT
643635
jl_genericmemory_t *m = (jl_genericmemory_t*)v;
644636
assert(jl_genericmemory_how(m) == 1 || jl_genericmemory_how(m) == 2);
645637
char *d = (char*)m->ptr;
638+
size_t freed_bytes = memory_block_usable_size(d, isaligned);
639+
assert(freed_bytes != 0);
646640
if (isaligned)
647641
jl_free_aligned(d);
648642
else
649643
free(d);
650644
jl_atomic_store_relaxed(&gc_heap_stats.heap_size,
651-
jl_atomic_load_relaxed(&gc_heap_stats.heap_size) - jl_genericmemory_nbytes(m));
652-
gc_num.freed += jl_genericmemory_nbytes(m);
645+
jl_atomic_load_relaxed(&gc_heap_stats.heap_size) - freed_bytes);
646+
gc_num.freed += freed_bytes;
653647
gc_num.freecall++;
654648
}
655649

@@ -3741,11 +3735,13 @@ JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz)
37413735
if (b == NULL)
37423736
jl_throw(jl_memory_exception);
37433737

3738+
size_t allocated_bytes = memory_block_usable_size(b, 1);
3739+
assert(allocated_bytes >= allocsz);
37443740
jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd,
3745-
jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + allocsz);
3741+
jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + allocated_bytes);
37463742
jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.malloc,
37473743
jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.malloc) + 1);
3748-
jl_batch_accum_heap_size(ptls, allocsz);
3744+
jl_batch_accum_heap_size(ptls, allocated_bytes);
37493745
#ifdef _OS_WINDOWS_
37503746
SetLastError(last_error);
37513747
#endif

src/genericmemory.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void
165165
if (own_buffer) {
166166
int isaligned = 0; // TODO: allow passing memalign'd buffers
167167
jl_gc_track_malloced_genericmemory(ct->ptls, m, isaligned);
168-
jl_gc_count_allocd(nel*elsz);
168+
size_t allocated_bytes = memory_block_usable_size(data, isaligned);
169+
jl_gc_count_allocd(allocated_bytes);
169170
}
170171
return m;
171172
}
@@ -208,8 +209,6 @@ JL_DLLEXPORT jl_value_t *jl_genericmemory_to_string(jl_genericmemory_t *m, size_
208209
JL_GC_PUSH1(&o);
209210
jl_value_t *str = jl_pchar_to_string((const char*)m->ptr, len);
210211
JL_GC_POP();
211-
if (how == 1) // TODO: we might like to early-call jl_gc_free_memory here instead actually, but hopefully `m` will die soon
212-
jl_gc_count_freed(mlength);
213212
return str;
214213
}
215214
// n.b. how == 0 is always pool-allocated, so the freed bytes are computed from the pool not the object

src/julia_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,8 +615,8 @@ jl_svec_t *jl_perm_symsvec(size_t n, ...);
615615

616616
void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT;
617617
size_t jl_genericmemory_nbytes(jl_genericmemory_t *a) JL_NOTSAFEPOINT;
618+
size_t memory_block_usable_size(void *mem, int isaligned) JL_NOTSAFEPOINT;
618619
void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT;
619-
void jl_gc_count_freed(size_t sz) JL_NOTSAFEPOINT;
620620
void jl_gc_run_all_finalizers(jl_task_t *ct);
621621
void jl_release_task_stack(jl_ptls_t ptls, jl_task_t *task);
622622
void jl_gc_add_finalizer_(jl_ptls_t ptls, void *v, void *f) JL_NOTSAFEPOINT;

0 commit comments

Comments
 (0)