<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>HI Ashutosh,</p>
    <p>Thanks for confirming. I created a JBS issue for this and pushed
      the fix:</p>
    <p><a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8340869">https://bugs.openjdk.org/browse/JDK-8340869</a><br>
<a class="moz-txt-link-freetext" href="https://github.com/openjdk/leyden/commit/7a6fadcae03d86c91713ffae452817bce7a4674d">https://github.com/openjdk/leyden/commit/7a6fadcae03d86c91713ffae452817bce7a4674d</a><br>
      <br>
      Thanks</p>
    <p>- Ioi<br>
    </p>
    <div class="moz-cite-prefix">On 9/24/24 6:36 PM, Ashutosh Mehra
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAKt0pyTixr_fwL-f+=zuRv38a2=3tXHRct2tVAVLvgrp7jVYhg@mail.gmail.com">
      
      <div dir="ltr">
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I
          disabled the AOTClassInitializer::is_forced_preinit_class()
          call and synced
          AOTClassInitializer::can_archive_preinitialized_mirror() with
          my upstream PR. This seems to fix the error in your test case.<br clear="all">
        </blockquote>
        <div><br>
        </div>
        <div>I verified that this change fixes the error in the
          testcase. Thanks for fixing this issue.</div>
        <div><br>
        </div>
        <div>- Ashutosh Mehra<br>
        </div>
        <br>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, Sep 24, 2024 at
          1:01 PM <<a href="mailto:ioi.lam@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">ioi.lam@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>
            <p>Hi Ashutosh,</p>
            <p>I disabled the
              AOTClassInitializer::is_forced_preinit_class() call and
              synced
              AOTClassInitializer::can_archive_preinitialized_mirror()
              with my upstream PR. This seems to fix the error in your
              test case.</p>
            <p>Could you give it a try?</p>
            <p><a href="https://urldefense.com/v3/__https://github.com/iklam/jdk/commit/df72d0ba8dc799767521c939a531c4128e58c636__;!!ACWV5N9M2RV99hQ!JlCvAYhu5kpAYkOTVF5UgMSFalpCIQtIFb-TURRezEh4nHbqPTRgCJPjokWlgwcGFibvjMg1fnNZBg$" target="_blank" moz-do-not-send="true">https://github.com/iklam/jdk/commit/df72d0ba8dc799767521c939a531c4128e58c636</a><br>
            </p>
            <p>Thanks</p>
            <p>- Ioi<br>
            </p>
            <p><br>
            </p>
            <p><a href="https://urldefense.com/v3/__https://github.com/iklam/jdk/commit/df72d0ba8dc799767521c939a531c4128e58c636__;!!ACWV5N9M2RV99hQ!JlCvAYhu5kpAYkOTVF5UgMSFalpCIQtIFb-TURRezEh4nHbqPTRgCJPjokWlgwcGFibvjMg1fnNZBg$" target="_blank" moz-do-not-send="true">https://github.com/iklam/jdk/commit/df72d0ba8dc799767521c939a531c4128e58c636</a><br>
            </p>
            <div>On 9/24/24 8:24 AM, Ashutosh Mehra wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">Hi Ioi,
                <div>Thanks for sharing the code changes.</div>
                <div>The wildfly-elytron testcase passes with these
                  changes, but I still get the NPE
                  in PrimitiveClassDescImpl.<clinit> when running
                  with my own testcase.</div>
                <div>I have pushed my test case to a repo [2], so you
                  can try it as well. I have added some instructions to
                  the Readme file.</div>
                <div>Let me know if you face any issues in running the
                  test case.</div>
                <div><br>
                </div>
                <div>[2] <a href="https://urldefense.com/v3/__https://github.com/ashu-mehra/leyden-testcase/__;!!ACWV5N9M2RV99hQ!JiRlHQ7c-vdXVJoc61a64CilNOg5VTLitO8JELhohSZdibAXZUEjeA38WbtygjLvPsQIQKUYXJ2_kA$" target="_blank" moz-do-not-send="true">https://github.com/ashu-mehra/leyden-testcase/</a></div>
                <div><br>
                </div>
                <div>Thanks,<br>
                  <div>
                    <div>
                      <div dir="ltr" class="gmail_signature">
                        <div dir="ltr">- Ashutosh Mehra</div>
                      </div>
                    </div>
                    <br>
                  </div>
                </div>
              </div>
              <br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Mon, Sep 23, 2024
                  at 11:24 PM <<a href="mailto:ioi.lam@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">ioi.lam@oracle.com</a>>
                  wrote:<br>
                </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                  <div>
                    <p>Hi Ashutosh,</p>
                    <p>Thank you again for the summary of the issues.</p>
                    I looked at the call paths again and I think two
                    calls need to be moved<br>
                    <blockquote>
                      <p>(1) MethodType::createArchivedObjects() needs
                        to be called after we have executed all other
                        Java code. So I put it before the
                        StringTable::allocate_shared_strings_array()
                        call.</p>
                      <p>(2)
                        SystemDictionary::get_all_method_handle_intrinsics()
                        needs to be done inside the safepoint, so it can
                        be sure to find all the method handle intrinsic
                        methods (which can be generated as the side
                        effect of Java code execution).</p>
                    </blockquote>
                    <blockquote>
                      <p>I also added the archiving of the classData
                        field.</p>
                    </blockquote>
                    <p>See my temporary change at <a href="https://urldefense.com/v3/__https://github.com/iklam/jdk/commit/eafaa9731ae89b93f3e20702fc4d5a12cb070149__;!!ACWV5N9M2RV99hQ!JiRlHQ7c-vdXVJoc61a64CilNOg5VTLitO8JELhohSZdibAXZUEjeA38WbtygjLvPsQIQKXvE8zr1g$" target="_blank" moz-do-not-send="true">https://github.com/iklam/jdk/commit/eafaa9731ae89b93f3e20702fc4d5a12cb070149</a><br>
                      <br>
                      With this change, I am able to successfully run
                      the test in <a href="https://urldefense.com/v3/__https://github.com/tristantarrant/elytron-leyden__;!!ACWV5N9M2RV99hQ!JiRlHQ7c-vdXVJoc61a64CilNOg5VTLitO8JELhohSZdibAXZUEjeA38WbtygjLvPsQIQKW7YFmGjQ$" target="_blank" moz-do-not-send="true">https://github.com/tristantarrant/elytron-leyden</a>
                      . I also modified the
                      LambdaWithUseImplMethodHandle.java test to add a
                      similar test scenario.</p>
                    <p>I agree with you that the code in
                      AOTClassInitializer::is_forced_preinit_class() is
                      too ad-hoc, and might change the order of class
                      initialization. In the upstream PR, I have changed
                      the code to only assert that the listed of classes
                      has been initialized:</p>
                    <p><a href="https://urldefense.com/v3/__https://github.com/iklam/jdk/blob/5cc31ed60cc9597d63b86f20b95c964d4d1a6b84/src/hotspot/share/cds/aotClassInitializer.cpp*L66-L84__;Iw!!ACWV5N9M2RV99hQ!JiRlHQ7c-vdXVJoc61a64CilNOg5VTLitO8JELhohSZdibAXZUEjeA38WbtygjLvPsQIQKUJSR9oEw$" target="_blank" moz-do-not-send="true">https://github.com/iklam/jdk/blob/5cc31ed60cc9597d63b86f20b95c964d4d1a6b84/src/hotspot/share/cds/aotClassInitializer.cpp#L66-L84</a><br>
                    </p>
                    <p>I will try to merge this version of the code back
                      to the Leyden repo.</p>
                    <p>I think by doing this, we can avoid direct
                      manipulation of the class-init order of the
                      core-library classes. Instead, we just make sure
                      that we execute enough "normal" code during the
                      assembly phase to ensure that these classes are
                      initialized in their normal order.</p>
                    <p>What do you think?</p>
                    <p>Thanks</p>
                    <p>- Ioi<br>
                    </p>
                    <p><br>
                    </p>
                    <div>On 9/19/24 8:05 PM, Ashutosh Mehra wrote:<br>
                    </div>
                    <blockquote type="cite">
                      <div dir="ltr">
                        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                          <p>Upon further investigation, it seems a
                            simple patch might fix the problem with
                            classData.<br>
                          </p>
                          <p>I tested with
                            test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java
                            by running jtreg with
                            -javaoptions:-XX:+AOTClassLinking<br>
                            Without the patch, I'd get a
                            NullPointerException. With the patch, the
                            test passes.</p>
                          <p>It looks like classData is not treated as a
                            static field of the class, but rather an
                            instance field in the mirror. So classData
                            wasn't copied by the loop in
                            HeapShared::copy_preinitialized_mirror().</p>
                          <p>Ashutosh, could you try it this fixes the
                            crash on your side?<br>
                          </p>
                          <p>Thanks</p>
                          <p>- Ioi<br>
                          </p>
                          <p>diff --git
                            a/src/hotspot/share/cds/heapShared.cpp
                            b/src/hotspot/share/cds/heapShared.cpp<br>
                            index 0e70778f057..62cf142f67a 100644<br>
                            --- a/src/hotspot/share/cds/heapShared.cpp<br>
                            +++ b/src/hotspot/share/cds/heapShared.cpp<br>
                            @@ -634,6 +634,8 @@ void
                            HeapShared::copy_preinitialized_mirror(Klass*
                            orig_k, oop orig_mirror, oop<br>
                                 }<br>
                               }<br>
                             <br>
                            +  java_lang_Class::set_class_data(m,
                            java_lang_Class::class_data(orig_mirror));<br>
                            +<br>
                               // Class::reflectData use SoftReference,
                            which cannot be archived. Set it<br>
                               // to null and it will be recreated at
                            runtime.<br>
                               java_lang_Class::set_reflection_data(m,
                            nullptr);</p>
                        </blockquote>
                        <div><br>
                        </div>
                        <div>Hi Ioi,</div>
                        <div><br>
                        </div>
                        <div>This patch effectively does the same thing
                          as my initial patch for storing classData in
                          the scratch mirror object [1].</div>
                        <div><br>
                        </div>
                        <div>At this point I think it would be useful to
                          do a quick recap of the issues mentioned in
                          this thread. There are 3 issues I have
                          encountered so far.</div>
                        <div>I was initially thinking of a solution that
                          would cover all these problems, but looking at
                          these again, I feel these are orthogonal to
                          each other:</div>
                        <div><br>
                        </div>
                        <div>1. The missing classData in scratch mirrors
                          which can be fixed by either of the patches
                          shared in this thread. They achieve the same
                          goal and I don't have any strong preference
                          for any of them.</div>
                        <div><br>
                        </div>
                        <div>2. After fixing the classData, I ran into 
                          WrongMethodTypeException issue [2] which I
                          fixed by exchanging the order of indy
                          resolution with the call to
                          MethodType::createArchivedObjects [3].</div>
                        <div>This change makes sense because we want to
                          make sure all the MethodType objects that can
                          be archived are in MethodType internTable
                          before calling
                          MethodType::createArchivedObjects.</div>
                        <div>I am not sure why
                          LambdaWithUseImplMethodHandle.java didn't
                          throw the WrongMethodTypeException, as the
                          Infinispan code does.<br>
                        </div>
                        <div><br>
                        </div>
                        <div>3. After fixing the
                          WrongMethodTypeException I hit NPE due to the
                          class initialization cycle between <font face="monospace">PrimitiveClassDescImpl</font> and <font face="monospace">ConstantDescs </font><font face="arial, sans-serif">[4] in one of my
                            own testcase.</font></div>
                        <div><span style="font-family:arial,sans-serif">We
                            are looking for a solution to this problem.
                            I am not sure if we can break this cycle
                            by refactoring the Java code.</span></div>
                        <div><span style="font-family:arial,sans-serif">Nevertheless,
                            I think it is fair to assume that there is
                            no Java code that can initiate
                            initialization of </span><span style="font-family:monospace">PrimitiveClassDescImpl
                          </span><font face="arial, sans-serif">before</font><span style="font-family:monospace"> ConstantDescs</span><font face="arial, sans-serif">, otherwise we
                            would have hit the NPE earlier.</font></div>
                        <div><font face="arial, sans-serif">So if </font><font face="monospace">ConstantDescs</font><font face="arial, sans-serif"> is always expected
                            to be initialized before </font><span style="font-family:monospace">PrimitiveClassDescImpl</span><font face="arial, sans-serif"> then I think the
                            VM code should also maintain this
                            assumption.</font></div>
                        <div><font face="arial, sans-serif">Now this
                            brings us back to the forceful
                            initialization done by the VM during the
                            assembly phase based on the </font>forced_preinit_classes
                          list in aotClassInitializer.cpp:</div>
                        <div><br>
                        </div>
                        <div><font face="monospace">    // TODO:<br>
                                // This is needed since JDK-8338532.
                            Without this, when<br>
                                // archived heap objects are used, the
                            class init order is not<br>
                                // expected by the jdk/internal/constant
                            bootstrap code and we<br>
                                // will get a null pointer exception.<br>
                                //<br>
                                // When bootstraping has
                            intricated/fragile order, it's probably<br>
                                // better to archive all related classes
                            in an initialized state<br>
                                // (i.e., take a snapshot). The existing
                            approach in<br>
                                //
                            heapShared::resolve_or_init_classes_for_subgraph_of()
                            won't work.<br>
                               
                            "jdk/internal/constant/PrimitiveClassDescImpl",<br>
                               
                            "jdk/internal/constant/ReferenceClassDescImpl",<br>
                                "java/lang/constant/ConstantDescs",<br>
                                "sun/invoke/util/Wrapper",</font><br>
                        </div>
                        <div><font face="arial, sans-serif"><br>
                          </font></div>
                        <div><font face="arial, sans-serif">I wonder why
                            we need to explicitly add  </font><span style="font-family:monospace">PrimitiveClassDescImpl</span><font face="arial, sans-serif"> and </font><span style="font-family:monospace">ReferenceClassDescImpl</span><font face="arial, sans-serif"> in this list.</font></div>
                        <div><font face="arial, sans-serif">Initialization
                            of </font><span style="font-family:monospace">ConstantDescs</span><font face="arial, sans-serif"> would anyway
                            trigger the initialization of </font><span style="font-family:monospace">PrimitiveClassDescImpl</span><font face="arial, sans-serif"> and </font><span style="font-family:monospace">ReferenceClassDescImpl</span><font face="arial, sans-serif">.</font></div>
                        <div><font face="arial, sans-serif">So if we
                            only keep the entry for </font><span style="font-family:monospace">ConstantDescs</span><font face="arial, sans-serif"> and remove </font><span style="font-family:monospace">PrimitiveClassDescImpl</span><font face="arial, sans-serif"> and </font><span style="font-family:monospace">ReferenceClassDescImpl</span><font face="arial, sans-serif"> from this list,</font></div>
                        <div><font face="arial, sans-serif">we can be
                            sure that the forceful initialization by the
                            VM would maintain the same </font><span style="font-family:arial,sans-serif">order
                            of initialization as guided by the Java
                            code,</span></div>
                        <div><span style="font-family:arial,sans-serif">and
                            we will not hit the NPE when initializing </span><span style="font-family:monospace">PrimitiveClassDescImpl
                          </span><font face="arial, sans-serif">during
                            the assembly phase.</font></div>
                        <div><font face="arial, sans-serif">Does this
                            make sense?</font></div>
                        <div><span style="font-family:arial,sans-serif"><br>
                          </span></div>
                        <div><br>
                        </div>
                        <div>[1] <a href="https://mail.openjdk.org/pipermail/leyden-dev/2024-September/000994.html" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/leyden-dev/2024-September/000994.html</a></div>
                        <div>[2] <a href="https://mail.openjdk.org/pipermail/leyden-dev/2024-September/000997.html" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/leyden-dev/2024-September/000997.html</a></div>
                        <div>[3] <a href="https://urldefense.com/v3/__https://github.com/ashu-mehra/leyden/commit/d8f99cce67df1c7b0f7ef8562676df438633a66e__;!!ACWV5N9M2RV99hQ!KvYLs_vG0a4GO3ltinXQkxBG1kMhCAvmmM6MwODoKzOhhVjzNL80S_0mBzYvYyhYPQnGmXhAXSw78Q$" style="font-family:arial,sans-serif" target="_blank" moz-do-not-send="true">https://github.com/ashu-mehra/leyden/commit/d8f99cce67df1c7b0f7ef8562676df438633a66e</a></div>
                        <div>[4] <a href="https://mail.openjdk.org/pipermail/leyden-dev/2024-September/001018.html" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/leyden-dev/2024-September/001018.html</a></div>
                        <div><br>
                        </div>
                        <div>Thanks,</div>
                        <div>
                          <div dir="ltr" class="gmail_signature">
                            <div dir="ltr">- Ashutosh Mehra</div>
                          </div>
                        </div>
                        <br>
                      </div>
                      <br>
                      <div class="gmail_quote">
                        <div dir="ltr" class="gmail_attr">On Thu, Sep
                          19, 2024 at 8:51 PM <<a href="mailto:ioi.lam@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">ioi.lam@oracle.com</a>>
                          wrote:<br>
                        </div>
                        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                          <div>
                            <p>Upon further investigation, it seems a
                              simple patch might fix the problem with
                              classData. <br>
                            </p>
                            <p>I tested with
                              test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java
                              by running jtreg with
                              -javaoptions:-XX:+AOTClassLinking<br>
                              Without the patch, I'd get a
                              NullPointerException. With the patch, the
                              test passes.</p>
                            <p>It looks like classData is not treated as
                              a static field of the class, but rather an
                              instance field in the mirror. So classData
                              wasn't copied by the loop in
                              HeapShared::copy_preinitialized_mirror().</p>
                            <p>Ashutosh, could you try it this fixes the
                              crash on your side?<br>
                            </p>
                            <p>Thanks</p>
                            <p>- Ioi<br>
                            </p>
                            <p>diff --git
                              a/src/hotspot/share/cds/heapShared.cpp
                              b/src/hotspot/share/cds/heapShared.cpp<br>
                              index 0e70778f057..62cf142f67a 100644<br>
                              --- a/src/hotspot/share/cds/heapShared.cpp<br>
                              +++ b/src/hotspot/share/cds/heapShared.cpp<br>
                              @@ -634,6 +634,8 @@ void
                              HeapShared::copy_preinitialized_mirror(Klass*
                              orig_k, oop orig_mirror, oop<br>
                                   }<br>
                                 }<br>
                               <br>
                              +  java_lang_Class::set_class_data(m,
                              java_lang_Class::class_data(orig_mirror));<br>
                              +<br>
                                 // Class::reflectData use
                              SoftReference, which cannot be archived.
                              Set it<br>
                                 // to null and it will be recreated at
                              runtime.<br>
                                 java_lang_Class::set_reflection_data(m,
                              nullptr);<br>
                              <br>
                            </p>
                            <p><br>
                            </p>
                            <p><br>
                            </p>
                            <div>On 9/19/24 12:51 PM, <a href="mailto:ioi.lam@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">ioi.lam@oracle.com</a>
                              wrote:<br>
                            </div>
                            <blockquote type="cite">
                              <p><br>
                              </p>
                              <div>On 9/19/24 7:44 AM, Ashutosh Mehra
                                wrote:<br>
                              </div>
                              <blockquote type="cite">
                                <div dir="ltr">
                                  <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">As
                                    I am cleaning up the code for
                                    upstreaming to mainline, I am going
                                    add an equivalent check in the C
                                    code to filter out these indy call
                                    sites, so they won't be resolved at
                                    all during the assembly phase.
                                    Otherwise, I will run into problems
                                    described in <a href="https://bugs.openjdk.org/browse/JDK-8290417" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8290417</a></blockquote>
                                  <div><br>
                                  </div>
                                  <div>Thanks for the link to the bug.
                                    The scenario described in that bug
                                    is exactly the same as the
                                    Infinispan case.</div>
                                  <div>So if we filter out such cases
                                    during indy resolution then it
                                    should resolve the Infinispan issue
                                    as well.</div>
                                  <div><br>
                                  </div>
                                  <div>A basic question: why can't CDS
                                    handle the lambda proxy class
                                    generated in <span style="color:rgb(31,35,40)"><font face="arial, sans-serif">useImplMethodHandle</font></span><span style="color:rgb(31,35,40);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji""> mode?</span><br>
                                  </div>
                                  <div><span style="color:rgb(31,35,40);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji""><br>
                                    </span></div>
                                </div>
                              </blockquote>
                              <p>If I remember correctly, it has to do
                                with the shape of dynamically generated
                                bytecode:</p>
                              <p>  public void accept(java.lang.Object);<br>
                                    Code:<br>
                                       0: ldc #28 // Dynamic
                                #0:_:Ljava/lang/invoke/MethodHandle;<br>
                                       2: aload_0<br>
                                       3: getfield #15 // Field
                                arg$1:LTester;<br>
                                       6: aload_1<br>
                                       7: checkcast #30 // class
                                java/lang/String<br>
                                      10: invokevirtual #36 // Method
                                java/lang/invoke/MethodHandle.invokeExact:(LTester;Ljava/lang/String;)V<br>
                                      13: return<br>
                              </p>
                              <p>The result of the "ldc" was not
                                symbolically encoded in the generated
                                class (as the generated class has no
                                permission to access that method). So
                                the MethodHandle is stored as a binary
                                object in the mirror of this generated
                                class (with the
                                java.lang.Class::classData field).</p>
                              <p>Plain CDS doesn't archive class
                                mirrors, so the classData will be lost.</p>
                              <p>With JEP 483, we should be able to
                                preserve the classData, so I am not sure
                                why the useImplMethodHandle case is
                                still failing. My plan is to filter
                                these out for now, but I will get back
                                to it later when I have more time.</p>
                              <p>Thanks</p>
                              <p>- Ioi<br>
                              </p>
                              <br>
                              <p><br>
                              </p>
                              <p><br>
                              </p>
                              <blockquote type="cite">
                                <div dir="ltr">
                                  <div><span style="color:rgb(31,35,40);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"">Thanks,</span></div>
                                  <div>
                                    <div dir="ltr" class="gmail_signature">
                                      <div dir="ltr">- Ashutosh Mehra</div>
                                    </div>
                                  </div>
                                  <br>
                                </div>
                                <br>
                                <div class="gmail_quote">
                                  <div dir="ltr" class="gmail_attr">On
                                    Thu, Sep 19, 2024 at 1:45 AM <<a href="mailto:ioi.lam@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">ioi.lam@oracle.com</a>>
                                    wrote:<br>
                                  </div>
                                  <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                    <div>
                                      <p>Hi Ashutosh,<br>
                                      </p>
                                      <p>I have some update:</p>
                                      <p>The original crash was caused
                                        by the "useImplMethodHandle"
                                        code in
                                        InnerClassLambdaMetafactory.java:<br>
                                      </p>
                                      <p>        // If the target class
                                        invokes a protected method
                                        inherited from a<br>
                                                // superclass in a
                                        different package, or does
                                        'invokespecial', the<br>
                                                // lambda class has no
                                        access to the resolved method,
                                        or does<br>
                                                // 'invokestatic' on a
                                        hidden class which cannot be
                                        resolved by name.<br>
                                                // Instead, we need to
                                        pass the live implementation
                                        method handle to<br>
                                                // the proxy class to
                                        invoke directly. (javac prefers
                                        to avoid this<br>
                                                // situation by
                                        generating bridges in the target
                                        class)<br>
                                                useImplMethodHandle =
                                        (Modifier.isProtected(implInfo.getModifiers())
                                        &&<br>
                                                                      
                                        !VerifyAccess.isSamePackage(targetClass,
                                        implInfo.getDeclaringClass()))
                                        ||<br>
                                                                      
                                        implKind ==
                                        MethodHandleInfo.REF_invokeSpecial
                                        ||<br>
                                                                      
                                        implKind ==
                                        MethodHandleInfo.REF_invokeStatic
                                        && implClass.isHidden();<br>
                                      </p>
                                      <p>As I am cleaning up the code
                                        for upstreaming to mainline, I
                                        am going add an equivalent check
                                        in the C code to filter out
                                        these indy call sites, so they
                                        won't be resolved at all during
                                        the assembly phase. Otherwise, I
                                        will run into problems described
                                        in <a href="https://bugs.openjdk.org/browse/JDK-8290417" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/JDK-8290417</a><br>
                                      </p>
                                      <p>Once I get the filtering code
                                        working, I will integrate it
                                        back to premain.<br>
                                      </p>
                                      <p>>I am wondering if we can
                                        workaround class circularity
                                        issues by recording class
                                        initialization order<br>
                                        >during training run and use
                                        that to guide the initialization
                                        during assembly phase.<br>
                                      </p>
                                      <p>In the production run we take
                                        different paths than the
                                        training run<br>
                                      </p>
                                      <p>(1) some classes are
                                        aot-initialized (especially the
                                        enums)<br>
                                        (2) some classes make special
                                        CDS calls<br>
                                      </p>
                                      <p>so I am not sure if it's
                                        possible to get the same
                                        initialization order as in the
                                        training run (or assembly
                                        phase).</p>
                                      <p>(more below)<br>
                                      </p>
                                      <div>On 9/18/24 9:10 AM, Ashutosh
                                        Mehra wrote:<br>
                                      </div>
                                      <blockquote type="cite">
                                        <div dir="ltr">Hi Ioi,
                                          <div><br>
                                          </div>
                                          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I
                                            was having a similar
                                            circularity issue (but in
                                            production time) and I just
                                            added enough classes to make
                                            the NPE go away.<br>
                                          </blockquote>
                                          <div> </div>
                                          <div>
                                            <div>I am wondering if you
                                              have a test case that
                                              reproduces the NPE which
                                              prompted you to add these
                                              classes:</div>
                                            <div><br>
                                            </div>
                                            <div><a href="https://urldefense.com/v3/__https://github.com/openjdk/leyden/blob/7781109154bf2af89854c7e13aa3e160bb82608e/src/hotspot/share/cds/aotClassInitializer.cpp*L65-L78__;Iw!!ACWV5N9M2RV99hQ!NYvqLbb_Ib2kSdm2fcYVLGby-AiB2TG7KtC1HQHVKLiM-_kRb5mOt8krV5IZfReaYZ0MPadDfa08hQ$" target="_blank" moz-do-not-send="true">https://github.com/openjdk/leyden/blob/7781109154bf2af89854c7e13aa3e160bb82608e/src/hotspot/share/cds/aotClassInitializer.cpp#L65-L78</a></div>
                                            <div><br>
                                            </div>
                                            <div>I commented this code
                                              and ran the tests under
                                              premain but didn't hit the
                                              NPE.</div>
                                            <div><br>
                                            </div>
                                          </div>
                                        </div>
                                      </blockquote>
                                      <p>I forgot what the problem was,
                                        but it happened for very simple
                                        cases.<br>
                                      </p>
                                      <p>Thanks</p>
                                      <p>- Ioi<br>
                                      </p>
                                      <p><br>
                                      </p>
                                      <blockquote type="cite">
                                        <div dir="ltr">
                                          <div>
                                            <div>Thanks,</div>
                                            <div>
                                              <div>
                                                <div dir="ltr" class="gmail_signature">
                                                  <div dir="ltr">-
                                                    Ashutosh Mehra</div>
                                                </div>
                                              </div>
                                              <br>
                                            </div>
                                          </div>
                                        </div>
                                        <br>
                                        <div class="gmail_quote">
                                          <div dir="ltr" class="gmail_attr">On Tue,
                                            Sep 17, 2024 at 1:11 AM <<a href="mailto:ioi.lam@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">ioi.lam@oracle.com</a>> wrote:<br>
                                          </div>
                                          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                            <div>
                                              <p>Hi Ashutosh,<br>
                                              </p>
                                              <p>So this looks like a
                                                potential bug (or
                                                feature) in the core lib
                                                code. When CDS
                                                forcefully initializes a
                                                class in an unexpected
                                                (or untested) order, the
                                                "initialization soup"
                                                fails.</p>
                                              <p>Perhaps a work-around
                                                would be to make some
                                                harmless calls at the
                                                place where CDS was
                                                calling into
                                                MethodType.createArchivedObjects().
                                                E.g., do something like
                                                this:</p>
                                              <p><font face="monospace">+   
                                                  if
