示例#1
0
        static void DoRTA(IMetadataHost host, ClassAndMethodVisitor visitor, IModule rootModule, IModule stubsModule)
        {
            bool rootIsExe = false;

            if (rootModule.Kind == ModuleKind.ConsoleApplication)
            {
                rootIsExe = true;
            }
            StreamWriter rtaLogSW = new StreamWriter(Path.Combine(ConfigParams.LogDir, "rta_log.txt"));

            rtaAnalyzer = new RTAAnalyzer(rootIsExe, rtaLogSW, host);
            visitor.SetupRTAAnalyzer(rtaAnalyzer);
            Stubber.SetupRTAAnalyzer(rtaAnalyzer);
            Stubs.SetupInternFactory(host.InternFactory);
            GenericMethods.SetupInternFactory(host.InternFactory);
            Stubs.SetupStubs(stubsModule);

            bool diskLoadSuccessful = false;

            if (ConfigParams.LoadSavedScope)
            {
                diskLoadSuccessful = rtaAnalyzer.LoadSavedScope(host);
            }
            if (!diskLoadSuccessful)
            {
                Initialize(rtaAnalyzer.classes, rtaAnalyzer.entryPtClasses, rootModule, rootIsExe);
            }

            int  iterationCount = 0;
            bool changeInCount = true;
            int  startClassCnt, startMethCnt;

            while (changeInCount)
            {
                rtaLogSW.WriteLine();
                rtaLogSW.WriteLine("Starting RTA ITERATION:{0}", iterationCount);
                startClassCnt = rtaAnalyzer.classes.Count;
                startMethCnt  = rtaAnalyzer.methods.Count;
                rtaLogSW.WriteLine("Counts: classes:{0}   methods:{1}", startClassCnt, startMethCnt);
                rtaAnalyzer.classWorkList.Clear();
                rtaAnalyzer.visitedClasses.Clear();
                rtaAnalyzer.ignoredClasses.Clear();
                rtaAnalyzer.visitedMethods.Clear();
                rtaAnalyzer.ignoredMethods.Clear();
                CopyAll(rtaAnalyzer.classes, rtaAnalyzer.classWorkList);
                while (rtaAnalyzer.classWorkList.Count > 0)
                {
                    ITypeDefinition ty = rtaAnalyzer.classWorkList.First <ITypeDefinition>();
                    rtaAnalyzer.classWorkList.RemoveAt(0);
                    visitor.Traverse(ty);
                }
                if (rtaAnalyzer.classes.Count == startClassCnt && rtaAnalyzer.methods.Count == startMethCnt)
                {
                    changeInCount = false;
                }
                iterationCount++;
            }
            Copy(rtaAnalyzer.allocClasses, rtaAnalyzer.classes);
            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine();
            foreach (IMethodDefinition m in rtaAnalyzer.methods)
            {
                rtaLogSW.WriteLine(m.FullName());
            }
            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine();
            foreach (IMethodDefinition m in rtaAnalyzer.entryPtMethods)
            {
                rtaLogSW.WriteLine(m.FullName());
            }
            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine();
            foreach (ITypeDefinition cl in rtaAnalyzer.classes)
            {
                rtaLogSW.WriteLine(cl.FullName());
            }

            rtaLogSW.WriteLine();
            rtaLogSW.WriteLine("ALLOC CLASSES");
            foreach (ITypeDefinition cl in rtaAnalyzer.allocClasses)
            {
                rtaLogSW.WriteLine(cl.FullName());
            }
            rtaLogSW.WriteLine("+++++++++++++++ RTA DONE ++++++++++++++++++");

            if (!diskLoadSuccessful)
            {
                rtaAnalyzer.SaveScope(host);
            }
            rtaLogSW.Close();
        }
示例#2
0
        public void ProcessVirtualInvoke(IMethodDefinition mCallee, ITypeDefinition calleeClass, bool isAddrTaken)
        {
            // mCallee is an ordinary method - never a template method.
            // calleeClass and mCallee are either both stubbed or, both unstubbed - i.e. they are consistent.
            bool isInterface = calleeClass.IsInterface;

            IMethodDefinition calleeTemplate = null;

            if (mCallee is IGenericMethodInstance)
            {
                calleeTemplate = (mCallee as IGenericMethodInstance).GenericMethod.ResolvedMethod;
            }

            foreach (ITypeDefinition cl in allocClasses)
            {
                if (cl is IArrayTypeReference)
                {
                    continue;
                }
                if (!Stubber.SuppressM(cl))
                {
                    bool process = false;
                    if (isInterface && Utils.ImplementsInterface(cl, calleeClass))
                    {
                        process = true;
                    }
                    if (Utils.ExtendsClass(cl, calleeClass))
                    {
                        process = true;
                    }
                    if (!process)
                    {
                        continue;
                    }
                    IMethodDefinition calleeArg;
                    if (mCallee is IGenericMethodInstance)
                    {
                        calleeArg = calleeTemplate;
                    }
                    else
                    {
                        calleeArg = mCallee;
                    }
                    IMethodDefinition meth = Utils.GetMethodSignMatchRecursive(cl, calleeArg);
                    if (meth == null)
                    {
                        continue;
                    }
                    if (meth.IsGeneric && calleeTemplate != null)
                    {
                        IMethodDefinition instMeth  = GenericMethods.RecordInfo(meth, mCallee, /* createIfReqd = */ true);
                        IMethodDefinition addedMeth = Stubber.CheckAndAdd(instMeth);
                        if (addedMeth != null && isAddrTaken)
                        {
                            addrTakenMethods.Add(addedMeth);
                        }
                    }
                    else if (meth.IsGeneric && calleeTemplate == null)
                    {
                        continue;
                    }
                    else if (!meth.IsGeneric && calleeTemplate != null)
                    {
                        continue;
                    }
                    else // meth is not generic and calleeTemplate is null
                    {
                        IMethodDefinition addedMeth = Stubber.CheckAndAdd(meth);
                        if (addedMeth != null && isAddrTaken)
                        {
                            addrTakenMethods.Add(addedMeth);
                        }
                    }
                }
            }
        }