diff --git a/base/boot.jl b/base/boot.jl index 6d0627cfca837..099a9e863922e 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -93,7 +93,8 @@ #end #struct LineInfoNode -# method::Any +# module::Module +# method::Symbol # file::Symbol # line::Int # inlined_at::Int @@ -396,8 +397,8 @@ eval(Core, :(PiNode(val, typ) = $(Expr(:new, :PiNode, :val, :typ)))) eval(Core, :(PhiCNode(values::Array{Any, 1}) = $(Expr(:new, :PhiCNode, :values)))) eval(Core, :(UpsilonNode(val) = $(Expr(:new, :UpsilonNode, :val)))) eval(Core, :(UpsilonNode() = $(Expr(:new, :UpsilonNode)))) -eval(Core, :(LineInfoNode(@nospecialize(method), file::Symbol, line::Int, inlined_at::Int) = - $(Expr(:new, :LineInfoNode, :method, :file, :line, :inlined_at)))) +eval(Core, :(LineInfoNode(mod::Module, @nospecialize(method), file::Symbol, line::Int, inlined_at::Int) = + $(Expr(:new, :LineInfoNode, :mod, :method, :file, :line, :inlined_at)))) eval(Core, :(CodeInstance(mi::MethodInstance, @nospecialize(rettype), @nospecialize(inferred_const), @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt) = diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index a493033752a1a..c19627dea5794 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -30,7 +30,6 @@ struct InliningTodo sparams::Vector{Any} # The static parameters we computed for this call site metharg # ::Type # The LineTable and IR of the inlinee - linetable::Vector{LineInfoNode} ir::IRCode # If the function being inlined is a single basic block we can use a # simpler inlining algorithm. This flag determines whether that's allowed @@ -307,8 +306,8 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector linetable_offset::Int32 = length(linetable) # Append the linetable of the inlined function to our line table inlined_at = Int(compact.result[idx][:line]) - for entry in item.linetable - push!(linetable, LineInfoNode(entry.method, entry.file, entry.line, + for entry in item.ir.linetable + push!(linetable, LineInfoNode(entry.module, entry.method, entry.file, entry.line, (entry.inlined_at > 0 ? entry.inlined_at + linetable_offset : inlined_at))) end if item.isva @@ -735,15 +734,15 @@ function analyze_method!(idx::Int, atypes::Vector{Any}, match::MethodMatch, @timeit "inline IR inflation" begin ir2 = inflate_ir(src, mi) - # prepare inlining linetable with method instance information - inline_linetable = Vector{LineInfoNode}(undef, length(src.linetable)) - for i = 1:length(src.linetable) - entry = src.linetable[i] - if entry.inlined_at === 0 && entry.method === method - entry = LineInfoNode(mi, entry.file, entry.line, entry.inlined_at) - end - inline_linetable[i] = entry - end + # #optional: prepare inlining linetable with method instance information + # inline_linetable = ir2.linetable + # for i = 1:length(inline_linetable) + # entry = inline_linetable[i] + # if entry.inlined_at === 0 && entry.method === method + # entry = LineInfoNode(entry.module, mi, entry.file, entry.line, entry.inlined_at) + # inline_linetable[i] = entry + # end + # end end #verify_ir(ir2) @@ -751,7 +750,7 @@ function analyze_method!(idx::Int, atypes::Vector{Any}, match::MethodMatch, na > 0 && method.isva, isinvoke, na, method, Any[match.sparams...], match.spec_types, - inline_linetable, ir2, linear_inline_eligible(ir2)) + ir2, linear_inline_eligible(ir2)) end # Neither the product iterator not CartesianIndices are available diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index 01d1311a80b5c..9af65c8cc1bb4 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -589,7 +589,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance) tree.slotflags = fill(0x00, nargs) tree.ssavaluetypes = 1 tree.codelocs = Int32[1] - tree.linetable = [LineInfoNode(method, method.file, Int(method.line), 0)] + tree.linetable = [LineInfoNode(method.module, method.name, method.file, Int(method.line), 0)] tree.inferred = true tree.ssaflags = UInt8[0] tree.pure = true diff --git a/src/ast.c b/src/ast.c index 024956122fe07..9c7465a44b53d 100644 --- a/src/ast.c +++ b/src/ast.c @@ -596,7 +596,7 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m else if (sym == thunk_sym) { ex = scm_to_julia_(fl_ctx, car_(e), mod); assert(jl_is_code_info(ex)); - jl_linenumber_to_lineinfo((jl_code_info_t*)ex, (jl_value_t*)jl_symbol("top-level scope")); + jl_linenumber_to_lineinfo((jl_code_info_t*)ex, mod, (jl_value_t*)jl_symbol("top-level scope")); temp = (jl_value_t*)jl_exprn(sym, 1); jl_exprargset(temp, 0, ex); } diff --git a/src/codegen.cpp b/src/codegen.cpp index b4286c41d3e39..4aefc3046eed7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5665,8 +5665,8 @@ static std::pair, jl_llvm_functions_t> } else if (jl_array_len(src->linetable) > 0) { jl_value_t *locinfo = jl_array_ptr_ref(src->linetable, 0); - ctx.file = jl_symbol_name((jl_sym_t*)jl_fieldref_noalloc(locinfo, 1)); - toplineno = jl_unbox_long(jl_fieldref(locinfo, 2)); + ctx.file = jl_symbol_name((jl_sym_t*)jl_fieldref_noalloc(locinfo, 2)); + toplineno = jl_unbox_long(jl_fieldref(locinfo, 3)); } if (ctx.file.empty()) ctx.file = ""; @@ -6284,40 +6284,44 @@ static std::pair, jl_llvm_functions_t> ssize_t line; bool is_user_code; unsigned inlined_at; + bool operator ==(const DebugLineTable &other) const { + return other.loc == loc && other.file == file && other.line == line && other.is_user_code == is_user_code && other.inlined_at == inlined_at; + } }; std::vector linetable; - { + { // populate the linetable data format assert(jl_is_array(src->linetable)); size_t nlocs = jl_array_len(src->linetable); std::map, DISubprogram*> subprograms; linetable.resize(nlocs + 1); + DebugLineTable &topinfo = linetable[0]; + topinfo.file = ctx.file; + topinfo.line = toplineno; + topinfo.is_user_code = mod_is_user_mod; + topinfo.inlined_at = 0; + topinfo.loc = topdebugloc; for (size_t i = 0; i < nlocs; i++) { // LineInfoNode(mod::Module, method::Any, file::Symbol, line::Int, inlined_at::Int) jl_value_t *locinfo = jl_array_ptr_ref(src->linetable, i); DebugLineTable &info = linetable[i + 1]; assert(jl_typeis(locinfo, jl_lineinfonode_type)); - jl_value_t *method = jl_fieldref_noalloc(locinfo, 0); - if (jl_is_method_instance(method)) - method = ((jl_method_instance_t*)method)->def.value; - jl_sym_t *filesym = (jl_sym_t*)jl_fieldref_noalloc(locinfo, 1); - info.line = jl_unbox_long(jl_fieldref(locinfo, 2)); - info.inlined_at = jl_unbox_long(jl_fieldref(locinfo, 3)); + jl_module_t *module = (jl_module_t*)jl_fieldref_noalloc(locinfo, 0); + jl_value_t *method = jl_fieldref_noalloc(locinfo, 1); + jl_sym_t *filesym = (jl_sym_t*)jl_fieldref_noalloc(locinfo, 2); + info.line = jl_unbox_long(jl_fieldref(locinfo, 3)); + info.inlined_at = jl_unbox_long(jl_fieldref(locinfo, 4)); assert(info.inlined_at <= i); - if (jl_is_method(method)) { - jl_module_t *module = ((jl_method_t*)method)->module; - if (module == ctx.module) - info.is_user_code = mod_is_user_mod; - else - info.is_user_code = in_user_mod(module); - } - else { - info.is_user_code = (info.inlined_at == 0) ? mod_is_user_mod : linetable.at(info.inlined_at).is_user_code; - } + if (module == ctx.module) + info.is_user_code = mod_is_user_mod; + else + info.is_user_code = in_user_mod(module); info.file = jl_symbol_name(filesym); if (info.file.empty()) info.file = ""; if (ctx.debug_enabled) { StringRef fname; + if (jl_is_method_instance(method)) + method = ((jl_method_instance_t*)method)->def.value; if (jl_is_method(method)) method = (jl_value_t*)((jl_method_t*)method)->name; if (jl_is_symbol(method)) diff --git a/src/dump.c b/src/dump.c index fe1f7f68700c7..70bc8afa9d538 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1656,7 +1656,7 @@ static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc { assert(!ios_eof(s->s)); jl_value_t *v; - size_t i, n; + size_t n; uintptr_t pos; uint8_t tag = read_uint8(s->s); if (tag > LAST_TAG) @@ -1774,14 +1774,6 @@ static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc arraylist_push(&backref_list, v); ios_readall(s->s, jl_string_data(v), n); return v; - case TAG_LINEINFO: - v = jl_new_struct_uninit(jl_lineinfonode_type); - arraylist_push(&backref_list, v); - for (i = 0; i < jl_datatype_nfields(jl_lineinfonode_type); i++) { - size_t offs = jl_field_offset(jl_lineinfonode_type, i); - set_nth_field(jl_lineinfonode_type, (void*)v, i, jl_deserialize_value(s, (jl_value_t**)((char*)v + offs))); - } - return v; case TAG_DATATYPE: pos = backref_list.len; arraylist_push(&backref_list, NULL); diff --git a/src/jltypes.c b/src/jltypes.c index 60734398b3bdd..32988c7662eba 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2193,8 +2193,9 @@ void jl_init_types(void) JL_GC_DISABLED jl_lineinfonode_type = jl_new_datatype(jl_symbol("LineInfoNode"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(4, "method", "file", "line", "inlined_at"), - jl_svec(4, jl_any_type, jl_symbol_type, jl_long_type, jl_long_type), 0, 0, 4); + jl_perm_symsvec(5, "module", "method", "file", "line", "inlined_at"), + jl_svec(5, jl_module_type, jl_any_type, jl_symbol_type, jl_long_type, jl_long_type), + 0, 0, 5); jl_gotonode_type = jl_new_datatype(jl_symbol("GotoNode"), core, jl_any_type, jl_emptysvec, diff --git a/src/julia.h b/src/julia.h index aa7a3cf049164..4069b59fde320 100644 --- a/src/julia.h +++ b/src/julia.h @@ -252,6 +252,7 @@ JL_EXTENSION typedef union { typedef struct _jl_method_instance_t jl_method_instance_t; typedef struct _jl_line_info_node_t { + struct _jl_module_t *module; jl_value_t *method; jl_sym_t *file; intptr_t line; diff --git a/src/julia_internal.h b/src/julia_internal.h index 4754c534fb3cb..b6b5df22cd023 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -476,7 +476,7 @@ jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e, jl_svec_t *sparam_vals); int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT; jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule); -void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_value_t *name); +void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_module_t *mod, jl_value_t *name); jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world); jl_value_t *jl_gf_invoke(jl_value_t *types, jl_value_t *f, jl_value_t **args, size_t nargs); diff --git a/src/method.c b/src/method.c index 2665325b44ee1..c0d218a69e175 100644 --- a/src/method.c +++ b/src/method.c @@ -356,7 +356,7 @@ jl_code_info_t *jl_new_code_info_from_ir(jl_expr_t *ir) return src; } -void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_value_t *name) +void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_module_t *mod, jl_value_t *name) { jl_array_t *li = (jl_array_t*)ci->linetable; size_t i, n = jl_array_len(li); @@ -366,11 +366,11 @@ void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_value_t *name) jl_value_t *ln = jl_array_ptr_ref(li, i); if (jl_is_linenode(ln)) { rt = jl_box_long(jl_linenode_line(ln)); - rt = jl_new_struct(jl_lineinfonode_type, name, jl_linenode_file(ln), rt, jl_box_long(0)); + rt = jl_new_struct(jl_lineinfonode_type, mod, name, jl_linenode_file(ln), rt, jl_box_long(0)); jl_array_ptr_set(li, i, rt); } else if (jl_is_expr(ln) && ((jl_expr_t*)ln)->head == line_sym && jl_expr_nargs(ln) == 3) { - rt = jl_new_struct(jl_lineinfonode_type, jl_symbol("macro expansion"), + rt = jl_new_struct(jl_lineinfonode_type, mod, jl_symbol("macro expansion"), jl_exprarg(ln, 1), jl_exprarg(ln, 0), jl_exprarg(ln, 2)); jl_array_ptr_set(li, i, rt); } @@ -461,7 +461,7 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo) ptls->in_pure_callback = last_in; jl_lineno = last_lineno; ptls->world_age = last_age; - jl_linenumber_to_lineinfo(func, (jl_value_t*)def->name); + jl_linenumber_to_lineinfo(func, def->module, (jl_value_t*)def->name); } JL_CATCH { ptls->in_pure_callback = last_in; @@ -514,7 +514,7 @@ static void jl_method_set_source(jl_method_t *m, jl_code_info_t *src) } m->called = called; m->pure = src->pure; - jl_linenumber_to_lineinfo(src, (jl_value_t*)m->name); + jl_linenumber_to_lineinfo(src, m->module, (jl_value_t*)m->name); jl_array_t *copy = NULL; jl_svec_t *sparam_vars = jl_outer_unionall_vars(m->sig); diff --git a/src/stackwalk.c b/src/stackwalk.c index f3ab648fe7ad9..ffe834235f588 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -660,14 +660,14 @@ void jl_print_bt_entry_codeloc(jl_bt_element_t *bt_entry) JL_NOTSAFEPOINT jl_line_info_node_t *locinfo = (jl_line_info_node_t*) jl_array_ptr_ref(src->linetable, debuginfoloc - 1); assert(jl_typeis(locinfo, jl_lineinfonode_type)); + const char *func_name = "Unknown"; jl_value_t *method = locinfo->method; - if (jl_is_method_instance(method)) { + if (jl_is_method_instance(method)) method = ((jl_method_instance_t*)method)->def.value; - if (jl_is_method(method)) - method = (jl_value_t*)((jl_method_t*)method)->name; - } - const char *func_name = jl_is_symbol(method) ? - jl_symbol_name((jl_sym_t*)method) : "Unknown"; + if (jl_is_method(method)) + method = (jl_value_t*)((jl_method_t*)method)->name; + if (jl_is_symbol(method)) + func_name = jl_symbol_name((jl_sym_t*)method); jl_safe_print_codeloc(func_name, jl_symbol_name(locinfo->file), locinfo->line, locinfo->inlined_at); debuginfoloc = locinfo->inlined_at; diff --git a/stdlib/Serialization/src/Serialization.jl b/stdlib/Serialization/src/Serialization.jl index d4cb39f5744e1..7a4b3da4b8ea8 100644 --- a/stdlib/Serialization/src/Serialization.jl +++ b/stdlib/Serialization/src/Serialization.jl @@ -1038,12 +1038,15 @@ function deserialize(s::AbstractSerializer, ::Type{Core.MethodInstance}) end function deserialize(s::AbstractSerializer, ::Type{Core.LineInfoNode}) - _meth = deserialize(s) - if _meth isa Module - # pre v1.2, skip - _meth = deserialize(s) + mod = deserialize(s) + if mod isa Module + method = deserialize(s) + else + # files post v1.2 and pre v1.6 are broken + method = mod + mod = Main end - return Core.LineInfoNode(_meth::Symbol, deserialize(s)::Symbol, deserialize(s)::Int, deserialize(s)::Int) + return Core.LineInfoNode(mod, method, deserialize(s)::Symbol, deserialize(s)::Int, deserialize(s)::Int) end function deserialize(s::AbstractSerializer, ::Type{PhiNode}) diff --git a/test/compiler/ssair.jl b/test/compiler/ssair.jl index eb76e62c45453..ae8e86c2c9a5e 100644 --- a/test/compiler/ssair.jl +++ b/test/compiler/ssair.jl @@ -36,7 +36,7 @@ end # false, false, false, false # )) # -# NullLineInfo = Core.LineInfoNode(Symbol(""), Symbol(""), 0, 0) +# NullLineInfo = Core.LineInfoNode(Main, Symbol(""), Symbol(""), 0, 0) # Compiler.run_passes(ci, 1, [NullLineInfo]) # # XXX: missing @test #end