Esempio n. 1
0
        public bool VirtualMethodIsInDemand(IMethodDefinition methodDefinition)
        {
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(methodDefinition));
            Contract.Requires(methodDefinition.IsVirtual);

            return(runtimeTargetsByDispatch.ContainsKey(methodDefinition));
        }
Esempio n. 2
0
        // Called when the first new T() is detected.
        // This method is where we add worst-case-scenario
        // constructed types for those stategies.

        // t-devinc: Now that we don't do construct reachable types
        // this maybe doesn't make sense.
        private void NoteFirstTypeVariableConstructed()
        {
            IEnumerable <ITypeDefinition> potentialUniverse;

            switch (createInstanceStrategy)
            {
            case TypeVariableCreateInstanceStrategy.ConstructAll:
                potentialUniverse = wholeProgram.AllDefinedTypes();
                break;

            default:
                // do nothing
                potentialUniverse = new HashSet <ITypeDefinition>();
                break;
            }

            foreach (ITypeDefinition t in potentialUniverse)
            {
                if (GarbageCollectHelper.TypeIsConstructable(t))
                {
                    ConstructionFound(t);
                    // t-devinc: We should associate a reason with this!
                }
            }
        }
Esempio n. 3
0
        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);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        public bool MethodIsReachable(IMethodDefinition method)
        {
            Contract.Requires(!method.IsAbstract);
            Contract.Assert(GarbageCollectHelper.MethodDefinitionIsUnspecialized(method));

            return(methods.Contains(method));
        }
Esempio n. 5
0
        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));
            }
        }
Esempio n. 6
0
        /// <summary>
        /// A version of Implements that works over instantiated types and methods.
        ///
        /// t-devinc: Not entirely convinced this is correct.
        /// </summary>
        /// <param name="derived"></param>
        /// <param name="upto"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        internal static IMethodDefinition ImplementsInstantiated(ITypeDefinition derived, IMethodDefinition m)
        {
            Contract.Requires(derived != null);
            Contract.Requires(!(derived is Dummy));
            Contract.Requires(m != null);
            Contract.Requires(!(m is Dummy));

            Contract.Requires(TypeHelper.Type1DerivesFromOrIsTheSameAsType2(derived, m.ContainingTypeDefinition));

            Contract.Requires(!derived.IsInterface);

            Contract.Ensures(Contract.Result <IMethodDefinition>() != null);
            Contract.Ensures(!(Contract.Result <IMethodDefinition>() is Dummy));

            var classHierarchyChain = new ITypeDefinition[] { derived }.Concat(GarbageCollectHelper.AllSuperClasses(derived));

            foreach (var classInHierarchy in classHierarchyChain)
            {
                IMethodDefinition specializedImplementation = ImplementationForMethodInClass(m, classInHierarchy);

                if (specializedImplementation != null)
                {
                    return(specializedImplementation);
                }
            }

            // We shouldn't get here
            return(null);
        }
Esempio n. 7
0
        private bool VirtualMethodIsInDemand(IMethodDefinition virtualMethod)
        {
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(virtualMethod));
            Contract.Requires(virtualMethod.IsVirtual);

            return(virtualCallsInDemand.VirtualMethodIsInDemand(virtualMethod));
        }
Esempio n. 8
0
        private void MarkMethodAsReachable(IMethodDefinition method)
        {
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(method));
            Contract.Requires(!method.IsAbstract);

            Contract.Ensures(methods.Contains(method));

            methods.Add(method);
        }
Esempio n. 9
0
        public bool NoteVirtualMethodMayDispatchToMethod(IMethodDefinition compileTimeMethod, IMethodDefinition runtimeTarget)
        {
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(compileTimeMethod));
            Contract.Requires(compileTimeMethod.IsVirtual);

            NoteDispatchIsInDemand(compileTimeMethod);

            return(runtimeTargetsByDispatch[compileTimeMethod].Add(runtimeTarget));
        }
Esempio n. 10
0
        /// <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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        private static bool AssemblyShouldBeRewritten(IAssembly assembly)
        {
            // Fragile

            if (GarbageCollectHelper.AssemblyMayBeSystemOrFramework(assembly))
            {
                return(false);
            }

            return(true);
        }
