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