Skip to content

Commit

Permalink
Merge branch 'master' of github.com:JuliaLang/julia
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Sep 16, 2015
2 parents af98334 + 0e5784b commit 37b4735
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 53 deletions.
3 changes: 2 additions & 1 deletion src/abi_x86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ void classifyType(Classification& accum, jl_value_t* ty, uint64_t offset) {
else if (jl_datatype_size(ty) <= 16) {
size_t i;
for (i = 0; i < jl_datatype_nfields(ty); ++i) {
classifyType(accum, jl_field_type(ty,i), offset + jl_field_offset(ty,i));
classifyType(accum, jl_field_type((jl_datatype_t*)ty,i),
offset + jl_field_offset((jl_datatype_t*)ty,i));
}
}
else {
Expand Down
35 changes: 25 additions & 10 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,9 @@ DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uin
jl_set_nth_field(jv, i, args[i]);
}
for(size_t i=na; i < nf; i++) {
if (type->fields[i].isptr)
if (jl_field_isptr(type, i)) {
*(jl_value_t**)((char*)jl_data_ptr(jv)+jl_field_offset(type,i)) = NULL;
}
}
return jv;
}
Expand Down Expand Up @@ -535,11 +536,18 @@ jl_datatype_t *jl_new_abstracttype(jl_value_t *name, jl_datatype_t *super,
return dt;
}

jl_datatype_t *jl_new_uninitialized_datatype(size_t nfields)
jl_datatype_t *jl_new_uninitialized_datatype(size_t nfields,
int8_t fielddesc_type)
{
// fielddesc_type is specified manually for builtin types
// and is (will be) calculated automatically for user defined types.
uint32_t fielddesc_size = jl_fielddesc_size(fielddesc_type);
jl_datatype_t *t = (jl_datatype_t*)
newobj((jl_value_t*)jl_datatype_type,
NWORDS(sizeof(jl_datatype_t) + nfields*sizeof(jl_fielddesc_t)));
NWORDS(sizeof(jl_datatype_t) + nfields * fielddesc_size));
// fielddesc_type should only be assigned here. It can cause data
// corruption otherwise.
t->fielddesc_type = fielddesc_type;
t->nfields = nfields;
return t;
}
Expand All @@ -549,15 +557,22 @@ void jl_compute_field_offsets(jl_datatype_t *st)
size_t sz = 0, alignm = 1;
int ptrfree = 1;

assert(0 <= st->fielddesc_type && st->fielddesc_type <= 2);

uint64_t max_offset = (((uint64_t)1) <<
(1 << (3 + st->fielddesc_type))) - 1;
uint64_t max_size = max_offset >> 1;

