Skip to content

Commit 54d5f54

Browse files
committed
JIT: record line info at continuation labels after function splits
Add current_line tracking to the compiler state and `record_continuation_line/3` to emit line info at continuation points. Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 3dbb496 commit 54d5f54

1 file changed

Lines changed: 28 additions & 9 deletions

File tree

libs/jit/src/jit.erl

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585

8686
-record(state, {
8787
line_offsets :: [{integer(), integer()}],
88+
current_line :: integer() | undefined,
8889
labels_count :: pos_integer(),
8990
atom_resolver :: fun((integer()) -> atom()),
9091
literal_resolver :: fun((integer()) -> any()),
@@ -136,6 +137,7 @@ compile(
136137
) when OpcodeMax =< ?OPCODE_MAX ->
137138
State0 = #state{
138139
line_offsets = [],
140+
current_line = undefined,
139141
labels_count = LabelsCount,
140142
atom_resolver = AtomResolver,
141143
literal_resolver = LiteralResolver,
@@ -296,11 +298,12 @@ first_pass(<<?OP_CALL_EXT, Rest0/binary>>, MMod, MSt0, State0) ->
296298
{Index, Rest2} = decode_literal(Rest1),
297299
?TRACE("OP_CALL_EXT ~p, ~p\n", [Arity, Index]),
298300
MSt1 = MMod:decrement_reductions_and_maybe_schedule_next(MSt0),
301+
State1 = record_continuation_line(MMod, MSt1, State0),
299302
MSt2 = MMod:call_primitive_with_cp(MSt1, ?PRIM_CALL_EXT, [
300303
ctx, jit_state, offset, Arity, Index, ?CALL_EXT_NO_DEALLOC_MFA
301304
]),
302305
?ASSERT_ALL_NATIVE_FREE(MSt2),
303-
first_pass(Rest2, MMod, MSt2, State0);
306+
first_pass(Rest2, MMod, MSt2, State1);
304307
% 8
305308
first_pass(<<?OP_CALL_EXT_LAST, Rest0/binary>>, MMod, MSt0, State0) ->
306309
?ASSERT_ALL_NATIVE_FREE(MSt0),
@@ -309,11 +312,12 @@ first_pass(<<?OP_CALL_EXT_LAST, Rest0/binary>>, MMod, MSt0, State0) ->
309312
{NWords, Rest3} = decode_literal(Rest2),
310313
?TRACE("OP_CALL_EXT_LAST ~p, ~p, ~p\n", [Arity, Index, NWords]),
311314
MSt1 = MMod:decrement_reductions_and_maybe_schedule_next(MSt0),
315+
State1 = record_continuation_line(MMod, MSt1, State0),
312316
MSt2 = MMod:call_primitive_last(MSt1, ?PRIM_CALL_EXT, [
313317
ctx, jit_state, offset, Arity, Index, NWords
314318
]),
315319
?ASSERT_ALL_NATIVE_FREE(MSt2),
316-
first_pass(Rest3, MMod, MSt2, State0);
320+
first_pass(Rest3, MMod, MSt2, State1);
317321
% 9
318322
first_pass(<<?OP_BIF0, Rest0/binary>>, MMod, MSt0, State0) ->
319323
?ASSERT_ALL_NATIVE_FREE(MSt0),
@@ -1033,13 +1037,14 @@ first_pass(<<?OP_CALL_FUN, Rest0/binary>>, MMod, MSt0, State0) ->
10331037
{ArgsCount, Rest1} = decode_literal(Rest0),
10341038
?TRACE("OP_CALL_FUN ~p\n", [ArgsCount]),
10351039
MSt1 = MMod:decrement_reductions_and_maybe_schedule_next(MSt0),
1040+
State1a = record_continuation_line(MMod, MSt1, State0),
10361041
{MSt2, FuncReg} = read_any_xreg(ArgsCount, MMod, MSt1),
10371042
{MSt3, Reg} = verify_is_function(FuncReg, MMod, MSt2),
10381043
MSt4 = MMod:call_primitive_with_cp(MSt3, ?PRIM_CALL_FUN, [
10391044
ctx, jit_state, offset, {free, Reg}, ArgsCount
10401045
]),
10411046
?ASSERT_ALL_NATIVE_FREE(MSt4),
1042-
first_pass(Rest1, MMod, MSt4, State0);
1047+
first_pass(Rest1, MMod, MSt4, State1a);
10431048
% 77
10441049
first_pass(<<?OP_IS_FUNCTION, Rest0/binary>>, MMod, MSt0, State0) ->
10451050
?ASSERT_ALL_NATIVE_FREE(MSt0),
@@ -1056,11 +1061,12 @@ first_pass(<<?OP_CALL_EXT_ONLY, Rest0/binary>>, MMod, MSt0, State0) ->
10561061
{Index, Rest2} = decode_literal(Rest1),
10571062
?TRACE("OP_CALL_EXT_ONLY ~p, ~p\n", [Arity, Index]),
10581063
MSt1 = MMod:decrement_reductions_and_maybe_schedule_next(MSt0),
1064+
State1 = record_continuation_line(MMod, MSt1, State0),
10591065
MSt2 = MMod:call_primitive_last(MSt1, ?PRIM_CALL_EXT, [
10601066
ctx, jit_state, offset, Arity, Index, ?CALL_EXT_NO_DEALLOC
10611067
]),
10621068
?ASSERT_ALL_NATIVE_FREE(MSt2),
1063-
first_pass(Rest2, MMod, MSt2, State0);
1069+
first_pass(Rest2, MMod, MSt2, State1);
10641070
% 96
10651071
first_pass(<<?OP_FMOVE, ?COMPACT_EXTENDED_FP_REGISTER, Rest0/binary>>, MMod, MSt0, State0) ->
10661072
?ASSERT_ALL_NATIVE_FREE(MSt0),
@@ -1188,6 +1194,7 @@ first_pass(<<?OP_APPLY, Rest0/binary>>, MMod, MSt0, State0) ->
11881194
{Arity, Rest1} = decode_literal(Rest0),
11891195
?TRACE("OP_APPLY ~p\n", [Arity]),
11901196
MSt1 = MMod:decrement_reductions_and_maybe_schedule_next(MSt0),
1197+
State1a = record_continuation_line(MMod, MSt1, State0),
11911198
{MSt2, Module} = read_any_xreg(Arity, MMod, MSt1),
11921199
{MSt3, Function} = read_any_xreg(Arity + 1, MMod, MSt2),
11931200
MSt4 = verify_is_atom(Module, 0, MMod, MSt3),
@@ -1196,14 +1203,15 @@ first_pass(<<?OP_APPLY, Rest0/binary>>, MMod, MSt0, State0) ->
11961203
ctx, jit_state, offset, {free, Module}, {free, Function}, Arity
11971204
]),
11981205
?ASSERT_ALL_NATIVE_FREE(MSt6),
1199-
first_pass(Rest1, MMod, MSt6, State0);
1206+
first_pass(Rest1, MMod, MSt6, State1a);
12001207
% 113
12011208
first_pass(<<?OP_APPLY_LAST, Rest0/binary>>, MMod, MSt0, State0) ->
12021209
?ASSERT_ALL_NATIVE_FREE(MSt0),
12031210
{Arity, Rest1} = decode_literal(Rest0),
12041211
{NWords, Rest2} = decode_literal(Rest1),
12051212
?TRACE("OP_APPLY_LAST ~p, ~p\n", [Arity, NWords]),
12061213
MSt1 = MMod:decrement_reductions_and_maybe_schedule_next(MSt0),
1214+
State1 = record_continuation_line(MMod, MSt1, State0),
12071215
{MSt2, Module} = read_any_xreg(Arity, MMod, MSt1),
12081216
{MSt3, Function} = read_any_xreg(Arity + 1, MMod, MSt2),
12091217
MSt4 = verify_is_atom(Module, 0, MMod, MSt3),
@@ -1214,7 +1222,7 @@ first_pass(<<?OP_APPLY_LAST, Rest0/binary>>, MMod, MSt0, State0) ->
12141222
ctx, jit_state, offset, {free, Module}, {free, Function}, Arity
12151223
]),
12161224
?ASSERT_ALL_NATIVE_FREE(MSt8),
1217-
first_pass(Rest2, MMod, MSt8, State0);
1225+
first_pass(Rest2, MMod, MSt8, State1);
12181226
% 114
12191227
first_pass(<<?OP_IS_BOOLEAN, Rest0/binary>>, MMod, MSt0, State0) ->
12201228
?ASSERT_ALL_NATIVE_FREE(MSt0),
@@ -1729,7 +1737,8 @@ first_pass(
17291737
MSt0 = ?DWARF_LINE(MMod, MSt, Line),
17301738
Offset = MMod:offset(MSt0),
17311739
first_pass(Rest1, MMod, MSt0, State0#state{
1732-
line_offsets = [{Line, Offset} | AccLines]
1740+
line_offsets = [{Line, Offset} | AccLines],
1741+
current_line = Line
17331742
});
17341743
% 154
17351744
first_pass(<<?OP_PUT_MAP_ASSOC, Rest0/binary>>, MMod, MSt0, State0) ->
@@ -2446,13 +2455,14 @@ first_pass(<<?OP_CALL_FUN2, Rest0/binary>>, MMod, MSt0, State0) ->
24462455
% We ignore Tag (could be literal 0 or atom unsafe)
24472456
MSt2 = MMod:free_native_registers(MSt1, [Tag]),
24482457
MSt3 = MMod:decrement_reductions_and_maybe_schedule_next(MSt2),
2449-
{MSt4, Fun, Rest3} = decode_typed_compact_term(Rest2, MMod, MSt3, State0),
2458+
State1a = record_continuation_line(MMod, MSt3, State0),
2459+
{MSt4, Fun, Rest3} = decode_typed_compact_term(Rest2, MMod, MSt3, State1a),
24502460
{MSt5, Reg} = verify_is_function(Fun, MMod, MSt4),
24512461
MSt6 = MMod:call_primitive_with_cp(MSt5, ?PRIM_CALL_FUN, [
24522462
ctx, jit_state, offset, {free, Reg}, ArgsCount
24532463
]),
24542464
?ASSERT_ALL_NATIVE_FREE(MSt6),
2455-
first_pass(Rest3, MMod, MSt6, State0);
2465+
first_pass(Rest3, MMod, MSt6, State1a);
24562466
% 180
24572467
first_pass(<<?OP_BADRECORD, Rest0/binary>>, MMod, MSt0, State0) ->
24582468
?ASSERT_ALL_NATIVE_FREE(MSt0),
@@ -4518,6 +4528,15 @@ memory_ensure_free_with_extra_root(ExtraRoot, Live, Size, MMod, MSt0) when is_tu
45184528
MSt4 = MMod:move_to_vm_register(MSt3, ExtraRootXReg, ExtraRoot),
45194529
{MSt4, ExtraRoot}.
45204530

4531+
%% Record the current line at the current offset, so that continuation labels
4532+
%% created by function-splitting operations (WASM) have line info.
4533+
%% On native backends this is a no-op as the offset is within the existing range.
4534+
record_continuation_line(_MMod, _MSt, #state{current_line = undefined} = State) ->
4535+
State;
4536+
record_continuation_line(MMod, MSt, #state{current_line = Line, line_offsets = AccLines} = State) ->
4537+
Offset = MMod:offset(MSt),
4538+
State#state{line_offsets = [{Line, Offset} | AccLines]}.
4539+
45214540
second_pass(MMod, MSt0, #state{line_offsets = Lines}) ->
45224541
?TRACE("SECOND PASS -- ~B lines\n", [length(Lines)]),
45234542
% Add extra function that returns labels and line information

0 commit comments

Comments
 (0)