Skip to content

Commit

Permalink
Delete GetClassHierarchy/GetDerivedInterfacesForInterface (#1186)
Browse files Browse the repository at this point in the history
This removes the easily removable parts of the TypeMap step. Contributes to #1164.
  • Loading branch information
MichalStrehovsky authored May 14, 2020
1 parent 6d85654 commit e9f0009
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 96 deletions.
33 changes: 21 additions & 12 deletions src/linker/Linker.Steps/MarkStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -485,18 +485,8 @@ bool IsInterfaceOverrideThatDoesNotNeedMarked (OverrideInformation overrideInfor
var interfaceType = overrideInformation.InterfaceType;
var overrideDeclaringType = overrideInformation.Override.DeclaringType;

if (!IsInterfaceImplementationMarked (overrideDeclaringType, interfaceType)) {
var derivedInterfaceTypes = Annotations.GetDerivedInterfacesForInterface (interfaceType);

// There are no derived interface types that could be marked, it's safe to skip marking this override
if (derivedInterfaceTypes == null)
return true;

// If none of the other interfaces on the type that implement the interface from the @base type are marked, then it's safe to skip
// marking this override
if (!derivedInterfaceTypes.Any (d => IsInterfaceImplementationMarked (overrideDeclaringType, d)))
return true;
}
if (!IsInterfaceImplementationMarkedRecursively (overrideDeclaringType, interfaceType))
return true;

return false;
}
Expand All @@ -506,6 +496,25 @@ bool IsInterfaceImplementationMarked (TypeDefinition type, TypeDefinition interf
return type.HasInterface (@interfaceType, out InterfaceImplementation implementation) && Annotations.IsMarked (implementation);
}

bool IsInterfaceImplementationMarkedRecursively (TypeDefinition type, TypeDefinition interfaceType)
{
if (IsInterfaceImplementationMarked (type, interfaceType))
return true;

if (type.HasInterfaces) {
foreach (var iface in type.Interfaces) {
var resolved = iface.InterfaceType.Resolve ();
if (resolved == null)
continue;

if (IsInterfaceImplementationMarkedRecursively (resolved, interfaceType))
return true;
}
}

return false;
}

void MarkMarshalSpec (IMarshalInfoProvider spec, in DependencyInfo reason)
{
if (!spec.HasMarshalInfo)
Expand Down
40 changes: 0 additions & 40 deletions src/linker/Linker.Steps/TypeMapStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ protected virtual void MapType (TypeDefinition type)
{
MapVirtualMethods (type);
MapInterfaceMethodsInTypeHierarchy (type);
MapInterfaceHierarchy (type);
MapBaseTypeHierarchy (type);

if (!type.HasNestedTypes)
return;
Expand All @@ -55,20 +53,6 @@ protected virtual void MapType (TypeDefinition type)
MapType (nested);
}

void MapInterfaceHierarchy (TypeDefinition type)
{
if (!type.IsInterface || !type.HasInterfaces)
return;

foreach (var iface in type.Interfaces) {
var resolved = iface.InterfaceType.Resolve ();
if (resolved == null)
continue;

Annotations.AddDerivedInterfaceForInterface (resolved, type);
}
}

void MapInterfaceMethodsInTypeHierarchy (TypeDefinition type)
{
if (!type.HasInterfaces)
Expand Down Expand Up @@ -167,30 +151,6 @@ void MapOverrides (MethodDefinition method)
}
}

void MapBaseTypeHierarchy (TypeDefinition type)
{
if (!type.IsClass)
return;

var bases = new List<TypeDefinition> ();
var current = type.BaseType;

while (current != null) {
var resolved = current.Resolve ();
if (resolved == null)
break;

// Exclude Object. That's implied and adding it to the list will just lead to lots of extra unnecessary processing
if (resolved.BaseType == null)
break;

bases.Add (resolved);
current = resolved.BaseType;
}

Annotations.SetClassHierarchy (type, bases);
}

void AnnotateMethods (MethodDefinition @base, MethodDefinition @override, InterfaceImplementation matchingInterfaceImplementation = null)
{
Annotations.AddBaseMethod (@override, @base);
Expand Down
40 changes: 0 additions & 40 deletions src/linker/Linker/Annotations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ public partial class AnnotationStore
protected readonly Dictionary<MethodDefinition, List<OverrideInformation>> override_methods = new Dictionary<MethodDefinition, List<OverrideInformation>> ();
protected readonly Dictionary<MethodDefinition, List<MethodDefinition>> base_methods = new Dictionary<MethodDefinition, List<MethodDefinition>> ();
protected readonly Dictionary<AssemblyDefinition, ISymbolReader> symbol_readers = new Dictionary<AssemblyDefinition, ISymbolReader> ();
protected readonly Dictionary<TypeDefinition, List<TypeDefinition>> class_type_base_hierarchy = new Dictionary<TypeDefinition, List<TypeDefinition>> ();
protected readonly Dictionary<TypeDefinition, List<TypeDefinition>> derived_interfaces = new Dictionary<TypeDefinition, List<TypeDefinition>> ();

readonly Dictionary<object, Dictionary<IMetadataTokenProvider, object>> custom_annotations = new Dictionary<object, Dictionary<IMetadataTokenProvider, object>> ();
protected readonly Dictionary<AssemblyDefinition, HashSet<string>> resources_to_remove = new Dictionary<AssemblyDefinition, HashSet<string>> ();
Expand Down Expand Up @@ -428,43 +426,5 @@ public bool SetPreservedStaticCtor (TypeDefinition type)
{
return marked_types_with_cctor.Add (type);
}

public void SetClassHierarchy (TypeDefinition type, List<TypeDefinition> bases)
{
class_type_base_hierarchy[type] = bases;
}

public List<TypeDefinition> GetClassHierarchy (TypeDefinition type)
{
if (class_type_base_hierarchy.TryGetValue (type, out List<TypeDefinition> bases))
return bases;

return null;
}

public void AddDerivedInterfaceForInterface (TypeDefinition @base, TypeDefinition derived)
{
if (!@base.IsInterface)
throw new ArgumentException ($"{nameof (@base)} must be an interface");

if (!derived.IsInterface)
throw new ArgumentException ($"{nameof (derived)} must be an interface");

if (!derived_interfaces.TryGetValue (@base, out List<TypeDefinition> derivedInterfaces))
derived_interfaces[@base] = derivedInterfaces = new List<TypeDefinition> ();

derivedInterfaces.Add (derived);
}

public List<TypeDefinition> GetDerivedInterfacesForInterface (TypeDefinition @interface)
{
if (!@interface.IsInterface)
throw new ArgumentException ($"{nameof (@interface)} must be an interface");

if (derived_interfaces.TryGetValue (@interface, out List<TypeDefinition> derivedInterfaces))
return derivedInterfaces;

return null;
}
}
}
12 changes: 8 additions & 4 deletions src/linker/Linker/MethodBodyScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ public static bool IsWorthConvertingToThrow (MethodBody body)
if (!type.IsClass)
continue;

AddMatchingInterfaces (interfaceImplementations, type, interfaceTypes);
var bases = annotations.GetClassHierarchy (type);
foreach (var @base in bases) {
AddMatchingInterfaces (interfaceImplementations, @base, interfaceTypes);
TypeDefinition currentType = type;
while (currentType?.BaseType != null) // Checking BaseType != null to skip System.Object
{
AddMatchingInterfaces (interfaceImplementations, currentType, interfaceTypes);
currentType = currentType.BaseType.Resolve ();
}
}

Expand Down Expand Up @@ -130,6 +131,9 @@ static HashSet<TypeDefinition> AllPossibleStackTypes (MethodDefinition method)

static void AddMatchingInterfaces (HashSet<(InterfaceImplementation, TypeDefinition)> results, TypeDefinition type, TypeDefinition[] interfaceTypes)
{
if (!type.HasInterfaces)
return;

foreach (var interfaceType in interfaceTypes) {
if (type.HasInterface (interfaceType, out InterfaceImplementation implementation))
results.Add ((implementation, type));
Expand Down

0 comments on commit e9f0009

Please sign in to comment.