Ejemplo n.º 1
0
        public static IEnumerator Convert(LegacyPackedMemorySnapshot snapshot, string writePath)
        {
            if (snapshot == null)
            {
                Debug.LogError("Parameter 'snapshot' was null.");
                yield break;
            }

            //using fully qualified name in advance to us moving both writer/reader to package
            UnityEditorInternal.Profiling.Memory.Experimental.MemorySnapshotFileWriter writer = null;
            try
            {
                writer = new UnityEditorInternal.Profiling.Memory.Experimental.MemorySnapshotFileWriter(writePath);
            }
            catch (Exception e)
            {
                Debug.LogError("Failed to create snapshot file: " + e.Message);
                yield break;
            }

            var status = new EnumerationStatus(kCurrentConversionStepCount);

            status.StepStatus = "Writing metadata";
            yield return(status);

            //snapshot version will always be the current one for conversion operations
            writer.WriteEntry(EntryType.Metadata_Version, kCurrentVersion);

            //timestamp with conversion date
            writer.WriteEntry(EntryType.Metadata_RecordDate, (ulong)DateTime.Now.Ticks);

            //prepare metadata
            string platform         = "Unknown";
            string content          = "Converted Snapshot";
            int    stringDataLength = (platform.Length + content.Length) * sizeof(char);

            byte[] metaDataBytes = new byte[stringDataLength + (sizeof(int) * 3)]; // add space for serializing the lengths of the strings

            int offset = 0;

            offset = WriteIntToByteArray(metaDataBytes, offset, content.Length);
            offset = WriteStringToByteArray(metaDataBytes, offset, content);
            offset = WriteIntToByteArray(metaDataBytes, offset, platform.Length);
            offset = WriteStringToByteArray(metaDataBytes, offset, platform);
            offset = WriteIntToByteArray(metaDataBytes, offset, 0);

            // Write metadata
            writer.WriteEntryArray(EntryType.Metadata_UserMetadata, metaDataBytes);

            writer.WriteEntry(EntryType.Metadata_CaptureFlags, (UInt32)UnityEngine.Profiling.Memory.Experimental.CaptureFlags.ManagedObjects); //capture just managed

            // Write managed heap sections
            status.IncrementStep();
            status.StepStatus = "Writing managed heap sections.";
            yield return(status);

            for (int i = 0; i < snapshot.m_ManagedHeapSections.Length; ++i)
            {
                var heapSection = snapshot.m_ManagedHeapSections[i];
                writer.WriteEntry(EntryType.ManagedHeapSections_StartAddress, heapSection.m_StartAddress);
                writer.WriteEntryArray(EntryType.ManagedHeapSections_Bytes, heapSection.m_Bytes);
            }

            // Write managed types
            int fieldDescriptionCount = 0;

            status.IncrementStep();
            status.StepStatus = string.Format("Writing managed type descriptions.");
            yield return(status);

            for (int i = 0; i < snapshot.m_TypeDescriptions.Length; ++i)
            {
                var type = snapshot.m_TypeDescriptions[i];
                writer.WriteEntry(EntryType.TypeDescriptions_Flags, (UInt32)type.m_Flags);
                writer.WriteEntry(EntryType.TypeDescriptions_BaseOrElementTypeIndex, type.m_BaseOrElementTypeIndex);
                writer.WriteEntry(EntryType.TypeDescriptions_TypeIndex, type.m_TypeIndex);

                if (!type.IsArray)
                {
                    var   typeFields   = type.m_Fields;
                    int[] fieldIndices = new int[typeFields.Length];

                    for (int j = 0; j < typeFields.Length; ++j)
                    {
                        var field = typeFields[j];
                        fieldIndices[j] = fieldDescriptionCount;
                        ++fieldDescriptionCount;

                        writer.WriteEntry(EntryType.FieldDescriptions_Offset, field.m_Offset);
                        writer.WriteEntry(EntryType.FieldDescriptions_TypeIndex, field.m_TypeIndex);
                        writer.WriteEntry(EntryType.FieldDescriptions_Name, field.m_Name);
                        writer.WriteEntry(EntryType.FieldDescriptions_IsStatic, field.m_IsStatic);
                    }

                    writer.WriteEntryArray(EntryType.TypeDescriptions_FieldIndices, fieldIndices);
                    writer.WriteEntryArray(EntryType.TypeDescriptions_StaticFieldBytes, type.m_StaticFieldBytes);
                }
                else
                {
                    writer.WriteEntryArray(EntryType.TypeDescriptions_FieldIndices, new int[0]);
                    writer.WriteEntryArray(EntryType.TypeDescriptions_StaticFieldBytes, new byte[0]);
                }

                writer.WriteEntry(EntryType.TypeDescriptions_Name, type.m_Name);
                writer.WriteEntry(EntryType.TypeDescriptions_Assembly, type.m_Assembly);
                writer.WriteEntry(EntryType.TypeDescriptions_TypeInfoAddress, type.m_TypeInfoAddress);
                writer.WriteEntry(EntryType.TypeDescriptions_Size, type.m_Size);
            }

            //write managed GC handles
            status.IncrementStep();
            status.StepStatus = "Writing managed object handles.";
            yield return(status);

            for (int i = 0; i < snapshot.m_GCHandles.Length; ++i)
            {
                var handle = snapshot.m_GCHandles[i];
                writer.WriteEntry(EntryType.GCHandles_Target, handle.m_Target);
            }

            //write managed connections
            status.IncrementStep();
            status.StepStatus = "Writing connections.";
            yield return(status);

            for (int i = 0; i < snapshot.m_Connections.Length; ++i)
            {
                var connection = snapshot.m_Connections[i];
                writer.WriteEntry(EntryType.Connections_From, connection.m_From);
                writer.WriteEntry(EntryType.Connections_To, connection.m_To);
            }

            //write native types
            status.IncrementStep();
            status.StepStatus = "Writing native type descriptions.";
            yield return(status);

            for (int i = 0; i < snapshot.m_NativeTypes.Length; ++i)
            {
                var nativeType = snapshot.m_NativeTypes[i];
                writer.WriteEntry(EntryType.NativeTypes_NativeBaseTypeArrayIndex, nativeType.m_NativeBaseTypeArrayIndex);
                writer.WriteEntry(EntryType.NativeTypes_Name, nativeType.m_Name);
            }

            //write stub root reference for all native objects to point to, as the old format did not capture these
            writer.WriteEntry(EntryType.NativeRootReferences_AreaName, "Invalid Root");
            writer.WriteEntry(EntryType.NativeRootReferences_AccumulatedSize, (ulong)0);
            writer.WriteEntry(EntryType.NativeRootReferences_Id, (long)0);
            writer.WriteEntry(EntryType.NativeRootReferences_ObjectName, "Invalid Root Object");

            //write native objects
            status.IncrementStep();
            status.StepStatus = "Writing native object descriptions.";
            yield return(status);

            for (int i = 0; i < snapshot.m_NativeObjects.Length; ++i)
            {
                var nativeObject = snapshot.m_NativeObjects[i];
                writer.WriteEntry(EntryType.NativeObjects_Name, nativeObject.m_Name);
                writer.WriteEntry(EntryType.NativeObjects_InstanceId, nativeObject.m_InstanceId);
                writer.WriteEntry(EntryType.NativeObjects_Size, (ulong)nativeObject.m_Size);
                writer.WriteEntry(EntryType.NativeObjects_NativeTypeArrayIndex, nativeObject.m_NativeTypeArrayIndex);
                writer.WriteEntry(EntryType.NativeObjects_HideFlags, (UInt32)nativeObject.m_HideFlags);
                writer.WriteEntry(EntryType.NativeObjects_Flags, (UInt32)nativeObject.m_Flags);
                writer.WriteEntry(EntryType.NativeObjects_NativeObjectAddress, (ulong)nativeObject.m_NativeObjectAddress);
                writer.WriteEntry(EntryType.NativeObjects_RootReferenceId, (long)0);
            }

            //write virtual machine information
            status.IncrementStep();
            status.StepStatus = "Writing virtual machine information.";
            yield return(status);

            writer.WriteEntry(EntryType.Metadata_VirtualMachineInformation, snapshot.m_VirtualMachineInformation);

            writer.Dispose();
        }