Skip to content

Commit 6151792

Browse files
committed
wip
1 parent ea0e862 commit 6151792

File tree

3 files changed

+319
-38
lines changed

3 files changed

+319
-38
lines changed

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

Lines changed: 278 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -145,115 +145,355 @@ class InlineBytecodeTests extends DottyBytecodeTest {
145145
LineNumber(3, Label(0)),
146146
VarOp(ALOAD, 0),
147147
Ldc(LDC, "track"),
148+
Label(5),
149+
LineNumber(18, Label(5)),
148150
Op(ICONST_0),
151+
// TODO missing LineNumber(3, ...) and other below. It look like we do not emmit the position
152+
// of the invocation, instead we use the position of the last parameter (see `@Test def i4947a2`)
149153
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
150-
Label(7),
151-
LineNumber(4, Label(7)),
154+
Label(9),
155+
LineNumber(4, Label(9)),
152156
VarOp(ALOAD, 0),
153157
Ldc(LDC, "track"),
158+
Label(13),
159+
LineNumber(18, Label(13)),
154160
Op(ICONST_0),
155161
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
156-
Label(13),
157-
LineNumber(3, Label(13)),
162+
Label(17),
163+
LineNumber(3, Label(17)),
158164
VarOp(ALOAD, 0),
159165
Ldc(LDC, "track"),
166+
Label(21),
167+
LineNumber(19, Label(21)),
160168
Op(ICONST_2),
161169
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
162-
Label(19),
163-
LineNumber(4, Label(19)),
170+
Label(25),
171+
LineNumber(4, Label(25)),
164172
VarOp(ALOAD, 0),
165173
Ldc(LDC, "track"),
174+
Label(29),
175+
LineNumber(19, Label(29)),
166176
Op(ICONST_2),
167177
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
168-
Label(25),
169-
LineNumber(20, Label(25)),
178+
Label(33),
179+
LineNumber(20, Label(33)),
170180
VarOp(ALOAD, 0),
171181
Ldc(LDC, "main1"),
172182
Op(ICONST_M1),
173183
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
174-
Label(31),
175-
LineNumber(21, Label(31)),
184+
Label(39),
185+
LineNumber(21, Label(39)),
176186
VarOp(ALOAD, 0),
177187
Ldc(LDC, "main2"),
178188
Op(ICONST_M1),
179189
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
180-
Label(37),
181-
LineNumber(9, Label(37)),
190+
Label(45),
191+
LineNumber(19, Label(45)),
182192
Op(ICONST_2),
183-
Label(40),
184-
LineNumber(3, Label(40)),
193+
Label(48),
194+
LineNumber(3, Label(48)),
185195
VarOp(ALOAD, 0),
186196
Ldc(LDC, "track"),
197+
Label(52),
198+
LineNumber(9, Label(52)),
187199
Op(ICONST_1),
188200
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
189-
Label(46),
190-
LineNumber(4, Label(46)),
201+
Label(56),
202+
LineNumber(4, Label(56)),
191203
VarOp(ALOAD, 0),
192204
Ldc(LDC, "track"),
205+
Label(60),
206+
LineNumber(9, Label(60)),
193207
Op(ICONST_1),
194208
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
195-
Label(52),
196-
LineNumber(20, Label(52)),
209+
Label(64),
210+
LineNumber(20, Label(64)),
197211
VarOp(ALOAD, 0),
198212
Ldc(LDC, "main1"),
199213
Op(ICONST_M1),
200214
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
201-
Label(58),
202-
LineNumber(21, Label(58)),
215+
Label(70),
216+
LineNumber(21, Label(70)),
203217
VarOp(ALOAD, 0),
204218
Ldc(LDC, "main2"),
205219
Op(ICONST_M1),
206220
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
207-
Label(64),
208-
LineNumber(9, Label(64)),
221+
Label(76),
222+
LineNumber(9, Label(76)),
209223
Op(ICONST_1),
210-
Label(67),
211-
LineNumber(3, Label(67)),
224+
Label(79),
225+
LineNumber(3, Label(79)),
212226
VarOp(ALOAD, 0),
213227
Ldc(LDC, "track"),
228+
Label(83),
229+
LineNumber(9, Label(83)),
214230
Op(ICONST_0),
215231
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
216-
Label(73),
217-
LineNumber(4, Label(73)),
232+
Label(87),
233+
LineNumber(4, Label(87)),
218234
VarOp(ALOAD, 0),
219235
Ldc(LDC, "track"),
236+
Label(91),
237+
LineNumber(9, Label(91)),
220238
Op(ICONST_0),
221239
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
222-
Label(79),
223-
LineNumber(20, Label(79)),
240+
Label(95),
241+
LineNumber(20, Label(95)),
224242
VarOp(ALOAD, 0),
225243
Ldc(LDC, "main1"),
226244
Op(ICONST_M1),
227245
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
228-
Label(85),
229-
LineNumber(21, Label(85)),
246+
Label(101),
247+
LineNumber(21, Label(101)),
230248
VarOp(ALOAD, 0),
231249
Ldc(LDC, "main2"),
232250
Op(ICONST_M1),
233251
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(Ljava/lang/String;I)V", false),
252+
Label(107),
253+
LineNumber(7, Label(107)),
254+
Op(ICONST_1),
255+
Op(IMUL),
256+
Label(111),
257+
LineNumber(9, Label(111)),
258+
Op(IMUL),
259+
Op(POP),
260+
Label(115),
261+
LineNumber(7, Label(115)),
262+
Op(ICONST_1),
263+
Op(POP),
264+
Label(119),
265+
LineNumber(23, Label(119)),
266+
Op(RETURN),
267+
Label(122)
268+
)
269+
assert(instructions == expected,
270+
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
271+
272+
}
273+
}
274+
275+
@Test def i4947a2 = {
276+
val source = """class Foo {
277+
| inline def fact[T](inline i: Int)(f: => T): Int = {
278+
| printStack(i, "track") // line 3
279+
| printStack(i, "track") // line 4
280+
| f
281+
| if (i == 0)
282+
| 1 // line 7
283+
| else {
284+
| i * fact(i-1)(f) // line 9
285+
| }
286+
| }
287+
|
288+
| def printStack(i: Int, tag: String): Unit = { // line 13
289+
| println(s"$tag (i = $i): ${new Exception().getStackTrace().apply(1)}") // line 14
290+
| }
291+
|
292+
| def main(args: Array[String]): Unit = {
293+
| fact(0) { // line 18
294+
| fact(2) { // line 19
295+
| printStack(-1, "main1") // line 20
296+
| printStack(-1, "main2") // line 21
297+
| }
298+
| } // line 23
299+
| }
300+
|}
301+
""".stripMargin
302+
303+
checkBCode(source) { dir =>
304+
val clsIn = dir.lookupName("Foo.class", directory = false).input
305+
val clsNode = loadClassNode(clsIn, skipDebugInfo = false)
306+
307+
val track = clsNode.methods.asScala.find(_.name == "fact")
308+
assert(track.isEmpty, "method `fact` should have been erased")
309+
310+
val main = getMethod(clsNode, "main")
311+
val instructions = instructionsFromMethod(main)
312+
val expected =
313+
List(
314+
Label(0),
315+
LineNumber(17, Label(0)),
316+
LineNumber(3, Label(0)),
317+
VarOp(ALOAD, 0),
318+
Label(4),
319+
LineNumber(18, Label(4)),
320+
Op(ICONST_0),
321+
Label(7),
322+
LineNumber(3, Label(7)),
323+
Ldc(LDC, "track"),
324+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
325+
Label(11),
326+
LineNumber(4, Label(11)),
327+
VarOp(ALOAD, 0),
328+
Label(14),
329+
LineNumber(18, Label(14)),
330+
Op(ICONST_0),
331+
Label(17),
332+
LineNumber(4, Label(17)),
333+
Ldc(LDC, "track"),
334+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
335+
Label(21),
336+
LineNumber(3, Label(21)),
337+
VarOp(ALOAD, 0),
338+
Label(24),
339+
LineNumber(19, Label(24)),
340+
Op(ICONST_2),
341+
Label(27),
342+
LineNumber(3, Label(27)),
343+
Ldc(LDC, "track"),
344+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
345+
Label(31),
346+
LineNumber(4, Label(31)),
347+
VarOp(ALOAD, 0),
348+
Label(34),
349+
LineNumber(19, Label(34)),
350+
Op(ICONST_2),
351+
Label(37),
352+
LineNumber(4, Label(37)),
353+
Ldc(LDC, "track"),
354+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
355+
Label(41),
356+
LineNumber(20, Label(41)),
357+
VarOp(ALOAD, 0),
358+
Op(ICONST_M1),
359+
Ldc(LDC, "main1"),
360+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
361+
Label(47),
362+
LineNumber(21, Label(47)),
363+
VarOp(ALOAD, 0),
364+
Op(ICONST_M1),
365+
Ldc(LDC, "main2"),
366+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
367+
Label(53),
368+
LineNumber(19, Label(53)),
369+
Op(ICONST_2),
370+
Label(56),
371+
LineNumber(3, Label(56)),
372+
VarOp(ALOAD, 0),
373+
Label(59),
374+
LineNumber(9, Label(59)),
375+
Op(ICONST_1),
376+
Label(62),
377+
LineNumber(3, Label(62)),
378+
Ldc(LDC, "track"),
379+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
380+
Label(66),
381+
LineNumber(4, Label(66)),
382+
VarOp(ALOAD, 0),
383+
Label(69),
384+
LineNumber(9, Label(69)),
385+
Op(ICONST_1),
386+
Label(72),
387+
LineNumber(4, Label(72)),
388+
Ldc(LDC, "track"),
389+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
390+
Label(76),
391+
LineNumber(20, Label(76)),
392+
VarOp(ALOAD, 0),
393+
Op(ICONST_M1),
394+
Ldc(LDC, "main1"),
395+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
396+
Label(82),
397+
LineNumber(21, Label(82)),
398+
VarOp(ALOAD, 0),
399+
Op(ICONST_M1),
400+
Ldc(LDC, "main2"),
401+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
402+
Label(88),
403+
LineNumber(9, Label(88)),
404+
Op(ICONST_1),
234405
Label(91),
235-
LineNumber(7, Label(91)),
406+
LineNumber(3, Label(91)),
407+
VarOp(ALOAD, 0),
408+
Label(94),
409+
LineNumber(9, Label(94)),
410+
Op(ICONST_0),
411+
Label(97),
412+
LineNumber(3, Label(97)),
413+
Ldc(LDC, "track"),
414+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
415+
Label(101),
416+
LineNumber(4, Label(101)),
417+
VarOp(ALOAD, 0),
418+
Label(104),
419+
LineNumber(9, Label(104)),
420+
Op(ICONST_0),
421+
Label(107),
422+
LineNumber(4, Label(107)),
423+
Ldc(LDC, "track"),
424+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
425+
Label(111),
426+
LineNumber(20, Label(111)),
427+
VarOp(ALOAD, 0),
428+
Op(ICONST_M1),
429+
Ldc(LDC, "main1"),
430+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
431+
Label(117),
432+
LineNumber(21, Label(117)),
433+
VarOp(ALOAD, 0),
434+
Op(ICONST_M1),
435+
Ldc(LDC, "main2"),
436+
Invoke(INVOKEVIRTUAL, "Foo", "printStack", "(ILjava/lang/String;)V", false),
437+
Label(123),
438+
LineNumber(7, Label(123)),
236439
Op(ICONST_1),
237440
Op(IMUL),
238-
Label(95),
239-
LineNumber(9, Label(95)),
441+
Label(127),
442+
LineNumber(9, Label(127)),
240443
Op(IMUL),
241444
Op(POP),
242-
Label(99),
243-
LineNumber(7, Label(99)),
445+
Label(131),
446+
LineNumber(7, Label(131)),
244447
Op(ICONST_1),
245448
Op(POP),
246-
Label(103),
247-
LineNumber(23, Label(103)),
449+
Label(135),
450+
LineNumber(23, Label(135)),
248451
Op(RETURN),
249-
Label(106)
452+
Label(138)
250453
)
251454
assert(instructions == expected,
252455
"`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
253456

254457
}
255458
}
256459

460+
// @Test def i4947a3 = {
461+
// val source = """class Foo {
462+
// | inline def fun(tag: String): Unit = {
463+
// | printStack( // line 3
464+
// | tag // line 4
465+
// | )
466+
// | }
467+
// |
468+
// | def printStack(tag: String): Unit = { // line 8
469+
// | println(s"$tag: ${new Exception().getStackTrace().apply(1)}") // line 9
470+
// | }
471+
// |
472+
// | def main(args: Array[String]): Unit = { // line 12
473+
// | fun("track") // line 13
474+
// | }
475+
// |}
476+
// """.stripMargin
477+
//
478+
// checkBCode(source) { dir =>
479+
// val clsIn = dir.lookupName("Foo.class", directory = false).input
480+
// val clsNode = loadClassNode(clsIn, skipDebugInfo = false)
481+
//
482+
// val track = clsNode.methods.asScala.find(_.name == "fact")
483+
// assert(track.isEmpty, "method `fact` should have been erased")
484+
//
485+
// val main = getMethod(clsNode, "main")
486+
// val instructions = instructionsFromMethod(main)
487+
// val expected =
488+
// List(
489+
//
490+
// )
491+
// assert(instructions == expected,
492+
// "`track` was not properly inlined in `main`\n" + diffInstructions(instructions, expected))
493+
//
494+
// }
495+
// }
496+
257497
@Test def i4947b = {
258498
val source = """class Foo {
259499
| inline def track2[T](f: => T) <: T = {

0 commit comments

Comments
 (0)