MH inlining fails for a package-private and protected calls

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Fri Oct 24 22:00:36 UTC 2014


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