<div dir="auto"><div><div dir="auto">Thanks for the info Maurizio, Per and Rémi</div><div dir="auto"><br></div><div dir="auto">I did try out that record in my own modifications to jextract and it reduces the jar sizes, but as you suggest its better to review with Stable Value API in due course.</div><div dir="auto"><br></div><div dir="auto">Kind regards </div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">Duncan </div></div><div dir="auto"><br><div class="gmail_quote gmail_quote_container" dir="auto"><div dir="ltr" class="gmail_attr">On Mon, 31 Mar 2025, 09:48 Maurizio Cimadamore, <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>

  
  <div>
    <p>Yes, you need a constant root (e.g. static final field), followed
      by one or more "trusted" final edges.</p>
    <p><br>
    </p>
    <p>The record provides the trusted edges. But you still need to
      store the record in a static final field (which you have done).</p>
    <p><br>
    </p>
    <p>Note that, while we could do what you propose in jextract's
      generated code, the record creation is still eager (so it needs to
      run at class initialization time). Jextract code goes to some
      length to make sure that only the downcall handles that are used
      are actually initialized.</p>
    <p>Once we have the stable value API, we might be able to do a lot
      better here.</p>
    <p><br>
    </p>
    <p>Cheers<br>
      Maurizio<br>
    </p>
    <p><br>
    </p>
    <div>On 31/03/2025 07:33, Remi Forax wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:#000000">
        <div>I would complete saying that it's static + final which is
          important.</div>
        <div>static only or final only are not enough for the VM to
          consider the field as a constant.</div>
        <div><br>
        </div>
        <div>regards,</div>
        <div>Rémi</div>
        <div><br>
        </div>
        <hr id="m_-7987212022226481290zwchr">
        <div>
          <blockquote style="border-left:2px solid #1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt"><b>From:
            </b>"Per-Ake Minborg" <a href="mailto:per-ake.minborg@oracle.com" target="_blank" rel="noreferrer"><per-ake.minborg@oracle.com></a><br>
            <b>To: </b>"duncan gittins"
            <a href="mailto:duncan.gittins@gmail.com" target="_blank" rel="noreferrer"><duncan.gittins@gmail.com></a>, "panama-dev"
            <a href="mailto:panama-dev@openjdk.org" target="_blank" rel="noreferrer"><panama-dev@openjdk.org></a><br>
            <b>Sent: </b>Monday, March 31, 2025 8:24:27 AM<br>
            <b>Subject: </b>Re: static field record holding downcall
            MethodHandle<br>
          </blockquote>
        </div>
        <div>
          </div>
        <div>
          <blockquote style="border-left:2px solid #1010ff;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt">
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              Hi Duncan,</div>
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              As components in a record are trusted by the VM, this will
              give similar performance.</div>
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              If you always use LOOKUP, then you could perhaps create an
              even more easy-to-use constructor where you just provide
              the name of the native function (e.g. "qsort") and the
              FunctionDescription.</div>
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              <br>
            </div>
            <div style="font-family:Aptos,Aptos_EmbeddedFont,Aptos_MSFontService,Calibri,Helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">
              Best, Per</div>
            <hr style="display:inline-block;width:98%">
            <div id="m_-7987212022226481290divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> panama-dev
                <a href="mailto:panama-dev-retn@openjdk.org" target="_blank" rel="noreferrer"><panama-dev-retn@openjdk.org></a> on behalf of Duncan
                Gittins <a href="mailto:duncan.gittins@gmail.com" target="_blank" rel="noreferrer"><duncan.gittins@gmail.com></a><br>
                <b>Sent:</b> Sunday, March 30, 2025 9:55 AM<br>
                <b>To:</b> panama-dev <a href="mailto:panama-dev@openjdk.org" target="_blank" rel="noreferrer"><panama-dev@openjdk.org></a><br>
                <b>Subject:</b> static field record holding downcall
                MethodHandle</font>
              <div> </div>
            </div>
            <div>
              <div dir="ltr">
                <div>Sorry if this is a silly question. I wanted to
                  check my understanding of method handles in
                  downcalls.  The example below is from jextract, though
                  I have similar handwritten sections in my own
                  non-jextract examples. For best performance, the
                  MethodHandle is declared in static field:</div>
                <div><br>
                </div>
                <div>
                  <div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px">
                    <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap">
