// the most popular targets.
ISymbolDefinitionNode firstSymbol = null;
var relocOccurences = new Dictionary<ISymbolNode, int>();
- foreach (ObjectNode.ObjectData o in factory.MetadataManager.GetDehydratableData())
+ foreach (ObjectData o in factory.MetadataManager.GetDehydratableData())
{
firstSymbol ??= o.DefinedSymbols[0];
{
Debug.Assert(sourcePosition == reloc.Offset);
-#if DEBUG
+ long delta;
unsafe
{
fixed (byte* pData = &o.Data[reloc.Offset])
{
- long delta = Relocation.ReadValue(reloc.RelocType, pData);
- // Extra work needed to be able to encode/decode relocs with deltas
- Debug.Assert(delta == 0);
+ delta = Relocation.ReadValue(reloc.RelocType, pData);
}
}
-#endif
// The size of the relocation is included in the ObjectData bytes. Skip the literal bytes.
sourcePosition += Relocation.GetSize(reloc.RelocType);
if (target is ISymbolNodeWithLinkage withLinkage)
target = withLinkage.NodeForLinkage(factory);
- if (relocs.TryGetValue(target, out int targetIndex))
+ if (delta == 0 && relocs.TryGetValue(target, out int targetIndex))
{
// Reloc goes through the lookup table
int relocCommand = reloc.RelocType switch
bool hasNextReloc;
do
{
- builder.EmitReloc(target, RelocType.IMAGE_REL_BASED_RELPTR32);
+ builder.EmitReloc(target, RelocType.IMAGE_REL_BASED_RELPTR32, checked((int)delta));
numRelocs++;
hasNextReloc = false;
if (nextTarget is ISymbolNodeWithLinkage nextTargetWithLinkage)
nextTarget = nextTargetWithLinkage.NodeForLinkage(factory);
+ unsafe
+ {
+ fixed (byte* pData = &o.Data[reloc.Offset])
+ {
+ delta = Relocation.ReadValue(reloc.RelocType, pData);
+ }
+ }
+
// We don't have a short code for it?
- if (relocs.ContainsKey(nextTarget))
+ if (delta == 0 && relocs.ContainsKey(nextTarget))
break;
// This relocation is good - we'll generate it as part of the run
namespace ILCompiler.DependencyAnalysis
{
- public class InterfaceDispatchCellNode : EmbeddedObjectNode, ISymbolDefinitionNode
+ public sealed class InterfaceDispatchCellNode : EmbeddedObjectNode, ISymbolDefinitionNode
{
private readonly MethodDesc _targetMethod;
private readonly string _callSiteIdentifier;
}
}
- protected override void OnMarked(NodeFactory factory)
- {
- factory.InterfaceDispatchCellSection.AddEmbeddedObject(this);
- }
-
public override int ClassCode => -2023802120;
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
using System;
using System.Collections.Generic;
-
+using Internal.Text;
using Internal.TypeSystem;
using Debug = System.Diagnostics.Debug;
/// Represents a section of the executable where interface dispatch cells and their slot information
/// is stored.
/// </summary>
- public class InterfaceDispatchCellSectionNode : ArrayOfEmbeddedDataNode<InterfaceDispatchCellNode>
+ public class InterfaceDispatchCellSectionNode : DehydratableObjectNode, ISymbolDefinitionNode
{
- public InterfaceDispatchCellSectionNode(NodeFactory factory)
- : base("__InterfaceDispatchCellSection_Start", "__InterfaceDispatchCellSection_End", new DispatchCellComparer(factory))
- {
- }
-
- protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
+ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relocsOnly)
{
if (relocsOnly)
- return;
+ return new ObjectData(Array.Empty<byte>(), Array.Empty<Relocation>(), 1, Array.Empty<ISymbolDefinitionNode>());
+
+ var builder = new ObjectDataBuilder(factory, relocsOnly);
+ builder.AddSymbol(this);
// The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the
// synchronization mechanism of the two values in the runtime.
//
int runLength = 0;
int currentSlot = NoSlot;
- foreach (InterfaceDispatchCellNode node in NodesList)
+ foreach (InterfaceDispatchCellNode node in new SortedSet<InterfaceDispatchCellNode>(factory.MetadataManager.GetInterfaceDispatchCells(), new DispatchCellComparer(factory)))
{
MethodDesc targetMethod = node.TargetMethod;
int targetSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, targetMethod, targetMethod.OwningType);
builder.EmitZeroPointer();
builder.EmitNaturalInt(currentSlot);
}
+
+ return builder.ToObjectData();
}
+ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ => sb.Append(nameMangler.CompilationUnitPrefix).Append("__InterfaceDispatchCellSection_Start");
+ protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory) => ObjectNodeSection.DataSection;
+ protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+
public override int ClassCode => -1389343;
+ public int Offset => 0;
+
+ public override bool IsShareable => false;
+
+ public override bool StaticDependenciesAreComputed => true;
+
/// <summary>
/// Comparer that groups interface dispatch cells by their slot number.
/// </summary>
MetadataManager = metadataManager;
LazyGenericsPolicy = lazyGenericsPolicy;
_importedNodeProvider = importedNodeProvider;
- InterfaceDispatchCellSection = new InterfaceDispatchCellSectionNode(this);
PreinitializationManager = preinitializationManager;
}
internal ModuleInitializerListNode ModuleInitializerList = new ModuleInitializerListNode();
- public InterfaceDispatchCellSectionNode InterfaceDispatchCellSection { get; }
+ public InterfaceDispatchCellSectionNode InterfaceDispatchCellSection = new InterfaceDispatchCellSectionNode();
public ReadyToRunHeaderNode ReadyToRunHeader;
protected readonly ManifestResourceBlockingPolicy _resourceBlockingPolicy;
protected readonly DynamicInvokeThunkGenerationPolicy _dynamicInvokeThunkGenerationPolicy;
+ private readonly List<InterfaceDispatchCellNode> _interfaceDispatchCells = new List<InterfaceDispatchCellNode>();
private readonly SortedSet<NonGCStaticsNode> _cctorContextsGenerated = new SortedSet<NonGCStaticsNode>(CompilerComparer.Instance);
private readonly SortedSet<TypeDesc> _typesWithEETypesGenerated = new SortedSet<TypeDesc>(TypeSystemComparer.Instance);
private readonly SortedSet<TypeDesc> _typesWithConstructedEETypesGenerated = new SortedSet<TypeDesc>(TypeSystemComparer.Instance);
_reflectableMethods.Add(method);
}
+ if (obj is InterfaceDispatchCellNode dispatchCell)
+ {
+ _interfaceDispatchCells.Add(dispatchCell);
+ }
+
if (obj is StructMarshallingDataNode structMarshallingDataNode)
{
_typesWithStructMarshalling.Add(structMarshallingDataNode.Type);
return _stackTraceMappings;
}
+ internal IEnumerable<InterfaceDispatchCellNode> GetInterfaceDispatchCells()
+ {
+ return _interfaceDispatchCells;
+ }
+
internal IEnumerable<NonGCStaticsNode> GetCctorContextMapping()
{
return _cctorContextsGenerated;