internal Graph BuildHandleAllocationGraph(FilterForm filterForm) { Vertex[] funcVertex = new Vertex[1]; Vertex[] vertexStack = new Vertex[1]; var graph = new Graph(this, Graph.GraphType.HandleAllocationGraph); BuildFuncVertices(graph, ref funcVertex, filterForm); for (int i = 0; i < typeSizeStacktraceToCount.Length; i++) { if (typeSizeStacktraceToCount[i] > 0) { int[] stacktrace = readNewLog.stacktraceTable.IndexToStacktrace(i); uint count = (uint)typeSizeStacktraceToCount[i]; BuildHandleAllocationTrace(graph, i, count, funcVertex, ref vertexStack, filterForm); } } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return(graph); }
internal Graph BuildModuleGraph(FilterForm filterForm) { Vertex[] funcVertex = new Vertex[1]; Vertex[] vertexStack = new Vertex[1]; Vertex[] modVertex = new Vertex[1]; var graph = new Graph(this, Graph.GraphType.ModuleGraph); BuildFuncVertices(graph, ref funcVertex, filterForm); BuildModVertices(graph, ref modVertex, filterForm); foreach (var fd in functionList) { BuildModuleTrace(graph, fd.funcCallStack, fd.funcModule, fd.funcSize, funcVertex, modVertex, ref vertexStack, filterForm); } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return(graph); }
internal Graph BuildAssemblyGraph(FilterForm filterForm) { Vertex[] assemblyVertex = new Vertex[1]; Vertex[] funcVertex = new Vertex[1]; Vertex[] typeVertex = new Vertex[1]; Vertex[] vertexStack = new Vertex[1]; var graph = new Graph(this, Graph.GraphType.AssemblyGraph); int count = BuildAssemblyVertices(graph, ref assemblyVertex, filterForm); BuildTypeVertices(graph, ref typeVertex, filterForm); BuildFuncVertices(graph, ref funcVertex, filterForm); for (int i = 0; i < count; i++) { Vertex v = (Vertex)assemblyVertex[i], tv = null; string c = v.name; int stackid = readNewLog.assemblies[c]; if (stackid < 0) { int[] stacktrace = readNewLog.stacktraceTable.IndexToStacktrace(-stackid); tv = typeVertex[stacktrace[0]]; } BuildAssemblyTrace(graph, stackid, v, tv, funcVertex, ref vertexStack); } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return(graph); }
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 AssignInterestLevelsToTypes(BuildTypeGraphOptions options, FilterForm filterForm) { foreach (GcType gcType in typeIdToGcType.Values) { gcType.interestLevel = filterForm.IsInterestingTypeName(gcType.name, null, readNewLog.finalizableTypes.ContainsKey(gcType.typeID)) ? InterestLevel.Interesting : InterestLevel.Ignore; } }
internal void AssignInterestLevelsToTypes(BuildTypeGraphOptions options, FilterForm filterForm) { foreach (GcType gcType in typeIdToGcType.Values) { // Otherwise figure which the interesting types are. gcType.interestLevel = filterForm.InterestLevelOfTypeName(gcType.name, null, readNewLog.finalizableTypes.ContainsKey(gcType.typeID)); } }
internal int BuildAssemblyVertices(Graph graph, ref Vertex[] typeVertex, FilterForm filterForm) { int count = 0; foreach (string c in readNewLog.assemblies.Keys) { readNewLog.AddTypeVertex(count++, c, graph, ref typeVertex, filterForm); } return(count); }
private void BuildFuncVertices(Graph graph, ref Vertex[] funcVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.funcName.Length; i++) { string name = readNewLog.funcName[i]; string signature = readNewLog.funcSignature[i]; if (name != null && signature != null) { readNewLog.AddFunctionVertex(i, name, signature, graph, ref funcVertex, filterForm); } } }
internal void BuildTypeVertices(Graph graph, ref Vertex[] typeVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.typeName.Length; i++) { string typeName = readNewLog.typeName[i]; if (typeName == null) { typeName = string.Format("???? type {0}", i); } readNewLog.AddTypeVertex(i, typeName, graph, ref typeVertex, filterForm); } }
private void BuildModVertices(Graph graph, ref Vertex[] modVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.modBasicName.Length; i++) { string basicName = readNewLog.modBasicName[i]; string fullName = readNewLog.modFullName[i]; if (basicName != null && fullName != null) { readNewLog.AddFunctionVertex(i, basicName, fullName, graph, ref modVertex, filterForm); modVertex[i].basicName = basicName; modVertex[i].basicSignature = fullName; } } }
internal void BuildFuncVertices(Graph graph, ref Vertex[] funcVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.funcName.Length; i++) { string name = readNewLog.funcName[i]; string signature = readNewLog.funcSignature[i]; if (name == null) { name = string.Format("???? function {0}", i); } if (signature == null) { signature = "( ???????? )"; } readNewLog.AddFunctionVertex(i, name, signature, graph, ref funcVertex, filterForm); } }
private void AssignInterestLevels() { foreach (GcType gcType in typeNameToGcType.Values) { // Otherwise figure which the interesting types are. gcType.interestLevel = FilterForm.InterestLevelOfTypeName(gcType.name, readNewLog.finalizableTypes[gcType.typeID] != null); } foreach (GcObject gcObject in idToObject.Values) { // The initial interest level in objects is the one of their type gcObject.interestLevel = gcObject.type.interestLevel; } foreach (GcObject gcObject in idToObject.Values) { // Check if this is an interesting object, and we are supposed to mark its ancestors if ((gcObject.interestLevel & InterestLevel.InterestingParents) == InterestLevel.InterestingParents) { for (GcObject parentObject = gcObject.parent; parentObject != null; parentObject = parentObject.parent) { // As long as we find uninteresting object, mark them for display // When we find an interesting object, we stop, because either it // will itself mark its parents, or it isn't interested in them (and we // respect that despite the interest of the current object, somewhat arbitrarily). if ((parentObject.interestLevel & InterestLevel.InterestingParents) == InterestLevel.Ignore) { parentObject.interestLevel |= InterestLevel.Display; } else { break; } } } // Check if this object should be displayed because one of its ancestors // is interesting, and it says its descendents are interesting as well if ((gcObject.interestLevel & (InterestLevel.Interesting | InterestLevel.Display)) == InterestLevel.Ignore) { CheckForParentMarkingDescendant(gcObject); } } }
void BuildFuncVertices(Graph graph, ref Vertex[] funcVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.funcName.Length; i++) { string name = readNewLog.funcName[i]; string signature = readNewLog.funcSignature[i]; if (name != null && signature != null) readNewLog.AddFunctionVertex(i, name, signature, graph, ref funcVertex, filterForm); } }
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 GraphViewForm(Graph graph, string title) { // // Required for Windows Form Designer support // InitializeComponent(); toolTip = new ToolTip(); toolTip.Active = false; toolTip.ShowAlways = true; toolTip.AutomaticDelay = 70; toolTip.ReshowDelay = 1; this.graph = graph; font = MainForm.instance.font; fontHeight = font.Height; Text = title; EnableDisableMenuItems(); filterForm = new FilterForm(); findForm = new FindRoutineForm(); }
internal void AddTypeVertex(int typeId, string typeName, Graph graph, ref Vertex[] typeVertex, FilterForm filterForm) { EnsureVertexCapacity(typeId, ref typeVertex); typeVertex[typeId] = graph.FindOrCreateVertex(typeName, null, null); typeVertex[typeId].interestLevel = filterForm.IsInterestingTypeName(typeName, null, finalizableTypes.ContainsKey(typeId)) ? InterestLevel.Interesting | filterForm.InterestLevelForParentsAndChildren() : InterestLevel.Ignore; }
internal Graph BuildClassGraph(FilterForm filterForm) { Vertex[] funcVertex = new Vertex[1]; Vertex[] vertexStack = new Vertex[1]; Graph graph = new Graph(this); graph.graphType = Graph.GraphType.ClassGraph; BuildFuncVertices(graph, ref funcVertex, filterForm); foreach (FunctionDescriptor fd in functionList) { BuildClassTrace(graph, fd.funcCallStack, fd.functionId, fd.funcSize, funcVertex, ref vertexStack, filterForm); } foreach (Vertex v in graph.vertices.Values) v.active = true; graph.BottomVertex.active = false; return graph; }
internal void AddTypeVertex(int typeId, string typeName, Graph graph, ref Vertex[] typeVertex, FilterForm filterForm) { EnsureVertexCapacity(typeId, ref typeVertex); typeVertex[typeId] = graph.FindOrCreateVertex(typeName, null, null); typeVertex[typeId].interestLevel = filterForm.InterestLevelOfTypeName(typeName, null, finalizableTypes.ContainsKey(typeId)); }
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); } }
void BuildModVertices(Graph graph, ref Vertex[] modVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.modBasicName.Length; i++) { string basicName = readNewLog.modBasicName[i]; string fullName = readNewLog.modFullName[i]; if (basicName != null && fullName != null) { readNewLog.AddFunctionVertex(i, basicName, fullName, graph, ref modVertex, filterForm); modVertex[i].basicName = basicName; modVertex[i].basicSignature = fullName; } } }
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); } }
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); } } }
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 int BuildAssemblyVertices(Graph graph, ref Vertex[] typeVertex, FilterForm filterForm) { int count = 0; foreach(string c in readNewLog.assemblies.Keys) { readNewLog.AddTypeVertex(count++, c, graph, ref typeVertex, filterForm); } return count; }
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); } } }
internal static bool InterestingCallStack(Vertex[] vertexStack, int stackPtr, FilterForm filterForm) { if (stackPtr == 0) return filterForm.methodFilters.Length == 0; if ((vertexStack[stackPtr-1].interestLevel & InterestLevel.Interesting) == InterestLevel.Interesting) return true; for (int i = stackPtr-2; i >= 0; i--) { switch (vertexStack[i].interestLevel & InterestLevel.InterestingChildren) { case InterestLevel.Ignore: break; case InterestLevel.InterestingChildren: return true; default: return false; } } return false; }
internal void BuildTypeVertices(Graph graph, ref Vertex[] typeVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.typeName.Length; i++) { string typeName = readNewLog.typeName[i]; if (typeName == null) typeName = string.Format("???? type {0}", i); readNewLog.AddTypeVertex(i, typeName, graph, ref typeVertex, filterForm); } }
internal Graph BuildHandleAllocationGraph(FilterForm filterForm) { Vertex[] funcVertex = new Vertex[1]; Vertex[] vertexStack = new Vertex[1]; Graph graph = new Graph(this); graph.graphType = Graph.GraphType.HandleAllocationGraph; BuildFuncVertices(graph, ref funcVertex, filterForm); for (int i = 0; i < typeSizeStacktraceToCount.Length; i++) { if (typeSizeStacktraceToCount[i] > 0) { int[] stacktrace = readNewLog.stacktraceTable.IndexToStacktrace(i); uint count = (uint)typeSizeStacktraceToCount[i]; BuildHandleAllocationTrace(graph, i, count, funcVertex, ref vertexStack, filterForm); } } foreach (Vertex v in graph.vertices.Values) v.active = true; graph.BottomVertex.active = false; return graph; }
internal void AddFunctionVertex(int funcId, string functionName, string signature, Graph graph, ref Vertex[] funcVertex, FilterForm filterForm) { EnsureVertexCapacity(funcId, ref funcVertex); int moduleId = funcModule[funcId]; string moduleName = null; if (moduleId >= 0) moduleName = modBasicName[moduleId]; funcVertex[funcId] = graph.FindOrCreateVertex(functionName, signature, moduleName); funcVertex[funcId].interestLevel = filterForm.InterestLevelOfMethodName(functionName, signature); }
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 BuildFuncVertices(Graph graph, ref Vertex[] funcVertex, FilterForm filterForm) { for (int i = 0; i < readNewLog.funcName.Length; i++) { string name = readNewLog.funcName[i]; string signature = readNewLog.funcSignature[i]; if (name == null) name = string.Format("???? function {0}", i); if (signature == null) signature = "( ???????? )"; readNewLog.AddFunctionVertex(i, name, signature, graph, ref funcVertex, filterForm); } }
internal void AssignInterestLevelToObject(ulong id, GcObject gcObject, BuildTypeGraphOptions options, FilterForm filterForm) { // The initial interest level in objects is the one of their type InterestLevel interestLevel = gcObject.Type(this).interestLevel; if (filterForm.signatureFilters.Length != 0) { string signature = SignatureOfObject(id, gcObject, BuildTypeGraphOptions.LumpBySignature); interestLevel &= filterForm.InterestLevelOfTypeName(gcObject.Type(this).name, signature, readNewLog.finalizableTypes.ContainsKey(gcObject.Type(this).typeID)); } if (filterForm.addressFilters.Length != 0) { interestLevel &= filterForm.InterestLevelOfAddress(id); } gcObject.InterestLevel |= interestLevel; // Check if this is an interesting object, and we are supposed to mark its ancestors if ((gcObject.InterestLevel & InterestLevel.InterestingParents) == InterestLevel.InterestingParents) { for (GcObject parentObject = gcObject.parent; parentObject != null; parentObject = parentObject.parent) { // As long as we find uninteresting objects, mark them for display // When we find an interesting object, we stop, because either it // will itself mark its parents, or it isn't interested in them (and we // respect that despite the interest of the current object, somewhat arbitrarily). if ((parentObject.InterestLevel & InterestLevel.InterestingParents) == InterestLevel.Ignore) { parentObject.InterestLevel |= InterestLevel.Display; } else { break; } } } // It's tempting here to mark the descendants as well, but they may be reached via // long reference paths, when there are shorter ones that were deemed uninteresting // Instead, we look whether our parent objects are interesting and want to show their // descendants, but we have to do that in a separate pass. }
internal Graph BuildAssemblyGraph(FilterForm filterForm) { Vertex[] assemblyVertex = new Vertex[1]; Vertex[] funcVertex = new Vertex[1]; Vertex[] typeVertex = new Vertex[1]; Vertex[] vertexStack = new Vertex[1]; Graph graph = new Graph(this); graph.graphType = Graph.GraphType.AssemblyGraph; int count = BuildAssemblyVertices(graph, ref assemblyVertex, filterForm); BuildTypeVertices(graph, ref typeVertex, filterForm); BuildFuncVertices(graph, ref funcVertex, filterForm); for(int i = 0; i < count; i++) { Vertex v = (Vertex)assemblyVertex[i], tv = null; string c = v.name; int stackid = readNewLog.assemblies[c]; if(stackid < 0) { int[] stacktrace = readNewLog.stacktraceTable.IndexToStacktrace(-stackid); tv = typeVertex[stacktrace[0]]; } BuildAssemblyTrace(graph, stackid, v, tv, funcVertex, ref vertexStack); } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return graph; }
internal Graph BuildTypeGraph(FilterForm filterForm) { return(BuildTypeGraph(-1, int.MaxValue, BuildTypeGraphOptions.LumpBySignature, filterForm)); }
internal Graph BuildTypeGraph(int allocatedAfterTickIndex, int allocatedBeforeTickIndex, BuildTypeGraphOptions options, FilterForm filterForm) { Graph graph; if (filterForm.filterVersion != 0 || options != BuildTypeGraphOptions.LumpBySignature || allocatedAfterTickIndex > 0 || allocatedBeforeTickIndex < int.MaxValue) { graph = new Graph(this); graph.graphType = Graph.GraphType.HeapGraph; graph.previousGraphTickIndex = allocatedAfterTickIndex; } else { Graph previousGraph = cachedGraph; if (previousGraph != null && previousGraph.graphSource == this) { return(previousGraph); } cachedGraph = graph = new Graph(this); graph.graphType = Graph.GraphType.HeapGraph; graph.graphSource = this; if (previousGraph != null) { graph.previousGraphTickIndex = ((ObjectGraph)previousGraph.graphSource).tickIndex; foreach (Vertex v in previousGraph.vertices.Values) { Vertex newV = graph.FindOrCreateVertex(v.name, v.signature, v.moduleName); if (v.weightHistory == null) { newV.weightHistory = new ulong[1]; } else { ulong[] weightHistory = v.weightHistory; newV.weightHistory = new ulong[Math.Min(weightHistory.Length + 1, historyDepth)]; for (int i = v.weightHistory.Length - 1; i > 0; i--) { newV.weightHistory[i] = weightHistory[i - 1]; } } newV.weightHistory[0] = v.weight; } } } graph.typeGraphOptions = options; graph.filterVersion = filterForm.filterVersion; if (graph.previousGraphTickIndex < graph.allocatedAfterTickIndex) { graph.previousGraphTickIndex = graph.allocatedAfterTickIndex; } graph.allocatedAfterTickIndex = allocatedAfterTickIndex; graph.allocatedBeforeTickIndex = allocatedBeforeTickIndex; GcObject rootObject = CreateRootObject(); for (int i = 0; i < rootCount; i++) { roots[i].InterestLevel = InterestLevel.Ignore; } foreach (GcObject gcObject in idToObject.Values) { gcObject.parent = null; gcObject.vertex = null; gcObject.InterestLevel = InterestLevel.Ignore; } AssignParents(rootObject); int index = 0; foreach (GcType gcType in typeIdToGcType.Values) { gcType.index = index++; } GcType[] gcTypes = new GcType[index]; typeHintTable = new int[index]; foreach (GcType gcType in typeIdToGcType.Values) { gcTypes[gcType.index] = gcType; } AssignInterestLevelsToTypes(options, filterForm); for (int i = 0; i < rootCount; i++) { AssignInterestLevelToObject(rootIDs[i], roots[i], options, filterForm); } foreach (KeyValuePair <ulong, GcObject> keyValuePair in idToObject) { AssignInterestLevelToObject(keyValuePair.Key, keyValuePair.Value, options, filterForm); } foreach (GcObject gcObject in idToObject.Values) { if (gcObject.InterestLevel == InterestLevel.Ignore) { CheckForParentMarkingDescendant(gcObject); } } FindVertex(0, rootObject, graph, options); for (int i = 0; i < rootCount; i++) { roots[i].vertex = null; FindVertex(rootIDs[i], roots[i], graph, options); } foreach (KeyValuePair <ulong, GcObject> keyValuePair in idToObject) { ulong id = keyValuePair.Key; GcObject gcObject = keyValuePair.Value; if (gcObject.parent == null || (gcObject.InterestLevel & (InterestLevel.Interesting | InterestLevel.Display)) == InterestLevel.Ignore) { continue; } FindVertex(id, gcObject, graph, options); } Vertex[] pathFromRoot = new Vertex[32]; foreach (GcObject gcObject in idToObject.Values) { if (gcObject.parent == null || (gcObject.InterestLevel & (InterestLevel.Interesting | InterestLevel.Display)) == InterestLevel.Ignore || gcObject.AllocTickIndex <= allocatedAfterTickIndex || gcObject.AllocTickIndex >= allocatedBeforeTickIndex) { continue; } int levels = 0; for (GcObject pathObject = gcObject; pathObject != null; pathObject = pathObject.parent) { if (pathObject.vertex != null) { levels++; } } while (pathFromRoot.Length < levels + 1) { pathFromRoot = new Vertex[pathFromRoot.Length * 2]; } int level = levels; for (GcObject pathObject = gcObject; pathObject != null; pathObject = pathObject.parent) { if (pathObject.vertex != null) { level--; pathFromRoot[level] = pathObject.vertex; } } levels = Vertex.SqueezeOutRepetitions(pathFromRoot, levels); 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(gcObject.Size(this)); } Vertex thisVertex = pathFromRoot[levels - 1]; thisVertex.basicWeight += gcObject.Size(this); 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 ulong[1]; } } foreach (Vertex v in graph.vertices.Values) { v.active = true; } graph.BottomVertex.active = false; return(graph); }
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); } } }