protected static IEnumerable <VisibleHeapAllocation> WalkHeapAllocations( HeapSnapshot.Heap heap, int bytesPerRow, int rowY, int contentWidth ) { for (int i = 0, c = heap.Allocations.Count; i < c; i++) { var allocation = heap.Allocations[i]; var pos = (int)(allocation.Address - heap.Info.EstimatedStart); var nextPos = (int)(allocation.NextOffset - heap.Info.EstimatedStart); int y1 = (rowY + (pos / bytesPerRow)), y2 = (rowY + (nextPos / bytesPerRow)); float x1 = (pos % bytesPerRow) / (float)BytesPerPixel, x2 = (nextPos % bytesPerRow) / (float)BytesPerPixel; for (var barY = y1; barY <= y2; barY += 1) { var barX = (barY == y1) ? x1 : 0; yield return(new VisibleHeapAllocation( heap, i, barY, y1, ref allocation, new RectangleF( barX, barY * RowHeight, (barY == y2) ? x2 - barX : contentWidth - barX, RowHeight ) )); } } }
protected void HideTooltip() { if (TooltipHeap != null) { TooltipHeap = null; TooltipAllocationIndex = -1; Tooltip.Hide(); Invalidate(); } }
public VisibleHeapAllocation( HeapSnapshot.Heap heap, int index, int rowIndex, int firstRowIndex, ref HeapSnapshot.Allocation allocation, RectangleF rectangle ) { Heap = heap; Index = index; RowIndex = rowIndex; FirstRowIndex = firstRowIndex; Allocation = allocation; Rectangle = rectangle; }
protected IEnumerator <object> FinishShowingTooltip( Point mouseLocation, HeapSnapshot.Heap heap, HeapSnapshot.Allocation allocation, HeapSnapshot.Traceback rawTraceback ) { var uniqueRawFrames = rawTraceback.Frames.AsEnumerable().Distinct(); var fSymbols = Instance.Database.SymbolCache.Select(uniqueRawFrames); using (fSymbols) yield return(fSymbols); var symbolDict = SequenceUtils.ToDictionary( uniqueRawFrames, fSymbols.Result ); var tracebackInfo = HeapRecording.ConstructTracebackInfo( rawTraceback.ID, rawTraceback.Frames, symbolDict ); var renderParams = new DeltaInfo.RenderParams { BackgroundBrush = new SolidBrush(SystemColors.Info), BackgroundColor = SystemColors.Info, TextBrush = new SolidBrush(SystemColors.InfoText), IsExpanded = true, IsSelected = false, Font = Font, ShadeBrush = new SolidBrush(Color.FromArgb(31, 0, 0, 0)), StringFormat = CustomTooltip.GetDefaultStringFormat() }; var content = new HeapSnapshot.AllocationTooltipContent( ref allocation, ref tracebackInfo, ref renderParams ) { Location = mouseLocation, Font = Font }; using (var g = CreateGraphics()) CustomTooltip.FitContentOnScreen( g, content, ref content.RenderParams.Font, ref content.Location, ref content.Size ); Tooltip.SetContent(content); }
protected bool AllocationFromPoint(Point pt, out HeapSnapshot.Heap heap, out int allocationIndex) { if (Snapshot == null) { heap = null; allocationIndex = -1; return(false); } var width = ClientSize.Width - ScrollBar.Width; var bytesPerRow = BytesPerRow; foreach (var vh in WalkHeaps(Snapshot, _ScrollOffset, bytesPerRow, width)) { if (((vh.FirstRow + vh.HeightInRows) * RowHeight) < pt.Y) { continue; } foreach (var vha in WalkHeapAllocations(vh.Heap, bytesPerRow, vh.FirstRow, width)) { if (vha.Rectangle.Bottom < pt.Y) { continue; } if (vha.Rectangle.Y > pt.Y) { break; } if (vha.Rectangle.Contains(pt)) { heap = vha.Heap; allocationIndex = vha.Index; return(true); } } } heap = null; allocationIndex = -1; return(false); }
protected override void OnMouseMove(MouseEventArgs e) { HeapSnapshot.Heap heap; int allocationIndex; if (AllocationFromPoint(e.Location, out heap, out allocationIndex)) { if ((heap != TooltipHeap) || (allocationIndex != TooltipAllocationIndex)) { TooltipAllocationIndex = allocationIndex; TooltipHeap = heap; if (Tooltip == null) { Tooltip = new CustomTooltip(this); } Instance.Scheduler.Start( FinishShowingTooltip( PointToScreen(e.Location), heap, heap.Allocations[allocationIndex], Snapshot.Tracebacks[heap.Allocations[allocationIndex].TracebackID] ), TaskExecutionPolicy.RunAsBackgroundTask ); Invalidate(); } } else { HideTooltip(); base.OnMouseMove(e); } }
public VisibleHeap(HeapSnapshot.Heap heap, int firstRow, int heightInRows) { Heap = heap; FirstRow = firstRow; HeightInRows = heightInRows; }
protected static int ComputeHeapHeightInRows(HeapSnapshot.Heap heap, float bytesPerRow) { return((int)(Math.Ceiling( heap.Info.EstimatedSize / bytesPerRow ) + 1)); }
protected IEnumerator <object> LoadSnapshotFromDatabase(HeapSnapshotInfo info) { var result = new HeapSnapshot(info); var fModules = Database.SnapshotModules.Get(info.Index); var fHeaps = Database.SnapshotHeaps.Get(info.Index); using (fModules) yield return(fModules); var fModuleInfos = Database.Modules.Select( from moduleName in fModules.Result select moduleName ); using (fModuleInfos) yield return(fModuleInfos); foreach (var module in fModuleInfos.Result) { result.Modules.Add(module); } using (fHeaps) yield return(fHeaps); var heapIDs = from heap in fHeaps.Result select heap.HeapID; var fAllocations = Database.HeapAllocations.Select(heapIDs); using (fAllocations) yield return(fAllocations); var allocations = SequenceUtils.ToDictionary(heapIDs, fAllocations.Result); var tracebackIDs = new HashSet <UInt32>(); foreach (var heapInfo in fHeaps.Result) { var theHeap = new HeapSnapshot.Heap(heapInfo); var allocationIds = allocations[heapInfo.HeapID]; theHeap.Allocations.Capacity = allocationIds.Length; var fRanges = Database.Allocations.Select(allocationIds); using (fRanges) yield return(fRanges); yield return(Future.RunInThread(() => SequenceUtils.Zip( allocationIds, fRanges.Result, (id, ranges) => { HeapSnapshot.AllocationRanges.Range range; if (ranges.Get(info.Index, out range)) { theHeap.Allocations.Add(new HeapSnapshot.Allocation( id, range.Size, range.Overhead, range.TracebackID )); tracebackIDs.Add(range.TracebackID); } } ) )); result.Heaps.Add(theHeap); } var fTracebacks = Database.Tracebacks.Select(tracebackIDs); using (fTracebacks) yield return(fTracebacks); yield return(Future.RunInThread(() => { foreach (var traceback in fTracebacks.Result) { result.Tracebacks.Add(traceback); } })); yield return(Result.New(result)); }