internal IEnumerable EnumerateObjects()

in src/Microsoft.Diagnostics.Runtime/ClrHeap.cs [362:428]


        internal IEnumerable<ClrObject> EnumerateObjects(ClrSegment segment, ulong startAddress, bool carefully)
        {
            if (!segment.ObjectRange.Contains(startAddress))
                yield break;

            uint pointerSize = (uint)_memoryReader.PointerSize;
            uint minObjSize = pointerSize * 3;
            uint objSkip = segment.Kind != GCSegmentKind.Large ? minObjSize : 85000;
            using MemoryCache cache = new(_memoryReader, segment);

            ulong obj = GetValidObjectForAddress(segment, startAddress);
            while (segment.ObjectRange.Contains(obj))
            {
                if (!cache.ReadPointer(obj, out ulong mt))
                {
                    if (!carefully)
                        break;

                    obj = FindNextValidObject(segment, pointerSize, obj + objSkip, cache);
                    continue;
                }

                ClrType? type = _typeFactory.GetOrCreateType(mt, obj);
                ClrObject result = new(obj, type ?? ErrorType);
                yield return result;
                if (type is null)
                {
                    if (!carefully)
                        break;

                    obj = FindNextValidObject(segment, pointerSize, obj + objSkip, cache);
                    continue;
                }

                SetMarkerIndex(segment, obj);

                ulong size;
                if (type.ComponentSize == 0)
                {
                    size = (uint)type.StaticSize;
                }
                else
                {
                    if (!cache.ReadUInt32(obj + pointerSize, out uint count))
                    {
                        if (!carefully)
                            break;

                        obj = FindNextValidObject(segment, pointerSize, obj + objSkip, cache);
                        continue;
                    }

                    // Strings in v4+ contain a trailing null terminator not accounted for.
                    if (StringType == type)
                        count++;

                    size = count * (ulong)type.ComponentSize + (ulong)type.StaticSize;
                }

                size = Align(size, segment);
                if (size < minObjSize)
                    size = minObjSize;

                obj += size;
                obj = SkipAllocationContext(segment, obj);
            }
        }