Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit689f0d8

Browse files
committed
detect Py_TRACE_REFS at runtime and calculate object offsets accordingly
1 parent23527d1 commit689f0d8

File tree

7 files changed

+108
-110
lines changed

7 files changed

+108
-110
lines changed

‎src/runtime/classderived.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,7 @@ internal static IntPtr ToPython(IPythonDerivedType obj)
101101
// collected while Python still has a reference to it.
102102
if(Runtime.Refcount(self.pyHandle)==1)
103103
{
104-
105-
#ifPYTHON_WITH_PYDEBUG
106-
Runtime._Py_NewReference(self.pyHandle);
107-
#endif
104+
Runtime._Py_NewReference(self.ObjectReference);
108105
GCHandlegc=GCHandle.Alloc(self,GCHandleType.Normal);
109106
Marshal.WriteIntPtr(self.pyHandle,ObjectOffset.magic(self.tpHandle),(IntPtr)gc);
110107
self.gcHandle.Free();

‎src/runtime/converter.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,16 @@ internal static bool ToManagedValue(IntPtr value, Type obType,
525525

526526
internaldelegateboolTryConvertFromPythonDelegate(IntPtrpyObj,outobjectresult);
527527

528+
internalstaticintToInt32(BorrowedReferencevalue)
529+
{
530+
nintnum=Runtime.PyLong_AsSignedSize_t(value);
531+
if(num==-1&&Exceptions.ErrorOccurred())
532+
{
533+
thrownewPythonException();
534+
}
535+
returnchecked((int)num);
536+
}
537+
528538
/// <summary>
529539
/// Convert a Python value to an instance of a primitive managed type.
530540
/// </summary>

‎src/runtime/interop.cs

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ internal static partial class TypeOffset
7676
internalstaticclassManagedDataOffsets
7777
{
7878
publicstaticintMagic{get;internalset;}
79-
publicstaticreadonlyDictionary<string,int>NameMapping=newDictionary<string,int>();
8079

8180
staticclassDataOffsets
8281
{
@@ -95,17 +94,10 @@ static DataOffsets()
9594

9695
staticManagedDataOffsets()
9796
{
98-
NameMapping=TypeOffset.GetOffsets();
99-
10097
FieldInfo[]fields=typeof(DataOffsets).GetFields(BindingFlags.Static|BindingFlags.Public);
10198
size=fields.Length*IntPtr.Size;
10299
}
103100

104-
publicstaticintGetSlotOffset(stringname)
105-
{
106-
returnNameMapping[name];
107-
}
108-
109101
privatestaticintBaseOffset(IntPtrtype)
110102
{
111103
Debug.Assert(type!=IntPtr.Zero);
@@ -135,30 +127,15 @@ internal static class OriginalObjectOffsets
135127
{
136128
staticOriginalObjectOffsets()
137129
{
138-
intsize=IntPtr.Size;
139-
varn=0;// Py_TRACE_REFS add two pointers to PyObject_HEAD
140-
#ifPYTHON_WITH_PYDEBUG
141-
_ob_next=0;
142-
_ob_prev=1*size;
143-
n=2;
144-
#endif
145-
ob_refcnt=(n+0)*size;
146-
ob_type=(n+1)*size;
130+
ob_refcnt=Native.ABI.ObjectHeadOffset;
131+
ob_type=ob_refcnt+IntPtr.Size;
132+
size=ob_type+IntPtr.Size;
147133
}
148134

149135
publicstaticintSize{get{returnsize;}}
150136

151-
privatestaticreadonlyintsize=
152-
#ifPYTHON_WITH_PYDEBUG
153-
4*IntPtr.Size;
154-
#else
155-
2*IntPtr.Size;
156-
#endif
157-
158-
#ifPYTHON_WITH_PYDEBUG
159-
publicstaticint_ob_next;
160-
publicstaticint_ob_prev;
161-
#endif
137+
privatestaticreadonlyintsize;
138+
162139
publicstaticintob_refcnt;
163140
publicstaticintob_type;
164141
}
@@ -168,10 +145,6 @@ internal class ObjectOffset
168145
{
169146
staticObjectOffset()
170147
{
171-
#ifPYTHON_WITH_PYDEBUG
172-
_ob_next=OriginalObjectOffsets._ob_next;
173-
_ob_prev=OriginalObjectOffsets._ob_prev;
174-
#endif
175148
ob_refcnt=OriginalObjectOffsets.ob_refcnt;
176149
ob_type=OriginalObjectOffsets.ob_type;
177150

@@ -198,10 +171,6 @@ public static int Size(IntPtr pyType)
198171
returnsize;
199172
}
200173

201-
#ifPYTHON_WITH_PYDEBUG
202-
publicstaticint_ob_next;
203-
publicstaticint_ob_prev;
204-
#endif
205174
publicstaticintob_refcnt;
206175
publicstaticintob_type;
207176
privatestaticreadonlyintsize;
@@ -256,17 +225,12 @@ static BytesOffset()
256225
intsize=IntPtr.Size;
257226
for(inti=0;i<fi.Length;i++)
258227
{
259-
fi[i].SetValue(null,i*size);
228+
fi[i].SetValue(null,i*size+Native.ABI.ObjectHeadOffset);
260229
}
261230
}
262231

263232
/* The *real* layout of a type object when allocated on the heap */
264233
//typedef struct _heaptypeobject {
265-
#ifPYTHON_WITH_PYDEBUG
266-
/* _PyObject_HEAD_EXTRA defines pointers to support a doubly-linked list of all live heap objects. */
267-
publicstaticint_ob_next=0;
268-
publicstaticint_ob_prev=0;
269-
#endif
270234
// PyObject_VAR_HEAD {
271235
// PyObject_HEAD {
272236
publicstaticintob_refcnt=0;

‎src/runtime/native/ABI.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace Python.Runtime.Native
88

99
staticclassABI
1010
{
11+
publicstaticintObjectHeadOffset{get;}=GetRefCountOffset();
12+
1113
internalstaticvoidInitialize(Versionversion,BorrowedReferencepyType)
1214
{
1315
stringoffsetsClassSuffix=string.Format(CultureInfo.InvariantCulture,
@@ -17,20 +19,36 @@ internal static void Initialize(Version version, BorrowedReference pyType)
1719

1820
conststringnativeTypeOffsetClassName="Python.Runtime.NativeTypeOffset";
1921
stringclassName="Python.Runtime.TypeOffset"+offsetsClassSuffix;
22+
TypenativeOffsetsClass=thisAssembly.GetType(nativeTypeOffsetClassName,throwOnError:false);
2023
TypetypeOffsetsClass=
2124
// Try platform native offsets first. It is only present when generated by setup.py
22-
thisAssembly.GetType(nativeTypeOffsetClassName,throwOnError:false)
23-
??thisAssembly.GetType(className,throwOnError:false);
25+
nativeOffsetsClass??thisAssembly.GetType(className,throwOnError:false);
2426
if(typeOffsetsClassisnull)
2527
{
2628
vartypes=thisAssembly.GetTypes().Select(type=>type.Name).Where(name=>name.StartsWith("TypeOffset"));
2729
stringmessage=$"Searching for{className}, found{string.Join(",",types)}.";
2830
thrownewNotSupportedException($"Python ABI v{version} is not supported:{message}");
2931
}
32+
3033
vartypeOffsets=(ITypeOffsets)Activator.CreateInstance(typeOffsetsClass);
31-
TypeOffset.Use(typeOffsets);
34+
TypeOffset.Use(typeOffsets,nativeOffsetsClass==null?ObjectHeadOffset:0);
3235

3336
ManagedDataOffsets.Magic=Marshal.ReadInt32(pyType.DangerousGetAddress(),TypeOffset.tp_basicsize);
3437
}
38+
39+
staticunsafeintGetRefCountOffset()
40+
{
41+
IntPtrtempObject=Runtime.PyList_New(0);
42+
IntPtr*tempPtr=(IntPtr*)tempObject;
43+
intoffset=0;
44+
while(tempPtr[offset]!=(IntPtr)1)
45+
{
46+
offset++;
47+
if(offset>100)
48+
thrownewInvalidProgramException("PyObject_HEAD could not be found withing reasonable distance from the start of PyObject");
49+
}
50+
Runtime.XDecref(tempObject);
51+
returnoffset*IntPtr.Size;
52+
}
3553
}
3654
}

‎src/runtime/native/TypeOffset.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static partial class TypeOffset
7474
internalstaticinttp_str{get;privateset;}
7575
internalstaticinttp_traverse{get;privateset;}
7676

77-
internalstaticvoidUse(ITypeOffsetsoffsets)
77+
internalstaticvoidUse(ITypeOffsetsoffsets,intextraHeadOffset)
7878
{
7979
if(offsetsisnull)thrownewArgumentNullException(nameof(offsets));
8080

@@ -86,9 +86,12 @@ internal static void Use(ITypeOffsets offsets)
8686

8787
varsourceProperty=typeof(ITypeOffsets).GetProperty(offsetProperty.Name);
8888
intvalue=(int)sourceProperty.GetValue(offsets,null);
89+
value+=extraHeadOffset;
8990
offsetProperty.SetValue(obj:null,value:value,index:null);
9091
}
9192

93+
NameMapping=GetOffsets();
94+
9295
ValidateUnusedTypeOffsetProperties(offsetProperties);
9396
ValidateRequiredOffsetsPresent(offsetProperties);
9497
}
@@ -167,5 +170,12 @@ static void ValidateRequiredOffsetsPresent(PropertyInfo[] offsetProperties)
167170
Debug.Assert(missing.Count==0,
168171
"Missing slots: "+string.Join(", ",missing));
169172
}
173+
174+
staticDictionary<string,int>NameMapping;
175+
176+
publicstaticintGetSlotOffset(stringname)
177+
{
178+
returnNameMapping[name];
179+
}
170180
}
171181
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp