Skip to content

Commit

Permalink
fix JuliaLang#38224, set and use DataType.zeroinit in arrays (JuliaLa…
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Nov 21, 2020
1 parent 8de4268 commit aa18d37
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 15 deletions.
24 changes: 11 additions & 13 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ size_t jl_arr_xtralloc_limit = 0;
#define MAXINTVAL (((size_t)-1)>>1)

static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
int isunboxed, int hasptr, int isunion, int elsz)
int8_t isunboxed, int8_t hasptr, int8_t isunion, int8_t zeroinit, int elsz)
{
jl_ptls_t ptls = jl_get_ptls_states();
size_t i, tot, nel=1;
Expand Down Expand Up @@ -123,8 +123,6 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
// No allocation or safepoint allowed after this
a->flags.how = 0;
data = (char*)a + doffs;
if (tot > 0 && (!isunboxed || hasptr || isunion)) // TODO: check for zeroinit
memset(data, 0, tot);
}
else {
tsz = JL_ARRAY_ALIGN(tsz, JL_CACHE_BYTE_ALIGNMENT); // align whole object
Expand All @@ -135,12 +133,11 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
// No allocation or safepoint allowed after this
a->flags.how = 2;
jl_gc_track_malloced_array(ptls, a);
if (tot > 0 && (!isunboxed || hasptr || isunion)) // TODO: check for zeroinit
// need to zero out isbits union array selector bytes to ensure a valid type index
memset(data, 0, tot);
}
a->flags.pooled = tsz <= GC_MAX_SZCLASS;

if (zeroinit)
memset(data, 0, tot);
a->data = data;
if (JL_ARRAY_IMPL_NUL && elsz == 1)
((char*)data)[tot - 1] = '\0';
Expand Down Expand Up @@ -186,14 +183,15 @@ static inline jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *
else {
elsz = LLT_ALIGN(elsz, al);
}
int zi = !isunboxed || hasptr || isunion || (jl_is_datatype(eltype) && ((jl_datatype_t*)eltype)->zeroinit);

return _new_array_(atype, ndims, dims, isunboxed, hasptr, isunion, elsz);
return _new_array_(atype, ndims, dims, isunboxed, hasptr, isunion, zi, elsz);
}

jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims, size_t *dims,
int isunboxed, int hasptr, int isunion, int elsz)
{
return _new_array_(atype, ndims, dims, isunboxed, hasptr, isunion, elsz);
return _new_array_(atype, ndims, dims, isunboxed, hasptr, isunion, 0, elsz);
}

#ifndef JL_NDEBUG
Expand Down Expand Up @@ -784,7 +782,7 @@ STATIC_INLINE void jl_array_grow_at_beg(jl_array_t *a, size_t idx, size_t inc,
char *data = (char*)a->data;
char *newdata;
char *typetagdata;
char *newtypetagdata;
char *newtypetagdata = NULL;
int isbitsunion = jl_array_isbitsunion(a);
if (isbitsunion) typetagdata = jl_array_typetagdata(a);
if (a->offset >= inc) {
Expand Down Expand Up @@ -864,10 +862,10 @@ STATIC_INLINE void jl_array_grow_at_beg(jl_array_t *a, size_t idx, size_t inc,
#endif
a->nrows = newnrows;
a->data = newdata;
if (a->flags.ptrarray || a->flags.hasptr) { // TODO: check for zeroinit
if (jl_is_array_zeroinit(a)) {
memset(newdata + idx * elsz, 0, nbinc);
}
else if (isbitsunion) {
if (newtypetagdata) {
memset(newtypetagdata + idx, 0, inc);
}
}
Expand Down Expand Up @@ -945,7 +943,7 @@ STATIC_INLINE void jl_array_grow_at_end(jl_array_t *a, size_t idx,
a->length = newnrows;
#endif
a->nrows = newnrows;
if (a->flags.ptrarray || a->flags.hasptr) { // TODO: check for zeroinit
if (jl_is_array_zeroinit(a)) {
memset(data + idx * elsz, 0, inc * elsz);
}
}
Expand Down Expand Up @@ -1201,7 +1199,7 @@ JL_DLLEXPORT jl_array_t *jl_array_copy(jl_array_t *ary)
int isunion = jl_is_uniontype(jl_tparam0(jl_typeof(ary)));
jl_array_t *new_ary = _new_array_(jl_typeof(ary), jl_array_ndims(ary),
&ary->nrows, !ary->flags.ptrarray,
ary->flags.hasptr, isunion, elsz);
ary->flags.hasptr, isunion, 0, elsz);
memcpy(new_ary->data, ary->data, len * elsz);
// ensure isbits union arrays copy their selector bytes correctly
if (jl_array_isbitsunion(ary))
Expand Down
1 change: 1 addition & 0 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
if (npointers)
free(pointers);
}
st->zeroinit = zeroinit;
}
// now finish deciding if this instantiation qualifies for special properties
assert(!isbitstype || st->layout->npointers == 0); // the definition of isbits
Expand Down
2 changes: 1 addition & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ static jl_value_t *jl_deserialize_value_array(jl_serializer_state *s, uint8_t ta
isptr = (elsize >> 15) & 1;
hasptr = (elsize >> 14) & 1;
isunion = (elsize >> 13) & 1;
elsize = elsize & 0x3fff;
elsize = elsize & 0x1fff;
}
uintptr_t pos = backref_list.len;
arraylist_push(&backref_list, NULL);
Expand Down
2 changes: 1 addition & 1 deletion src/ircode.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ static jl_value_t *jl_decode_value_array(jl_ircode_state *s, uint8_t tag) JL_GC_
isptr = (elsize >> 15) & 1;
hasptr = (elsize >> 14) & 1;
isunion = (elsize >> 13) & 1;
elsize = elsize & 0x3fff;
elsize = elsize & 0x1fff;
}
size_t *dims = (size_t*)alloca(ndims * sizeof(size_t));
for (i = 0; i < ndims; i++) {
Expand Down
8 changes: 8 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,14 @@ STATIC_INLINE int jl_is_type_type(jl_value_t *v) JL_NOTSAFEPOINT
((jl_datatype_t*)(v))->name == ((jl_datatype_t*)jl_type_type->body)->name);
}

STATIC_INLINE int jl_is_array_zeroinit(jl_array_t *a) JL_NOTSAFEPOINT
{
if (a->flags.ptrarray || a->flags.hasptr)
return 1;
jl_value_t *elty = jl_tparam0(jl_typeof(a));
return jl_is_datatype(elty) && ((jl_datatype_t*)elty)->zeroinit;
}

// object identity
JL_DLLEXPORT int jl_egal(jl_value_t *a JL_MAYBE_UNROOTED, jl_value_t *b JL_MAYBE_UNROOTED) JL_NOTSAFEPOINT;
JL_DLLEXPORT uintptr_t jl_object_id(jl_value_t *v) JL_NOTSAFEPOINT;
Expand Down
11 changes: 11 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7508,3 +7508,14 @@ let array = Int[]
end
@test compare_union37557(Ref{Union{Int,Vector{Int}}}(1),
Ref{Union{Int,Vector{Int}}}(1))

# issue #38224
struct S38224
i::Union{Int,Missing}
end
@test S38224.zeroinit
for _ in 1:5
let a = Vector{S38224}(undef, 1000000)
@test all(x->ismissing(x.i), a)
end
end

0 comments on commit aa18d37

Please sign in to comment.