Esempio n. 13
0
        // For debugging purposes only
        internal static bool MethodDefinitionHasName(IMethodDefinition methodDefinition, string className, string methodName)
        {
            IMethodDefinition unspecializedMethodDefinition = GarbageCollectHelper.UnspecializeAndResolveMethodReference(methodDefinition);

            if (unspecializedMethodDefinition.Name.Value.Equals(methodName))
            {
                INamedTypeDefinition containingType = unspecializedMethodDefinition.ContainingTypeDefinition as INamedTypeDefinition;

                if (containingType != null && containingType.Name.Value.Equals(className))
                {
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 14
0
        public void NoteDispatchIsInDemand(IMethodDefinition compileTimeMethod)
        {
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(compileTimeMethod));
            Contract.Requires(compileTimeMethod.IsVirtual);
            Contract.Ensures(VirtualMethodIsInDemand(compileTimeMethod));
            Contract.Ensures(runtimeTargetsByDispatch[compileTimeMethod] != null);

            HashSet <IMethodDefinition> calls = null;

            if (!runtimeTargetsByDispatch.TryGetValue(compileTimeMethod, out calls))
            {
                calls = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());
                runtimeTargetsByDispatch[compileTimeMethod] = calls;
            }
        }
Esempio n. 15
0
        private void NoteDispatch(IMethodDefinition compileTimeMethod, IMethodDefinition runtimeMethod, ITypeDefinition runtimeType)
        {
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(compileTimeMethod));
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(runtimeMethod));
            Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(runtimeType));

            // Note: runtimeType may not be type containing runtimeMethod, but it will be a subtype of it.
            // Might want a contract for this.

            if (virtualCallsInDemand.NoteVirtualMethodMayDispatchToMethod(compileTimeMethod, runtimeMethod))
            {
                AddToWorklist(runtimeMethod);

                analysisReasons.NoteMethodReachableForReason(runtimeMethod, analysisReasons.MethodReachedByDispatchAgainstVirtualMethodWithTypeConstructed(compileTimeMethod, runtimeType));
            }
        }
Esempio n. 16
0
        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);
            }
        }
Esempio n. 17
0
        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()));
        }
Esempio n. 18
0
        private void NoteVirtualDispatch(IMethodDefinition methodDispatchedUpon)
        {
            Contract.Requires(methodDispatchedUpon != null);
            Contract.Requires(!(methodDispatchedUpon is Dummy));
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(methodDispatchedUpon));
            Contract.Requires(methodDispatchedUpon.IsVirtual);

            Contract.Ensures(VirtualMethodIsInDemand(methodDispatchedUpon));

            //Console.WriteLine("VirtCallFound on {0} of type {1}", methodDefinition, methodDefinition.GetType());

            bool virtualMethodIsAlreadyKnown = VirtualMethodIsInDemand(methodDispatchedUpon);

            MarkVirtualMethodAsInDemand(methodDispatchedUpon);

            if (virtualMethodIsAlreadyKnown)
            {
                return;
            }

            // The code below this point is called only the first time we learn that
            // someone has dispatched against this method.

            //Console.WriteLine("{0} has {1} derived methods", methodDefinition, this.callgraph.GetAllDerivedMethods(methodDefinition).ToArray().Length);


            ITypeDefinition typeDefiningM = methodDispatchedUpon.ContainingTypeDefinition;

            this.TypeUseFound(typeDefiningM);

            // t-devinc: clean this up
            foreach (ITypeDefinition subType in new ITypeDefinition[] { typeDefiningM }.Concat(wholeProgram.ClassHierarchy().AllSubClassesOfClass(typeDefiningM)))
            {
                if (GarbageCollectHelper.TypeIsConstructable(subType) && ((subType.IsStruct || constructed.Contains(subType))))
                {
                    ICollection <IMethodDefinition> implementationsOfMethodDefinitionForSubType = GarbageCollectHelper.Implements(subType, typeDefiningM, methodDispatchedUpon);

                    Contract.Assert(implementationsOfMethodDefinitionForSubType.Count() > 0);

                    foreach (IMethodDefinition implementationOfM in implementationsOfMethodDefinitionForSubType)
                    {
                        NoteDispatch(methodDispatchedUpon, GarbageCollectHelper.UnspecializeAndResolveMethodReference(implementationOfM), subType);
                    }
                }
            }
        }
Esempio n. 19
0
        public RapidTypeAnalysis(WholeProgram wholeProgram, TargetProfile profile)
        {
            Contract.Ensures(!this.FinishedAnalysis);

            this.types   = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());
            this.methods = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());
            this.virtualCallsInDemand = new VirtualDispatchDemand();

            this.nonvirtualDispatches = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            this.fields      = new HashSet <IFieldDefinition>(new FieldDefinitionEqualityComparer());
            this.constructed = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());

            this.constructedGenericParameters = new HashSet <IGenericParameter>(new TypeDefinitionEqualityComparer());

            // Note: we use the interned key as the hashcode, so this set should be deterministic
            this.worklist = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            this.wholeProgram = wholeProgram;

            this.reflectionSummarizers = new HashSet <IMethodSummarizer>();

            this.simpleBytecodeSummarizer           = new SimpleBytecodeMethodSummarizer();
            this.reachabilityFlowBytecodeSummarizer = new ReachabilityBasedLocalFlowMethodSummarizer();

            //systemObjectType = wholeProgram.Host().PlatformType.SystemObject.ResolvedType;

            // Weak heuristic -- should provide custom host?

            IAssembly coreAssembly = wholeProgram.HeuristicFindCoreAssemblyForProfile(profile);

            Contract.Assert(coreAssembly != null);

            systemObjectType = GarbageCollectHelper.CreateTypeReference(wholeProgram.Host(), coreAssembly, "System.Object").ResolvedType;
            Contract.Assert(!(systemObjectType is Dummy));

            systemObjectFinalizeMethod = TypeHelper.GetMethod(systemObjectType, wholeProgram.Host().NameTable.GetNameFor("Finalize"));
            Contract.Assert(!(systemObjectFinalizeMethod is Dummy));

            methodsRequiringReflectionSummary = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            unresolvedReferences = new HashSet <IReference>(new ReferenceEqualityComparer());

            unspecializedTypesPassedAsTypeVariables = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());
        }
