Exemple #1
0
        GcObject CreateRootObject()
        {
            GcObject rootObject = GcObject.CreateGcObject(rootCount);

            rootObject.TypeSizeStackTraceId = GetOrCreateGcType("<root>");
            GcObject unknownObject = GcObject.CreateGcObject(0);

            unknownObject.TypeSizeStackTraceId = GetOrCreateGcType("<unknown type>");
            for (int i = 0; i < rootCount; i++)
            {
                if (roots[i] == null)
                {
                    roots[i] = idToObject[rootIDs[i]];
                    if (roots[i] == null)
                    {
                        roots[i] = unknownObject;
                    }
                }
                roots[i].parent        = null;
                roots[i].InterestLevel = InterestLevel.Interesting;
                rootObject.SetReference(i, roots[i]);
            }
            // patch up any unresolved forward references by making them point to "unknownObject"
            foreach (ForwardReference head in addressToForwardReferences.Values)
            {
                for (ForwardReference forwardReference = head; forwardReference != null; forwardReference = forwardReference.next)
                {
                    forwardReference.source.SetReference(forwardReference.referenceNumber, unknownObject);
                }
            }
            addressToForwardReferences.Clear();
            return(rootObject);
        }
Exemple #2
0
        void CreateForwardReference(ulong targetAddress, GcObject source, int referenceNumber)
        {
            ForwardReference nextForwardReference;

            addressToForwardReferences.TryGetValue(targetAddress, out nextForwardReference);
            addressToForwardReferences[targetAddress] = new ForwardReference(source, referenceNumber, nextForwardReference);
        }
Exemple #3
0
        // Check whether we have a parent object interested in this one
        private bool CheckForParentMarkingDescendant(GcObject gcObject)
        {
            GcObject parentObject = gcObject.parent;

            if (parentObject == null)
            {
                return(false);
            }
            switch (parentObject.interestLevel & InterestLevel.InterestingChildren)
            {
            // Parent says it wants to show children
            case    InterestLevel.InterestingChildren:
                gcObject.interestLevel |= InterestLevel.Display;
                return(true);

            // Parent is not interesting - check its parent
            case    InterestLevel.Ignore:
                if (CheckForParentMarkingDescendant(parentObject))
                {
                    gcObject.interestLevel |= InterestLevel.Display;
                    return(true);
                }
                else
                {
                    return(false);
                }

            default:
                return(false);
            }
        }
        void AssignLevels(GcObject rootObject)
        {
            // We use a breadth first traversal of the object graph.
            // To do this, we make use of a queue of objects still to process.
            GcObject head, tail;

            // Initialize
            head             = rootObject;
            tail             = rootObject;
            rootObject.level = 0;

            // Loop
            while (head != null)
            {
                if (head.references != null)
                {
                    int nextLevel = head.level + 1;
                    foreach (GcObject refObject in head.references)
                    {
                        if (refObject.level > nextLevel)
                        {
                            refObject.parent = head;
                            refObject.level  = nextLevel;
                            tail.next        = refObject;
                            tail             = refObject;
                        }
                    }
                }
                head = head.next;
            }
        }
Exemple #5
0
 private GcObject[] GrowHintTable(GcObject[] hintTable)
 {
     GcObject[] newHintTable = new GcObject[hintTable.Length * 2];
     for (int i = 0; i < hintTable.Length; i++)
     {
         newHintTable[i] = hintTable[i];
     }
     return(newHintTable);
 }
Exemple #6
0
 internal void GrowMasterTable()
 {
     GcObject[][] newmasterTable = new GcObject[masterTable.Length * 2][];
     for (int i = 0; i < masterTable.Length; i++)
     {
         newmasterTable[i] = masterTable[i];
     }
     masterTable = newmasterTable;
 }
Exemple #7
0
        internal GcObject CreateAndEnterObject(ulong objectID, int typeSizeStackTraceId, int numberOfReferences, ulong[] references)
        {
            GcObject o = CreateObject(typeSizeStackTraceId, numberOfReferences, references);

            idToObject[objectID] = o;

            FillInForwardReferences(objectID, o);

            return(o);
        }
