Skip to content

Commit 07bec48

Browse files
committed
Merge branch 'maint'
* maint: jit: func_line alignment for line table
2 parents c9601cd + 10bfe4a commit 07bec48

File tree

7 files changed

+66
-35
lines changed

7 files changed

+66
-35
lines changed

erts/emulator/beam/jit/arm/beam_asm.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,10 @@ class BeamModuleAssembler : public BeamAssembler,
14011401
* the current code position is unreachable. */
14021402
void flush_pending_labels();
14031403

1404+
/* Move past the `last_error_offset` if necessary for the next instruction
1405+
* to be properly aligned (e.g. for line mappings). */
1406+
void flush_last_error();
1407+
14041408
/* Calls the given shared fragment, ensuring that the redzone is unused and
14051409
* that the return address forms a valid CP. */
14061410
template<typename Any>

erts/emulator/beam/jit/arm/beam_asm_module.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,11 @@ void BeamModuleAssembler::emit_aligned_label(const ArgLabel &Label,
376376
emit_label(Label);
377377
}
378378

379+
void BeamModuleAssembler::emit_i_func_label(const ArgLabel &Label) {
380+
flush_last_error();
381+
emit_aligned_label(Label, ArgVal(ArgVal::Word, sizeof(UWord)));
382+
}
383+
379384
void BeamModuleAssembler::emit_on_load() {
380385
on_load = current_label;
381386
}
@@ -430,22 +435,12 @@ void BeamModuleAssembler::emit_int_code_end() {
430435
void BeamModuleAssembler::emit_line(const ArgWord &Loc) {
431436
/* There is no need to align the line instruction. In the loaded code, the
432437
* type of the pointer will be void* and that pointer will only be used in
433-
* comparisons.
434-
*
435-
* We only need to do something when there's a possibility of raising an
436-
* exception at the very end of the preceding instruction (and thus
437-
* pointing at the start of this one). If we were to do nothing, the error
438-
* would erroneously refer to this instead of the preceding line.
439-
*
440-
* Since line addresses are taken _after_ line instructions we can avoid
441-
* this by adding a nop when we detect this condition. */
442-
if (a.offset() == last_error_offset) {
443-
a.nop();
444-
}
438+
* comparisons. */
439+
440+
flush_last_error();
445441
}
446442

447443
void BeamModuleAssembler::emit_func_line(const ArgWord &Loc) {
448-
emit_line(Loc);
449444
}
450445

451446
void BeamModuleAssembler::emit_empty_func_line() {
@@ -817,3 +812,16 @@ void BeamModuleAssembler::emit_constant(const Constant &constant) {
817812
}
818813
}
819814
}
815+
816+
void BeamModuleAssembler::flush_last_error() {
817+
/* When there's a possibility of raising an exception at the very end of the
818+
* preceding instruction (and thus pointing at the start of this one) and
819+
* this instruction has a new line registered, the error would erroneously
820+
* refer to this instead of the preceding line.
821+
*
822+
* By adding a nop when we detect this condition, the error will correctly
823+
* refer to the preceding line. */
824+
if (a.offset() == last_error_offset) {
825+
a.nop();
826+
}
827+
}

erts/emulator/beam/jit/arm/ops.tab

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ label L
4242

4343
# An label aligned to a certain boundary. This is used in two cases:
4444
#
45-
# * When the label points to the start of a function, as the ErtsCodeInfo
46-
# struct must be word-aligned.
45+
# * When the label points to the start of a function. See `i_func_label`.
4746
# * When the address is stored on the stack or otherwise needs to be properly
4847
# tagged as a continuation pointer.
4948
aligned_label L t
5049

50+
# A label indicating the start of a function. The label is word-aligned as is
51+
# required by the ErtsCodeInfo struct.
52+
i_func_label L
53+
5154
i_func_info I a a I
5255
int_code_end
5356
nif_start
@@ -904,8 +907,8 @@ int_func_start Func_Label Func_Line M F A |
904907
func_prologue Entry_Label Entry_Line |
905908
is_mfa_bif(M, F, A) =>
906909
i_flush_stubs |
910+
i_func_label Func_Label |
907911
func_line Func_Line |
908-
aligned_label Func_Label u=8 |
909912
i_func_info Func_Label M F A |
910913
aligned_label Entry_Label u=4 |
911914
i_breakpoint_trampoline |
@@ -915,8 +918,8 @@ int_func_start Func_Label Func_Line M F A |
915918
int_func_start Func_Label Func_Line M F A |
916919
func_prologue Entry_Label Entry_Line =>
917920
i_flush_stubs |
921+
i_func_label Func_Label |
918922
func_line Func_Line |
919-
aligned_label Func_Label u=8 |
920923
i_func_info Func_Label M F A |
921924
aligned_label Entry_Label u=4 |
922925
i_breakpoint_trampoline |

