Skip to content

Commit 663ece2

Browse files
committed
Make jl_datatype_size reflect non-padded field size
Padding is then added when creating the struct layout, but otherwise the memory layout should be unchanged. This is an alternative to the proposal in #46260. LLVM size and julia size should now be aligned.
1 parent 61f58be commit 663ece2

File tree

4 files changed

+19
-13
lines changed

4 files changed

+19
-13
lines changed

src/datatype.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static unsigned union_isinlinable(jl_value_t *ty, int pointerfree, size_t *nbyte
282282
size_t sz = jl_datatype_size(ty);
283283
size_t al = jl_datatype_align(ty);
284284
// primitive types in struct slots need their sizes aligned. issue #37974
285-
if (asfield && jl_is_primitivetype(ty))
285+
if (asfield)
286286
sz = LLT_ALIGN(sz, al);
287287
if (*nbytes < sz)
288288
*nbytes = sz;
@@ -465,6 +465,8 @@ void jl_compute_field_offsets(jl_datatype_t *st)
465465
uint32_t fld_npointers = ((jl_datatype_t*)fld)->layout->npointers;
466466
if (((jl_datatype_t*)fld)->layout->haspadding)
467467
haspadding = 1;
468+
if (jl_datatype_size(fld) < fsz)
469+
haspadding = 1;
468470
if (i >= nfields - st->name->n_uninitialized && fld_npointers &&
469471
fld_npointers * sizeof(void*) != fsz) {
470472
// field may be undef (may be uninitialized and contains pointer),
@@ -491,8 +493,13 @@ void jl_compute_field_offsets(jl_datatype_t *st)
491493
}
492494
if (isatomic && fsz > MAX_ATOMIC_SIZE)
493495
needlock = 1;
494-
if (isatomic && fsz <= MAX_ATOMIC_SIZE)
495-
al = fsz = next_power_of_two(fsz);
496+
if (isatomic && fsz <= MAX_ATOMIC_SIZE) {
497+
size_t nfsz = next_power_of_two(fsz);
498+
if (nfsz > fsz) {
499+
haspadding = 1;
500+
}
501+
al = fsz = nfsz;
502+
}
496503
if (al != 0) {
497504
size_t alsz = LLT_ALIGN(sz, al);
498505
if (alsz != sz)
@@ -525,9 +532,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
525532
if (al > alignm)
526533
alignm = al;
527534
}
528-
st->size = LLT_ALIGN(sz, alignm);
529-
if (st->size > sz)
530-
haspadding = 1;
535+
st->size = sz;
531536
if (should_malloc && npointers)
532537
pointers = (uint32_t*)malloc_s(npointers * sizeof(uint32_t));
533538
else
@@ -1470,6 +1475,7 @@ static inline void memassign_safe(int hasptr, jl_value_t *parent, char *dst, con
14701475
memmove_refs((void**)dst, (void**)src, nptr);
14711476
jl_gc_multi_wb(parent, src);
14721477
src = (jl_value_t*)((char*)src + nptr * sizeof(void*));
1478+
dst += nptr * sizeof(void*);
14731479
nb -= nptr * sizeof(void*);
14741480
}
14751481
else {

test/atomics.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ swap(x, y) = y
4646
let T1 = Refxy{NTuple{3,UInt8}},
4747
T2 = ARefxy{NTuple{3,UInt8}}
4848
@test sizeof(T1) == 6
49-
@test sizeof(T2) == 8
49+
@test sizeof(T2) == 7
5050
@test fieldoffset(T1, 1) == 0
5151
@test fieldoffset(T2, 1) == 0
5252
@test fieldoffset(T1, 2) == 3

test/compiler/codegen.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,10 @@ let a = Core.Intrinsics.trunc_int(UInt24, 3),
540540
f(t) = t[2]
541541
@test f((a, true)) === true
542542
@test f((a, false)) === false
543-
@test sizeof(Tuple{UInt24,Bool}) == 8
543+
@test sizeof(Tuple{UInt24,Bool}) == 5
544544
@test sizeof(UInt24) == 3
545545
@test sizeof(Union{UInt8,UInt24}) == 3
546-
@test sizeof(Base.RefValue{Union{UInt8,UInt24}}) == 8
546+
@test sizeof(Base.RefValue{Union{UInt8,UInt24}}) == 5
547547
end
548548

549549
# issue #39232

test/core.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6085,7 +6085,7 @@ let
60856085
@test b.x === Int8(91)
60866086
@test b.z === Int8(23)
60876087
@test b.y === A23367((Int8(1), Int8(2), Int8(3), Int8(4), Int8(5), Int8(6), Int8(7)))
6088-
@test sizeof(b) == 12
6088+
@test sizeof(b) == 11
60896089
@test A23367(Int8(1)).x === Int8(1)
60906090
@test A23367(Int8(0)).x === Int8(0)
60916091
@test A23367(Int16(1)).x === Int16(1)
@@ -6118,17 +6118,17 @@ struct UnionFieldInlineStruct
61186118
y::Union{Float64, Missing}
61196119
end
61206120

6121-
@test sizeof(Vector{UnionFieldInlineStruct}(undef, 2)) == sizeof(UnionFieldInlineStruct) * 2
6121+
@test sizeof(Vector{UnionFieldInlineStruct}(undef, 2)) >= sizeof(UnionFieldInlineStruct) * 2
61226122

61236123
let x = UnionFieldInlineStruct(1, 3.14)
61246124
AInlineUnion = [x for i = 1:10]
6125-
@test sizeof(AInlineUnion) == sizeof(UnionFieldInlineStruct) * 10
6125+
@test sizeof(AInlineUnion) >= sizeof(UnionFieldInlineStruct) * 10
61266126
BInlineUnion = Vector{UnionFieldInlineStruct}(undef, 10)
61276127
copyto!(BInlineUnion, AInlineUnion)
61286128
@test AInlineUnion == BInlineUnion
61296129
@test BInlineUnion[end] == x
61306130
CInlineUnion = vcat(AInlineUnion, BInlineUnion)
6131-
@test sizeof(CInlineUnion) == sizeof(UnionFieldInlineStruct) * 20
6131+
@test sizeof(CInlineUnion) >= sizeof(UnionFieldInlineStruct) * 20
61326132
@test CInlineUnion[end] == x
61336133
end
61346134

0 commit comments

Comments
 (0)