<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Jan, thank you so much for this report!<br>
java.lang.invoke is part of core libraries, so I replied to the core-libs list instead.</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I see the bottom-up view of MethodHandleNatives.resolve missing, but I need a top-down view to understand better what's happening. Is InvokerBytecodeGenerator.lookupPregenerated part of this flame graph?</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);">
Fyi, there's a preexisting problem with pre-generated MethodHandle infrastructure lookup; we use that resolve, but internally JVM will create Error instances and throw them (as part of regular method resolution) which will call this stacktrace filling. The
stack will look weird but here's how they are generated and eliminated in case you are interested:
<a href="https://github.com/openjdk/jdk/blob/3cf3f300de1e9d2c8767877ed3a26679e34b7d22/src/hotspot/share/prims/methodHandles.cpp#L792">
https://github.com/openjdk/jdk/blob/3cf3f300de1e9d2c8767877ed3a26679e34b7d22/src/hotspot/share/prims/methodHandles.cpp#L792</a></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 this is the problem you are encountering, we are currently thinking about generating a list of present methods so we don't go through VM's resolution. A temporary workaround is to generate a CDS (<a href="https://docs.oracle.com/en/java/javase/22/vm/class-data-sharing.html" id="OWA26ec67be-04c9-5e0d-a8ad-bbf48c67d586" class="OWAAutoLink">Class
Data Sharing (oracle.com)</a>) archive from a boot run so these methods will be present, and it will also slightly improve your startup speed. Or you can generate a jlink image (which is more complicated). Both solutions are not valid for the libraries. (You
can try grasp how these two work at <a href="https://github.com/openjdk/jdk/pull/19164">
https://github.com/openjdk/jdk/pull/19164</a>)</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);">
Maybe another way to verify the problem is to run with the system property <code>
-Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true</code>, which jli will start printing if it can resolve methods; each time it fails, it will go through this error creation and stacktrace filling, unfortunately. If you have CDS archive, these resolution may
print success if those infrastructures are generated in the run that generated the CDS archive.</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);">
Finally, before we take action, I still need you to verify my said issue is the root cause; you can confirm either by looking at the callers to MHN.resolve, or by running with
<code>-Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true</code> and check its outputs. I would prefer you to test on the latest versions, such as 22 or the test builds at
<a href="https://jdk.java.net/23" title="https://jdk.java.net/23">https://jdk.java.net/23</a>, in addition to your baseline supported version 17. I am more than glad to help if you encounter further issues, or if this turns out not to be the cause. And again,
thank you for taking your time to diagnose and report!</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 regards,</div>
<div class="elementToProof" style="font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Chen Liang</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> discuss <discuss-retn@openjdk.org> on behalf of Jan Bernitt <jaanbernitt@gmail.com><br>
<b>Sent:</b> Friday, August 9, 2024 6:15 AM<br>
<b>To:</b> discuss@openjdk.org <discuss@openjdk.org><br>
<b>Subject:</b> Costs of caught exceptions during method handle resolve</font>
<div> </div>
</div>
<div>
<div dir="ltr">Hi everyone!
<div><br>
</div>
<div>I recently found a performance issue in my library that goes back to large numbers of exceptions being thrown and caught where the costs are dominated by filling in the stack trace and resolving method handles.</div>
<div> <br>
So I investigated ways to avoid causing the exceptions. One of the reasons for the exceptions</div>
<div>was somewhere internally in the method handle resolve. I ended up caching the method handles to avoid this happening over and over again as my library uses method handles all the time :D <br>
<br>
As far as I can tell this should be something the JDK can solve differently internally to avoid the cost of throwing and catching the exception which should improve performance of method handles significantly if you use them (including the lookup) in a hot
loop. You can find more details here <a href="https://github.com/dhis2/json-tree/pull/66">https://github.com/dhis2/json-tree/pull/66</a></div>
<div><br>
</div>
<div>If this is of interest to some feel free to ask for more details. <br>
Also if anyone sees that I am just using methods handles wrong and therefore cause the internal exception please let me know.<br>
<br>
Best <br>
Jan</div>
</div>
</div>
</body>
</html>