Skip to content

Commit

Permalink
fix another intermittent segfault
Browse files Browse the repository at this point in the history
before I failed to fully fix the deserialization bug where constructing
an Array needs to look at the element type, but the element type might
not be fully initialized yet.
  • Loading branch information
JeffBezanson committed Aug 16, 2013
1 parent e2df92c commit a48eeef
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
29 changes: 18 additions & 11 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ typedef uint64_t wideint_t;

#define MAXINTVAL (((size_t)-1)>>1)

static jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *dims)
static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
int isunboxed, int elsz)
{
size_t i, tot, nel=1;
wideint_t prod;
int isunboxed=0, elsz;
void *data;
jl_array_t *a;

Expand All @@ -46,11 +46,8 @@ static jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *dims)
jl_error("invalid Array dimensions");
nel = prod;
}
jl_value_t *el_type = jl_tparam0(atype);

isunboxed = store_unboxed(el_type);
if (isunboxed) {
elsz = jl_datatype_size(el_type);
prod = (wideint_t)elsz * (wideint_t)nel;
if (prod > (wideint_t) MAXINTVAL)
jl_error("invalid Array size");
Expand All @@ -61,7 +58,6 @@ static jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *dims)
}
}
else {
elsz = sizeof(void*);
prod = (wideint_t)sizeof(void*) * (wideint_t)nel;
if (prod > (wideint_t) MAXINTVAL)
jl_error("invalid Array size");
Expand Down Expand Up @@ -124,6 +120,22 @@ static jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *dims)
return a;
}

static inline jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *dims)
{
int isunboxed=0, elsz=sizeof(void*);
jl_value_t *el_type = jl_tparam0(atype);
isunboxed = store_unboxed(el_type);
if (isunboxed)
elsz = jl_datatype_size(el_type);
return _new_array_(atype, ndims, dims, isunboxed, elsz);
}

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

jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data, jl_tuple_t *dims)
{
size_t i;
Expand Down Expand Up @@ -277,11 +289,6 @@ jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data, jl_tuple_t *dims,
return a;
}

jl_array_t *jl_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims)
{
return _new_array(atype, ndims, dims);
}

jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims)
{
size_t ndims = jl_tuple_len(dims);
Expand Down
28 changes: 20 additions & 8 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,16 @@ static void jl_serialize_value_(ios_t *s, jl_value_t *v)
}
else if (jl_is_array(v)) {
jl_array_t *ar = (jl_array_t*)v;
if (ar->ndims == 1)
if (ar->ndims == 1 && ar->elsize < 128) {
writetag(s, (jl_value_t*)Array1d_tag);
else
write_uint8(s, (ar->ptrarray<<7) | (ar->elsize & 0x7f));
}
else {
writetag(s, (jl_value_t*)jl_array_type);
jl_serialize_value(s, jl_typeof(ar));
if (ar->ndims != 1)
write_uint16(s, ar->ndims);
write_uint16(s, (ar->ptrarray<<15) | (ar->elsize & 0x7fff));
}
jl_serialize_value(s, jl_typeof(ar));
for (i=0; i < ar->ndims; i++)
jl_serialize_value(s, jl_box_long(jl_array_dim(ar,i)));
if (!ar->ptrarray) {
Expand Down Expand Up @@ -536,16 +539,25 @@ static jl_value_t *jl_deserialize_value(ios_t *s)
}
else if (vtag == (jl_value_t*)jl_array_type ||
vtag == (jl_value_t*)Array1d_tag) {
jl_value_t *aty = jl_deserialize_value(s);
int16_t ndims;
if (vtag == (jl_value_t*)Array1d_tag)
int isunboxed, elsize;
if (vtag == (jl_value_t*)Array1d_tag) {
ndims = 1;
else
elsize = read_uint8(s);
isunboxed = !(elsize>>7);
elsize = elsize&0x7f;
}
else {
ndims = read_uint16(s);
elsize = read_uint16(s);
isunboxed = !(elsize>>15);
elsize = elsize&0x7fff;
}
jl_value_t *aty = jl_deserialize_value(s);
size_t *dims = alloca(ndims*sizeof(size_t));
for(i=0; i < ndims; i++)
dims[i] = jl_unbox_long(jl_deserialize_value(s));
jl_array_t *a = jl_new_array_((jl_value_t*)aty, ndims, dims);
jl_array_t *a = jl_new_array_for_deserialization((jl_value_t*)aty, ndims, dims, isunboxed, elsize);
if (usetable)
ptrhash_put(&backref_table, (void*)(ptrint_t)pos, (jl_value_t*)a);
if (!a->ptrarray) {
Expand Down
3 changes: 2 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,8 @@ int jl_field_isdefined(jl_value_t *v, jl_sym_t *fld, int err);
// arrays
DLLEXPORT jl_array_t *jl_new_array(jl_value_t *atype, jl_tuple_t *dims);
DLLEXPORT jl_array_t *jl_new_arrayv(jl_value_t *atype, ...);
jl_array_t *jl_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims);
jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims, size_t *dims,
int isunboxed, int elsz);
DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data,
jl_tuple_t *dims);
DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data,
Expand Down

0 comments on commit a48eeef

Please sign in to comment.