Bug: no line number for invokedynamic
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Feb 26 23:32:50 UTC 2018
On 21/02/18 11:59, B. Blaser wrote:
> On 19 February 2018 at 13:04, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>>
>> On 16/02/18 11:43, B. Blaser wrote:
>>> On 15 February 2018 at 18:19, Vicente Romero <vicente.romero at oracle.com>
>>> wrote:
>>>>
>>>> On 02/14/2018 05:24 PM, B. Blaser wrote:
>>>>> This is also somewhat related to JDK-8019486 associated test which
>>>>> should probably be updated as next if we want to re-enable this
>>>>> feature to have a clean stack trace.
>>>>
>>>> right if we were introduce any change in this area the test below would
>>>> start failing
>>> I tried some stepping with 'jdb' on the examples present in this test
>>> case with the patch I suggested two days ago:
>>> - if (!msym.isDynamic()) {
>>> +// if (!msym.isDynamic()) {
>>> code.statBegin(tree.pos);
>>> - }
>>> +// }
>>>
>>> It appeared to me smooth enough and the stack trace for the initial
>>> example is right (line 7 instead of 6).
>> I wonder if this could depend on the IDE? The big we were referring to was
>> created very early in JDK 8 lifetime. I wonder if IDEs have gotten better at
>> ignoring indys during debugging?
> So, not emitting the line number looks more like an old javac tweak to
> help debuggers being smooth at the early days of invokedynamic...
Well, thats what's the hack was for - but honestly I believe IDEs are
still not skipping indys when debugging - so they kind of rely on what
compilers do here.
Maurizio
>
> Another thing I can note is that if we'd like to step into the
> bootstrap method, it'd be right to stop first on the dynamic call
> site. In such a situation, having the indy line number would be
> necessary too.
>
> Bernard
>
>
>> Would be very helpful if some IDE people
>> with experience in debuggers could chime in here?
>>
>> Maurizio
>>
>>
>>> Are we going in this direction? Is there any open JBS issue for that?
>>>
>>> Bernard
>>>
>>>>> Cheers,
>>>>> Bernard
>>>>
>>>> Vicente
>>>>
>>>>
>>>>> diff -r b3a833c9c6e9
>>>>> test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java
>>>>> --- a/test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java
>>>>> Mon Feb 12 09:12:41 2018 +0100
>>>>> +++ b/test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java
>>>>> Wed Feb 14 22:56:43 2018 +0100
>>>>> @@ -107,6 +107,8 @@
>>>>> static final int[][] deserializeExpectedLNT = {
>>>>> // {line-number, start-pc},
>>>>> {05, 0}, //number -> number / 1
>>>>> + {21, 137}, //number -> number / 1
>>>>> + {05, 142}, //number -> number / 1
>>>>> };
>>>>>
>>>>> static final int[][] lambdaBridgeExpectedLNT = {
>>>>> @@ -123,6 +125,8 @@
>>>>> static final int[][] callExpectedLNT = {
>>>>> // {line-number, start-pc},
>>>>> {29, 0}, //number -> number / 1
>>>>> + {30, 2}, //number -> number / 1
>>>>> + {29, 7}, //number -> number / 1
>>>>> {31, 10}, //number -> number / 1
>>>>> };
>>>>>
>>>>>
>>>>> On 14 February 2018 at 21:47, Maurizio Cimadamore
>>>>> <maurizio.cimadamore at oracle.com> wrote:
>>>>>> This comes from here:
>>>>>>
>>>>>> https://bugs.openjdk.java.net/browse/JDK-8010404
>>>>>>
>>>>>> Back when developing JDK 8 - we had a feeling that having the debugger
>>>>>> stop
>>>>>> at lambda capture sites would be confusing - and so we disabled it.
>>>>>>
>>>>>> I agree that in the stack trace case this decision seems to backfire a
>>>>>> bit.
>>>>>>
>>>>>> Maurizio
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 14/02/18 15:26, B. Blaser wrote:
>>>>>>> The line number is deliberately not emitted for dynamic callsites (but
>>>>>>> I don't know why?), see below.
>>>>>>> I hope this helps,
>>>>>>> Bernard
>>>>>>>
>>>>>>> diff -r b3a833c9c6e9
>>>>>>> src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
>>>>>>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
>>>>>>> Mon Feb 12 09:12:41 2018 +0100
>>>>>>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
>>>>>>> Wed Feb 14 16:14:17 2018 +0100
>>>>>>> @@ -1649,9 +1649,9 @@
>>>>>>> MethodSymbol msym =
>>>>>>> (MethodSymbol)TreeInfo.symbol(tree.meth);
>>>>>>> genArgs(tree.args,
>>>>>>> msym.externalType(types).getParameterTypes());
>>>>>>> - if (!msym.isDynamic()) {
>>>>>>> +// if (!msym.isDynamic()) {
>>>>>>> code.statBegin(tree.pos);
>>>>>>> - }
>>>>>>> +// }
>>>>>>> result = m.invoke();
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> On 14 February 2018 at 09:16, Vladimir Parfinenko
>>>>>>> <vparfinenko at excelsior-usa.com> wrote:
>>>>>>>> Hi all,
>>>>>>>>
>>>>>>>> I think I have found a minor bug. There is no line number information
>>>>>>>> for invokedynamic instructions generated for method handle or lambda
>>>>>>>> function.
>>>>>>>>
>>>>>>>> The problem can be reproduced using the example below and running it
>>>>>>>> like this:
>>>>>>>>
>>>>>>>> $ javac Test.java
>>>>>>>> $ rm A.class
>>>>>>>> $ java Test
>>>>>>>> Exception in thread "main" java.lang.NoClassDefFoundError: A
>>>>>>>> at Test.main(Test.java:6)
>>>>>>>> Caused by: java.lang.ClassNotFoundException: A
>>>>>>>> ...
>>>>>>>>
>>>>>>>> The correct line number for this stack trace element would be 7.
>>>>>>>>
>>>>>>>> The line number table is missing an entry for invokedynamic:
>>>>>>>>
>>>>>>>> Code:
>>>>>>>> stack=2, locals=2, args_size=1
>>>>>>>> 0: invokestatic #2 // Method
>>>>>>>> fortyTwo:()I
>>>>>>>> 3: invokedynamic #3, 0 // InvokeDynamic
>>>>>>>> #0:apply:()Ljava/util/function/Function;
>>>>>>>> 8: invokestatic #4 // Method
>>>>>>>> foo:(ILjava/util/function/Function;)Ljava/lang/Object;
>>>>>>>> 11: astore_1
>>>>>>>> 12: return
>>>>>>>> LineNumberTable:
>>>>>>>> line 6: 0
>>>>>>>> line 5: 8
>>>>>>>> line 9: 12
>>>>>>>>
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Vladimir Parfinenko
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> -- Test.java
>>>>>>>>
>>>>>>>> // line 1
>>>>>>>> public class Test {
>>>>>>>> public static void main(String[] args) {
>>>>>>>> Object res =
>>>>>>>> foo(
>>>>>>>> fortyTwo(), // line 6
>>>>>>>> A::sqr // line 7
>>>>>>>> );
>>>>>>>> }
>>>>>>>>
>>>>>>>> public static Object foo(int x,
>>>>>>>> java.util.function.Function<Integer,
>>>>>>>> Integer> f) {
>>>>>>>> return null;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public static int fortyTwo() {
>>>>>>>> return 42;
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> class A {
>>>>>>>> public static int sqr(int x) {
>>>>>>>> return x * x;
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>>
More information about the compiler-dev
mailing list