diff --git a/base/boot.jl b/base/boot.jl index 16820aa070369..4a59bf6279d63 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -488,6 +488,8 @@ eval(Core, quote MethodMatch(@nospecialize(spec_types), sparams::SimpleVector, method::Method, fully_covers::Bool) = $(Expr(:new, :MethodMatch, :spec_types, :sparams, :method, :fully_covers)) end) +const NullDebugInfo = DebugInfo(:none) + struct LineInfoNode # legacy support for aiding Serializer.deserialize of old IR mod::Module method diff --git a/src/jltypes.c b/src/jltypes.c index 2ea432a7a5cc3..b6bba6d9dd7ce 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3535,6 +3535,8 @@ static jl_value_t *core(const char *name) return jl_get_global(jl_core_module, jl_symbol(name)); } +jl_debuginfo_t *jl_nulldebuginfo; + // fetch references to things defined in boot.jl void post_boot_hooks(void) { @@ -3590,6 +3592,7 @@ void post_boot_hooks(void) jl_weakref_type = (jl_datatype_t*)core("WeakRef"); jl_vecelement_typename = ((jl_datatype_t*)jl_unwrap_unionall(core("VecElement")))->name; + jl_nulldebuginfo = (jl_debuginfo_t*)core("NullDebugInfo"); jl_init_box_caches(); diff --git a/src/julia_internal.h b/src/julia_internal.h index 15090ee319a6e..900591fa206a7 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -325,6 +325,7 @@ extern JL_DLLIMPORT jl_methtable_t *jl_nonfunction_mt JL_GLOBALLY_ROOTED; extern jl_methtable_t *jl_kwcall_mt JL_GLOBALLY_ROOTED; extern JL_DLLEXPORT jl_method_t *jl_opaque_closure_method JL_GLOBALLY_ROOTED; extern JL_DLLEXPORT _Atomic(size_t) jl_world_counter; +extern jl_debuginfo_t *jl_nulldebuginfo JL_GLOBALLY_ROOTED; typedef void (*tracer_cb)(jl_value_t *tracee); extern tracer_cb jl_newmeth_tracer; diff --git a/src/staticdata.c b/src/staticdata.c index a41d6b76586eb..980a1e69e77d8 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -100,7 +100,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 189 +#define NUM_TAGS 190 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -265,6 +265,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_kwcall_mt); INSERT_TAG(jl_kwcall_func); INSERT_TAG(jl_opaque_closure_method); + INSERT_TAG(jl_nulldebuginfo); // some Core.Builtin Functions that we want to be able to reference: INSERT_TAG(jl_builtin_throw); @@ -2352,7 +2353,19 @@ static void jl_prune_type_cache_linear(jl_svec_t *cache) jl_svecset(cache, ins++, jl_nothing); } -static jl_value_t *strip_codeinfo_meta(jl_method_t *m, jl_value_t *ci_, jl_code_instance_t *codeinst, int orig) +static void strip_slotnames(jl_array_t *slotnames) +{ + // replace slot names with `?`, except unused_sym since the compiler looks at it + jl_sym_t *questionsym = jl_symbol("?"); + int i, l = jl_array_len(slotnames); + for (i = 0; i < l; i++) { + jl_value_t *s = jl_array_ptr_ref(slotnames, i); + if (s != (jl_value_t*)jl_unused_sym) + jl_array_ptr_set(slotnames, i, questionsym); + } +} + +static jl_value_t *strip_codeinfo_meta(jl_method_t *m, jl_value_t *ci_, jl_code_instance_t *codeinst) { jl_code_info_t *ci = NULL; JL_GC_PUSH1(&ci); @@ -2364,18 +2377,9 @@ static jl_value_t *strip_codeinfo_meta(jl_method_t *m, jl_value_t *ci_, jl_code_ else { ci = (jl_code_info_t*)ci_; } - // replace slot names with `?`, except unused_sym since the compiler looks at it - jl_sym_t *questionsym = jl_symbol("?"); - int i, l = jl_array_len(ci->slotnames); - for (i = 0; i < l; i++) { - jl_value_t *s = jl_array_ptr_ref(ci->slotnames, i); - if (s != (jl_value_t*)jl_unused_sym) - jl_array_ptr_set(ci->slotnames, i, questionsym); - } - if (orig) { - m->slot_syms = jl_compress_argnames(ci->slotnames); - jl_gc_wb(m, m->slot_syms); - } + strip_slotnames(ci->slotnames); + ci->debuginfo = jl_nulldebuginfo; + jl_gc_wb(ci, ci->debuginfo); jl_value_t *ret = (jl_value_t*)ci; if (compressed) ret = (jl_value_t*)jl_compress_ir(m, ci); @@ -2394,12 +2398,14 @@ static void strip_specializations_(jl_method_instance_t *mi) record_field_change((jl_value_t**)&codeinst->inferred, jl_nothing); } else if (jl_options.strip_metadata) { - jl_value_t *stripped = strip_codeinfo_meta(mi->def.method, inferred, codeinst, 0); + jl_value_t *stripped = strip_codeinfo_meta(mi->def.method, inferred, codeinst); if (jl_atomic_cmpswap_relaxed(&codeinst->inferred, &inferred, stripped)) { jl_gc_wb(codeinst, stripped); } } } + if (jl_options.strip_metadata) + record_field_change((jl_value_t**)&codeinst->debuginfo, (jl_value_t*)jl_nulldebuginfo); codeinst = jl_atomic_load_relaxed(&codeinst->next); } if (jl_options.strip_ir) { @@ -2414,31 +2420,45 @@ static int strip_all_codeinfos__(jl_typemap_entry_t *def, void *_env) if (m->source) { int stripped_ir = 0; if (jl_options.strip_ir) { - if (jl_atomic_load_relaxed(&m->unspecialized)) { - jl_code_instance_t *unspec = jl_atomic_load_relaxed(&jl_atomic_load_relaxed(&m->unspecialized)->cache); - if (unspec && jl_atomic_load_relaxed(&unspec->invoke)) { - // we have a generic compiled version, so can remove the IR - record_field_change(&m->source, jl_nothing); - stripped_ir = 1; + int should_strip_ir = 0; + if (!should_strip_ir) { + if (jl_atomic_load_relaxed(&m->unspecialized)) { + jl_code_instance_t *unspec = jl_atomic_load_relaxed(&jl_atomic_load_relaxed(&m->unspecialized)->cache); + if (unspec && jl_atomic_load_relaxed(&unspec->invoke)) { + // we have a generic compiled version, so can remove the IR + should_strip_ir = 1; + } } } - if (!stripped_ir) { + if (!should_strip_ir) { int mod_setting = jl_get_module_compile(m->module); - // if the method is declared not to be compiled, keep IR for interpreter if (!(mod_setting == JL_OPTIONS_COMPILE_OFF || mod_setting == JL_OPTIONS_COMPILE_MIN)) { - record_field_change(&m->source, jl_nothing); - stripped_ir = 1; + // if the method is declared not to be compiled, keep IR for interpreter + should_strip_ir = 1; } } + if (should_strip_ir) { + record_field_change(&m->source, jl_nothing); + stripped_ir = 1; + } } - if (jl_options.strip_metadata && !stripped_ir) { - m->source = strip_codeinfo_meta(m, m->source, NULL, 1); - jl_gc_wb(m, m->source); + if (jl_options.strip_metadata) { + if (!stripped_ir) { + m->source = strip_codeinfo_meta(m, m->source, NULL); + jl_gc_wb(m, m->source); + } + jl_array_t *slotnames = jl_uncompress_argnames(m->slot_syms); + JL_GC_PUSH1(&slotnames); + strip_slotnames(slotnames); + m->slot_syms = jl_compress_argnames(slotnames); + jl_gc_wb(m, m->slot_syms); + JL_GC_POP(); } } if (jl_options.strip_metadata) { record_field_change((jl_value_t**)&m->file, (jl_value_t*)jl_empty_sym); m->line = 0; + record_field_change((jl_value_t**)&m->debuginfo, (jl_value_t*)jl_nulldebuginfo); } jl_value_t *specializations = jl_atomic_load_relaxed(&m->specializations); if (!jl_is_svec(specializations)) { diff --git a/stdlib/Serialization/src/Serialization.jl b/stdlib/Serialization/src/Serialization.jl index 3f38708e8bb1e..c9cb1edea4b6b 100644 --- a/stdlib/Serialization/src/Serialization.jl +++ b/stdlib/Serialization/src/Serialization.jl @@ -1288,7 +1288,7 @@ function deserialize(s::AbstractSerializer, ::Type{CodeInfo}) return ci end -const NullDebugInfo = DebugInfo(:none) +import Core: NullDebugInfo if Int === Int64 const OtherInt = Int32