Skip to content

Commit

Permalink
Fix #15107: Avoid re-emitting a LineNumber after only LabelNodes. (#1…
Browse files Browse the repository at this point in the history
…6813)

There was already some deduplication code to avoid consecutive
`LineNumber` nodes. However, it can happen that `LabelNode`s appear
in-between. In that case, we also want to deduplicate the `LineNumber`s,
since labels do not actually contribute to the final bytecode.
  • Loading branch information
sjrd authored Feb 3, 2023
2 parents dd92c85 + b9b3ed5 commit fb584eb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 29 deletions.
8 changes: 7 additions & 1 deletion compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -556,11 +556,17 @@ trait BCodeSkelBuilder extends BCodeHelpers {
case _ => false } )
}
def lineNumber(tree: Tree): Unit = {
@tailrec
def getNonLabelNode(a: asm.tree.AbstractInsnNode): asm.tree.AbstractInsnNode = a match {
case a: asm.tree.LabelNode => getNonLabelNode(a.getPrevious)
case _ => a
}

if (!emitLines || !tree.span.exists) return;
val nr = ctx.source.offsetToLine(tree.span.point) + 1
if (nr != lastEmittedLineNr) {
lastEmittedLineNr = nr
lastInsn match {
getNonLabelNode(lastInsn) match {
case lnn: asm.tree.LineNumberNode =>
// overwrite previous landmark as no instructions have been emitted for it
lnn.line = nr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,6 @@ class DottyBytecodeTests extends DottyBytecodeTest {
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])

val expected = List(
LineNumber(2, Label(0)),
LineNumber(3, Label(0)),
LineNumber(4, Label(5)), // case y =>
LineNumber(5, Label(9)),
Expand Down Expand Up @@ -1664,7 +1663,6 @@ class DottyBytecodeTests extends DottyBytecodeTest {
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])

val expected = List(
LineNumber(2, Label(0)),
LineNumber(3, Label(0)),
LineNumber(4, Label(5)), // case a if a == 3 =>
LineNumber(5, Label(15)),
Expand Down
48 changes: 22 additions & 26 deletions compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,28 +163,27 @@ class InlineBytecodeTests extends DottyBytecodeTest {
val expected =
List(
Label(0),
LineNumber(6, Label(0)),
LineNumber(3, Label(0)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(6),
LineNumber(8, Label(6)),
Label(5),
LineNumber(8, Label(5)),
VarOp(ALOAD, 0),
Ldc(LDC, "abc"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(11),
LineNumber(3, Label(11)),
Label(10),
LineNumber(3, Label(10)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(16),
LineNumber(10, Label(16)),
Label(15),
LineNumber(10, Label(15)),
VarOp(ALOAD, 0),
Ldc(LDC, "inner"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Op(RETURN),
Label(22)
Label(21)
)
assert(instructions == expected,
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
Expand Down Expand Up @@ -228,23 +227,22 @@ class InlineBytecodeTests extends DottyBytecodeTest {
val expected =
List(
Label(0),
LineNumber(12, Label(0)),
LineNumber(7, Label(0)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(6),
LineNumber(3, Label(6)),
Label(5),
LineNumber(3, Label(5)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking2"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(11),
LineNumber(14, Label(11)),
Label(10),
LineNumber(14, Label(10)),
VarOp(ALOAD, 0),
Ldc(LDC, "abc"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Op(RETURN),
Label(17)
Label(16)
)
assert(instructions == expected,
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
Expand Down Expand Up @@ -288,23 +286,22 @@ class InlineBytecodeTests extends DottyBytecodeTest {
val expected =
List(
Label(0),
LineNumber(12, Label(0)),
LineNumber(3, Label(0)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking2"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(6),
LineNumber(8, Label(6)),
Label(5),
LineNumber(8, Label(5)),
VarOp(ALOAD, 0),
Ldc(LDC, "fgh"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(11),
LineNumber(14, Label(11)),
Label(10),
LineNumber(14, Label(10)),
VarOp(ALOAD, 0),
Ldc(LDC, "abc"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Op(RETURN),
Label(17)
Label(16)
)
assert(instructions == expected,
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
Expand Down Expand Up @@ -349,23 +346,22 @@ class InlineBytecodeTests extends DottyBytecodeTest {
val expected =
List(
Label(0),
LineNumber(13, Label(0)),
LineNumber(3, Label(0)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking2"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(6),
LineNumber(3, Label(6)),
Label(5),
LineNumber(3, Label(5)),
VarOp(ALOAD, 0),
Ldc(LDC, "tracking2"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Label(11),
LineNumber(15, Label(11)),
Label(10),
LineNumber(15, Label(10)),
VarOp(ALOAD, 0),
Ldc(LDC, "abc"),
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
Op(RETURN),
Label(17)
Label(16)
)
assert(instructions == expected,
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
Expand Down

0 comments on commit fb584eb

Please sign in to comment.