Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
CppCodeGen: implement shared generics and support generic virtual met…
Browse files Browse the repository at this point in the history
…hods
  • Loading branch information
Konstantin Baladurin committed Oct 25, 2018
1 parent b894cd1 commit 30a641b
Show file tree
Hide file tree
Showing 26 changed files with 2,190 additions and 385 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a hashtable of all type blocked from reflection.
/// </summary>
internal sealed class BlockReflectionTypeMapNode : ObjectNode, ISymbolDefinitionNode
public sealed class BlockReflectionTypeMapNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ namespace ILCompiler.DependencyAnalysis
/// Similarly, the dependencies that we track for canonicl type instantiations are minimal, and are just the ones used
/// by the dynamic type loader
/// </summary>
internal sealed class CanonicalEETypeNode : EETypeNode
public sealed class CanonicalEETypeNode : EETypeNode
{
public CanonicalEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type)
{
Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any));
Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any));
Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific));
Debug.Assert(!type.IsMdArray);
}

public override bool StaticDependenciesAreComputed => true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Hashtable of all exact (non-canonical) generic method instantiations compiled in the module.
/// </summary>
internal sealed class ExactMethodInstantiationsNode : ObjectNode, ISymbolDefinitionNode
public sealed class ExactMethodInstantiationsNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,24 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)

foreach (SymbolAndDelta symbolAndDelta in _insertedSymbols)
{
if (factory.Target.Abi == TargetAbi.CoreRT)
if (factory.Target.Abi == TargetAbi.ProjectN)
{
// TODO: set low bit if the linkage of the symbol is IAT_PVALUE.
builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_RELPTR32, symbolAndDelta.Delta);
}
else
{
Debug.Assert(factory.Target.Abi == TargetAbi.ProjectN);
int delta = symbolAndDelta.Delta;
if (symbolAndDelta.Symbol.RepresentsIndirectionCell)
{
delta = (int)((uint)delta | IndirectionConstants.RVAPointsToIndirection);
}
builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_ADDR32NB, delta);
}
else if (factory.Target.SupportsRelativePointers)
{
// TODO: set low bit if the linkage of the symbol is IAT_PVALUE.
builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_RELPTR32, symbolAndDelta.Delta);
}
else
{
builder.EmitPointerReloc(symbolAndDelta.Symbol, symbolAndDelta.Delta);
}
}

