Bug: no line number for invokedynamic

B. Blaser bsrbnd at gmail.com
Wed Feb 21 11:59:16 UTC 2018


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...

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