8027142: Invokedynamic instructions don't get line number table entries
Summary: When emitting invokedynamic instruction, write pendingStatPos, if set, into the LineNumberTable. Invokedynamic itself does not set the pendingStatPos.
Reviewed-by: jjg, jrose, ksrini, vromero
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Fri Nov 08 17:39:33 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java Sat Nov 09 15:24:38 2013 +0100
@@ -483,17 +483,8 @@
/** Emit an invokedynamic instruction.
*/
public void emitInvokedynamic(int desc, Type mtype) {
- // N.B. this format is under consideration by the JSR 292 EG
int argsize = width(mtype.getParameterTypes());
- int prevPos = pendingStatPos;
- try {
- //disable line number generation (we could have used 'emit1', that
- //bypasses stackmap generation - which is needed for indy calls)
- pendingStatPos = Position.NOPOS;
- emitop(invokedynamic);
- } finally {
- pendingStatPos = prevPos;
- }
+ emitop(invokedynamic);
if (!alive) return;
emit2(desc);
emit2(0);
--- a/langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Fri Nov 08 17:39:33 2013 -0800
+++ b/langtools/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Sat Nov 09 15:24:38 2013 +0100
@@ -25,7 +25,7 @@
/*
* @test
- * @bug 8019486 8026861
+ * @bug 8019486 8026861 8027142
* @summary javac, generates erroneous LVT for a test case with lambda code
* @library /tools/javac/lib
* @build ToolBox
@@ -68,7 +68,14 @@
/* 22 */ " Runnable r4 = super :: notify;\n" +
/* 23 */ " }\n" +
/* 24 */ " private void foo() {}\n" +
- /* 25 */ "}";
+ /* 25 */ " void assignLambda() {\n" +
+ /* 26 */ " Runnable r = () -> { };\n" +
+ /* 27 */ " }\n" +
+ /* 28 */ " void callLambda(int i, Runnable r) {\n" +
+ /* 29 */ " callLambda(0,\n" +
+ /* 30 */ " () -> { });\n" +
+ /* 31 */ " }\n" +
+ /* 32 */ "}";
static final int[][] simpleLambdaExpectedLNT = {
// {line-number, start-pc},
@@ -102,6 +109,18 @@
{22, 0}, //number -> number / 1
};
+ static final int[][] assignmentExpectedLNT = {
+ // {line-number, start-pc},
+ {26, 0}, //number -> number / 1
+ {27, 6}, //number -> number / 1
+ };
+
+ static final int[][] callExpectedLNT = {
+ // {line-number, start-pc},
+ {29, 0}, //number -> number / 1
+ {31, 10}, //number -> number / 1
+ };
+
public static void main(String[] args) throws Exception {
new WrongLNTForLambdaTest().run();
}
@@ -120,6 +139,10 @@
"Foo.class").toUri()), "$deserializeLambda$", deserializeExpectedLNT);
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
"Foo.class").toUri()), "lambda$MR$variablesInLambdas$notify$8bc4f5bd$1", lambdaBridgeExpectedLNT);
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Foo.class").toUri()), "assignLambda", assignmentExpectedLNT);
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "Foo.class").toUri()), "callLambda", callExpectedLNT);
}
void compileTestClass() throws Exception {
--- a/langtools/test/tools/javac/lambda/TestInvokeDynamic.java Fri Nov 08 17:39:33 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TestInvokeDynamic.java Sat Nov 09 15:24:38 2013 +0100
@@ -356,7 +356,7 @@
if (lnt == null) {
throw new Error("No LineNumberTable attribute");
}
- if (lnt.line_number_table_length != 2) {
+ if (lnt.line_number_table_length != 3) {
throw new Error("Wrong number of entries in LineNumberTable");
}
} catch (Exception e) {