<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>Hi Cheng Jin,<br>
</p>
<p>Thanks for the email.<br>
<br>
In this case it is not a problem since memory sessions (including
upcall stubs) are kept alive/reachable for the duration of a
downcall (see the third bullet here: [1])</p>
<p> "The memory session of R is kept alive (and cannot be closed)
during the invocation."</p>
<p>Since we don't store a reference to the upcall stub in native
code until after the downcall returns, this is safe to rely on.</p>
<p>Cheers,<br>
Jorn<br>
</p>
<p>[1]:
<a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/foreign/Linker.html#safety">https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/foreign/Linker.html#safety</a><br>
</p>
<div class="moz-cite-prefix">On 31/01/2023 18:49, Cheng Jin wrote:<br>
</div>
<blockquote type="cite" cite="mid:MN2PR15MB259203DEDEAA3332947ED4CEF5D09@MN2PR15MB2592.namprd15.prod.outlook.com">
<meta name="Generator" content="Microsoft Word 15 (filtered
medium)">
<style>@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
{font-family:DengXian;
panose-1:2 1 6 0 3 1 1 1 1 1;}@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}@font-face
{font-family:"\@DengXian";
panose-1:2 1 6 0 3 1 1 1 1 1;}p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;}div.WordSection1
{page:WordSection1;}</style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
<div class="WordSection1">
<p class="MsoNormal">Hi there, <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I notice there might be an issue with the
allocation of upcall stub under an implicit session at
test/jdk/java/foreign/SafeFunctionAccessTest.java in JDK19+ as
follows:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">e.g.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> @Test<o:p></o:p></p>
<p class="MsoNormal"> public void testClosedStructCallback()
throws Throwable {<o:p></o:p></p>
<p class="MsoNormal"> MethodHandle handle =
Linker.nativeLinker().downcallHandle(<o:p></o:p></p>
<p class="MsoNormal">
findNativeOrThrow("addr_func_cb"),<o:p></o:p></p>
<p class="MsoNormal">
FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> try (MemorySession session =
MemorySession.openConfined()) {<o:p></o:p></p>
<p class="MsoNormal"> MemorySegment segment =
MemorySegment.allocateNative(POINT, session);<o:p></o:p></p>
<p class="MsoNormal"> handle.invoke(segment,
sessionChecker(session));
<span style="font-family:Wingdings">ß</span>---------------
the upcall stub is allocated in sessionChecker()<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> MemorySegment
sessionChecker(MemorySession session) {<o:p></o:p></p>
<p class="MsoNormal"> try {<o:p></o:p></p>
<p class="MsoNormal"> MethodHandle handle =
MethodHandles.lookup().findStatic(SafeFunctionAccessTest.class,
"checkSession",<o:p></o:p></p>
<p class="MsoNormal">
MethodType.methodType(void.class, MemorySession.class));<o:p></o:p></p>
<p class="MsoNormal"> handle =
handle.bindTo(session);<o:p></o:p></p>
<p class="MsoNormal"> return
Linker.nativeLinker().upcallStub(handle,
FunctionDescriptor.ofVoid(), MemorySession.openImplicit());
<span style="font-family:Wingdings">ß</span>-----the upcall
stub is allocated with an implicit session<o:p></o:p></p>
<p class="MsoNormal"> } catch (Throwable ex) {<o:p></o:p></p>
<p class="MsoNormal"> throw new AssertionError(ex);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal" style="text-indent:9.9pt">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">It is correct to allocate the upcall stub
with a session different from the current session in tests
given these tests intend to close the current session in
upcall to verify the behavior. But it is problematic to
exploit an implicit session backed by GC, in which case the
memory of the upcall stub is more likely to be forced to
release by GC (when implicitly closing the session to free
memory) especially on the memory-restricted machines, which
leads to unexpected behavior in upcall (e.g. crash which was
captured recently). To work around this case, I’d suggest to
replace it with a global session or others so as to keep the
upcall stub alive during the upcall.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Best Regards<o:p></o:p></p>
<p class="MsoNormal">Cheng Jin<o:p></o:p></p>
</div>
</blockquote>
</body>
</html>