private ChainLink? WalkObject()

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;
        }