public static EditorWindow CreateWindow(PackedMemorySnapshot snapshot, AbstractMemoryReader memoryReader, System.UInt64 address, PackedManagedType type) { var visualizer = AbstractDataVisualizer.CreateVisualizer(type.name); if (visualizer == null) { Debug.LogWarningFormat("Could not create DataVisualizer for type '{0}'", type.name); return(null); } visualizer.Initialize(snapshot, memoryReader, address, type); var window = DataVisualizerWindow.CreateInstance <DataVisualizerWindow>(); window.SetVisualizer(visualizer); window.ShowUtility(); return(window); }
public void Initialize(ManagedHeapSectionsControl owner, PackedMemorySnapshot snapshot, int memorySegmentIndex) { m_Owner = owner; m_Snapshot = snapshot; arrayIndex = memorySegmentIndex; displayName = "MemorySection"; address = m_Snapshot.managedHeapSections[arrayIndex].startAddress; if (m_Snapshot.managedHeapSections[arrayIndex].bytes != null) { size = (ulong)m_Snapshot.managedHeapSections[arrayIndex].bytes.LongLength; #if HEAPEXPLORER_DISPLAY_REFS m_Snapshot.GetConnectionsCount(m_Snapshot.managedHeapSections[arrayIndex], out refs); #endif } }
// this method is a hack that excludes native object connections to workaround an unity bug. // https://forum.unity.com/threads/wip-heap-explorer-memory-profiler-debugger-and-analyzer-for-unity.527949/page-2#post-3615223 static PackedConnection[] ConnectionsFromMemoryProfilerWithoutNativeHACK(PackedMemorySnapshot snapshot, UnityEditor.MemoryProfiler.PackedMemorySnapshot source) { var managedStart = 0; var managedEnd = managedStart + source.gcHandles.Length; var nativeStart = managedStart + managedEnd; var nativeEnd = nativeStart + source.nativeObjects.Length; var output = new List <PackedConnection>(1024 * 1024); for (int n = 0, nend = source.connections.Length; n < nend; ++n) { if ((n % (nend / 100)) == 0) { var progress = ((n + 1.0f) / nend) * 100; snapshot.busyString = string.Format("Analyzing GCHandle Connections\n{0}/{1}, {2:F0}% done", n + 1, source.connections.Length, progress); } var connection = new PackedConnection { from = source.connections[n].from, to = source.connections[n].to, }; connection.fromKind = PackedConnection.Kind.GCHandle; if (connection.from >= nativeStart && connection.from < nativeEnd) { connection.from -= nativeStart; connection.fromKind = PackedConnection.Kind.Native; } connection.toKind = PackedConnection.Kind.GCHandle; if (connection.to >= nativeStart && connection.to < nativeEnd) { connection.to -= nativeStart; connection.toKind = PackedConnection.Kind.Native; } if (connection.fromKind != PackedConnection.Kind.Native) { output.Add(connection); } } snapshot.header.nativeObjectFromConnectionsExcluded = true; Debug.LogWarning("HeapExplorer: Native object 'from' connections are excluded due workaround an Unity bug. Thus the object connections in Heap Explorer show fewer connections than actually exist.\nhttps://forum.unity.com/threads/wip-heap-explorer-memory-profiler-debugger-and-analyzer-for-unity.527949/page-2#post-3615223"); return(output.ToArray()); }
public static GUIContent GetTypeContent(PackedMemorySnapshot snapshot, PackedManagedType type) { const string valueTypeLabel = "Value types are either stack-allocated or allocated inline in a structure."; const string referenceTypeLabel = "Reference types are heap-allocated."; if (type.isValueType) { if (snapshot.IsSubclassOf(type, snapshot.coreTypes.systemEnum)) { return(new GUIContent(csEnumTypeImage, valueTypeLabel)); } return(new GUIContent(csValueTypeImage, valueTypeLabel)); } return(new GUIContent(csReferenceTypeImage, referenceTypeLabel)); }
void ReceiveHeapThreaded(object userData) { var args = new MemorySnapshotProcessingArgs(); args.source = userData as UnityEditor.Profiling.Memory.Experimental.PackedMemorySnapshot; try { m_Heap = PackedMemorySnapshot.FromMemoryProfiler(args); m_Heap.Initialize(); } catch { m_CloseDueToError = true; throw; } }
void InspectInternal(PackedMemorySnapshot snapshot, PackedManagedObject managedObject) { m_Snapshot = snapshot; m_ManagedObject = managedObject; if (m_ManagedObject.address == 0) { m_ErrorString = "Cannot inspect 'null' address."; return; } var type = m_Snapshot.managedTypes[managedObject.managedTypesArrayIndex]; titleContent = new GUIContent(string.Format("C# Object Inspector | {0} | {1:X}", type.name, managedObject.address)); m_PropertyGrid = new PropertyGridControl(null, "ManagedObjectInspectorWindow.m_propertyGrid", new TreeViewState()); m_PropertyGrid.Inspect(m_Snapshot, managedObject); m_ErrorString = ""; }
void ReceiveHeapThreaded(object userData) { var args = new MemorySnapshotProcessingArgs(); args.source = userData as UnityEditor.MemoryProfiler.PackedMemorySnapshot; args.excludeNativeFromConnections = excludeNativeFromConnections; try { m_Heap = PackedMemorySnapshot.FromMemoryProfiler(args); m_Heap.Initialize(); } catch { m_CloseDueToError = true; throw; } }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot) { m_Snapshot = snapshot; m_UniqueId = 1; m_ManagedObjectCount = 0; m_ManagedObjectSize = 0; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null || m_Snapshot.managedObjects == null || m_Snapshot.managedObjects.Length == 0) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } OnBeforeBuildTree(); OnBuildTree(root); // remove groups if it contains one item only if (root.hasChildren) { for (int n = root.children.Count - 1; n >= 0; --n) { var group = root.children[n]; if (group.children.Count == 1) { group.children[0].depth -= 1; root.AddChild(group.children[0]); root.children.RemoveAt(n); continue; } } } SortItemsRecursive(root, OnSortItem); return(root); }
/// <summary> /// Converts an Unity PackedMemorySnapshot to our own format. /// </summary> public static PackedMemorySnapshot FromMemoryProfiler(MemorySnapshotProcessingArgs args) { var source = args.source; var value = new PackedMemorySnapshot(); try { VerifyMemoryProfilerSnapshot(source); value.busyString = "Loading Header"; value.header = PackedMemorySnapshotHeader.FromMemoryProfiler(); value.busyString = string.Format("Loading {0} Native Types", source.nativeTypes.GetNumEntries()); value.nativeTypes = PackedNativeType.FromMemoryProfiler(source); value.busyString = string.Format("Loading {0} Native Objects", source.nativeObjects.GetNumEntries()); value.nativeObjects = PackedNativeUnityEngineObject.FromMemoryProfiler(source); value.busyString = string.Format("Loading {0} GC Handles", source.gcHandles.GetNumEntries()); value.gcHandles = PackedGCHandle.FromMemoryProfiler(source); value.busyString = string.Format("Loading {0} Object Connections", source.connections.GetNumEntries()); value.connections = PackedConnection.FromMemoryProfiler(source); value.busyString = string.Format("Loading {0} Managed Heap Sections", source.managedHeapSections.GetNumEntries()); value.managedHeapSections = PackedMemorySection.FromMemoryProfiler(source); value.busyString = string.Format("Loading {0} Managed Types", source.typeDescriptions.GetNumEntries()); value.managedTypes = PackedManagedType.FromMemoryProfiler(source); value.busyString = "Loading VM Information"; value.virtualMachineInformation = PackedVirtualMachineInformation.FromMemoryProfiler(source); } catch (System.Exception e) { Debug.LogException(e); value = null; throw; } return(value); }
public void Inspect(PackedMemorySnapshot memory, System.UInt64 address, System.UInt64 size) { m_Segment = new ArraySegment64 <byte>(); if (address == 0) { return; } var heapIndex = memory.FindHeapOfAddress(address); if (heapIndex < 0) { return; } var heap = memory.managedHeapSections[heapIndex]; var segment = new ArraySegment64 <byte>(heap.bytes, address - heap.startAddress, size); Inspect(memory, address, segment); }
public void Inspect(PackedMemorySnapshot snapshot, PackedManagedObject managedObject) { m_Snapshot = snapshot; var m_type = snapshot.managedTypes[managedObject.managedTypesArrayIndex]; var m_address = managedObject.address; if (m_type.isValueType) { m_address -= (ulong)m_Snapshot.virtualMachineInformation.objectHeaderSize; } var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return; } var args = new PropertyGridItem.BuildChildrenArgs(); args.parent = root; args.type = m_type; args.address = m_address; args.memoryReader = new MemoryReader(snapshot); AddType(args); // add at least one item to the tree, otherwise it outputs an error if (!root.hasChildren) { root.AddChild(new TreeViewItem(1, 0, "")); } SetTree(root); TryCreateDataVisualizer(args.memoryReader, args.type, args.address, false); }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot) { m_Snapshot = snapshot; m_UniqueId = 1; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } for (int n = 0, nend = m_Snapshot.managedStaticTypes.Length; n < nend; ++n) { if (window.isClosing) // the window is closing { break; } var type = m_Snapshot.managedTypes[m_Snapshot.managedStaticTypes[n]]; var group = new StaticTypeItem { id = m_UniqueId++, depth = 0, displayName = "" }; group.Initialize(this, m_Snapshot, type); root.AddChild(group); } return(root); }
public static void GetInheritanceAsString(PackedMemorySnapshot snapshot, int managedTypesArrayIndex, System.Text.StringBuilder target) { var depth = 0; var loopguard = 0; while (managedTypesArrayIndex != -1) { for (var n = 0; n < depth; ++n) { target.Append(" "); } target.AppendFormat("{0}\n", snapshot.managedTypes[managedTypesArrayIndex].name); depth++; managedTypesArrayIndex = snapshot.managedTypes[managedTypesArrayIndex].baseOrElementTypeIndex; if (++loopguard > 64) { break; } } }
//public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, bool removeUnalignedSections = false) public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, PackedMemorySection[] sections) { m_Snapshot = snapshot; m_UniqueId = 1; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } for (int n = 0, nend = sections.Length; n < nend; ++n) { if (window.isClosing) // the window is closing { break; } var section = sections[n]; var item = new HeapSectionItem() { id = m_UniqueId++, depth = root.depth + 1, }; item.Initialize(this, m_Snapshot, section.arrayIndex); root.AddChild(item); } return(root); }
public void LoadFromFile(string path) { SaveView(); FreeMem(); HeMruFiles.AddPath(path); Reset(); m_Heap = null; if (useThreads) { var job = new LoadThreadJob { path = path, threadFunc = LoadFromFileThreaded }; ScheduleJob(job); } else { LoadFromFileThreaded(path); } }
public void Show(PackedMemorySnapshot heap) { if (snapshot != heap) { if (snapshot != null && isVisible) { Hide(); // Hide normally implements to save the layout of various UI elements } snapshot = heap; OnCreate(); } OnShow(); // Show any views that might have been added during OnShow() foreach (var v in m_Views) { v.Show(heap); } isVisible = true; Repaint(); }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshotA, PackedMemorySnapshot snapshotB) { var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (snapshotA == null || snapshotB == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } var uniqueId = 1; var snapshots = new[] { snapshotA, snapshotB }; BuildNativeTree(snapshots, ref uniqueId, root); BuildManagedTree(snapshots, ref uniqueId, root); BuildMemoryTree(snapshots, ref uniqueId, root); BuildGCHandleTree(snapshots, ref uniqueId, root); return(root); }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot) { m_Snapshot = snapshot; m_UniqueId = 1; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } for (int n = 0, nend = m_Snapshot.managedStaticTypes.Length; n < nend; ++n) { var type = m_Snapshot.managedTypes[m_Snapshot.managedStaticTypes[n]]; var group = new StaticTypeItem { id = m_UniqueId++, depth = 0, displayName = "" }; group.Initialize(this, m_Snapshot, type); root.AddChild(group); } SortItemsRecursive(root, OnSortItem); return(root); }
public void InspectStaticType(PackedMemorySnapshot snapshot, PackedManagedType managedType) { m_Snapshot = snapshot; var m_type = managedType; var m_address = 0ul; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return; } var args = new PropertyGridItem.BuildChildrenArgs(); args.parent = root; args.type = m_type; args.address = m_address; args.memoryReader = new StaticMemoryReader(snapshot, managedType.staticFieldBytes); AddType(args); // add at least one item to the tree, otherwise it outputs an error if (!root.hasChildren) { root.AddChild(new TreeViewItem(1, 0, "")); } SetTree(root); TryCreateDataVisualizer(args.memoryReader, args.type, args.address, false); }
public static Texture2D GetTypeImage(PackedMemorySnapshot snapshot, PackedManagedType type) { if (type.isArray) { return(csReferenceTypeImage); } if (type.isValueType) { if (snapshot.IsSubclassOf(type, snapshot.coreTypes.systemEnum)) { return(csEnumTypeImage); } return(csValueTypeImage); } if (snapshot.IsSubclassOf(type, snapshot.coreTypes.systemDelegate)) { return(csDelegateTypeImage); } return(csReferenceTypeImage); }
public void Initialize(ConnectionsControl owner, PackedMemorySnapshot snapshot, PackedNativeUnityEngineObject nativeObject) { m_Owner = owner; m_Snapshot = snapshot; m_NativeObject = new RichNativeObject(snapshot, nativeObject.nativeObjectsArrayIndex); m_Value = m_NativeObject.name; address = m_NativeObject.address; displayName = m_NativeObject.type.name; // If it's a MonoBehaviour or ScriptableObject, use the C# typename instead // It makes it easier to understand what it is, otherwise everything displays 'MonoBehaviour' only. if (m_NativeObject.type.IsSubclassOf(m_Snapshot.coreTypes.nativeMonoBehaviour) || m_NativeObject.type.IsSubclassOf(m_Snapshot.coreTypes.nativeScriptableObject)) { string monoScriptName; if (m_Snapshot.FindNativeMonoScriptType(m_NativeObject.packed.nativeObjectsArrayIndex, out monoScriptName) != -1) { if (!string.IsNullOrEmpty(monoScriptName)) { displayName = monoScriptName; } } } }
public void Initialize(PackedMemorySnapshot snapshot, int managedTypesArrayIndex) { m_Type = new RichManagedType(snapshot, managedTypesArrayIndex); }
public void Initialize(GCHandlesControl owner, PackedMemorySnapshot snapshot, int gcHandlesArrayIndex) { m_Owner = owner; m_GCHandle = new RichGCHandle(snapshot, gcHandlesArrayIndex); }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot) { m_Snapshot = snapshot; m_UniqueId = 1; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } // int=typeIndex var groupLookup = new Dictionary <int, GroupItem>(); for (int n = 0, nend = m_Snapshot.gcHandles.Length; n < nend; ++n) { var gcHandle = m_Snapshot.gcHandles[n]; var managedTypeIndex = -1; if (gcHandle.managedObjectsArrayIndex >= 0) { managedTypeIndex = m_Snapshot.managedObjects[gcHandle.managedObjectsArrayIndex].managedTypesArrayIndex; } var targetItem = root; if (managedTypeIndex >= 0) { GroupItem group; if (!groupLookup.TryGetValue(managedTypeIndex, out group)) { group = new GroupItem { id = m_UniqueId++, depth = 0, displayName = "" }; group.Initialize(m_Snapshot, managedTypeIndex); groupLookup[managedTypeIndex] = group; root.AddChild(group); } targetItem = group; } var item = new GCHandleItem { id = m_UniqueId++, depth = targetItem.depth + 1, displayName = "" }; item.Initialize(this, m_Snapshot, gcHandle.gcHandlesArrayIndex); targetItem.AddChild(item); } // remove groups if it contains one item only for (int n = root.children.Count - 1; n >= 0; --n) { var group = root.children[n]; if (group.hasChildren && group.children.Count == 1) { group.children[0].depth -= 1; root.AddChild(group.children[0]); root.children.RemoveAt(n); } } return(root); }
public RichNativeType(PackedMemorySnapshot snapshot, int nativeTypesArrayIndex) : this() { m_Snapshot = snapshot; m_NativeTypesArrayIndex = nativeTypesArrayIndex; }
public RichStaticField(PackedMemorySnapshot snapshot, int staticFieldsArrayIndex) : this() { m_Snapshot = snapshot; m_ManagedStaticFieldsArrayIndex = staticFieldsArrayIndex; }
public RichNativeObject(PackedMemorySnapshot snapshot, int nativeObjectsArrayIndex) : this() { m_Snapshot = snapshot; m_NativeObjectArrayIndex = nativeObjectsArrayIndex; }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, PackedConnection[] connections, bool addFrom, bool addTo) { m_Snapshot = snapshot; m_Connections = connections; m_AddFrom = addFrom; m_AddTo = addTo; m_UniqueId = 1; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null || m_Connections == null || m_Connections.Length < 1) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } for (int n = 0, nend = m_Connections.Length; n < nend; ++n) { var connection = m_Connections[n]; if (m_AddTo) { switch (connection.toKind) { case PackedConnection.Kind.GCHandle: AddGCHandle(root, m_Snapshot.gcHandles[connection.to]); break; case PackedConnection.Kind.Managed: AddManagedObject(root, m_Snapshot.managedObjects[connection.to]); break; case PackedConnection.Kind.Native: AddNativeUnityObject(root, m_Snapshot.nativeObjects[connection.to]); break; case PackedConnection.Kind.StaticField: AddStaticField(root, m_Snapshot.managedStaticFields[connection.to]); break; } } if (m_AddFrom) { switch (connection.fromKind) { case PackedConnection.Kind.GCHandle: AddGCHandle(root, m_Snapshot.gcHandles[connection.from]); break; case PackedConnection.Kind.Managed: AddManagedObject(root, m_Snapshot.managedObjects[connection.from]); break; case PackedConnection.Kind.Native: AddNativeUnityObject(root, m_Snapshot.nativeObjects[connection.from]); break; case PackedConnection.Kind.StaticField: AddStaticField(root, m_Snapshot.managedStaticFields[connection.from]); break; } } } //if (root.hasChildren) //{ // root.children.Sort(delegate (TreeViewItem x, TreeViewItem y) // { // var xx = x as Item; // var yy = y as Item; // return xx.m_address.CompareTo(yy.m_address); // }); //} return(root); }
public ArrayPropertyGridItem(PropertyGridControl owner, PackedMemorySnapshot snapshot, System.UInt64 address, AbstractMemoryReader memoryReader) : base(owner, snapshot, address, memoryReader) { }
public ObjectProxy(PackedMemorySnapshot snp, PackedManagedStaticField packed) { snapshot = snp; staticField = new RichStaticField(snp, packed.staticFieldsArrayIndex); }