示例#1
0
 internal Graph(object graphSource)
 {
     this.graphSource = graphSource;
     vertices = new Dictionary<string, Vertex>();
     topVertex = FindOrCreateVertex("<root>", null, null);
     bottomVertex = FindOrCreateVertex("<bottom>", null, null);
 }
示例#2
0
        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);
            }
        }
示例#3
0
 internal Vertex FindOrCreateVertex(string name, string signature, string module)
 {
     string nameSignatureModule = NameSignatureModule(name, signature, module);
     Vertex vertex;
     if (!vertices.TryGetValue(nameSignatureModule, out vertex))
     {
         vertex = new Vertex(name, signature, module, this);
         vertices[nameSignatureModule] = vertex;
     }
     return vertex;
 }
示例#4
0
		public int SelectedVertexCount(out Vertex selectedVertex)
		{
			int selectedCount = 0;
			selectedVertex = null;
			foreach (Vertex v in graph.vertices.Values)
			{
				if (v.selected)
				{
					selectedCount++;
					selectedVertex = v;
				}
			}
			return selectedCount;
		}
示例#5
0
        internal int BuildVertexStack(int stackTraceIndex, Vertex[] funcVertex, ref Vertex[] vertexStack, int skipCount)
        {
            int[] stackTrace = readNewLog.stacktraceTable.IndexToStacktrace(stackTraceIndex);
                
            while (vertexStack.Length < stackTrace.Length + 3)
            {
                vertexStack = new Vertex[vertexStack.Length*2];
            }

            for (int i = skipCount; i < stackTrace.Length; i++)
            {
                vertexStack[i-skipCount] = funcVertex[stackTrace[i]];
            }

            return stackTrace.Length - skipCount;
        }
示例#6
0
        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.HeapGraph);
                graph.previousGraphTickIndex = allocatedAfterTickIndex;
            }
            else
            {
                Graph previousGraph = cachedGraph;
                if (previousGraph != null && previousGraph.graphSource == this)
                {
                    return(previousGraph);
                }

                cachedGraph = graph = new Graph(this, Graph.GraphType.HeapGraph);
                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, true);
            }

            foreach (KeyValuePair <ulong, GcObject> keyValuePair in idToObject)
            {
                GcObject gcObject = keyValuePair.Value;
                if (gcObject.AllocTickIndex > allocatedAfterTickIndex && gcObject.AllocTickIndex < allocatedBeforeTickIndex)
                {
                    AssignInterestLevelToObject(keyValuePair.Key, gcObject, options, filterForm, false);
                }
                else
                {
                    gcObject.InterestLevel = InterestLevel.Ignore;
                }
            }
            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);
        }
 private void activateOutgoing(Vertex v)
 {
     if (v.active)
         return;
     v.active = true;
     foreach (Edge e in v.outgoingEdges.Values)
         activateOutgoing(e.ToVertex);
 }
示例#8
0
        internal static int FilterVertices(Vertex[] vertexStack, int stackPtr)
        {
            bool display = false;
            for (int i = 0; i < stackPtr; i++)
            {
                Vertex vertex = vertexStack[i];
                switch (vertex.interestLevel & InterestLevel.InterestingChildren)
                {
                    case    InterestLevel.Ignore:
                        if (display)
                            vertex.interestLevel |= InterestLevel.Display;
                        break;

                    case    InterestLevel.InterestingChildren:
                        display = true;
                        break;

                    default:
                        display = false;
                        break;
                }
            }
            display = false;
            for (int i = stackPtr-1; i >= 0; i--)
            {
                Vertex vertex = vertexStack[i];
                switch (vertex.interestLevel & InterestLevel.InterestingParents)
                {
                    case    InterestLevel.Ignore:
                        if (display)
                            vertex.interestLevel |= InterestLevel.Display;
                        break;

                    case    InterestLevel.InterestingParents:
                        display = true;
                        break;

                    default:
                        display = false;
                        break;
                }
            }
            int newStackPtr = 0;
            for (int i = 0; i < stackPtr; i++)
            {
                Vertex vertex = vertexStack[i];
                if ((vertex.interestLevel & (InterestLevel.Display|InterestLevel.Interesting)) != InterestLevel.Ignore)
                {
                    vertexStack[newStackPtr++] = vertex;
                    vertex.interestLevel &= ~InterestLevel.Display;
                }
            }
            return newStackPtr;
        }
