Skip to content

Commit

Permalink
Array fixes for non-power-of-2 sized elements, fixes #26026
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Sep 17, 2019
1 parent ad475e3 commit 2b6ddaf
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
7 changes: 5 additions & 2 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,10 @@ segfault your program, in the same manner as C.
function unsafe_copyto!(dest::Ptr{T}, src::Ptr{T}, n) where T
# Do not use this to copy data between pointer arrays.
# It can't be made safe no matter how carefully you checked.
al = datatype_alignment(T)
sz = (sizeof(T) + al - 1) & -al
ccall(:memmove, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt),
dest, src, n*sizeof(T))
dest, src, n*sz)
return dest
end

Expand Down Expand Up @@ -1568,7 +1570,8 @@ function vcat(arrays::Vector{T}...) where T
elsz = bitsunionsize(T)
selptr = ccall(:jl_array_typetagdata, Ptr{UInt8}, (Any,), arr)
elseif allocatedinline(T)
elsz = Core.sizeof(T)
al = datatype_alignment(T)
elsz = (Core.sizeof(T) + al - 1) & -al
else
elsz = Core.sizeof(Ptr{Cvoid})
end
Expand Down
9 changes: 6 additions & 3 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ static inline jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *
elsz = sizeof(void*);
al = elsz;
}
else {
elsz = LLT_ALIGN(elsz, al);
}

return _new_array_(atype, ndims, dims, isunboxed, isunion, elsz);
}
Expand Down Expand Up @@ -207,7 +210,7 @@ JL_DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data,
int isboxed = !jl_islayout_inline(eltype, &elsz, &align);
assert(isboxed == data->flags.ptrarray);
if (!isboxed) {
a->elsize = elsz;
a->elsize = LLT_ALIGN(elsz, align);
jl_value_t *ownerty = jl_typeof(owner);
size_t oldelsz = 0, oldalign = 0;
if (ownerty == (jl_value_t*)jl_string_type) {
Expand Down Expand Up @@ -323,7 +326,7 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data,
#ifdef STORE_ARRAY_LEN
a->length = nel;
#endif
a->elsize = elsz;
a->elsize = LLT_ALIGN(elsz, align);
a->flags.ptrarray = !isunboxed;
a->flags.ndims = 1;
a->flags.isshared = 1;
Expand Down Expand Up @@ -389,7 +392,7 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data,
#ifdef STORE_ARRAY_LEN
a->length = nel;
#endif
a->elsize = elsz;
a->elsize = LLT_ALIGN(elsz, align);
a->flags.ptrarray = !isunboxed;
a->flags.ndims = ndims;
a->offset = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ JL_EXTENSION typedef struct {
size_t length;
#endif
jl_array_flags_t flags;
uint16_t elsize;
uint16_t elsize; // element size including alignment (dim 1 memory stride)
uint32_t offset; // for 1-d only. does not need to get big.
size_t nrows;
union {
Expand Down
24 changes: 24 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6461,6 +6461,30 @@ let A=[0, missing], B=[missing, 0], C=Vector{Union{Int, Missing}}(undef, 6)
@test isequal(C, [0, missing, missing, missing, 0, missing])
end

# non-power-of-2 element sizes, issue #26026
primitive type TypeWith24Bits 24 end
TypeWith24Bits(x::UInt32) = Core.Intrinsics.trunc_int(TypeWith24Bits, x)
let x = TypeWith24Bits(0x112233), y = TypeWith24Bits(0x445566), z = TypeWith24Bits(0x778899)
a = [x, x]
Core.arrayset(true, a, y, 2)
@test a == [x, y]
a[2] = z
@test a == [x, z]

b = [(x, x), (x, x)]
Core.arrayset(true, b, (x, y), 2)
@test b == [(x, x), (x, y)]
b[2] = (y, z)
@test b == [(x, x), (y, z)]

V = Vector{TypeWith24Bits}(undef, 1000)
p = Ptr{UInt8}(pointer(V))
for i = 1:sizeof(V)
unsafe_store!(p, i % UInt8, i)
end
@test V[1:4] == [TypeWith24Bits(0x030201), TypeWith24Bits(0x070605), TypeWith24Bits(0x0b0a09), TypeWith24Bits(0x0f0e0d)]
end

# issue #29718
function f29718()
nt = NamedTuple{(:a, :b, :c, :d, :e, :f,),
Expand Down

0 comments on commit 2b6ddaf

Please sign in to comment.