Skip to content

Commit

Permalink
Keep track of number of initialized fields and avoid undefined checks
Browse files Browse the repository at this point in the history
  • Loading branch information
simonster committed Oct 30, 2014
1 parent cc42812 commit 46ec202
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 43 deletions.
9 changes: 3 additions & 6 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,6 @@ jl_datatype_t *jl_new_abstracttype(jl_value_t *name, jl_datatype_t *super,
{
jl_datatype_t *dt = jl_new_datatype((jl_sym_t*)name, super, parameters, jl_null, jl_null, 1, 0, 0);
dt->pointerfree = 0;
dt->undeffree = 0;
return dt;
}

Expand Down Expand Up @@ -632,15 +631,14 @@ void jl_compute_field_offsets(jl_datatype_t *st)
st->alignment = alignm;
st->size = LLT_ALIGN(sz, alignm);
st->pointerfree = ptrfree && !st->abstract;
st->undeffree |= st->pointerfree;
}

extern int jl_boot_file_loaded;

jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super,
jl_tuple_t *parameters,
jl_tuple_t *fnames, jl_tuple_t *ftypes,
int abstract, int mutabl, int undeffree)
int abstract, int mutabl, int ninitialized)
{
jl_datatype_t *t=NULL;
jl_typename_t *tn=NULL;
Expand Down Expand Up @@ -669,7 +667,7 @@ jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super,
t->abstract = abstract;
t->mutabl = mutabl;
t->pointerfree = 0;
t->undeffree = undeffree;
t->ninitialized = ninitialized;
t->instance = NULL;
t->struct_decl = NULL;
t->size = 0;
Expand Down Expand Up @@ -703,13 +701,12 @@ jl_datatype_t *jl_new_bitstype(jl_value_t *name, jl_datatype_t *super,
jl_tuple_t *parameters, size_t nbits)
{
jl_datatype_t *bt = jl_new_datatype((jl_sym_t*)name, super, parameters,
jl_null, jl_null, 0, 0, 1);
jl_null, jl_null, 0, 0, 0);
bt->size = nbits/8;
bt->alignment = bt->size;
if (bt->alignment > MAX_ALIGN)
bt->alignment = MAX_ALIGN;
bt->pointerfree = 1;
bt->undeffree = 1;
return bt;
}

