1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-08 03:27:04 +09:00

Use function pointers in crossgen2 (#42655)

Co-authored-by: Adeel Mujahid <adeelbm@outlook.com>
This commit is contained in:
Jan Kotas 2020-09-24 02:38:23 -07:00 committed by GitHub
parent 11350c5902
commit 7c3d2384f3
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 706 additions and 1313 deletions

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,6 @@ namespace Internal.JitInterface
private IntPtr _jit;
private IntPtr _unmanagedCallbacks; // array of pointers to JIT-EE interface callbacks
private Object _keepAlive; // Keeps delegates for the callbacks alive
private ExceptionDispatchInfo _lastException;
@ -122,7 +121,7 @@ namespace Internal.JitInterface
throw new IOException("Failed to initialize JIT");
}
_unmanagedCallbacks = GetUnmanagedCallbacks(out _keepAlive);
_unmanagedCallbacks = GetUnmanagedCallbacks();
}
public TextWriter Log
@ -1043,7 +1042,7 @@ namespace Internal.JitInterface
private bool satisfiesMethodConstraints(CORINFO_CLASS_STRUCT_* parent, CORINFO_METHOD_STRUCT_* method)
{ throw new NotImplementedException("satisfiesMethodConstraints"); }
private bool isCompatibleDelegate(CORINFO_CLASS_STRUCT_* objCls, CORINFO_CLASS_STRUCT_* methodParentCls, CORINFO_METHOD_STRUCT_* method, CORINFO_CLASS_STRUCT_* delegateCls, ref bool pfIsOpenDelegate)
private bool isCompatibleDelegate(CORINFO_CLASS_STRUCT_* objCls, CORINFO_CLASS_STRUCT_* methodParentCls, CORINFO_METHOD_STRUCT_* method, CORINFO_CLASS_STRUCT_* delegateCls, BOOL* pfIsOpenDelegate)
{ throw new NotImplementedException("isCompatibleDelegate"); }
private void setPatchpointInfo(PatchpointInfo* patchpointInfo)
{ throw new NotImplementedException("setPatchpointInfo"); }
@ -1529,7 +1528,7 @@ namespace Internal.JitInterface
Marshal.FreeCoTaskMem((IntPtr)obj);
}
private byte* getClassModuleIdForStatics(CORINFO_CLASS_STRUCT_* cls, CORINFO_MODULE_STRUCT_** pModule, void** ppIndirection)
private UIntPtr getClassModuleIdForStatics(CORINFO_CLASS_STRUCT_* cls, CORINFO_MODULE_STRUCT_** pModule, void** ppIndirection)
{ throw new NotImplementedException("getClassModuleIdForStatics"); }
private uint getClassSize(CORINFO_CLASS_STRUCT_* cls)
@ -2525,7 +2524,7 @@ namespace Internal.JitInterface
return (uint)HandleToObject(ftn).GetHashCode();
}
private byte* findNameOfToken(CORINFO_MODULE_STRUCT_* moduleHandle, mdToken token, byte* szFQName, UIntPtr FQNameCapacity)
private UIntPtr findNameOfToken(CORINFO_MODULE_STRUCT_* moduleHandle, mdToken token, byte* szFQName, UIntPtr FQNameCapacity)
{ throw new NotImplementedException("findNameOfToken"); }
private bool getSystemVAmd64PassStructInRegisterDescriptor(CORINFO_CLASS_STRUCT_* structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr)
@ -2615,7 +2614,7 @@ namespace Internal.JitInterface
ppIndirection = null;
return null;
}
private void GetProfilingHandle(ref bool pbHookFunction, ref void* pProfilerHandle, ref bool pbIndirectedHandles)
private void GetProfilingHandle(BOOL* pbHookFunction, ref void* pProfilerHandle, BOOL* pbIndirectedHandles)
{ throw new NotImplementedException("GetProfilingHandle"); }
/// <summary>

View file

