diff --git a/src/datatype.c b/src/datatype.c index 593a2ededd169..d6604fb790ab1 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -282,7 +282,7 @@ static unsigned union_isinlinable(jl_value_t *ty, int pointerfree, size_t *nbyte size_t sz = jl_datatype_size(ty); size_t al = jl_datatype_align(ty); // primitive types in struct slots need their sizes aligned. issue #37974 - if (asfield && jl_is_primitivetype(ty)) + if (asfield) sz = LLT_ALIGN(sz, al); if (*nbytes < sz) *nbytes = sz; @@ -465,6 +465,8 @@ void jl_compute_field_offsets(jl_datatype_t *st) uint32_t fld_npointers = ((jl_datatype_t*)fld)->layout->npointers; if (((jl_datatype_t*)fld)->layout->haspadding) haspadding = 1; + if (jl_datatype_size(fld) < fsz) + haspadding = 1; if (i >= nfields - st->name->n_uninitialized && fld_npointers && fld_npointers * sizeof(void*) != fsz) { // field may be undef (may be uninitialized and contains pointer), @@ -491,8 +493,13 @@ void jl_compute_field_offsets(jl_datatype_t *st) } if (isatomic && fsz > MAX_ATOMIC_SIZE) needlock = 1; - if (isatomic && fsz <= MAX_ATOMIC_SIZE) - al = fsz = next_power_of_two(fsz); + if (isatomic && fsz <= MAX_ATOMIC_SIZE) { + size_t nfsz = next_power_of_two(fsz); + if (nfsz > fsz) { + haspadding = 1; + } + al = fsz = nfsz; + } if (al != 0) { size_t alsz = LLT_ALIGN(sz, al); if (alsz != sz) @@ -525,9 +532,7 @@ void jl_compute_field_offsets(jl_datatype_t *st) if (al > alignm) alignm = al; } - st->size = LLT_ALIGN(sz, alignm); - if (st->size > sz) - haspadding = 1; + st->size = sz; if (should_malloc && npointers) pointers = (uint32_t*)malloc_s(npointers * sizeof(uint32_t)); else @@ -1470,6 +1475,7 @@ static inline void memassign_safe(int hasptr, jl_value_t *parent, char *dst, con memmove_refs((void**)dst, (void**)src, nptr); jl_gc_multi_wb(parent, src); src = (jl_value_t*)((char*)src + nptr * sizeof(void*)); + dst += nptr * sizeof(void*); nb -= nptr * sizeof(void*); } else { diff --git a/test/atomics.jl b/test/atomics.jl index 15ffd84a2c0a2..1e9a5b087abba 100644 --- a/test/atomics.jl +++ b/test/atomics.jl @@ -46,7 +46,7 @@ swap(x, y) = y let T1 = Refxy{NTuple{3,UInt8}}, T2 = ARefxy{NTuple{3,UInt8}} @test sizeof(T1) == 6 - @test sizeof(T2) == 8 + @test sizeof(T2) == 7 @test fieldoffset(T1, 1) == 0 @test fieldoffset(T2, 1) == 0 @test fieldoffset(T1, 2) == 3 diff --git a/test/compiler/codegen.jl b/test/compiler/codegen.jl index 5db536af6222f..eaa511b6aee10 100644 --- a/test/compiler/codegen.jl +++ b/test/compiler/codegen.jl @@ -540,10 +540,10 @@ let a = Core.Intrinsics.trunc_int(UInt24, 3), f(t) = t[2] @test f((a, true)) === true @test f((a, false)) === false - @test sizeof(Tuple{UInt24,Bool}) == 8 + @test sizeof(Tuple{UInt24,Bool}) == 5 @test sizeof(UInt24) == 3 @test sizeof(Union{UInt8,UInt24}) == 3 - @test sizeof(Base.RefValue{Union{UInt8,UInt24}}) == 8 + @test sizeof(Base.RefValue{Union{UInt8,UInt24}}) == 5 end # issue #39232 diff --git a/test/core.jl b/test/core.jl index a0bd78df8e1ce..3dac23c34b2c1 100644 --- a/test/core.jl +++ b/test/core.jl @@ -6085,7 +6085,7 @@ let @test b.x === Int8(91) @test b.z === Int8(23) @test b.y === A23367((Int8(1), Int8(2), Int8(3), Int8(4), Int8(5), Int8(6), Int8(7))) - @test sizeof(b) == 12 + @test sizeof(b) == 11 @test A23367(Int8(1)).x === Int8(1) @test A23367(Int8(0)).x === Int8(0) @test A23367(Int16(1)).x === Int16(1) @@ -6118,17 +6118,17 @@ struct UnionFieldInlineStruct y::Union{Float64, Missing} end -@test sizeof(Vector{UnionFieldInlineStruct}(undef, 2)) == sizeof(UnionFieldInlineStruct) * 2 +@test sizeof(Vector{UnionFieldInlineStruct}(undef, 2)) >= sizeof(UnionFieldInlineStruct) * 2 let x = UnionFieldInlineStruct(1, 3.14) AInlineUnion = [x for i = 1:10] - @test sizeof(AInlineUnion) == sizeof(UnionFieldInlineStruct) * 10 + @test sizeof(AInlineUnion) >= sizeof(UnionFieldInlineStruct) * 10 BInlineUnion = Vector{UnionFieldInlineStruct}(undef, 10) copyto!(BInlineUnion, AInlineUnion) @test AInlineUnion == BInlineUnion @test BInlineUnion[end] == x CInlineUnion = vcat(AInlineUnion, BInlineUnion) - @test sizeof(CInlineUnion) == sizeof(UnionFieldInlineStruct) * 20 + @test sizeof(CInlineUnion) >= sizeof(UnionFieldInlineStruct) * 20 @test CInlineUnion[end] == x end