in src/Microsoft.Diagnostics.Runtime/GCRoot.cs [198:266]
private ChainLink? WalkObject(List<byte[]> stack, ulong parent, ulong curr, CancellationToken cancellation)
{
ClrObject obj = _heap.GetObject(curr);
TraceWalkObject(obj);
if (_targetPredicate is not null && _targetPredicate(obj))
{
TraceFound(obj);
ChainLink result = new()
{
Object = curr,
};
_found[curr] = result;
return result;
}
if (obj.Type is not null && obj.Type.ContainsPointers)
{
ReferenceList refList = default;
byte offset = 0;
foreach (ulong reference in obj.EnumerateReferenceAddresses())
{
cancellation.ThrowIfCancellationRequested();
if (_found.TryGetValue(reference, out ChainLink? link))
{
ChainLink result = new()
{
Next = link,
Object = curr,
};
TraceFound(reference, link);
_found[curr] = result;
return result;
}
else if (!_seen.Add(reference))
{
TraceSeen(reference);
continue;
}
TraceReference(obj, reference);
if (refList.IsDefault)
refList = new ReferenceList(curr, parent, out offset);
offset = refList.Store(reference, offset);
if (offset == 0)
{
stack.Add(refList.Complete());
refList = new ReferenceList(curr, parent, out offset);
offset = refList.Store(reference, offset);
DebugOnly.Assert(offset != 0);
}
}
byte[]? item = refList.Complete();
if (item is not null)
stack.Add(item);
}
return null;
}