From ec3d632686d2577009139893078b3101393bf6e6 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 1 Jan 2016 23:48:46 -0500 Subject: [PATCH] fix incremental deserializer on some cases of external singleton values this was causing several package test failures on jb/functions --- src/dump.c | 74 +++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/src/dump.c b/src/dump.c index 4a676e3afcfca..0aeaa00791ffb 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1508,6 +1508,7 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t jl_set_typeof(v, dt); if (dt == jl_datatype_type) return jl_deserialize_datatype(s, pos, loc); + assert(mode==MODE_AST || sz!=0 || loc); if ((mode == MODE_MODULE || mode == MODE_MODULE_POSTWORK) && dt == jl_typename_type) { int ref_only = read_uint8(s); if (ref_only) { @@ -1566,6 +1567,8 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t uptrint_t pos = backref_list.len; arraylist_push(&backref_list, (void*)v); if (mode == MODE_MODULE) { + // TODO: optimize the case where the value can easily be obtained + // from an external module (tag == 6) as dt->instance assert(loc != NULL); arraylist_push(&flagref_list, loc); arraylist_push(&flagref_list, (void*)pos); @@ -1705,7 +1708,7 @@ static void jl_reinit_item(ios_t *f, jl_value_t *v, int how) { jl_idtable_rehash(a, jl_array_len(*a)); jl_gc_wb(v, *a); break; - } + } case 2: { // reinsert module v into parent (const) jl_module_t *mod = (jl_module_t*)v; jl_binding_t *b = jl_get_binding_wr(mod->parent, mod->name); @@ -1724,7 +1727,7 @@ static void jl_reinit_item(ios_t *f, jl_value_t *v, int how) { b->value = v; jl_gc_wb_binding(b, v); break; - } + } default: assert(0); } @@ -2072,38 +2075,43 @@ JL_DLLEXPORT int jl_save_incremental(const char *fname, jl_array_t *worklist) return 0; } -static jl_datatype_t *jl_recache_type(jl_datatype_t *dt, size_t start) +static jl_datatype_t *jl_recache_type(jl_datatype_t *dt, size_t start, jl_value_t *v) { - assert(dt->uid == -1); - jl_svec_t *tt = dt->parameters; - jl_value_t *v = dt->instance; // the instance before unique'ing + if (v == NULL) + v = dt->instance; // the instance before unique'ing jl_datatype_t *t; // the type after unique'ing - size_t l = jl_svec_len(tt); - if (l == 0) { // jl_cache_type doesn't work if length(parameters) == 0 - dt->uid = jl_assign_type_uid(); - t = dt; - } - else { - // recache all type parameters, then type type itself - size_t i; - for (i = 0; i < l; i++) { - jl_datatype_t *p = (jl_datatype_t*)jl_svecref(tt, i); - if (jl_is_datatype(p) && p->uid == -1) { - jl_datatype_t *cachep = jl_recache_type(p, start); - if (p != cachep) - jl_svecset(tt, i, cachep); - } - jl_datatype_t *tp = (jl_datatype_t*)jl_typeof(p); - if (jl_is_datatype_singleton(tp)) { - if (tp->uid == -1) { - tp = jl_recache_type(tp, start); + if (dt->uid == -1) { + jl_svec_t *tt = dt->parameters; + size_t l = jl_svec_len(tt); + if (l == 0) { // jl_cache_type doesn't work if length(parameters) == 0 + dt->uid = jl_assign_type_uid(); + t = dt; + } + else { + // recache all type parameters, then type type itself + size_t i; + for (i = 0; i < l; i++) { + jl_datatype_t *p = (jl_datatype_t*)jl_svecref(tt, i); + if (jl_is_datatype(p) && p->uid == -1) { + jl_datatype_t *cachep = jl_recache_type(p, start, NULL); + if (p != cachep) + jl_svecset(tt, i, cachep); + } + jl_datatype_t *tp = (jl_datatype_t*)jl_typeof(p); + if (jl_is_datatype_singleton(tp)) { + if (tp->uid == -1) { + tp = jl_recache_type(tp, start, NULL); + } + if ((jl_value_t*)p != tp->instance) + jl_svecset(tt, i, tp->instance); } - if ((jl_value_t*)p != tp->instance) - jl_svecset(tt, i, tp->instance); } + dt->uid = 0; + t = (jl_datatype_t*)jl_cache_type_(dt); } - dt->uid = 0; - t = (jl_datatype_t*)jl_cache_type_(dt); + } + else { + t = dt; } assert(t->uid != 0); // delete / replace any other usages of this type in the backref list @@ -2150,15 +2158,13 @@ static void jl_recache_types(void) if (jl_is_datatype(o)) { dt = (jl_datatype_t*)o; v = dt->instance; - t = jl_recache_type(dt, i); + assert(dt->uid == -1); + t = jl_recache_type(dt, i, NULL); } else { dt = (jl_datatype_t*)jl_typeof(o); v = o; - if (dt->uid == -1) - t = jl_recache_type(dt, i); - else - t = dt; + t = jl_recache_type(dt, i, v); } assert(dt); if (t != dt) {