Skip to content

Commit

Permalink
keep track of whether a bits type contains padding
Browse files Browse the repository at this point in the history
this is the run time system side of JuliaLang#11813
  • Loading branch information
JeffBezanson committed Jun 23, 2015
1 parent fc604d1 commit 6ec7c21
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 8 deletions.
8 changes: 7 additions & 1 deletion src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@ void jl_compute_field_offsets(jl_datatype_t *st)
jl_throw(jl_overflow_exception);
al = ((jl_datatype_t*)ty)->alignment;
st->fields[i].isptr = 0;
if (((jl_datatype_t*)ty)->haspadding)
st->haspadding = 1;
}
else {
fsz = sizeof(void*);
Expand All @@ -552,7 +554,10 @@ void jl_compute_field_offsets(jl_datatype_t *st)
ptrfree = 0;
}
if (al != 0) {
sz = LLT_ALIGN(sz, al);
size_t alsz = LLT_ALIGN(sz, al);
if (alsz > sz)
st->haspadding = 1;
sz = alsz;
if (al > alignm)
alignm = al;
}
Expand Down Expand Up @@ -608,6 +613,7 @@ jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super,
t->ditype = NULL;
t->size = 0;
t->alignment = 1;
t->haspadding = 0;

if (tn == NULL) {
t->name = NULL;
Expand Down
15 changes: 9 additions & 6 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ static int NOINLINE compare_svec(jl_value_t *a, jl_value_t *b)
}

// See comment above for an explanation of NOINLINE.
static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b,
jl_datatype_t *dt, size_t nf)
static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *dt)
{
size_t nf = jl_datatype_nfields(dt);
for (size_t f=0; f < nf; f++) {
size_t offs = dt->fields[f].offset;
char *ao = (char*)jl_data_ptr(a) + offs;
Expand All @@ -267,7 +267,11 @@ static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b,
else eq = jl_egal(af, bf);
}
else {
eq = bits_equal(ao, bo, dt->fields[f].size);
jl_datatype_t *ft = (jl_datatype_t*)jl_field_type(dt, f);
if (!ft->haspadding)
eq = bits_equal(ao, bo, dt->fields[f].size);
else
eq = compare_fields((jl_value_t*)ao, (jl_value_t*)bo, ft);
}
if (!eq) return 0;
}
Expand All @@ -294,10 +298,9 @@ int jl_egal(jl_value_t *a, jl_value_t *b) // warning: a,b may NOT have been gc-r
size_t sz = dt->size;
if (sz == 0) return 1;
size_t nf = jl_datatype_nfields(dt);
if (nf == 0) {
if (nf == 0)
return bits_equal(jl_data_ptr(a), jl_data_ptr(b), sz);
}
return compare_fields(a, b, dt, nf);
return compare_fields(a, b, dt);
}

JL_CALLABLE(jl_f_is)
Expand Down
2 changes: 2 additions & 0 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ static void jl_serialize_datatype(ios_t *s, jl_datatype_t *dt)
jl_serialize_value(s, dt->instance);
if (nf > 0) {
write_int32(s, dt->alignment);
write_int8(s, dt->haspadding);
ios_write(s, (char*)&dt->fields[0], nf*sizeof(jl_fielddesc_t));
jl_serialize_value(s, dt->types);
}
Expand Down Expand Up @@ -956,6 +957,7 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos, jl_value_t **loc)

if (nf > 0) {
dt->alignment = read_int32(s);
dt->haspadding = read_int8(s);
ios_read(s, (char*)&dt->fields[0], nf*sizeof(jl_fielddesc_t));
dt->types = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&dt->types);
jl_gc_wb(dt, dt->types);
Expand Down
3 changes: 2 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ typedef struct _jl_datatype_t {
// hidden fields:
uint32_t nfields;
int32_t ninitialized;
uint32_t alignment; // strictest alignment over all fields
uint32_t alignment : 31; // strictest alignment over all fields
uint32_t haspadding : 1; // has internal undefined bytes
uint32_t uid;
void *struct_decl; //llvm::Value*
void *ditype; // llvm::MDNode* to be used as llvm::DIType(ditype)
Expand Down
8 changes: 8 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2997,3 +2997,11 @@ type D11597{T} <: C11597{T} d::T end

# issue #11772
@test_throws UndefRefError (cell(5)...)

# issue #11813
let a = UInt8[1, 107, 66, 88, 2, 99, 254, 13, 0, 0, 0, 0]
u32 = UInt32[0x3]
a[9:end] = reinterpret(UInt8, u32)
p = pointer(a)
@test (Int8(1),(Int8(2),Int32(3))) === unsafe_load(convert(Ptr{Tuple{Int8,Tuple{Int8,Int32}}},p))
end

0 comments on commit 6ec7c21

Please sign in to comment.