Skip to content

Commit 42a1d34

Browse files
committed
restore explicit module field to LineNumberNode
While this takes a non-trivial amount of space in the system image (about the same as putting the Method object here, but less than putting the full edge to the MethodInstance), it is necessary to avoid the regression #36462 caused by 2e37784.
1 parent 840ecac commit 42a1d34

File tree

13 files changed

+67
-66
lines changed

13 files changed

+67
-66
lines changed

base/boot.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@
9393
#end
9494

9595
#struct LineInfoNode
96-
# method::Any
96+
# module::Module
97+
# method::Symbol
9798
# file::Symbol
9899
# line::Int
99100
# inlined_at::Int
@@ -396,8 +397,8 @@ eval(Core, :(PiNode(val, typ) = $(Expr(:new, :PiNode, :val, :typ))))
396397
eval(Core, :(PhiCNode(values::Array{Any, 1}) = $(Expr(:new, :PhiCNode, :values))))
397398
eval(Core, :(UpsilonNode(val) = $(Expr(:new, :UpsilonNode, :val))))
398399
eval(Core, :(UpsilonNode() = $(Expr(:new, :UpsilonNode))))
399-
eval(Core, :(LineInfoNode(@nospecialize(method), file::Symbol, line::Int, inlined_at::Int) =
400-
$(Expr(:new, :LineInfoNode, :method, :file, :line, :inlined_at))))
400+
eval(Core, :(LineInfoNode(mod::Module, @nospecialize(method), file::Symbol, line::Int, inlined_at::Int) =
401+
$(Expr(:new, :LineInfoNode, :mod, :method, :file, :line, :inlined_at))))
401402
eval(Core, :(CodeInstance(mi::MethodInstance, @nospecialize(rettype), @nospecialize(inferred_const),
402403
@nospecialize(inferred), const_flags::Int32,
403404
min_world::UInt, max_world::UInt) =

base/compiler/ssair/inlining.jl

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ struct InliningTodo
3030
sparams::Vector{Any} # The static parameters we computed for this call site
3131
metharg # ::Type
3232
# The LineTable and IR of the inlinee
33-
linetable::Vector{LineInfoNode}
3433
ir::IRCode
3534
# If the function being inlined is a single basic block we can use a
3635
# simpler inlining algorithm. This flag determines whether that's allowed
@@ -307,8 +306,8 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector
307306
linetable_offset::Int32 = length(linetable)
308307
# Append the linetable of the inlined function to our line table
309308
inlined_at = Int(compact.result[idx][:line])
310-
for entry in item.linetable
311-
push!(linetable, LineInfoNode(entry.method, entry.file, entry.line,
309+
for entry in item.ir.linetable
310+
push!(linetable, LineInfoNode(entry.module, entry.method, entry.file, entry.line,
312311
(entry.inlined_at > 0 ? entry.inlined_at + linetable_offset : inlined_at)))
313312
end
314313
if item.isva
@@ -735,23 +734,23 @@ function analyze_method!(idx::Int, atypes::Vector{Any}, match::MethodMatch,
735734

736735
@timeit "inline IR inflation" begin
737736
ir2 = inflate_ir(src, mi)
738-
# prepare inlining linetable with method instance information
739-
inline_linetable = Vector{LineInfoNode}(undef, length(src.linetable))
740-
for i = 1:length(src.linetable)
741-
entry = src.linetable[i]
742-
if entry.inlined_at === 0 && entry.method === method
743-
entry = LineInfoNode(mi, entry.file, entry.line, entry.inlined_at)
744-
end
745-
inline_linetable[i] = entry
746-
end
737+
# #optional: prepare inlining linetable with method instance information
738+
# inline_linetable = ir2.linetable
739+
# for i = 1:length(inline_linetable)
740+
# entry = inline_linetable[i]
741+
# if entry.inlined_at === 0 && entry.method === method
742+
# entry = LineInfoNode(entry.module, mi, entry.file, entry.line, entry.inlined_at)
743+
# inline_linetable[i] = entry
744+
# end
745+
# end
747746
end
748747
#verify_ir(ir2)
749748

750749
return InliningTodo(idx,
751750
na > 0 && method.isva,
752751
isinvoke, na,
753752
method, Any[match.sparams...], match.spec_types,
754-
inline_linetable, ir2, linear_inline_eligible(ir2))
753+
ir2, linear_inline_eligible(ir2))
755754
end
756755

757756
# Neither the product iterator not CartesianIndices are available

base/compiler/typeinfer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance)
589589
tree.slotflags = fill(0x00, nargs)
590590
tree.ssavaluetypes = 1
591591
tree.codelocs = Int32[1]
592-
tree.linetable = [LineInfoNode(method, method.file, Int(method.line), 0)]
592+
tree.linetable = [LineInfoNode(method.module, method.name, method.file, Int(method.line), 0)]
593593
tree.inferred = true
594594
tree.ssaflags = UInt8[0]
595595
tree.pure = true

src/ast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m
596596
else if (sym == thunk_sym) {
597597
ex = scm_to_julia_(fl_ctx, car_(e), mod);
598598
assert(jl_is_code_info(ex));
599-
jl_linenumber_to_lineinfo((jl_code_info_t*)ex, (jl_value_t*)jl_symbol("top-level scope"));
599+
jl_linenumber_to_lineinfo((jl_code_info_t*)ex, mod, (jl_value_t*)jl_symbol("top-level scope"));
600600
temp = (jl_value_t*)jl_exprn(sym, 1);
601601
jl_exprargset(temp, 0, ex);
602602
}

src/codegen.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5665,8 +5665,8 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
56655665
}
56665666
else if (jl_array_len(src->linetable) > 0) {
56675667
jl_value_t *locinfo = jl_array_ptr_ref(src->linetable, 0);
5668-
ctx.file = jl_symbol_name((jl_sym_t*)jl_fieldref_noalloc(locinfo, 1));
5669-
toplineno = jl_unbox_long(jl_fieldref(locinfo, 2));
5668+
ctx.file = jl_symbol_name((jl_sym_t*)jl_fieldref_noalloc(locinfo, 2));
5669+
toplineno = jl_unbox_long(jl_fieldref(locinfo, 3));
56705670
}
56715671
if (ctx.file.empty())
56725672
ctx.file = "<missing>";
@@ -6284,40 +6284,44 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
62846284
ssize_t line;
62856285
bool is_user_code;
62866286
unsigned inlined_at;
6287+
bool operator ==(const DebugLineTable &other) const {
6288+
return other.loc == loc && other.file == file && other.line == line && other.is_user_code == is_user_code && other.inlined_at == inlined_at;
6289+
}
62876290
};
62886291
std::vector<DebugLineTable> linetable;
6289-
{
6292+
{ // populate the linetable data format
62906293
assert(jl_is_array(src->linetable));
62916294
size_t nlocs = jl_array_len(src->linetable);
62926295
std::map<std::tuple<StringRef, StringRef>, DISubprogram*> subprograms;
62936296
linetable.resize(nlocs + 1);
6297+
DebugLineTable &topinfo = linetable[0];
6298+
topinfo.file = ctx.file;
6299+
topinfo.line = toplineno;
6300+
topinfo.is_user_code = mod_is_user_mod;
6301+
topinfo.inlined_at = 0;
6302+
topinfo.loc = topdebugloc;
62946303
for (size_t i = 0; i < nlocs; i++) {
62956304
// LineInfoNode(mod::Module, method::Any, file::Symbol, line::Int, inlined_at::Int)
62966305
jl_value_t *locinfo = jl_array_ptr_ref(src->linetable, i);
62976306
DebugLineTable &info = linetable[i + 1];
62986307
assert(jl_typeis(locinfo, jl_lineinfonode_type));
6299-
jl_value_t *method = jl_fieldref_noalloc(locinfo, 0);
6300-
if (jl_is_method_instance(method))
6301-
method = ((jl_method_instance_t*)method)->def.value;
6302-
jl_sym_t *filesym = (jl_sym_t*)jl_fieldref_noalloc(locinfo, 1);
6303-
info.line = jl_unbox_long(jl_fieldref(locinfo, 2));
6304-
info.inlined_at = jl_unbox_long(jl_fieldref(locinfo, 3));
6308+
jl_module_t *module = (jl_module_t*)jl_fieldref_noalloc(locinfo, 0);
6309+
jl_value_t *method = jl_fieldref_noalloc(locinfo, 1);
6310+
jl_sym_t *filesym = (jl_sym_t*)jl_fieldref_noalloc(locinfo, 2);
6311+
info.line = jl_unbox_long(jl_fieldref(locinfo, 3));
6312+
info.inlined_at = jl_unbox_long(jl_fieldref(locinfo, 4));
63056313
assert(info.inlined_at <= i);
6306-
if (jl_is_method(method)) {
6307-
jl_module_t *module = ((jl_method_t*)method)->module;
6308-
if (module == ctx.module)
6309-
info.is_user_code = mod_is_user_mod;
6310-
else
6311-
info.is_user_code = in_user_mod(module);
6312-
}
6313-
else {
6314-
info.is_user_code = (info.inlined_at == 0) ? mod_is_user_mod : linetable.at(info.inlined_at).is_user_code;
6315-
}
6314+
if (module == ctx.module)
6315+
info.is_user_code = mod_is_user_mod;
6316+
else
6317+
info.is_user_code = in_user_mod(module);
63166318
info.file = jl_symbol_name(filesym);
63176319
if (info.file.empty())
63186320
info.file = "<missing>";
63196321
if (ctx.debug_enabled) {
63206322
StringRef fname;
6323+
if (jl_is_method_instance(method))
6324+
method = ((jl_method_instance_t*)method)->def.value;
63216325
if (jl_is_method(method))
63226326
method = (jl_value_t*)((jl_method_t*)method)->name;
63236327
if (jl_is_symbol(method))

src/dump.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,7 +1656,7 @@ static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc
16561656
{
16571657
assert(!ios_eof(s->s));
16581658
jl_value_t *v;
1659-
size_t i, n;
1659+
size_t n;
16601660
uintptr_t pos;
16611661
uint8_t tag = read_uint8(s->s);
16621662
if (tag > LAST_TAG)
@@ -1774,14 +1774,6 @@ static jl_value_t *jl_deserialize_value(jl_serializer_state *s, jl_value_t **loc
17741774
arraylist_push(&backref_list, v);
17751775
ios_readall(s->s, jl_string_data(v), n);
17761776
return v;
1777-
case TAG_LINEINFO:
1778-
v = jl_new_struct_uninit(jl_lineinfonode_type);
1779-
arraylist_push(&backref_list, v);
1780-
for (i = 0; i < jl_datatype_nfields(jl_lineinfonode_type); i++) {
1781-
size_t offs = jl_field_offset(jl_lineinfonode_type, i);
1782-
set_nth_field(jl_lineinfonode_type, (void*)v, i, jl_deserialize_value(s, (jl_value_t**)((char*)v + offs)));
1783-
}
1784-
return v;
17851777
case TAG_DATATYPE:
17861778
pos = backref_list.len;
17871779
arraylist_push(&backref_list, NULL);

src/jltypes.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,8 +2193,9 @@ void jl_init_types(void) JL_GC_DISABLED
21932193

21942194
jl_lineinfonode_type =
21952195
jl_new_datatype(jl_symbol("LineInfoNode"), core, jl_any_type, jl_emptysvec,
2196-
jl_perm_symsvec(4, "method", "file", "line", "inlined_at"),
2197-
jl_svec(4, jl_any_type, jl_symbol_type, jl_long_type, jl_long_type), 0, 0, 4);
2196+
jl_perm_symsvec(5, "module", "method", "file", "line", "inlined_at"),
2197+
jl_svec(5, jl_module_type, jl_any_type, jl_symbol_type, jl_long_type, jl_long_type),
2198+
0, 0, 5);
21982199

21992200
jl_gotonode_type =
22002201
jl_new_datatype(jl_symbol("GotoNode"), core, jl_any_type, jl_emptysvec,

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ JL_EXTENSION typedef union {
252252
typedef struct _jl_method_instance_t jl_method_instance_t;
253253

254254
typedef struct _jl_line_info_node_t {
255+
struct _jl_module_t *module;
255256
jl_value_t *method;
256257
jl_sym_t *file;
257258
intptr_t line;

src/julia_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e,
476476
jl_svec_t *sparam_vals);
477477
int jl_is_toplevel_only_expr(jl_value_t *e) JL_NOTSAFEPOINT;
478478
jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule);
479-
void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_value_t *name);
479+
void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_module_t *mod, jl_value_t *name);
480480

481481
jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world);
482482
jl_value_t *jl_gf_invoke(jl_value_t *types, jl_value_t *f, jl_value_t **args, size_t nargs);

src/method.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ jl_code_info_t *jl_new_code_info_from_ir(jl_expr_t *ir)
356356
return src;
357357
}
358358

359-
void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_value_t *name)
359+
void jl_linenumber_to_lineinfo(jl_code_info_t *ci, jl_module_t *mod, jl_value_t *name)
360360
{
361361
jl_array_t *li = (jl_array_t*)ci->linetable;
362362
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)
366366
jl_value_t *ln = jl_array_ptr_ref(li, i);
367367
if (jl_is_linenode(ln)) {
368368
rt = jl_box_long(jl_linenode_line(ln));
369-
rt = jl_new_struct(jl_lineinfonode_type, name, jl_linenode_file(ln), rt, jl_box_long(0));
369+
rt = jl_new_struct(jl_lineinfonode_type, mod, name, jl_linenode_file(ln), rt, jl_box_long(0));
370370
jl_array_ptr_set(li, i, rt);
371371
}
372372
else if (jl_is_expr(ln) && ((jl_expr_t*)ln)->head == line_sym && jl_expr_nargs(ln) == 3) {
373-
rt = jl_new_struct(jl_lineinfonode_type, jl_symbol("macro expansion"),
373+
rt = jl_new_struct(jl_lineinfonode_type, mod, jl_symbol("macro expansion"),
374374
jl_exprarg(ln, 1), jl_exprarg(ln, 0), jl_exprarg(ln, 2));
375375
jl_array_ptr_set(li, i, rt);
376376
}
@@ -461,7 +461,7 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *linfo)
461461
ptls->in_pure_callback = last_in;
462462
jl_lineno = last_lineno;
463463
ptls->world_age = last_age;
464-
jl_linenumber_to_lineinfo(func, (jl_value_t*)def->name);
464+
jl_linenumber_to_lineinfo(func, def->module, (jl_value_t*)def->name);
465465
}
466466
JL_CATCH {
467467
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)
514514
}
515515
m->called = called;
516516
m->pure = src->pure;
517-
jl_linenumber_to_lineinfo(src, (jl_value_t*)m->name);
517+
jl_linenumber_to_lineinfo(src, m->module, (jl_value_t*)m->name);
518518

519519
jl_array_t *copy = NULL;
520520
jl_svec_t *sparam_vars = jl_outer_unionall_vars(m->sig);

0 commit comments

Comments
 (0)