@@ -176,10 +176,29 @@ static const int jl_gc_sizeclasses[JL_GC_N_POOLS] = {
176
176
// 64, 32, 160, 64, 16, 64, 112, 128, bytes lost
177
177
};
178
178
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
+ }
180
196
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)
182
199
{
200
+ // Check that the object fits in the largest pool.
201
+ assert (sz <= GC_MAX_SZCLASS + sizeof (jl_taggedvalue_t ));
183
202
#ifdef _P64
184
203
if (sz <= 8 )
185
204
return 0 ;
@@ -207,19 +226,28 @@ STATIC_INLINE int JL_CONST_FUNC jl_gc_szclass(size_t sz, size_t alignment)
207
226
#else
208
227
# define jl_is_constexpr (e ) (0 )
209
228
#endif
229
+ <<<<<<< HEAD
230
+ =======
231
+
232
+ #define jl_buff_tag ((uintptr_t )0x4eade800 )
233
+ >>>>>>> 84f91e6f5e... select bucket that fits multiple of alignment
210
234
211
235
STATIC_INLINE jl_value_t *jl_gc_alloc_ (jl_ptls_t ptls, size_t sz, void *ty)
212
236
{
213
237
const size_t allocsz = sz + sizeof (jl_taggedvalue_t );
214
- const size_t alignment = jl_datatype_align (ty);
215
238
if (allocsz < sz) // overflow in adding offs, size was "negative"
216
239
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);
217
245
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 );
220
248
jl_gc_pool_t *p = &ptls->heap .norm_pools [pool_id];
221
249
int osize;
222
- if (jl_is_constexpr (allocsz )) {
250
+ if (jl_is_constexpr (alignsz )) {
223
251
osize = jl_gc_sizeclasses[pool_id];
224
252
}
225
253
else {
@@ -243,7 +271,6 @@ JL_DLLEXPORT jl_value_t *jl_gc_alloc(jl_ptls_t ptls, size_t sz, void *ty);
243
271
# define jl_gc_alloc (ptls, sz, ty ) jl_gc_alloc_(ptls, sz, ty)
244
272
#endif
245
273
246
- #define jl_buff_tag ((uintptr_t )0x4eade800 )
247
274
STATIC_INLINE void *jl_gc_alloc_buf (jl_ptls_t ptls, size_t sz)
248
275
{
249
276
return jl_gc_alloc (ptls, sz, (void *)jl_buff_tag);
0 commit comments