Skip to content
26 changes: 23 additions & 3 deletions src/coreclr/tools/Common/Compiler/ProcessLinkerXmlBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,8 @@ protected static string GetAttribute(XPathNavigator nav, string attribute)
public static string GetMethodSignature(MethodDesc meth, bool includeGenericParameters)
{
StringBuilder sb = new StringBuilder();
CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature.ReturnType);
var formatter = new CecilTypeNameFormatter(meth);
formatter.AppendName(sb, meth.Signature.ReturnType);
sb.Append(' ');
sb.Append(meth.GetName());
if (includeGenericParameters && meth.HasInstantiation)
Expand All @@ -545,7 +546,7 @@ public static string GetMethodSignature(MethodDesc meth, bool includeGenericPara
if (i > 0)
sb.Append(',');

CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature[i]);
formatter.AppendName(sb, meth.Signature[i]);
}

sb.Append(')');
Expand All @@ -572,7 +573,14 @@ protected void LogWarning(XPathNavigator position, DiagnosticId id, params strin

private sealed class CecilTypeNameFormatter : TypeNameFormatter
{
public static readonly CecilTypeNameFormatter Instance = new CecilTypeNameFormatter();
public static readonly CecilTypeNameFormatter Instance = new CecilTypeNameFormatter(null);

private readonly MethodDesc? _method;

public CecilTypeNameFormatter(MethodDesc? method)
{
_method = method;
}

public override void AppendName(StringBuilder sb, ArrayType type)
{
Expand Down Expand Up @@ -620,9 +628,21 @@ public override void AppendName(StringBuilder sb, GenericParameterDesc type)
}
public override void AppendName(StringBuilder sb, SignatureMethodVariable type)
{
if (_method is not null &&
type.Index < _method.Instantiation.Length &&
_method.Instantiation[type.Index] is GenericParameterDesc genericParameter)
{
sb.Append(genericParameter.Name);
}
}
public override void AppendName(StringBuilder sb, SignatureTypeVariable type)
{
if (_method is not null &&
type.Index < _method.OwningType.Instantiation.Length &&
_method.OwningType.Instantiation[type.Index] is GenericParameterDesc genericParameter)
{
sb.Append(genericParameter.Name);
}
}
protected override void AppendNameForInstantiatedType(StringBuilder sb, DefType type)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;

using Internal.IL;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;

using Mono.Linker;

namespace ILCompiler.DependencyAnalysis
{
/// <summary>
Expand Down Expand Up @@ -172,6 +175,8 @@ protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
EcmaType ecmaType = (EcmaType)_module.GetObject(methodDef.GetDeclaringType());
MethodBodyNode bodyNode = writeContext.Factory.MethodBody(_module, Handle);
int bodyOffset = bodyNode.Marked
|| !writeContext.Factory.Settings.Optimizations.IsEnabled(CodeOptimizations.UnreachableBodies, _module.Assembly.GetName().Name)
|| !IsWorthConvertingToThrow(methodDef)
Comment thread
MichalStrehovsky marked this conversation as resolved.
? bodyNode.Write(writeContext)
: writeContext.WriteUnreachableMethodBody(Handle, _module);

Expand Down Expand Up @@ -201,6 +206,31 @@ protected override EntityHandle WriteInternal(ModuleWritingContext writeContext)
return outputHandle;
}

private bool IsWorthConvertingToThrow(MethodDefinition methodDef)
{
// Some bodies are cheaper size-wise to preserve as-is than to convert to a throw.
const int EmptyBodyLength = 0; // No IL body.
const int RetOnlyBodyLength = 1; // ret
const int NopRetBodyLength = 2; // nop; ret

int rva = methodDef.RelativeVirtualAddress;
if (rva == 0)
return false;

BlobReader ilReader = _module.PEReader.GetMethodBody(rva).GetILReader();
int ilLength = ilReader.Length;
if (ilLength == EmptyBodyLength)
return false;

if (ilLength == RetOnlyBodyLength)
return ilReader.ReadByte() != (byte)ILOpcode.ret;

if (ilLength == NopRetBodyLength)
return ilReader.ReadByte() != (byte)ILOpcode.nop || ilReader.ReadByte() != (byte)ILOpcode.ret;

return true;
}

public override string ToString()
{
// TODO: would be nice to have a common formatter we can call into that also includes owning type
Expand Down
13 changes: 0 additions & 13 deletions src/coreclr/tools/ILTrim.Tests/ILTrimExpectedFailures.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ DataFlow.GenericParameterDataFlowMarking
DataFlow.GenericParameterWarningLocation
DataFlow.InterfaceImplementedThroughBaseValidation
DataFlow.IReflectDataflow
DataFlow.LocalDataFlowKeptMembers
DataFlow.MemberTypes
DataFlow.MemberTypesAllOnCopyAssembly
DataFlow.MethodParametersDataFlow
Expand Down Expand Up @@ -174,9 +173,7 @@ Generics.VariantCasting
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.CanDisableOverrideRemoval
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.OverrideOfAbstractIsKept
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.OverrideOfAbstractIsKeptNonEmpty
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.OverrideOfVirtualCanBeRemoved
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.OverrideOfVirtualCanBeRemoved2
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.OverrideOfVirtualCanBeRemoved3
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.OverrideThatAlsoFulfilsInterface
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved
Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval.PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved2
Expand Down Expand Up @@ -229,7 +226,6 @@ Inheritance.Interfaces.OnReferenceType.NoKeptCtor.LocalDowncastDoesNotCuaseOther
Inheritance.Interfaces.OnReferenceType.NoKeptCtor.PreserveDependencyPreservesInterfaceMethod
Inheritance.Interfaces.OnReferenceType.NoKeptCtor.UnusedTypeHasExplicitInterfaceMethodPreservedViaXml
Inheritance.Interfaces.OnReferenceType.NoKeptCtor.UnusedTypeHasExplicitInterfacePropertyPreservedViaXml
Inheritance.Interfaces.OnReferenceType.NoKeptCtor.UnusedTypeHasInterfaceMethodPreservedViaXml
Inheritance.Interfaces.OnReferenceType.NoKeptCtor.UnusedTypeWithPreserveMethodsAndInterfaceTypeMarked
Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeeded.ArrayWithIndexAssignedToReturnValue
Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeeded.FieldDowncastedToInterface
Expand Down Expand Up @@ -324,10 +320,7 @@ LinkXml.EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod
LinkXml.LinkXmlErrorCases
LinkXml.UnusedFieldPreservedByLinkXmlIsKept
LinkXml.UnusedInterfaceTypeOnTypeWithPreserveAllIsKept
LinkXml.UnusedMethodPreservedByLinkXmlIsKept
LinkXml.UnusedNonRequiredTypeIsRemoved
LinkXml.UnusedTypeWithPreserveFieldsHasMethodsRemoved
LinkXml.UnusedTypeWithPreserveNothingAndPreserveMembers
LinkXml.UsedNonRequiredExportedTypeIsKept
LinkXml.UsedNonRequiredExportedTypeIsKeptWhenRooted
LinkXml.UsedNonRequiredTypeIsKeptWithSingleMethod
Expand Down Expand Up @@ -370,17 +363,13 @@ Reflection.AssemblyImportedViaReflectionWithDerivedType
Reflection.CoreLibMessages
Reflection.EventHanderTypeGetInvokeMethod
Reflection.EventsUsedViaReflection
Reflection.ExpressionCallString
Reflection.IsAssignableFrom
Reflection.MethodsUsedViaReflection
Reflection.MethodUsedViaReflection
Reflection.ObjectGetType
Reflection.ObjectGetTypeLibraryMode
Reflection.ParametersUsedViaReflection
Reflection.PropertiesUsedViaReflection
Reflection.PropertyUsedViaReflection
Reflection.RunClassConstructor
Reflection.RuntimeReflectionExtensionsCalls
Reflection.TypeHierarchyLibraryModeSuppressions
Reflection.TypeHierarchyReflectionWarnings
Reflection.TypeMap
Expand All @@ -392,7 +381,6 @@ RequiresCapability.ReflectionAccessFromCompilerGeneratedCode
RequiresCapability.RequiresAccessedThrough
RequiresCapability.RequiresAttributeMismatch
RequiresCapability.RequiresCapabilityFromCopiedAssembly
RequiresCapability.RequiresCapabilityReflectionAnalysisEnabled
RequiresCapability.RequiresExcludeStatics
RequiresCapability.RequiresInCompilerGeneratedCode
RequiresCapability.RequiresInCompilerGeneratedCodeRelease
Expand Down Expand Up @@ -506,7 +494,6 @@ UnreachableBody.ExplicitInstructionCheck
UnreachableBody.InterfaceMethod
UnreachableBody.LinkedOtherIncludedLibrary
UnreachableBody.LinkedOtherIncludedLibraryNoInstanceCtor
UnreachableBody.NotWorthConvertingEmpty
UnreachableBody.NotWorthConvertingReturnDouble
UnreachableBody.NotWorthConvertingReturnFalse
UnreachableBody.NotWorthConvertingReturnFloat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ private void NotPreservedMethod()
{
}

// NativeAOT fails to translate Cecil generic methods
// https://github.com/dotnet/runtime/issues/80462
[Kept(By = Tool.Trimmer)]
[Kept]
private void PreservedMethod5<T>(T arg)
{
}
Expand Down
Loading