Skip to content

Commit 867592b

Browse files
committed
[GR-15132] Keep NFI arguments from being GCed until the native call returns.
PullRequest: graal/3425
2 parents 27e7276 + 4237388 commit 867592b

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

truffle/src/com.oracle.truffle.nfi/src/com/oracle/truffle/nfi/impl/FunctionExecuteNode.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ abstract class FunctionExecuteNode extends Node {
7373
protected Object cachedSignature(NativePointer receiver, @SuppressWarnings("unused") LibFFISignature signature, Object[] args,
7474
@Cached("signature") @SuppressWarnings("unused") LibFFISignature cachedSignature,
7575
@Cached("createCachedSignatureCall(cachedSignature)") DirectCallNode execute) {
76-
return execute.call(receiver.asPointer(), args);
76+
try {
77+
return execute.call(receiver.asPointer(), args);
78+
} finally {
79+
assert keepAlive(args);
80+
}
7781
}
7882

7983
static class SignatureExecuteNode extends RootNode {
@@ -170,7 +174,11 @@ protected Object cachedArgCount(NativePointer receiver, LibFFISignature signatur
170174
throw ArityException.create(argIdx, args.length);
171175
}
172176

173-
return slowPathCall.call(receiver, signature, buffer);
177+
try {
178+
return slowPathCall.call(receiver, signature, buffer);
179+
} finally {
180+
assert keepAlive(args);
181+
}
174182
}
175183

176184
DirectCallNode createSlowPathCall() {
@@ -222,7 +230,11 @@ static Object genericExecute(NativePointer receiver, LibFFISignature signature,
222230
throw ArityException.create(argIdx, args.length);
223231
}
224232

225-
return IndirectCallNode.getUncached().call(language.getSlowPathCall(), receiver, signature, buffer);
233+
try {
234+
return IndirectCallNode.getUncached().call(language.getSlowPathCall(), receiver, signature, buffer);
235+
} finally {
236+
assert keepAlive(args);
237+
}
226238
}
227239

228240
static class SlowPathExecuteNode extends RootNode {
@@ -248,4 +260,14 @@ static Object slowPathExecute(NFIContext ctx, LibFFISignature signature, long fu
248260
return signature.execute(ctx, functionPointer, buffer);
249261
}
250262
}
263+
264+
/**
265+
* Helper method to keep the argument array alive. The method itself does nothing, but it keeps
266+
* the value alive in a FrameState. That way, the GC can not free the objects as long as they
267+
* might still be in use by the native code (maybe indirectly via an embedded native pointer),
268+
* but the escape analysis can still virtualize the objects if the allocation is visible.
269+
*/
270+
private static boolean keepAlive(@SuppressWarnings("unused") Object args) {
271+
return true;
272+
}
251273
}

0 commit comments

Comments
 (0)