|
43 | 43 | import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE;
|
44 | 44 | import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PTR_ADD;
|
45 | 45 | import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PTR_COMPARE;
|
| 46 | +import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_DEALLOC; |
46 | 47 | import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_GC_DEL;
|
47 | 48 | import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TRUFFLE_MEMORYVIEW_FROM_OBJECT;
|
48 | 49 | import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_TYPE_GENERIC_ALLOC;
|
| 50 | +import static com.oracle.graal.python.builtins.objects.cext.capi.PythonNativeWrapper.PythonAbstractObjectNativeWrapper.IMMORTAL_REFCNT; |
49 | 51 | import static com.oracle.graal.python.builtins.objects.cext.structs.CConstants.PYLONG_BITS_IN_DIGIT;
|
50 | 52 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyFloatObject__ob_fval;
|
51 | 53 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyMethodDef__ml_doc;
|
|
58 | 60 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyModuleDef__m_methods;
|
59 | 61 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyModuleDef__m_size;
|
60 | 62 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyModuleDef__m_slots;
|
| 63 | +import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyObject__ob_refcnt; |
61 | 64 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyObject__ob_type;
|
62 | 65 | import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_as_buffer;
|
63 | 66 | import static com.oracle.graal.python.nodes.HiddenAttr.METHOD_DEF_PTR;
|
|
83 | 86 | import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
|
84 | 87 | import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
|
85 | 88 | import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
|
86 |
| -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AddRefCntNodeGen; |
87 | 89 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.AsCharPointerNodeGen;
|
88 | 90 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.CreateFunctionNodeGen;
|
89 | 91 | import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.FromCharPointerNodeGen;
|
|
113 | 115 | import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
|
114 | 116 | import com.oracle.graal.python.builtins.objects.cext.common.CExtContext.ModuleSpec;
|
115 | 117 | import com.oracle.graal.python.builtins.objects.cext.common.GetNextVaArgNode;
|
| 118 | +import com.oracle.graal.python.builtins.objects.cext.common.NativePointer; |
116 | 119 | import com.oracle.graal.python.builtins.objects.cext.structs.CFields;
|
117 | 120 | import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
|
118 | 121 | import com.oracle.graal.python.builtins.objects.cext.structs.CStructs;
|
|
200 | 203 | import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
201 | 204 | import com.oracle.truffle.api.library.CachedLibrary;
|
202 | 205 | import com.oracle.truffle.api.nodes.Node;
|
| 206 | +import com.oracle.truffle.api.profiles.InlinedBranchProfile; |
203 | 207 | import com.oracle.truffle.api.profiles.InlinedConditionProfile;
|
204 | 208 | import com.oracle.truffle.api.source.Source;
|
205 | 209 | import com.oracle.truffle.api.strings.TruffleString;
|
@@ -1132,51 +1136,56 @@ static PRaiseNativeNode doIt(@Cached(inline = false) PRaiseNativeNode node) {
|
1132 | 1136 | @GenerateInline
|
1133 | 1137 | @GenerateCached(false)
|
1134 | 1138 | @GenerateUncached
|
1135 |
| - @ImportStatic(CApiGuards.class) |
1136 |
| - public abstract static class AddRefCntNode extends PNodeWithContext { |
| 1139 | + public abstract static class DecRefPointerNode extends PNodeWithContext { |
1137 | 1140 |
|
1138 |
| - public static Object executeUncached(Object object, long value) { |
1139 |
| - return AddRefCntNodeGen.getUncached().execute(null, object, value); |
| 1141 | + public static void executeUncached(Object pointer) { |
| 1142 | + CExtNodesFactory.DecRefPointerNodeGen.getUncached().execute(null, pointer); |
1140 | 1143 | }
|
1141 | 1144 |
|
1142 |
| - public abstract Object execute(Node inliningTarget, Object object, long value); |
1143 |
| - |
1144 |
| - @Specialization(guards = "value == 1") |
1145 |
| - static PythonAbstractObjectNativeWrapper doNativeWrapperIncByOne(Node inliningTarget, PythonAbstractObjectNativeWrapper nativeWrapper, @SuppressWarnings("unused") long value, |
1146 |
| - @Shared @Cached InlinedConditionProfile isNativeProfile) { |
1147 |
| - if (nativeWrapper.isNative(inliningTarget, isNativeProfile)) { |
1148 |
| - nativeWrapper.incRef(); |
1149 |
| - } |
1150 |
| - return nativeWrapper; |
1151 |
| - } |
| 1145 | + public abstract void execute(Node inliningTarget, Object pointer); |
1152 | 1146 |
|
1153 |
| - @Specialization(replaces = "doNativeWrapperIncByOne") |
1154 |
| - static PythonAbstractObjectNativeWrapper doNativeWrapper(Node inliningTarget, PythonAbstractObjectNativeWrapper nativeWrapper, long value, |
1155 |
| - @Shared @Cached InlinedConditionProfile isNativeProfile, |
1156 |
| - @Exclusive @Cached InlinedConditionProfile hasRefProfile) { |
1157 |
| - assert value >= 0 : "adding negative reference count; dealloc might not happen"; |
1158 |
| - if (nativeWrapper.isNative(inliningTarget, isNativeProfile)) { |
1159 |
| - nativeWrapper.setRefCount(inliningTarget, nativeWrapper.getRefCount() + value, hasRefProfile); |
| 1147 | + @Specialization |
| 1148 | + static void doDecref(Node inliningTarget, Object pointerObj, |
| 1149 | + @CachedLibrary(limit = "2") InteropLibrary lib, |
| 1150 | + @Cached(inline = false) CApiTransitions.ToPythonWrapperNode toPythonWrapperNode, |
| 1151 | + @Cached InlinedBranchProfile isWrapperProfile, |
| 1152 | + @Cached InlinedBranchProfile isNativeObject, |
| 1153 | + @Cached(inline = false) CStructAccess.ReadI64Node readRefcount, |
| 1154 | + @Cached(inline = false) CStructAccess.WriteLongNode writeRefcount, |
| 1155 | + @Cached(inline = false) PCallCapiFunction callDealloc) { |
| 1156 | + long pointer; |
| 1157 | + if (pointerObj instanceof Long longPointer) { |
| 1158 | + pointer = longPointer; |
| 1159 | + } else { |
| 1160 | + if (lib.isPointer(pointerObj)) { |
| 1161 | + try { |
| 1162 | + pointer = lib.asPointer(pointerObj); |
| 1163 | + } catch (UnsupportedMessageException e) { |
| 1164 | + throw CompilerDirectives.shouldNotReachHere(); |
| 1165 | + } |
| 1166 | + } else { |
| 1167 | + // No refcounting in managed mode |
| 1168 | + return; |
| 1169 | + } |
1160 | 1170 | }
|
1161 |
| - return nativeWrapper; |
1162 |
| - } |
1163 |
| - |
1164 |
| - @Specialization(guards = "!isNativeWrapper(object)", limit = "2") |
1165 |
| - static Object doNativeObject(Object object, long value, |
1166 |
| - @CachedLibrary("object") InteropLibrary lib) { |
1167 |
| - CApiContext cApiContext = PythonContext.get(lib).getCApiContext(); |
1168 |
| - if (cApiContext != null && !lib.isNull(object)) { |
1169 |
| - assert value >= 0 : "adding negative reference count; dealloc might not happen"; |
1170 |
| - try { |
1171 |
| - long pointer = lib.asPointer(object); |
1172 |
| - cApiContext.checkAccess(object, lib); |
1173 |
| - long refCount = CApiTransitions.readNativeRefCount(pointer); |
1174 |
| - CApiTransitions.writeNativeRefCount(pointer, refCount + value); |
1175 |
| - } catch (UnsupportedMessageException e) { |
1176 |
| - throw shouldNotReachHere(e); |
| 1171 | + PythonNativeWrapper wrapper = toPythonWrapperNode.executeWrapper(pointer, false); |
| 1172 | + if (wrapper instanceof PythonAbstractObjectNativeWrapper objectWrapper) { |
| 1173 | + isWrapperProfile.enter(inliningTarget); |
| 1174 | + objectWrapper.decRef(); |
| 1175 | + } else if (wrapper == null) { |
| 1176 | + isNativeObject.enter(inliningTarget); |
| 1177 | + assert NativeToPythonNode.executeUncached(new NativePointer(pointer)) instanceof PythonAbstractNativeObject; |
| 1178 | + long refcount = readRefcount.read(pointer, PyObject__ob_refcnt); |
| 1179 | + if (refcount != IMMORTAL_REFCNT) { |
| 1180 | + refcount--; |
| 1181 | + writeRefcount.write(pointer, PyObject__ob_refcnt, refcount); |
| 1182 | + if (refcount == 0) { |
| 1183 | + callDealloc.call(FUN_PY_DEALLOC, pointer); |
| 1184 | + } |
1177 | 1185 | }
|
| 1186 | + } else { |
| 1187 | + throw CompilerDirectives.shouldNotReachHere("Cannot DECREF non-object"); |
1178 | 1188 | }
|
1179 |
| - return object; |
1180 | 1189 | }
|
1181 | 1190 | }
|
1182 | 1191 |
|
|
0 commit comments