static bool CrawlPointer(IntermediateCrawlData dataStack)
        {
            UnityEngine.Debug.Assert(dataStack.CrawlDataStack.Count > 0);

            var snapshot                  = dataStack.CachedMemorySnapshot;
            var typeDescriptions          = snapshot.typeDescriptions;
            var data                      = dataStack.CrawlDataStack.Pop();
            var virtualMachineInformation = snapshot.virtualMachineInformation;
            var managedHeapSections       = snapshot.managedHeapSections;
            var byteOffset                = managedHeapSections.Find(data.ptr, virtualMachineInformation);

            if (!byteOffset.IsValid)
            {
                return(false);
            }

            ManagedObjectInfo obj;
            bool wasAlreadyCrawled;

            obj = ParseObjectHeader(snapshot, data.ptr, out wasAlreadyCrawled, false);
            ++obj.RefCount;

            snapshot.CrawledData.ManagedObjects[obj.ManagedObjectIndex] = obj;
            snapshot.CrawledData.ManagedObjectByAddress[obj.PtrObject]  = obj;

            dataStack.ManagedConnections.Add(ManagedConnection.MakeConnection(snapshot, data.indexOfFrom, data.ptrFrom, obj.ManagedObjectIndex, data.ptr, data.typeFrom, data.fieldFrom, data.fromArrayIndex));

            if (!obj.IsKnownType())
            {
                return(false);
            }
            if (wasAlreadyCrawled)
            {
                return(true);
            }

            if (!typeDescriptions.HasFlag(obj.ITypeDescription, TypeFlags.kArray))
            {
                CrawlRawObjectData(dataStack, byteOffset.Add(snapshot.virtualMachineInformation.objectHeaderSize), obj.ITypeDescription, false, data.ptr, obj.ManagedObjectIndex);
                return(true);
            }

            var arrayLength             = ArrayTools.ReadArrayLength(snapshot, data.ptr, obj.ITypeDescription);
            int iElementTypeDescription = typeDescriptions.baseOrElementTypeIndex[obj.ITypeDescription];

            if (iElementTypeDescription == -1)
            {
                return(false); //do not crawl uninitialized object types, as we currently don't have proper handling for these
            }
            var arrayData = byteOffset.Add(virtualMachineInformation.arrayHeaderSize);

            for (int i = 0; i != arrayLength; i++)
            {
                if (typeDescriptions.HasFlag(iElementTypeDescription, TypeFlags.kValueType))
                {
                    CrawlRawObjectData(dataStack, arrayData, iElementTypeDescription, false, data.ptr, obj.ManagedObjectIndex);
                    arrayData = arrayData.Add(typeDescriptions.size[iElementTypeDescription]);
                }
                else
                {
                    dataStack.CrawlDataStack.Push(new StackCrawlData()
                    {
                        ptr = arrayData.ReadPointer(), ptrFrom = data.ptr, typeFrom = obj.ITypeDescription, indexOfFrom = obj.ManagedObjectIndex, fieldFrom = -1, fromArrayIndex = i
                    });
                    arrayData = arrayData.NextPointer();
                }
            }
            return(true);
        }
示例#2
0
        public bool IsGroupExpandable(ObjectData od, bool forceExpandAllObject = false)
        {
            switch (od.dataType)
            {
            case ObjectDataType.Array:
            {
                var l = ArrayTools.ReadArrayLength(Snapshot, od.hostManagedObjectPtr, od.managedTypeIndex);
                return(l > 0 || forceExpandAllObject);
            }

            case ObjectDataType.ReferenceArray:
            {
                var ptr = od.GetReferencePointer();
                if (ptr != 0)
                {
                    var arr = ObjectData.FromManagedPointer(Snapshot, ptr);
                    var l   = ArrayTools.ReadArrayLength(Snapshot, arr.hostManagedObjectPtr, arr.managedTypeIndex);
                    return(l > 0 || forceExpandAllObject);
                }
                return(false);
            }

            case ObjectDataType.ReferenceObject:
            {
                ulong ptr = od.GetReferencePointer();
                if (ptr == 0)
                {
                    return(false);
                }
                var obj = ObjectData.FromManagedPointer(Snapshot, ptr);
                if (!obj.IsValid)
                {
                    return(false);
                }
                if (forceExpandAllObject)
                {
                    return(true);
                }
                if (!Formatter.IsExpandable(obj.managedTypeIndex))
                {
                    return(false);
                }
                return(Snapshot.typeDescriptions.HasAnyField(obj.managedTypeIndex));
            }

            case ObjectDataType.BoxedValue:
            case ObjectDataType.Object:
            case ObjectDataType.Value:
                if (forceExpandAllObject)
                {
                    return(true);
                }
                if (!Formatter.IsExpandable(od.managedTypeIndex))
                {
                    return(false);
                }
                return(Snapshot.typeDescriptions.HasAnyField(od.managedTypeIndex));

            case ObjectDataType.Type:
                if (!Formatter.IsExpandable(od.managedTypeIndex))
                {
                    return(false);
                }
                if (Formatter.flattenFields)
                {
                    return(Snapshot.typeDescriptions.HasAnyStaticField(od.managedTypeIndex));
                }
                else
                {
                    return(Snapshot.typeDescriptions.HasStaticField(od.managedTypeIndex));
                }

            default:
                return(false);
            }
        }