private void BuildClassTrace(Graph graph, int stackTraceIndex, int funcIndex, ulong size, Vertex[] funcVertex, ref Vertex[] vertexStack, FilterForm filterForm) { string className = ClassNameOfFunc(funcIndex); int functionsToSkip = FunctionsInSameClass(className, stackTraceIndex); int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0) - functionsToSkip; Vertex toVertex = graph.TopVertex; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = graph.FindOrCreateVertex(className, null, null); vertexStack[stackPtr].interestLevel = filterForm.IsInterestingMethodName(className, null) ? InterestLevel.Interesting | filterForm.InterestLevelForParentsAndChildren() : InterestLevel.Ignore; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); Edge edge; Vertex fromVertex; for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } if (toVertex != graph.TopVertex) { fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } } }
private void BuildFunctionTrace(Graph graph, int stackTraceIndex, int funcIndex, ulong size, Vertex[] funcVertex, ref Vertex[] vertexStack, FilterForm filterForm) { int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0); Vertex toVertex = graph.TopVertex; if ((funcVertex[funcIndex].interestLevel & InterestLevel.Interesting) == InterestLevel.Interesting && ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = funcVertex[funcIndex]; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); Edge edge; Vertex fromVertex; for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } }
private void BuildModuleTrace(Graph graph, int stackTraceIndex, int modIndex, ulong size, Vertex[] funcVertex, Vertex[] modVertex, ref Vertex[] vertexStack, FilterForm filterForm) { int functionsToSkip = FunctionsInSameModule(modIndex, stackTraceIndex); int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0) - functionsToSkip; Vertex toVertex = graph.TopVertex; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = modVertex[modIndex]; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); Edge edge; Vertex fromVertex; for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } }
internal void BuildHandleAllocationTrace(Graph graph, int stackTraceIndex, uint count, Vertex[] funcVertex, ref Vertex[] vertexStack, FilterForm filterForm) { int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0); Vertex handleVertex = graph.FindOrCreateVertex("Handle", null, null); handleVertex.interestLevel = InterestLevel.Interesting; Vertex toVertex = graph.TopVertex; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = handleVertex; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); Edge edge; Vertex fromVertex; for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(count); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(count); } }
internal void BuildAssemblyTrace(Graph graph, int stackTraceIndex, Vertex assembly, Vertex typeVertex, Vertex[] funcVertex, ref Vertex[] vertexStack) { int stackPtr = BuildVertexStack(Math.Abs(stackTraceIndex), funcVertex, ref vertexStack, stackTraceIndex < 0 ? 2 : 0); Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if (typeVertex != null) { vertexStack[stackPtr++] = typeVertex; } vertexStack[stackPtr++] = assembly; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(1); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(1); }
internal void BuildAllocationTrace(Graph graph, int stackTraceIndex, int typeIndex, ulong size, Vertex[] typeVertex, Vertex[] funcVertex, ref Vertex[] vertexStack, FilterForm filterForm) { int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 2); Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if ((typeVertex[typeIndex].interestLevel & InterestLevel.Interesting) == InterestLevel.Interesting && ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = typeVertex[typeIndex]; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } }
internal void BuildCallTrace(Graph graph, int stackTraceIndex, Vertex[] funcVertex, ref Vertex[] vertexStack, int count, FilterForm filterForm) { int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0); Vertex toVertex = graph.TopVertex; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { Vertex fromVertex = toVertex; toVertex = vertexStack[i]; Edge edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight((uint)count); } } }
internal void BuildAssemblyTrace(Graph graph, int stackTraceIndex, Vertex assembly, Vertex typeVertex, Vertex[] funcVertex, ref Vertex[] vertexStack) { int stackPtr = BuildVertexStack(Math.Abs(stackTraceIndex), funcVertex, ref vertexStack, stackTraceIndex < 0 ? 2 : 0); Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if(typeVertex != null) { vertexStack[stackPtr++] = typeVertex; } vertexStack[stackPtr++] = assembly; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(1); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(1); }
void BuildClassTrace(Graph graph, int stackTraceIndex, int funcIndex, ulong size, Vertex[] funcVertex, ref Vertex[] vertexStack, FilterForm filterForm) { string className = ClassNameOfFunc(funcIndex); int functionsToSkip = FunctionsInSameClass(className, stackTraceIndex); int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0) - functionsToSkip; Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = graph.FindOrCreateVertex(className, null, null); vertexStack[stackPtr].interestLevel = filterForm.InterestLevelOfMethodName(className, null); stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } if (toVertex != graph.TopVertex) { fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } } }
void BuildModuleTrace(Graph graph, int stackTraceIndex, int modIndex, ulong size, Vertex[] funcVertex, Vertex[] modVertex, ref Vertex[] vertexStack, FilterForm filterForm) { int functionsToSkip = FunctionsInSameModule(modIndex, stackTraceIndex); int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0) - functionsToSkip; Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = modVertex[modIndex]; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(size); } }
internal void BuildHandleAllocationTrace(Graph graph, int stackTraceIndex, uint count, Vertex[] funcVertex, ref Vertex[] vertexStack, FilterForm filterForm) { int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0); Vertex handleVertex = graph.FindOrCreateVertex("Handle", null, null); handleVertex.interestLevel = InterestLevel.Interesting; Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { vertexStack[stackPtr] = handleVertex; stackPtr++; stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(count); } fromVertex = toVertex; toVertex = graph.BottomVertex; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(count); } }
internal void BuildCallTrace(Graph graph, int stackTraceIndex, Vertex[] funcVertex, ref Vertex[] vertexStack, int count, FilterForm filterForm) { int stackPtr = BuildVertexStack(stackTraceIndex, funcVertex, ref vertexStack, 0); Vertex toVertex = graph.TopVertex; Vertex fromVertex; Edge edge; if (ReadNewLog.InterestingCallStack(vertexStack, stackPtr, filterForm)) { stackPtr = ReadNewLog.FilterVertices(vertexStack, stackPtr); stackPtr = Vertex.SqueezeOutRepetitions(vertexStack, stackPtr); for (int i = 0; i < stackPtr; i++) { fromVertex = toVertex; toVertex = vertexStack[i]; edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight((uint)count); } } }
internal Graph BuildReferenceGraph(Graph orgGraph) { Graph graph = new Graph(this); graph.graphType = Graph.GraphType.ReferenceGraph; Vertex[] pathFromRoot = new Vertex[32]; GcObject rootObject = CreateRootObject(); FindVertex(0, rootObject, graph, BuildTypeGraphOptions.LumpBySignature); rootObject.InterestLevel = InterestLevel.Interesting; foreach (GcObject gcObject in idToObject.Values) { gcObject.parent = null; } // We wish to find all references to certain selected objects, // or, to be precise, all references that keep these objects alive. // To do this, we use a breadth first traversal of the object graph, using // a queue of objects still to process. If we find a reference to one of the // selected objects, we don't actually include this object, but instead // just make note of the reference // Initialize rootObject.parent = null; GcObject foundBeforeMarker = new GcObject(); Queue <GcObject> queue = new Queue <GcObject>(); queue.Enqueue(rootObject); // Loop while (queue.Count != 0) { GcObject head = queue.Dequeue(); foreach (GcObject refObject in head.References) { if (refObject.parent == null || refObject.parent == foundBeforeMarker) { // this is a reference to either one of the "selected" objects // or just to a new object if (refObject.vertex != null && refObject.vertex.selected && (refObject.InterestLevel & (InterestLevel.Interesting | InterestLevel.Display)) != InterestLevel.Ignore && refObject.AllocTickIndex > orgGraph.allocatedAfterTickIndex && refObject.AllocTickIndex < orgGraph.allocatedBeforeTickIndex) { // add <root> -> ... -> head -> refObject to the reference graph int levels = 0; for (GcObject pathObject = head; pathObject != null; pathObject = pathObject.parent) { levels++; } while (pathFromRoot.Length < levels + 2) { pathFromRoot = new Vertex[pathFromRoot.Length * 2]; } pathFromRoot[levels + 1] = graph.FindOrCreateVertex(refObject.vertex.name, refObject.vertex.signature, refObject.vertex.moduleName); int level = levels; for (GcObject pathObject = head; pathObject != null; pathObject = pathObject.parent) { if ((pathObject.InterestLevel & (InterestLevel.Interesting | InterestLevel.Display)) == InterestLevel.Ignore || pathObject.vertex == null) { pathFromRoot[level] = null; } else { pathFromRoot[level] = graph.FindOrCreateVertex(pathObject.vertex.name, pathObject.vertex.signature, pathObject.vertex.moduleName); } level--; } int nonZeroLevels = 0; for (int j = 0; j <= levels + 1; j++) { if (pathFromRoot[j] != null) { pathFromRoot[nonZeroLevels++] = pathFromRoot[j]; } } levels = Vertex.SqueezeOutRepetitions(pathFromRoot, nonZeroLevels); for (int j = 0; j < levels - 1; j++) { Vertex fromVertex = pathFromRoot[j]; Vertex toVertex = pathFromRoot[j + 1]; Edge edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(1); } Vertex thisVertex = pathFromRoot[levels - 1]; thisVertex.basicWeight += 1; if (refObject.parent == null) { thisVertex.count += 1; refObject.parent = foundBeforeMarker; } } else { refObject.parent = head; queue.Enqueue(refObject); } } } } foreach (Vertex v in graph.vertices.Values) { if (v.weight < v.outgoingWeight) { v.weight = v.outgoingWeight; } if (v.weight < v.incomingWeight) { v.weight = v.incomingWeight; } if (v.weightHistory == null) { v.weightHistory = new ulong[1]; } } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return(graph); }
internal Graph BuildTypeGraph(int allocatedAfterTickIndex, int allocatedBeforeTickIndex, BuildTypeGraphOptions options) { if (graph == null || FilterForm.filterVersion != graphFilterVersion || allocatedAfterTickIndex >= 0 || allocatedBeforeTickIndex < int.MaxValue) { graph = new Graph(this); graph.graphType = Graph.GraphType.HeapGraph; graphFilterVersion = FilterForm.filterVersion; graph.previousGraphTickIndex = allocatedAfterTickIndex; } else { ObjectGraph previousGraph = (ObjectGraph)graph.graphSource; graph.previousGraphTickIndex = previousGraph.tickIndex; graph.graphSource = this; foreach (Vertex v in graph.vertices.Values) { if (v.weightHistory == null) { v.weightHistory = new uint[1]; } else { uint[] weightHistory = v.weightHistory; if (weightHistory.Length < historyDepth) { v.weightHistory = new uint[weightHistory.Length + 1]; } for (int i = v.weightHistory.Length - 1; i > 0; i--) { v.weightHistory[i] = weightHistory[i - 1]; } } v.weightHistory[0] = v.weight; v.weight = v.incomingWeight = v.outgoingWeight = v.basicWeight = 0; v.count = 0; foreach (Edge e in v.outgoingEdges.Values) { e.weight = 0; } } } if (graph.previousGraphTickIndex < graph.allocatedAfterTickIndex) { graph.previousGraphTickIndex = graph.allocatedAfterTickIndex; } graph.allocatedAfterTickIndex = allocatedAfterTickIndex; graph.allocatedBeforeTickIndex = allocatedBeforeTickIndex; GcType rootType = GetOrCreateGcType("<root>", 0); GcObject rootObject = GetOrCreateObject(0); rootObject.type = rootType; rootObject.references = roots; foreach (GcObject gcObject in idToObject.Values) { gcObject.level = int.MaxValue; gcObject.vertex = null; } AssignLevels(rootObject); AssignInterestLevels(); int index = 0; foreach (GcType gcType in typeNameToGcType.Values) { gcType.index = index++; } GcType[] gcTypes = new GcType[index]; typeHintTable = new int[index]; foreach (GcType gcType in typeNameToGcType.Values) { gcTypes[gcType.index] = gcType; } Vertex[] pathFromRoot = new Vertex[32]; foreach (GcObject gcObject in idToObject.Values) { if (gcObject.level == int.MaxValue || (gcObject.interestLevel & (InterestLevel.Interesting | InterestLevel.Display)) == InterestLevel.Ignore || gcObject.allocTickIndex <= allocatedAfterTickIndex || gcObject.allocTickIndex >= allocatedBeforeTickIndex) { continue; } while (pathFromRoot.Length < gcObject.level + 1) { pathFromRoot = new Vertex[pathFromRoot.Length * 2]; } for (GcObject pathObject = gcObject; pathObject != null; pathObject = pathObject.parent) { if ((pathObject.interestLevel & (InterestLevel.Interesting | InterestLevel.Display)) == InterestLevel.Ignore) { pathFromRoot[pathObject.level] = null; } else { pathFromRoot[pathObject.level] = FindVertex(pathObject, graph, options); } } int levels = 0; for (int i = 0; i <= gcObject.level; i++) { if (pathFromRoot[i] != null) { pathFromRoot[levels++] = pathFromRoot[i]; } } levels = Vertex.SqueezeOutRepetitions(pathFromRoot, levels); for (int i = 0; i < levels - 1; i++) { Vertex fromVertex = pathFromRoot[i]; Vertex toVertex = pathFromRoot[i + 1]; Edge edge = graph.FindOrCreateEdge(fromVertex, toVertex); edge.AddWeight(gcObject.size); } Vertex thisVertex = pathFromRoot[levels - 1]; thisVertex.basicWeight += gcObject.size; thisVertex.count += 1; } foreach (Vertex v in graph.vertices.Values) { if (v.weight < v.outgoingWeight) { v.weight = v.outgoingWeight; } if (v.weight < v.incomingWeight) { v.weight = v.incomingWeight; } if (v.weightHistory == null) { v.weightHistory = new uint[1]; } } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return(graph); }