Exemple #8
0
 internal ObjectGraph()
 {
     //
     // TODO: Add constructor logic here
     //
     idToObject       = new Hashtable();
     typeNameToGcType = new Hashtable();
     hintTable        = new GcObject[10];
     unknownType      = GetOrCreateGcType("<unknown type>");
 }
Exemple #9
0
 internal void CalculateTreeSize(GcObject rootObject)
 {
     nextHintIndex = 0;
     MarkObject(rootObject);
     rootObject.treeSize = 0;
     for (int i = 0; i < nextHintIndex; i++)
     {
         rootObject.treeSize += hintTable[i].size;
     }
 }
Exemple #10
0
            internal override void SetReference(int referenceNumber, GcObject target)
            {
                switch (referenceNumber)
                {
                case 0: reference0 = target; break;

                case 1: reference1 = target; break;

                default: Debug.Assert(referenceNumber == 0); break;
                }
            }
Exemple #11
0
 private void MarkDescendants(GcObject gcObject)
 {
     foreach (GcObject refObject in gcObject.References)
     {
         if (refObject.InterestLevel == InterestLevel.Ignore)
         {
             refObject.InterestLevel |= InterestLevel.Display;
             MarkDescendants(refObject);
         }
     }
 }
Exemple #12
0
 internal void GrowRoots()
 {
     GcObject[] newRoots   = new GcObject[roots.Length * 2];
     ulong[]    newRootIDs = new ulong[roots.Length * 2];
     for (int i = 0; i < roots.Length; i++)
     {
         newRoots[i]   = roots[i];
         newRootIDs[i] = rootIDs[i];
     }
     roots   = newRoots;
     rootIDs = newRootIDs;
 }
Exemple #13
0
        internal GcObject GetOrCreateObject(int objectID)
        {
            GcObject o = (GcObject)idToObject[objectID];

            if (o == null)
            {
                o = new GcObject(objectID);
                idToObject[objectID] = o;
                o.type = unknownType;
            }
            return(o);
        }
Exemple #14
0
 internal GcObject[] LookupReferences(int count, int[] refIDs)
 {
     if (count == 0)
     {
         return(null);
     }
     GcObject[] result = new GcObject[count];
     for (int i = 0; i < count; i++)
     {
         result[i] = GetOrCreateObject(refIDs[i]);
     }
     return(result);
 }
Exemple #15
0
        void FillInForwardReferences(ulong address, GcObject target)
        {
            ForwardReference forwardReference;

            if (addressToForwardReferences.TryGetValue(address, out forwardReference))
            {
                while (forwardReference != null)
                {
                    forwardReference.source.SetReference(forwardReference.referenceNumber, target);
                    forwardReference = forwardReference.next;
                }
            }
            addressToForwardReferences.Remove(address);
        }
Exemple #16
0
        internal void AssignInterestLevelToObject(ulong id, GcObject gcObject, BuildTypeGraphOptions options, FilterForm filterForm, bool isRoot)
        {
            bool isInteresting = gcObject.Type(this).interestLevel == InterestLevel.Interesting &&
                                 filterForm.IsInterestingAddress(id);

            if (isInteresting && filterForm.signatureFilters.Length != 0)
            {
                string signature = SignatureOfObject(id, gcObject, BuildTypeGraphOptions.LumpBySignature);
                isInteresting = filterForm.IsInterestingTypeName(gcObject.Type(this).name, signature,
                                                                 readNewLog.finalizableTypes.ContainsKey(gcObject.Type(this).typeID));
            }

            if (isInteresting)
            {
                gcObject.InterestLevel = InterestLevel.Interesting;
                if (!isRoot)
                {
                    gcObject.InterestLevel |= filterForm.InterestLevelForParentsAndChildren();
                }
            }
            else
            {
                gcObject.InterestLevel = InterestLevel.Ignore;
            }

            // 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.
        }
Exemple #17
0
 void AssignLevel(GcObject parent, GcObject thisObject, int level)
 {
     if (thisObject.level > level)
     {
         thisObject.level  = level;
         thisObject.parent = parent;
         if (thisObject.references != null)
         {
             foreach (GcObject refObject in thisObject.references)
             {
                 AssignLevel(thisObject, refObject, level + 1);
             }
         }
     }
 }
Exemple #18
0
 internal void AddRootObject(GcObject rootObject, ulong rootID)
 {
     if (roots == null)
     {
         roots   = new GcObject[initialRootCount];
         rootIDs = new ulong[initialRootCount];
     }
     if (roots.Length < rootCount + 1)
     {
         GrowRoots();
     }
     rootIDs[rootCount] = rootID;
     roots[rootCount]   = rootObject;
     rootCount++;
 }
Exemple #19
0
        internal Vertex FindVertex(ulong id, GcObject gcObject, Graph graph, BuildTypeGraphOptions options)
        {
            Vertex vertex = gcObject.vertex;

            if (vertex != null)
            {
                return(vertex);
            }

            string signature = SignatureOfObject(id, gcObject, options);

            vertex          = graph.FindOrCreateVertex(gcObject.Type(this).name, signature, null);
            gcObject.vertex = vertex;

            return(vertex);
        }
            internal GcObject this[ulong objectID]
            {
                get
                {
                    int lowBits  = (int)(objectID & lowAddressMask);
                    int highBits = (int)(objectID >> lowAddressBits);
                    if (highBits >= masterTable.Length)
                    {
                        return(null);
                    }

                    GcObject[] subTable = masterTable[highBits];
                    if (subTable == null)
                    {
                        return(null);
                    }

                    int bucket = lowBits >> bucketBits;
                    lowBits = (lowBits >> alignBits) & idMask;
                    GcObject o = subTable[bucket];
                    while (o != null && o.Id != lowBits)
                    {
                        o = o.nextInHash;
                    }

                    return(o);
                }
                set
                {
                    int lowBits  = (int)(objectID & lowAddressMask);
                    int highBits = (int)(objectID >> lowAddressBits);
                    while (highBits >= masterTable.Length)
                    {
                        GrowMasterTable();
                    }
                    GcObject[] subTable = masterTable[highBits];
                    if (subTable == null)
                    {
                        masterTable[highBits] = subTable = new GcObject[1 << (lowAddressBits - bucketBits)];
                    }
                    int bucket = lowBits >> bucketBits;
                    lowBits          = (lowBits >> alignBits) & idMask;
                    value.Id         = lowBits;
                    value.nextInHash = subTable[bucket];
                    subTable[bucket] = value;
                }
            }
Exemple #21
0
        internal void PrintStackTrace(ulong[] path)
        {
            System.Console.WriteLine("<StackTrace>");
            if ((path != null) && (path.Length > 0))
            {
                GcObject tempGcObject = idToObject[path[path.Length - 1]];
                Console.WriteLine("<!-- ");
                int[] stacktrace = readNewLog.stacktraceTable.IndexToStacktrace(tempGcObject.TypeSizeStackTraceId);
                for (int i = stacktrace.Length - 1; i >= 2; i--)
                {
                    System.Console.WriteLine("{0} <-", readNewLog.funcName[stacktrace[i]]);
                }

                Console.WriteLine("-->");
            }
            System.Console.WriteLine("</StackTrace>");
        }
Exemple #22
0
 internal void PrintGCRoot(ulong[] path)
 {
     Console.WriteLine("<GcRoot>");
     Console.WriteLine("<!-- ");
     for (int j = 0; j < path.Length; j++)
     {
         GcObject temp = idToObject[path[j]];
         if (temp != null)
         {
             System.Console.WriteLine("{0}, {1:X} ->", temp.Type(this).name, path[j]);
         }
         //else
         //  System.Console.WriteLine("{0}, n/a ->", path[j]);
     }
     Console.WriteLine("-->");
     Console.WriteLine("</GcRoot>");
 }
Exemple #23
0
        private void AssignInterestLevels()
        {
            foreach (GcType gcType in typeNameToGcType.Values)
            {
                // Otherwise figure which the interesting types are.
                gcType.interestLevel = FilterForm.InterestLevelOfTypeName(gcType.name);
            }

            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);
                }
            }
        }
Exemple #24
0
 public IEnumerator <KeyValuePair <ulong, GcObject> > GetEnumerator()
 {
     for (int i = 0; i < masterTable.Length; i++)
     {
         GcObject[] subTable = masterTable[i];
         if (subTable == null)
         {
             continue;
         }
         for (int j = 0; j < subTable.Length; j++)
         {
             for (GcObject gcObject = subTable[j]; gcObject != null; gcObject = gcObject.nextInHash)
             {
                 yield return(new KeyValuePair <ulong, GcObject>(((ulong)i << lowAddressBits) +
                                                                 ((ulong)j << bucketBits) +
                                                                 ((ulong)gcObject.Id << alignBits), gcObject));
             }
         }
     }
 }
