Skip to content

Commit eae9d4d

Browse files
committed
Extract decrefing native objects to a node
1 parent e6f4794 commit eae9d4d

File tree

4 files changed

+34
-106
lines changed

4 files changed

+34
-106
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,10 @@
116116
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
117117
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.ToBytesNode;
118118
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
119-
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
120119
import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext;
121-
import com.oracle.graal.python.builtins.objects.cext.capi.CApiGuards;
122-
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AddRefCntNode;
123-
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
120+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
124121
import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
122+
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
125123
import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CByteArrayWrapper;
126124
import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ApiInitException;
127125
import com.oracle.graal.python.builtins.objects.cext.common.LoadCExtException.ImportException;
@@ -134,7 +132,6 @@
134132
import com.oracle.graal.python.builtins.objects.dict.PDict;
135133
import com.oracle.graal.python.builtins.objects.function.PKeyword;
136134
import com.oracle.graal.python.builtins.objects.module.PythonModule;
137-
import com.oracle.graal.python.builtins.objects.object.PythonObject;
138135
import com.oracle.graal.python.builtins.objects.str.StringBuiltins.PrefixSuffixNode;
139136
import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
140137
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
@@ -1696,55 +1693,29 @@ static Object doit(Object obj,
16961693
}
16971694
}
16981695

1699-
@ImportStatic(CApiGuards.class)
17001696
@Builtin(name = "Py_INCREF", minNumOfPositionalArgs = 1)
17011697
@GenerateNodeFactory
17021698
protected abstract static class PyINCREFNode extends PythonUnaryBuiltinNode {
17031699

17041700
@Specialization
17051701
@TruffleBoundary
17061702
static Object doGeneric(Object arg) {
1707-
1708-
Object pointerObject = null;
1709-
if (arg instanceof PythonAbstractNativeObject nativeObject) {
1710-
pointerObject = nativeObject.getPtr();
1711-
} else if (arg instanceof PythonObject managedObject) {
1712-
pointerObject = managedObject.getNativeWrapper();
1713-
}
1714-
// ignore other cases; also: don't allocate wrappers just because of this
1715-
1716-
if (pointerObject != null) {
1717-
AddRefCntNode.executeUncached(pointerObject, //
1718-
1 /* that's what this function is for */ + //
1719-
1 /* that for returning it */);
1720-
}
1703+
CApiContext.ensureCapiWasLoaded();
1704+
CApiTransitions.PythonToNativeNewRefNode.executeUncached(arg);
17211705
return arg;
17221706
}
17231707
}
17241708