<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> FunctionDescriptor
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">DESC</span><span style="color:rgb(0,0,0)"> = FunctionDescriptor.</span><span style="color:rgb(0,0,0);font-style:italic">ofVoid</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">ADDRESS</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">JAVA_LONG</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">JAVA_LONG</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">ADDRESS</span><span style="color:rgb(0,0,0)">);</span></p>
<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> MemorySegment
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">ADDR</span><span style="color:rgb(0,0,0)"> =
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">LOOKUP</span><span style="color:rgb(0,0,0)">.findOrThrow(</span><span style="color:rgb(42,0,255)">"qsort"</span><span style="color:rgb(0,0,0)">);</span></p>
<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)"> MethodHandle
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">MH</span><span style="color:rgb(0,0,0)"> =
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">LINKER</span><span style="color:rgb(0,0,0)">.downcallHandle(</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">ADDR</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">DESC</span><span style="color:rgb(0,0,0)">);</span></p>
<p style="margin:0px">

</p>
</div>
                  </div>
                  Would I get similar performance benefit for qsort
                  MH.invokeExact if I changed above to use a record for
                  Download fields instead?
                  <br>
                </div>
                <div><br>
                </div>
                <div>
                  <div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px">
                    <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap">
<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">record</span><span style="color:rgb(0,0,0)"> Downcall(MemorySegment
</span><span style="color:rgb(106,62,62)">address</span><span style="color:rgb(0,0,0)">, FunctionDescriptor
</span><span style="color:rgb(106,62,62)">descriptor</span><span style="color:rgb(0,0,0)">, MethodHandle
</span><span style="color:rgb(106,62,62)">handle</span><span style="color:rgb(0,0,0)">) {</span></p>

<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">public</span><span style="color:rgb(0,0,0)"> Downcall(MemorySegment
</span><span style="color:rgb(106,62,62)">addr</span><span style="color:rgb(0,0,0)">, FunctionDescriptor
</span><span style="color:rgb(106,62,62)">desc</span><span style="color:rgb(0,0,0)">) {</span></p>
<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">this</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(106,62,62)">addr</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(106,62,62)">desc</span><span style="color:rgb(0,0,0)">, Linker.</span><span style="color:rgb(0,0,0);font-style:italic">nativeLinker</span><span style="color:rgb(0,0,0)">().downcallHandle(</span><span style="color:rgb(106,62,62)">addr</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(106,62,62)">desc</span><span style="color:rgb(0,0,0)">));</span></p>
<p style="margin:0px"><span style="color:rgb(0,0,0)">}</span></p>
}</div>
                    <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap">


</div>
                  </div>
                  This means the definition is now a one liner:</div>
                <div><br>
                </div>
                <div>
                  <div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px">
                    <div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap">
<div style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px">
<div style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap">
<p style="margin:0px"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(127,0,85);font-weight:bold">private</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">static</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(127,0,85);font-weight:bold">final</span><span style="color:rgb(0,0,0)">
</span><span style="text-decoration:underline rgb(0,102,204);color:rgb(0,102,204)">Downcall</span><span style="color:rgb(0,0,0)">
</span><span style="color:rgb(0,0,0)">CALL = </span><span style="color:rgb(127,0,85);font-weight:bold">new</span><span style="color:rgb(0,0,0)"> Downcall(</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">LOOKUP</span><span style="color:rgb(0,0,0)">.findOrThrow(</span><span style="color:rgb(42,0,255)">"qsort"</span><span style="color:rgb(0,0,0)">),
 FunctionDescriptor.</span><span style="color:rgb(0,0,0);font-style:italic">ofVoid</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">ADDRESS</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">JAVA_LONG</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">JAVA_LONG</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(0,0,192);font-style:italic;font-weight:bold">ADDRESS</span><span style="color:rgb(0,0,0)">));</span></p>
<p style="margin:0px">// invoke with <span style="color:rgb(0,0,0)">CALL.</span><span style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><span style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap"><span style="color:rgb(0,0,0)"></span><span style="color:rgb(0,0,192)">handle</span></span></span><span style="background-color:rgb(255,255,255);padding:0px 0px 0px 2px"><span style="color:rgb(0,0,0);background-color:rgb(255,255,255);font-family:"Consolas";font-size:10pt;white-space:pre-wrap"><span style="color:rgb(0,0,192)"></span><span style="color:rgb(0,0,0)">.invokeExact(</span><span style="color:rgb(106,62,62)">base</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(106,62,62)">nitems</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(106,62,62)">size</span><span style="color:rgb(0,0,0)">,
</span><span style="color:rgb(106,62,62)">compar</span><span style="color:rgb(0,0,0)">)</span></span></span>


</p>
<p style="margin:0px">Kind regards</p>
<p style="margin:0px">

</p>
<p style="margin:0px">Duncan Gittins</p>
<div>

</div>
<p style="margin:0px">

</p>
<p style="margin:0px">

</p>
<p style="margin:0px">

</p>
</div>
</div>
<p style="margin:0px">

</p>
</div>
                  </div>
                  <br>
                </div>
              </div>
            </div>
            <br>
          </blockquote>
        </div>
      </div>
    </blockquote>
  </div>

</blockquote></div></div></div>