示例#9
0
        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;
        }
示例#10
0
 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);
 }
示例#11
0
 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);
     }
 }
示例#12
0
        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;
        }
示例#13
0
 static void EnsureVertexCapacity(int id, ref Vertex[] vertexArray)
 {
     Debug.Assert(id >= 0);
     if (id < vertexArray.Length)
         return;
     int newLength = vertexArray.Length*2;
     if (newLength <= id)
         newLength = id + 1;
     Vertex[] newVertexArray = new Vertex[newLength];
     Array.Copy(vertexArray, 0, newVertexArray, 0, vertexArray.Length);
     vertexArray = newVertexArray;
 }
示例#14
0
        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);
            }
        }
示例#15
0
 private void activateIncoming(Vertex v)
 {
     if (v.active)
         return;
     v.active = true;
     foreach (Edge e in v.incomingEdges.Values)
         activateIncoming(e.FromVertex);
 }
示例#16
0
 private void AppendVertexHeader(StringBuilder sb, Vertex v, int indent)
 {
     for (int i = 0; i < indent; i++)
         sb.Append(" ");
     string signature = v.signature != null ? v.signature : "";
     sb.AppendFormat("{0} {1}:\t{2}\r\n", v.name, signature, v.weightString);
     if (NonEmptyWeightHistory(v))
     {
         for (int i = 0; i < indent; i++)
             sb.Append(" ");
         sb.Append("  Previous allocations (newest to oldest): ");
         for (int i = 0; i < v.weightHistory.Length; i++)
         {
             sb.Append(formatWeight(v.weightHistory[i]));
             sb.Append(",  ");
         }
         sb.Append("\r\n");
     }
 }
示例#17
0
        private Dictionary <GcObject, ulong> objectToId;        // reverse mapping from gc objects to their addresses

        internal void WriteVertexPaths(int allocatedAfterTickIndex, int allocatedBeforeTickIndex, string typeName)
        {
            BuildTypeGraph(new FilterForm());

            if (objectToId == null)
            {
                objectToId = new Dictionary <GcObject, ulong>();
                // initialize the reverse mapping
                foreach (KeyValuePair <ulong, GcObject> keyValuePair in idToObject)
                {
                    objectToId[keyValuePair.Value] = keyValuePair.Key;
                }
            }

            ulong[][] idsFromRoot  = new ulong[1][];
            Vertex[]  pathFromRoot = new Vertex[32];
            int       counter      = 0;

            foreach (GcObject gcObject in idToObject.Values)
            {
                if (gcObject.Type(this).name.CompareTo(typeName) != 0)
                {
                    continue;
                }

                if (gcObject.AllocTickIndex <= allocatedAfterTickIndex ||
                    gcObject.AllocTickIndex >= allocatedBeforeTickIndex)
                {
                    continue;
                }
                ulong[][] _idsFromRoot = idsFromRoot;
                if (_idsFromRoot.Length <= counter)
                {
                    idsFromRoot = new ulong[counter + 1][];
                    for (int i = 0; i < _idsFromRoot.Length; i++)
                    {
                        idsFromRoot[i] = _idsFromRoot[i];
                    }
                }

                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;
                //System.Console.WriteLine("{0} -- {1}:", counter, gcObject.id);
                for (GcObject pathObject = gcObject; pathObject != null; pathObject = pathObject.parent)
                {
                    if (pathObject.vertex != null)
                    {
                        level--;
                        pathFromRoot[level]  = pathObject.vertex;
                        pathObject.vertex.id = 0;
                        objectToId.TryGetValue(pathObject, out pathObject.vertex.id);
                    }
                }

                levels = Vertex.SqueezeOutRepetitions(pathFromRoot, levels);
                idsFromRoot[counter] = new ulong[levels];
                for (int i = 0; i < levels; i++)
                {
                    //System.Console.Write("{0}, {1} ->", pathFromRoot[i].name, pathFromRoot[i].id);
                    idsFromRoot[counter][i] = pathFromRoot[i].id;
                }
                //System.Console.WriteLine("---------------------------------------");
                counter++;
            }
            Console.WriteLine("<TotalAllocations>{0}</TotalAllocations>", idsFromRoot.Length);
            Console.WriteLine("</Difference>");
            Console.WriteLine("</Summary>");
            Console.WriteLine("<PossibleCulPrits>");
            // Display the reference list and stack trace for 0th object

            // Find Culprit here.
            var mismatchedObjects = new List <int>();
            var differentCulprits = new List <string>();

            for (int j = 1; j < idsFromRoot.Length; j++)
            {
                for (int i = 0; i < idsFromRoot[0].Length; i++)
                {
                    if ((i > idsFromRoot[j].Length) || ((i < idsFromRoot[j].Length) && (idsFromRoot[0][i] != idsFromRoot[j][i])))
                    {
                        if (i < idsFromRoot[0].Length - 1)
                        {
                            mismatchedObjects.Add(j);
                        }
                        GcObject temp = idToObject[idsFromRoot[0][i - 1]];
                        if (temp != null)
                        {
                            if (!differentCulprits.Contains(temp.Type(this).name))
                            {
                                differentCulprits.Add(temp.Type(this).name);
                                if (differentCulprits.Count <= 5)
                                {
                                    System.Console.WriteLine("<CulPrit><!--{0}--></CulPrit>", temp.Type(this).name);
                                }
                            }
                        }
                        break;
                    }
                }
            }
            Console.WriteLine("</PossibleCulPrits>");
            Console.WriteLine("<FirstObject>");
            PrintGCRoot(idsFromRoot[0]);
            PrintStackTrace(idsFromRoot[0]);
            Console.WriteLine("</FirstObject>");
            Console.WriteLine("<MisMatchedObjects>");

            if (mismatchedObjects.Count > 0)
            {
                Console.WriteLine();
                int limit = (mismatchedObjects.Count > 5) ? 5 : mismatchedObjects.Count;
                for (int i = 0; i < limit; i++)
                {
                    Console.WriteLine("<Object>");
                    PrintGCRoot(idsFromRoot[mismatchedObjects[i]]);
                    PrintStackTrace(idsFromRoot[mismatchedObjects[i]]);
                    Console.WriteLine("</Object>");
                }
            }
            Console.WriteLine("</MisMatchedObjects>");
        }
示例#18
0
        internal Graph BuildReferenceGraph(Graph orgGraph)
        {
            var graph = new Graph(this, 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;

            var foundBeforeMarker = new GcObject();

            var 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);
        }
示例#19
0
        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);
                }
            }
        }
示例#20
0
 private double Score(Vertex v)
 {
     return v.weight*(Diversity(v.incomingEdges) + Diversity(v.outgoingEdges));
 }
示例#21
0
 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);
     }
 }
示例#22
0
 private Vertex CloneVertex(Graph g, Vertex v)
 {
     Vertex vn = g.FindOrCreateVertex(v.name, v.signature, v.moduleName);
     vn.basicName = v.basicName;
     vn.basicSignature = v.basicSignature;
     vn.active = true;
     return vn;
 }
示例#23
0
 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));
 }