for(size_t i=0; i < jl_datatype_nfields(st); i++) {
jl_value_t *ty = jl_field_type(st, i);
size_t fsz, al;
if (jl_isbits(ty) && jl_is_leaf_type(ty)) {
fsz = jl_datatype_size(ty);
if (__unlikely(fsz > JL_FIELD_MAX_SIZE))
// Should never happen
if (__unlikely(fsz > max_size))
jl_throw(jl_overflow_exception);
al = ((jl_datatype_t*)ty)->alignment;
st->fields[i].isptr = 0;
jl_field_setisptr(st, i, 0);
if (((jl_datatype_t*)ty)->haspadding)
st->haspadding = 1;
}
Expand All @@ -566,7 +581,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
if (fsz > MAX_ALIGN)
fsz = MAX_ALIGN;
al = fsz;
st->fields[i].isptr = 1;
jl_field_setisptr(st, i, 1);
ptrfree = 0;
}
if (al != 0) {
Expand All @@ -577,10 +592,10 @@ void jl_compute_field_offsets(jl_datatype_t *st)
if (al > alignm)
alignm = al;
}
if (__unlikely(sz > JL_FIELD_MAX_OFFSET))
jl_field_setoffset(st, i, sz);
jl_field_setsize(st, i, fsz);
if (__unlikely(max_offset - sz < fsz))
jl_throw(jl_overflow_exception);
st->fields[i].offset = sz;
st->fields[i].size = fsz;
sz += fsz;
}
st->alignment = alignm;
Expand Down Expand Up @@ -612,7 +627,7 @@ jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super,
t = jl_bool_type;
}
if (t == NULL)
t = jl_new_uninitialized_datatype(jl_svec_len(fnames));
t = jl_new_uninitialized_datatype(jl_svec_len(fnames), 2); // TODO
else
tn = t->name;
// init before possibly calling jl_new_typename
Expand Down
14 changes: 7 additions & 7 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,11 @@ static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *
{
size_t nf = jl_datatype_nfields(dt);
for (size_t f=0; f < nf; f++) {
size_t offs = dt->fields[f].offset;
size_t offs = jl_field_offset(dt, f);
char *ao = (char*)jl_data_ptr(a) + offs;
char *bo = (char*)jl_data_ptr(b) + offs;
int eq;
if (dt->fields[f].isptr) {
if (jl_field_isptr(dt, f)) {
jl_value_t *af = *(jl_value_t**)ao;
jl_value_t *bf = *(jl_value_t**)bo;
if (af == bf) eq = 1;
Expand All @@ -268,7 +268,7 @@ static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *
else {
jl_datatype_t *ft = (jl_datatype_t*)jl_field_type(dt, f);
if (!ft->haspadding) {
eq = bits_equal(ao, bo, dt->fields[f].size);
eq = bits_equal(ao, bo, jl_field_size(dt, f));
}
else {
assert(jl_datatype_nfields(ft) > 0);
Expand Down Expand Up @@ -1178,20 +1178,20 @@ static uptrint_t jl_object_id_(jl_value_t *tv, jl_value_t *v)
return bits_hash(jl_data_ptr(v), sz) ^ h;
}
for (size_t f=0; f < nf; f++) {
size_t offs = dt->fields[f].offset;
size_t offs = jl_field_offset(dt, f);
char *vo = (char*)jl_data_ptr(v) + offs;
uptrint_t u;
if (dt->fields[f].isptr) {
if (jl_field_isptr(dt, f)) {
jl_value_t *f = *(jl_value_t**)vo;
u = f==NULL ? 0 : jl_object_id(f);
}
else {
jl_datatype_t *fieldtype = (jl_datatype_t*)jl_svecref(dt->types, f);
jl_datatype_t *fieldtype = (jl_datatype_t*)jl_field_type(dt, f);
assert(jl_is_datatype(fieldtype) && !fieldtype->abstract && !fieldtype->mutabl);
if (fieldtype->haspadding)
u = jl_object_id_((jl_value_t*)fieldtype, (jl_value_t*)vo);
else
u = bits_hash(vo, dt->fields[f].size);
u = bits_hash(vo, jl_field_size(dt, f));
}
h = bitmix(h, u);
}
Expand Down
13 changes: 7 additions & 6 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ static Type *julia_struct_to_llvm(jl_value_t *jt)
for(i = 0; i < ntypes; i++) {
jl_value_t *ty = jl_svecref(jst->types, i);
Type *lty;
if (jst->fields[i].isptr)
if (jl_field_isptr(jst, i))
lty = jl_pvalue_llvmt;
else
lty = ty==(jl_value_t*)jl_bool_type ? T_int8 : julia_type_to_llvm(ty);
Expand Down Expand Up @@ -764,8 +764,9 @@ static bool is_datatype_all_pointers(jl_datatype_t *dt)
{
size_t i, l = jl_datatype_nfields(dt);
for(i=0; i < l; i++) {
if (!dt->fields[i].isptr)
if (!jl_field_isptr(dt, i)) {
return false;
}
}
return true;
}
Expand Down Expand Up @@ -1848,7 +1849,7 @@ static void emit_setfield(jl_datatype_t *sty, const jl_cgval_t &strct, size_t id
builder.CreateGEP(builder.CreateBitCast(strct.V, T_pint8),
ConstantInt::get(T_size, jl_field_offset(sty,idx0)));
jl_value_t *jfty = jl_svecref(sty->types, idx0);
if (sty->fields[idx0].isptr) {
if (jl_field_isptr(sty, idx0)) {
Value *r = boxed(rhs, ctx);
builder.CreateStore(r,
builder.CreateBitCast(addr, jl_ppvalue_llvmt));
Expand Down Expand Up @@ -1912,7 +1913,7 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
}
}
size_t j = 0;
if (nf > 0 && sty->fields[0].isptr && nargs>1) {
if (nf > 0 && jl_field_isptr(sty, 0) && nargs>1) {
// emit first field before allocating struct to save
// a couple store instructions. avoids initializing
// the first field to NULL, and sometimes the GC root
Expand Down Expand Up @@ -1940,7 +1941,7 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
make_gcroot(strct, ctx);
}
for(size_t i=j; i < nf; i++) {
if (sty->fields[i].isptr) {
if (jl_field_isptr(sty, i)) {
builder.CreateStore(
V_null,
builder.CreatePointerCast(
Expand All @@ -1952,7 +1953,7 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
bool need_wb = false;
for(size_t i=j+1; i < nargs; i++) {
jl_cgval_t rhs = emit_expr(args[i],ctx);
if (sty->fields[i-1].isptr && !rhs.isboxed) {
if (jl_field_isptr(sty, i - 1) && !rhs.isboxed) {
if (!needroots) {
// if this struct element needs boxing and we haven't rooted
// the struct, root it now.
Expand Down
4 changes: 2 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,7 @@ static bool is_getfield_nonallocating(jl_datatype_t *ty, jl_value_t *fld)
else if (jl_is_quotenode(fld) && jl_is_long(jl_fieldref(fld,0)))
idx = jl_unbox_long(jl_fieldref(fld,0))-1;
for(size_t i=0; i < jl_svec_len(ty->types); i++) {
if (!(ty->fields[i].isptr || (idx >= 0 && (size_t)idx != i)))
if (!(jl_field_isptr(ty,i) || (idx >= 0 && (size_t)idx != i)))
return false;
}
return true;
Expand Down Expand Up @@ -2570,7 +2570,7 @@ static bool emit_known_call(jl_cgval_t *ret, jl_value_t *ff,
if (jl_is_leaf_type((jl_value_t*)sty) && jl_subtype(rhst, ft, 0)) {
// TODO: attempt better codegen for approximate types
jl_cgval_t strct = emit_expr(args[1], ctx); // emit lhs
if (sty->fields[idx].isptr) // emit rhs
if (jl_field_isptr(sty, idx)) // emit rhs
*ret = emit_expr(args[3], ctx);
else
*ret = emit_unboxed(args[3], ctx);
Expand Down
16 changes: 10 additions & 6 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ static void jl_serialize_datatype(ios_t *s, jl_datatype_t *dt)
write_int32(s, dt->size);
int has_instance = !!(dt->instance != NULL);
write_uint8(s, dt->abstract | (dt->mutabl<<1) | (dt->pointerfree<<2) | (has_instance<<3));
write_int8(s, dt->fielddesc_type);
if (!dt->abstract) {
write_uint16(s, dt->ninitialized);
if (mode != MODE_MODULE && mode != MODE_MODULE_POSTWORK) {
Expand All @@ -525,7 +526,8 @@ static void jl_serialize_datatype(ios_t *s, jl_datatype_t *dt)
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));
size_t fieldsize = jl_fielddesc_size(dt->fielddesc_type);
ios_write(s, (char*)&dt->fields32[0], nf * fieldsize);
jl_serialize_value(s, dt->types);
}

Expand Down Expand Up @@ -896,7 +898,7 @@ static void jl_serialize_value_(ios_t *s, jl_value_t *v)
}
else {
for(size_t i=0; i < nf; i++) {
if (t->fields[i].size > 0) {
if (jl_field_size(t, i) > 0) {
jl_serialize_value(s, jl_get_nth_field(v, i));
}
}
Expand Down Expand Up @@ -1082,6 +1084,7 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos, jl_value_t **loc)
uint16_t nf = read_uint16(s);
size_t size = read_int32(s);
uint8_t flags = read_uint8(s);
uint8_t fielddesc_type = read_int8(s);
jl_datatype_t *dt;
if (tag == 2)
dt = jl_int32_type;
Expand All @@ -1090,7 +1093,7 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos, jl_value_t **loc)
else if (tag == 4)
dt = jl_int64_type;
else
dt = jl_new_uninitialized_datatype(nf);
dt = jl_new_uninitialized_datatype(nf, fielddesc_type);
assert(tree_literal_values==NULL && mode != MODE_AST);
backref_list.items[pos] = dt;
dt->size = size;
Expand Down Expand Up @@ -1125,7 +1128,8 @@ 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));
size_t fieldsize = jl_fielddesc_size(fielddesc_type);
ios_read(s, (char*)&dt->fields32[0], nf * fieldsize);
dt->types = (jl_svec_t*)jl_deserialize_value(s, (jl_value_t**)&dt->types);
jl_gc_wb(dt, dt->types);
}
Expand Down Expand Up @@ -1511,8 +1515,8 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t
else {
char *data = (char*)jl_data_ptr(v);
for(i=0; i < nf; i++) {
if (dt->fields[i].size > 0) {
if (dt->fields[i].isptr) {
if (jl_field_size(dt,i) > 0) {
if (jl_field_isptr(dt,i)) {
jl_value_t **fld = (jl_value_t**)(data+jl_field_offset(dt, i));
*fld = jl_deserialize_value(s, fld);
}
Expand Down
16 changes: 10 additions & 6 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1734,21 +1734,25 @@ static int push_root(jl_value_t *v, int d, int bits)
else if (gc_typeof(vt) == (jl_value_t*)jl_datatype_type) {
jl_datatype_t *dt = (jl_datatype_t*)vt;
size_t dtsz;
if (dt == jl_datatype_type)
dtsz = NWORDS(sizeof(jl_datatype_t) + jl_datatype_nfields(v)*sizeof(jl_fielddesc_t))*sizeof(void*);
else
if (dt == jl_datatype_type) {
size_t fieldsize =
jl_fielddesc_size(((jl_datatype_t*)v)->fielddesc_type);
dtsz = NWORDS(sizeof(jl_datatype_t) +
jl_datatype_nfields(v) * fieldsize) * sizeof(void*);
} else {
dtsz = jl_datatype_size(dt);
}
MARK(v, bits = gc_setmark(v, dtsz, GC_MARKED_NOESC));
int nf = (int)jl_datatype_nfields(dt);
// TODO check if there is a perf improvement for objects with a lot of fields
// int fdsz = sizeof(void*)*nf;
// void** children = alloca(fdsz);
// int ci = 0;
jl_fielddesc_t* fields = dt->fields;
for(int i=0; i < nf; i++) {
if (fields[i].isptr) {
if (jl_field_isptr(dt, i)) {
nptr++;
jl_value_t **slot = (jl_value_t**)((char*)v + fields[i].offset);
jl_value_t **slot = (jl_value_t**)((char*)v +
jl_field_offset(dt, i));
jl_value_t *fld = *slot;
if (fld) {
verify_parent2("object", v, slot, "field(%d)", i);
Expand Down
10 changes: 5 additions & 5 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2059,7 +2059,7 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
}

// create and initialize new type
ndt = jl_new_uninitialized_datatype(istuple ? ntp : dt->nfields);
ndt = jl_new_uninitialized_datatype(istuple ? ntp : dt->nfields, 2); // TODO
// associate these parameters with the new type on
// the stack, in case one of its field types references it.
top.tt = (jl_datatype_t*)ndt;
Expand Down Expand Up @@ -3148,12 +3148,12 @@ extern void jl_init_int32_int64_cache(void);
void jl_init_types(void)
{
// create base objects
jl_datatype_type = jl_new_uninitialized_datatype(10);
jl_datatype_type = jl_new_uninitialized_datatype(10, 1);
jl_set_typeof(jl_datatype_type, jl_datatype_type);
jl_typename_type = jl_new_uninitialized_datatype(7);
jl_sym_type = jl_new_uninitialized_datatype(0);
jl_typename_type = jl_new_uninitialized_datatype(7, 1);
jl_sym_type = jl_new_uninitialized_datatype(0, 1);
jl_symbol_type = jl_sym_type;
jl_simplevector_type = jl_new_uninitialized_datatype(1);
jl_simplevector_type = jl_new_uninitialized_datatype(1, 1);

jl_emptysvec = (jl_svec_t*)newobj((jl_value_t*)jl_simplevector_type, 1);
jl_svec_set_len_unsafe(jl_emptysvec, 0);
Expand Down
Loading

0 comments on commit 37b4735

Please sign in to comment.