Exemplo n.º 1
0
        private void CrawlRawObjectData(PackedMemorySnapshot packedMemorySnapshot, StartIndices startIndices, BytesAndOffset bytesAndOffset, TypeDescription typeDescription, bool useStaticFields, int indexOfFrom, List <Connection> out_connections, List <PackedManagedObject> out_managedObjects)
        {
            foreach (var field in TypeTools.AllFieldsOf(typeDescription, _typeDescriptions, useStaticFields ? TypeTools.FieldFindOptions.OnlyStatic : TypeTools.FieldFindOptions.OnlyInstance))
            {
                if (field.typeIndex == typeDescription.typeIndex && typeDescription.isValueType)
                {
                    //this happens in System.Single, which is a weird type that has a field of its own type.
                    continue;
                }

                if (field.offset == -1)
                {
                    //this is how we encode TLS fields. todo: actually treat TLS fields as roots
                    continue;
                }

                var fieldType = packedMemorySnapshot.typeDescriptions[field.typeIndex];

                var fieldLocation = bytesAndOffset.Add(field.offset - (useStaticFields ? 0 : _virtualMachineInformation.objectHeaderSize));

                if (fieldType.isValueType)
                {
                    CrawlRawObjectData(packedMemorySnapshot, startIndices, fieldLocation, fieldType, false, indexOfFrom, out_connections, out_managedObjects);
                    continue;
                }

                //temporary workaround for a bug in 5.3b4 and earlier where we would get literals returned as fields with offset 0. soon we'll be able to remove this code.
                bool gotException = false;
                try {
                    fieldLocation.ReadPointer();
                } catch (ArgumentException) {
                    UnityEngine.Debug.LogWarningFormat("Skipping field {0} on type {1}", field.name, typeDescription.name);
                    UnityEngine.Debug.LogWarningFormat("FieldType.name: {0}", fieldType.name);
                    gotException = true;
                }

                if (!gotException)
                {
                    CrawlPointer(packedMemorySnapshot, startIndices, fieldLocation.ReadPointer(), indexOfFrom, out_connections, out_managedObjects);
                }
            }
        }
Exemplo n.º 2
0
        public PackedCrawlerData Crawl(PackedMemorySnapshot input)
        {
            UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "init", 0);
            _typeInfoToTypeDescription = input.typeDescriptions.ToDictionary(td => td.typeInfoAddress, td => td);
            _virtualMachineInformation = input.virtualMachineInformation;
            _typeDescriptions          = input.typeDescriptions;
            _instanceFields            = new FieldDescription[_typeDescriptions.Length][];
            _staticFields = new FieldDescription[_typeDescriptions.Length][];

            foreach (var type in _typeDescriptions)
            {
                _instanceFields[type.typeIndex] = TypeTools.AllFieldsOf(type, _typeDescriptions, TypeTools.FieldFindOptions.OnlyInstance).ToArray();
                _staticFields[type.typeIndex]   = TypeTools.AllFieldsOf(type, _typeDescriptions, TypeTools.FieldFindOptions.OnlyStatic).ToArray();
            }

            UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "adding connections", 0.1f);
            var result = new PackedCrawlerData(input);

            var managedObjects = new List <PackedManagedObject>(result.startIndices.OfFirstManagedObject * 3);

            var connections = new List <Connection>(managedObjects.Capacity * 3);

            //we will be adding a lot of connections, but the input format also already had connections. (nativeobject->nativeobject and nativeobject->gchandle). we'll add ours to the ones already there.
            connections.AddRange(input.connections);

            UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "adding thing to profile", 0.2f);

            Stack <ThingToProfile> thingsToProfile = new Stack <ThingToProfile>();

            for (int i = 0; i < input.gcHandles.Length; ++i)
            {
                thingsToProfile.Push(new ThingToProfile(input.gcHandles[i].target, result.startIndices.OfFirstGCHandle + i));
            }

            for (int i = 0; i < result.typesWithStaticFields.Length; i++)
            {
                var typeDescription = result.typesWithStaticFields[i];
                thingsToProfile.Push(new ThingToProfile(typeDescription, new BytesAndOffset {
                    bytes = typeDescription.staticFieldBytes, offset = 0, pointerSize = _virtualMachineInformation.pointerSize
                }, true, result.startIndices.OfFirstStaticFields + i));
            }

            UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "crawlpointer and crawlrawobjectdata", 0.3f);

            int totalCount = thingsToProfile.Count;

            while (thingsToProfile.Count > 0)
            {
                var thingToProfile = thingsToProfile.Pop();
                if (thingToProfile.type == PointerType.Reference)
                {
                    CrawlPointerNonRecursive(input, result.startIndices, thingToProfile.objectPointer, thingToProfile.indexOfFrom, connections, managedObjects, thingsToProfile);
                }
                else
                {
                    CrawlRawObjectDataNonRecursive(input, result.startIndices, thingToProfile.bytesAndOffset, thingToProfile.typeDescription, thingToProfile.useStaticFields, thingToProfile.indexOfFrom, connections, managedObjects, thingsToProfile);
                }
                int leftCount = thingsToProfile.Count;
                if (leftCount % 5 == 0 && UnityEditor.EditorUtility.DisplayCancelableProgressBar("Crawl", string.Format("crawlpointer and crawlrawobjectdata (left:{0}/initial:{1})", leftCount, totalCount), 0.3f + 0.5f * (totalCount - (leftCount > 0 ? leftCount : 0)) / totalCount))
                {
                    break;
                }
            }

            UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "composing result", 0.8f);

            result.managedObjects = managedObjects.ToArray();
            connections.AddRange(AddManagedToNativeConnectionsAndRestoreObjectHeaders(input, result.startIndices, result));
            result.connections = connections.ToArray();

            UnityEditor.EditorUtility.DisplayProgressBar("Crawl", "finish.", 1.0f);
            UnityEditor.EditorUtility.ClearProgressBar();

            return(result);
        }