Skip to content

Commit 43bbb5e

Browse files
committed
Close handles owned by managed code
1 parent 5dd2f96 commit 43bbb5e

File tree

4 files changed

+328
-24
lines changed

4 files changed

+328
-24
lines changed

graalpython/com.oracle.graal.python.cext/hpy/hpy.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,13 +334,13 @@ OutVarPtr* graal_hpy_allocate_outvar() {
334334
* support passing structs via interop. Therefore, we pretend to have 'void *'
335335
* array and convert to handle using 'HPy_FromVoidP'.
336336
*/
337-
HPy* graal_hpy_array_to_native(VoidPtr *source, uint64_t len) {
337+
void* graal_hpy_array_to_native(VoidPtr *source, uint64_t len) {
338338
uint64_t i;
339339
HPy *dest = (HPy *)malloc(len*sizeof(HPy));
340340
for (i=0; i < len; i++) {
341341
dest[i] = HPy_FromVoidP(source[i]);
342342
}
343-
return dest;
343+
return polyglot_from_HPy_array(dest, len);
344344
}
345345

346346
void get_next_vaarg(va_list *p_va, OutVarPtr *p_outvar) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyNodes.java

Lines changed: 134 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@
8080
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyGetSetDescriptorSetterRootNode;
8181
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyReadMemberNode;
8282
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyMemberAccessNodes.HPyWriteMemberNode;
83+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyAllHandleCloseNodeGen;
84+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyGetSetSetterHandleCloseNodeGen;
85+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyKeywordsHandleCloseNodeGen;
86+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPySelfHandleCloseNodeGen;
87+
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodesFactory.HPyVarargsHandleCloseNodeGen;
88+
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyArrayWrappers.HPyArrayWrapper;
89+
import com.oracle.graal.python.builtins.objects.cext.hpy.HPyArrayWrappers.HPyCloseArrayWrapperNode;
8390
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
8491
import com.oracle.graal.python.builtins.objects.function.PFunction;
8592
import com.oracle.graal.python.builtins.objects.function.PKeyword;
@@ -1177,6 +1184,13 @@ static Object doGeneric(@SuppressWarnings("unused") CExtContext hpyContext, Obje
11771184
public abstract static class HPyConvertArgsToSulongNode extends PNodeWithContext {
11781185

11791186
public abstract void executeInto(VirtualFrame frame, GraalHPyContext hpyContext, Object[] args, int argsOffset, Object[] dest, int destOffset);
1187+
1188+
abstract HPyCloseArgHandlesNode createCloseHandleNode();
1189+
}
1190+
1191+
public abstract static class HPyCloseArgHandlesNode extends PNodeWithContext {
1192+
1193+
public abstract void executeInto(VirtualFrame frame, GraalHPyContext hpyContext, Object[] args, int argsOffset);
11801194
}
11811195

11821196
public abstract static class HPyVarargsToSulongNode extends HPyConvertArgsToSulongNode {
@@ -1188,6 +1202,37 @@ static void doConvert(GraalHPyContext hpyContext, Object[] args, int argsOffset,
11881202
dest[destOffset + 1] = args[argsOffset + 1];
11891203
dest[destOffset + 2] = args[argsOffset + 2];
11901204
}
1205+
1206+
@Override
1207+
HPyCloseArgHandlesNode createCloseHandleNode() {
1208+
return HPyVarargsHandleCloseNodeGen.create();
1209+
}
1210+
}
1211+
1212+
/**
1213+
* The counter part of {@link HPyVarargsToSulongNode}.
1214+
*/
1215+
public abstract static class HPyVarargsHandleCloseNode extends HPyCloseArgHandlesNode {
1216+
1217+
@Specialization
1218+
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1219+
@Cached HPyEnsureHandleNode ensureHandleNode,
1220+
@Cached HPyCloseArrayWrapperNode closeArrayWrapperNode) {
1221+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1222+
closeArrayWrapperNode.execute(hpyContext, (HPyArrayWrapper) dest[destOffset + 1]);
1223+
}
1224+
}
1225+
1226+
/**
1227+
* Always closes parameter at position {@code destOffset} (assuming that it is a handle).
1228+
*/
1229+
public abstract static class HPySelfHandleCloseNode extends HPyCloseArgHandlesNode {
1230+
1231+
@Specialization
1232+
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1233+
@Cached HPyEnsureHandleNode ensureHandleNode) {
1234+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1235+
}
11911236
}
11921237

11931238
public abstract static class HPyKeywordsToSulongNode extends HPyConvertArgsToSulongNode {
@@ -1201,6 +1246,26 @@ static void doConvert(GraalHPyContext hpyContext, Object[] args, int argsOffset,
12011246
dest[destOffset + 2] = args[argsOffset + 2];
12021247
dest[destOffset + 3] = kwAsHandleNode.execute(hpyContext, args[argsOffset + 3]);
12031248
}
1249+
1250+
@Override
1251+
HPyCloseArgHandlesNode createCloseHandleNode() {
1252+
return HPyKeywordsHandleCloseNodeGen.create();
1253+
}
1254+
}
1255+
1256+
/**
1257+
* The counter part of {@link HPyKeywordsToSulongNode}.
1258+
*/
1259+
public abstract static class HPyKeywordsHandleCloseNode extends HPyCloseArgHandlesNode {
1260+
1261+
@Specialization
1262+
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1263+
@Cached HPyEnsureHandleNode ensureHandleNode,
1264+
@Cached HPyCloseArrayWrapperNode closeArrayWrapperNode) {
1265+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1266+
closeArrayWrapperNode.execute(hpyContext, (HPyArrayWrapper) dest[destOffset + 1]);
1267+
ensureHandleNode.execute(hpyContext, dest[destOffset + 3]).close(hpyContext);
1268+
}
12041269
}
12051270