@ -8,6 +8,12 @@ using Internal.TypeSystem;
namespace Internal.JitInterface
{
public enum BOOL : int
{
FALSE = 0,
TRUE = 1,
}
public static class CORINFO
{
// CORINFO_MAXINDIRECTIONS is the maximum number of
@ -20,40 +26,14 @@ namespace Internal.JitInterface
public struct CORINFO_METHOD_STRUCT_
{
internal static unsafe CORINFO_METHOD_STRUCT_* Construct(int i)
{
return (CORINFO_METHOD_STRUCT_*)((i + 1) << 4);
}
internal static unsafe int GetValue(CORINFO_METHOD_STRUCT_* val)
{
return ((int)val - 1) >> 4;
}
}
public struct CORINFO_FIELD_STRUCT_
{
internal static unsafe CORINFO_FIELD_STRUCT_* Construct(int i)
{
return (CORINFO_FIELD_STRUCT_*)((i + 1) << 4);
}
internal static unsafe int GetValue(CORINFO_FIELD_STRUCT_* val)
{
return ((int)val - 1) >> 4;
}
}
public struct CORINFO_CLASS_STRUCT_
{
internal static unsafe CORINFO_CLASS_STRUCT_* Construct(int i)
{
return (CORINFO_CLASS_STRUCT_*)((i + 1) << 4);
}
internal static unsafe int GetValue(CORINFO_CLASS_STRUCT_* val)
{
return ((int)val - 1) >> 4;
}
}
public struct CORINFO_ARG_LIST_STRUCT_
@ -62,14 +42,6 @@ namespace Internal.JitInterface
public struct CORINFO_MODULE_STRUCT_
{
internal static unsafe CORINFO_MODULE_STRUCT_* Construct(int i)
{
return (CORINFO_MODULE_STRUCT_*)((i + 1) << 4);
}
internal static unsafe int GetValue(CORINFO_MODULE_STRUCT_* val)
{
return ((int)val - 1) >> 4;
}
}
public struct CORINFO_ASSEMBLY_STRUCT_

View file

@ -27,7 +27,6 @@ namespace Internal.JitInterface
private CorJitFlag[] _jitFlags;
private Dictionary<string, string> _config = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private object _keepAlive; // Keeps callback delegates alive
public static void Initialize(
TargetDetails target,
@ -151,43 +150,34 @@ namespace Internal.JitInterface
#region Unmanaged instance
private unsafe IntPtr CreateUnmanagedInstance()
private static unsafe IntPtr CreateUnmanagedInstance()
{
// TODO: this potentially leaks memory, but since we only expect to have one per compilation,
// This potentially leaks memory, but since we only expect to have one per compilation,
// it shouldn't matter...
const int numCallbacks = 2;
IntPtr* callbacks = (IntPtr*)Marshal.AllocCoTaskMem(sizeof(IntPtr) * numCallbacks);
object[] delegates = new object[numCallbacks];
void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * numCallbacks);
var d0 = new __getIntConfigValue(getIntConfigValue);
callbacks[0] = Marshal.GetFunctionPointerForDelegate(d0);
delegates[0] = d0;
callbacks[0] = (delegate* <IntPtr, char*, int, int>)&getIntConfigValue;
callbacks[1] = (delegate* <IntPtr, char*, char*, int, int>)&getStringConfigValue;
var d1 = new __getStringConfigValue(getStringConfigValue);
callbacks[1] = Marshal.GetFunctionPointerForDelegate(d1);
delegates[1] = d1;
_keepAlive = delegates;
IntPtr instance = Marshal.AllocCoTaskMem(sizeof(IntPtr));
*(IntPtr**)instance = callbacks;
*(IntPtr*)instance = (IntPtr)callbacks;
return instance;
}
[UnmanagedFunctionPointer(default(CallingConvention))]
private unsafe delegate int __getIntConfigValue(IntPtr thisHandle, [MarshalAs(UnmanagedType.LPWStr)] string name, int defaultValue);
private unsafe int getIntConfigValue(IntPtr thisHandle, string name, int defaultValue)
[UnmanagedCallersOnly]
private static unsafe int getIntConfigValue(IntPtr thisHandle, char* name, int defaultValue)
{
return GetIntConfigValue(name, defaultValue);
return s_instance.GetIntConfigValue(new string(name), defaultValue);
}
[UnmanagedFunctionPointer(default(CallingConvention))]
private unsafe delegate int __getStringConfigValue(IntPtr thisHandle, [MarshalAs(UnmanagedType.LPWStr)] string name, char* retBuffer, int retBufferLength);
private unsafe int getStringConfigValue(IntPtr thisHandle, string name, char* retBuffer, int retBufferLength)
[UnmanagedCallersOnly]
private static unsafe int getStringConfigValue(IntPtr thisHandle, char* name, char* retBuffer, int retBufferLength)
{
string result = GetStringConfigValue(name);
string result = s_instance.GetStringConfigValue(new string(name));
for (int i = 0; i < Math.Min(retBufferLength, result.Length); i++)
retBuffer[i] = result[i];

View file

@ -66,6 +66,28 @@ namespace Thunkerator
public readonly string ThunkTypeName;
public readonly string NativeTypeName;
public readonly string ManagedTypeName;
public bool IsByRef => ManagedTypeName.Contains("ref ");
public bool IsBoolean => ManagedTypeName == "[MarshalAs(UnmanagedType.I1)]bool";
public bool IsBOOL => ManagedTypeName == "[MarshalAs(UnmanagedType.Bool)]bool";
public string UnmanagedTypeName
{
get
{
if (IsBoolean)
return "byte";
if (IsBOOL)
return "int";
if (IsByRef)
return ManagedTypeName.Replace("ref ", "") + "*";
// No special marshaling rules
return ManagedTypeName;
}
}
}
class Parameter
@ -92,12 +114,6 @@ namespace Thunkerator
line = line.Replace("[ManualNativeWrapper]", string.Empty);
}
if (line.Contains("[ReturnAsParm]"))
{
ReturnAsParm = true;
line = line.Replace("[ReturnAsParm]", string.Empty);
}
int indexOfOpenParen = line.IndexOf('(');
int indexOfCloseParen = line.IndexOf(')');
string returnTypeAndFunctionName = line.Substring(0, indexOfOpenParen).Canonicalize();
@ -136,7 +152,6 @@ namespace Thunkerator
public readonly TypeReplacement ReturnType;
public readonly Parameter[] Parameters;
public readonly bool ManualNativeWrapper = false;
public readonly bool ReturnAsParm = false;
}
class Program
@ -249,65 +264,13 @@ namespace Internal.JitInterface
{
");
#if false
foreach (FunctionDecl decl in functionData)
{
string returnType = decl.ReturnType.ManagedTypeName;
tr.Write(" " + returnType + " " + decl.FunctionName + "(");
tr.Write("IntPtr thisHandle");
tr.WriteLine(" [UnmanagedCallersOnly]");
tr.Write($" static {decl.ReturnType.UnmanagedTypeName} _{decl.FunctionName}(IntPtr thisHandle, IntPtr* ppException");
foreach (Parameter param in decl.Parameters)
{
tr.Write(", ");
tr.Write(param.Type.ManagedTypeName + " " + param.Name);
}
tr.WriteLine(")");
tr.WriteLine(" { throw new NotImplementedException(); }");
}
tr.WriteLine();
#endif
foreach (FunctionDecl decl in functionData)
{
tr.WriteLine(" [UnmanagedFunctionPointerAttribute(default(CallingConvention))]");
string returnType = decl.ReturnAsParm ? "void" : decl.ReturnType.ManagedTypeName;
int marshalAs = returnType.LastIndexOf(']');
string returnTypeWithDelegate = returnType.Insert((marshalAs != -1) ? (marshalAs + 1) : 0, "delegate ");
tr.Write(" " + returnTypeWithDelegate + " " + "__" + decl.FunctionName + "(");
tr.Write("IntPtr _this");
tr.Write(", IntPtr* ppException");
if (decl.ReturnAsParm)
{
tr.Write(", out " + decl.ReturnType.ManagedTypeName + " _return");
}
foreach (Parameter param in decl.Parameters)
{
tr.Write(", ");
tr.Write(param.Type.ManagedTypeName + " " + param.Name);
}
tr.WriteLine(");");
}
tr.WriteLine();
foreach (FunctionDecl decl in functionData)
{
string returnType = decl.ReturnAsParm ? "void" : decl.ReturnType.ManagedTypeName;
int marshalAs = returnType.LastIndexOf(']');
string returnTypeWithStatic = returnType.Insert((marshalAs != -1) ? (marshalAs + 1) : 0, "static ");
tr.Write(" " + returnTypeWithStatic + " " + "_" + decl.FunctionName + "(");
tr.Write("IntPtr thisHandle");
tr.Write(", IntPtr* ppException");
if (decl.ReturnAsParm)
{
tr.Write(", out " + decl.ReturnType.ManagedTypeName + " _return");
}
foreach (Parameter param in decl.Parameters)
{
tr.Write(", ");
tr.Write(param.Type.ManagedTypeName + " " + param.Name);
tr.Write($", {param.Type.UnmanagedTypeName} {param.Name}");
}
tr.Write(@")
{
@ -315,14 +278,9 @@ namespace Internal.JitInterface
try
{
");
bool isVoid = decl.ReturnAsParm || decl.ReturnType.ManagedTypeName == "void";
tr.Write(" " + (isVoid ? "" : "return ") + "_this." + decl.FunctionName + "(");
bool isVoid = decl.ReturnType.ManagedTypeName == "void";
tr.Write($" {(isVoid ? "" : "return ")}_this.{decl.FunctionName}(");
bool isFirst = true;
if (decl.ReturnAsParm)
{
tr.Write("out _return");
isFirst = false;
}
foreach (Parameter param in decl.Parameters)
{
if (isFirst)
@ -334,13 +292,22 @@ namespace Internal.JitInterface
tr.Write(", ");
}
if (param.Type.ManagedTypeName.Contains("ref "))
if (param.Type.IsByRef)
{
tr.Write("ref ");
tr.Write("ref *");
}
tr.Write(param.Name);
if (param.Type.IsBoolean || param.Type.IsBOOL)
{
tr.Write(" != 0");
}
}
tr.Write(");");
tr.Write(")");
if (decl.ReturnType.IsBOOL || decl.ReturnType.IsBoolean)
{
tr.Write(" ? 1 : 0");
}
tr.Write(";");
tr.Write(@"
}
catch (Exception ex)
@ -349,12 +316,7 @@ namespace Internal.JitInterface
");
if (!isVoid)
{
string retunTypeWithoutMarshalAs = marshalAs == -1 ? returnType : returnType.Substring(marshalAs + 1);
tr.WriteLine(" return default(" + retunTypeWithoutMarshalAs + ");");
}
else if (decl.ReturnAsParm)
{
tr.WriteLine(" _return = default(" + decl.ReturnType.ManagedTypeName + ");");
tr.WriteLine(" return default;");
}
tr.WriteLine(@" }");
tr.WriteLine(" }");
@ -363,23 +325,24 @@ namespace Internal.JitInterface
int total = functionData.Count();
tr.WriteLine(@"
static IntPtr GetUnmanagedCallbacks(out Object keepAlive)
static IntPtr GetUnmanagedCallbacks()
{
IntPtr * callbacks = (IntPtr *)Marshal.AllocCoTaskMem(sizeof(IntPtr) * " + total + @");
Object[] delegates = new Object[" + total + @"];
void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * " + total + @");
");
int index = 0;
foreach (FunctionDecl decl in functionData)
{
tr.WriteLine(" var d" + index + " = new " + "__" + decl.FunctionName + "(" + "_" + decl.FunctionName + ");");
tr.WriteLine(" callbacks[" + index + "] = Marshal.GetFunctionPointerForDelegate(d" + index + ");");
tr.WriteLine(" delegates[" + index + "] = d" + index + ";");
tr.Write($" callbacks[{index}] = (delegate* <IntPtr, IntPtr*");
foreach (Parameter param in decl.Parameters)
{
tr.Write($", {param.Type.UnmanagedTypeName}");
}
tr.WriteLine($", {decl.ReturnType.UnmanagedTypeName}>)&_{decl.FunctionName};");
index++;
}
tr.WriteLine(@"
keepAlive = delegates;
return (IntPtr)callbacks;
}
}
@ -395,26 +358,16 @@ namespace Internal.JitInterface
// DO NOT EDIT THIS FILE! It IS AUTOGENERATED
#include ""corinfoexception.h""
struct CORINFO_LOOKUP_KIND;
struct JitInterfaceCallbacks
{
");
foreach (FunctionDecl decl in functionData)
{
string returnType = decl.ReturnAsParm ? "void" : decl.ReturnType.NativeTypeName;
tw.Write(" " + returnType + " (* " + decl.FunctionName + ")(");
tw.Write("void * thisHandle");
tw.Write(", CorInfoException** ppException");
if (decl.ReturnAsParm)
{
tw.Write(", " + decl.ReturnType.NativeTypeName + "* _return");
}
tw.Write($" {decl.ReturnType.NativeTypeName} (* {decl.FunctionName})(void * thisHandle, CorInfoException** ppException");
foreach (Parameter param in decl.Parameters)
{
tw.Write(", ");
tw.Write(param.Type.NativeTypeName + " " + param.Name);
tw.Write($", {param.Type.NativeTypeName} {param.Name}");
}
tw.WriteLine(");");
}
@ -464,12 +417,12 @@ public:
");
if (decl.ReturnType.NativeTypeName != "void")
{
tw.Write(decl.ReturnType.NativeTypeName + " _ret = ");
tw.Write($"{decl.ReturnType.NativeTypeName} _ret = ");
}
tw.Write("_callbacks->" + decl.FunctionName + "(_thisHandle, &pException");
tw.Write($"_callbacks->{decl.FunctionName}(_thisHandle, &pException");
foreach (Parameter param in decl.Parameters)
{
tw.Write(", " + param.Name);
tw.Write($", {param.Name}");
}
tw.Write(@");
if (pException != nullptr)

View file

@ -59,8 +59,8 @@ BYTE*,byte*,unsigned char*
GSCookie*,IntPtr*,void*
GSCookie**,IntPtr**,void**
BOOL*,[MarshalAs(UnmanagedType.Bool)] ref bool,int*
bool*,[MarshalAs(UnmanagedType.U1)] ref bool
BOOL*,BOOL*,int*
bool*,ref bool,bool*
BoolStar,byte*,bool*
UINT32*,ref uint,unsigned int*
ULONG*,ref uint,unsigned long*
@ -155,12 +155,6 @@ ICorDebugInfo::BoundaryTypes*,BoundaryTypes*,void*
struct _EXCEPTION_POINTERS*,_EXCEPTION_POINTERS*,void*
RETURNTYPES
BOOL,[return: MarshalAs(UnmanagedType.Bool)]bool,int
bool,[return: MarshalAs(UnmanagedType.I1)]bool
; NOTE in managed SIZE_T is an enum that is 64bits in size, and returning one of those causing mcg to do the wrong thing.
size_t,byte*,size_t
FUNCTIONS
DWORD getMethodAttribs( CORINFO_METHOD_HANDLE ftn );
void setMethodAttribs( CORINFO_METHOD_HANDLE ftn, CorInfoMethodRuntimeFlags attribs );

View file

@ -4,8 +4,6 @@
// DO NOT EDIT THIS FILE! It IS AUTOGENERATED
#include "corinfoexception.h"
struct CORINFO_LOOKUP_KIND;
struct JitInterfaceCallbacks
{
unsigned int (* getMethodAttribs)(void * thisHandle, CorInfoException** ppException, void* ftn);