-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Move static helpers to managed #108167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move static helpers to managed #108167
Changes from 27 commits
0fbff89
7d6a205
51c69d5
d1fccda
08fe963
12c9de2
2c0cb78
0fb7f4a
0cb8f78
aacdb2a
00b6df4
34ebcaf
f740618
e2498bb
0d03a51
367e95b
ccfafe1
5ff66b4
0586455
0f6290a
8f5448f
0d6edfc
46fc106
a08dc02
8fb5f22
4c92dc1
f9d19fa
2a89bce
47fc1e5
67bc96a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace System.Runtime | ||
| { | ||
| // Use to disable ReadyToRun compilation for a method. | ||
| internal sealed class BypassReadyToRunAttribute : Attribute | ||
| { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -877,8 +877,40 @@ public TypeHandle GetArrayElementTypeHandle() | |
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.InternalCall)] | ||
| public extern MethodTable* GetMethodTableMatchingParentClass(MethodTable* parent); | ||
|
|
||
| /// <summary> | ||
| /// Given a statics pointer in the DynamicStaticsInfo, get the actual statics pointer. | ||
| /// </summary> | ||
| [MethodImpl(MethodImplOptions.InternalCall)] | ||
| public static extern ref byte MaskStaticsPointer(ref byte staticsPtr); | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe ref struct DynamicStaticsInfo | ||
| { | ||
| internal const int ISCLASSINITED = 1; | ||
|
||
| internal IntPtr _pGCStatics; // The ISCLASSINITED bit is set when the class is NOT initialized | ||
| internal IntPtr _pNonGCStatics; // The ISCLASSINITED bit is set when the class is NOT initialized | ||
| internal unsafe MethodTable* _methodTable; | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe ref struct GenericsStaticsInfo | ||
| { | ||
| // Pointer to field descs for statics | ||
| internal IntPtr _pFieldDescs; | ||
| internal DynamicStaticsInfo _dynamicStatics; | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe ref struct ThreadStaticsInfo | ||
| { | ||
| internal int _nonGCTlsIndex; | ||
| internal int _gcTlsIndex; | ||
| internal GenericsStaticsInfo _genericStatics; | ||
| } | ||
|
|
||
|
|
||
| // Subset of src\vm\methodtable.h | ||
| [StructLayout(LayoutKind.Sequential)] | ||
| internal unsafe struct MethodTableAuxiliaryData | ||
|
|
@@ -939,6 +971,18 @@ public RuntimeType? ExposedClassObject | |
| public bool IsClassInited => (Volatile.Read(ref Flags) & enum_flag_Initialized) != 0; | ||
|
|
||
| public bool IsClassInitedAndActive => (Volatile.Read(ref Flags) & (enum_flag_Initialized | enum_flag_EnsuredInstanceActive)) == (enum_flag_Initialized | enum_flag_EnsuredInstanceActive); | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public ref DynamicStaticsInfo GetDynamicStaticsInfo() | ||
| { | ||
| return ref Unsafe.Subtract(ref Unsafe.As<MethodTableAuxiliaryData, DynamicStaticsInfo>(ref this), 1); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public ref ThreadStaticsInfo GetThreadStaticsInfo() | ||
| { | ||
| return ref Unsafe.Subtract(ref Unsafe.As<MethodTableAuxiliaryData, ThreadStaticsInfo>(ref this), 1); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,279 @@ | ||||||||||||
| // Licensed to the .NET Foundation under one or more agreements. | ||||||||||||
| // The .NET Foundation licenses this file to you under the MIT license. | ||||||||||||
|
|
||||||||||||
| using System.Diagnostics; | ||||||||||||
| using System.Runtime.InteropServices; | ||||||||||||
|
|
||||||||||||
| namespace System.Runtime.CompilerServices | ||||||||||||
| { | ||||||||||||
| [StackTraceHidden] | ||||||||||||
| [DebuggerStepThrough] | ||||||||||||
| internal static unsafe partial class StaticsHelpers | ||||||||||||
| { | ||||||||||||
| [LibraryImport(RuntimeHelpers.QCall)] | ||||||||||||
| private static partial void GetThreadStaticsByIndex(ByteRefOnStack result, int index, [MarshalAs(UnmanagedType.Bool)] bool gcStatics); | ||||||||||||
|
|
||||||||||||
| [LibraryImport(RuntimeHelpers.QCall)] | ||||||||||||
| private static partial void GetThreadStaticsByMethodTable(ByteRefOnStack result, MethodTable* pMT, [MarshalAs(UnmanagedType.Bool)] bool gcStatics); | ||||||||||||
|
|
||||||||||||
| [MethodImpl(MethodImplOptions.InternalCall)] | ||||||||||||
| [Intrinsic] | ||||||||||||
| private static extern ref byte VolatileReadAsByref(ref IntPtr address); | ||||||||||||
|
||||||||||||
| [MethodImpl(MethodImplOptions.InternalCall)] | |
| [Intrinsic] | |
| private static extern ref byte VolatileReadAsByref(ref IntPtr address); | |
| [Intrinsic] | |
| private static extern ref byte VolatileReadAsByref(ref IntPtr address) => ref VolatileReadAsByref(ref address); |
Make it must-expand intrinsic and delete the FCall?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have RawData and GetRawData in RuntimeHelpers.CoreCLR.cs that this should be able to use instead of defining a local clone.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return ref Unsafe.Add(ref Unsafe.As<RawData>(obj)._data, -sizeof(MethodTable*)); | |
| return ref Unsafe.Subtract(ref Unsafe.As<RawData>(obj)._data, sizeof(MethodTable*)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be implemented like this in C# to avoid FCall? It is not on any perf critical path, so a few extra instructions from pinning are not a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I had it on the critical path initially, and planned to make it an intrinsic to make it just work with it written as an fcall as a correct stopgap... then I realized I didn't need it on the critical path, and didn't move on from the FCALL.