private void NoteGenericParameterFlow(ITypeDefinition actual, IGenericParameter formal) { if (createInstanceStrategy == TypeVariableCreateInstanceStrategy.ConstructAllConcreteParameters) { if (!(actual is IGenericParameter)) { // actual is concrete ITypeDefinition unspecializedConcreteType = GarbageCollectHelper.UnspecializeAndResolveTypeReference(actual); unspecializedTypesPassedAsTypeVariables.Add(unspecializedConcreteType); if (GarbageCollectHelper.TypeIsConstructable(unspecializedConcreteType)) { // t-devinc: We should associate a reason with this construction found ConstructionFound(unspecializedConcreteType); IMethodDefinition defaultConstructor = TypeHelper.GetMethod(unspecializedConcreteType, wholeProgram.Host().NameTable.GetNameFor(".ctor")); if (!(defaultConstructor is Dummy)) { // t-devinc: Add reason for this NotePotentialNonVirtualMethodReachedForReason(defaultConstructor, null); } } } } }
private void TypeUseFound(ITypeDefinition t) { Contract.Requires(t != null); Contract.Requires(!(t is Dummy)); Contract.Requires(GarbageCollectHelper.UnspecializeAndResolveTypeReference(t) == t); Contract.Ensures(this.types.Contains(t)); if (this.types.Contains(t)) { return; } // add all base classes of this class foreach (var baseclass in GarbageCollectHelper.BaseClasses(t)) { this.TypeUseFound(GarbageCollectHelper.UnspecializeAndResolveTypeReference(baseclass)); } this.types.Add(t); // add static constructor to worklist var cctor = GarbageCollectHelper.GetStaticConstructor(this.wholeProgram.Host().NameTable, t); if (!(cctor is Dummy)) { this.AddToWorklist(GarbageCollectHelper.UnspecializeAndResolveMethodReference(cctor)); } }
/// <summary> /// Find possible implementations of m for derived, upto (and including) 'upto'). /// /// If m is an unspecialized generic interface, they may be multiple possible implementations; at this /// point we can't tell which one would be called since we've removed all specialization from m. /// /// We require 'derived' to be unspecialized, but note that its super types may be specialized. /// We require 'm' to be unspecialized. /// /// </summary> internal static ICollection <IMethodDefinition> Implements(ITypeDefinition derived, ITypeDefinition upto, IMethodDefinition m) { Contract.Requires(derived != null); Contract.Requires(!(derived is Dummy)); Contract.Requires(upto != null); Contract.Requires(!(upto is Dummy)); Contract.Requires(m != null); Contract.Requires(!(m is Dummy)); Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(derived)); Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(m)); Contract.Requires(!derived.IsInterface); Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM => GarbageCollectHelper.MethodDefinitionIsUnspecialized(resultM))); Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM => resultM != null && !(resultM is Dummy)) ); ISet <IMethodDefinition> foundImplementations = new HashSet <IMethodDefinition>(); // If derived implements an interface multiple times, there may be multiple specialized versions for derived IEnumerable <IMethodDefinition> versionsOfMSpecializedForDerived = SearchSpecializedHierarchyForVersionOfMethod(derived, m); var classHierarchyChain = new ITypeDefinition[] { derived }.Concat(GarbageCollectHelper.AllSuperClasses(derived)); foreach (IMethodDefinition mSpecializedForDerived in versionsOfMSpecializedForDerived) { // Check explicit implementation overrides before implicit methods IMethodDefinition foundImplementation = null; foreach (var classInHierarchy in classHierarchyChain) { IMethodDefinition specializedImplementation = ImplementationForMethodInClass(mSpecializedForDerived, classInHierarchy); if (specializedImplementation != null) { foundImplementation = specializedImplementation; break; } if (TypeHelper.TypesAreEquivalent(GarbageCollectHelper.UnspecializeAndResolveTypeReference(classInHierarchy), upto)) { break; } } // Do we really expect to find an implementation for EACH mSpecializedForDerived; or do we expect to find at least one overall all? Contract.Assert(foundImplementation != null); foundImplementations.Add(GarbageCollectHelper.UnspecializeAndResolveMethodReference(foundImplementation)); } return(foundImplementations); }
public void ProcessSummary(ReachabilitySummary summary, IMethodDefinition summarizedMethod) { Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(summarizedMethod)); foreach (IMethodDefinition nonvirtuallyCalledMethod in summary.NonvirtuallyCalledMethods) { NoteGenericParameterFlowForMethod(nonvirtuallyCalledMethod); IMethodDefinition unspecializedMethod = GarbageCollectHelper.UnspecializeAndResolveMethodReference(nonvirtuallyCalledMethod); analysisReasons.NoteNonVirtualDispatchReachableForReason(nonvirtuallyCalledMethod, analysisReasons.DispatchReachedBecauseContainingMethodWasReached(summarizedMethod)); if (nonvirtualDispatches.Add(unspecializedMethod)) { MethodReachedReason reason = analysisReasons.MethodReachedByDispatchAgainstNonVirtualMethod(unspecializedMethod); NotePotentialNonVirtualMethodReachedForReason(unspecializedMethod, reason); } } foreach (IMethodDefinition virtuallyCalledMethod in summary.VirtuallyCalledMethods) { NoteGenericParameterFlowForMethod(virtuallyCalledMethod); IMethodDefinition unspecializedMethod = GarbageCollectHelper.UnspecializeAndResolveMethodReference(virtuallyCalledMethod); analysisReasons.NoteVirtualDispatchReachableForReason(unspecializedMethod, analysisReasons.DispatchReachedBecauseContainingMethodWasReached(summarizedMethod)); NoteVirtualDispatch(unspecializedMethod); } foreach (ITypeDefinition reachableType in summary.ReachableTypes) { TypeUseFound(GarbageCollectHelper.UnspecializeAndResolveTypeReference(reachableType)); } foreach (ITypeDefinition constructedType in summary.ConstructedTypes) { ITypeDefinition unspecializedConstructedType = GarbageCollectHelper.UnspecializeAndResolveTypeReference(constructedType); ConstructionFoundWithReason(unspecializedConstructedType, analysisReasons.TypeConstructedBecauseAllocatingMethodReached(summarizedMethod)); } foreach (IFieldDefinition reachableField in summary.ReachableFields) { fields.Add(GarbageCollectHelper.UnspecializeAndResolveFieldReference(reachableField)); } foreach (IGenericParameter genericParameter in summary.ConstructedTypeParameters) { NoteTypeVariableConstructed(genericParameter); } unresolvedReferences.UnionWith(summary.UnresolvedReferences); }
private void NotePotentialNonVirtualMethodReachedForReason(IMethodDefinition targetMethodDefinition, MethodReachedReason reason) { Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(targetMethodDefinition)); this.TypeUseFound(GarbageCollectHelper.UnspecializeAndResolveTypeReference(targetMethodDefinition.ContainingTypeDefinition)); this.AddToWorklist(GarbageCollectHelper.UnspecializeAndResolveMethodReference(targetMethodDefinition)); // Really should a precondition requiring reason to not be null, // but for now there are some situations where we still don't // create reasons, so they pass null as a cop out. if (reason != null) { analysisReasons.NoteMethodReachableForReason(targetMethodDefinition, reason); } }
private void ConstructionFound(ITypeDefinition t) { Contract.Requires(t != null); Contract.Requires(!(t is Dummy)); Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(t)); Contract.Requires(GarbageCollectHelper.TypeIsConstructable(t)); Contract.Ensures(this.constructed.Contains(t)); //Console.WriteLine("Found construction of {0}", t); if (this.constructed.Contains(t)) { return; } this.constructed.Add(t); // t-devinc: should change AllSuperTypes, etc. to include t foreach (var baseclass in new ITypeDefinition[] { t }.Concat(GarbageCollectHelper.AllSuperTypes(t))) { ITypeDefinition unspecializedBaseClass = GarbageCollectHelper.UnspecializeAndResolveTypeReference(baseclass); foreach (var m in unspecializedBaseClass.Methods) { if (m.IsVirtual && VirtualMethodIsInDemand(m)) { ICollection <IMethodDefinition> implementationsOfMForT = GarbageCollectHelper.Implements(t, unspecializedBaseClass, m); Contract.Assert(implementationsOfMForT.Count() > 0); foreach (IMethodDefinition mprime in implementationsOfMForT) { NoteDispatch(m, GarbageCollectHelper.UnspecializeAndResolveMethodReference(mprime), t); } } } } // If a type is constructed then its Finalize method may be called ICollection <IMethodDefinition> implementationsOfFinalizeForT = GarbageCollectHelper.Implements(t, systemObjectType, systemObjectFinalizeMethod); Contract.Assert(implementationsOfFinalizeForT.Count() == 1); // t-devinc: Need to to add reason for this this.AddToWorklist(GarbageCollectHelper.UnspecializeAndResolveMethodReference(implementationsOfFinalizeForT.First())); }
/// <summary> /// Find possible implementations of m for derived, upto (and including) 'upto'). /// /// If m is an unspecialized generic interface, they may be multiple possible implementations; at this /// point we can't tell which one would be called since we've removed all specialization from m. /// /// We require 'derived' to be unspecialized, but note that its super types may be specialized. /// We require 'm' to be unspecialized. /// /// </summary> internal static ICollection <IMethodDefinition> Implements(ITypeDefinition derived, ITypeDefinition upto, IMethodDefinition m) { Contract.Requires(derived != null); Contract.Requires(!(derived is Dummy)); Contract.Requires(upto != null); Contract.Requires(!(upto is Dummy)); Contract.Requires(m != null); Contract.Requires(!(m is Dummy)); Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(derived)); Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(m)); Contract.Requires(!derived.IsInterface); Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM => GarbageCollectHelper.MethodDefinitionIsUnspecialized(resultM))); Contract.Ensures(Contract.ForAll(Contract.Result <ICollection <IMethodDefinition> >(), resultM => resultM != null && !(resultM is Dummy)) ); ISet <IMethodDefinition> foundImplementations = new HashSet <IMethodDefinition>(); // If derived implements an interface multiple times, there may be multiple specialized versions for derived IEnumerable <IMethodDefinition> versionsOfMSpecializedForDerived = SearchSpecializedHierarchyForVersionOfMethod(derived, m); var classHierarchyChain = new ITypeDefinition[] { derived }.Concat(GarbageCollectHelper.AllSuperClasses(derived)); foreach (IMethodDefinition mSpecializedForDerived in versionsOfMSpecializedForDerived) { IMethodDefinition foundImplementation = null; // If this is a method defined on an inteface, we must first search the hierarchy for explicit implementations, // since an explicit implementation on a base type supercedes an implicit implementation on a derived type if (m.ContainingTypeDefinition.IsInterface) { foreach (var classInHierarchy in classHierarchyChain) { foreach (IMethodImplementation methodImplementation in classInHierarchy.ExplicitImplementationOverrides) { if (methodImplementation.ImplementedMethod.InternedKey == mSpecializedForDerived.InternedKey) { foundImplementation = methodImplementation.ImplementingMethod.ResolvedMethod; break; } } if (foundImplementation != null) { break; } if (TypeHelper.TypesAreEquivalent(GarbageCollectHelper.UnspecializeAndResolveTypeReference(classInHierarchy), upto)) { break; } } } // If we found an explicit implementation, don't seach for an implicit one if (foundImplementation == null) { foreach (var classInHierarchy in classHierarchyChain) { foundImplementation = ImplementationForMethodInClass(mSpecializedForDerived, classInHierarchy); if (foundImplementation != null) { break; } if (TypeHelper.TypesAreEquivalent(GarbageCollectHelper.UnspecializeAndResolveTypeReference(classInHierarchy), upto)) { break; } } } // Do we really expect to find an implementation for EACH mSpecializedForDerived; or do we expect to find at least one overall all? Contract.Assert(foundImplementation != null); foundImplementations.Add(GarbageCollectHelper.UnspecializeAndResolveMethodReference(foundImplementation)); } return(foundImplementations); }