Skip to content

Commit

Permalink
Place dispatch cells in dehydrated section (#78748)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalStrehovsky committed Dec 4, 2022
1 parent b545ecb commit cd3a76c
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
// 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];

Expand Down Expand Up @@ -209,17 +209,14 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
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);
Expand All @@ -228,7 +225,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
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
Expand All @@ -252,7 +249,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
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;

Expand All @@ -276,8 +273,16 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace ILCompiler.DependencyAnalysis
{
public class InterfaceDispatchCellNode : EmbeddedObjectNode, ISymbolDefinitionNode
public sealed class InterfaceDispatchCellNode : EmbeddedObjectNode, ISymbolDefinitionNode
{
private readonly MethodDesc _targetMethod;
private readonly string _callSiteIdentifier;
Expand Down Expand Up @@ -113,11 +113,6 @@ public override void EncodeData(ref ObjectDataBuilder objData, NodeFactory facto
}
}

protected override void OnMarked(NodeFactory factory)
{
factory.InterfaceDispatchCellSection.AddEmbeddedObject(this);
}

public override int ClassCode => -2023802120;

public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System;
using System.Collections.Generic;

using Internal.Text;
using Internal.TypeSystem;

using Debug = System.Diagnostics.Debug;
Expand All @@ -14,17 +14,15 @@ namespace ILCompiler.DependencyAnalysis
/// 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.
Expand All @@ -48,7 +46,7 @@ protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, No
//
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);
Expand Down Expand Up @@ -83,10 +81,23 @@ protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, No
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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ public NodeFactory(
MetadataManager = metadataManager;
LazyGenericsPolicy = lazyGenericsPolicy;
_importedNodeProvider = importedNodeProvider;
InterfaceDispatchCellSection = new InterfaceDispatchCellSectionNode(this);
PreinitializationManager = preinitializationManager;
}

Expand Down Expand Up @@ -1122,7 +1121,7 @@ public string GetSymbolAlternateName(ISymbolNode node)

internal ModuleInitializerListNode ModuleInitializerList = new ModuleInitializerListNode();

public InterfaceDispatchCellSectionNode InterfaceDispatchCellSection { get; }
public InterfaceDispatchCellSectionNode InterfaceDispatchCellSection = new InterfaceDispatchCellSectionNode();

public ReadyToRunHeaderNode ReadyToRunHeader;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public abstract class MetadataManager : ICompilationRootProvider
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);
Expand Down Expand Up @@ -260,6 +261,11 @@ protected virtual void Graph_NewMarkedNode(DependencyNodeCore<NodeFactory> obj)
_reflectableMethods.Add(method);
}

if (obj is InterfaceDispatchCellNode dispatchCell)
{
_interfaceDispatchCells.Add(dispatchCell);
}

if (obj is StructMarshallingDataNode structMarshallingDataNode)
{
_typesWithStructMarshalling.Add(structMarshallingDataNode.Type);
Expand Down Expand Up @@ -666,6 +672,11 @@ public IEnumerable<MetadataMapping<MethodDesc>> GetStackTraceMapping(NodeFactory
return _stackTraceMappings;
}

internal IEnumerable<InterfaceDispatchCellNode> GetInterfaceDispatchCells()
{
return _interfaceDispatchCells;
}

internal IEnumerable<NonGCStaticsNode> GetCctorContextMapping()
{
return _cctorContextsGenerated;
Expand Down

0 comments on commit cd3a76c

Please sign in to comment.