예제 #1
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);
        }
예제 #2
0
        private ISet <ReachabilitySummary> RunReflectionSummarizers(IMethodDefinition method, WholeProgram wholeProgram)
        {
            ISet <ReachabilitySummary> summaries = new HashSet <ReachabilitySummary>();


            foreach (IMethodSummarizer reflectionSummarizer in reflectionSummarizers)
            {
                ReachabilitySummary summary = reflectionSummarizer.SummarizeMethod(method, wholeProgram);

                if (summary != null)
                {
                    summaries.Add(summary);
                }
            }

            return(summaries);
        }
예제 #3
0
        private bool IsReflectionSummaryProbablyNeeded(ReachabilitySummary bytecodeSummary, IMethodDefinition containingMethod)
        {
            // Note we only get the compile-time targets for virtually called methods here.
            // This is not right; but we're really just using it as a heuristic to help debugging.

            // If a non-system class calls a reflection class, heuristically we probably need a summary
            // t-devinc: ToString(): gross
            if (!containingMethod.ContainingType.ToString().Contains("System"))
            {
                foreach (IMethodDefinition calledMethod in bytecodeSummary.NonvirtuallyCalledMethods.Concat(bytecodeSummary.VirtuallyCalledMethods))
                {
                    if (calledMethod.ContainingType.ToString().Contains("System.Reflection") ||
                        calledMethod.ContainingType.ToString().Contains("System.Activator") ||
                        calledMethod.ContainingType.ToString().Contains("System.Xml.Serialization.XmlSerializer"))
                    {
                        //Console.WriteLine("{0} calls reflection method {1}", containingMethod, calledMethod);
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #4
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);
        }
예제 #5
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());
        }