Skip to content

Commit 0e43fd4

Browse files
Merge pull request #71 from Martin-Molinero/bug-remove-reference-tracking
Remove managed reference tracking
2 parents 83f88d2 + f4190fd commit 0e43fd4

File tree

8 files changed

+7
-85
lines changed

8 files changed

+7
-85
lines changed

src/perf_tests/Python.PerformanceTests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1414
</PackageReference>
1515
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.*" />
16-
<PackageReference Include="quantconnect.pythonnet" Version="2.0.17" GeneratePathProperty="true">
16+
<PackageReference Include="quantconnect.pythonnet" Version="2.0.18" GeneratePathProperty="true">
1717
<IncludeAssets>compile</IncludeAssets>
1818
</PackageReference>
1919
</ItemGroup>
@@ -25,7 +25,7 @@
2525
</Target>
2626

2727
<Target Name="CopyBaseline" AfterTargets="Build">
28-
<Copy SourceFiles="$(NuGetPackageRoot)quantconnect.pythonnet\2.0.17\lib\net5.0\Python.Runtime.dll" DestinationFolder="$(OutDir)baseline" />
28+
<Copy SourceFiles="$(NuGetPackageRoot)quantconnect.pythonnet\2.0.18\lib\net5.0\Python.Runtime.dll" DestinationFolder="$(OutDir)baseline" />
2929
</Target>
3030

3131
<Target Name="CopyNewBuild" AfterTargets="Build">

src/runtime/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
[assembly: InternalsVisibleTo("Python.EmbeddingTest, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")]
55
[assembly: InternalsVisibleTo("Python.Test, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")]
66

7-
[assembly: AssemblyVersion("2.0.17")]
8-
[assembly: AssemblyFileVersion("2.0.17")]
7+
[assembly: AssemblyVersion("2.0.18")]
8+
[assembly: AssemblyFileVersion("2.0.18")]

src/runtime/Python.Runtime.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<RootNamespace>Python.Runtime</RootNamespace>
66
<AssemblyName>Python.Runtime</AssemblyName>
77
<PackageId>QuantConnect.pythonnet</PackageId>
8-
<Version>2.0.17</Version>
8+
<Version>2.0.18</Version>
99
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
1010
<PackageLicenseFile>LICENSE</PackageLicenseFile>
1111
<RepositoryUrl>https://github.com/pythonnet/pythonnet</RepositoryUrl>

src/runtime/Runtime.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ internal static void Shutdown()
280280
ClearClrModules();
281281
RemoveClrRootModule();
282282

283-
NullGCHandles(ExtensionType.loadedExtensions);
284283
ClassManager.RemoveClasses();
285284
TypeManager.RemoveTypes();
286285
_typesInitialized = false;
@@ -319,8 +318,6 @@ internal static void Shutdown()
319318
PyEval_SaveThread();
320319
}
321320

322-
ExtensionType.loadedExtensions.Clear();
323-
CLRObject.reflectedObjects.Clear();
324321
}
325322
else
326323
{
@@ -349,11 +346,6 @@ static bool TryCollectingGarbage(int runs, bool forceBreakLoops)
349346
{
350347
if (attempt + 1 == runs) return true;
351348
}
352-
else if (forceBreakLoops)
353-
{
354-
NullGCHandles(CLRObject.reflectedObjects);
355-
CLRObject.reflectedObjects.Clear();
356-
}
357349
}
358350
return false;
359351
}

