源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
6.2 KiB

  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEditor.MemoryProfiler;
  4. using System;
  5. using UnityEngine;
  6. namespace MemoryProfilerWindow
  7. {
  8. class CrawlDataUnpacker
  9. {
  10. public static CrawledMemorySnapshot Unpack(PackedCrawlerData packedCrawlerData)
  11. {
  12. var packedSnapshot = packedCrawlerData.packedMemorySnapshot;
  13. var result = new CrawledMemorySnapshot
  14. {
  15. nativeObjects = packedSnapshot.nativeObjects.Select(packedNativeUnityEngineObject => UnpackNativeUnityEngineObject(packedSnapshot, packedNativeUnityEngineObject)).ToArray(),
  16. managedObjects = packedCrawlerData.managedObjects.Select(pm => UnpackManagedObject(packedSnapshot, pm)).ToArray(),
  17. gcHandles = packedSnapshot.gcHandles.Select(pgc => UnpackGCHandle(packedSnapshot)).ToArray(),
  18. staticFields = packedSnapshot.typeDescriptions.Where(t => t.staticFieldBytes != null & t.staticFieldBytes.Length > 0).Select(t => UnpackStaticFields(t)).ToArray(),
  19. typeDescriptions = packedSnapshot.typeDescriptions,
  20. managedHeap = packedSnapshot.managedHeapSections,
  21. nativeTypes = packedSnapshot.nativeTypes,
  22. virtualMachineInformation = packedSnapshot.virtualMachineInformation
  23. };
  24. var combined = new ThingInMemory[0].Concat(result.gcHandles).Concat(result.nativeObjects).Concat(result.staticFields).Concat(result.managedObjects).ToArray();
  25. result.allObjects = combined;
  26. var referencesLists = MakeTempLists(combined);
  27. var referencedByLists = MakeTempLists(combined);
  28. foreach (var connection in packedCrawlerData.connections)
  29. {
  30. referencesLists[connection.@from].Add(combined[connection.to]);
  31. referencedByLists[connection.to].Add(combined[connection.@from]);
  32. }
  33. for (var i = 0; i != combined.Length; i++)
  34. {
  35. combined[i].references = referencesLists[i].ToArray();
  36. combined[i].referencedBy = referencedByLists[i].ToArray();
  37. }
  38. return result;
  39. }
  40. static List<ThingInMemory>[] MakeTempLists(ThingInMemory[] combined)
  41. {
  42. var referencesLists = new List<ThingInMemory>[combined.Length];
  43. for (int i = 0; i != referencesLists.Length; i++)
  44. referencesLists[i] = new List<ThingInMemory>(4);
  45. return referencesLists;
  46. }
  47. static StaticFields UnpackStaticFields(TypeDescription typeDescription)
  48. {
  49. return new StaticFields()
  50. {
  51. typeDescription = typeDescription,
  52. caption = "static fields of " + typeDescription.name,
  53. size = typeDescription.staticFieldBytes.Length
  54. };
  55. }
  56. static GCHandle UnpackGCHandle(PackedMemorySnapshot packedSnapshot)
  57. {
  58. return new GCHandle() { size = packedSnapshot.virtualMachineInformation.pointerSize, caption = "gchandle" };
  59. }
  60. static ManagedObject UnpackManagedObject(PackedMemorySnapshot packedSnapshot, PackedManagedObject pm)
  61. {
  62. var typeDescription = packedSnapshot.typeDescriptions[pm.typeIndex];
  63. return new ManagedObject() { address = pm.address, size = pm.size, typeDescription = typeDescription, caption = typeDescription.name };
  64. }
  65. static NativeUnityEngineObject UnpackNativeUnityEngineObject(PackedMemorySnapshot packedSnapshot, PackedNativeUnityEngineObject packedNativeUnityEngineObject)
  66. {
  67. var className = packedSnapshot.nativeTypes[packedNativeUnityEngineObject.nativeTypeArrayIndex].name;
  68. return new NativeUnityEngineObject()
  69. {
  70. instanceID = packedNativeUnityEngineObject.instanceId,
  71. classID = packedNativeUnityEngineObject.nativeTypeArrayIndex,
  72. className = className,
  73. name = packedNativeUnityEngineObject.name,
  74. caption = packedNativeUnityEngineObject.name + "(" + className + ")",
  75. size = packedNativeUnityEngineObject.size,
  76. isPersistent = packedNativeUnityEngineObject.isPersistent,
  77. isDontDestroyOnLoad = packedNativeUnityEngineObject.isDontDestroyOnLoad,
  78. isManager = packedNativeUnityEngineObject.isManager,
  79. hideFlags = packedNativeUnityEngineObject.hideFlags
  80. };
  81. }
  82. }
  83. [System.Serializable]
  84. internal class PackedCrawlerData
  85. {
  86. public bool valid;
  87. public PackedMemorySnapshot packedMemorySnapshot;
  88. public StartIndices startIndices;
  89. public PackedManagedObject[] managedObjects;
  90. public TypeDescription[] typesWithStaticFields;
  91. public Connection[] connections;
  92. public PackedCrawlerData(PackedMemorySnapshot packedMemorySnapshot)
  93. {
  94. this.packedMemorySnapshot = packedMemorySnapshot;
  95. typesWithStaticFields = packedMemorySnapshot.typeDescriptions.Where(t => t.staticFieldBytes != null && t.staticFieldBytes.Length > 0).ToArray();
  96. startIndices = new StartIndices(this.packedMemorySnapshot.gcHandles.Length, this.packedMemorySnapshot.nativeObjects.Length, typesWithStaticFields.Length);
  97. valid = true;
  98. }
  99. }
  100. [System.Serializable]
  101. internal class StartIndices
  102. {
  103. [SerializeField]
  104. private int _gcHandleCount;
  105. [SerializeField]
  106. private int _nativeObjectCount;
  107. [SerializeField]
  108. private int _staticFieldsCount;
  109. public StartIndices(int gcHandleCount, int nativeObjectCount, int staticFieldsCount)
  110. {
  111. _gcHandleCount = gcHandleCount;
  112. _nativeObjectCount = nativeObjectCount;
  113. _staticFieldsCount = staticFieldsCount;
  114. }
  115. public int OfFirstGCHandle { get { return 0; } }
  116. public int OfFirstNativeObject { get { return OfFirstGCHandle + _gcHandleCount; } }
  117. public int OfFirstStaticFields { get { return OfFirstNativeObject + _nativeObjectCount; } }
  118. public int OfFirstManagedObject { get { return OfFirstStaticFields + _staticFieldsCount; } }
  119. }
  120. }