1725-
@ImportStatic(CApiGuards.class)
17261709
@Builtin(name = "Py_DECREF", minNumOfPositionalArgs = 1)
17271710
@GenerateNodeFactory
17281711
protected abstract static class PyDECREFNode extends PythonUnaryBuiltinNode {
17291712

17301713
@Specialization
17311714
@TruffleBoundary
17321715
static Object doGeneric(Object arg) {
1733-
1734-
Object pointerObject = null;
1735-
if (arg instanceof PythonAbstractNativeObject nativeObject) {
1736-
pointerObject = nativeObject.getPtr();
1737-
} else if (arg instanceof PythonObject managedObject) {
1738-
pointerObject = managedObject.getNativeWrapper();
1739-
}
1740-
// ignore other cases; also: don't allocate wrappers just because of this
1741-
1742-
if (pointerObject != null) {
1743-
// that's what this function is for
1744-
PCallCapiFunction.callUncached(NativeCAPISymbol.FUN_DECREF, pointerObject);
1745-
// that for returning it
1746-
PCallCapiFunction.callUncached(NativeCAPISymbol.FUN_INCREF, pointerObject);
1747-
}
1716+
CApiContext.ensureCapiWasLoaded();
1717+
Object nativePointer = CApiTransitions.PythonToNativeNode.executeUncached(arg);
1718+
CExtNodes.DecRefPointerNode.executeUncached(nativePointer);
17481719
return arg;
17491720
}
17501721
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
8484
import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
8585
import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
86-
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AddRefCntNodeGen;
8786
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AsCharPointerNodeGen;
8887
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.CreateFunctionNodeGen;
8988
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.FromCharPointerNodeGen;
@@ -191,6 +190,7 @@
191190
import com.oracle.truffle.api.interop.UnsupportedTypeException;
192191
import com.oracle.truffle.api.library.CachedLibrary;
193192
import com.oracle.truffle.api.nodes.Node;
193+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
194194
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
195195
import com.oracle.truffle.api.source.Source;
196196
import com.oracle.truffle.api.strings.TruffleString;
@@ -1092,51 +1092,31 @@ static PRaiseNativeNode doIt(@Cached(inline = false) PRaiseNativeNode node) {
10921092
@GenerateInline
10931093
@GenerateCached(false)
10941094
@GenerateUncached
1095-
@ImportStatic(CApiGuards.class)
1096-
public abstract static class AddRefCntNode extends PNodeWithContext {
1095+
public abstract static class DecRefPointerNode extends PNodeWithContext {
10971096

1098-
public static Object executeUncached(Object object, long value) {
1099-
return AddRefCntNodeGen.getUncached().execute(null, object, value);
1097+
public static void executeUncached(Object pointer) {
1098+
CExtNodesFactory.DecRefPointerNodeGen.getUncached().execute(null, pointer);
11001099
}
11011100

1102-
public abstract Object execute(Node inliningTarget, Object object, long value);
1103-
1104-
@Specialization(guards = "value == 1")
1105-
static PythonAbstractObjectNativeWrapper doNativeWrapperIncByOne(Node inliningTarget, PythonAbstractObjectNativeWrapper nativeWrapper, @SuppressWarnings("unused") long value,
1106-
@Shared @Cached InlinedConditionProfile isNativeProfile) {
1107-
if (nativeWrapper.isNative(inliningTarget, isNativeProfile)) {
1108-
nativeWrapper.incRef();
1109-
}
1110-
return nativeWrapper;
1111-
}
1112-
1113-
@Specialization(replaces = "doNativeWrapperIncByOne")
1114-
static PythonAbstractObjectNativeWrapper doNativeWrapper(Node inliningTarget, PythonAbstractObjectNativeWrapper nativeWrapper, long value,
1115-
@Shared @Cached InlinedConditionProfile isNativeProfile,
1116-
@Exclusive @Cached InlinedConditionProfile hasRefProfile) {
1117-
assert value >= 0 : "adding negative reference count; dealloc might not happen";
1118-
if (nativeWrapper.isNative(inliningTarget, isNativeProfile)) {
1119-
nativeWrapper.setRefCount(inliningTarget, nativeWrapper.getRefCount() + value, hasRefProfile);
1120-
}
1121-
return nativeWrapper;
1122-
}
1101+
public abstract void execute(Node inliningTarget, Object pointer);
11231102

1124-
@Specialization(guards = "!isNativeWrapper(object)", limit = "2")
1125-
static Object doNativeObject(Object object, long value,
1126-
@CachedLibrary("object") InteropLibrary lib) {
1127-
CApiContext cApiContext = PythonContext.get(lib).getCApiContext();
1128-
if (cApiContext != null && !lib.isNull(object)) {
1129-
assert value >= 0 : "adding negative reference count; dealloc might not happen";
1130-
try {
1131-
long pointer = lib.asPointer(object);
1132-
cApiContext.checkAccess(object, lib);
1133-
long refCount = CApiTransitions.readNativeRefCount(pointer);
1134-
CApiTransitions.writeNativeRefCount(pointer, refCount + value);
1135-
} catch (UnsupportedMessageException e) {
1136-
throw shouldNotReachHere(e);
1137-
}
1103+
@Specialization
1104+
static void doDecref(Node inliningTarget, Object pointer,
1105+
@Cached(inline = false) CApiTransitions.ToPythonWrapperNode toPythonWrapperNode,
1106+
@Cached InlinedBranchProfile isWrapperProfile,
1107+
@Cached InlinedBranchProfile isNativeObject,
1108+
@Cached(inline = false) PCallCapiFunction callDecrefNode) {
1109+
PythonNativeWrapper wrapper = toPythonWrapperNode.executeWrapper(pointer, false);
1110+
if (wrapper instanceof PythonAbstractObjectNativeWrapper objectWrapper) {
1111+
isWrapperProfile.enter(inliningTarget);
1112+
objectWrapper.decRef();
1113+
} else if (wrapper == null) {
1114+
isNativeObject.enter(inliningTarget);
1115+
assert NativeToPythonNode.executeUncached(pointer) instanceof PythonAbstractNativeObject;
1116+
callDecrefNode.call(NativeCAPISymbol.FUN_DECREF, pointer);
1117+
} else {
1118+
throw CompilerDirectives.shouldNotReachHere("Cannot DECREF non-object");
11381119
}
1139-
return object;
11401120
}
11411121
}
11421122

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@
6565
import com.oracle.graal.python.builtins.PythonBuiltins;
6666
import com.oracle.graal.python.builtins.objects.PNone;
6767
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
68-
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
69-
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
7068
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ReleaseNativeWrapperNode;
7169
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AsCharPointerNodeGen;
7270
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.ReleaseNativeWrapperNodeGen;
@@ -75,13 +73,11 @@
7573
import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodesFactory.ExternalFunctionInvokeNodeGen;
7674
import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodesFactory.MaterializePrimitiveNodeGen;
7775
import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodesFactory.ReleaseNativeSequenceStorageNodeGen;
78-
import com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper.PythonAbstractObjectNativeWrapper;
7976
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor;
8077
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming;
8178
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
8279
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeToPythonNode;
8380
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.PythonToNativeNode;
84-
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.ToPythonWrapperNode;
8581
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitionsFactory.PythonToNativeNodeGen;
8682
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.CheckFunctionResultNode;
8783
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.ConvertPIntToPrimitiveNode;
@@ -2228,46 +2224,28 @@ abstract static class ReleaseNativeSequenceStorageNode extends Node {
22282224
@Specialization(guards = {"storage.length() == cachedLen", "cachedLen <= 8"}, limit = "1")
22292225
@ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL)
22302226
static void doObjectCachedLen(NativeObjectSequenceStorage storage,
2227+
@Bind("this") Node inliningTarget,
22312228
@Cached("storage.length()") int cachedLen,
2232-
@Cached(value = "createConditionProfiles(cachedLen)", dimensions = 1) ConditionProfile[] objectWrapperProfiles,
2233-
@Cached(value = "createConditionProfiles(cachedLen)", dimensions = 1) ConditionProfile[] nativeObjectProfiles,
22342229
@Shared @Cached CStructAccess.ReadPointerNode readNode,
2235-
@Shared @Cached ToPythonWrapperNode toPythonWrapperNode,
2236-
@Shared @Cached PCallCapiFunction callDecrefNode,
2230+
@Shared @Cached CExtNodes.DecRefPointerNode decRefPointerNode,
22372231
@Shared @Cached CStructAccess.FreeNode freeNode) {
22382232
for (int i = 0; i < cachedLen; i++) {
22392233
Object elementPointer = readNode.readArrayElement(storage.getPtr(), i);
2240-
PythonNativeWrapper pythonNativeWrapper = toPythonWrapperNode.executeWrapper(elementPointer, false);
2241-
if (objectWrapperProfiles[i].profile(pythonNativeWrapper instanceof PythonAbstractObjectNativeWrapper)) {
2242-
((PythonAbstractObjectNativeWrapper) pythonNativeWrapper).decRef();
2243-
} else if (nativeObjectProfiles[i].profile(pythonNativeWrapper == null)) {
2244-
assert NativeToPythonNode.executeUncached(elementPointer) instanceof PythonAbstractNativeObject;
2245-
callDecrefNode.call(NativeCAPISymbol.FUN_DECREF, elementPointer);
2246-
} else {
2247-
throw CompilerDirectives.shouldNotReachHere("NativeObjectSequenceStorage contains non-object element");
2248-
}
2234+
decRefPointerNode.execute(inliningTarget, elementPointer);
22492235
}
22502236
// in this case, the runtime still exclusively owns the memory
22512237
freeNode.free(storage.getPtr());
22522238
}
22532239

22542240
@Specialization(replaces = "doObjectCachedLen")
22552241
static void doObjectGeneric(NativeObjectSequenceStorage storage,
2242+
@Bind("this") Node inliningTarget,
22562243
@Shared @Cached CStructAccess.ReadPointerNode readNode,
2257-
@Shared @Cached ToPythonWrapperNode toPythonWrapperNode,
2258-
@Shared @Cached PCallCapiFunction callDecrefNode,
2244+
@Shared @Cached CExtNodes.DecRefPointerNode decRefPointerNode,
22592245
@Shared @Cached CStructAccess.FreeNode freeNode) {
22602246
for (int i = 0; i < storage.length(); i++) {
22612247
Object elementPointer = readNode.readArrayElement(storage.getPtr(), i);
2262-
PythonNativeWrapper pythonNativeWrapper = toPythonWrapperNode.executeWrapper(elementPointer, false);
2263-
if (pythonNativeWrapper instanceof PythonAbstractObjectNativeWrapper objectNativeWrapper) {
2264-
objectNativeWrapper.decRef();
2265-
} else if (pythonNativeWrapper == null) {
2266-
assert NativeToPythonNode.executeUncached(elementPointer) instanceof PythonAbstractNativeObject;
2267-
callDecrefNode.call(NativeCAPISymbol.FUN_DECREF, elementPointer);
2268-
} else {
2269-
throw CompilerDirectives.shouldNotReachHere("NativeObjectSequenceStorage contains non-object element");
2270-
}
2248+
decRefPointerNode.execute(inliningTarget, elementPointer);
22712249
}
22722250
// in this case, the runtime still exclusively owns the memory
22732251
freeNode.free(storage.getPtr());

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ public enum NativeCAPISymbol implements NativeCExtSymbol {
138138
FUN_PY_UNICODE_GET_LENGTH("PyUnicode_GetLength", Py_ssize_t, PyObject),
139139
FUN_PY_TRUFFLE_FREE("PyTruffle_Free", ArgDescriptor.Void, Pointer),
140140
FUN_PYMEM_ALLOC("PyMem_Calloc", Pointer, SIZE_T, SIZE_T),
141-
FUN_INCREF("Py_IncRef", Void, Pointer),
142141
FUN_DECREF("Py_DecRef", Void, Pointer),
143142
FUN_SUBREF("PyTruffle_SUBREF", Py_ssize_t, Pointer, Py_ssize_t),
144143
FUN_BULK_DEALLOC("PyTruffle_bulk_DEALLOC", Py_ssize_t, Pointer, INT64_T),

0 commit comments

Comments
 (0)