Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/ILCompiler.Compiler/src/Compiler/CompilationModuleGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,21 @@ public abstract class CompilationModuleGroup
/// <param name="calleeMethod">The called method to be inlined into the caller</param>
/// <returns></returns>
public virtual bool CanInline(MethodDesc callerMethod, MethodDesc calleeMethod) => true;

/// <summary>
/// Returns true when a given type belongs to the same version bubble as the compilation module group.
/// By default return the same outcome as ContainsType.
/// </summary>
/// <param name="typeDesc">Type to check</param>
/// <returns>True if the given type versions with the current compilation module group</returns>
public virtual bool VersionsWithType(TypeDesc typeDesc) => ContainsType(typeDesc);

/// <summary>
/// Returns true when a given method belongs to the same version bubble as the compilation module group.
/// By default return the same outcome as ContainsMethodBody.
/// </summary>
/// <param name="methodDesc">Method to check</param>
/// <returns>True if the given method versions with the current compilation module group</returns>
public virtual bool VersionsWithMethodBody(MethodDesc methodDesc) => ContainsMethodBody(methodDesc, unboxingStub: false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,24 @@ public DelegateCtorSignature(

public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory;
ObjectDataSignatureBuilder builder = new ObjectDataSignatureBuilder();
builder.AddSymbol(this);

if (!relocsOnly)
{
builder.EmitByte((byte)ReadyToRunFixupKind.READYTORUN_FIXUP_DelegateCtor);
SignatureContext innerContext = builder.EmitFixup(r2rFactory, ReadyToRunFixupKind.READYTORUN_FIXUP_DelegateCtor, _methodToken.Module, _signatureContext);

builder.EmitMethodSignature(
_targetMethod.Method,
constrainedType: null,
methodToken: _methodToken,
enforceDefEncoding: false,
_signatureContext,
innerContext,
isUnboxingStub: false,
isInstantiatingStub: false);
builder.EmitTypeSignature(_delegateType, _signatureContext);

builder.EmitTypeSignature(_delegateType, innerContext);
}

return builder.ToObjectData();
Expand All @@ -71,7 +74,13 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
sb.Append(nameMangler.CompilationUnitPrefix);
sb.Append($@"DelegateCtor({_delegateType} -> {_targetMethod.Method})");
sb.Append($@"DelegateCtor(");
sb.Append(nameMangler.GetMangledTypeName(_delegateType));
sb.Append(" -> ");
sb.Append(nameMangler.GetMangledMethodName(_targetMethod.Method));
sb.Append("; ");
sb.Append(_methodToken.ToString());
sb.Append(")");
}

public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Internal.JitInterface;
using Internal.Text;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;

namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
Expand Down Expand Up @@ -36,8 +37,10 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
dataBuilder.AddSymbol(this);

dataBuilder.EmitByte((byte)_fixupKind);
dataBuilder.EmitFieldSignature(_fieldDesc, _signatureContext);
EcmaModule targetModule = _signatureContext.GetTargetModule(_fieldDesc);
SignatureContext innerContext = dataBuilder.EmitFixup(r2rFactory, _fixupKind, targetModule, _signatureContext);

dataBuilder.EmitFieldSignature(_fieldDesc, innerContext);
}

return dataBuilder.ToObjectData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public enum DictionaryEntryKind
DeclaringTypeHandleSlot = 7,
}

