Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8327499

MethodHandleStatics.traceLambdaForm includes methods that cannot be generated

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 23
    • None
    • core-libs
    • None

      The following bug can be reproduced with this commit
      https://github.com/openjdk/jdk/commit/989fc3e6ea65e530055296ac4bc181cb5c6a41ea

      [1] Apply the following patch for diagnosis. Build a non-product JVM:

      diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
      index 500036febab..39850d1d208 100644
      --- a/src/hotspot/share/prims/jvm.cpp
      +++ b/src/hotspot/share/prims/jvm.cpp
      @@ -3715,6 +3715,8 @@ JVM_ENTRY_NO_ENV(jint, JVM_GetCDSConfigStatus())
         return CDSConfig::get_status();
       JVM_END
       
      +extern "C" JNIEXPORT void ps();
      +
       JVM_ENTRY(void, JVM_LogLambdaFormInvoker(JNIEnv *env, jstring line))
       #if INCLUDE_CDS
         assert(CDSConfig::is_logging_lambda_form_invokers(), "sanity");
      @@ -3730,6 +3732,11 @@ JVM_ENTRY(void, JVM_LogLambdaFormInvoker(JNIEnv *env, jstring line))
           if (ClassListWriter::is_enabled()) {
             ClassListWriter w;
             w.stream()->print_cr("%s %s", LAMBDA_FORM_TAG, c_line);
      + if (strstr(c_line, "L3I_L") != nullptr &&
      + strstr(c_line, "Invokers$Holder") != nullptr) {
      + tty->print_cr("%s", c_line);
      + ps();
      + }
           }
         }

      [2] Create this file: TestInvokers.java

      =================
      import java.lang.invoke.MethodHandle;
      import java.lang.invoke.MethodHandles;
      import java.lang.invoke.MethodType;

      public class TestInvokers {
          public static void main(String args[]) throws Exception {
              MethodType type = MethodType.methodType(Object.class, Object.class, int.class);
              System.out.println(type);
              MethodHandle inv = MethodHandles.invoker(type);
              System.out.println(inv);
          }
      }
      =================

      [3] Run the following commands:

      $ javac TestInvokers.java
      $ java -XX:DumpLoadedClassList=TestInvokers.classlist -cp . TestInvokers

      (Object,int)Object
      [LF_RESOLVE] java.lang.invoke.Invokers$Holder invoker L3I_L

      "Executing ps"
       for thread: "main" #1 [1018846] prio=5 os_prio=0 cpu=265.15ms elapsed=0.27s tid=0x00007fe2d002a150 nid=1018846 runnable [0x00007fe2d6047000]
         java.lang.Thread.State: RUNNABLE
      Thread: 0x00007fe2d002a150 [0xf8bde] State: _running _at_poll_safepoint 0
         JavaThread state: _thread_in_vm

      at jdk.internal.misc.CDS.logLambdaFormInvoker(java.base@23-internal/Native Method)
      at jdk.internal.misc.CDS.logLambdaFormInvoker(java.base@23-internal/CDS.java:110)
      at java.lang.invoke.MethodHandleStatics.traceLambdaForm(java.base@23-internal/MethodHandleStatics.java:138)
      at java.lang.invoke.InvokerBytecodeGenerator.resolveFrom(java.base@23-internal/InvokerBytecodeGenerator.java:648)
      at java.lang.invoke.InvokerBytecodeGenerator.lookupPregenerated(java.base@23-internal/InvokerBytecodeGenerator.java:674)
      at java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCode(java.base@23-internal/InvokerBytecodeGenerator.java:708)
      at java.lang.invoke.LambdaForm.compileToBytecode(java.base@23-internal/LambdaForm.java:849)
      at java.lang.invoke.LambdaForm.prepare(java.base@23-internal/LambdaForm.java:807)
      at java.lang.invoke.MethodHandle.<init>(java.base@23-internal/MethodHandle.java:482)
      at java.lang.invoke.BoundMethodHandle.<init>(java.base@23-internal/BoundMethodHandle.java:52)
      at java.lang.invoke.BoundMethodHandle$Species_L.<init>(java.base@23-internal/BoundMethodHandle.java:210)
      at java.lang.invoke.BoundMethodHandle$Species_L.make(java.base@23-internal/BoundMethodHandle.java:225)
      at java.lang.invoke.BoundMethodHandle.bindSingle(java.base@23-internal/BoundMethodHandle.java:66)
      at java.lang.invoke.Invokers.makeExactOrGeneralInvoker(java.base@23-internal/Invokers.java:147)
      at java.lang.invoke.Invokers.genericInvoker(java.base@23-internal/Invokers.java:80)
      at java.lang.invoke.MethodHandles.invoker(java.base@23-internal/MethodHandles.java:4771)
      at TestInvokers.main(TestInvokers.java:9)
      MethodHandle(MethodHandle,Object,int)Object

      $ grep Invokers.Holder.*L3I_L lst
      @lambda-form-invoker [LF_RESOLVE] java.lang.invoke.Invokers$Holder invoker L3I_L

      $ d -Xshare:dump -XX:SharedArchiveFile=jsa -XX:SharedClassListFile=lst
      [0.752s][error][cds] java.lang.RuntimeException: Invoker type parameter must start and end with Object: L3I_L
      [0.752s][error][cds] Failed to generate LambdaForm holder classes. Is your classlist out of date?

      ==================================
      Note that MethodHandleStatics.traceLambdaForm produces the trace

      [LF_RESOLVE] java.lang.invoke.Invokers$Holder invoker L3I_L

      However, this invoker cannot be generated due to this check:

      https://github.com/openjdk/jdk/blob/989fc3e6ea65e530055296ac4bc181cb5c6a41ea/src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java#L139-L141

      if (mt.parameterCount() < 2 ||
          mt.parameterType(0) != Object.class ||
          mt.parameterType(lastParam) != Object.class) {
          throw new RuntimeException(
             "Invoker type parameter must start and end with Object: " + invokerType);
      }

            liach Chen Liang
            iklam Ioi Lam
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: