diff --git a/src/alloc.c b/src/alloc.c index 4841f18caf7b3..7d581d0dff0be 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -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; } @@ -632,7 +631,6 @@ 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; @@ -640,7 +638,7 @@ 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; @@ -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; @@ -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; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 2a076fc8499a9..a61ea9a8aca36 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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; @@ -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); @@ -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(); diff --git a/src/dump.c b/src/dump.c index 700d564959be6..9e2dc7428d32a 100644 --- a/src/dump.c +++ b/src/dump.c @@ -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) { @@ -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) { diff --git a/src/interpreter.c b/src/interpreter.c index d7a3d0086ba4d..307535251183f 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -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 diff --git a/src/jltypes.c b/src/jltypes.c index c01a2ad04e06f..5bf23fbdaa6e3 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -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; @@ -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"), @@ -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; @@ -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; @@ -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; @@ -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; @@ -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, @@ -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); diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index d6ab1a89a4933..acb22c549129c 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -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) @@ -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")))) @@ -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 @@ -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 () diff --git a/src/julia.h b/src/julia.h index 08fad7e832920..8299ea7bc60b2 100644 --- a/src/julia.h +++ b/src/julia.h @@ -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* @@ -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}