| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -32,21 +32,6 @@ public static void Py_IsInitializedValue() | |||
| 32 | 32 | Assert.AreEqual(0, Runtime.Runtime.Py_IsInitialized()); | |
| 33 | 33 | } | |
| 34 | 34 | ||
| 35 | - [Test] | ||
| 36 | - public static void IterAcrossRuns() | ||
| 37 | - { | ||
| 38 | - Runtime.Runtime.Py_Initialize(); | ||
| 39 | - BorrowedReference builtins = Runtime.Runtime.PyEval_GetBuiltins(); | ||
| 40 | - BorrowedReference iter = Runtime.Runtime.PyDict_GetItemString(builtins, "iter"); | ||
| 41 | - | ||
| 42 | - using var ownedIter = new NewReference(iter); | ||
| 43 | - Runtime.Runtime.Py_Finalize(); | ||
| 44 | - | ||
| 45 | - Runtime.Runtime.Py_Initialize(); | ||
| 46 | - ownedIter.Dispose(); | ||
| 47 | - Runtime.Runtime.Py_Finalize(); | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | 35 | [Test] | |
| 51 | 36 | public static void RefCountTest() | |
| 52 | 37 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | using System; | |
| 2 | 2 | using System.Diagnostics; | |
| 3 | + using System.Runtime.Serialization; | ||
| 3 | 4 | ||
| 4 | 5 | using static Python.Runtime.PythonException; | |
| 5 | 6 | ||
@@ -10,6 +11,7 @@ internal sealed class ReflectedClrType : PyType | |||
| 10 | 11 | { | |
| 11 | 12 | private ReflectedClrType(StolenReference reference) : base(reference, prevalidated: true) { } | |
| 12 | 13 | internal ReflectedClrType(ReflectedClrType original) : base(original, prevalidated: true) { } | |
| 14 | + ReflectedClrType(SerializationInfo info, StreamingContext context) : base(info, context) { } | ||
| 13 | 15 | ||
| 14 | 16 | internal ClassBase Impl => (ClassBase)ManagedType.GetManagedObject(this)!; | |
| 15 | 17 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -337,7 +337,6 @@ public static NewReference tp_repr(BorrowedReference ob) | |||
| 337 | 337 | /// </summary> | |
| 338 | 338 | public static void tp_dealloc(NewReference lastRef) | |
| 339 | 339 | { | |
| 340 | - Runtime.PyGC_ValidateLists(); | ||
| 341 | 340 | Runtime.PyObject_GC_UnTrack(lastRef.Borrow()); | |
| 342 | 341 | ||
| 343 | 342 | CallClear(lastRef.Borrow()); | |
@@ -347,12 +346,10 @@ public static void tp_dealloc(NewReference lastRef) | |||
| 347 | 346 | Debug.Assert(deleted); | |
| 348 | 347 | ||
| 349 | 348 | DecrefTypeAndFree(lastRef.Steal()); | |
| 350 | - Runtime.PyGC_ValidateLists(); | ||
| 351 | 349 | } | |
| 352 | 350 | ||
| 353 | 351 | public static int tp_clear(BorrowedReference ob) | |
| 354 | 352 | { | |
| 355 | - Runtime.PyGC_ValidateLists(); | ||
| 356 | 353 | GCHandle? gcHandle = TryGetGCHandle(ob); | |
| 357 | 354 | gcHandle?.Free(); | |
| 358 | 355 | ||
@@ -363,7 +360,6 @@ public static int tp_clear(BorrowedReference ob) | |||
| 363 | 360 | } | |
| 364 | 361 | ||
| 365 | 362 | ClearObjectDict(ob); | |
| 366 | - Runtime.PyGC_ValidateLists(); | ||
| 367 | 363 | return 0; | |
| 368 | 364 | } | |
| 369 | 365 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -69,7 +69,6 @@ internal ClassDerivedObject(Type tp) : base(tp) | |||
| 69 | 69 | ||
| 70 | 70 | public new static void tp_dealloc(NewReference ob) | |
| 71 | 71 | { | |
| 72 | - Runtime.PyGC_ValidateLists(); | ||
| 73 | 72 | var self = (CLRObject)GetManagedObject(ob.Borrow())!; | |
| 74 | 73 | ||
| 75 | 74 | // don't let the python GC destroy this object | |
@@ -83,7 +82,6 @@ internal ClassDerivedObject(Type tp) : base(tp) | |||
| 83 | 82 | GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak); | |
| 84 | 83 | SetGCHandle(ob.Borrow(), gc); | |
| 85 | 84 | oldHandle.Free(); | |
| 86 | - Runtime.PyGC_ValidateLists(); | ||
| 87 | 85 | } | |
| 88 | 86 | ||
| 89 | 87 | /// <summary> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -152,9 +152,7 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg) | |||
| 152 | 152 | var self = (ConstructorBinding?)GetManagedObject(ob); | |
| 153 | 153 | if (self is null) return 0; | |
| 154 | 154 | ||
| 155 | - Runtime.PyGC_ValidateLists(); | ||
| 156 | 155 | int res = PyVisit(self.typeToCreate, visit, arg); | |
| 157 | - Runtime.PyGC_ValidateLists(); | ||
| 158 | 156 | return res; | |
| 159 | 157 | } | |
| 160 | 158 | } | |
@@ -237,9 +235,7 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg) | |||
| 237 | 235 | var self = (BoundContructor?)GetManagedObject(ob); | |
| 238 | 236 | if (self is null) return 0; | |
| 239 | 237 | ||
| 240 | - Runtime.PyGC_ValidateLists(); | ||
| 241 | 238 | int res = PyVisit(self.typeToCreate, visit, arg); | |
| 242 | - Runtime.PyGC_ValidateLists(); | ||
| 243 | 239 | return res; | |
| 244 | 240 | } | |
| 245 | 241 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -76,7 +76,6 @@ public static int tp_setattro(BorrowedReference ob, BorrowedReference key, Borro | |||
| 76 | 76 | ||
| 77 | 77 | public unsafe static void tp_dealloc(NewReference lastRef) | |
| 78 | 78 | { | |
| 79 | - Runtime.PyGC_ValidateLists(); | ||
| 80 | 79 | Runtime.PyObject_GC_UnTrack(lastRef.Borrow()); | |
| 81 | 80 | ||
| 82 | 81 | tp_clear(lastRef.Borrow()); | |
@@ -86,18 +85,15 @@ public unsafe static void tp_dealloc(NewReference lastRef) | |||
| 86 | 85 | ||
| 87 | 86 | // we must decref our type: https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_dealloc | |
| 88 | 87 | DecrefTypeAndFree(lastRef.Steal()); | |
| 89 | - Runtime.PyGC_ValidateLists(); | ||
| 90 | 88 | } | |
| 91 | 89 | ||
| 92 | 90 | public static int tp_clear(BorrowedReference ob) | |
| 93 | 91 | { | |
| 94 | - Runtime.PyGC_ValidateLists(); | ||
| 95 | 92 | GCHandle? gcHandle = TryGetGCHandle(ob); | |
| 96 | 93 | gcHandle?.Free(); | |
| 97 | 94 | if (gcHandle is not null) SetGCHandle(ob, default); | |
| 98 | 95 | ||
| 99 | 96 | int res = ClassBase.BaseUnmanagedClear(ob); | |
| 100 | - Runtime.PyGC_ValidateLists(); | ||
| 101 | 97 | return res; | |
| 102 | 98 | } | |
| 103 | 99 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -122,19 +122,30 @@ internal List<IntPtr> GetCollectedObjects() | |||
| 122 | 122 | return _objQueue.Select(o => o.PyObj).ToList(); | |
| 123 | 123 | } | |
| 124 | 124 | ||
| 125 | - internal void AddFinalizedObject(ref IntPtr obj, int run) | ||
| 125 | + internal void AddFinalizedObject(ref IntPtr obj, int run | ||
| 126 | + #if TRACE_ALLOC | ||
| 127 | + , StackTrace stackTrace | ||
| 128 | + #endif | ||
| 129 | + ) | ||
| 126 | 130 | { | |
| 127 | 131 | Debug.Assert(obj != IntPtr.Zero); | |
| 128 | 132 | if (!Enable) | |
| 129 | 133 | { | |
| 130 | 134 | return; | |
| 131 | 135 | } | |
| 132 | 136 | ||
| 137 | + Debug.Assert(Runtime.Refcount(new BorrowedReference(obj)) > 0); | ||
| 138 | + | ||
| 133 | 139 | #if FINALIZER_CHECK | |
| 134 | 140 | lock (_queueLock) | |
| 135 | 141 | #endif | |
| 136 | 142 | { | |
| 137 | - this._objQueue.Enqueue(new PendingFinalization { PyObj = obj, RuntimeRun = run }); | ||
| 143 | + this._objQueue.Enqueue(new PendingFinalization { | ||
| 144 | + PyObj = obj, RuntimeRun = run, | ||
| 145 | + #if TRACE_ALLOC | ||
| 146 | + StackTrace = stackTrace.ToString(), | ||
| 147 | + #endif | ||
| 148 | + }); | ||
| 138 | 149 | } | |
| 139 | 150 | obj = IntPtr.Zero; | |
| 140 | 151 | } | |
@@ -165,10 +176,12 @@ internal static void Shutdown() | |||
| 165 | 176 | Instance.started = false; | |
| 166 | 177 | } | |
| 167 | 178 | ||
| 168 | - private void DisposeAll() | ||
| 179 | + internal nint DisposeAll() | ||
| 169 | 180 | { | |
| 170 | 181 | if (_objQueue.IsEmpty && _derivedQueue.IsEmpty) | |
| 171 | - return; | ||
| 182 | + return 0; | ||
| 183 | + | ||
| 184 | + nint collected = 0; | ||
| 172 | 185 | ||
| 173 | 186 | BeforeCollect?.Invoke(this, new CollectArgs() | |
| 174 | 187 | { | |
@@ -200,16 +213,8 @@ private void DisposeAll() | |||
| 200 | 213 | } | |
| 201 | 214 | ||
| 202 | 215 | IntPtr copyForException = obj.PyObj; | |
| 203 | - Runtime.PyGC_ValidateLists(); | ||
| 204 | - var @ref = new BorrowedReference(obj.PyObj); | ||
| 205 | - nint refs = Runtime.Refcount(@ref); | ||
| 206 | - var type = Runtime.PyObject_TYPE(@ref); | ||
| 207 | - string typeName = Runtime.ToString(type); | ||
| 208 | - if (typeName == "<class 'clr.interop.PyErr'>") | ||
| 209 | - { | ||
| 210 | - | ||
| 211 | - } | ||
| 212 | 216 | Runtime.XDecref(StolenReference.Take(ref obj.PyObj)); | |
| 217 | + collected++; | ||
| 213 | 218 | try | |
| 214 | 219 | { | |
| 215 | 220 | Runtime.CheckExceptionOccurred(); | |
@@ -218,7 +223,6 @@ private void DisposeAll() | |||
| 218 | 223 | { | |
| 219 | 224 | HandleFinalizationException(obj.PyObj, e); | |
| 220 | 225 | } | |
| 221 | - Runtime.PyGC_ValidateLists(); | ||
| 222 | 226 | } | |
| 223 | 227 | ||
| 224 | 228 | while (!_derivedQueue.IsEmpty) | |
@@ -241,6 +245,7 @@ private void DisposeAll() | |||
| 241 | 245 | // matches correspdonging PyObject_GC_UnTrack | |
| 242 | 246 | // in ClassDerivedObject.tp_dealloc | |
| 243 | 247 | Runtime.PyObject_GC_Del(@ref.Steal()); | |
| 248 | + collected++; | ||
| 244 | 249 | ||
| 245 | 250 | gcHandle.Free(); | |
| 246 | 251 | } | |
@@ -252,6 +257,7 @@ private void DisposeAll() | |||
| 252 | 257 | Runtime.PyErr_Restore(errType.StealNullable(), errVal.StealNullable(), traceback.StealNullable()); | |
| 253 | 258 | } | |
| 254 | 259 | } | |
| 260 | + return collected; | ||
| 255 | 261 | } | |
| 256 | 262 | ||
| 257 | 263 | void HandleFinalizationException(IntPtr obj, Exception cause) | |
@@ -341,6 +347,9 @@ struct PendingFinalization | |||
| 341 | 347 | { | |
| 342 | 348 | public IntPtr PyObj; | |
| 343 | 349 | public int RuntimeRun; | |
| 350 | + #if TRACE_ALLOC | ||
| 351 | + public string StackTrace; | ||
| 352 | + #endif | ||
| 344 | 353 | } | |
| 345 | 354 | ||
| 346 | 355 | public class FinalizationException : Exception | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -290,7 +290,6 @@ public static NewReference mp_subscript(BorrowedReference tp, BorrowedReference | |||
| 290 | 290 | /// </summary> | |
| 291 | 291 | public static void tp_dealloc(NewReference lastRef) | |
| 292 | 292 | { | |
| 293 | - Runtime.PyGC_ValidateLists(); | ||
| 294 | 293 | // Fix this when we dont cheat on the handle for subclasses! | |
| 295 | 294 | ||
| 296 | 295 | var flags = PyType.GetFlags(lastRef.Borrow()); | |
@@ -318,7 +317,6 @@ public static void tp_dealloc(NewReference lastRef) | |||
| 318 | 317 | // We must decref our type. | |
| 319 | 318 | // type_dealloc from PyType will use it to get tp_free so we must keep the value | |
| 320 | 319 | Runtime.XDecref(StolenReference.DangerousFromPointer(op.DangerousGetAddress())); | |
| 321 | - Runtime.PyGC_ValidateLists(); | ||
| 322 | 320 | } | |
| 323 | 321 | ||
| 324 | 322 | private static NewReference DoInstanceCheck(BorrowedReference tp, BorrowedReference args, bool checkType) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | using System.Linq; | |
| 3 | 3 | using System.Collections.Generic; | |
| 4 | 4 | using System.Dynamic; | |
| 5 | + using System.Runtime.Serialization; | ||
| 5 | 6 | ||
| 6 | 7 | namespace Python.Runtime | |
| 7 | 8 | { | |
@@ -42,6 +43,9 @@ internal PyModule(in StolenReference reference) : base(reference) | |||
| 42 | 43 | } | |
| 43 | 44 | } | |
| 44 | 45 | ||
| 46 | + protected PyModule(SerializationInfo info, StreamingContext context) | ||
| 47 | + : base(info, context) { } | ||
| 48 | + | ||
| 45 | 49 | private void InitializeBuiltins() | |
| 46 | 50 | { | |
| 47 | 51 | int res = Runtime.PyDict_SetItem( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -323,16 +323,12 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg) | |||
| 323 | 323 | var self = (ModuleObject?)GetManagedObject(ob); | |
| 324 | 324 | if (self is null) return 0; | |
| 325 | 325 | ||
| 326 | - Runtime.PyGC_ValidateLists(); | ||
| 327 | 326 | Debug.Assert(self.dict == GetObjectDict(ob)); | |
| 328 | 327 | int res = PyVisit(self.dict, visit, arg); | |
| 329 | - Runtime.PyGC_ValidateLists(); | ||
| 330 | 328 | if (res != 0) return res; | |
| 331 | 329 | foreach (var attr in self.cache.Values) | |
| 332 | 330 | { | |
| 333 | - Runtime.PyGC_ValidateLists(); | ||
| 334 | 331 | res = PyVisit(attr, visit, arg); | |
| 335 | - Runtime.PyGC_ValidateLists(); | ||
| 336 | 332 | if (res != 0) return res; | |
| 337 | 333 | } | |
| 338 | 334 | return 0; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments