public CachedSnapshot(IQueriedMemorySnapshot s) { var vmInfo = s.virtualMachineInformation; if (!VMTools.ValidateVirtualMachineInfo(vmInfo)) { throw new UnityException("Invalid VM info. Snapshot file is corrupted."); } virtualMachineInformation = vmInfo; packedMemorySnapshot = s; m_SnapshotVersion = s.version; nativeAllocationSites = new NativeAllocationSiteEntriesCache(s.nativeAllocationSites); typeDescriptions = new TypeDescriptionEntriesCache(s.typeDescriptions); nativeTypes = new NativeTypeEntriesCache(s.nativeTypes); nativeRootReferences = new NativeRootReferenceEntriesCache(s.nativeRootReferences); nativeObjects = new NativeObjectEntriesCache(s.nativeObjects); nativeMemoryRegions = new NativeMemoryRegionEntriesCache(s.nativeMemoryRegions); nativeMemoryLabels = new NativeMemoryLabelEntriesCache(s.nativeMemoryLabels); nativeCallstackSymbols = new NativeCallstackSymbolEntriesCache(s.nativeCallstackSymbols); nativeAllocations = new NativeAllocationEntriesCache(s.nativeAllocations); managedStacks = new ManagedMemorySectionEntriesCache(s.managedStacks); managedHeapSections = new ManagedMemorySectionEntriesCache(s.managedHeapSections); gcHandles = new GCHandleEntriesCache(s.gcHandles); fieldDescriptions = new FieldDescriptionEntriesCache(s.fieldDescriptions); connections = new ConnectionEntriesCache(s, HasConnectionOverhaul); SortedNativeRegionsEntries = new SortedNativeMemoryRegionEntriesCache(this); SortedManagedStacksEntries = new SortedManagedMemorySectionEntriesCache(managedStacks); SortedManagedHeapEntries = new SortedManagedMemorySectionEntriesCache(managedHeapSections); SortedManagedObjects = new SortedManagedObjectsCache(this); SortedNativeAllocations = new SortedNativeAllocationsCache(this); SortedNativeObjects = new SortedNativeObjectsCache(this); CrawledData = new ManagedData(gcHandles.Count, connections.Count); typeDescriptions.InitSecondaryItems(this); nativeObjects.InitSecondaryItems(); nativeObjects.InitSecondaryItems(this); }
public ConnectionEntriesCache(IQueriedMemorySnapshot snap, bool connectionsNeedRemaping) { var ss = snap.connections; Count = ss.GetNumEntries(); dataSet = new SoaDataSet(Count, kCacheEntrySize); #if UNITY_2019_3_OR_NEWER if (connectionsNeedRemaping) { var fromAPIArr = new int[Count]; ss.from.GetEntries(0, (uint)Count, ref fromAPIArr); var toAPIArr = new int[Count]; ss.to.GetEntries(0, (uint)Count, ref toAPIArr); var instanceIDArr = new int[snap.nativeObjects.instanceId.GetNumEntries()]; snap.nativeObjects.instanceId.GetEntries(0, snap.nativeObjects.instanceId.GetNumEntries(), ref instanceIDArr); var gchandlesIndexArr = new int[snap.nativeObjects.gcHandleIndex.GetNumEntries()]; snap.nativeObjects.gcHandleIndex.GetEntries(0, snap.nativeObjects.gcHandleIndex.GetNumEntries(), ref gchandlesIndexArr); Dictionary <int, int> instanceIDToIndex = new Dictionary <int, int>(); Dictionary <int, int> instanceIDToGcHandleIndex = new Dictionary <int, int>(); for (int i = 0; i < instanceIDArr.Length; ++i) { if (gchandlesIndexArr[i] != -1) { instanceIDToGcHandleIndex.Add(instanceIDArr[i], gchandlesIndexArr[i]); } instanceIDToIndex.Add(instanceIDArr[i], i); } var gcHandlesCount = snap.gcHandles.GetNumEntries(); int[] fromIndices = new int[Count + instanceIDToGcHandleIndex.Count]; int[] toIndices = new int[fromIndices.Length]; for (long i = 0; i < Count; ++i) { fromIndices[i] = (int)(gcHandlesCount + instanceIDToIndex[fromAPIArr[i]]); //some native objects might have references to other native objects that are currently getting deleted or have been deleted int instanceIDIDX = -1; if (!instanceIDToIndex.TryGetValue(toAPIArr[i], out instanceIDIDX)) { toIndices[i] = instanceIDIDX; } else { toIndices[i] = (int)(gcHandlesCount + instanceIDIDX); } } var enumerator = instanceIDToGcHandleIndex.GetEnumerator(); for (long i = Count; i < fromIndices.Length; ++i) { enumerator.MoveNext(); fromIndices[i] = (int)(gcHandlesCount + instanceIDToIndex[enumerator.Current.Key]); toIndices[i] = enumerator.Current.Value; } from = DataArray.MakeCache(dataSet, DataSourceFromAPI.ApiToDatabase(fromIndices)); to = DataArray.MakeCache(dataSet, DataSourceFromAPI.ApiToDatabase(toIndices)); } else #endif { from = DataArray.MakeCache(dataSet, DataSourceFromAPI.ApiToDatabase(ss.from)); to = DataArray.MakeCache(dataSet, DataSourceFromAPI.ApiToDatabase(ss.to)); } }