|
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