bool IsVirtualAndHasPreservedParent(MethodDefinition method) { if (!method.IsVirtual) { return(false); } var base_list = Annotations.GetBaseMethods(method); if (base_list == null) { return(false); } foreach (MethodDefinition @base in base_list) { if (IgnoreScope(@base.DeclaringType.Scope)) { return(true); } if (IsVirtualAndHasPreservedParent(@base)) { return(true); } } return(false); }
void PrintMap(TypeDefinition type) { if (!type.HasMethods) { return; } Console.WriteLine("Type {0} map", type); foreach (MethodDefinition method in type.Methods) { if (!method.IsVirtual) { continue; } Console.WriteLine(" Method {0} map", method); IEnumerable <MethodDefinition> overrides = Annotations.GetOverrides(method); foreach (var @override in overrides ?? new MethodDefinition[0]) { Console.WriteLine(" HasOverride {0}", @override); } IEnumerable <MethodDefinition> bases = Annotations.GetBaseMethods(method); foreach (var @base in bases ?? new MethodDefinition[0]) { Console.WriteLine(" Base {0}", @base); } } }
void MarkBaseMethods(MethodDefinition method) { IList base_methods = Annotations.GetBaseMethods(method); if (base_methods == null) { return; } foreach (MethodDefinition base_method in base_methods) { MarkMethod(base_method); MarkBaseMethods(base_method); } }
void MarkBaseMethods(MethodDefinition method) { IList base_methods = Annotations.GetBaseMethods(method); if (base_methods == null) { return; } foreach (MethodDefinition base_method in base_methods) { // Console.WriteLine ("Marking method {0}.{1} as base method of {1}.{2}", base_method.DeclaringType.FullName, base_method.Name, method.DeclaringType.FullName, method.Name); MarkMethod(base_method); MarkBaseMethods(base_method); } }
void ProcessMethods(TypeDefinition type, List <ExportedMethod> exported) { foreach (MethodDefinition method in type.GetMethods()) { CustomAttribute attribute; if (TryGetExportAttribute(method, out attribute)) { exported.Add(new ExportedMethod(attribute, method)); continue; } if (!method.IsVirtual) { continue; } var bases = Annotations.GetBaseMethods(method); if (bases == null) { continue; } foreach (MethodDefinition @base in bases) { if (@base.DeclaringType.IsInterface) { continue; } if (TryGetExportAttribute(@base, out attribute)) { exported.Add(new ExportedMethod(attribute, method)); break; } } } }
void ProcessType(TypeDefinition type) { if (type.HasNestedTypes) { foreach (var nt in type.NestedTypes) { ProcessType(nt); } } // // interface members are virtual (and we cannot change this) // if (type.IsInterface) { return; } // // the code does not include any subclass for this type // if (!type.IsAbstract && !type.IsSealed && !IsSubclassed(type)) { SealType(type); } if (!type.HasMethods) { return; } // process methods to see if we can seal or devirtualize them foreach (var method in type.Methods) { if (method.IsFinal || !method.IsVirtual || method.IsAbstract || method.IsRuntime) { continue; } Debug.Assert(Annotations.IsMarked(method)); if (!Annotations.IsMarked(method)) { continue; } var overrides = Annotations.GetOverrides(method); // // cannot de-virtualize nor seal methods if something overrides them // if (IsAnyMarked(overrides)) { continue; } SealMethod(method); // subclasses might need this method to satisfy an interface requirement // and requires dispatch/virtual support if (!type.IsSealed) { continue; } var bases = Annotations.GetBaseMethods(method); // Devirtualize if a method is not override to existing marked methods if (!IsAnyMarked(bases)) { method.IsVirtual = method.IsFinal = method.IsNewSlot = false; } } }
protected override void Process(TypeDefinition type) { // interface members are virtual (and we cannot change this) // we cannot seal interfaces either if (type.IsInterface) { return; } // only optimize code that was marked earlier (the rest will be swept away) if (!Annotations.IsMarked(type)) { return; } // if we do not include any subclass for this type if (!type.IsAbstract && !type.IsSealed && !IsSubclassed(type)) { type.IsSealed = true; #if DEBUG Console.WriteLine("Seal {0} ({1})", type, ++seal); #endif } if (!type.HasMethods) { return; } // process virtual methods to see if we can "seal" or devirtualize them foreach (var method in type.Methods) { if (method.IsFinal || !method.IsVirtual || method.IsAbstract || method.IsRuntime) { continue; } if (!Annotations.IsMarked(method)) { continue; } var overrides = Annotations.GetOverrides(method); // we cannot de-virtualize nor seal methods if something overrides them if (overrides != null) { // sanity (disable IsSealed == true above) //if (type.IsSealed) // Console.WriteLine (); continue; } // we can seal the method (final in IL / !virtual in C#) method.IsFinal = true; #if DEBUG Console.WriteLine("Final {0} ({1})", method, ++final); #endif // subclasses might need this method to satisfy an interface requirement // and requires dispatch/virtual support if (!type.IsSealed) { continue; } var bases = Annotations.GetBaseMethods(method); // look if this method is an override to existing _marked_ methods if (!AreMarked(bases)) { method.IsVirtual = false; #if DEBUG Console.WriteLine("Devirtualize {0} ({1})", method, ++devirtualize); #endif } } }