Expand Down
10 changes: 4 additions & 6 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,7 @@ static Value *emit_getfield(jl_value_t *expr, jl_sym_t *name, jl_codectx_t *ctx)
JL_GC_POP();
if (sty->fields[idx].isptr) {
Value *fldv = builder.CreateLoad(builder.CreateBitCast(addr,jl_ppvalue_llvmt));
if (!sty->undeffree) {
if (idx >= sty->ninitialized) {
null_pointer_check(fldv, ctx);
}
return fldv;
Expand All @@ -1514,10 +1514,8 @@ static Value *emit_getfield(jl_value_t *expr, jl_sym_t *name, jl_codectx_t *ctx)
if (jfty == (jl_value_t*)jl_bool_type) {
fldv = builder.CreateTrunc(fldv, T_int1);
}
else if (sty->fields[idx].isptr) {
if (!sty->undeffree) {
null_pointer_check(fldv, ctx);
}
else if (sty->fields[idx].isptr && idx >= sty->ninitialized) {
null_pointer_check(fldv, ctx);
}
JL_GC_POP();
return mark_julia_type(fldv, jfty);
Expand Down Expand Up @@ -2146,7 +2144,7 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs,
CreateGEP(builder.
CreateBitCast(strct, jl_ppvalue_llvmt),
builder.CreateAdd(idx,ConstantInt::get(T_size,1)))));
if (!stt->undeffree) {
if (stt->ninitialized != jl_tuple_len(stt->types)) {
null_pointer_check(fld, ctx);
}
JL_GC_POP();
Expand Down
21 changes: 14 additions & 7 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,13 @@ static void jl_serialize_datatype(ios_t *s, jl_datatype_t *dt)
write_uint16(s, nf);
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) | (dt->undeffree<<4));
if (!dt->abstract && mode != MODE_MODULE && mode != MODE_MODULE_LAMBDAS)
write_int32(s, dt->uid);
write_uint8(s, dt->abstract | (dt->mutabl<<1) | (dt->pointerfree<<2) | (has_instance<<3));
if (!dt->abstract) {
write_uint16(s, dt->ninitialized);
if (mode != MODE_MODULE && mode != MODE_MODULE_LAMBDAS) {
write_int32(s, dt->uid);
}
}
if (has_instance)
jl_serialize_value(s, dt->instance);
if (nf > 0) {
Expand Down Expand Up @@ -824,16 +828,19 @@ static jl_value_t *jl_deserialize_datatype(ios_t *s, int pos, jl_value_t **loc)
dt->abstract = flags&1;
dt->mutabl = (flags>>1)&1;
dt->pointerfree = (flags>>2)&1;
if (!dt->abstract && mode != MODE_MODULE && mode != MODE_MODULE_LAMBDAS)
dt->uid = read_int32(s);
else
if (!dt->abstract) {
dt->ninitialized = read_uint16(s);
dt->uid = mode != MODE_MODULE && mode != MODE_MODULE_LAMBDAS ? read_int32(s) : 0;
}
else {
dt->ninitialized = 0;
dt->uid = 0;
}
int has_instance = (flags>>3)&1;
if (has_instance) {
dt->instance = jl_deserialize_value(s, &dt->instance);
dt->instance->type = (jl_value_t*)dt;
}
dt->undeffree = (flags>>4)&1;
assert(tree_literal_values==NULL && mode != MODE_AST);
ptrhash_put(&backref_table, (void*)(ptrint_t)pos, dt);
if (tag == 5 || tag == 8) {
Expand Down
2 changes: 1 addition & 1 deletion src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ static jl_value_t *eval(jl_value_t *e, jl_value_t **locals, size_t nl)
temp = eval(args[2], locals, nl); // field names
dt = jl_new_datatype((jl_sym_t*)name, jl_any_type, (jl_tuple_t*)para,
(jl_tuple_t*)temp, NULL,
0, args[5]==jl_true ? 1 : 0, args[6]==jl_true ? 1 : 0);
0, args[5]==jl_true ? 1 : 0, jl_unbox_long(args[6]));

jl_binding_t *b = jl_get_binding_wr(jl_current_module, (jl_sym_t*)name);
temp = b->value; // save old value
Expand Down
23 changes: 11 additions & 12 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1992,7 +1992,7 @@ static jl_value_t *inst_type_w_(jl_value_t *t, jl_value_t **env, size_t n,
if (tn == jl_array_typename)
ndt->pointerfree = 0;
}
ndt->undeffree = dt->undeffree || jl_isbits(ndt);
ndt->ninitialized = dt->ninitialized;
if (cacheable) cache_type_((jl_value_t*)ndt);
result = (jl_value_t*)ndt;

Expand Down Expand Up @@ -2905,7 +2905,7 @@ void jl_init_types(void)
jl_datatype_type->name->primary = (jl_value_t*)jl_datatype_type;
jl_datatype_type->super = jl_type_type;
jl_datatype_type->parameters = jl_null;
jl_datatype_type->names = jl_tuple(11, jl_symbol("name"),
jl_datatype_type->names = jl_tuple(10, jl_symbol("name"),
jl_symbol("super"),
jl_symbol("parameters"),
jl_symbol("names"),
Expand All @@ -2914,13 +2914,12 @@ void jl_init_types(void)
jl_symbol("size"),
jl_symbol("abstract"),
jl_symbol("mutable"),
jl_symbol("pointerfree"),
jl_symbol("undeffree"));
jl_datatype_type->types = jl_tuple(11, jl_typename_type, jl_type_type,
jl_symbol("pointerfree"));
jl_datatype_type->types = jl_tuple(10, jl_typename_type, jl_type_type,
jl_tuple_type, jl_tuple_type,
jl_tuple_type, jl_any_type,
jl_any_type, //types will be fixed later
jl_any_type, jl_any_type, jl_any_type, jl_any_type);
jl_any_type, jl_any_type, jl_any_type);
jl_datatype_type->instance = NULL;
jl_datatype_type->uid = jl_assign_type_uid();
jl_datatype_type->struct_decl = NULL;
Expand All @@ -2929,7 +2928,7 @@ void jl_init_types(void)
// NOTE: types should not really be mutable, but the instance and
// struct_decl fields are basically caches, which are mutated.
jl_datatype_type->mutabl = 1;
jl_datatype_type->undeffree = 0;
jl_datatype_type->ninitialized = 0;

jl_typename_type->name = jl_new_typename(jl_symbol("TypeName"));
jl_typename_type->name->primary = (jl_value_t*)jl_typename_type;
Expand All @@ -2945,7 +2944,7 @@ void jl_init_types(void)
jl_typename_type->abstract = 0;
jl_typename_type->pointerfree = 0;
jl_typename_type->mutabl = 1;
jl_typename_type->undeffree = 0;
jl_typename_type->ninitialized = 0;

jl_sym_type->name = jl_new_typename(jl_symbol("Symbol"));
jl_sym_type->name->primary = (jl_value_t*)jl_sym_type;
Expand All @@ -2960,11 +2959,11 @@ void jl_init_types(void)
jl_sym_type->abstract = 0;
jl_sym_type->pointerfree = 0;
jl_sym_type->mutabl = 1;
jl_sym_type->undeffree = 0;
jl_sym_type->ninitialized = 0;

// now they can be used to create the remaining base kinds and types
jl_void_type = jl_new_datatype(jl_symbol("Void"), jl_any_type, jl_null,
jl_null, jl_null, 0, 0, 1);
jl_null, jl_null, 0, 0, 0);
jl_nothing = newstruct(jl_void_type);
jl_void_type->instance = jl_nothing;

