/
MonoGCRootRangeTracker.cs
68 lines (60 loc) · 2.4 KB
/
MonoGCRootRangeTracker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MonoGCDump
{
internal class MonoGCRootRangeTracker
{
public record GCRootRangeData(long Start, long End, string Name);
class GCRootRangeComparer : IComparer<GCRootRangeData>
{
public int Compare(GCRootRangeData? x, GCRootRangeData? y)
{
if (x == y)
return 0;
if (x == null)
return 1;
if (y == null)
return -1;
return x.Start.CompareTo(y.Start);
}
}
private List<GCRootRangeData> rootRangeData = new();
private static GCRootRangeComparer rootRangeComparer = new();
public void Attach(MonoProfilerTraceEventParser traceEventParser)
{
traceEventParser.MonoProfilerGCRootRegister += TraceEventParser_MonoProfilerGCRootRegister;
traceEventParser.MonoProfilerGCRootUnregister += TraceEventParser_MonoProfilerGCRootUnregister;
}
public void Detach(MonoProfilerTraceEventParser traceEventParser)
{
traceEventParser.MonoProfilerGCRootRegister -= TraceEventParser_MonoProfilerGCRootRegister;
traceEventParser.MonoProfilerGCRootUnregister -= TraceEventParser_MonoProfilerGCRootUnregister;
}
private void TraceEventParser_MonoProfilerGCRootRegister(GCRootRegisterData data)
{
// FIXME: Unique root names?
var rootRange = new GCRootRangeData(data.RootID, data.RootID + data.RootSize, data.RootKeyName);
int newIndex = rootRangeData.BinarySearch(rootRange, rootRangeComparer);
if (newIndex < 0)
{
rootRangeData.Insert(~newIndex, rootRange);
}
}
private void TraceEventParser_MonoProfilerGCRootUnregister(GCRootUnregisterData data)
{
// TODO: Binary search
var rootRangeIndex = rootRangeData.FindIndex(rootRange => data.RootID == rootRange.Start);
if (rootRangeIndex >= 0)
{
rootRangeData.RemoveAt(rootRangeIndex);
}
}
public GCRootRangeData? FindRootRange(long address)
{
return rootRangeData.Find(rootRange => address >= rootRange.Start && address < rootRange.End);
}
}
}