RFR: 8271461: CompileCommand support for hidden class methods [v2]

Jie Fu jiefu at openjdk.java.net
Fri Jul 30 08:37:35 UTC 2021


On Fri, 30 Jul 2021 02:01:55 GMT, Jie Fu <jiefu at openjdk.org> wrote:

>> Hi all,
>> 
>> We'd like to improve the CompileCommand to support hidden class methods, which is helpful for debugging and perfmance analysis.
>> 
>> Current implementation of CompileCommand doesn't work for hidden class methods.
>> For example, if you run with `java -Xcomp -Xbatch -XX:+PrintCompilation`
>> The following hidden class methods were compiled:
>> 
>>    5317 1573    b  3       java.util.ResourceBundle$$Lambda$1/0x00000008010413c8::run (8 bytes)
>>    5318 1574    b  4       java.util.ResourceBundle$$Lambda$1/0x00000008010413c8::run (8 bytes)
>>    6735 1938    b  3       java.util.ResourceBundle$ResourceBundleProviderHelper$$Lambda$2/0x0000000801041e80::run (12 bytes)
>>    6736 1939    b  4       java.util.ResourceBundle$ResourceBundleProviderHelper$$Lambda$2/0x0000000801041e80::run (12 bytes)
>>    7060 2029    b  3       java.util.ResourceBundle$ResourceBundleProviderHelper$$Lambda$58/0x800000060::run (8 bytes)
>>    7061 2030    b  4       java.util.ResourceBundle$ResourceBundleProviderHelper$$Lambda$58/0x800000060::run (8 bytes)
>>    7688 2153    b  3       java.util.ResourceBundle$ResourceBundleProviderHelper$$Lambda$4/0x0000000801043218::run (16 bytes)
>>    7688 2154    b  4       java.util.ResourceBundle$ResourceBundleProviderHelper$$Lambda$4/0x0000000801043218::run (16 bytes)
>> 
>> 
>> Then people may want to exclude the compilation of `java.util.ResourceBundle$$Lambda$1/0x00000008010413c8::run` like this
>> 
>> -XX:CompileCommand=exclude,'java.util.ResourceBundle$$Lambda$1/0x00000008010413c8::run'
>> 
>> 
>> But unfortunately, it doesn't work.
>> 
>> CompileCommand: An error occurred during parsing
>> Error: Method pattern uses '/' together with '::'
>> Line: 'exclude,java.util.ResourceBundle$$Lambda$1/0x00000008010413c8::run'
>> 
>> Usage: '-XX:CompileCommand=<option>,<method pattern>' - to set boolean option to true
>> Usage: '-XX:CompileCommand=<option>,<method pattern>,<value>'
>> Use:   '-XX:CompileCommand=help' for more information and to list all option.
>> 
>> 
>> The failing reason is that the name of `java.util.ResourceBundle$$Lambda$1/0x00000008010413c8::run` is actually `java.util.ResourceBundle$$Lambda$1+0x00000008010413c8::run` in the VM.
>> But "+" had been replaced with "/" when it was printed by PrintCompilation [1].
>> 
>> So for a hidden class method, "/" should be replaced with "+" to make CompileCommand work.
>> 
>> Thanks.
>> Best regards,
>> Jie
>> 
>> 
>> [1] https://github.com/openjdk/jdk/blob/master/src/hotspot/share/oops/klass.cpp#L685
>
> Jie Fu has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Use isdigit

> At JDK level, the generated class name depends on a counter:(`Test$$Lambda$215`)
> 
> https://github.com/openjdk/jdk/blob/4f42eb6601c3b6011d3c2b30af6b2be264ff7c0e/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java#L207-L214
> 
> Later, class file parser mangles this class name:(`Test$$Lambda$215+0x0000000801144200`)
> https://github.com/openjdk/jdk/blob/4f42eb6601c3b6011d3c2b30af6b2be264ff7c0e/src/hotspot/share/classfile/classFileParser.cpp#L5910-L5933
> 
> When we want to print this class name, we will replace '+' with '/':(`Test$$Lambda$215/0x0000000801144200`)
> https://github.com/openjdk/jdk/blob/4f42eb6601c3b6011d3c2b30af6b2be264ff7c0e/src/hotspot/share/oops/klass.cpp#L665-L694
> 
> I don't fully practice what I see but it looks like the class name depends on class loading, there is no reliable way to ensure the same class loading order from run to run.
> 
> ```java
> import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.Random;
> 
> public class Test {
>     static class Foo {
>     }
> 
>     public static void main(String args[]) {
>         for (int i = 0; i < 100000; i++) {
>             test0();
>             if (new Random().nextInt(50) > 25) {
>                 new Foo(); // class loading, -Xlog:class+load
>             }
>             test2();
>         }
>     }
> 
>     static void test0() {
>         doit(() -> {
>         });
>     }
> 
>     static void test2() {
>         doit(() -> {
>         });
>     }
> 
>     static void doit(Runnable r) {
>         r.run();
>     }
> }
> ```
> 
> ```
> [9.716s][info][class,load] Test source: file:/home/qingfeng.yy/jdktip/mytest/Lambda.java
> [9.724s][info][class,load] Test$$Lambda$216/0x0000000801144200 source: Test
> [9.730s][info][class,load] java.util.random.RandomGenerator source: shared objects file
> [9.732s][info][class,load] java.util.Random source: shared objects file
> [9.745s][info][class,load] Test$Foo source: file:/home/qingfeng.yy/jdktip/mytest/Lambda.java
> [9.751s][info][class,load] Test$$Lambda$217/0x0000000801144618 source: Test
> ```
> 
> ```
> [9.933s][info][class,load] Test source: file:/home/qingfeng.yy/jdktip/mytest/Lambda.java
> [9.940s][info][class,load] Test$$Lambda$216/0x0000000801144200 source: Test
> [9.946s][info][class,load] java.util.random.RandomGenerator source: shared objects file
> [9.949s][info][class,load] java.util.Random source: shared objects file
> [9.962s][info][class,load] Test$$Lambda$217/0x0000000801144418 source: Test
> [9.968s][info][class,load] Test$Foo source: file:/home/qingfeng.yy/jdktip/mytest/Lambda.java
> ```

I agree with you all that in theory the hidden class name may be different from run to run.
But the fact is that they actually don't change.
Even in your experiment above, right? @kelthuzadx

-------------

PR: https://git.openjdk.java.net/jdk/pull/4926


More information about the hotspot-compiler-dev mailing list