Skip to content

Commit c8e7bbe

Browse files
committed
Increase refCount for items stolen by temporary varargs tuple.
1 parent 5d3edb2 commit c8e7bbe

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ExternalFunctionNodes.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@
5454
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ConvertArgsToSulongNode;
5555
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.SubRefCntNode;
5656
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToJavaStealingNode;
57+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToNewRefNode;
5758
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToJavaStealingNodeGen;
5859
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.ConvertPIntToPrimitiveNode;
5960
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.ConvertPIntToPrimitiveNodeGen;
61+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToNewRefNodeGen;
6062
import com.oracle.graal.python.builtins.objects.cext.DynamicObjectNativeWrapper;
6163
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapper;
6264
import com.oracle.graal.python.builtins.objects.cext.PythonNativeWrapperLibrary;
@@ -1030,24 +1032,46 @@ abstract static class CreateArgsTupleNode extends Node {
10301032
@ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL)
10311033
static PTuple doCachedLen(PythonObjectFactory factory, Object[] args,
10321034
@Cached("args.length") int cachedLen,
1035+
@Cached("createToNewRefNodes(args.length)") ToNewRefNode[] toNewRefNodes,
10331036
@Cached("createMaterializeNodes(args.length)") MaterializePrimitiveNode[] materializePrimitiveNodes) {
10341037

10351038
for (int i = 0; i < cachedLen; i++) {
1036-
args[i] = materializePrimitiveNodes[i].execute(factory, args[i]);
1039+
args[i] = prepareReference(args[i], factory, materializePrimitiveNodes[i], toNewRefNodes[i]);
10371040
}
10381041
return factory.createTuple(args);
10391042
}
10401043

10411044
@Specialization(replaces = "doCachedLen")
10421045
static PTuple doGeneric(PythonObjectFactory factory, Object[] args,
1046+
@Cached ToNewRefNode toNewRefNode,
10431047
@Cached MaterializePrimitiveNode materializePrimitiveNode) {
10441048

10451049
for (int i = 0; i < args.length; i++) {
1046-
args[i] = materializePrimitiveNode.execute(factory, args[i]);
1050+
args[i] = prepareReference(args[i], factory, materializePrimitiveNode, toNewRefNode);
10471051
}
10481052
return factory.createTuple(args);
10491053
}
10501054

1055+
private static Object prepareReference(Object arg, PythonObjectFactory factory, MaterializePrimitiveNode materializePrimitiveNode, ToNewRefNode toNewRefNode) {
1056+
Object result = materializePrimitiveNode.execute(factory, arg);
1057+
1058+
// Tuples are actually stealing the reference of their items. That's why we need to
1059+
// increase the reference count by 1 at this point. However, it could be that the
1060+
// object does not have a native wrapper yet. We use ToNewRefNode to ensure that the
1061+
// object has a native wrapper or to increase the reference count by 1 if a native
1062+
// wrapper already exists.
1063+
toNewRefNode.execute(result);
1064+
return result;
1065+
}
1066+
1067+
static ToNewRefNode[] createToNewRefNodes(int length) {
1068+
ToNewRefNode[] newRefNodes = new ToNewRefNode[length];
1069+
for (int i = 0; i < length; i++) {
1070+
newRefNodes[i] = ToNewRefNodeGen.create();
1071+
}
1072+
return newRefNodes;
1073+
}
1074+
10511075
static MaterializePrimitiveNode[] createMaterializeNodes(int length) {
10521076
MaterializePrimitiveNode[] materializePrimitiveNodes = new MaterializePrimitiveNode[length];
10531077
for (int i = 0; i < length; i++) {

0 commit comments

Comments
 (0)