Esempio n. 20
0
        // Filter all methods in methodref by those that ILGC says are reachable.
        public IEnumerable <IMethodReference> GetMethodCallees(IMethodReference methodref)
        {
            Contract.Requires(methodref != null);
            Contract.Requires(!(methodref is Dummy));
            Contract.Requires(this.FinishedAnalysis);

            // use a set to remove potential duplicates.
            ISet <IMethodDefinition> calls = new HashSet <IMethodDefinition>(new MethodDefinitionEqualityComparer());

            // get unspecialized definition of this method reference
            IMethodDefinition methoddef = GarbageCollectHelper.UnspecializeAndResolveMethodReference(methodref);

            IMethodSummarizer   bestSummarizer = new CompleteBytecodeMethodSummarizer();
            ReachabilitySummary summary        = bestSummarizer.SummarizeMethod(methoddef, wholeProgram);


            if (summary != null)
            {
                foreach (var method in summary.NonvirtuallyCalledMethods)
                {
                    if (this.ReachableMethods().Contains(GarbageCollectHelper.UnspecializeAndResolveMethodReference(method as IMethodReference))) // && this.ReachableTypes().Contains(method.ContainingTypeDefinition))
                    {
                        calls.Add(method);
                    }
                }

                foreach (var method in summary.VirtuallyCalledMethods)
                {
                    if (this.ReachableMethods().Contains(GarbageCollectHelper.UnspecializeAndResolveMethodReference(method as IMethodReference)))// && this.ReachableTypes().Contains(method.ContainingTypeDefinition))
                    {
                        calls.Add(method);
                    }
                }
            }

            return(calls);
        }
Esempio n. 21
0
        public void Run(IEnumerable <IMethodReference> roots)
        {
            // add the rootset
            foreach (var rootReference in roots)
            {
                IMethodDefinition rootDefinition = GarbageCollectHelper.UnspecializeAndResolveMethodReference(rootReference);

                NotePotentialNonVirtualMethodReachedForReason(rootDefinition, analysisReasons.MethodReachedBecauseEntryPoint());

                // If a constructor for a type is an entry point, we consider that type to be constructed.
                if (rootDefinition.IsConstructor)
                {
                    ITypeDefinition constructedType = rootDefinition.ContainingTypeDefinition;

                    ConstructionFoundWithReason(constructedType, analysisReasons.TypeConstructedBecauseConstructorIsEntryPoint());
                }
            }

            // walk over worklist
            do
            {
                IMethodDefinition m = this.worklist.First();
                this.worklist.Remove(m);
                //Console.WriteLine("Pulled method {0} off of worklist", m);



                if (!m.IsExternal)
                {
                    IMethodSummarizer bestSummarizer = GetBytecodeSummarizerForMethod(m);

                    ReachabilitySummary bytecodeSummary = bestSummarizer.SummarizeMethod(m, wholeProgram);

                    if (bytecodeSummary != null)
                    {
                        ProcessSummary(bytecodeSummary, m);

                        ISet <ReachabilitySummary> reflectionSummaries = RunReflectionSummarizers(m, wholeProgram);

                        foreach (ReachabilitySummary summary in reflectionSummaries)
                        {
                            ProcessSummary(summary, m);
                        }

                        bool gotReflectionSummary = reflectionSummaries.Count() > 0;

                        if (!gotReflectionSummary && IsReflectionSummaryProbablyNeeded(bytecodeSummary, m))
                        {
                            //Console.WriteLine("{0} calls reflection but doesn't have a summary. (UNSOUND?).", m);

                            methodsRequiringReflectionSummary.Add(m);
                        }
                    }
                }
                else
                {
                    if (!m.IsAbstract)
                    {
                        // Boy, there are a lot of these
                        // Console.WriteLine("Note: cannot process external method {0}. (UNSOUND)", m);
                    }
                }
            } while (this.worklist.Count > 0);


            Console.WriteLine("Used flow-based summarizer for {0}/{1} methods", countUsedFlowBasedSummarizer, ReachableMethods().Count());
        }
Esempio n. 22
0
 private void MarkVirtualMethodAsInDemand(IMethodDefinition virtualMethod)
 {
     Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(virtualMethod));
     Contract.Requires(virtualMethod.IsVirtual);
     virtualCallsInDemand.NoteDispatchIsInDemand(virtualMethod);
 }
Esempio n. 23
0
        /// <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);
        }