_endSymbol.SetSymbolOffset(builder.CountBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class FatFunctionPointerNode : ObjectNode, IMethodNode, ISymbolDefinition
{
private bool _isUnboxingStub;

public bool IsUnboxingStub => _isUnboxingStub;

public FatFunctionPointerNode(MethodDesc methodRepresented, bool isUnboxingStub)
{
// We should not create these for methods that don't have a canonical method body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a hashtable of all compiled generic method instantiations
/// </summary>
internal sealed class GenericMethodsHashtableNode : ObjectNode, ISymbolDefinitionNode
public sealed class GenericMethodsHashtableNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Hashtable of all generic method templates used by the TypeLoader at runtime
/// </summary>
internal sealed class GenericMethodsTemplateMap : ObjectNode, ISymbolDefinitionNode
public sealed class GenericMethodsTemplateMap : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a hashtable of all compiled generic type instantiations
/// </summary>
internal sealed class GenericTypesHashtableNode : ObjectNode, ISymbolDefinitionNode
public sealed class GenericTypesHashtableNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a map of generic virtual method implementations.
/// </summary>
internal sealed class GenericVirtualMethodTableNode : ObjectNode, ISymbolDefinitionNode
public sealed class GenericVirtualMethodTableNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a map between reflection metadata and generated method bodies.
/// </summary>
internal sealed class InterfaceGenericVirtualMethodTableNode : ObjectNode, ISymbolDefinitionNode
public sealed class InterfaceGenericVirtualMethodTableNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ILCompiler.DependencyAnalysis
/// Represents a blob of native metadata describing assemblies, the types in them, and their members.
/// The data is used at runtime to e.g. support reflection.
/// </summary>
internal sealed class MetadataNode : ObjectNode, ISymbolDefinitionNode
public sealed class MetadataNode : ObjectNode, ISymbolDefinitionNode
{
ObjectAndOffsetSymbolNode _endSymbol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Native layout info blob.
/// </summary>
internal sealed class NativeLayoutInfoNode : ObjectNode, ISymbolDefinitionNode
public sealed class NativeLayoutInfoNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class NativeLayoutSignatureNode : ObjectNode, ISymbolDefinitionNode
private Utf8String _identityPrefix;
private NativeLayoutSavedVertexNode _nativeSignature;

public TypeSystemEntity Identity => _identity;

public NativeLayoutSignatureNode(NativeLayoutSavedVertexNode nativeSignature, TypeSystemEntity identity, Utf8String identityPrefix)
{
_nativeSignature = nativeSignature;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// The node is used in ProjectX to represent a canonical type that does not have a vtable.
/// </summary>
internal sealed class NecessaryCanonicalEETypeNode : EETypeNode
public sealed class NecessaryCanonicalEETypeNode : EETypeNode
{
public NecessaryCanonicalEETypeNode(NodeFactory factory, TypeDesc type) : base(factory, type)
{
Debug.Assert(!type.IsCanonicalDefinitionType(CanonicalFormKind.Any));
Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any));
Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific));
Debug.Assert(!type.IsMdArray);
}

protected override ISymbolNode GetBaseTypeNode(NodeFactory factory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public abstract partial class ReadyToRunGenericHelperNode : AssemblyStubNode, IN
protected TypeSystemEntity _dictionaryOwner;
protected GenericLookupResult _lookupSignature;

public ReadyToRunHelperId Id => _id;
public Object Target => _target;
public TypeSystemEntity DictionaryOwner => _dictionaryOwner;
public GenericLookupResult LookupSignature => _lookupSignature;

public ReadyToRunGenericHelperNode(NodeFactory factory, ReadyToRunHelperId helperId, object target, TypeSystemEntity dictionaryOwner)
{
_id = helperId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a map between EETypes and metadata records within the <see cref="MetadataNode"/>.
/// </summary>
internal sealed class TypeMetadataMapNode : ObjectNode, ISymbolDefinitionNode
public sealed class TypeMetadataMapNode : ObjectNode, ISymbolDefinitionNode
{
private ObjectAndOffsetSymbolNode _endSymbol;
private ExternalReferencesTableNode _externalReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace ILCompiler.DependencyAnalysis
/// <summary>
/// Represents a node containing information necessary at runtime to locate type's thread static base.
/// </summary>
internal class TypeThreadStaticIndexNode : ObjectNode, ISymbolDefinitionNode
public class TypeThreadStaticIndexNode : ObjectNode, ISymbolDefinitionNode
{
private MetadataType _type;

Expand Down Expand Up @@ -67,6 +67,8 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
return objData.ToObjectData();
}

public MetadataType Type => _type;

public override int ClassCode => -149601250;

public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
Expand Down
17 changes: 15 additions & 2 deletions src/ILCompiler.CppCodeGen/src/Compiler/CppCodegenCompilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,22 @@ protected override void CompileInternal(string outputFile, ObjectDumper dumper)

protected override void ComputeDependencyNodeDependencies(List<DependencyNodeCore<NodeFactory>> obj)
{
foreach (CppMethodCodeNode methodCodeNodeNeedingCode in obj)
foreach (var dependency in obj)
{
_cppWriter.CompileMethod(methodCodeNodeNeedingCode);
var methodCodeNodeNeedingCode = dependency as CppMethodCodeNode;
if (methodCodeNodeNeedingCode == null)
{
// To compute dependencies of the shadow method that tracks dictionary
// dependencies we need to ensure there is code for the canonical method body.
var dependencyMethod = (ShadowConcreteMethodNode)dependency;
methodCodeNodeNeedingCode = (CppMethodCodeNode)dependencyMethod.CanonicalMethodNode;
}

// We might have already compiled this method.
if (methodCodeNodeNeedingCode.StaticDependenciesAreComputed)
continue;

_cppWriter.CompileMethod((CppMethodCodeNode)methodCodeNodeNeedingCode);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/ILCompiler.CppCodeGen/src/Compiler/CppNodeMangler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public sealed override string TypeGenericDictionary(TypeDesc type)

public sealed override string MethodGenericDictionary(MethodDesc method)
{
return GenericDictionaryNamePrefix + NameMangler.GetMangledMethodName(method);
return GenericDictionaryNamePrefix + NameMangler.GetMangledTypeName(method.OwningType) +
"_" + NameMangler.GetMangledMethodName(method);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ public CppCodegenNodeFactory(CompilerTypeSystemContext context, CompilationModul

protected override IMethodNode CreateMethodEntrypointNode(MethodDesc method)
{
if (method.IsInternalCall)
{
if (method.IsArrayAddressMethod())
{
return MethodEntrypoint(((ArrayType)method.OwningType).GetArrayMethod(ArrayMethodKind.AddressWithHiddenArg));
}
}

if (CompilationModuleGroup.ContainsMethodBody(method, false))
{
return new CppMethodCodeNode(method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFacto
foreach (Object node in _dependencies)
dependencies.Add(node, "CPP code ");

CodeBasedDependencyAlgorithm.AddDependenciesDueToMethodCodePresence(ref dependencies, factory, _method);

return dependencies;
}

Expand Down
Loading

0 comments on commit 30a641b

Please sign in to comment.