Skip to content
This repository was archived by the owner on Jul 22, 2023. It is now read-only.

Commit 183f9d8

Browse files
committed
Load cache of ModuleObject after reload
1 parent f23cae6 commit 183f9d8

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

src/runtime/fieldobject.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Python.Runtime
66
/// <summary>
77
/// Implements a Python descriptor type that provides access to CLR fields.
88
/// </summary>
9+
[Serializable]
910
internal class FieldObject : ExtensionType
1011
{
1112
private FieldInfo info;

src/runtime/moduleobject.cs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ internal class ModuleObject : ExtensionType
1717
[NonSerialized]
1818
private Dictionary<string, ManagedType> cache;
1919

20+
[NonSerialized]
21+
// FIXME: Used by reload mode, remove it after implement a delay load handler.
22+
private bool _cacheInited;
23+
2024
internal string moduleName;
2125
internal IntPtr dict;
2226
protected string _namespace;
@@ -29,6 +33,7 @@ public ModuleObject(string name)
2933
}
3034
moduleName = name;
3135
cache = new Dictionary<string, ManagedType>();
36+
_cacheInited = true;
3237
_namespace = name;
3338

3439
// Use the filename from any of the assemblies just so there's something for
@@ -72,6 +77,11 @@ public ModuleObject(string name)
7277
/// </summary>
7378
public ManagedType GetAttribute(string name, bool guess)
7479
{
80+
if (!_cacheInited)
81+
{
82+
// XXX: Used by reload mode.
83+
SetupCacheByDict();
84+
}
7585
ManagedType cached = null;
7686
cache.TryGetValue(name, out cached);
7787
if (cached != null)
@@ -116,7 +126,6 @@ public ManagedType GetAttribute(string name, bool guess)
116126
{
117127
c = ClassManager.GetClass(type);
118128
StoreAttribute(name, c);
119-
c.DecrRefCount();
120129
return c;
121130
}
122131

@@ -140,7 +149,6 @@ public ManagedType GetAttribute(string name, bool guess)
140149
{
141150
c = ClassManager.GetClass(type);
142151
StoreAttribute(name, c);
143-
c.DecrRefCount();
144152
return c;
145153
}
146154
}
@@ -364,9 +372,34 @@ protected override void OnSave()
364372
protected override void OnLoad()
365373
{
366374
base.OnLoad();
375+
// XXX: Set the cache after all objects loaded.
367376
cache = new Dictionary<string, ManagedType>();
377+
_cacheInited = false;
368378
SetObjectDict(pyHandle, dict);
369379
}
380+
381+
private void SetupCacheByDict()
382+
{
383+
System.Diagnostics.Debug.Assert(!_cacheInited);
384+
_cacheInited = true;
385+
IntPtr key, value;
386+
IntPtr pos;
387+
while (Runtime.PyDict_Next(dict, out pos, out key, out value) != 0)
388+
{
389+
ManagedType obj = GetManagedObject(value);
390+
if (obj == null)
391+
{
392+
continue;
393+
}
394+
string name = Runtime.GetManagedString(key);
395+
if (cache.ContainsKey(name))
396+
{
397+
continue;
398+
}
399+
Runtime.XIncref(value);
400+
cache.Add(name, obj);
401+
}
402+
}
370403
}
371404

372405
/// <summary>

src/runtime/runtime.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ private static void MoveClrInstancesOnwershipToPython()
490490
ManagedType obj = entry.Key;
491491
if (!objs.ContainsKey(obj))
492492
{
493+
System.Diagnostics.Debug.Assert(obj.gcHandle == default);
493494
continue;
494495
}
495496
if (entry.Value == ManagedType.TrackTypes.Extension)
@@ -1675,6 +1676,9 @@ internal static bool PyDict_Check(IntPtr ob)
16751676
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
16761677
internal static extern IntPtr PyDict_New();
16771678

1679+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
1680+
internal static extern int PyDict_Next(IntPtr p, out IntPtr ppos, out IntPtr pkey, out IntPtr pvalue);
1681+
16781682
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
16791683
internal static extern IntPtr PyDictProxy_New(IntPtr dict);
16801684

@@ -2004,7 +2008,7 @@ internal static IntPtr PyType_GenericAlloc(IntPtr type, long n)
20042008
private static extern IntPtr PyType_GenericAlloc(IntPtr type, IntPtr n);
20052009

20062010
/// <summary>
2007-
/// Finalize a type object. This should be called on all type objects to finish their initialization. This function is responsible for adding inherited slots from a type¡¯s base class. Return 0 on success, or return -1 and sets an exception on error.
2011+
/// Finalize a type object. This should be called on all type objects to finish their initialization. This function is responsible for adding inherited slots from a types base class. Return 0 on success, or return -1 and sets an exception on error.
20082012
/// </summary>
20092013
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
20102014
internal static extern int PyType_Ready(IntPtr type);

0 commit comments

Comments
 (0)