(CDSConfig::is_dumping_invokedynamic()) {<br>
                                                  +       // call into
                                                  Java:
                                                  jdk.internal.misc::warmupInvokeDynamic();<br>
                                                  +   }<br>
                                                      // Rewrite and
                                                  link classes<br>
                                                     
                                                  log_info(cds)("Rewriting
                                                  and linking classes
                                                  ...");<br>
                                                  <br>
                                                </font>Maybe you can add
                                                a new Lambda
                                                expressions,
                                                MethodHandle
                                                invocations, etc, that
                                                would hopefully cause
                                                PrimitiveClassDescImpl
                                                and friends to be
                                                initialized in their
                                                natural order.<br>
                                              </p>
                                              <p>Or call
                                                class.forName("java.lang.constant.ConstantDescs")
                                                ??</p>
                                              <p>BTW, you can see my
                                                comments in
AOTClassInitializer::is_forced_preinit_class():<br>
                                                <br>
                                                    // TODO:<br>
                                                    // This is needed
                                                since JDK-8338532.
                                                Without this, when<br>
                                                    // archived heap
                                                objects are used, the
                                                class init order is not<br>
                                                    // expected by the
                                                jdk/internal/constant
                                                bootstrap code and we<br>
                                                    // will get a null
                                                pointer exception.<br>
                                                    //<br>
                                                    // When bootstraping
                                                has intricated/fragile
                                                order, it's probably<br>
                                                    // better to archive
                                                all related classes in
                                                an initialized state<br>
                                                    // (i.e., take a
                                                snapshot). The existing
                                                approach in<br>
                                                    //
                                                heapShared::resolve_or_init_classes_for_subgraph_of()
                                                won't work.<br>
                                                   
                                                "jdk/internal/constant/PrimitiveClassDescImpl",<br>
                                                   
                                                "jdk/internal/constant/ReferenceClassDescImpl",<br>
                                                   
                                                "java/lang/constant/ConstantDescs",<br>
                                                   
                                                "sun/invoke/util/Wrapper",<br>
                                                <br>
                                                I was having a similar
                                                circularity issue (but
                                                in production time) and
                                                I just added enough
                                                classes to make the NPE
                                                go away. For your test
                                                case, if you manage to
                                                fix in in the assembly
                                                run but run into NPE in
                                                production run, you
                                                might need to add more
                                                classes to this list.
                                                Yes, it's a hack :-(<br>
                                              </p>
                                              <p><br>
                                              </p>
                                              <p>Thanks</p>
                                              <p>- Ioi<br>
                                              </p>
                                              <div>On 9/13/24 7:05 PM,
                                                Ashutosh Mehra wrote:<br>
                                              </div>
                                              <blockquote type="cite">
                                                <div dir="ltr">This is
                                                  turning out to be a
                                                  real example of class
                                                  initialization soup!
                                                  <div>As mentioned
                                                    during the meeting,
                                                    I am getting NPE in
                                                    the assembly phase
                                                    when testing the
                                                    patch [0] that I
                                                    proposed in my
                                                    earlier mail </div>
                                                  <div>using a test case
                                                    inspired by the
                                                    Infinispan code.</div>
                                                  <div>NPE occurs when
                                                    running the class
                                                    initializer for <font face="monospace">PrimitiveClassDescImpl </font></div>
                                                  <div>
                                                    <div>Interestingly, <span style="font-family:monospace">PrimitiveClassDescImpl</span> is
                                                      "forcefully"
                                                      initialized by <font face="monospace">MetaspaceShared::link_shared_classes()</font>.</div>
                                                    <div><br>
                                                    </div>
                                                    <div>
                                                      <div>
                                                        <div dir="ltr" class="gmail_signature">
                                                          <div dir="ltr">I
                                                          couldn't get a
                                                          stack trace so
                                                          I relied on
                                                          exception logs
                                                          (using
                                                          -Xlog:exceptions=trace)
                                                          to find the
                                                          cause which
                                                          indicate
                                                          following
                                                          frames on the
                                                          stack:</div>
                                                          <div dir="ltr"><br>
                                                          </div>
                                                          <div dir="ltr"><font face="monospace">[0]
