Skip to content

Commit b9b3ed5

Browse files
committed
Fix #15107: Avoid re-emitting a LineNumber after only LabelNodes.
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.
1 parent af95ceb commit b9b3ed5

File tree

3 files changed

+29
-29
lines changed

3 files changed

+29
-29
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala

+7-1
Original file line numberDiff line numberDiff line change
@@ -556,11 +556,17 @@ trait BCodeSkelBuilder extends BCodeHelpers {
556556
case _ => false } )
557557
}
558558
def lineNumber(tree: Tree): Unit = {
559+
@tailrec
560+
def getNonLabelNode(a: asm.tree.AbstractInsnNode): asm.tree.AbstractInsnNode = a match {
561+
case a: asm.tree.LabelNode => getNonLabelNode(a.getPrevious)
562+
case _ => a
563+
}
564+
559565
if (!emitLines || !tree.span.exists) return;
560566
val nr = ctx.source.offsetToLine(tree.span.point) + 1
561567
if (nr != lastEmittedLineNr) {
562568
lastEmittedLineNr = nr
563-
lastInsn match {
569+
getNonLabelNode(lastInsn) match {
564570
case lnn: asm.tree.LineNumberNode =>
565571
// overwrite previous landmark as no instructions have been emitted for it
566572
lnn.line = nr

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

-2
Original file line numberDiff line numberDiff line change
@@ -1622,7 +1622,6 @@ class DottyBytecodeTests extends DottyBytecodeTest {
16221622
val instructions = instructionsFromMethod(method).filter(_.isInstanceOf[LineNumber])
16231623

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

16661665
val expected = List(
1667-
LineNumber(2, Label(0)),
16681666
LineNumber(3, Label(0)),
16691667
LineNumber(4, Label(5)), // case a if a == 3 =>
16701668
LineNumber(5, Label(15)),

compiler/test/dotty/tools/backend/jvm/InlineBytecodeTests.scala

+22-26
Original file line numberDiff line numberDiff line change
@@ -163,28 +163,27 @@ class InlineBytecodeTests extends DottyBytecodeTest {
163163
val expected =
164164
List(
165165
Label(0),
166-
LineNumber(6, Label(0)),
167166
LineNumber(3, Label(0)),
168167
VarOp(ALOAD, 0),
169168
Ldc(LDC, "tracking"),
170169
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
171-
Label(6),
172-
LineNumber(8, Label(6)),
170+
Label(5),
171+
LineNumber(8, Label(5)),
173172
VarOp(ALOAD, 0),
174173
Ldc(LDC, "abc"),
175174
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
176-
Label(11),
177-
LineNumber(3, Label(11)),
175+
Label(10),
176+
LineNumber(3, Label(10)),
178177
VarOp(ALOAD, 0),
179178
Ldc(LDC, "tracking"),
180179
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
181-
Label(16),
182-
LineNumber(10, Label(16)),
180+
Label(15),
181+
LineNumber(10, Label(15)),
183182
VarOp(ALOAD, 0),
184183
Ldc(LDC, "inner"),
185184
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
186185
Op(RETURN),
187-
Label(22)
186+
Label(21)
188187
)
189188
assert(instructions == expected,
190189
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
@@ -228,23 +227,22 @@ class InlineBytecodeTests extends DottyBytecodeTest {
228227
val expected =
229228
List(
230229
Label(0),
231-
LineNumber(12, Label(0)),
232230
LineNumber(7, Label(0)),
233231
VarOp(ALOAD, 0),
234232
Ldc(LDC, "tracking"),
235233
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
236-
Label(6),
237-
LineNumber(3, Label(6)),
234+
Label(5),
235+
LineNumber(3, Label(5)),
238236
VarOp(ALOAD, 0),
239237
Ldc(LDC, "tracking2"),
240238
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
241-
Label(11),
242-
LineNumber(14, Label(11)),
239+
Label(10),
240+
LineNumber(14, Label(10)),
243241
VarOp(ALOAD, 0),
244242
Ldc(LDC, "abc"),
245243
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
246244
Op(RETURN),
247-
Label(17)
245+
Label(16)
248246
)
249247
assert(instructions == expected,
250248
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
@@ -288,23 +286,22 @@ class InlineBytecodeTests extends DottyBytecodeTest {
288286
val expected =
289287
List(
290288
Label(0),
291-
LineNumber(12, Label(0)),
292289
LineNumber(3, Label(0)),
293290
VarOp(ALOAD, 0),
294291
Ldc(LDC, "tracking2"),
295292
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
296-
Label(6),
297-
LineNumber(8, Label(6)),
293+
Label(5),
294+
LineNumber(8, Label(5)),
298295
VarOp(ALOAD, 0),
299296
Ldc(LDC, "fgh"),
300297
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
301-
Label(11),
302-
LineNumber(14, Label(11)),
298+
Label(10),
299+
LineNumber(14, Label(10)),
303300
VarOp(ALOAD, 0),
304301
Ldc(LDC, "abc"),
305302
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
306303
Op(RETURN),
307-
Label(17)
304+
Label(16)
308305
)
309306
assert(instructions == expected,
310307
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
@@ -349,23 +346,22 @@ class InlineBytecodeTests extends DottyBytecodeTest {
349346
val expected =
350347
List(
351348
Label(0),
352-
LineNumber(13, Label(0)),
353349
LineNumber(3, Label(0)),
354350
VarOp(ALOAD, 0),
355351
Ldc(LDC, "tracking2"),
356352
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
357-
Label(6),
358-
LineNumber(3, Label(6)),
353+
Label(5),
354+
LineNumber(3, Label(5)),
359355
VarOp(ALOAD, 0),
360356
Ldc(LDC, "tracking2"),
361357
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
362-
Label(11),
363-
LineNumber(15, Label(11)),
358+
Label(10),
359+
LineNumber(15, Label(10)),
364360
VarOp(ALOAD, 0),
365361
Ldc(LDC, "abc"),
366362
Invoke(INVOKEVIRTUAL, "Foo", "foo", "(Ljava/lang/String;)V", false),
367363
Op(RETURN),
368-
Label(17)
364+
Label(16)
369365
)
370366
assert(instructions == expected,
371367
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))

0 commit comments

Comments
 (0)