Exemple #25
0
 private void MarkObject(GcObject o)
 {
     if (o.hint < nextHintIndex && hintTable[o.hint] == o)
     {
         return;
     }
     if (nextHintIndex >= hintTable.Length)
     {
         hintTable = GrowHintTable(hintTable);
     }
     o.hint            = nextHintIndex++;
     hintTable[o.hint] = o;
     if (o.references != null)
     {
         foreach (GcObject refObject in o.references)
         {
             MarkObject(refObject);
         }
     }
 }
Exemple #26
0
        internal GcObject CreateObject(int typeSizeStackTraceId, int numberOfReferences, ulong[] references)
        {
            GcObject o = GcObject.CreateGcObject(numberOfReferences);

            o.TypeSizeStackTraceId = typeSizeStackTraceId;

            for (int i = 0; i < numberOfReferences; i++)
            {
                GcObject target = idToObject[references[i]];
                if (target != null)
                {
                    o.SetReference(i, target);
                }
                else
                {
                    CreateForwardReference(references[i], o, i);
                }
            }
            empty = false;
            return(o);
        }
Exemple #27
0
        internal Graph BuildTypeGraph1()
        {
            Graph graph = new Graph(this);

            graph.graphType = Graph.GraphType.HeapGraph;

            GcType   rootType   = GetOrCreateGcType("<root>");
            GcObject rootObject = GetOrCreateObject(0);

            rootObject.type       = rootType;
            rootObject.references = roots;

            foreach (GcObject gcObject in idToObject.Values)
            {
                rootObject.size += gcObject.size;
                if (gcObject.references != null)
                {
                    Vertex fromVertex = graph.FindOrCreateVertex(gcObject.type.name, null);

                    foreach (GcObject toObject in gcObject.references)
                    {
                        Vertex toVertex = graph.FindOrCreateVertex(toObject.type.name, null);
                        graph.FindOrCreateEdge(fromVertex, toVertex);
                    }
                }
            }

            CalculateWeightsNonTransitive(graph);

            foreach (Vertex v in graph.vertices.Values)
            {
                v.active = true;
            }
            graph.BottomVertex.active = false;

            return(graph);
        }
Exemple #28
0
        void AssignParents(GcObject rootObject)
        {
            // We use a breadth first traversal of the object graph.
            // To do this, we make use of a queue of objects still to process.

            // Initialize
            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 = head;
                        queue.Enqueue(refObject);
                    }
                }
            }
        }
 internal override void SetReference(int referenceNumber, GcObject target)
 {
     Debug.Assert(referenceNumber == 0);
     reference0 = target;
 }
Exemple #30
0
        internal Graph BuildTypeGraph()
        {
            if (graph == null || FilterForm.filterVersion != graphFilterVersion)
            {
                graph              = new Graph(this);
                graph.graphType    = Graph.GraphType.HeapGraph;
                graphFilterVersion = FilterForm.filterVersion;
            }
            else
            {
                foreach (Vertex v in graph.vertices.Values)
                {
                    if (v.weightHistory == null)
                    {
                        v.weightHistory = new int[1];
                    }
                    else
                    {
                        int[] weightHistory = v.weightHistory;
                        if (weightHistory.Length < historyDepth)
                        {
                            v.weightHistory = new int[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 = v.count = 0;
                    foreach (Edge e in v.outgoingEdges.Values)
                    {
                        e.weight = 0;
                    }
                }
            }

            GcType   rootType   = GetOrCreateGcType("<root>");
            GcObject rootObject = GetOrCreateObject(0);

            rootObject.type       = rootType;
            rootObject.references = roots;

            foreach (GcObject gcObject in idToObject.Values)
            {
                gcObject.level  = int.MaxValue;
                gcObject.vertex = null;
            }

            AssignLevel(null, rootObject, 0);

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

                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 int[1];
                }
            }

            foreach (Vertex v in graph.vertices.Values)
            {
                v.active = true;
            }
            graph.BottomVertex.active = false;

            return(graph);
        }