jdk/internal/constant/MethodTypeDescImpl::validateArgument(Ljava/lang/constant/ClassDesc;)Ljava/lang/constant/ClassDesc; @
                                                          bci 1<br>
                                                          </font></div>
                                                          <div dir="ltr"><font face="monospace">[1]
jdk/internal/constant/MethodTypeDescImpl::ofTrusted(Ljava/lang/constant/ClassDesc;[Ljava/lang/constant/ClassDesc;)Ljdk/internal/constant/MethodTypeDescImpl; @
                                                          bci 27<br>
                                                          </font></div>
                                                          <div dir="ltr"><font face="monospace">[2]
java/lang/constant/ConstantDescs::ofConstantBootstrap(Ljava/lang/constant/ClassDesc;Ljava/lang/String;Ljava/lang/constant/ClassDesc;[Ljava/lang/constant/ClassDesc;)Ljava/lang/constant/DirectMethodHandleDesc; @
                                                          bci 47</font></div>
                                                          <div dir="ltr"><font face="monospace">[3]
java/lang/constant/ConstantDescs::<clinit> @ bci 664<br>
                                                          </font></div>
                                                          <div dir="ltr"><font face="monospace">[4]
jdk/internal/constant/PrimitiveClassDescImpl::<init>(Ljava/lang/String;)V @
                                                          bci 1<br>
                                                          </font></div>
                                                          <div dir="ltr"><font face="monospace">[5]
jdk/internal/constant/PrimitiveClassDescImpl::<clinit>(Ljava/lang/String;)V @
                                                          bci 6</font><span style="font-family:monospace"><br>
                                                          </span></div>
                                                          <div dir="ltr"><span style="font-family:monospace"><br>
                                                          </span></div>
                                                          <div dir="ltr">Notice that
                                                          invocation of <font face="monospace">PrimitiveClassDescImpl::<clinit> </font>results
                                                          in
                                                          initialization
                                                          of <font face="monospace">ConstantDescs</font> class (see frame 3).<br>
                                                          </div>
                                                          <div><font face="monospace">ConstantDescs::<clinit> @ 664 </font><font face="arial, sans-serif">corresponds to following java code:</font></div>
                                                          <div><br>
                                                          </div>
                                                          <div><font face="monospace">    public static final DirectMethodHandleDesc
                                                          BSM_CLASS_DATA_AT<br>
                                                          </font></div>
                                                          <div><font face="monospace">            = ofConstantBootstrap(CD_MethodHandles,
                                                          "classDataAt",<br>
                                                                     
                                                          CD_Object,
                                                          CD_int);<br>
                                                          </font></div>
                                                          <div><br>
                                                          </div>
                                                          <div>The last
                                                          parameter
                                                          CD_int is
                                                          initialized
                                                          as:</div>
                                                          <div><br>
                                                          </div>
                                                          <div><font face="monospace">    public static final ClassDesc CD_int =
                                                          PrimitiveClassDescImpl.CD_int;<br>
                                                          </font></div>
                                                          <div><br>
                                                          </div>
                                                          <div>So, its
                                                          value is
                                                          obtained from
                                                          <font face="monospace">PrimitiveClassDescImpl.CD_int</font> which hasn't been
                                                          initialized
                                                          properly yet.
                                                          As a result <font face="monospace">ConstantDescs::CD_int </font><font face="arial, sans-serif">is assigned</font> null which results in <font face="monospace">MethodTypeDescImpl::validateArgument</font> throwing
                                                          NPE later.</div>
                                                          <div>There is
                                                          a clear class
                                                          initialization
                                                          circularity
                                                          involving <font face="monospace">PrimitiveClassDescImpl</font> and <font face="monospace">ConstantDescs</font>, and the result depends on which
                                                          class gets
                                                          initialized
                                                          first.</div>
                                                          <div><br>
                                                          </div>
                                                          <div>Without
                                                          my patch this
                                                          issue is not
                                                          seen because <font face="monospace">PrimitiveClassDescImpl</font> has already been
                                                          initialized by
                                                          the time <font face="monospace">MetaspaceShared::link_shared_classes()</font><font face="arial, sans-serif"> is called.</font></div>
                                                          <div><font face="arial, sans-serif">Its initialization is triggered by the call to </font><font face="monospace">MethodType::createArchivedObjects(). </font></div>
                                                          <div><font face="arial, sans-serif">It also explains why my patch introduced this
                                                          issue because
                                                          it effectively
                                                          moved the call
                                                          to </font><span style="font-family:monospace">MethodType::createArchivedObjects() </span><font face="arial, sans-serif">after </font><span style="font-family:monospace">MetaspaceShared::link_shared_classes().</span></div>
                                                          <div><span style="font-family:monospace"><br>
                                                          </span></div>
                                                          <div><font face="arial, sans-serif">[0] <a href="https://urldefense.com/v3/__https://github.com/ashu-mehra/leyden/commit/d8f99cce67df1c7b0f7ef8562676df438633a66e__;!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhZK3GwoiA$" target="_blank" moz-do-not-send="true">https://github.com/ashu-mehra/leyden/commit/d8f99cce67df1c7b0f7ef8562676df438633a66e</a></font></div>
                                                          <div><font face="arial, sans-serif"><br>
                                                          </font></div>
                                                          <div><font face="arial, sans-serif">Thanks,</font></div>
                                                          <div><font face="arial, sans-serif">- Ashutosh Mehra</font></div>
                                                        </div>
                                                      </div>
                                                      <br>
                                                    </div>
                                                  </div>
                                                </div>
                                                <br>
                                                <div class="gmail_quote">
                                                  <div dir="ltr" class="gmail_attr">On
                                                    Wed, Sep 11, 2024 at
                                                    3:12 PM Ashutosh
                                                    Mehra <<a href="mailto:asmehra@redhat.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">asmehra@redhat.com</a>> wrote:<br>
                                                  </div>
                                                  <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                                    <div dir="ltr">Regarding
                                                      the
                                                      WrongMethodTypeException
                                                      that I mentioned
                                                      in my previous
                                                      email (see pt 3),
                                                      <div>this
                                                        exception
                                                        happens when
                                                        lambda proxy
                                                        class attempts
                                                        to invoke the
                                                        MethodHandle it
                                                        obtained from
                                                        the classData:</div>
                                                      <div><br>
                                                      </div>
                                                      <div><font face="monospace">  public void accept(java.lang.Object);<br>
                                                             
                                                          descriptor:
                                                          (Ljava/lang/Object;)V<br>
                                                              flags:
                                                          (0x0001)
                                                          ACC_PUBLIC<br>
                                                              Code:<br>
                                                                stack=3,
                                                          locals=2,
                                                          args_size=2<br>
                                                                   0:
                                                          ldc          
                                                          #26          
                                                                //
                                                          Dynamic
                                                          #0:_:Ljava/lang/invoke/MethodHandle;<br>
                                                                   2:
                                                          aload_0<br>
                                                                   3:
                                                          getfield    
                                                           #13          
                                                                // Field
arg$1:Lorg/wildfly/security/WildFlyElytronBaseProvider;<br>
                                                                   6:
                                                          aload_1<br>
                                                                   7:
                                                          checkcast    
                                                          #28          
                                                                // class
java/security/Provider$Service<br>
                                                                  10:
                                                          invokevirtual
                                                          #34          
                                                                //
                                                          Method
java/lang/invoke/MethodHandle.invokeExact:(Lorg/wildfly/security/WildFlyElytronBaseProvider;Ljava/security/Provider$Service;)V<br>
                                                                  13:
                                                          return</font><br>
                                                      </div>
                                                      <div><br>
                                                      </div>
                                                      <div>
                                                        <div>The
                                                          scenario is
                                                          during the
                                                          assembly phase
                                                          as part of the
                                                          indy
                                                          resolution the
                                                          MethodHandle
                                                          for which the
                                                          exception is
                                                          thrown gets
                                                          created.</div>
                                                        <div>Normally
                                                          MethodHandle's
                                                          type gets
                                                          added in <font face="monospace">MethodType::internTable</font> but by the time indy
                                                          resolution
                                                          happens, JVM
                                                          has already
                                                          taken </div>
                                                        <div>snapshot of
                                                          the <font face="monospace">MethodType::internTable</font> through an upcall to <font face="monospace">MethodType::createArchivedObjects()</font>.</div>
                                                        <div>As a result
                                                          the AOTCache
                                                          ends up with
                                                          the MethodType
                                                          object which
                                                          is not in <font face="monospace">AOTHolder.archivedMethodTypes</font>.</div>
                                                        <div><br>
                                                        </div>
                                                        <div>During the
                                                          production
                                                          run, when the
                                                          jvm invokes
                                                          the
                                                          MethodHandle,
                                                          it searches
                                                          for the
                                                          MethodType
                                                          corresponding
                                                          to the
                                                          signature
                                                          passed at the
                                                          callsite.</div>
                                                        <div>As
                                                          expected, it
                                                          fails to find
                                                          it in the <font face="monospace">AOTHolder.archivedMethodTypes</font>, so it creates a
                                                          new instance
                                                          of the
                                                          MethodType.</div>
                                                        <div>But <font face="monospace">Invokers.checkExactType()</font> relies on the
                                                          MethodHandle's type
                                                          to be the same
                                                          object as the
                                                          MethodType
                                                          object passed
                                                          as parameter.</div>
                                                        <div><br>
                                                        </div>
                                                        <div><font face="monospace">    static void checkExactType(M</font><span style="font-family:monospace">ethodHandle mh</span><span style="font-family:monospace">M, MethodType expected) {</span></div>
                                                        <div><font face="monospace">        MethodType targetType = mh.type();<br>
                                                                  if
                                                          (targetType !=
                                                          expected)<br>
                                                                     
                                                          throw
                                                          newWrongMethodTypeException(targetType,
                                                          expected);<br>
                                                              }</font><br>
                                                        </div>
                                                        <div><br>
                                                        </div>
                                                        <div>Hence, it
                                                          throws <span style="font-family:monospace">WrongMethodTypeException</span><font face="arial, sans-serif"> though the two MT objects have the same
                                                          signature.</font></div>
                                                        <div><font face="arial, sans-serif"><br>
                                                          </font></div>
                                                        <div><font face="arial, sans-serif">To handle this scenario, I changed the order of
                                                          indy
                                                          resolution
                                                          and </font>upcall
                                                          to <font face="monospace">MethodType::createArchivedObjects()</font><font face="arial, sans-serif"> as:</font></div>
                                                        <div><font face="arial, sans-serif"><br>
                                                          </font></div>
                                                        <div><font face="monospace">diff --git a/src/hotspot/share/cds/metaspaceShared.cpp
b/src/hotspot/share/cds/metaspaceShared.cpp<br>
                                                          index
                                                          df4bcadefa3..457716cac5b
                                                          100644<br>
                                                          ---
                                                          a/src/hotspot/share/cds/metaspaceShared.cpp<br>
                                                          +++
                                                          b/src/hotspot/share/cds/metaspaceShared.cpp<br>
                                                          @@ -751,6
                                                          +751,20 @@
                                                          void
                                                          MetaspaceShared::link_shared_classes(bool
                                                          jcmd_request,
                                                          TRAPS) {<br>
                                                             if
                                                          (CDSConfig::is_dumping_final_static_archive())
                                                          {<br>
                                                             
                                                           FinalImageRecipes::apply_recipes(CHECK);<br>
                                                             }<br>
                                                          +<br>
                                                          +#if
                                                          INCLUDE_CDS_JAVA_HEAP<br>
                                                          +  if
                                                          (CDSConfig::is_dumping_invokedynamic())
                                                          {<br>
                                                          +    // This
                                                          makes sure
                                                          that the
                                                          MethodType and
                                                          MethodTypeForm
                                                          tables won't
                                                          be updated<br>
                                                          +    //
                                                          concurrently
                                                          when we are
                                                          saving their
                                                          contents into
                                                          a side table.<br>
                                                          +  
                                                           assert(CDSConfig::allow_only_single_java_thread(),
                                                          "Required");<br>
                                                          +<br>
                                                          +    JavaValue
result(T_VOID);<br>
                                                          +  
                                                           JavaCalls::call_static(&result,
vmClasses::MethodType_klass(),<br>
                                                          +            
                                                                       
vmSymbols::createArchivedObjects(),<br>
                                                          +            
                                                                       
vmSymbols::void_method_signature(),<br>
                                                          +            
                                                                       
                                                          CHECK);<br>
                                                          +  }<br>
                                                          +#endif<br>
                                                           }</font><br>
                                                           </div>
                                                        <div>Note that
                                                          indy
                                                          resolution
                                                          happens as
                                                          part of <span style="font-family:monospace">FinalImageRecipes::apply_recipes(CHECK) </span><font face="arial, sans-serif">which is now invoked before the upcall to </font><span style="font-family:monospace">createArchivedObjects().</span></div>
                                                        <div><font face="arial, sans-serif">With this change I am able to run the
                                                          application
                                                          without any
                                                          exceptions.</font></div>
                                                        <div>My complete
                                                          patch can be
                                                          seen here: <a href="https://urldefense.com/v3/__https://github.com/ashu-mehra/leyden/commit/d8f99cce67df1c7b0f7ef8562676df438633a66e__;!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhZK3GwoiA$" target="_blank" moz-do-not-send="true">https://github.com/ashu-mehra/leyden/commit/d8f99cce67df1c7b0f7ef8562676df438633a66e</a></div>
                                                        <div>I will do
                                                          more testing
                                                          with this
                                                          patch.</div>
                                                        <div><br>
                                                        </div>
                                                        <div><a class="gmail_plusreply" id="m_5728834885895654793m_-8594911495544208436m_-6235568143876299380m_5385423560619785655m_-6081196208708063630m_-8326742188757259955m_-669397441264475055m_4538222356731470316m_-1862706623606286828plusReplyChip-0" href="mailto:ioi.lam@oracle.com" target="_blank" moz-do-not-send="true">@Ioi
                                                          Lam</a> do you
                                                          have any
                                                          feedback on
                                                          this patch.<br>
                                                        </div>
                                                        <div><br>
                                                        </div>
                                                        <div>Thanks,<br clear="all">
                                                          <div>
                                                          <div dir="ltr" class="gmail_signature">
                                                          <div dir="ltr">-
                                                          Ashutosh Mehra</div>
                                                          </div>
                                                          </div>
                                                          <br>
                                                        </div>
                                                        <div><br>
                                                        </div>
                                                      </div>
                                                    </div>
                                                    <br>
                                                    <div class="gmail_quote">
                                                      <div dir="ltr" class="gmail_attr">On Wed, Sep 11, 2024 at 10:14 AM Ashutosh Mehra <<a href="mailto:asmehra@redhat.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">asmehra@redhat.com</a>> wrote:<br>
                                                      </div>
                                                      <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                                        <div dir="ltr">Hi
                                                          Andrew,
                                                          <div>Thanks
                                                          for sharing
                                                          the initial
                                                          investigation.
                                                          <div>I have
                                                          been looking
                                                          into this and
                                                          have a few of
                                                          things to add
                                                          to your
                                                          analysis:</div>
                                                          <div><br>
                                                          </div>
                                                          <div>1.  As
                                                          you mentioned
                                                          the classData
                                                          for the lambda
class WildFlyElytronBaseProvider$$Lambda is null.</div>
                                                          <div>The
                                                          classData is
                                                          stored in the
                                                          mirror object
                                                          of the
                                                          InstanceKlass
                                                          when the class
                                                          is defined
                                                          through JVM_LookupDefineClass.</div>
                                                          <div>However,
                                                          when we create
                                                          the scratch
                                                          mirror object
                                                          (which get
                                                          stored in the
                                                          AOT cache) the
                                                          classData is
                                                          not populated.</div>
                                                          <div>See <a href="https://urldefense.com/v3/__https://github.com/openjdk/leyden/blob/d23b9f2d5e3523cc547337da59327ed86a6057a3/src/hotspot/share/classfile/javaClasses.cpp*L1128-L1131__;Iw!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhbKjzG3gw$" target="_blank" moz-do-not-send="true">https://github.com/openjdk/leyden/blob/d23b9f2d5e3523cc547337da59327ed86a6057a3/src/hotspot/share/classfile/javaClasses.cpp#L1128-L1131</a></div>
                                                          <div><br>
                                                          </div>
                                                          <div><font face="monospace">  Handle classData; // set to null. Will be
                                                          reinitialized
                                                          at runtime<br>
                                                            Handle
                                                          mirror;<br>
                                                            Handle
                                                          comp_mirror;<br>
                                                           
                                                          allocate_mirror(k,
/*is_scratch=*/true, protection_domain, classData, mirror, comp_mirror,
                                                          CHECK);</font><br>
                                                          </div>
                                                          <div><br>
                                                          </div>
                                                          <div>So this
                                                          explains why
                                                          the call to <font face="monospace">classData(caller.lookupClass())</font><font face="arial, sans-serif"> returned null.</font></div>
                                                          <div><br>
                                                          </div>
                                                          <div>2. In the
                                                          mainline there
                                                          is a check
                                                          in InnerClassLambdaMetafactory.java
                                                          for the
                                                          particular
                                                          code pattern
                                                          used by the
                                                          application.</div>
                                                          <div>If this
                                                          code pattern
                                                          is found then
                                                          the lambda
                                                          proxy class is
                                                          not included
                                                          in the CDS
                                                          archive.</div>
                                                          <div>See <a href="https://urldefense.com/v3/__https://github.com/openjdk/leyden/blob/d23b9f2d5e3523cc547337da59327ed86a6057a3/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java*L163-L170__;Iw!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhZl2S9tQg$" target="_blank" moz-do-not-send="true">https://github.com/openjdk/leyden/blob/d23b9f2d5e3523cc547337da59327ed86a6057a3/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java#L163-L170</a></div>
                                                          <div>and <a href="https://urldefense.com/v3/__https://github.com/openjdk/leyden/blob/d23b9f2d5e3523cc547337da59327ed86a6057a3/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java*L246__;Iw!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhYsI3Xx0g$" target="_blank" moz-do-not-send="true">https://github.com/openjdk/leyden/blob/d23b9f2d5e3523cc547337da59327ed86a6057a3/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java#L246</a></div>
                                                          <div><br>
                                                          </div>
                                                          <div><font face="monospace">        // If the target class invokes a protected
                                                          method
                                                          inherited from
                                                          a<br>
                                                                  //
                                                          superclass in
                                                          a different
                                                          package, or
                                                          does
                                                          'invokespecial',
                                                          the<br>
                                                                  //
                                                          lambda class
                                                          has no access
                                                          to the
                                                          resolved
                                                          method, or
                                                          does<br>
                                                                  //
                                                          'invokestatic'
                                                          on a hidden
                                                          class which
                                                          cannot be
                                                          resolved by
                                                          name.<br>
                                                                  //
                                                          Instead, we
                                                          need to pass
                                                          the live
                                                          implementation
                                                          method handle
                                                          to<br>
                                                                  // the
                                                          proxy class to
                                                          invoke
                                                          directly.
                                                          (javac prefers
                                                          to avoid this<br>
                                                                  //
                                                          situation by
                                                          generating
                                                          bridges in the
                                                          target class)<br>
                                                                 
                                                          useImplMethodHandle
                                                          =
                                                          (Modifier.isProtected(implInfo.getModifiers())
                                                          &&<br>
                                                                       
                                                                       
                                                           
                                                           !VerifyAccess.isSamePackage(targetClass,
implInfo.getDeclaringClass())) ||<br>
                                                                       
                                                                       
                                                             implKind ==
MethodHandleInfo.REF_invokeSpecial ||<br>
                                                                       
                                                                       
                                                             implKind ==
MethodHandleInfo.REF_invokeStatic && implClass.isHidden();</font><br>
                                                          </div>
                                                          <div><br>
                                                          </div>
                                                          <div>In
                                                          premain lambda
                                                          proxy classes
                                                          get included
                                                          in the AOT
                                                          cache as a
                                                          result of indy
                                                          resolution and
                                                          that mechanism
                                                          doesn't have
                                                          this kind of
                                                          check.</div>
                                                          <div><br>
                                                          </div>
                                                          <div>3. For
                                                          the null
                                                          classData
                                                          problem
                                                          mentioned
                                                          above, I tried
                                                          to fix it by
                                                          storing
                                                          classData in
                                                          the scratch
                                                          mirror using
                                                          the following
                                                          patch:<br>
                                                          <br>
                                                          </div>
                                                          <div><font face="monospace">diff --git
a/src/hotspot/share/classfile/javaClasses.cpp
b/src/hotspot/share/classfile/javaClasses.cpp<br>
                                                          index
                                                          bd8141adbcc..41766e98093
                                                          100644<br>
                                                          ---
                                                          a/src/hotspot/share/classfile/javaClasses.cpp<br>
                                                          +++
                                                          b/src/hotspot/share/classfile/javaClasses.cpp<br>
                                                          @@ -1094,9
                                                          +1094,9 @@
                                                          void
java_lang_Class::create_mirror(Klass* k, Handle class_loader,<br>
                                                               }<br>
                                                               if
                                                          (CDSConfig::is_dumping_heap())
                                                          {<br>
                                                                 if
                                                          (CDSConfig::is_dumping_protection_domains())
                                                          {<br>
                                                          -      
                                                           create_scratch_mirror(k,
protection_domain, CHECK);<br>
                                                          +      
                                                           create_scratch_mirror(k,
protection_domain, classData, CHECK);<br>
                                                                 } else
                                                          {<br>
                                                          -      
                                                           create_scratch_mirror(k,
                                                          Handle() /*
                                                          null
protection_domain*/, CHECK);<br>
                                                          +      
                                                           create_scratch_mirror(k,
                                                          Handle() /*
                                                          null
protection_domain*/, classData, CHECK);<br>
                                                                 }<br>
                                                               }<br>
                                                             } else {<br>
                                                          @@ -1117,7
                                                          +1117,7 @@
                                                          void
java_lang_Class::create_mirror(Klass* k, Handle class_loader,<br>
                                                           // Note: we
                                                          archive the
                                                          "scratch
                                                          mirror"
                                                          instead of
                                                          k->java_mirror(),
                                                          because the<br>
                                                           // latter may
                                                          contain
                                                          dumptime-specific
                                                          information
                                                          that cannot be
                                                          archived<br>
                                                           // (e.g.,
                                                          ClassLoaderData*,
                                                          or static
                                                          fields that
                                                          are modified
                                                          by Java code
                                                          execution).<br>
                                                          -void
                                                          java_lang_Class::create_scratch_mirror(Klass*
                                                          k, Handle
                                                          protection_domain,
                                                          TRAPS) {<br>
                                                          +void
                                                          java_lang_Class::create_scratch_mirror(Klass*
                                                          k, Handle
                                                          protection_domain,
                                                          Handle
                                                          classData,
                                                          TRAPS) {<br>
                                                             if
                                                          (k->class_loader()
                                                          != nullptr
                                                          &&<br>
                                                               
                                                           k->class_loader()
                                                          !=
SystemDictionary::java_platform_loader() &&<br>
                                                               
                                                           k->class_loader()
                                                          !=
SystemDictionary::java_system_loader()) {<br>
                                                          @@ -1125,9
                                                          +1125,11 @@
                                                          void
java_lang_Class::create_scratch_mirror(Klass* k, Handle
                                                          protection_domain,<br>
                                                               return;<br>
                                                             }<br>
                                                           <br>
                                                          -  Handle
                                                          classData; //
                                                          set to null.
                                                          Will be
                                                          reinitialized
                                                          at runtime<br>
                                                          +  //Handle
                                                          classData; //
                                                          set to null.
                                                          Will be
                                                          reinitialized
                                                          at runtime<br>
                                                             Handle
                                                          mirror;<br>
                                                             Handle
                                                          comp_mirror;<br>
                                                           
                                                           allocate_mirror(k,
/*is_scratch=*/true, protection_domain, classData, mirror, comp_mirror,
                                                          CHECK);<br>
                                                           <br>
                                                             if
                                                          (comp_mirror()
                                                          != nullptr) {<br>
                                                          diff --git
                                                          a/src/hotspot/share/classfile/javaClasses.hpp
b/src/hotspot/share/classfile/javaClasses.hpp<br>
                                                          index
                                                          bc49a0861a7..7ec2a2556dd
                                                          100644<br>
                                                          ---
                                                          a/src/hotspot/share/classfile/javaClasses.hpp<br>
                                                          +++
                                                          b/src/hotspot/share/classfile/javaClasses.hpp<br>
                                                          @@ -263,7
                                                          +263,7 @@
                                                          class
                                                          java_lang_Class
                                                          : AllStatic {<br>
                                                           <br>
                                                             //
                                                          Archiving<br>
                                                             static void
serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;<br>
                                                          -  static void
create_scratch_mirror(Klass* k, Handle protection_domain, TRAPS)
                                                          NOT_CDS_JAVA_HEAP_RETURN;<br>
                                                          +  static void
create_scratch_mirror(Klass* k, Handle protection_domain, Handle
                                                          classData,
                                                          TRAPS)
NOT_CDS_JAVA_HEAP_RETURN;<br>
                                                             static bool
restore_archived_mirror(Klass *k, Handle class_loader, Handle module,<br>
                                                                       
                                                                       
                                                                   
                                                           Handle
                                                          protection_domain,<br>
                                                                       
                                                                       
                                                                   
                                                           TRAPS)
                                                          NOT_CDS_JAVA_HEAP_RETURN_(false);</font><br>
                                                          </div>
                                                          <div><br>
                                                          </div>
                                                          <div>But this
                                                          resulted in a
                                                          different
                                                          exception:</div>
                                                          <div><br>
                                                          </div>
                                                          <div><font face="monospace">Exception in thread "main"
java.lang.ExceptionInInitializerError<br>
                                                          at
                                                          com.redhat.leyden.Main.main(Main.java:7)<br>
                                                          Caused by:
                                                          java.lang.invoke.WrongMethodTypeException:
                                                          handle's
                                                          method type
                                                          (WildFlyElytronBaseProvider,Service)void
                                                          but found
                                                          (WildFlyElytronBaseProvider,Service)void<br>
                                                          at
java.base/java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:521)<br>
                                                          at
                                                          java.base/java.lang.invoke.Invokers.checkExactType(Invokers.java:530)<br>
                                                          at
java.base/java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder)<br>
                                                          at
org.wildfly.security.WildFlyElytronBaseProvider$$Lambda/0x80000000c.accept(Unknown
                                                          Source)<br>
                                                          at
org.wildfly.security.WildFlyElytronBaseProvider.putMakedPasswordImplementations(WildFlyElytronBaseProvider.java:112)<br>
                                                          at
org.wildfly.security.WildFlyElytronBaseProvider.putPasswordImplementations(WildFlyElytronBaseProvider.java:107)<br>
                                                          at
org.wildfly.security.password.WildFlyElytronPasswordProvider.<init>(WildFlyElytronPasswordProvider.java:43)<br>
                                                          at
org.wildfly.security.password.WildFlyElytronPasswordProvider.<clinit>(WildFlyElytronPasswordProvider.java:36)<br>
                                                          ... 1 more</font><br>
                                                          </div>
                                                          <div><font face="monospace"><br>
                                                          </font></div>
                                                          <div>The
                                                          exception
                                                          message is
                                                          strange
                                                          because the
                                                          handle's
                                                          method type
                                                          and the
                                                          expected type
                                                          are both
                                                          symbolically
                                                          the same.</div>
                                                          <div>I am
                                                          debugging this
                                                          exception at
                                                          the moment.</div>
                                                          <div> </div>
                                                          <div>Thanks,</div>
                                                          <div>
                                                          <div>
                                                          <div dir="ltr" class="gmail_signature">
                                                          <div dir="ltr">-
                                                          Ashutosh Mehra</div>
                                                          </div>
                                                          </div>
                                                          <br>
                                                          </div>
                                                          </div>
                                                        </div>
                                                        <br>
                                                        <div class="gmail_quote">
                                                          <div dir="ltr" class="gmail_attr">On Wed, Sep 11, 2024 at 6:03 AM Andrew Dinn <<a href="mailto:adinn@redhat.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">adinn@redhat.com</a>> wrote:<br>
                                                          </div>
                                                          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Oops,
                                                          sorry, I
                                                          debugged this
                                                          a few days
                                                          ago!
                                                          Correction to
                                                          a few details:<br>
                                                          <br>
                                                          On 11/09/2024
                                                          10:39, Andrew
                                                          Dinn wrote:<br>
                                                          > A crash
                                                          due to an NPE
                                                          was observed
                                                          in the
                                                          Infinispan
                                                          (Data Grid)
                                                          server <br>
                                                          > app when
                                                          deployed using
                                                          the Leyden EA.
                                                          The crash
                                                          still
                                                          manifests with
                                                          <br>
                                                          > the
                                                          latest premain
                                                          code. The
                                                          crash happens
                                                          below an
                                                          application
                                                          call <br>
                                                          > which
                                                          employs a
                                                          method
                                                          reference as
                                                          argument<br>
                                                          > <br>
                                                          >         
putMakedPasswordImplementations(this::putService, this);<br>
                                                          <br>
                                                          The called
                                                          method in turn
                                                          calls
                                                          consumer.accept<br>
                                                          <br>
                                                                     
                                                           consumer.accept(new
Service(provider, <br>
PASSWORD_FACTORY_TYPE, algorithm, <br>
"org.wildfly.security.password.impl.PasswordFactorySpiImpl", emptyList,
                                                          <br>
                                                          emptyMap));<br>
                                                          <br>
                                                          which enters
                                                          enters
MethodHandleNative::linkDynamicConstant()<br>
                                                          <br>
                                                          > Debugging
                                                          shows that the
                                                          call to
                                                          linkDynamicConstant()
                                                          returns null.<br>
                                                          > <br>
                                                          > A simple
                                                          reproducer for
                                                          the problem is
                                                          available as a
                                                          maven project
                                                          on <br>
                                                          > github:<br>
                                                          > <br>
                                                          >    <a href="https://urldefense.com/v3/__https://github.com/tristantarrant/elytron-leyden__;!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhZaZr1akQ$" rel="noreferrer" target="_blank" moz-do-not-send="true">https://github.com/tristantarrant/elytron-leyden</a><br>
                                                          > <br>
                                                          > The
                                                          ReadMe
                                                          provides an
                                                          explanation of
                                                          how to
                                                          reproduce the
                                                          problem. I <br>
                                                          > did so
                                                          and the
                                                          debugged to
                                                          find out some
                                                          of the details
                                                          of what is <br>
                                                          > happening
                                                          (see below)
                                                          but did not
                                                          fully clarify
                                                          the problem.
                                                          Help from <br>
                                                          > someone
                                                          more
                                                          conversant
                                                          with the ins
                                                          and outs of
                                                          method handle
                                                          <br>
                                                          >
                                                          bootstraps in
                                                          premain would
                                                          be welcome.
                                                          Details
                                                          follow.<br>
                                                          > <br>
                                                          > regards,<br>
                                                          > <br>
                                                          > <br>
                                                          > Andrew
                                                          Dinn<br>
                                                          >
                                                          -----------<br>
                                                          > <br>
                                                          > I
                                                          downloaded the
                                                          git repo and
                                                          attached the
                                                          Java sources
                                                          using Maven
                                                          command<br>
                                                          > <br>
                                                          >    $ mvn
dependency:sources<br>
                                                          > <br>
                                                          > Having
                                                          manifested the
                                                          crash by
                                                          following the
                                                          instructions
                                                          in the README
                                                          <br>
                                                          > I reran
                                                          the leyden JVM
                                                          under gdb
                                                          using the
                                                          following
                                                          commands to
                                                          enable <br>
                                                          > Java
                                                          debugging<br>
                                                          > <br>
                                                          > $ gdb
                                                          ${LEYDEN_HOME}/bin/java<br>
                                                          > (gdb) cd
/path/to/mvn/project<br>
                                                          > (gdb) run
                                                          <br>
                                                          >
                                                          -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
                                                          <br>
                                                          >
                                                          -classpath <br>
                                                          >
/home/adinn/redhat/openjdk/infinispan/elytron-leyden/base/target/elytron-leyden-base-0.0.1-SNAPSHOT.jar:/home/adinn/.m2/repository/org/wildfly/security/wildfly-elytron-credential/<a href="https://urldefense.com/v3/__http://2.5.1.__;!!ACWV5N9M2RV99hQ!MnS3LSY2PXCCXbHvdyMfR6Nj57XH7Ey7aZuOLmQ__hhE_RhUrKnkzZ0uP8AwLZYcl8lAhhauJ-RjcQ$" target="_blank" moz-do-not-send="true">2.5.1.</a>Final/wildfly-elytron-credential-2.5.1.Final.jar:/home/adinn/.m2/repository/org/wildfly/security/wildfly-elytron-base/2.5.1.Final/wildfly-elytron-base-2.5.1.Final.jar
-XX:CacheDataStore=elytron.aot com.redhat.leyden.Main<br>
                                                          > <br>
                                                          > The
                                                          problem
                                                          manifests at
                                                          WildflyElytronBaseProvider.java:112
                                                          in method <br>
                                                          >
                                                          WildflyElytronBaseProvider::putMakedPasswordImplementations<br>
                                                          <br>
                                                               static
                                                          void
                                                          putMakedPasswordImplementations(Consumer<Service>
                                                          <br>
                                                          consumer,
                                                          Provider
                                                          provider) {<br>
                                                                   for
                                                          (String
                                                          algorithm :
                                                          MASKED_ALGORITHMS)
                                                          {<br>
                                                                     
                                                           consumer.accept(new
Service(provider, <br>
PASSWORD_FACTORY_TYPE, algorithm, <br>
"org.wildfly.security.password.impl.PasswordFactorySpiImpl", emptyList,
                                                          <br>
                                                          emptyMap));
                                                          <== NPE
                                                          under this
                                                          call<br>
                                                                   }<br>
                                                          <br>
                                                          <br>
                                                          > The
                                                          source code
                                                          for this
                                                          method can be
                                                          found in the
                                                          following
                                                          source jar<br>
                                                          > <br>
                                                          > <br>
                                                          >
${M2_REPO}/org/wildfly/security/wildfly-elytron-base/2.5.1.Final/wildfly-elytron-base-2.5.1.Final-sources.jar<br>
                                                          > <br>
                                                          > (where
                                                          M2_REPO will
                                                          normally be
                                                          ~/.m2/repository)<br>
                                                          > <br>
                                                          > Stepping
                                                          into accept
                                                          eventually
                                                          enters
                                                          MethodHandleNative::linkDynamicConstant
                                                          <br>
                                                          > which in
                                                          turn enters
                                                          into
                                                          ConstantBootstraps.makeConstant().
                                                          The caller <br>
                                                          > Class at
                                                          this point is
                                                          a lambda class
                                                          which prints
                                                          as <br>
                                                          >
                                                          org.wildfly.security.WildflyElytronBaseProvider$$Lambda/0x800000000c<br>
                                                          > <br>
                                                          > Several
                                                          steps further
                                                          the code
                                                          enters
                                                          BootstrapMethodInvoker::invoke
                                                          <br>
                                                          > (below
                                                          the app method
                                                          call but via 3
                                                          hidden frames)
                                                          with
                                                          bootstrapMethod
                                                          <br>
                                                          > bound to
                                                          a
                                                          DirectMethodHandle.
                                                          After several
                                                          more steps
                                                          this enters <br>
                                                          >
                                                          DirectMethodHandle$Holder.invokeStatic
                                                          which in turn
                                                          calls <br>
                                                          >
                                                          MethodHandles::classData(Lookup,String,Class).<br>
                                                          > <br>
                                                          > At this
                                                          point caller
                                                          is a
                                                          MethodHandleLookup
                                                          for the lambda
                                                          class <br>
                                                          >
                                                          Lambda/0x800000000c
                                                          mentioned
                                                          above. The
                                                          following call<br>
                                                          > <br>
                                                          >          
                                                          Object
                                                          classdata =
                                                          classData(caller.lookupClass());<br>
                                                          > <br>
                                                          > returns
                                                          null to
DirectMethodHandle$Holder.invokeStatic which pops the <br>
                                                          > same
                                                          result back
                                                          out to
BootstrapMethodInvoker::invoke at line 90<br>
                                                          > <br>
                                                          > 
                                                                         
                                                          if (type
                                                          instanceof
                                                          Class<?>
                                                          c) {<br>
                                                          > 
                                                                             
                                                          result =
                                                          bootstrapMethod.invoke(caller,
                                                          name, c); <br>
                                                          > <==
                                                          null<br>
                                                          > <br>
                                                          > This null
                                                          result pops
                                                          back out as
                                                          the value for
                                                          the call to <br>
                                                          >
                                                          BootstrapMethodInvoker.invoke(),
ConstantBootstraps.makeConstant() and <br>
                                                          >
                                                          MethodHandleNative::linkDynamicConstant().<br>
                                                          > <br>
                                                          <br>
                                                          </blockquote>
                                                        </div>
                                                      </blockquote>
                                                    </div>
                                                  </blockquote>
                                                </div>
                                              </blockquote>
                                            </div>
                                          </blockquote>
                                        </div>
                                      </blockquote>
                                    </div>
                                  </blockquote>
                                </div>
                              </blockquote>
                            </blockquote>
                          </div>
                        </blockquote>
                      </div>
                    </blockquote>
                  </div>
                </blockquote>
              </div>
            </blockquote>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>