Expand Down Expand Up @@ -3071,7 +3070,7 @@ void jl_init_types(void)
jl_null, jl_null, 0, 1, 0);
jl_array_typename = jl_array_type->name;
jl_array_type->pointerfree = 0;
jl_array_type->undeffree = 0;
jl_array_type->ninitialized = 0;

jl_array_any_type =
(jl_value_t*)jl_apply_type((jl_value_t*)jl_array_type,
Expand Down Expand Up @@ -3206,7 +3205,7 @@ void jl_init_types(void)
jl_tupleset(jl_datatype_type->types, 7, (jl_value_t*)jl_bool_type);
jl_tupleset(jl_datatype_type->types, 8, (jl_value_t*)jl_bool_type);
jl_tupleset(jl_datatype_type->types, 9, (jl_value_t*)jl_bool_type);
jl_tupleset(jl_datatype_type->types, 10, (jl_value_t*)jl_bool_type);
//jl_tupleset(jl_datatype_type->types, 10, jl_int32_type);
jl_tupleset(jl_function_type->types, 0, pointer_void);
jl_tupleset(jl_tvar_type->types, 3, (jl_value_t*)jl_bool_type);

Expand Down
18 changes: 9 additions & 9 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -856,17 +856,17 @@
ctor))

;; check if there are any calls to new with fewer than n arguments
(define (ctors-partial-new expr n)
(define (ctors-min-initialized expr)
(and (pair? expr)
(or
(min
((pattern-lambda
(call (-/ new) . args)
(not (length= args n))) (car expr))
(length args)) (car expr))
((pattern-lambda
(call (curly (-/ new) . p) . args)
(not (length= args n))) (car expr))
(ctors-partial-new (car expr) n)
(ctors-partial-new (cdr expr) n))))
(length args)) (car expr))
(ctors-min-initialized (car expr))
(ctors-min-initialized (cdr expr)))))

;; remove line numbers and nested blocks
(define (flatten-blocks e)
Expand All @@ -890,7 +890,7 @@
(defs2 (if (null? defs)
(default-inner-ctors name field-names field-types (null? params))
defs))
(undeffree (not (ctors-partial-new defs (length fields)))))
(min-initialized (min (ctors-min-initialized defs) (length fields))))
(for-each (lambda (v)
(if (not (symbol? v))
(error (string "field name \"" (deparse v) "\" is not a symbol"))))
Expand All @@ -900,7 +900,7 @@
(global ,name) (const ,name)
(composite_type ,name (tuple ,@params)
(tuple ,@(map (lambda (x) `',x) field-names))
,super (tuple ,@field-types) ,mut ,undeffree)
,super (tuple ,@field-types) ,mut ,min-initialized)
(call
(lambda ()
(scope-block
Expand All @@ -919,7 +919,7 @@
,@(map make-assignment params (symbols->typevars params bounds #t))
(composite_type ,name (tuple ,@params)
(tuple ,@(map (lambda (x) `',x) field-names))
,super (tuple ,@field-types) ,mut ,undeffree)))
,super (tuple ,@field-types) ,mut ,min-initialized)))
;; "inner" constructors
(call
(lambda ()
Expand Down
4 changes: 2 additions & 2 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ typedef struct _jl_datatype_t {
uint8_t abstract;
uint8_t mutabl;
uint8_t pointerfree;
uint8_t undeffree;
// hidden fields:
int32_t ninitialized;
uint32_t alignment; // strictest alignment over all fields
uint32_t uid;
void *struct_decl; //llvm::Value*
Expand Down Expand Up @@ -626,7 +626,7 @@ DLLEXPORT jl_datatype_t *jl_new_uninitialized_datatype(size_t nfields);
DLLEXPORT jl_datatype_t *jl_new_datatype(jl_sym_t *name, jl_datatype_t *super,
jl_tuple_t *parameters,
jl_tuple_t *fnames, jl_tuple_t *ftypes,
int abstract, int mutabl, int undeffree);
int abstract, int mutabl, int ninitialized);
DLLEXPORT jl_datatype_t *jl_new_bitstype(jl_value_t *name, jl_datatype_t *super,
jl_tuple_t *parameters, size_t nbits);
jl_datatype_t *jl_wrap_Type(jl_value_t *t); // x -> Type{x}
Expand Down

0 comments on commit 46ec202

Please sign in to comment.