[sgen] Fix logging of major heap size with concurrent sweep
[mono.git] / mcs / tools / corcompare / Util.cs
index 6ac49d7207b9b46e78c9fb38cb746b69d49fc8cf..fa643ed20f825ae59d74f69e96dc55358e52c089 100644 (file)
@@ -30,10 +30,17 @@ namespace CorCompare {
 
                internal static bool IsDerivedFrom (TypeReference type, string derivedFrom)
                {
-                       foreach (var def in WalkHierarchy (type))
+                       bool first = true;
+                       foreach (var def in WalkHierarchy (type)) {
+                               if (first) {
+                                       first = false;
+                                       continue;
+                               }
+                               
                                if (def.FullName == derivedFrom)
                                        return true;
-
+                       }
+                       
                        return false;
                }
 
@@ -76,5 +83,112 @@ namespace CorCompare {
                {
                        return att.AttributeType.Resolve ();
                }
+
+               static bool IsOverride (MethodDefinition method)
+               {
+                       return method.IsVirtual && !method.IsNewSlot;
+               }
+
+               public static MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition method)
+               {
+                       if (!IsOverride (method))
+                               return method;
+
+                       var @base = GetBaseType (method.DeclaringType);
+                       while (@base != null) {
+                               MethodDefinition base_method = TryMatchMethod (@base.Resolve (), method);
+                               if (base_method != null)
+                                       return GetBaseMethodInTypeHierarchy (base_method) ?? base_method;
+
+                               @base = GetBaseType (@base);
+                       }
+
+                       return method;
+               }
+
+               static MethodDefinition TryMatchMethod (TypeDefinition type, MethodDefinition method)
+               {
+                       if (!type.HasMethods)
+                               return null;
+
+                       foreach (MethodDefinition candidate in type.Methods)
+                               if (MethodMatch (candidate, method))
+                                       return candidate;
+
+                       return null;
+               }
+
+               static bool MethodMatch (MethodDefinition candidate, MethodDefinition method)
+               {
+                       if (!candidate.IsVirtual)
+                               return false;
+
+                       if (candidate.Name != method.Name)
+                               return false;
+
+                       if (!TypeMatch (candidate.ReturnType, method.ReturnType))
+                               return false;
+
+                       if (candidate.Parameters.Count != method.Parameters.Count)
+                               return false;
+
+                       for (int i = 0; i < candidate.Parameters.Count; i++)
+                               if (!TypeMatch (candidate.Parameters [i].ParameterType, method.Parameters [i].ParameterType))
+                                       return false;
+
+                       return true;
+               }
+
+               public static bool TypeMatch (IModifierType a, IModifierType b)
+               {
+                       if (!TypeMatch (a.ModifierType, b.ModifierType))
+                               return false;
+
+                       return TypeMatch (a.ElementType, b.ElementType);
+               }
+
+               public static bool TypeMatch (TypeSpecification a, TypeSpecification b)
+               {
+                       if (a is GenericInstanceType)
+                               return TypeMatch ((GenericInstanceType) a, (GenericInstanceType) b);
+
+                       if (a is IModifierType)
+                               return TypeMatch ((IModifierType) a, (IModifierType) b);
+
+                       return TypeMatch (a.ElementType, b.ElementType);
+               }
+
+               public static bool TypeMatch (GenericInstanceType a, GenericInstanceType b)
+               {
+                       if (!TypeMatch (a.ElementType, b.ElementType))
+                               return false;
+
+                       if (a.GenericArguments.Count != b.GenericArguments.Count)
+                               return false;
+
+                       if (a.GenericArguments.Count == 0)
+                               return true;
+
+                       for (int i = 0; i < a.GenericArguments.Count; i++)
+                               if (!TypeMatch (a.GenericArguments [i], b.GenericArguments [i]))
+                                       return false;
+
+                       return true;
+               }
+
+               public static bool TypeMatch (TypeReference a, TypeReference b)
+               {
+                       if (a is GenericParameter)
+                               return true;
+
+                       if (a is TypeSpecification || b is TypeSpecification) {
+                               if (a.GetType () != b.GetType ())
+                                       return false;
+
+                               return TypeMatch ((TypeSpecification) a, (TypeSpecification) b);
+                       }
+
+                       return a.FullName == b.FullName;
+               }
        }
 }