<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<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 class="moz-cite-prefix">On 31/03/2025 07:33, Remi Forax wrote:<br>
</div>
<blockquote type="cite" cite="mid:785517233.197283119.1743402831315.JavaMail.zimbra@univ-eiffel.fr">
<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 data-mce-bogus="1">
</div>
<div>regards,</div>
<div>Rémi</div>
<div><br>
</div>
<hr id="zwchr" data-marker="__DIVIDER__">
<div data-marker="__HEADERS__">
<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 class="moz-txt-link-rfc2396E" href="mailto:per-ake.minborg@oracle.com"><per-ake.minborg@oracle.com></a><br>
<b>To: </b>"duncan gittins"
<a class="moz-txt-link-rfc2396E" href="mailto:duncan.gittins@gmail.com"><duncan.gittins@gmail.com></a>, "panama-dev"
<a class="moz-txt-link-rfc2396E" href="mailto:panama-dev@openjdk.org"><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>
<style style="display:none;">P {margin-top:0;margin-bottom:0;}</style></div>
<div data-marker="__QUOTED_TEXT__">
<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 class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Duncan,</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" 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 class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" 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 class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" 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="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt" face="Calibri, sans-serif" color="#000000"><b>From:</b> panama-dev
<a class="moz-txt-link-rfc2396E" href="mailto:panama-dev-retn@openjdk.org"><panama-dev-retn@openjdk.org></a> on behalf of Duncan
Gittins <a class="moz-txt-link-rfc2396E" href="mailto:duncan.gittins@gmail.com"><duncan.gittins@gmail.com></a><br>
<b>Sent:</b> Sunday, March 30, 2025 9:55 AM<br>
<b>To:</b> panama-dev <a class="moz-txt-link-rfc2396E" href="mailto:panama-dev@openjdk.org"><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">
<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">
<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">
</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">
<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">
<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"><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"><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>
</body>
</html>