/// <summary> Updates internal state with allocation. </summary> private static void HandleMalloc(FStreamToken StreamToken, FStreamSnapshot Snapshot, Dictionary <ulong, FCallStackAllocationInfo> PointerToPointerInfoMap) { // Keep track of size associated with pointer and also current callstack. FCallStackAllocationInfo PointerInfo = new FCallStackAllocationInfo(StreamToken.Size, StreamToken.CallStackIndex, 1); if (PointerToPointerInfoMap.ContainsKey(StreamToken.Pointer)) { Debug.WriteLine("Same pointer malloced twice without being freed: " + StreamToken.Pointer + " in pool " + StreamToken.Pool); PointerToPointerInfoMap.Remove(StreamToken.Pointer); } PointerToPointerInfoMap.Add(StreamToken.Pointer, PointerInfo); if (StreamToken.CallStackIndex >= FStreamInfo.GlobalInstance.CallStackArray.Count) { Debug.WriteLine("CallStackIndex out of range!"); return; } // Add size to lifetime churn tracking. while (StreamToken.CallStackIndex >= Snapshot.LifetimeCallStackList.Count) { Snapshot.LifetimeCallStackList.Add(new FCallStackAllocationInfo(0, Snapshot.LifetimeCallStackList.Count, 0)); } //@todo: Sadly, we have to do all this ugly shuffling because of the way lists of structs work in C# Snapshot.LifetimeCallStackList[StreamToken.CallStackIndex] = Snapshot.LifetimeCallStackList[StreamToken.CallStackIndex].Add(StreamToken.Size, 1); if (Snapshot.AllocationSize > Snapshot.AllocationMaxSize) { Snapshot.AllocationMaxSize = Snapshot.AllocationSize; } // Maintain timeline view Snapshot.AllocationSize += PointerInfo.Size; Snapshot.AllocationCount++; if (Snapshot.AllocationCount % AllocationsPerSlice == 0) { FMemorySlice Slice = new FMemorySlice(Snapshot); Snapshot.OverallMemorySlice.Add(Slice); Snapshot.AllocationMaxSize = 0; } }
/// <summary> Updates internal state with free. </summary> private static bool HandleFree(FStreamToken StreamToken, FStreamSnapshot Snapshot, Dictionary <ulong, FLiveAllocationInfo> PointerToPointerInfoMap, out FLiveAllocationInfo FreedAllocInfo) { if (!PointerToPointerInfoMap.TryGetValue(StreamToken.Pointer, out FreedAllocInfo)) { Debug.WriteLine("Free without malloc: " + StreamToken.Pointer + " in pool " + StreamToken.Pool); return(false); } // Maintain timeline view Snapshot.AllocationSize -= FreedAllocInfo.Size; Snapshot.AllocationCount++; if (Snapshot.AllocationCount % AllocationsPerSlice == 0) { FMemorySlice Slice = new FMemorySlice(Snapshot); Snapshot.OverallMemorySlice.Add(Slice); } // Remove freed pointer if it is in the array. PointerToPointerInfoMap.Remove(StreamToken.Pointer); return(true); }
/// <summary> Updates internal state with free. </summary> private static bool HandleFree(FStreamToken StreamToken, FStreamSnapshot Snapshot, Dictionary<ulong, FCallStackAllocationInfo> PointerToPointerInfoMap, out FCallStackAllocationInfo FreedAllocInfo) { if (!PointerToPointerInfoMap.TryGetValue(StreamToken.Pointer, out FreedAllocInfo)) { Debug.WriteLine("Free without malloc: " + StreamToken.Pointer + " in pool " + StreamToken.Pool); return false; } // Maintain timeline view Snapshot.AllocationSize -= FreedAllocInfo.Size; Snapshot.AllocationCount++; if (Snapshot.AllocationCount % AllocationsPerSlice == 0) { FMemorySlice Slice = new FMemorySlice( Snapshot ); Snapshot.OverallMemorySlice.Add( Slice ); } // Remove freed pointer if it is in the array. PointerToPointerInfoMap.Remove(StreamToken.Pointer); return true; }
/// <summary> Updates internal state with allocation. </summary> private static void HandleMalloc(FStreamToken StreamToken, FStreamSnapshot Snapshot, Dictionary<ulong, FCallStackAllocationInfo> PointerToPointerInfoMap) { // Keep track of size associated with pointer and also current callstack. FCallStackAllocationInfo PointerInfo = new FCallStackAllocationInfo(StreamToken.Size, StreamToken.CallStackIndex, 1); if (PointerToPointerInfoMap.ContainsKey(StreamToken.Pointer)) { Debug.WriteLine("Same pointer malloced twice without being freed: " + StreamToken.Pointer + " in pool " + StreamToken.Pool); PointerToPointerInfoMap.Remove(StreamToken.Pointer); } PointerToPointerInfoMap.Add(StreamToken.Pointer, PointerInfo); if (StreamToken.CallStackIndex >= FStreamInfo.GlobalInstance.CallStackArray.Count) { Debug.WriteLine("CallStackIndex out of range!"); return; } // Add size to lifetime churn tracking. while (StreamToken.CallStackIndex >= Snapshot.LifetimeCallStackList.Count) { Snapshot.LifetimeCallStackList.Add(new FCallStackAllocationInfo(0, Snapshot.LifetimeCallStackList.Count, 0)); } //@todo: Sadly, we have to do all this ugly shuffling because of the way lists of structs work in C# Snapshot.LifetimeCallStackList[ StreamToken.CallStackIndex ] = Snapshot.LifetimeCallStackList[ StreamToken.CallStackIndex ].Add( StreamToken.Size, 1 ); if( Snapshot.AllocationSize > Snapshot.AllocationMaxSize ) { Snapshot.AllocationMaxSize = Snapshot.AllocationSize; } // Maintain timeline view Snapshot.AllocationSize += PointerInfo.Size; Snapshot.AllocationCount++; if (Snapshot.AllocationCount % AllocationsPerSlice == 0) { FMemorySlice Slice = new FMemorySlice( Snapshot ); Snapshot.OverallMemorySlice.Add( Slice ); Snapshot.AllocationMaxSize = 0; } }