12061271
public abstract static class HPyAllAsHandleNode extends HPyConvertArgsToSulongNode {
@@ -1223,6 +1288,7 @@ static void cached0(GraalHPyContext hpyContext, Object[] args, int argsOffset, O
12231288
static void cachedLoop(GraalHPyContext hpyContext, Object[] args, int argsOffset, Object[] dest, int destOffset,
12241289
@Cached("args.length") int cachedLength,
12251290
@Cached HPyAsHandleNode toSulongNode) {
1291+
CompilerAsserts.partialEvaluationConstant(destOffset);
12261292
for (int i = 0; i < cachedLength - argsOffset; i++) {
12271293
dest[destOffset + i] = toSulongNode.execute(hpyContext, args[argsOffset + i]);
12281294
}
@@ -1236,6 +1302,46 @@ static void uncached(GraalHPyContext hpyContext, Object[] args, int argsOffset,
12361302
dest[destOffset + i] = toSulongNode.execute(hpyContext, args[argsOffset + i]);
12371303
}
12381304
}
1305+
1306+
@Override
1307+
HPyCloseArgHandlesNode createCloseHandleNode() {
1308+
return HPyAllHandleCloseNodeGen.create();
1309+
}
1310+
}
1311+
1312+
/**
1313+
* The counter part of {@link HPyAllAsHandleNode}.
1314+
*/
1315+
public abstract static class HPyAllHandleCloseNode extends HPyCloseArgHandlesNode {
1316+
1317+
@Specialization(guards = {"dest.length == destOffset"})
1318+
@SuppressWarnings("unused")
1319+
static void cached0(GraalHPyContext hpyContext, Object[] dest, int destOffset) {
1320+
}
1321+
1322+
@Specialization(guards = {"dest.length == cachedLength", "isLeArgsOffsetPlus(cachedLength, destOffset, 8)"}, limit = "1", replaces = "cached0")
1323+
@ExplodeLoop
1324+
static void cachedLoop(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1325+
@Cached("dest.length") int cachedLength,
1326+
@Cached HPyEnsureHandleNode ensureHandleNode) {
1327+
CompilerAsserts.partialEvaluationConstant(destOffset);
1328+
for (int i = 0; i < cachedLength - destOffset; i++) {
1329+
ensureHandleNode.execute(hpyContext, dest[destOffset + i]).close(hpyContext);
1330+
}
1331+
}
1332+
1333+
@Specialization(replaces = {"cached0", "cachedLoop"})
1334+
static void uncached(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1335+
@Cached HPyEnsureHandleNode ensureHandleNode) {
1336+
int len = dest.length;
1337+
for (int i = 0; i < len - destOffset; i++) {
1338+
ensureHandleNode.execute(hpyContext, dest[destOffset + i]).close(hpyContext);
1339+
}
1340+
}
1341+
1342+
static boolean isLeArgsOffsetPlus(int len, int off, int plus) {
1343+
return len < plus + off;
1344+
}
12391345
}
12401346

12411347
/**
@@ -1250,6 +1356,11 @@ static void doConvert(GraalHPyContext hpyContext, Object[] args, int argsOffset,
12501356
dest[destOffset] = selfAsHandleNode.execute(hpyContext, args[argsOffset]);
12511357
dest[destOffset + 1] = args[argsOffset + 1];
12521358
}
1359+
1360+
@Override
1361+
HPyCloseArgHandlesNode createCloseHandleNode() {
1362+
return HPySelfHandleCloseNodeGen.create();
1363+
}
12531364
}
12541365

12551366
/**
@@ -1265,6 +1376,24 @@ static void doConvert(GraalHPyContext hpyContext, Object[] args, int argsOffset,
12651376
dest[destOffset + 1] = asHandleNode.execute(hpyContext, args[argsOffset + 1]);
12661377
dest[destOffset + 2] = args[argsOffset + 2];
12671378
}
1379+
1380+
@Override
1381+
HPyCloseArgHandlesNode createCloseHandleNode() {
1382+
return HPyGetSetSetterHandleCloseNodeGen.create();
1383+
}
1384+
}
1385+
1386+
/**
1387+
* The counter part of {@link HPyGetSetSetterToSulongNode}.
1388+
*/
1389+
public abstract static class HPyGetSetSetterHandleCloseNode extends HPyCloseArgHandlesNode {
1390+
1391+
@Specialization
1392+
static void doConvert(GraalHPyContext hpyContext, Object[] dest, int destOffset,
1393+
@Cached HPyEnsureHandleNode ensureHandleNode) {
1394+
ensureHandleNode.execute(hpyContext, dest[destOffset]).close(hpyContext);
1395+
ensureHandleNode.execute(hpyContext, dest[destOffset + 1]).close(hpyContext);
1396+
}
12681397
}
12691398

12701399
/**
@@ -1273,7 +1402,6 @@ static void doConvert(GraalHPyContext hpyContext, Object[] args, int argsOffset,
12731402
public abstract static class HPySSizeArgFuncToSulongNode extends HPyConvertArgsToSulongNode {
12741403

12751404
@Specialization(guards = {"isArity(args.length, argsOffset, 2)"})
1276-
@ExplodeLoop
12771405
static void doHandleSsizeT(VirtualFrame frame, GraalHPyContext hpyContext, Object[] args, int argsOffset, Object[] dest, int destOffset,
12781406
@Cached HPyAsHandleNode asHandleNode,
12791407
@Cached ConvertPIntToPrimitiveNode asSsizeTNode) {
@@ -1283,7 +1411,6 @@ static void doHandleSsizeT(VirtualFrame frame, GraalHPyContext hpyContext, Objec
12831411
}
12841412

12851413
@Specialization(guards = {"isArity(args.length, argsOffset, 3)"})
1286-
@ExplodeLoop
12871414
static void doHandleSsizeTSsizeT(VirtualFrame frame, GraalHPyContext hpyContext, Object[] args, int argsOffset, Object[] dest, int destOffset,
12881415
@Cached HPyAsHandleNode asHandleNode,
12891416
@Cached ConvertPIntToPrimitiveNode asSsizeTNode) {
@@ -1303,6 +1430,11 @@ static void doGeneric(VirtualFrame frame, @SuppressWarnings("unused") GraalHPyCo
13031430
}
13041431
}
13051432

1433+
@Override
1434+
HPyCloseArgHandlesNode createCloseHandleNode() {
1435+
return HPySelfHandleCloseNodeGen.create();
1436+
}
1437+
13061438
static boolean isArity(int len, int off, int expected) {
13071439
return len - off == expected;
13081440
}

0 commit comments

Comments
 (0)