[Flags]
public enum ReadyToRunFixupKind
{
READYTORUN_FIXUP_Invalid = 0x00,
Expand Down Expand Up @@ -120,6 +121,12 @@ public enum ReadyToRunFixupKind

READYTORUN_FIXUP_DelegateCtor = 0x2C, /* optimized delegate ctor */
READYTORUN_FIXUP_DeclaringTypeHandle = 0x2D,

READYTORUN_FIXUP_ModuleOverride = 0x80,
// followed by sig-encoded UInt with assemblyref index into either the assemblyref
// table of the MSIL metadata of the master context module for the signature or
// into the extra assemblyref table in the manifest metadata R2R header table
// (used in cases inlining brings in references to assemblies not seen in the MSIL).
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
using Internal.JitInterface;
using Internal.Text;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;

namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
public class GenericLookupSignature : Signature
{
private CORINFO_RUNTIME_LOOKUP_KIND _runtimeLookupKind;
private readonly CORINFO_RUNTIME_LOOKUP_KIND _runtimeLookupKind;

private readonly ReadyToRunFixupKind _fixupKind;

Expand All @@ -28,9 +29,9 @@ public class GenericLookupSignature : Signature
private readonly SignatureContext _signatureContext;

public GenericLookupSignature(
CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind,
ReadyToRunFixupKind fixupKind,
TypeDesc typeArgument,
CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind,
ReadyToRunFixupKind fixupKind,
TypeDesc typeArgument,
MethodWithToken methodArgument,
FieldDesc fieldArgument,
GenericContext methodContext,
Expand All @@ -50,56 +51,86 @@ public GenericLookupSignature(

public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
{
if (relocsOnly)
{
return new ObjectData(Array.Empty<byte>(), null, 1, null);
}

ReadyToRunCodegenNodeFactory r2rFactory = (ReadyToRunCodegenNodeFactory)factory;
ObjectDataSignatureBuilder dataBuilder = new ObjectDataSignatureBuilder();

if (!relocsOnly)
// Determine the need for module override
EcmaModule targetModule;
if (_methodArgument != null)
{
dataBuilder.AddSymbol(this);
targetModule = _methodArgument.Token.Module;
}
else if (_typeArgument != null)
{
targetModule = _signatureContext.GetTargetModule(_typeArgument);
}
else if (_fieldArgument != null)
{
targetModule = _signatureContext.GetTargetModule(_fieldArgument);
}
else
{
throw new NotImplementedException();
}

switch (_runtimeLookupKind)
{
case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_CLASSPARAM:
dataBuilder.EmitByte((byte)ReadyToRunFixupKind.READYTORUN_FIXUP_TypeDictionaryLookup);
break;
ReadyToRunFixupKind fixupToEmit;
TypeDesc contextTypeToEmit = null;

case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_METHODPARAM:
dataBuilder.EmitByte((byte)ReadyToRunFixupKind.READYTORUN_FIXUP_MethodDictionaryLookup);
break;
switch (_runtimeLookupKind)
{
case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_CLASSPARAM:
fixupToEmit = ReadyToRunFixupKind.READYTORUN_FIXUP_TypeDictionaryLookup;
break;

case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ:
dataBuilder.EmitByte((byte)ReadyToRunFixupKind.READYTORUN_FIXUP_ThisObjDictionaryLookup);
dataBuilder.EmitTypeSignature(_methodContext.ContextType, _signatureContext);
break;
case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_METHODPARAM:
fixupToEmit = ReadyToRunFixupKind.READYTORUN_FIXUP_MethodDictionaryLookup;
break;

default:
throw new NotImplementedException();
}
case CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ:
fixupToEmit = ReadyToRunFixupKind.READYTORUN_FIXUP_ThisObjDictionaryLookup;
contextTypeToEmit = _methodContext.ContextType;
break;

dataBuilder.EmitByte((byte)_fixupKind);
if (_methodArgument != null)
{
dataBuilder.EmitMethodSignature(
method: _methodArgument.Method,
constrainedType: _typeArgument,
methodToken: _methodArgument.Token,
enforceDefEncoding: false,
context: _signatureContext,
isUnboxingStub: false,
isInstantiatingStub: true);
}
else if (_typeArgument != null)
{
dataBuilder.EmitTypeSignature(_typeArgument, _signatureContext);
}
else if (_fieldArgument != null)
{
dataBuilder.EmitFieldSignature(_fieldArgument, _signatureContext);
}
else
{
default:
throw new NotImplementedException();
}
}

ObjectDataSignatureBuilder dataBuilder = new ObjectDataSignatureBuilder();
dataBuilder.AddSymbol(this);

SignatureContext innerContext = dataBuilder.EmitFixup(r2rFactory, fixupToEmit, targetModule, _signatureContext);
if (contextTypeToEmit != null)
{
dataBuilder.EmitTypeSignature(contextTypeToEmit, innerContext);
}

dataBuilder.EmitByte((byte)_fixupKind);
if (_methodArgument != null)
{
dataBuilder.EmitMethodSignature(
method: _methodArgument.Method,
constrainedType: _typeArgument,
methodToken: _methodArgument.Token,
enforceDefEncoding: false,
context: innerContext,
isUnboxingStub: false,
isInstantiatingStub: true);
}
else if (_typeArgument != null)
{
dataBuilder.EmitTypeSignature(_typeArgument, innerContext);
}
else if (_fieldArgument != null)
{
dataBuilder.EmitFieldSignature(_fieldArgument, innerContext);
}
else
{
throw new NotImplementedException();
}

return dataBuilder.ToObjectData();
Expand All @@ -115,7 +146,7 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde
sb.Append(": ");
if (_methodArgument != null)
{
RuntimeDeterminedTypeHelper.WriteTo(_methodArgument.Method, sb);
sb.Append(nameMangler.GetMangledMethodName(_methodArgument.Method));
if (!_methodArgument.Token.IsNull)
{
sb.Append(" [");
Expand All @@ -127,11 +158,11 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde
}
if (_typeArgument != null)
{
RuntimeDeterminedTypeHelper.WriteTo(_typeArgument, sb);
sb.Append(nameMangler.GetMangledTypeName(_typeArgument));
}
if (_fieldArgument != null)
{
RuntimeDeterminedTypeHelper.WriteTo(_fieldArgument, sb);
sb.Append(nameMangler.GetMangledFieldName(_fieldArgument));
}
sb.Append(" (");
_methodContext.AppendMangledName(nameMangler, sb);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 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 System.Collections.Generic;

namespace ILCompiler.DependencyAnalysis.ReadyToRun
Expand All @@ -11,6 +12,8 @@ public class ImportSectionNode : EmbeddedObjectNode
private readonly ArrayOfEmbeddedDataNode<Import> _imports;
// TODO: annoying - today there's no way to put signature RVA's into R/O data section
private readonly ArrayOfEmbeddedPointersNode<Signature> _signatures;
// TODO: annoying - cannot enumerate the ArrayOfEmbeddedPointersNode so we must keep a copy.
private readonly List<Signature> _signatureList;
private readonly GCRefMapNode _gcRefMap;

private readonly CorCompileImportType _type;
Expand All @@ -20,6 +23,8 @@ public class ImportSectionNode : EmbeddedObjectNode
private readonly bool _emitPrecode;
private readonly bool _emitGCRefMap;

private bool _materializedSignature;

public ImportSectionNode(string name, CorCompileImportType importType, CorCompileImportFlags flags, byte entrySize, bool emitPrecode, bool emitGCRefMap)
{
_name = name;
Expand All @@ -31,13 +36,32 @@ public ImportSectionNode(string name, CorCompileImportType importType, CorCompil

_imports = new ArrayOfEmbeddedDataNode<Import>(_name + "_ImportBegin", _name + "_ImportEnd", null);
_signatures = new ArrayOfEmbeddedPointersNode<Signature>(_name + "_SigBegin", _name + "_SigEnd", null);
_signatureList = new List<Signature>();
_gcRefMap = (_emitGCRefMap ? new GCRefMapNode(this) : null);
}

public void MaterializeSignature(ReadyToRunCodegenNodeFactory r2rFactory)
{
if (!_materializedSignature)
{
foreach (Signature signature in _signatureList)
{
signature.GetData(r2rFactory, relocsOnly: false);
}
_materializedSignature = true;
}
}

public void AddImport(NodeFactory factory, Import import)
{
if (_materializedSignature)
{
throw new Exception("Cannot call AddImport after MaterializeSignature");
}

_imports.AddEmbeddedObject(import);
_signatures.AddEmbeddedObject(import.ImportSignature);
_signatureList.Add(import.ImportSignature.Target);
if (_emitGCRefMap)
{
_gcRefMap.AddImport(import);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,31 @@

namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
public class ImportSectionsTableNode : ArrayOfEmbeddedDataNode<ImportSectionNode>
{
public ImportSectionsTableNode(TargetDetails target)
public class ImportSectionsTableNode : ArrayOfEmbeddedDataNode<ImportSectionNode>, ISignatureEmitter
{
private readonly ReadyToRunCodegenNodeFactory _r2rFactory;

private bool _materializedSignature;

public ImportSectionsTableNode(ReadyToRunCodegenNodeFactory r2rFactory)
: base("ImportSectionsTableStart", "ImportSectionsTableEnd", null)
{
_r2rFactory = r2rFactory;
_r2rFactory.ManifestMetadataTable.RegisterEmitter(this);
}

public void MaterializeSignature()
{
if (!_materializedSignature)
{
foreach (ImportSectionNode importSection in NodesList)
{
importSection.MaterializeSignature(_r2rFactory);
}
_materializedSignature = true;
}
}

protected override void GetElementDataForNodes(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
{
builder.RequireInitialPointerAlignment();
Expand Down
Loading