From bf1ec3c7113cff60f55694737ee1c4f2c7322edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Wed, 13 May 2020 14:51:48 +0200 Subject: [PATCH] Delete GetClassHierarchy/GetDerivedInterfacesForInterface This removes the easily removable parts of the TypeMap step. Contributes to #1164. --- src/linker/Linker.Steps/MarkStep.cs | 33 +++++++++++++-------- src/linker/Linker.Steps/TypeMapStep.cs | 40 -------------------------- src/linker/Linker/Annotations.cs | 40 -------------------------- src/linker/Linker/MethodBodyScanner.cs | 12 +++++--- 4 files changed, 29 insertions(+), 96 deletions(-) diff --git a/src/linker/Linker.Steps/MarkStep.cs b/src/linker/Linker.Steps/MarkStep.cs index 96af89382b1b..1d57a562ad81 100644 --- a/src/linker/Linker.Steps/MarkStep.cs +++ b/src/linker/Linker.Steps/MarkStep.cs @@ -479,18 +479,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; } @@ -500,6 +490,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) diff --git a/src/linker/Linker.Steps/TypeMapStep.cs b/src/linker/Linker.Steps/TypeMapStep.cs index 1038753a71a6..71784658b37c 100644 --- a/src/linker/Linker.Steps/TypeMapStep.cs +++ b/src/linker/Linker.Steps/TypeMapStep.cs @@ -45,8 +45,6 @@ protected virtual void MapType (TypeDefinition type) { MapVirtualMethods (type); MapInterfaceMethodsInTypeHierarchy (type); - MapInterfaceHierarchy (type); - MapBaseTypeHierarchy (type); if (!type.HasNestedTypes) return; @@ -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) @@ -167,30 +151,6 @@ void MapOverrides (MethodDefinition method) } } - void MapBaseTypeHierarchy (TypeDefinition type) - { - if (!type.IsClass) - return; - - var bases = new List (); - 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); diff --git a/src/linker/Linker/Annotations.cs b/src/linker/Linker/Annotations.cs index 9e305cac66e7..203a0340ad8a 100644 --- a/src/linker/Linker/Annotations.cs +++ b/src/linker/Linker/Annotations.cs @@ -54,8 +54,6 @@ public partial class AnnotationStore protected readonly Dictionary> override_methods = new Dictionary> (); protected readonly Dictionary> base_methods = new Dictionary> (); protected readonly Dictionary symbol_readers = new Dictionary (); - protected readonly Dictionary> class_type_base_hierarchy = new Dictionary> (); - protected readonly Dictionary> derived_interfaces = new Dictionary> (); readonly Dictionary> custom_annotations = new Dictionary> (); protected readonly Dictionary> resources_to_remove = new Dictionary> (); @@ -428,43 +426,5 @@ public bool SetPreservedStaticCtor (TypeDefinition type) { return marked_types_with_cctor.Add (type); } - - public void SetClassHierarchy (TypeDefinition type, List bases) - { - class_type_base_hierarchy[type] = bases; - } - - public List GetClassHierarchy (TypeDefinition type) - { - if (class_type_base_hierarchy.TryGetValue (type, out List 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 derivedInterfaces)) - derived_interfaces[@base] = derivedInterfaces = new List (); - - derivedInterfaces.Add (derived); - } - - public List GetDerivedInterfacesForInterface (TypeDefinition @interface) - { - if (!@interface.IsInterface) - throw new ArgumentException ($"{nameof (@interface)} must be an interface"); - - if (derived_interfaces.TryGetValue (@interface, out List derivedInterfaces)) - return derivedInterfaces; - - return null; - } } } diff --git a/src/linker/Linker/MethodBodyScanner.cs b/src/linker/Linker/MethodBodyScanner.cs index 7eb10ef44192..e79426db1fc1 100644 --- a/src/linker/Linker/MethodBodyScanner.cs +++ b/src/linker/Linker/MethodBodyScanner.cs @@ -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 (); } } @@ -130,6 +131,9 @@ static HashSet 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));