Skip to content

Commit 541e8de

Browse files
committed
select bucket that fits multiple of alignment
1 parent 9682d72 commit 541e8de

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

src/gc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,8 @@ int jl_gc_classify_pools(size_t sz, size_t alignment, int *osize)
970970
if (sz > GC_MAX_SZCLASS)
971971
return -1;
972972
size_t allocsz = sz + sizeof(jl_taggedvalue_t);
973-
int klass = jl_gc_szclass(allocsz, alignment);
973+
size_t alignsz = jl_gc_alignsz(allocsz, alignment);
974+
int klass = jl_gc_szclass(alignsz);
974975
*osize = jl_gc_sizeclasses[klass];
975976
return (int)(intptr_t)(&((jl_ptls_t)0)->heap.norm_pools[klass]);
976977
}

src/julia_internal.h

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,29 @@ static const int jl_gc_sizeclasses[JL_GC_N_POOLS] = {
176176
// 64, 32, 160, 64, 16, 64, 112, 128, bytes lost
177177
};
178178

179-
JL_DLLEXPORT int jl_alignment(void* ty);
179+
STATIC_INLINE int JL_CONST_FUNC jl_gc_alignsz(size_t sz, size_t alignment)
180+
{
181+
// The pools are aligned wit JL_CACHE_BYTE_ALIGNMENT (typically 64)
182+
// and we can't guarantee a bigger alignment. This is problematic since
183+
// vectortypes have an alignment fallback that is the next power of two.
184+
// TODO: Needs to be first fixed in LLVM. See #20961
185+
if (alignment > JL_CACHE_BYTE_ALIGNMENT)
186+
alignment = JL_CACHE_BYTE_ALIGNMENT
187+
188+
// Pools with the correct alignment will have an object size that
189+
// is a multiple of the alignment. As an example an allocation with
190+
// sz of 48 and an alignment of 32 will need to be in pool of size 64.
191+
// An alignment of 0 or 1 means unaligned and we can use sz directly.
192+
if (alignment != 0 && alignment != 1 && alignment != sz)
193+
sz = ((sz / alignment) + 1) * alignment;
194+
return sz;
195+
}
180196

181-
STATIC_INLINE int JL_CONST_FUNC jl_gc_szclass(size_t sz, size_t alignment)
197+
// Use jl_gc_alignsz to obtain the right sz.
198+
STATIC_INLINE int JL_CONST_FUNC jl_gc_szclass(size_t sz)
182199
{
200+
// Check that the object fits in the largest pool.
201+
assert(sz <= GC_MAX_SZCLASS + sizeof(jl_taggedvalue_t));
183202
#ifdef _P64
184203
if (sz <= 8)
185204
return 0;
@@ -207,19 +226,28 @@ STATIC_INLINE int JL_CONST_FUNC jl_gc_szclass(size_t sz, size_t alignment)
207226
#else
208227
# define jl_is_constexpr(e) (0)
209228
#endif
229+
<<<<<<< HEAD
230+
=======
231+
232+
#define jl_buff_tag ((uintptr_t)0x4eade800)
233+
>>>>>>> 84f91e6f5e... select bucket that fits multiple of alignment
210234

211235
STATIC_INLINE jl_value_t *jl_gc_alloc_(jl_ptls_t ptls, size_t sz, void *ty)
212236
{
213237
const size_t allocsz = sz + sizeof(jl_taggedvalue_t);
214-
const size_t alignment = jl_datatype_align(ty);
215238
if (allocsz < sz) // overflow in adding offs, size was "negative"
216239
jl_throw(jl_memory_exception);
240+
size_t alignment = JL_SMALL_BYTE_ALIGNMENT;
241+
if (ty && ((uintptr_t)ty != jl_buff_tag) &&
242+
jl_is_datatype(ty) && ((jl_datatype_t*)ty)->layout)
243+
alignment = jl_datatype_align(ty);
244+
const size_t alignsz = jl_gc_alignsz(allocsz, alignment);
217245
jl_value_t *v;
218-
if (allocsz <= GC_MAX_SZCLASS + sizeof(jl_taggedvalue_t)) {
219-
int pool_id = jl_gc_szclass(allocsz, alignment);
246+
if (alignsz <= GC_MAX_SZCLASS + sizeof(jl_taggedvalue_t)) {
247+
int pool_id = jl_gc_szclass(alignsz);
220248
jl_gc_pool_t *p = &ptls->heap.norm_pools[pool_id];
221249
int osize;
222-
if (jl_is_constexpr(allocsz)) {
250+
if (jl_is_constexpr(alignsz)) {
223251
osize = jl_gc_sizeclasses[pool_id];
224252
}
225253
else {
@@ -243,7 +271,6 @@ JL_DLLEXPORT jl_value_t *jl_gc_alloc(jl_ptls_t ptls, size_t sz, void *ty);
243271
# define jl_gc_alloc(ptls, sz, ty) jl_gc_alloc_(ptls, sz, ty)
244272
#endif
245273

246-
#define jl_buff_tag ((uintptr_t)0x4eade800)
247274
STATIC_INLINE void *jl_gc_alloc_buf(jl_ptls_t ptls, size_t sz)
248275
{
249276
return jl_gc_alloc(ptls, sz, (void*)jl_buff_tag);

0 commit comments

Comments
 (0)