diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ExternSymbolNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ExternSymbolNode.cs
index 3076da18905fbe..5321b9f48b3004 100644
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ExternSymbolNode.cs
+++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ExternSymbolNode.cs
@@ -2,12 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
-using System.Diagnostics;
using ILCompiler.DependencyAnalysisFramework;
-using ILCompiler.DependencyAnalysis.Wasm;
-using Internal.JitInterface;
using Internal.Text;
using Internal.TypeSystem;
@@ -63,72 +60,30 @@ public override string ToString()
}
}
- ///
- /// Signature information for an extern function, used to type its import on Wasm.
- ///
- public readonly record struct ExternalTypeSignature(
- MethodSignature Signature,
- bool IsUnmanagedCallersOnly,
- bool IsAsyncCall,
- bool HasGenericContextArg)
- {
- ///
- /// Signature for a native target, such as a direct P/Invoke or a native runtime helper.
- ///
- public static ExternalTypeSignature Unmanaged(MethodSignature signature)
- => new ExternalTypeSignature(signature, IsUnmanagedCallersOnly: true, IsAsyncCall: false, HasGenericContextArg: false);
-
- ///
- /// Signature for managed code that is referenced by name.
- ///
- // Keep aligned with IMethodCodeNodeWithTypeSignature
- public static ExternalTypeSignature FromMethod(MethodDesc method)
- => new ExternalTypeSignature(
- method.Signature,
- method.IsUnmanagedCallersOnly,
- method.IsAsyncCall(),
- method.RequiresInstMethodDescArg() || method.RequiresInstMethodTableArg() || method.IsArrayAddressMethod());
- }
-
///
/// Represents a function symbol that is defined externally and statically linked to the output obj file.
///
public class ExternFunctionSymbolNode : ExternSymbolNode, INodeWithTypeSignature
{
- private readonly ExternalTypeSignature? _typeSignature;
+ private readonly MethodSignature _signature;
+ private readonly bool _isUnmanagedCallersOnly;
+ private readonly bool _isAsyncCall;
+ private readonly bool _hasGenericContextArg;
+
+ public ExternFunctionSymbolNode(Utf8String name, MethodDesc method, bool isIndirection = false)
+ : this(name, method.Signature, method.IsUnmanagedCallersOnly, method.IsAsyncCall(), method.RequiresInstArg() || method.IsArrayAddressMethod(), isIndirection)
+ { }
- public ExternFunctionSymbolNode(Utf8String name, ExternalTypeSignature? typeSignature, bool isIndirection = false)
+ public ExternFunctionSymbolNode(Utf8String name, MethodSignature signature, bool isUnmanagedCallersOnly, bool isAsyncCall, bool hasGenericContextArg, bool isIndirection = false)
: base(name, isIndirection)
- {
- _typeSignature = typeSignature;
- }
+ => (_signature, _isUnmanagedCallersOnly, _isAsyncCall, _hasGenericContextArg) = (signature, isUnmanagedCallersOnly, isAsyncCall, hasGenericContextArg);
public override int ClassCode => 1452455506;
- ///
- /// The signature of the function, or null if it has no standard-ABI signature.
- ///
- public ExternalTypeSignature? TypeSignature => _typeSignature;
-
- MethodSignature INodeWithTypeSignature.Signature => _typeSignature.Value.Signature;
- bool INodeWithTypeSignature.IsUnmanagedCallersOnly => _typeSignature.Value.IsUnmanagedCallersOnly;
- bool INodeWithTypeSignature.IsAsyncCall => _typeSignature.Value.IsAsyncCall;
- bool INodeWithTypeSignature.HasGenericContextArg => _typeSignature.Value.HasGenericContextArg;
-
- public override IEnumerable GetStaticDependencies(NodeFactory factory)
- {
- // Indirection cells are data, not functions, so they are not imported as functions
- if (!factory.Target.IsWasm || RepresentsIndirectionCell)
- return null;
-
- Debug.Assert(_typeSignature is not null, $"Extern function '{this}' has no known signature and cannot be imported on Wasm");
- return [new DependencyListEntry(factory.WasmFunctionImport(this), "Wasm extern functions are imported")];
- }
- }
-
- public class AddressTakenExternFunctionSymbolNode(Utf8String name) : ExternFunctionSymbolNode(name, typeSignature: null)
- {
- public override int ClassCode => -45645737;
+ MethodSignature INodeWithTypeSignature.Signature => _signature;
+ bool INodeWithTypeSignature.IsUnmanagedCallersOnly => _isUnmanagedCallersOnly;
+ bool INodeWithTypeSignature.IsAsyncCall => _isAsyncCall;
+ bool INodeWithTypeSignature.HasGenericContextArg => _hasGenericContextArg;
}
///
diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/INodeWithTypeSignature.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/INodeWithTypeSignature.cs
index 11273e1d389e73..33c41b052e3a78 100644
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/INodeWithTypeSignature.cs
+++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/INodeWithTypeSignature.cs
@@ -4,7 +4,7 @@
namespace ILCompiler.DependencyAnalysis
{
- public interface INodeWithTypeSignature : ISymbolDefinitionNode
+ public interface INodeWithTypeSignature : ISymbolNode
{
MethodSignature Signature { get; }
bool IsUnmanagedCallersOnly { get; }
@@ -12,7 +12,7 @@ public interface INodeWithTypeSignature : ISymbolDefinitionNode
bool HasGenericContextArg { get; }
}
- public interface IMethodCodeNodeWithTypeSignature : IMethodNode, INodeWithTypeSignature
+ public interface IMethodCodeNodeWithTypeSignature : IMethodNode, INodeWithTypeSignature, ISymbolDefinitionNode
{
// Keep methods aligned with WasmLowering.GetSignature(MethodDesc)
MethodSignature INodeWithTypeSignature.Signature => Method.Signature;
diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/WasmFunctionImportNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/WasmFunctionImportNode.cs
deleted file mode 100644
index 2bc2564e94e527..00000000000000
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/WasmFunctionImportNode.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-
-using ILCompiler.DependencyAnalysis.Wasm;
-using ILCompiler.ObjectWriter;
-
-using Internal.Text;
-
-namespace ILCompiler.DependencyAnalysis
-{
- //
- // Represents an entry in the Wasm import section that imports an extern function. The node defines the
- // extern function's symbol name, so relocations against the extern function resolve to this import.
- //
- public class WasmFunctionImportNode : ObjectNode, ISymbolDefinitionNode
- {
- private static readonly Utf8String s_moduleName = new Utf8String("env"u8);
-
- private readonly Utf8String _name;
- private readonly INodeWithTypeSignature _signatureSource;
-
- /// The symbol name of the imported function.
- /// The node that provides the signature of the imported function.
- public WasmFunctionImportNode(Utf8String name, INodeWithTypeSignature signatureSource)
- {
- _name = name;
- _signatureSource = signatureSource;
- }
-
- public override bool IsShareable => true;
-
- public override int ClassCode => -683661982;
-
- public override bool StaticDependenciesAreComputed => true;
-
- public override ObjectNodeSection GetSection(NodeFactory factory) => WasmObjectNodeSection.ImportSection;
-
- protected override string GetName(NodeFactory factory) => $"Wasm Function Import: {_name}";
-
- public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
- {
- ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);
- builder.RequireInitialAlignment(1);
- builder.AddSymbol(this);
-
- // import ::= module:name name:name desc:importdesc
- // where importdesc for a function is 0x00 typeidx
- // and name is a length-prefixed UTF-8 string
- EmitName(ref builder, s_moduleName);
- EmitName(ref builder, _name);
- builder.EmitByte((byte)WasmExternalKind.Function);
- builder.EmitReloc(factory.WasmTypeNode(_signatureSource), RelocType.WASM_TYPE_INDEX_LEB);
-
- return builder.ToObjectData();
- }
-
- private static void EmitName(ref ObjectDataBuilder builder, Utf8String name)
- {
- // name is a length-prefixed UTF-8 string
- byte[] encodedName = new byte[DwarfHelper.SizeOfULEB128((ulong)name.Length) + name.Length];
- int lengthSize = DwarfHelper.WriteULEB128(encodedName, (ulong)name.Length);
- name.AsSpan().CopyTo(encodedName.AsSpan(lengthSize));
- builder.EmitBytes(encodedName);
- }
-
- public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
- {
- return _name.CompareTo(((WasmFunctionImportNode)other)._name);
- }
-
- public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
- {
- sb.Append(_name);
- }
-
- public int Offset => 0;
- }
-}
diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs
index 555c443a8521c6..180e170182d7b2 100644
--- a/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs
+++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs
@@ -297,6 +297,10 @@ private protected Utf8String GetMangledName(ISymbolNode symbolNode)
return symbolName;
}
+ private protected virtual void PrepareImportsForUndefinedSymbols()
+ {
+ }
+
private protected virtual void EmitSectionsAndLayout()
{
}
@@ -305,7 +309,7 @@ private protected virtual void EmitSectionsAndLayout()
partial void EmitDebugInfo(IReadOnlyCollection nodes, Logger logger);
- private SortedSet GetUndefinedSymbols()
+ private protected SortedSet GetUndefinedSymbols()
{
SortedSet undefinedSymbolSet = new SortedSet();
foreach (var relocationList in _sectionIndexToRelocations)
@@ -358,6 +362,11 @@ public virtual void EmitObject(Stream outputFileStream, IReadOnlyCollection checksumRelocations = [];
foreach (DependencyNode depNode in nodes)
{
+ if (_nodeFactory.Target.IsWasm && depNode is INodeWithTypeSignature methodDeclaration)
+ {
+ RecordMethodDeclaration(methodDeclaration);
+ }
+
// TODO-WASM: emit symbol ranges properly when code and data are separated
// Right now we still need to determine placements for some traditionally text-placed nodes,
// such as DebugDirectoryEntryNode and AssemblyStubNode
@@ -416,19 +425,11 @@ public virtual void EmitObject(Stream outputFileStream, IReadOnlyCollection
- /// Counts an import entry that was written directly to the section by an object node.
- ///
- public void CompleteExternallyWrittenEntry() => CompleteEntry();
-
protected override void WriteEntryCore(SectionWriter writer, WasmImport entry)
{
writer.EmitSymbolDefinition(new Utf8String(entry.Name));
diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmNative.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmNative.cs
index 9bc77de3a9f201..496d4139749bd2 100644
--- a/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmNative.cs
+++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmNative.cs
@@ -83,6 +83,21 @@ internal enum WasmExportKind : byte
Global = 0x03,
}
+ internal sealed class WasmFunctionImportType : WasmImportType
+ {
+ private readonly int _typeIndex;
+
+ public WasmFunctionImportType(int typeIndex) : base(WasmExternalKind.Function)
+ {
+ _typeIndex = typeIndex;
+ }
+
+ public override int Encode(Span buffer) => DwarfHelper.WriteULEB128(buffer, (ulong)_typeIndex);
+ public override int EncodeSize() => (int)DwarfHelper.SizeOfULEB128((ulong)_typeIndex);
+ public override int EncodeRelocationCount() => 0;
+ public override int EncodeRelocations(Span buffer) => 0;
+ }
+
public class WasmGlobalImportType : WasmImportType
{
private readonly WasmValueType _valueType;
diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
index 570921a48552f3..7f960eddb86e20 100644
--- a/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
+++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs
@@ -8,7 +8,6 @@
using System.Linq;
using ILCompiler.DependencyAnalysis;
using ILCompiler.DependencyAnalysis.Wasm;
-using ILCompiler.DependencyAnalysisFramework;
using ILCompiler.ObjectWriter.WasmInstructions;
using Internal.JitInterface;
using Internal.Text;
@@ -63,6 +62,7 @@ internal abstract partial class WasmObjectWriter : ObjectWriter
/// logical WebAssembly indices and must not be used to resolve index relocations.
///
private protected Dictionary _definedSymbols;
+ private readonly Dictionary _externalFunctions = new();
private int[] _sectionEmitOrder;
///
@@ -88,6 +88,25 @@ protected WasmObjectWriter(NodeFactory factory, ObjectWritingOptions options, Ou
{
}
+ private protected override void PrepareImportsForUndefinedSymbols()
+ {
+ // Imports must be registered before layout consumes function indices. Only actual unresolved
+ // references require imports; a marked extern can also resolve to a definition in this object.
+ foreach (Utf8String name in GetUndefinedSymbols())
+ {
+ if (_externalFunctions.TryGetValue(name, out INodeWithTypeSignature function))
+ {
+ if (function.Signature is null)
+ {
+ throw new InvalidOperationException($"Extern function '{name}' has no known signature and cannot be imported on Wasm");
+ }
+
+ int typeIndex = RegisterSignature(WasmLowering.GetSignature(function).FuncType);
+ WriteImport(new WasmImport("env", name.ToString(), new WasmFunctionImportType(typeIndex)));
+ }
+ }
+ }
+
private protected static void EmitWasmHeader(Stream outputFileStream)
{
outputFileStream.Write("\0asm"u8);
@@ -142,6 +161,14 @@ private protected override void RecordMethodSignature(WasmTypeNode signature)
}
private protected override void RecordMethodDeclaration(INodeWithTypeSignature node)
+ {
+ if (node is not ISymbolDefinitionNode && !node.RepresentsIndirectionCell)
+ {
+ _externalFunctions.TryAdd(GetMangledName(node), node);
+ }
+ }
+
+ private protected override void RecordMethodDefinition(INodeWithTypeSignature node)
{
WriteSignatureIndexForFunction(node);
Utf8String methodName = new(node.GetMangledName(_nodeFactory.NameMangler));
@@ -159,14 +186,6 @@ private protected override void RecordMethodDeclaration(INodeWithTypeSignature n
}
}
- private protected override void RecordFunctionImport(WasmFunctionImportNode import)
- {
- // Assign the import's index in the function index space. The import entry itself is emitted
- // by the node's own data.
- _wasmSymbolManager.AddImport(new Utf8String(import.GetMangledName(_nodeFactory.NameMangler)), WasmIndexSpace.Function);
- GetOrCreateSection(WasmObjectNodeSection.ImportSection, out _).CompleteExternallyWrittenEntry();
- }
-
private void RecordFunclets(INodeWithFunclets nodeWithFunclets)
{
FuncletKind[] funcletKinds = nodeWithFunclets.GetFuncletKinds();
@@ -329,7 +348,7 @@ private protected void WriteGlobal(
private protected void RegisterFunctionSymbol(Utf8String name) =>
_wasmSymbolManager.AddDefinition(name, WasmIndexSpace.Function);
- // This effectively recreates the logic of RecordMethodBody/RecordMethodDeclaration, but for manually inserted stubs that are not
+ // This effectively recreates the logic of RecordMethodDefinition, but for manually inserted stubs that are not
// represented by nodes in the dependency graph.
// TODO-Wasm: for maintability, we should try and push some of this into the dependency graph when we do more stub generation.
private protected void RegisterStubIndexAndSignature(WasmFuncType signature)
diff --git a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
index 4c9d12a4714e2e..2da01e22f707c0 100644
--- a/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
+++ b/src/coreclr/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
@@ -426,7 +426,6 @@ public enum ReadyToRunHelper
ResolveInterfaceMethodFast,
ResolveInterfaceMethod,
- NyiLdVirtFtn,
TlsGetAddr,
}
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
index 615f5c91ccf897..ace489f8250afa 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
@@ -760,6 +760,7 @@ private void CompileMethodCleanup()
private const int handleMultiplier = 8;
private const int handleBase = 0x420000;
+ private void* InvalidHandle => (void*)(handleBase - handleMultiplier);
private IntPtr ObjectToHandle(object obj)
{
@@ -785,6 +786,7 @@ private IntPtr ObjectToHandleUnchecked(object obj)
private object HandleToObject(void* handle)
{
Debug.Assert(handle != null);
+ Debug.Assert(handle != InvalidHandle);
int index = ((int)handle - handleBase) / handleMultiplier;
return _handleToObject[index];
}
diff --git a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs
index cedf930dba1e7a..dab10296c1c529 100644
--- a/src/coreclr/tools/Common/JitInterface/WasmLowering.cs
+++ b/src/coreclr/tools/Common/JitInterface/WasmLowering.cs
@@ -613,29 +613,6 @@ public static unsafe WasmSignature GetSignature(MethodSignature signature, CORIN
return GetSignature(signature, GetLoweringFlags(callSig));
}
- public static WasmSignature GetSignature(MethodSignature signature, bool hasGenericContextArg, bool isAsyncCall, bool isUnmanagedCallersOnly)
- {
- return GetSignature(signature, GetLoweringFlags(hasGenericContextArg, isAsyncCall, isUnmanagedCallersOnly));
- }
-
- public static LoweringFlags GetLoweringFlags(bool hasGenericContextArg, bool isAsyncCall, bool isUnmanagedCallersOnly)
- {
- LoweringFlags flags = 0;
- if (hasGenericContextArg)
- {
- flags |= LoweringFlags.HasGenericContextArg;
- }
- if (isAsyncCall)
- {
- flags |= LoweringFlags.IsAsyncCall;
- }
- if (isUnmanagedCallersOnly)
- {
- flags |= LoweringFlags.IsUnmanagedCallersOnly;
- }
- return flags;
- }
-
public static LoweringFlags GetLoweringFlags(MethodDesc method)
{
LoweringFlags flags = 0;
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs
index c32b79fe1636fd..cad0906405c123 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Compilation.cs
@@ -368,7 +368,7 @@ public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object t
case ReadyToRunHelperId.ObjectAllocator:
{
var type = (TypeDesc)targetOfLookup;
- return NodeFactory.KnownExternFunction(JitHelper.GetNewObjectHelperForType(type));
+ return NodeFactory.ReadyToRunHelper(JitHelper.GetNewObjectHelperForType(type));
}
default:
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerGeneratedInteropStubManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerGeneratedInteropStubManager.cs
index 16cb8dcc6e8bb8..5074b26c6cbbc5 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerGeneratedInteropStubManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilerGeneratedInteropStubManager.cs
@@ -15,18 +15,17 @@ namespace ILCompiler
///
public abstract class CompilerGeneratedInteropStubManager : InteropStubManager
{
- private readonly PInvokeILEmitterConfiguration _pInvokeILEmitterConfiguration;
internal readonly InteropStateManager _interopStateManager;
public CompilerGeneratedInteropStubManager(InteropStateManager interopStateManager, PInvokeILEmitterConfiguration pInvokeILEmitterConfiguration)
+ : base(pInvokeILEmitterConfiguration)
{
_interopStateManager = interopStateManager;
- _pInvokeILEmitterConfiguration = pInvokeILEmitterConfiguration;
}
public sealed override PInvokeILProvider CreatePInvokeILProvider()
{
- return new PInvokeILProvider(_pInvokeILEmitterConfiguration, _interopStateManager);
+ return new PInvokeILProvider(_configuration, _interopStateManager);
}
public sealed override void AddToReadyToRunHeader(ReadyToRunHeaderNode header, NodeFactory nodeFactory, ExternalReferencesTableNode commonFixupsTableNode)
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs
index 35b96088a3bf71..973e1574a90525 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ExternMethodSymbolNode.cs
@@ -17,7 +17,7 @@ public sealed class ExternMethodSymbolNode : ExternFunctionSymbolNode, IMethodNo
public ExternMethodSymbolNode(NodeFactory factory, MethodDesc method, bool isUnboxing = false)
: base(isUnboxing ? UnboxingStubNode.GetMangledName(factory.NameMangler, method) :
factory.NameMangler.GetMangledMethodName(method),
- ExternalTypeSignature.FromMethod(method))
+ method)
{
_method = method;
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs
index 2a9b9fb2346a88..6aafd57815e65f 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GenericLookupResult.cs
@@ -962,7 +962,7 @@ public override ISymbolNode GetTarget(NodeFactory factory, GenericLookupResultCo
return null;
}
Debug.Assert(!instantiatedType.IsCanonicalSubtype(CanonicalFormKind.Any));
- return factory.KnownExternFunction(JitHelper.GetNewObjectHelperForType(instantiatedType));
+ return factory.ReadyToRunHelper(JitHelper.GetNewObjectHelperForType(instantiatedType));
}
public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/KnownExternFunctions.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/KnownExternFunctions.cs
index c4d8c7bac0f787..150636eb0bfd88 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/KnownExternFunctions.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/KnownExternFunctions.cs
@@ -88,7 +88,6 @@ public static Utf8String GetName(ReadyToRunHelper function, TargetDetails target
ReadyToRunHelper.StackProbe => "RhpStackProbe",
ReadyToRunHelper.GCPoll => "RhpGcPoll",
- ReadyToRunHelper.NyiLdVirtFtn => "NYI_LDVIRTFTN",
ReadyToRunHelper.TlsGetAddr => "__tls_get_addr",
_ => throw new NotImplementedException(function.ToString())
@@ -104,7 +103,7 @@ public static Utf8String GetName(ReadyToRunHelper function, TargetDetails target
/// Extern function nodes are shared by name, so when a function is also reachable through a direct
/// P/Invoke (e.g. CoreLib's memset), its signature must exactly match that P/Invoke's signature.
///
- public static ExternalTypeSignature? GetTypeSignature(ReadyToRunHelper function, TypeSystemContext context)
+ public static MethodSignature GetSignature(ReadyToRunHelper function, TypeSystemContext context)
{
TypeDesc voidType = context.GetWellKnownType(WellKnownType.Void);
TypeDesc voidPointerType = voidType.MakePointerType();
@@ -117,23 +116,22 @@ public static Utf8String GetName(ReadyToRunHelper function, TargetDetails target
TypeDesc singleType = context.GetWellKnownType(WellKnownType.Single);
TypeDesc doubleType = context.GetWellKnownType(WellKnownType.Double);
- // All of these use the unmanaged calling convention, like the native FCIMPLs that implement most of them.
- ExternalTypeSignature UnmanagedSignature(TypeDesc returnType, params TypeDesc[] parameters) =>
- ExternalTypeSignature.Unmanaged(new MethodSignature(MethodSignatureFlags.Static, 0, returnType, parameters));
+ MethodSignature MakeSignature(TypeDesc returnType, params TypeDesc[] parameters) =>
+ new MethodSignature(MethodSignatureFlags.Static, 0, returnType, parameters);
return function switch
{
- ReadyToRunHelper.Throw => UnmanagedSignature(voidType, objectType),
- ReadyToRunHelper.ThrowExact => UnmanagedSignature(voidType, objectType),
+ ReadyToRunHelper.Throw => MakeSignature(voidType, objectType),
+ ReadyToRunHelper.ThrowExact => MakeSignature(voidType, objectType),
- ReadyToRunHelper.Rethrow => UnmanagedSignature(voidType),
+ ReadyToRunHelper.Rethrow => MakeSignature(voidType),
- ReadyToRunHelper.FailFast => UnmanagedSignature(voidType),
+ ReadyToRunHelper.FailFast => MakeSignature(voidType),
- ReadyToRunHelper.DebugBreak => UnmanagedSignature(voidType),
+ ReadyToRunHelper.DebugBreak => MakeSignature(voidType),
- ReadyToRunHelper.WriteBarrier => UnmanagedSignature(voidType, nativeIntType, objectType),
- ReadyToRunHelper.CheckedWriteBarrier => UnmanagedSignature(voidType, nativeIntType, objectType),
+ ReadyToRunHelper.WriteBarrier => MakeSignature(voidType, nativeIntType, objectType),
+ ReadyToRunHelper.CheckedWriteBarrier => MakeSignature(voidType, nativeIntType, objectType),
ReadyToRunHelper.WriteBarrier_EAX or
ReadyToRunHelper.WriteBarrier_EBX or
@@ -148,46 +146,46 @@ ReadyToRunHelper.CheckedWriteBarrier_EDI or
ReadyToRunHelper.CheckedWriteBarrier_ESI or
ReadyToRunHelper.CheckedWriteBarrier_EBP => null,
- ReadyToRunHelper.BulkWriteBarrierSmall => UnmanagedSignature(voidType, nativeIntType, nativeIntType, nativeUIntType),
+ ReadyToRunHelper.BulkWriteBarrierSmall => MakeSignature(voidType, nativeIntType, nativeIntType, nativeUIntType),
- ReadyToRunHelper.NewArray => UnmanagedSignature(objectType, nativeIntType, nativeIntType),
- ReadyToRunHelper.NewObject => UnmanagedSignature(objectType, nativeIntType),
+ ReadyToRunHelper.NewArray => MakeSignature(objectType, nativeIntType, nativeIntType),
+ ReadyToRunHelper.NewObject => MakeSignature(objectType, nativeIntType),
- ReadyToRunHelper.NewFast => UnmanagedSignature(objectType, nativeIntType),
- ReadyToRunHelper.NewFinalizable => UnmanagedSignature(objectType, nativeIntType),
- ReadyToRunHelper.NewFastAlign8 => UnmanagedSignature(objectType, nativeIntType),
- ReadyToRunHelper.NewFinalizableAlign8 => UnmanagedSignature(objectType, nativeIntType),
- ReadyToRunHelper.NewFastMisalign => UnmanagedSignature(objectType, nativeIntType),
+ ReadyToRunHelper.NewFast => MakeSignature(objectType, nativeIntType),
+ ReadyToRunHelper.NewFinalizable => MakeSignature(objectType, nativeIntType),
+ ReadyToRunHelper.NewFastAlign8 => MakeSignature(objectType, nativeIntType),
+ ReadyToRunHelper.NewFinalizableAlign8 => MakeSignature(objectType, nativeIntType),
+ ReadyToRunHelper.NewFastMisalign => MakeSignature(objectType, nativeIntType),
- ReadyToRunHelper.NewPtrArrayFast => UnmanagedSignature(objectType, nativeIntType, nativeIntType),
- ReadyToRunHelper.NewArrayFastAlign8 => UnmanagedSignature(objectType, nativeIntType, nativeIntType),
- ReadyToRunHelper.NewArrayFast => UnmanagedSignature(objectType, nativeIntType, nativeIntType),
+ ReadyToRunHelper.NewPtrArrayFast => MakeSignature(objectType, nativeIntType, nativeIntType),
+ ReadyToRunHelper.NewArrayFastAlign8 => MakeSignature(objectType, nativeIntType, nativeIntType),
+ ReadyToRunHelper.NewArrayFast => MakeSignature(objectType, nativeIntType, nativeIntType),
- ReadyToRunHelper.NativeMemSet => UnmanagedSignature(voidPointerType, voidPointerType, int32Type, nativeUIntType),
- ReadyToRunHelper.DblRem => UnmanagedSignature(doubleType, doubleType, doubleType),
- ReadyToRunHelper.FltRem => UnmanagedSignature(singleType, singleType, singleType),
+ ReadyToRunHelper.NativeMemSet => MakeSignature(voidPointerType, voidPointerType, int32Type, nativeUIntType),
+ ReadyToRunHelper.DblRem => MakeSignature(doubleType, doubleType, doubleType),
+ ReadyToRunHelper.FltRem => MakeSignature(singleType, singleType, singleType),
- ReadyToRunHelper.Lng2Dbl => UnmanagedSignature(doubleType, int64Type),
- ReadyToRunHelper.ULng2Dbl => UnmanagedSignature(doubleType, uint64Type),
- ReadyToRunHelper.Lng2Flt => UnmanagedSignature(singleType, int64Type),
- ReadyToRunHelper.ULng2Flt => UnmanagedSignature(singleType, uint64Type),
- ReadyToRunHelper.Dbl2Lng => UnmanagedSignature(int64Type, doubleType),
- ReadyToRunHelper.Dbl2ULng => UnmanagedSignature(uint64Type, doubleType),
+ ReadyToRunHelper.Lng2Dbl => MakeSignature(doubleType, int64Type),
+ ReadyToRunHelper.ULng2Dbl => MakeSignature(doubleType, uint64Type),
+ ReadyToRunHelper.Lng2Flt => MakeSignature(singleType, int64Type),
+ ReadyToRunHelper.ULng2Flt => MakeSignature(singleType, uint64Type),
+ ReadyToRunHelper.Dbl2Lng => MakeSignature(int64Type, doubleType),
+ ReadyToRunHelper.Dbl2ULng => MakeSignature(uint64Type, doubleType),
- ReadyToRunHelper.LMul => UnmanagedSignature(int64Type, int64Type, int64Type),
- ReadyToRunHelper.LRsz => UnmanagedSignature(uint64Type, uint64Type, int32Type),
- ReadyToRunHelper.LRsh => UnmanagedSignature(int64Type, int64Type, int32Type),
- ReadyToRunHelper.LLsh => UnmanagedSignature(int64Type, int64Type, int32Type),
+ ReadyToRunHelper.LMul => MakeSignature(int64Type, int64Type, int64Type),
+ ReadyToRunHelper.LRsz => MakeSignature(uint64Type, uint64Type, int32Type),
+ ReadyToRunHelper.LRsh => MakeSignature(int64Type, int64Type, int32Type),
+ ReadyToRunHelper.LLsh => MakeSignature(int64Type, int64Type, int32Type),
- ReadyToRunHelper.PInvokeBegin => UnmanagedSignature(voidType, nativeIntType),
- ReadyToRunHelper.PInvokeEnd => UnmanagedSignature(voidType, nativeIntType),
- ReadyToRunHelper.ReversePInvokeEnter => UnmanagedSignature(voidType, nativeIntType),
- ReadyToRunHelper.ReversePInvokeExit => UnmanagedSignature(voidType, nativeIntType),
+ ReadyToRunHelper.PInvokeBegin => MakeSignature(voidType, nativeIntType),
+ ReadyToRunHelper.PInvokeEnd => MakeSignature(voidType, nativeIntType),
+ ReadyToRunHelper.ReversePInvokeEnter => MakeSignature(voidType, nativeIntType),
+ ReadyToRunHelper.ReversePInvokeExit => MakeSignature(voidType, nativeIntType),
- ReadyToRunHelper.GCPoll => UnmanagedSignature(voidType),
+ ReadyToRunHelper.GCPoll => MakeSignature(voidType),
- ReadyToRunHelper.GVMLookupForSlot => UnmanagedSignature(nativeIntType, objectType, nativeIntType),
- ReadyToRunHelper.ResolveInterfaceMethod => UnmanagedSignature(nativeIntType, objectType, nativeIntType),
+ ReadyToRunHelper.GVMLookupForSlot => MakeSignature(nativeIntType, objectType, nativeIntType),
+ ReadyToRunHelper.ResolveInterfaceMethod => MakeSignature(nativeIntType, objectType, nativeIntType),
ReadyToRunHelper.ResolveInterfaceMethodFast => throw new NotImplementedException(
$"{nameof(ReadyToRunHelper.ResolveInterfaceMethodFast)} is not implemented by the runtime."),
@@ -196,8 +194,6 @@ ReadyToRunHelper.InterfaceDispatch or
ReadyToRunHelper.StackProbe => null,
- ReadyToRunHelper.NyiLdVirtFtn => null,
-
ReadyToRunHelper.TlsGetAddr => null,
_ => throw new NotImplementedException(function.ToString())
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs
index fc23ef4f4f01f5..22e2fe649d7f52 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -272,13 +272,17 @@ private void CreateNodeCaches()
return new FieldRvaDataNode(key);
});
- _externFunctionSymbols = new NodeCache(static (ExternFunctionKey key) =>
+ _directPInvokes = new NodeCache((MethodDesc key) =>
{
- return new ExternFunctionSymbolNode(key.Name, key.TypeSignature);
+ Utf8String externName = new Utf8String(InteropStubManager.GetDirectCallExternName(key));
+ externName = NameMangler.NodeMangler.ExternMethod(externName, key);
+
+ return new ExternFunctionSymbolNode(externName, key.Signature, isUnmanagedCallersOnly: true, isAsyncCall: false, hasGenericContextArg: false);
});
+
_externIndirectFunctionSymbols = new NodeCache((Utf8String name) =>
{
- return new ExternFunctionSymbolNode(name, typeSignature: null, isIndirection: true);
+ return new ExternFunctionSymbolNode(name, signature: null, false, false, false, isIndirection: true);
});
_externDataSymbols = new NodeCache((Utf8String name) =>
{
@@ -432,6 +436,14 @@ private void CreateNodeCaches()
return new InterfaceUseNode(type);
});
+ _r2rHelpers = new NodeCache((ReadyToRunHelper id) =>
+ {
+ return new ExternFunctionSymbolNode(
+ KnownExternFunctions.GetName(id, TypeSystemContext.Target),
+ KnownExternFunctions.GetSignature(id, TypeSystemContext),
+ isUnmanagedCallersOnly: true, isAsyncCall: false, hasGenericContextArg: false);
+ });
+
_readyToRunHelpers = new NodeCache(CreateReadyToRunHelperNode);
_genericReadyToRunHelpersFromDict = new NodeCache(CreateGenericLookupFromDictionaryNode);
@@ -627,9 +639,6 @@ private void CreateNodeCaches()
return new AnalysisCharacteristicNode(c);
});
- _wasmFunctionImports = new NodeCache((Utf8String name) =>
- throw new InvalidOperationException($"Wasm function import '{name}' must be created from an extern function"));
-
_wasmTypeNodes = new NodeCache(key =>
{
return new WasmTypeNode(key);
@@ -998,31 +1007,6 @@ internal ISymbolNode GenericVariance(GenericVarianceDetails details)
return _genericVariances.GetOrAdd(details);
}
- private NodeCache _externFunctionSymbols;
-
- ///
- /// Gets the node for an extern function. Nodes are keyed by name alone, so every reference to the
- /// same symbol (e.g. a JIT helper and a direct P/Invoke to the same native function) shares one node,
- /// and on Wasm all references must agree on its lowered function type.
- ///
- private ExternFunctionSymbolNode ExternFunctionSymbol(Utf8String name, ExternalTypeSignature? typeSignature)
- {
- ExternFunctionSymbolNode node = _externFunctionSymbols.GetOrAdd(new ExternFunctionKey(name, typeSignature));
- // Distinct managed types can describe the same native ABI. In the a case like shared pinvoke source with
- // different managed enum types, fall back to checking the lowered ABI is at least the same.
- Debug.Assert(!Target.IsWasm || node.TypeSignature == typeSignature ||
- Equals(
- WasmLowering.GetSignature(node),
- typeSignature.HasValue ?
- WasmLowering.GetSignature(typeSignature.Value.Signature,
- typeSignature.Value.HasGenericContextArg,
- typeSignature.Value.IsAsyncCall,
- typeSignature.Value.IsUnmanagedCallersOnly)
- : null),
- $"Conflicting signatures for extern function '{name}'");
- return node;
- }
-
private NodeCache _externIndirectFunctionSymbols;
public ISortableSymbolNode ExternIndirectFunctionSymbol(Utf8String name)
@@ -1030,9 +1014,10 @@ public ISortableSymbolNode ExternIndirectFunctionSymbol(Utf8String name)
return _externIndirectFunctionSymbols.GetOrAdd(name);
}
- public ExternFunctionSymbolNode DirectPInvokeTarget(Utf8String externName, MethodDesc pInvoke)
+ private NodeCache _directPInvokes;
+ public ExternFunctionSymbolNode DirectPInvokeTarget(MethodDesc method)
{
- return ExternFunctionSymbol(externName, ExternalTypeSignature.Unmanaged(pInvoke.Signature));
+ return _directPInvokes.GetOrAdd(method);
}
private NodeCache _externDataSymbols;
@@ -1042,13 +1027,6 @@ public ISortableSymbolNode ExternDataSymbol(Utf8String name)
return _externDataSymbols.GetOrAdd(name);
}
- public ExternFunctionSymbolNode KnownExternFunction(ReadyToRunHelper function)
- {
- return ExternFunctionSymbol(
- KnownExternFunctions.GetName(function, TypeSystemContext.Target),
- KnownExternFunctions.GetTypeSignature(function, TypeSystemContext));
- }
-
public ISortableSymbolNode ExternVariable(Utf8String name)
{
Utf8String mangledName = NameMangler.NodeMangler.ExternVariable(name);
@@ -1458,6 +1436,13 @@ public DependencyNodeCore InterfaceUse(TypeDesc type)
return _interfaceUses.GetOrAdd(type);
}
+ private NodeCache _r2rHelpers;
+
+ public ISymbolNode ReadyToRunHelper(ReadyToRunHelper id)
+ {
+ return _r2rHelpers.GetOrAdd(id);
+ }
+
private NodeCache _readyToRunHelpers;
public ISymbolNode ReadyToRunHelper(ReadyToRunHelperId id, object target)
@@ -1657,13 +1642,6 @@ public AnalysisCharacteristicNode AnalysisCharacteristic(string ch)
private NodeCache _wasmTypeNodes;
- private NodeCache _wasmFunctionImports;
-
- public WasmFunctionImportNode WasmFunctionImport(ExternFunctionSymbolNode node)
- {
- return _wasmFunctionImports.GetOrAdd(node.Name, name => new WasmFunctionImportNode(name, node));
- }
-
// TODO-Wasm: Do not use WasmFuncType directly as the key for better
// memory efficiency on lookup
public WasmTypeNode WasmTypeNode(MethodDesc desc)
@@ -1889,24 +1867,6 @@ public SerializedFrozenObjectKey(MetadataType ownerType, int allocationSiteId, T
public override int GetHashCode() => HashCode.Combine(OwnerType.GetHashCode(), AllocationSiteId);
}
- private struct ExternFunctionKey : IEquatable
- {
- public readonly Utf8String Name;
-
- // Used to create the node, but not part of the key's identity
- public readonly ExternalTypeSignature? TypeSignature;
-
- public ExternFunctionKey(Utf8String name, ExternalTypeSignature? typeSignature)
- {
- Name = name;
- TypeSignature = typeSignature;
- }
-
- public bool Equals(ExternFunctionKey other) => Name.Equals(other.Name);
- public override bool Equals(object obj) => obj is ExternFunctionKey other && Equals(other);
- public override int GetHashCode() => Name.GetHashCode();
- }
-
private struct MethodILKey : IEquatable
{
public readonly MethodIL MethodIL;
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs
index 37ab15a2d7d188..a7169798eb15b4 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/RuntimeImportMethodNode.cs
@@ -10,13 +10,13 @@ namespace ILCompiler.DependencyAnalysis
///
/// Represents a method that is imported from the runtime library.
///
- public class RuntimeImportMethodNode : ExternFunctionSymbolNode, IMethodNode, ISymbolDefinitionNode
+ public class RuntimeImportMethodNode : ExternFunctionSymbolNode, IMethodNode
{
private MethodDesc _method;
public RuntimeImportMethodNode(MethodDesc method, NameMangler nameMangler)
: base(nameMangler.NodeMangler.ExternMethod(new Utf8String(((EcmaMethod)method).GetRuntimeImportName()), method),
- ExternalTypeSignature.FromMethod(method))
+ method)
{
_method = method;
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs
index 523e4a1e29ecef..99a7c4eaae0e84 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM/ARMReadyToRunHelperNode.cs
@@ -132,7 +132,7 @@ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bo
if (targetMethod.OwningType.IsInterface)
{
encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.DispatchCell(targetMethod));
- encoder.EmitJMP(factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod));
+ encoder.EmitJMP(factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs
index 0510734bb7d575..05db57041dd5db 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs
@@ -147,7 +147,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder,
if (targetMethod.OwningType.IsInterface)
{
encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.DispatchCell(targetMethod));
- encoder.EmitJMP(factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod));
+ encoder.EmitJMP(factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs
index 52ed3590c522d6..026f6f44b5deaf 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64ReadyToRunHelperNode.cs
@@ -139,7 +139,7 @@ protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter enc
if (targetMethod.OwningType.IsInterface)
{
encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.DispatchCell(targetMethod));
- encoder.EmitJMP(factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod));
+ encoder.EmitJMP(factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs
index 4e928be256d8d3..7f4fb096c8575c 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64ReadyToRunHelperNode.cs
@@ -137,7 +137,7 @@ protected override void EmitCode(NodeFactory factory, ref RiscV64Emitter encoder
if (targetMethod.OwningType.IsInterface)
{
encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.DispatchCell(targetMethod));
- encoder.EmitJMP(factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod));
+ encoder.EmitJMP(factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_Wasm/WasmReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_Wasm/WasmReadyToRunHelperNode.cs
index cbdabcdc3b881f..5a263202b44612 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_Wasm/WasmReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_Wasm/WasmReadyToRunHelperNode.cs
@@ -179,7 +179,7 @@ protected override void EmitCode(NodeFactory factory, ref WasmEmitter encoder, b
MethodDesc targetMethod = (MethodDesc)Target;
if (targetMethod.OwningType.IsInterface)
{
- ISymbolNode helper = factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod);
+ ISymbolNode helper = factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod);
expressions.Add(Local.Get(1));
expressions.Add(I32.ConstRVA(factory.DispatchCell(targetMethod)));
expressions.Add(ControlFlow.ReturnCall(helper));
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs
index 8557152e5fe943..d87e3c902d507b 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs
@@ -152,7 +152,7 @@ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bo
if (targetMethod.OwningType.IsInterface)
{
encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.DispatchCell(targetMethod));
- encoder.EmitJMP(factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod));
+ encoder.EmitJMP(factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs
index a809bc0f4c52da..c4bec4b48661b9 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X86/X86ReadyToRunHelperNode.cs
@@ -161,7 +161,7 @@ protected override void EmitCode(NodeFactory factory, ref X86Emitter encoder, bo
if (targetMethod.OwningType.IsInterface)
{
encoder.EmitMOV(encoder.TargetRegister.Arg1, factory.DispatchCell(targetMethod));
- encoder.EmitJMP(factory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethod));
+ encoder.EmitJMP(factory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethod));
}
else
{
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/EmptyInteropStubManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/EmptyInteropStubManager.cs
index 53dc3e7143a53d..67f7213a7dfa74 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/EmptyInteropStubManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/EmptyInteropStubManager.cs
@@ -14,6 +14,19 @@ namespace ILCompiler
///
public sealed class EmptyInteropStubManager : InteropStubManager
{
+ private class DummyConfiguration : PInvokeILEmitterConfiguration
+ {
+ public override bool GenerateDirectCall(MethodDesc method, out string externName)
+ {
+ externName = method.GetPInvokeMethodMetadata().Name;
+ return true;
+ }
+ }
+
+ public EmptyInteropStubManager()
+ : base(new DummyConfiguration())
+ { }
+
public override PInvokeILProvider CreatePInvokeILProvider()
{
return null;
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
index ed0a36ccbb5f9f..214994a58b0dea 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
@@ -194,7 +194,7 @@ protected override Helper CreateValueFromKey(ReadyToRunHelper key)
{
MethodDesc methodDesc = JitHelper.GetEntryPoint(_compilation.TypeSystemContext, key);
ISymbolNode entryPoint = methodDesc is null
- ? _compilation.NodeFactory.KnownExternFunction(key)
+ ? _compilation.NodeFactory.ReadyToRunHelper(key)
: _compilation.NodeFactory.MethodEntrypoint(methodDesc);
return new Helper(key, entryPoint);
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/InteropStubManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/InteropStubManager.cs
index 3ea2357cda46cf..5b7290272113ec 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/InteropStubManager.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/InteropStubManager.cs
@@ -1,6 +1,8 @@
// 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 Internal.IL;
using Internal.TypeSystem;
using ILCompiler.DependencyAnalysis;
@@ -14,6 +16,13 @@ namespace ILCompiler
///
public abstract class InteropStubManager : ICompilationRootProvider
{
+ protected readonly PInvokeILEmitterConfiguration _configuration;
+
+ public InteropStubManager(PInvokeILEmitterConfiguration configuration)
+ {
+ _configuration = configuration;
+ }
+
public abstract void AddDependenciesDueToMethodCodePresence(ref DependencyList dependencies, NodeFactory factory, MethodDesc method);
public abstract void AddInterestingInteropConstructedTypeDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type);
@@ -33,5 +42,13 @@ public virtual void AddToReadyToRunHeader(ReadyToRunHeaderNode header, NodeFacto
public virtual void AddCompilationRoots(IRootingServiceProvider rootProvider)
{
}
+
+ public string GetDirectCallExternName(MethodDesc method)
+ {
+ bool directCall = _configuration.GenerateDirectCall(method, out string externName);
+ Debug.Assert(directCall);
+ Debug.Assert(externName != null);
+ return externName;
+ }
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs
index aff785577bb8d9..4be2bc2740591e 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs
@@ -158,7 +158,7 @@ partial void EmitUnwindInfoForNode(ObjectNode node, Utf8String currentSymbolName
partial void HandleControlFlowForRelocation(ISymbolNode relocTarget, Utf8String relocSymbolName)
{
- if (relocTarget is IMethodNode or AssemblyStubNode or AddressTakenExternFunctionSymbolNode)
+ if (relocTarget is IMethodNode or AssemblyStubNode)
{
// For now consider all method symbols address taken.
// We could restrict this in the future to those that are referenced from
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs
index 3b6c61264f1302..30c6f3d2434b5d 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/Stubs/PInvokeILProvider.cs
@@ -36,13 +36,5 @@ public MethodDesc GetCalliStub(MethodSignature signature, ModuleDesc moduleConte
{
return _interopStateManager.GetPInvokeCalliStub(signature, moduleContext);
}
-
- public string GetDirectCallExternName(MethodDesc method)
- {
- bool directCall = _pInvokeILEmitterConfiguration.GenerateDirectCall(method, out string externName);
- Debug.Assert(directCall);
- Debug.Assert(externName != null);
- return externName;
- }
}
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
index 55e76266df2f5b..55003585495e5f 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
@@ -330,7 +330,6 @@
-
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
index 58d17ff74d511e..c36307dd5c3cce 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
@@ -1500,12 +1500,6 @@ public Utf8String GetSymbolAlternateName(ISymbolNode node, out bool isHidden)
private NodeCache _wasmTypeNodes;
- public WasmFunctionImportNode WasmFunctionImport(ExternFunctionSymbolNode node)
- {
- // ReadyToRun does not reference extern functions
- throw new NotSupportedException();
- }
-
private NodeCache _wasmMethodRelativeVirtualIPs;
private readonly struct WasmUnboxingStubKey : IEquatable
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
index 47bf7c3876eebd..b0dd89c86f575d 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
@@ -111,7 +111,6 @@
-
diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
index 4a5510c5f9cf1b..61fbdf35a206f4 100644
--- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
+++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs
@@ -631,30 +631,30 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum)
id = ReadyToRunHelper.NewObject;
break;
case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewFast);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewFast);
case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_FINALIZE:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewFinalizable);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewFinalizable);
case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_ALIGN8:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewFastAlign8);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewFastAlign8);
case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewFinalizableAlign8);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewFinalizableAlign8);
case CorInfoHelpFunc.CORINFO_HELP_NEWSFAST_ALIGN8_VC:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewFastMisalign);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewFastMisalign);
case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_DIRECT:
id = ReadyToRunHelper.NewArray;
break;
case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_PTR:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewPtrArrayFast);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewPtrArrayFast);
case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_ALIGN8:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewArrayFastAlign8);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewArrayFastAlign8);
case CorInfoHelpFunc.CORINFO_HELP_NEWARR_1_VC:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NewArrayFast);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.NewArrayFast);
case CorInfoHelpFunc.CORINFO_HELP_STACK_PROBE:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.StackProbe);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.StackProbe);
case CorInfoHelpFunc.CORINFO_HELP_POLL_GC:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.GCPoll);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.GCPoll);
case CorInfoHelpFunc.CORINFO_HELP_LMUL:
id = ReadyToRunHelper.LMul;
@@ -800,10 +800,10 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum)
if ((_compilation._compilationOptions & RyuJitCompilationOptions.ControlFlowGuardAnnotations) != 0
// Not implemented on x86: https://github.com/dotnet/runtime/issues/99516
&& _compilation.NodeFactory.TypeSystemContext.Target.Architecture != TargetArchitecture.X86)
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.InterfaceDispatchGuarded);
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.InterfaceDispatch);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.InterfaceDispatchGuarded);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.InterfaceDispatch);
case CorInfoHelpFunc.CORINFO_HELP_INTERFACELOOKUP_FOR_SLOT:
- return _compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.ResolveInterfaceMethodFast);
+ return _compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.ResolveInterfaceMethodFast);
case CorInfoHelpFunc.CORINFO_HELP_GETREFANY:
id = ReadyToRunHelper.GetRefAny;
@@ -825,7 +825,7 @@ private ISymbolNode GetHelperFtnUncached(CorInfoHelpFunc ftnNum)
MethodDesc methodDesc = JitHelper.GetEntryPoint(_compilation.TypeSystemContext, id);
return methodDesc is null
- ? _compilation.NodeFactory.KnownExternFunction(id)
+ ? _compilation.NodeFactory.ReadyToRunHelper(id)
: _compilation.NodeFactory.MethodEntrypoint(methodDesc);
}
@@ -1674,7 +1674,8 @@ private void getCallInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_RESO
// If this is LDVIRTFTN of an interface method that is part of a verifiable delegate creation sequence,
// RyuJIT is not going to use this value.
pResult->exactContextNeedsRuntimeLookup = false;
- pResult->codePointerOrStubLookup.constLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.NyiLdVirtFtn));
+ pResult->codePointerOrStubLookup.constLookup.addr = InvalidHandle;
+ pResult->codePointerOrStubLookup.constLookup.accessType = InfoAccessType.IAT_VALUE;
}
else
{
@@ -1940,11 +1941,7 @@ private unsafe HRESULT allocPgoInstrumentationBySchema(CORINFO_METHOD_STRUCT_* f
private void getAddressOfPInvokeTarget(CORINFO_METHOD_STRUCT_* method, ref CORINFO_CONST_LOOKUP pLookup)
{
MethodDesc md = HandleToObject(method);
-
- Utf8String externName = new Utf8String(_compilation.PInvokeILProvider.GetDirectCallExternName(md));
- externName = _compilation.NodeFactory.NameMangler.NodeMangler.ExternMethod(externName, md);
-
- pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.DirectPInvokeTarget(externName, md));
+ pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.DirectPInvokeTarget(md));
}
private void getGSCookie(IntPtr* pCookieVal, IntPtr** ppCookieVal)
@@ -2495,7 +2492,7 @@ private void getThreadLocalStaticInfo_NativeAOT(CORINFO_THREAD_STATIC_INFO_NATIV
pInfo->tlsIndexObject = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternDataSymbol(new Utf8String("_tls_index"u8)));
pInfo->tlsRootObject = CreateConstLookupToSymbol(_compilation.NodeFactory.TlsRoot);
pInfo->threadStaticBaseSlow = CreateConstLookupToSymbol(_compilation.NodeFactory.HelperEntrypoint(HelperEntrypoint.GetInlinedThreadStaticBaseSlow));
- pInfo->tlsGetAddrFtnPtr = CreateConstLookupToSymbol(_compilation.NodeFactory.KnownExternFunction(ReadyToRunHelper.TlsGetAddr));
+ pInfo->tlsGetAddrFtnPtr = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelper.TlsGetAddr));
}
#pragma warning disable CA1822 // Mark members as static