Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2018-06-24 03:19:20 +0300
committerGitHub <noreply@github.com>2018-06-24 03:19:20 +0300
commitc9326538e74bcb8f73760cceb84b8abcddc9812f (patch)
tree97b300513b2eee7fc36691f657c482653acf4351 /src
parent6c2368b53687609f2fd8ce4389596f2a0d283e3f (diff)
Plumbing to generate calli PInvoke stubs (#6002)
Contributes to #5587
Diffstat (limited to 'src')
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs28
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs20
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs89
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.Mangling.cs3
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs8
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/PInvokeTargetNativeMethod.cs9
-rw-r--r--src/Common/src/TypeSystem/Interop/InteropStateManager.cs44
-rw-r--r--src/Common/src/TypeSystem/Mangling/IPrefixMangledSignature.cs23
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs33
-rw-r--r--src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs5
-rw-r--r--src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj18
-rw-r--r--src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs9
-rw-r--r--src/System.Private.Jit/src/System.Private.Jit.csproj1
13 files changed, 281 insertions, 9 deletions
diff --git a/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs b/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs
new file mode 100644
index 000000000..5bb37b622
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Mangling.cs
@@ -0,0 +1,28 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using Internal.TypeSystem;
+
+namespace Internal.IL.Stubs
+{
+ public partial class CalliMarshallingMethodThunk : IPrefixMangledSignature
+ {
+ MethodSignature IPrefixMangledSignature.BaseSignature
+ {
+ get
+ {
+ return _targetSignature;
+ }
+ }
+
+ string IPrefixMangledSignature.Prefix
+ {
+ get
+ {
+ return "Calli";
+ }
+ }
+ }
+}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs b/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs
new file mode 100644
index 000000000..2ac126d11
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.Sorting.cs
@@ -0,0 +1,20 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.TypeSystem;
+
+namespace Internal.IL.Stubs
+{
+ // Functionality related to deterministic ordering of methods
+ partial class CalliMarshallingMethodThunk
+ {
+ protected internal override int ClassCode => 1594107963;
+
+ protected internal override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
+ {
+ var otherMethod = (CalliMarshallingMethodThunk)other;
+ return comparer.Compare(_targetSignature, otherMethod._targetSignature);
+ }
+ }
+}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs b/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs
new file mode 100644
index 000000000..a70ceb5fe
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/Stubs/CalliMarshallingMethodThunk.cs
@@ -0,0 +1,89 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using Internal.TypeSystem;
+using Internal.TypeSystem.Interop;
+using Debug = System.Diagnostics.Debug;
+using Internal.TypeSystem.Ecma;
+
+namespace Internal.IL.Stubs
+{
+ /// <summary>
+ /// Thunk to marshal calli PInvoke parameters and invoke the appropriate function pointer
+ /// </summary>
+ public partial class CalliMarshallingMethodThunk : ILStubMethod
+ {
+ private readonly MethodSignature _targetSignature;
+ private readonly InteropStateManager _interopStateManager;
+ private readonly TypeDesc _owningType;
+
+ private MethodSignature _signature;
+
+ public CalliMarshallingMethodThunk(MethodSignature targetSignature, TypeDesc owningType,
+ InteropStateManager interopStateManager)
+ {
+ _targetSignature = targetSignature;
+ _owningType = owningType;
+ _interopStateManager = interopStateManager;
+ }
+
+ public MethodSignature TargetSignature
+ {
+ get
+ {
+ return _targetSignature;
+ }
+ }
+
+ public override TypeSystemContext Context
+ {
+ get
+ {
+ return _owningType.Context;
+ }
+ }
+
+ public override TypeDesc OwningType
+ {
+ get
+ {
+ return _owningType;
+ }
+ }
+
+ public override MethodSignature Signature
+ {
+ get
+ {
+ if (_signature == null)
+ {
+ // Prepend fnptr argument to the signature
+ TypeDesc[] parameterTypes = new TypeDesc[_targetSignature.Length + 1];
+
+ parameterTypes[0] = Context.GetWellKnownType(WellKnownType.IntPtr);
+ for (int i = 0; i < _targetSignature.Length; i++)
+ parameterTypes[i + 1] = _targetSignature[i];
+
+ _signature = new MethodSignature(MethodSignatureFlags.Static, 0, _targetSignature.ReturnType, parameterTypes);
+ }
+ return _signature;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ return "CalliMarshallingMethodThunk";
+ }
+ }
+
+ public override MethodIL EmitIL()
+ {
+ // TODO
+ throw null;
+ }
+ }
+}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.Mangling.cs b/src/Common/src/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.Mangling.cs
index 7813d0318..bd140239c 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.Mangling.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/DelegateMarshallingMethodThunk.Mangling.cs
@@ -7,9 +7,6 @@ using Internal.TypeSystem;
namespace Internal.IL.Stubs
{
- /// <summary>
- /// contains functionality related to name mangling
- /// </summary>
public partial class DelegateMarshallingMethodThunk : IPrefixMangledType
{
TypeDesc IPrefixMangledType.BaseType
diff --git a/src/Common/src/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs b/src/Common/src/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs
index 650b244c1..dd4f182de 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs
@@ -109,5 +109,13 @@ namespace Internal.IL.Stubs
{
return false;
}
+
+ public override string Name
+ {
+ get
+ {
+ return _targetMethod.Name;
+ }
+ }
}
}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/PInvokeTargetNativeMethod.cs b/src/Common/src/TypeSystem/IL/Stubs/PInvokeTargetNativeMethod.cs
index 2a2cae4e8..5aab575a2 100644
--- a/src/Common/src/TypeSystem/IL/Stubs/PInvokeTargetNativeMethod.cs
+++ b/src/Common/src/TypeSystem/IL/Stubs/PInvokeTargetNativeMethod.cs
@@ -72,6 +72,15 @@ namespace Internal.IL.Stubs
}
}
+ public override bool IsNoInlining
+ {
+ get
+ {
+ // This method does not have real IL body. NoInlining stops the JIT asking for it.
+ return true;
+ }
+ }
+
public override PInvokeMetadata GetPInvokeMethodMetadata()
{
return _declMethod.GetPInvokeMethodMetadata();
diff --git a/src/Common/src/TypeSystem/Interop/InteropStateManager.cs b/src/Common/src/TypeSystem/Interop/InteropStateManager.cs
index c28ca119d..3e71c1382 100644
--- a/src/Common/src/TypeSystem/Interop/InteropStateManager.cs
+++ b/src/Common/src/TypeSystem/Interop/InteropStateManager.cs
@@ -22,6 +22,7 @@ namespace Internal.TypeSystem
private readonly PInvokeDelegateWrapperHashtable _pInvokeDelegateWrapperHashtable;
private readonly InlineArrayHashTable _inlineArrayHashtable;
private readonly PInvokeLazyFixupFieldHashtable _pInvokeLazyFixupFieldHashtable;
+ private readonly PInvokeCalliHashtable _pInvokeCalliHashtable;
public InteropStateManager(ModuleDesc generatedAssembly)
{
@@ -33,6 +34,7 @@ namespace Internal.TypeSystem
_pInvokeDelegateWrapperHashtable = new PInvokeDelegateWrapperHashtable(this, _generatedAssembly);
_inlineArrayHashtable = new InlineArrayHashTable(this, _generatedAssembly);
_pInvokeLazyFixupFieldHashtable = new PInvokeLazyFixupFieldHashtable(_generatedAssembly.GetGlobalModuleType());
+ _pInvokeCalliHashtable = new PInvokeCalliHashtable(this, _generatedAssembly.GetGlobalModuleType());
}
//
// Delegate Marshalling Stubs
@@ -185,6 +187,11 @@ namespace Internal.TypeSystem
return _pInvokeLazyFixupFieldHashtable.GetOrCreateValue(method);
}
+ public MethodDesc GetPInvokeCalliStub(MethodSignature signature)
+ {
+ return _pInvokeCalliHashtable.GetOrCreateValue(signature);
+ }
+
private class NativeStructTypeHashtable : LockFreeReaderHashtable<MetadataType, NativeStructType>
{
protected override int GetKeyHashCode(MetadataType key)
@@ -471,5 +478,42 @@ namespace Internal.TypeSystem
_owningType = owningType;
}
}
+
+ private class PInvokeCalliHashtable : LockFreeReaderHashtable<MethodSignature, CalliMarshallingMethodThunk>
+ {
+ private readonly InteropStateManager _interopStateManager;
+ private readonly TypeDesc _owningType;
+
+ protected override int GetKeyHashCode(MethodSignature key)
+ {
+ return key.GetHashCode();
+ }
+
+ protected override int GetValueHashCode(CalliMarshallingMethodThunk value)
+ {
+ return value.TargetSignature.GetHashCode();
+ }
+
+ protected override bool CompareKeyToValue(MethodSignature key, CalliMarshallingMethodThunk value)
+ {
+ return key.Equals(value.TargetSignature);
+ }
+
+ protected override bool CompareValueToValue(CalliMarshallingMethodThunk value1, CalliMarshallingMethodThunk value2)
+ {
+ return value1.TargetSignature.Equals(value2.TargetSignature);
+ }
+
+ protected override CalliMarshallingMethodThunk CreateValueFromKey(MethodSignature key)
+ {
+ return new CalliMarshallingMethodThunk(key, _owningType, _interopStateManager);
+ }
+
+ public PInvokeCalliHashtable(InteropStateManager interopStateManager, TypeDesc owningType)
+ {
+ _interopStateManager = interopStateManager;
+ _owningType = owningType;
+ }
+ }
}
}
diff --git a/src/Common/src/TypeSystem/Mangling/IPrefixMangledSignature.cs b/src/Common/src/TypeSystem/Mangling/IPrefixMangledSignature.cs
new file mode 100644
index 000000000..3dabbc53a
--- /dev/null
+++ b/src/Common/src/TypeSystem/Mangling/IPrefixMangledSignature.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Internal.TypeSystem
+{
+ /// <summary>
+ /// When implemented by a <see cref="MethodDesc"/>, instructs a name mangler to use the same mangled name
+ /// as another entity while prepending a specific prefix to that mangled name.
+ /// </summary>
+ public interface IPrefixMangledSignature
+ {
+ /// <summary>
+ /// Signature whose mangled name to use.
+ /// </summary>
+ MethodSignature BaseSignature { get; }
+
+ /// <summary>
+ /// Prefix to apply when mangling.
+ /// </summary>
+ string Prefix { get; }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs b/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs
index 5c292f87f..8c5636c21 100644
--- a/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/CoreRTNameMangler.cs
@@ -410,6 +410,35 @@ namespace ILCompiler
return sb.ToUtf8String();
}
+ private Utf8String GetPrefixMangledSignatureName(IPrefixMangledSignature prefixMangledSignature)
+ {
+ Utf8StringBuilder sb = new Utf8StringBuilder();
+ sb.Append(EnterNameScopeSequence).Append(prefixMangledSignature.Prefix).Append(ExitNameScopeSequence);
+
+ var signature = prefixMangledSignature.BaseSignature;
+ sb.Append(signature.Flags.ToStringInvariant());
+
+ sb.Append(EnterNameScopeSequence);
+
+ string sigRetTypeName = GetMangledTypeName(signature.ReturnType);
+ if (_mangleForCplusPlus)
+ sigRetTypeName = sigRetTypeName.Replace("::", "_");
+ sb.Append(sigRetTypeName);
+
+ for (int i = 0; i < signature.Length; i++)
+ {
+ sb.Append("__");
+ string sigArgName = GetMangledTypeName(signature[i]);
+ if (_mangleForCplusPlus)
+ sigArgName = sigArgName.Replace("::", "_");
+ sb.Append(sigArgName);
+ }
+
+ sb.Append(ExitNameScopeSequence);
+
+ return sb.ToUtf8String();
+ }
+
private Utf8String GetPrefixMangledMethodName(IPrefixMangledMethod prefixMangledMetod)
{
Utf8StringBuilder sb = new Utf8StringBuilder();
@@ -497,6 +526,10 @@ namespace ILCompiler
{
utf8MangledName = GetPrefixMangledTypeName((IPrefixMangledType)method);
}
+ else if (method is IPrefixMangledSignature)
+ {
+ utf8MangledName = GetPrefixMangledSignatureName((IPrefixMangledSignature)method);
+ }
else
{
// Assume that Name is unique for all other methods
diff --git a/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs b/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs
index 4aec04036..7ae483dbc 100644
--- a/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs
+++ b/src/ILCompiler.Compiler/src/IL/Stubs/PInvokeILProvider.cs
@@ -29,5 +29,10 @@ namespace Internal.IL
{
return PInvokeILEmitter.EmitIL(method, _pInvokeILEmitterConfiguration, _interopStateManager);
}
+
+ public MethodDesc GetCalliStub(MethodSignature signature)
+ {
+ return _interopStateManager.GetPInvokeCalliStub(signature);
+ }
}
}
diff --git a/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj b/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj
index aab6301a4..ec7b134e6 100644
--- a/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj
+++ b/src/ILCompiler.TypeSystem/src/ILCompiler.TypeSystem.csproj
@@ -358,9 +358,6 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\DelegateInfo.cs">
<Link>IL\DelegateInfo.cs</Link>
</Compile>
- <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateMarshallingMethodThunk.Sorting.cs">
- <Link>IL\Stubs\DelegateMarshallingMethodThunk.Sorting.cs</Link>
- </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateThunks.Sorting.cs">
<Link>IL\Stubs\DelegateThunks.Sorting.cs</Link>
</Compile>
@@ -475,12 +472,24 @@
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DebuggerSteppingHelpers.cs">
<Link>IL\Stubs\DebuggerSteppingHelpers.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\CalliMarshallingMethodThunk.cs">
+ <Link>IL\Stubs\CalliMarshallingMethodThunk.cs</Link>
+ </Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\CalliMarshallingMethodThunk.Mangling.cs">
+ <Link>IL\Stubs\CalliMarshallingMethodThunk.Mangling.cs</Link>
+ </Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\CalliMarshallingMethodThunk.Sorting.cs">
+ <Link>IL\Stubs\CalliMarshallingMethodThunk.Sorting.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateMarshallingMethodThunk.cs">
<Link>IL\Stubs\DelegateMarshallingMethodThunk.cs</Link>
</Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateMarshallingMethodThunk.Mangling.cs">
<Link>IL\Stubs\DelegateMarshallingMethodThunk.Mangling.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\DelegateMarshallingMethodThunk.Sorting.cs">
+ <Link>IL\Stubs\DelegateMarshallingMethodThunk.Sorting.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\TypeSystem\IL\Stubs\ForwardDelegateCreationThunk.cs">
<Link>IL\Stubs\ForwardDelegateCreationThunk.cs</Link>
</Compile>
@@ -562,6 +571,9 @@
<Compile Include="..\..\Common\src\TypeSystem\Mangling\IPrefixMangledType.cs">
<Link>TypeSystem\Mangling\IPrefixMangledType.cs</Link>
</Compile>
+ <Compile Include="..\..\Common\src\TypeSystem\Mangling\IPrefixMangledSignature.cs">
+ <Link>TypeSystem\Mangling\IPrefixMangledSignature.cs</Link>
+ </Compile>
<Compile Include="..\..\Common\src\System\Collections\Generic\ArrayBuilder.cs">
<Link>Utilities\ArrayBuilder.cs</Link>
</Compile>
diff --git a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs
index e628978b9..2c5f06f72 100644
--- a/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs
+++ b/src/System.Private.Jit/src/Internal/Runtime/JitSupport/JitCompilation.cs
@@ -21,7 +21,8 @@ namespace ILCompiler
{
_typeSystemContext = context;
_typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(context.GetWellKnownType(WellKnownType.Object));
- _methodILCache = new ILProvider(new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyResolution: true), null));
+ _pInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyResolution: true), null);
+ _methodILCache = new ILProvider(_pInvokeILProvider);
_nodeFactory = new NodeFactory(context);
_devirtualizationManager = new DevirtualizationManager();
}
@@ -31,9 +32,11 @@ namespace ILCompiler
protected readonly Logger _logger = Logger.Null;
private readonly TypeGetTypeMethodThunkCache _typeGetTypeMethodThunks;
private ILProvider _methodILCache;
+ private PInvokeILProvider _pInvokeILProvider;
private readonly DevirtualizationManager _devirtualizationManager;
internal Logger Logger => _logger;
+ internal PInvokeILProvider PInvokeILProvider => _pInvokeILProvider;
public TypeSystemContext TypeSystemContext { get { return _typeSystemContext; } }
public NodeFactory NodeFactory { get { return _nodeFactory; } }
@@ -51,7 +54,7 @@ namespace ILCompiler
{
// Flush the cache when it grows too big
if (_methodILCache.Count > 1000)
- _methodILCache = new ILProvider(new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyResolution: true), null));
+ _methodILCache = new ILProvider(_pInvokeILProvider);
return _methodILCache.GetMethodIL(method);
}
@@ -142,4 +145,4 @@ namespace ILCompiler
return DelegateCreationInfo.Create(delegateType, target, NodeFactory, followVirtualDispatch);
}
}
-} \ No newline at end of file
+}
diff --git a/src/System.Private.Jit/src/System.Private.Jit.csproj b/src/System.Private.Jit/src/System.Private.Jit.csproj
index 662339fa5..39cb058cc 100644
--- a/src/System.Private.Jit/src/System.Private.Jit.csproj
+++ b/src/System.Private.Jit/src/System.Private.Jit.csproj
@@ -69,6 +69,7 @@
<Compile Include="$(TypeSystemBasePath)\IL\Stubs\ArrayMethodILEmitter.cs" />
<Compile Include="$(TypeSystemBasePath)\IL\Stubs\CalliIntrinsic.cs" />
<Compile Include="$(TypeSystemBasePath)\IL\Stubs\ComparerIntrinsics.cs" />
+ <Compile Include="$(TypeSystemBasePath)\IL\Stubs\CalliMarshallingMethodThunk.cs" />
<Compile Include="$(TypeSystemBasePath)\IL\Stubs\DelegateMarshallingMethodThunk.cs" />
<Compile Include="$(TypeSystemBasePath)\IL\Stubs\ForwardDelegateCreationThunk.cs" />
<Compile Include="$(TypeSystemBasePath)\IL\Stubs\EETypePtrOfIntrinsic.cs" />