public void GetStats(Dictionary <MethodBase, MethodStats> statsDict) { var selfTicks = Ticks; foreach (var child in Children) { child.GetStats(statsDict); selfTicks -= child.Ticks; } var method = MethodBaseTracingInstaller.GetMethod(MethodId); method = method.IsGenericMethod ? ((MethodInfo)method).GetGenericMethodDefinition() : method; MethodStats stats; if (!statsDict.TryGetValue(method, out stats)) { statsDict.Add(method, new MethodStats { Calls = Calls, Method = method, Ticks = selfTicks }); } else { stats.Calls += Calls; stats.Ticks += selfTicks; } }
private void ExtendInternal() { var methodBody = MethodBody.Read(dynamicMethod, false); bool output = true; if(output) Debug.WriteLine(""); if(output) Debug.WriteLine("Initial methodBody of DynamicMethod"); if(output) Debug.WriteLine(methodBody); var methodContainsCycles = CycleFinderWithoutRecursion.HasCycle(methodBody.Instructions.ToArray()); if(output) Debug.WriteLine("Contains cycles: " + methodContainsCycles + "\n"); if(!methodContainsCycles && methodBody.Instructions.Count < 50) { Debug.WriteLine(dynamicMethod + " too simple to be traced"); return; } AddLocalVariables(methodBody); int functionId; MethodBaseTracingInstaller.AddMethod(dynamicMethod, out functionId); ModifyMethodBody(methodBody, functionId); methodBody.WriteToDynamicMethod(dynamicMethod, Math.Max(methodBody.MaxStack, 3)); if(output) Debug.WriteLine(""); if(output) Debug.WriteLine("Changed methodBody of DynamicMethod"); if(output) Debug.WriteLine(methodBody); }
private void ModifyMethodBody(MethodBody methodBody, int functionId) { MethodBaseTracingInstaller.ReplaceRetInstructions(methodBody.Instructions, hasReturnType, resultLocalIndex); var ticksReaderSignature = typeof(MethodBaseTracingInstaller).Module.ResolveSignature(typeof(MethodBaseTracingInstaller).GetMethod("TemplateForTicksSignature", BindingFlags.Public | BindingFlags.Static).MetadataToken); var methodStartedSignature = typeof(TracingAnalyzer).Module.ResolveSignature(typeof(TracingAnalyzer).GetMethod("MethodStarted", BindingFlags.Public | BindingFlags.Static).MetadataToken); var methodFinishedSignature = typeof(TracingAnalyzer).Module.ResolveSignature(typeof(TracingAnalyzer).GetMethod("MethodFinished", BindingFlags.Public | BindingFlags.Static).MetadataToken); int startIndex = 0; methodBody.Instructions.Insert(startIndex++, Instruction.Create(IntPtr.Size == 4 ? OpCodes.Ldc_I4 : OpCodes.Ldc_I8, IntPtr.Size == 4 ? (int)ticksReaderAddress : (long)ticksReaderAddress)); methodBody.Instructions.Insert(startIndex++, Instruction.Create(OpCodes.Calli, ticksReaderSignature)); methodBody.Instructions.Insert(startIndex++, Instruction.Create(OpCodes.Stloc, ticksLocalIndex)); methodBody.Instructions.Insert(startIndex++, Instruction.Create(OpCodes.Ldc_I4, (int)functionId)); // [ ourMethod, functionId ] methodBody.Instructions.Insert(startIndex++, Instruction.Create(IntPtr.Size == 4 ? OpCodes.Ldc_I4 : OpCodes.Ldc_I8, IntPtr.Size == 4 ? (int)methodStartedAddress : (long)methodStartedAddress)); // [ ourMethod, functionId, funcAddr ] methodBody.Instructions.Insert(startIndex++, Instruction.Create(OpCodes.Calli, methodStartedSignature)); // [] var tryStartInstruction = methodBody.Instructions[startIndex]; Instruction tryEndInstruction; Instruction finallyStartInstruction; methodBody.Instructions.Insert(methodBody.Instructions.Count, finallyStartInstruction = tryEndInstruction = Instruction.Create(OpCodes.Ldc_I4, (int)functionId)); // [ functionId ] methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(IntPtr.Size == 4 ? OpCodes.Ldc_I4 : OpCodes.Ldc_I8, IntPtr.Size == 4 ? (int)ticksReaderAddress : (long)ticksReaderAddress)); // [ functionId, funcAddr ] methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(OpCodes.Calli, ticksReaderSignature)); // [ functionId, ticks ] methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(OpCodes.Ldloc, ticksLocalIndex)); // [ functionId, ticks, startTicks ] methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(OpCodes.Sub)); // [ functionId, elapsed ] methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(IntPtr.Size == 4 ? OpCodes.Ldc_I4 : OpCodes.Ldc_I8, IntPtr.Size == 4 ? (int)methodFinishedAddress : (long)methodFinishedAddress)); // [ functionId, elapsed, profilerOverhead , funcAddr ] methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(OpCodes.Calli, methodFinishedSignature)); // [] Instruction endFinallyInstruction; methodBody.Instructions.Insert(methodBody.Instructions.Count, endFinallyInstruction = Instruction.Create(OpCodes.Endfinally)); Instruction finallyEndInstruction; if(resultLocalIndex >= 0) { methodBody.Instructions.Insert(methodBody.Instructions.Count, finallyEndInstruction = Instruction.Create(OpCodes.Ldloc, resultLocalIndex)); methodBody.Instructions.Insert(methodBody.Instructions.Count, Instruction.Create(OpCodes.Ret)); } else methodBody.Instructions.Insert(methodBody.Instructions.Count, finallyEndInstruction = Instruction.Create(OpCodes.Ret)); ExceptionHandler newException = new ExceptionHandler(ExceptionHandlerType.Finally); newException.TryStart = tryStartInstruction; newException.TryEnd = tryEndInstruction; newException.HandlerStart = finallyStartInstruction; newException.HandlerEnd = finallyEndInstruction; methodBody.Instructions.Insert(methodBody.Instructions.IndexOf(tryEndInstruction), Instruction.Create(OpCodes.Leave, finallyEndInstruction)); methodBody.ExceptionHandlers.Add(newException); }
public static Stats GetStats() { var ticks = MethodBaseTracingInstaller.TicksReader(); var methodCallTree = GetMethodCallTreeForCurrentThread(); return(new Stats { ElapsedTicks = ticks - methodCallTree.startTicks, Tree = methodCallTree.GetStatsAsTree(ticks), List = methodCallTree.GetStatsAsList(ticks), }); }
public MethodStatsNode GetStats(long totalTicks) { return(new MethodStatsNode { MethodStats = new MethodStats { Method = MethodBaseTracingInstaller.GetMethod(MethodId), Calls = Calls, Ticks = Ticks, Percent = totalTicks == 0 ? 0.0 : Ticks * 100.0 / totalTicks }, Children = Children.Select(child => { var childStats = child.GetStats(totalTicks); return childStats; }).OrderByDescending(stats => stats.MethodStats.Ticks). ToArray() }); }
public MethodCallTree() { root = new MethodCallNode(null, 0); current = root; startTicks = MethodBaseTracingInstaller.TicksReader(); }
public void ClearStats() { current.ClearStats(); startTicks = MethodBaseTracingInstaller.TicksReader(); }