示例#24
0
 private void ZoomVertex(Vertex v, string titlePrefix)
 {
     toolTip.Active = false;
     Graph g;
     if (graph.graphSource is Graph)
     {
         Graph orgGraph = (Graph)graph.graphSource;
         g = new Graph(orgGraph);
         v = orgGraph.FindOrCreateVertex(v.name, v.signature, v.moduleName);
     }
     else
         g = new Graph(graph);
     g.allocatedAfterTickIndex = graph.allocatedAfterTickIndex;
     g.allocatedBeforeTickIndex = graph.allocatedBeforeTickIndex;
     Vertex vn = CloneVertex(g, v);
     vn.count = v.count;
     if (v.incomingEdges.Count == 0)
     {
         if (v != graph.TopVertex)
             g.FindOrCreateEdge(g.TopVertex, vn).AddWeight(v.weight);
     }
     else
     {
         foreach (Edge e in v.incomingEdges.Values)
         {
             Vertex vin = CloneVertex(g, e.FromVertex);
             g.FindOrCreateEdge(vin, vn).AddWeight(e.weight);
             if (vin != g.TopVertex)
                 g.FindOrCreateEdge(g.TopVertex, vin).AddWeight(e.weight);
         }
     }
     if (v.outgoingEdges.Count == 0)
     {
         if (v != graph.BottomVertex)
             g.FindOrCreateEdge(vn, g.BottomVertex).AddWeight(v.weight);
     }
     else
     {
         foreach (Edge e in v.outgoingEdges.Values)
         {
             Vertex von = CloneVertex(g, e.ToVertex);
             g.FindOrCreateEdge(vn, von).AddWeight(e.weight);
             if (von != g.BottomVertex)
                 g.FindOrCreateEdge(von, g.BottomVertex).AddWeight(e.weight);
         }
     }
     g.BottomVertex.active = false;
     g.graphType = graph.graphType;
     g.typeGraphOptions = graph.typeGraphOptions;
     if (titlePrefix == null)
         titlePrefix = "Zoom to: ";
     string title = titlePrefix + v.name + " " + (v.signature != null? v.signature : "");
     GraphViewForm graphViewForm = new GraphViewForm(g, title);
     graphViewForm.Visible = true;
 }
示例#25
0
 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;
 }
示例#26
0
        void PaintVertex(Vertex v, Graphics g, Brush penBrush, Pen pen)
        {
            Rectangle r = v.rectangle;
            v.selectionRectangle = r;
            g.DrawRectangle(pen, r);
            if (v.selected)
            {
                using (SolidBrush selectBrush = new SolidBrush(Color.Aqua))
                    g.FillRectangle(selectBrush, r);
            }

            RectangleF stringRect;
            int lineCount = 2;
            if (v.signature != null)
                lineCount = 3;
            if (r.Height > fontHeight*lineCount)
                stringRect = new RectangleF(r.X,r.Y,r.Width,fontHeight);
            else
            {
                stringRect = new RectangleF(r.X,r.Y+r.Height+3,r.Width,fontHeight);
                // for these very narrow rectangle, start the selection rectangle 5 pixels above
                // the actual rectangle, so people can hit it more easily. Even though they could click
                // on the text below, which not everybody tries...
                const int vTolerance = 5;
                v.selectionRectangle = new Rectangle(r.X, r.Y - vTolerance, r.Width, vTolerance + r.Height + 3 + fontHeight*lineCount);
            }

            if (v.weightHistory != null)
            {
                int alpha = 200;
                int previousHeight = r.Height;
                for (int i = 0; i < v.weightHistory.Length; i++)
                {
                    alpha = alpha*2/3;
                    ulong weight = v.weightHistory[i];
                    int height = (int)((float)r.Height/v.weight*weight);
                    if (height < previousHeight)
                    {
                        Color color = Color.FromArgb(alpha, Color.Red);
                        using (Brush brush = new SolidBrush(color))
                        {
                            g.FillRectangle(brush, r.X, r.Y+height, r.Width, previousHeight - height);
                        }
                    }
                    else
                    {
                        Color color = Color.FromArgb(alpha, Color.Green);
                        using (Brush brush = new SolidBrush(color))
                        {
                            g.FillRectangle(brush, r.X, r.Y+previousHeight, r.Width, height - previousHeight);
                        }
                    }
                    previousHeight = height;
                }
            }

            g.DrawString(v.basicName, font, penBrush, stringRect);
            stringRect.Y += fontHeight;
            if (v.signature != null)
            {
                g.DrawString(v.basicSignature, font, penBrush, stringRect);
                stringRect.Y += fontHeight;
                int width = (int)g.MeasureString(v.basicSignature, font).Width;
                if (stringRect.Width < width)
                    v.signatureCurtated = true;
            }

            g.DrawString(v.weightString, font, penBrush, stringRect);
        }
示例#27
0
        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;
        }
示例#28
0
        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);
                }
            }
        }
示例#29
0
        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;
        }
示例#30
0
 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);
     }
 }
示例#31
0
 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;
         }
     }
 }
示例#32
0
        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);
            }
        }
示例#33
0
        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);
        }
示例#34
0
        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);
        }