erts/emulator/beam/jit/asm_load.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,8 @@ int beam_load_emit_op(LoaderState *stp, BeamOp *tmp_op) {
505505
break;
506506
case 'L': /* Define label */
507507
ASSERT(stp->specific_op == op_label_L ||
508-
stp->specific_op == op_aligned_label_Lt);
508+
stp->specific_op == op_aligned_label_Lt ||
509+
stp->specific_op == op_i_func_label_L);
509510
BeamLoadVerifyTag(stp, tag, TAG_u);
510511
stp->last_label = curr->val;
511512
if (stp->last_label < 0 ||

erts/emulator/beam/jit/x86/beam_asm.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,10 @@ class BeamModuleAssembler : public BeamAssembler,
14241424
* appropriate address before jumping there. */
14251425
const Label &resolve_fragment(void (*fragment)());
14261426

1427+
/* Move past the `last_error_offset` if necessary for the next instruction
1428+
* to be properly aligned (e.g. for line mappings). */
1429+
void flush_last_error();
1430+
14271431
void safe_fragment_call(void (*fragment)()) {
14281432
emit_assert_redzone_unused();
14291433
a.call(resolve_fragment(fragment));

erts/emulator/beam/jit/x86/beam_asm_module.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@ void BeamModuleAssembler::emit_aligned_label(const ArgLabel &Label,
342342
emit_label(Label);
343343
}
344344

345+
void BeamModuleAssembler::emit_i_func_label(const ArgLabel &Label) {
346+
flush_last_error();
347+
emit_aligned_label(Label, ArgVal(ArgVal::Word, sizeof(UWord)));
348+
}
349+
345350
void BeamModuleAssembler::emit_on_load() {
346351
on_load = current_label;
347352
}
@@ -362,22 +367,12 @@ void BeamModuleAssembler::emit_int_code_end() {
362367
void BeamModuleAssembler::emit_line(const ArgWord &Loc) {
363368
/* There is no need to align the line instruction. In the loaded code, the
364369
* type of the pointer will be void* and that pointer will only be used in
365-
* comparisons.
366-
*
367-
* We only need to do something when there's a possibility of raising an
368-
* exception at the very end of the preceding instruction (and thus
369-
* pointing at the start of this one). If we were to do nothing, the error
370-
* would erroneously refer to this instead of the preceding line.
371-
*
372-
* Since line addresses are taken _after_ line instructions we can avoid
373-
* this by adding a nop when we detect this condition. */
374-
if (a.offset() == last_error_offset) {
375-
a.nop();
376-
}
370+
* comparisons. */
371+
372+
flush_last_error();
377373
}
378374

379375
void BeamModuleAssembler::emit_func_line(const ArgWord &Loc) {
380-
emit_line(Loc);
381376
}
382377

383378
void BeamModuleAssembler::emit_empty_func_line() {
@@ -416,3 +411,16 @@ const Label &BeamModuleAssembler::resolve_fragment(void (*fragment)()) {
416411

417412
return it->second;
418413
}
414+
415+
void BeamModuleAssembler::flush_last_error() {
416+
/* When there's a possibility of raising an exception at the very end of the
417+
* preceding instruction (and thus pointing at the start of this one) and
418+
* this instruction has a new line registered, the error would erroneously
419+
* refer to this instead of the preceding line.
420+
*
421+
* By adding a nop when we detect this condition, the error will correctly
422+
* refer to the preceding line. */
423+
if (a.offset() == last_error_offset) {
424+
a.nop();
425+
}
426+
}

erts/emulator/beam/jit/x86/ops.tab

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ label L
4242

4343
# An label aligned to a certain boundary. This is used in two cases:
4444
#
45-
# * When the label points to the start of a function, as the ErtsCodeInfo
46-
# struct must be word-aligned.
45+
# * When the label points to the start of a function. See `i_func_label`.
4746
# * When the address is stored on the stack or otherwise needs to be properly
4847
# tagged as a continuation pointer.
4948
aligned_label L t
5049

50+
# A label indicating the start of a function. The label is word-aligned as is
51+
# required by the ErtsCodeInfo struct.
52+
i_func_label L
53+
5154
i_func_info I a a I
5255
int_code_end
5356
nif_start
@@ -827,8 +830,8 @@ int_func_start Func_Label Func_Line M F A |
827830
int_func_start Func_Label Func_Line M F A |
828831
func_prologue Entry_Label Entry_Line |
829832
is_mfa_bif(M, F, A) =>
833+
i_func_label Func_Label |
830834
func_line Func_Line |
831-
aligned_label Func_Label u=8 |
832835
i_func_info Func_Label M F A |
833836
aligned_label Entry_Label u=4 |
834837
i_breakpoint_trampoline |
@@ -837,8 +840,8 @@ int_func_start Func_Label Func_Line M F A |
837840

838841
int_func_start Func_Label Func_Line M F A |
839842
func_prologue Entry_Label Entry_Line =>
843+
i_func_label Func_Label |
840844
func_line Func_Line |
841-
aligned_label Func_Label u=8 |
842845
i_func_info Func_Label M F A |
843846
aligned_label Entry_Label u=4 |
844847
i_breakpoint_trampoline |

0 commit comments

Comments
 (0)