MH inlining fails for a package-private and protected calls

Vladimir Kozlov vladimir.kozlov at oracle.com
Fri Oct 24 22:23:26 UTC 2014


Does it have > 2 types in profiling? If it is only 2 we should be able 
to do bi-morphic inlining.

Vladimir K

On 10/24/14 3:00 PM, Vladimir Ivanov wrote:
> Paul,
>
> Accessibility is not a problem. The reason is profile pollution, since
> DMH bytecode is shared:
> * MHInlineTest::testPublicMH
> @ 13   java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15
> bytes)   force inline by annotation
>
> * MHInlineTest::testProtectedMH (24 bytes)   inline (hot)
> @ 13   java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15
> bytes)   force inline by annotation
>
> * MHInlineTest::testPackageMH (24 bytes)   inline (hot)
>
> @ 13   java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15
> bytes)   force inline by annotation
>
> If you reorder the tests or mix then, inlining behavior will change.
>
> Don't know why LambdaForm is different for testPackageFinalMH case.
>
> I'll look into this on Monday.
>
> Best regards,
> Vladimir Ivanov
>
> On 10/25/14, 12:52 AM, Paul Sandoz wrote:
>> Hi,
>>
>> I am observing that inlining of a MH invocation to a package private
>> method fails.
>>
>> Below is a simple test that test MHs to a public, package-private and
>> protected methods.
>>
>> Using the tip of JDK 9 with "java  -XX:-TieredCompilation
>> -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining MHInlineTest"
>> produces the following:
>>
>>                 !            @ 10   MHInlineTest::testPublicMH (24
>> bytes)   inline (hot)
>>                                @ 7
>> java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes)
>> force inline by annotation
>>                                  @ 2
>> java.lang.invoke.Invokers::checkExactType (30 bytes)   force inline by
>> annotation
>>                                    @ 11
>> java.lang.invoke.MethodHandle::type (5 bytes)   accessor
>>                                  @ 13
>> java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15
>> bytes)   force inline by annotation
>>                                    @ 1
>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>> force inline by annotation
>>                                    @ 11   MHInlineTest$B::public_x (6
>> bytes)   inline (hot)
>>
>>                 !            @ 29   MHInlineTest::testProtectedMH (24
>> bytes)   inline (hot)
>>                                @ 7
>> java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes)
>> force inline by annotation
>>                                  @ 2
>> java.lang.invoke.Invokers::checkExactType (30 bytes)   force inline by
>> annotation
>>                                    @ 11
>> java.lang.invoke.MethodHandle::type (5 bytes)   accessor
>>                                  @ 13
>> java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15
>> bytes)   force inline by annotation
>>                                    @ 1
>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>> force inline by annotation
>>                                    @ 11   MHInlineTest$A::protected_x
>> (6 bytes)   virtual call
>>
>>                 !            @ 48   MHInlineTest::testPackageMH (24
>> bytes)   inline (hot)
>>                                @ 7
>> java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes)
>> force inline by annotation
>>                                  @ 2
>> java.lang.invoke.Invokers::checkExactType (30 bytes)   force inline by
>> annotation
>>                                    @ 11
>> java.lang.invoke.MethodHandle::type (5 bytes)   accessor
>>                                  @ 13
>> java.lang.invoke.LambdaForm$DMH/285377351::invokeVirtual_LL_V (15
>> bytes)   force inline by annotation
>>                                    @ 1
>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>> force inline by annotation
>>                                    @ 11   MHInlineTest$A::package_x (6
>> bytes)   virtual call
>>
>>                 !            @ 67   MHInlineTest::testPackageFinalMH
>> (24 bytes)   inline (hot)
>>                                @ 7
>> java.lang.invoke.LambdaForm$MH/314265080::invokeExact_MT (17 bytes)
>> force inline by annotation
>>                                  @ 2
>> java.lang.invoke.Invokers::checkExactType (30 bytes)   force inline by
>> annotation
>>                                    @ 11
>> java.lang.invoke.MethodHandle::type (5 bytes)   accessor
>>                                  @ 13
>> java.lang.invoke.LambdaForm$DMH/344560770::invokeSpecial_LL_V (15
>> bytes)   force inline by annotation
>>                                    @ 1
>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>> force inline by annotation
>>                                    @ 11
>> MHInlineTest$A::package_final_x (6 bytes)   inline (hot)
>>
>>                              @ 86   MHInlineTest::testPackage (8
>> bytes)   inline (hot)
>>                                @ 4   MHInlineTest$B::package_x (6
>> bytes)   inline (hot)
>>
>> Note that:
>>
>> - inlining bails out for the MH to the package-private and and
>> protected method, but does not bail out for an explicit
>> package-protected call.
>>
>> - the same LambdaForms are used for all virtual invocations.
>>
>> Is that the expected behaviour?
>>
>> Paul.
>>
>> public class MHInlineTest {
>>
>>      public static class A {
>>          volatile String s;
>>
>>          public void public_x(String s) {
>>              this.s = s;
>>          }
>>
>>          void protected_x(String s) {
>>              this.s = s;
>>          }
>>
>>          void package_x(String s) {
>>              this.s = s;
>>          }
>>
>>          final void package_final_x(String s) {
>>              this.s = s;
>>          }
>>      }
>>
>>      public static final class B extends A {
>>          volatile String s;
>>
>>          @Override
>>          public void public_x(String s) {
>>              this.s = s;
>>          }
>>
>>          @Override
>>          void protected_x(String s) {
>>              this.s = s;
>>          }
>>
>>          @Override
>>          void package_x(String s) {
>>              this.s = s;
>>          }
>>      }
>>
>>      static final MethodHandle A_PUBLIC_X;
>>      static final MethodHandle A_PROTECTED_X;
>>      static final MethodHandle A_PACKAGE_X;
>>      static final MethodHandle A_PACKAGE_FINAL_X;
>>
>>      static {
>>          try {
>>              A_PUBLIC_X = MethodHandles.lookup().findVirtual(
>>                      A.class, "public_x",
>> MethodType.methodType(void.class, String.class));
>>              A_PROTECTED_X = MethodHandles.lookup().findVirtual(
>>                      A.class, "protected_x",
>> MethodType.methodType(void.class, String.class));
>>              A_PACKAGE_X = MethodHandles.lookup().findVirtual(
>>                      A.class, "package_x",
>> MethodType.methodType(void.class, String.class));
>>              A_PACKAGE_FINAL_X = MethodHandles.lookup().findVirtual(
>>                      A.class, "package_final_x",
>> MethodType.methodType(void.class, String.class));
>>          }
>>          catch (Exception e) {
>>              throw new Error(e);
>>          }
>>      }
>>
>>      static final A a = new B();
>>
>>      public static void main(String[] args) {
>>          for (int i = 0; i < 1000_0000; i++) {
>>              testPublicMH("X");
>>          }
>>          for (int i = 0; i < 1000_0000; i++) {
>>              testProtectedMH("X");
>>          }
>>          for (int i = 0; i < 1000_0000; i++) {
>>              testPackageMH("X");
>>          }
>>          for (int i = 0; i < 1000_0000; i++) {
>>              testPackageFinalMH("X");
>>          }
>>          for (int i = 0; i < 1000_0000; i++) {
>>              testPackage("X");
>>          }
>>          System.out.println("END");
>>      }
>>
>>      private static void testPublicMH(String x) {
>>          try {
>>              A_PUBLIC_X.invokeExact(a, x);
>>          }
>>          catch (Throwable throwable) {
>>              throw new Error(throwable);
>>          }
>>      }
>>
>>      private static void testProtectedMH(String x) {
>>          try {
>>              A_PROTECTED_X.invokeExact(a, x);
>>          }
>>          catch (Throwable throwable) {
>>              throw new Error(throwable);
>>          }
>>      }
>>
>>      private static void testPackageMH(String x) {
>>          try {
>>              A_PACKAGE_X.invokeExact(a, x);
>>          }
>>          catch (Throwable throwable) {
>>              throw new Error(throwable);
>>          }
>>      }
>>
>>      private static void testPackageFinalMH(String x) {
>>          try {
>>              A_PACKAGE_FINAL_X.invokeExact(a, x);
>>          }
>>          catch (Throwable throwable) {
>>              throw new Error(throwable);
>>          }
>>      }
>>
>>      private static void testPackage(String x) {
>>          a.package_x(x);
>>      }
>> }
>>


More information about the hotspot-compiler-dev mailing list