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(); }
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); } } } } }