src/runtime/StateSerialization/RuntimeData.cs

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -140,57 +140,9 @@ static bool CheckSerializable (object o)
140140
private static SharedObjectsState SaveRuntimeDataObjects()
141141
{
142142
var contexts = new Dictionary<PyObject, Dictionary<string, object?>>(PythonReferenceComparer.Instance);
143-
var extensionObjs = new Dictionary<PyObject, ExtensionType>(PythonReferenceComparer.Instance);
144-
// make a copy with strongly typed references to avoid concurrent modification
145-
var extensions = ExtensionType.loadedExtensions
146-
.Select(addr => new PyObject(
147-
new BorrowedReference(addr),
148-
// if we don't skip collect, finalizer might modify loadedExtensions
149-
skipCollect: true))
150-
.ToArray();
151-
foreach (var pyObj in extensions)
152-
{
153-
var extension = (ExtensionType)ManagedType.GetManagedObject(pyObj)!;
154-
Debug.Assert(CheckSerializable(extension));
155-
var context = extension.Save(pyObj);
156-
if (context is not null)
157-
{
158-
contexts[pyObj] = context;
159-
}
160-
extensionObjs.Add(pyObj, extension);
161-
}
162143

163144
var wrappers = new Dictionary<object, List<CLRObject>>();
164145
var userObjects = new CLRWrapperCollection();
165-
// make a copy with strongly typed references to avoid concurrent modification
166-
var reflectedObjects = CLRObject.reflectedObjects
167-
.Select(addr => new PyObject(
168-
new BorrowedReference(addr),
169-
// if we don't skip collect, finalizer might modify reflectedObjects
170-
skipCollect: true))
171-
.ToList();
172-
foreach (var pyObj in reflectedObjects)
173-
{
174-
// Wrapper must be the CLRObject
175-
var clrObj = (CLRObject)ManagedType.GetManagedObject(pyObj)!;
176-
object inst = clrObj.inst;
177-
List<CLRObject> mappedObjs;
178-
if (!userObjects.TryGetValue(inst, out var item))
179-
{
180-
item = new CLRMappedItem(inst);
181-
userObjects.Add(item);
182-
183-
Debug.Assert(!wrappers.ContainsKey(inst));
184-
mappedObjs = new List<CLRObject>();
185-
wrappers.Add(inst, mappedObjs);
186-
}
187-
else
188-
{
189-
mappedObjs = wrappers[inst];
190-
}
191-
item.AddRef(pyObj);
192-
mappedObjs.Add(clrObj);
193-
}
194146

195147
var wrapperStorage = new Dictionary<string, object?>();
196148
WrappersStorer?.Store(userObjects, wrapperStorage);
@@ -215,7 +167,6 @@ private static SharedObjectsState SaveRuntimeDataObjects()
215167
return new()
216168
{
217169
InternalStores = internalStores,
218-
Extensions = extensionObjs,
219170
Wrappers = wrapperStorage,
220171
Contexts = contexts,
221172
};

src/runtime/Types/ClassBase.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,7 @@ public static int tp_clear(BorrowedReference ob)
352352
Runtime.PyObject_ClearWeakRefs(ob);
353353
}
354354

355-
if (TryFreeGCHandle(ob))
356-
{
357-
IntPtr addr = ob.DangerousGetAddress();
358-
bool deleted = CLRObject.reflectedObjects.Remove(addr);
359-
Debug.Assert(deleted);
360-
}
355+
TryFreeGCHandle(ob);
361356

362357
int baseClearResult = BaseUnmanagedClear(ob);
363358
if (baseClearResult != 0)

src/runtime/Types/ClrObject.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ internal sealed class CLRObject : ManagedType
1111
{
1212
internal readonly object inst;
1313

14-
// "borrowed" references
15-
internal static readonly HashSet<IntPtr> reflectedObjects = new();
1614
static NewReference Create(object ob, BorrowedReference tp)
1715
{
1816
Debug.Assert(tp != null);
@@ -23,8 +21,6 @@ static NewReference Create(object ob, BorrowedReference tp)
2321
GCHandle gc = GCHandle.Alloc(self);
2422
InitGCHandle(py.Borrow(), type: tp, gc);
2523

26-
bool isNew = reflectedObjects.Add(py.DangerousGetAddress());
27-
Debug.Assert(isNew);
2824

2925
// Fix the BaseException args (and __cause__ in case of Python 3)
3026
// slot if wrapping a CLR exception
@@ -64,9 +60,6 @@ protected override void OnLoad(BorrowedReference ob, Dictionary<string, object?>
6460
base.OnLoad(ob, context);
6561
GCHandle gc = GCHandle.Alloc(this);
6662
SetGCHandle(ob, gc);
67-
68-
bool isNew = reflectedObjects.Add(ob.DangerousGetAddress());
69-
Debug.Assert(isNew);
7063
}
7164
}
7265
}

src/runtime/Types/ExtensionType.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,11 @@ public virtual NewReference Alloc()
4242

4343
public PyObject AllocObject() => new PyObject(Alloc().Steal());
4444

45-
// "borrowed" references
46-
internal static readonly HashSet<IntPtr> loadedExtensions = new();
4745
void SetupGc (BorrowedReference ob, BorrowedReference tp)
4846
{
4947
GCHandle gc = GCHandle.Alloc(this);
5048
InitGCHandle(ob, tp, gc);
5149

52-
bool isNew = loadedExtensions.Add(ob.DangerousGetAddress());
53-
Debug.Assert(isNew);
54-
5550
// We have to support gc because the type machinery makes it very
5651
// hard not to - but we really don't have a need for it in most
5752
// concrete extension types, so untrack the object to save calls
@@ -92,11 +87,7 @@ public static int tp_clear(BorrowedReference ob)
9287
Runtime.PyObject_ClearWeakRefs(ob);
9388
}
9489

95-
if (TryFreeGCHandle(ob))
96-
{
97-
bool deleted = loadedExtensions.Remove(ob.DangerousGetAddress());
98-
Debug.Assert(deleted);
99-
}
90+
TryFreeGCHandle(ob);
10091

10192
int res = ClassBase.BaseUnmanagedClear(ob);
10293
return res;

0 commit comments

Comments
 (0)