<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Hi Duncan,<br>
      <br>
      I don't think they are ever different in practice, but they are
      not being de-duplicated currently, since the de-duplication of the
      constants works based on the name. All of these function
      descriptors describe the same function type, namely that of the
      function pointer:<br>
    </p>
    <p>        <font face="monospace">HRESULT
        (*QueryInterface)(IShellLinkW*,const IID*,void**);</font><br>
    </p>
    <p>With the recent patch that puts all the constants in the constant
      files, the de-duplication works based on the structure, and only
      one constant is generated for that particular function descriptor.
      I plan to backport that patch to jextract 20 as well:
      <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jextract/pull/118">https://github.com/openjdk/jextract/pull/118</a><br>
    </p>
    <p>Jorn<br>
    </p>
    <div class="moz-cite-prefix">On 11/04/2023 16:52, Duncan Gittins
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CABOqcFtnYimJ2QQR_dNwmU=dPMH7yk=689kQd+QG3q_5aSSG5Q@mail.gmail.com">
      
      <div dir="ltr">Thanks Jorn
        <div><br>
        </div>
        <div>Your suggestion to allow filtering out of the unnecessary
          interfaces will be a great help to simplify the generated code
          dependencies. I believe the changes giving this new behaviour
          was outlined here:</div>
        <div><br>
        </div>
        <div>      <a href="https://mail.openjdk.org/pipermail/jextract-dev/2023-February/000675.html" moz-do-not-send="true" class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/jextract-dev/2023-February/000675.html</a></div>
        <div><br>
        </div>
        <div>One query I had on the new UP/DOWN generated code - is
          there a circumstance where the FunctionDescriptor for the
          upcall QueryInterface_DOWN$FUNC differs from the
          downcall QueryInterface_DOWN$FUNC and the default
          FunctionDescriptor QueryInterface$FUNC? There is a strange
          dependency in generated code for QueryInterface callback:</div>
        <div><br>
        </div>
             QueryInterface_DOWN$MH depends on QueryInterface_DOWN$FUNC<br class="gmail-Apple-interchange-newline">
        <div>     QueryInterface_UP$MH depends on QueryInterface_UP$FUNC<br>
        </div>
        <div>
          <div>
            <div><br>
            </div>
          </div>
        </div>
        <div>The callback interface QueryInterface uses all three $FUNC
          definitions though each appears to be declared as the same
          value:</div>
        <div><br>
        </div>
        <div>     QueryInterface.allocate depends
          on QueryInterface_UP$MH and QueryInterface$FUNC and therefore
          also QueryInterface_UP$FUNC</div>
        <div>
          <div>     QueryInterface ofAddress depends on
            QueryInterface_DOWN$MH and therefore
            QueryInterface_DOWN$FUNC</div>
          <div><br>
          </div>
        </div>
        <div>Kind regards</div>
        <div><br>
        </div>
        <div>Duncan</div>
        <div><br>
        </div>
        <div><br>
        </div>
        <div><br>
          <div><br>
          </div>
        </div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, 11 Apr 2023 at 14:04,
          Jorn Vernee <<a href="mailto:jorn.vernee@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">jorn.vernee@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 Duncan,</p>
            <p>In this case the functional interface QueryInterface is
              being generated because a field in the enclosing struct
              has a field with a function pointer type.
              QueryInterface_UP$MH is a constant required by the
              implementation of that interface.<br>
            </p>
            <p>While I think your solution could fix the immediate issue
              you're having, we recently moved constants like
              QueryInterface_UP$MH to all be generated in the constant
              support files [1]. I think that is long term a better
              solution, since it takes the proper care to make sure the
              source files don't get too large.<br>
            </p>
            <p>With that patch, it would however still be dicey to
              manually strip the compiled classes from a jar though,
              since there would still be a reference to the class from
              the constants file. So, if another constant in the same
              file was accessed, the same issue would occur. Unless
              -Djextract.constants.per.class=0 is used as well, so that
              each constant class has only 1 constant.</p>
            <p> I think stripping classes from a jar will always be
              risky, since it is done without the knowledge of jextract.
              We have the <font face="monospace">--include-*</font>
              options as a supported way to do filtering in jextract. I
              think adding an <font face="monospace">--include-*</font>
              option for filtering out functional interface is
              reasonable as well. If you know you are never going to use
              the generated interface, it should be possible to filter
              it out (and all the constants it depends on). I've filled
              an issue for this: <a href="https://bugs.openjdk.org/browse/CODETOOLS-7903456" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://bugs.openjdk.org/browse/CODETOOLS-7903456</a><br>
            </p>
            <p>Jorn<br>
              <br>
              [1] : <a href="https://urldefense.com/v3/__https://github.com/openjdk/jextract/pull/117__;!!ACWV5N9M2RV99hQ!Mw1QdKzLbkgWCXYVEfk2wpl20WjBk3_AoeUPGenImk9P6pD8cYYWM9Se87bX83la-6G03Q_WktS0qYYq08OjpSymcQ$" target="_blank" moz-do-not-send="true">https://github.com/openjdk/jextract/pull/117</a><br>
            </p>
            <div>On 08/04/2023 19:10, Duncan Gittins wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">Jorn
                <div><br>
                </div>
                <div>Thanks everyone for the effort on this. Its been a
                  while since I've built my own jextract v20 so your
                  build has given me more recent changes.
                  <div><br>
                  </div>
                  <div>Apologies if this is covered in previous trails:
                    I have run into an issue related to the way some
                    performance changes were implemented in upcall stub
                    generation. The generated code has introduced new
                    class loader dependencies for Windows COM
                    interfaces. For example using IShellLinkWVtbl gives
                    rise to many interfaces such as
                    IShellLinkWVtbl$QueryInterface.  </div>
                  <div><br>
                  </div>
                  <div>All is fine if use new jextract and perform my
                    tests with generated file.  My arguments for
                    jextract are: </div>
                  <div>
                    <div>    --source  -lshell32 -t duncan.win.shell
                      --output source\duncan.win\java headers\Shell32.h </div>
                    <div>where Shell32.h is just: </div>
                    <div>     #include <shlobj_core.h></div>
                    <div><br>
                    </div>
                  </div>
                  <div>However I've noticed the new jextract generated
                    code has new class dependencies. I lookup COM
                    objects via IUnknown$QueryInterface and never call
                    the duplicate version like
                    IShellLinkWVtbl$QueryInterface so I've been striping
                    these similar and un-used classes from my jars. <br>
                  </div>
                  <div><br>
                  </div>
                  <div>In the old code generation, IShellLinkWVtbl was
                    independent of IShellLinkWVtbl$QueryInterface and
                    all other IXYZ COM interfaces.<br>
                  </div>
                  <div><br>
                  </div>
                  <div>The new generated code of IShellLinkWVtbl.java
                    references IShellLinkWVtbl$QueryInterface.class.
                    Similarly every vtable class (eg IUnknown /
                    IPersistFile etc) depends now on every interface
                    class file of every COM interface (AddRef / Release
                    / etc) it supports because of the new xyz_UP$MH
                    fields:</div>
                  <div>
                    <div><br>
                    </div>
                  </div>
                  <div>
                    <div>    Exception java.lang.NoClassDefFoundError:
                      duncan/win/shell/IShellLinkWVtbl$QueryInterface<br>
                           |        at IShellLinkWVtbl.<clinit>
                      (IShellLinkWVtbl.java:75)<br>
                    </div>
                    <div><br>
                    </div>
                    <div>
                      <div>Here is the snippet of new code which shows
                        the new upcallHandle which means every
                        vtable.class requires all com .class files. I am
                        hoping that this can be resolved easily simply
                        by generating the declaration of
                        QueryInterface_UP$MH inside interface
                        IShellLinkWVtbl$QueryInterface rather than into
                        the parent class IShellLinkWVtbl. This would
                        avoid a large number of .class files being read
                        when referencing a vtable class:</div>
                    </div>
                    <div><br>
                    </div>
                  </div>
                  <div>    public class IShellLinkWVtbl {<br>
                  </div>
                  <div>     ... </div>
                  <div>      static final MethodHandle
                    QueryInterface_UP$MH =
                    RuntimeHelper.upcallHandle(QueryInterface.class,
                    "apply", IShellLinkWVtbl.QueryInterface_UP$FUNC);</div>
                  <div>    ...<br>
                            /** HRESULT
                    (*QueryInterface)(IShellLinkW*,const
                    IID*,void**); */<br>
                            public interface QueryInterface { </div>
                  <div>            //  UP$MH should be here?<br>
                                int
                    apply(java.lang.foreign.MemorySegment _x0,
                    java.lang.foreign.MemorySegment _x1,
                    java.lang.foreign.MemorySegment _x2);<br>
                                static MemorySegment
                    allocate(QueryInterface fi, SegmentScope scope) {<br>
                                return
                    RuntimeHelper.upcallStub(IShellLinkWVtbl.QueryInterface_UP$MH,
                    fi, IShellLinkWVtbl.QueryInterface$FUNC, scope);<br>
                            }<br>
                          ...<br>
                        }<br>
                  </div>
                  <div><br>
                  </div>
                  <div>Kind regards</div>
                  <div><br>
                  </div>
                  <div>Duncan</div>
                </div>
              </div>
              <br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Fri, 7 Apr 2023 at
                  18:34, Jorn Vernee <<a href="mailto:jorn.vernee@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">jorn.vernee@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">Hello,<br>
                  <br>
                  Jextract 20 binaries are now available at: <a href="https://urldefense.com/v3/__https://jdk.java.net/jextract/__;!!ACWV5N9M2RV99hQ!Lub79JM1QWad74DQ066IIkIBcFwi4DYJXQssC4oVgEC8gOf4yh9sd209Pz_Tt0tFZjEMv4eIkP5e9hb0t0W-h2P5ww$" rel="noreferrer" target="_blank" moz-do-not-send="true">https://jdk.java.net/jextract/</a><br>
                  <br>
                  This version of jextract targets the foreign function
                  and memory access <br>
                  API in Java 20, which was released recently as well
                  [1]<br>
                  <br>
                  The existing binaries of jextract 19, which target
                  Java 19, are still <br>
                  available through a link under the "Other versions"
                  section on the <br>
                  jextract download page linked above.<br>
                  <br>
                  Jorn<br>
                  <br>
                  [1]: <a href="https://urldefense.com/v3/__https://jdk.java.net/20/__;!!ACWV5N9M2RV99hQ!Lub79JM1QWad74DQ066IIkIBcFwi4DYJXQssC4oVgEC8gOf4yh9sd209Pz_Tt0tFZjEMv4eIkP5e9hb0t0UTAflM8A$" rel="noreferrer" target="_blank" moz-do-not-send="true">https://jdk.java.net/20/</a><br>
                  <br>
                </blockquote>
              </div>
            </blockquote>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>