diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 47951336035ef..60ac19fb5808d 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -327,7 +327,7 @@ already_inferred_quick_test(interp::AbstractInterpreter, mi::MethodInstance) = function maybe_compress_codeinfo(interp::AbstractInterpreter, linfo::MethodInstance, ci::CodeInfo) def = linfo.def toplevel = !isa(def, Method) - if toplevel + if toplevel || JLOptions().incremental != Int8(0) # defer compression until serialization return ci end if may_discard_trees(interp) diff --git a/src/codegen.cpp b/src/codegen.cpp index af68bf1187e22..d0eb32ff759a3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7574,7 +7574,7 @@ jl_compile_result_t jl_emit_codeinst( jl_options.debug_level > 1) { // update the stored code if (codeinst->inferred != (jl_value_t*)src) { - if (jl_is_method(def)) + if (jl_is_method(def) && !jl_options.incremental) // defer compression until serialization src = (jl_code_info_t*)jl_compress_ir(def, src); codeinst->inferred = (jl_value_t*)src; jl_gc_wb(codeinst, src); diff --git a/src/dump.c b/src/dump.c index 0d07e46c8a0c7..8a2333205024f 100644 --- a/src/dump.c +++ b/src/dump.c @@ -484,6 +484,24 @@ static int jl_serialize_generic(jl_serializer_state *s, jl_value_t *v) JL_GC_DIS return 0; } +static void uncompress_code(jl_method_t *m, jl_code_instance_t *codeinst) +{ + while (codeinst) { + if (codeinst->inferred && jl_is_array(codeinst->inferred)) + codeinst->inferred = (jl_value_t*)jl_uncompress_ir(m, codeinst, (jl_array_t*)codeinst->inferred); + codeinst = codeinst->next; + } +} + +static void compress_code(jl_method_t *m, jl_code_instance_t *codeinst) +{ + while (codeinst) { + if (codeinst->inferred && jl_is_code_info(codeinst->inferred)) + codeinst->inferred = (jl_value_t*)jl_compress_ir(m, (jl_code_info_t*)codeinst->inferred); + codeinst = codeinst->next; + } +} + static void jl_serialize_code_instance(jl_serializer_state *s, jl_code_instance_t *codeinst, int skip_partial_opaque) JL_GC_DISABLED { if (jl_serialize_generic(s, (jl_value_t*)codeinst)) { @@ -662,7 +680,29 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li int serialization_mode = 0; if (m->is_for_opaque_closure || module_in_worklist(m->module)) serialization_mode |= METHOD_INTERNAL; - if (!(serialization_mode & METHOD_INTERNAL)) { + if (serialization_mode & METHOD_INTERNAL) { + // defer compression until serialization + // Compression must occur before roots are serialized. + // However, because jl_compress_ir is externally callable, first check + // whether we need to decompress. This enables root-reordering transformations. + if (m->source && jl_is_array(m->source)) + m->source = (jl_value_t*)jl_uncompress_ir(m, NULL, (jl_array_t*)m->source); + size_t l = jl_svec_len(m->specializations); + for (i = 0; i < l; i++) { + jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(m->specializations, i); + if ((jl_value_t*)mi != jl_nothing) + uncompress_code(m, mi->cache); + } + // Perform root-reordering transformations here + // Compress + if (m->source && jl_is_code_info(m->source)) + m->source = (jl_value_t*)jl_compress_ir(m, (jl_code_info_t*)m->source); + for (i = 0; i < l; i++) { + jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(m->specializations, i); + if ((jl_value_t*)mi != jl_nothing) + compress_code(m, mi->cache); + } + } else { // flag this in the backref table as special uintptr_t *bp = (uintptr_t*)ptrhash_bp(&backref_table, v); assert(*bp != (uintptr_t)HT_NOTFOUND); diff --git a/src/method.c b/src/method.c index d8cd1c30a94e1..53ebb4b5e9ab2 100644 --- a/src/method.c +++ b/src/method.c @@ -715,8 +715,12 @@ static void jl_method_set_source(jl_method_t *m, jl_code_info_t *src) jl_gc_wb(m, m->slot_syms); if (gen_only) m->source = NULL; - else - m->source = (jl_value_t*)jl_compress_ir(m, src); + else { + if (jl_options.incremental) // defer compression until serialization + m->source = (jl_value_t*)src; + else + m->source = (jl_value_t*)jl_compress_ir(m, src); + } jl_gc_wb(m, m->source); JL_GC_POP(); }