예제 #1
0
        public override void EnumerateRefsOfObject(ulong objRef, Action <ulong, int> action)
        {
            if (!_containsPointers)
            {
                return;
            }

            if (_gcDesc == null)
            {
                if (!FillGCDesc() || _gcDesc == null)
                {
                    return;
                }
            }

            var size  = GetSize(objRef);
            var cache = _heap.MemoryReader;

            if (!cache.Contains(objRef))
            {
                cache = _heap.NativeRuntime.MemoryReader;
            }

            _gcDesc.WalkObject(objRef, (ulong)size, cache, action);
        }
예제 #2
0
        public override IEnumerable <ClrReference> EnumerateReferencesWithFields(ulong obj, ClrType type, bool carefully, bool considerDependantHandles)
        {
            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (considerDependantHandles)
            {
                ImmutableArray <(ulong Source, ulong Target)> dependent = GetHeapData().GetDependentHandles(_helpers);

                if (dependent.Length > 0)
                {
                    int index = dependent.Search(obj, (x, y) => x.Source.CompareTo(y));
                    if (index != -1)
                    {
                        while (index >= 1 && dependent[index - 1].Source == obj)
                        {
                            index--;
                        }

                        while (index < dependent.Length && dependent[index].Source == obj)
                        {
                            ulong     dependantObj = dependent[index++].Target;
                            ClrObject target       = new ClrObject(dependantObj, GetObjectType(dependantObj));
                            yield return(ClrReference.CreateFromDependentHandle(target));
                        }
                    }
                }
            }

            if (type.ContainsPointers)
            {
                GCDesc gcdesc = type.GCDesc;
                if (!gcdesc.IsEmpty)
                {
                    ulong size = GetObjectSize(obj, type);
                    if (carefully)
                    {
                        ClrSegment?seg = GetSegmentByAddress(obj);
                        if (seg is null || obj + size > seg.End || (!seg.IsLargeObjectSegment && size > MaxGen2ObjectSize))
                        {
                            yield break;
                        }
                    }

                    foreach ((ulong reference, int offset) in gcdesc.WalkObject(obj, size, _helpers.DataReader))
                    {
                        ClrObject target = new ClrObject(reference, GetObjectType(reference));
                        yield return(ClrReference.CreateFromFieldOrArray(target, type, offset));
                    }
                }
            }
        }
예제 #3
0
        public override IEnumerable <ClrObject> EnumerateObjectReferences(ulong obj, ClrType type, bool carefully, bool considerDependantHandles)
        {
            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (considerDependantHandles)
            {
                ImmutableArray <(ulong Source, ulong Target)> dependent = GetHeapData().GetDependentHandles(_helpers);

                if (dependent.Length > 0)
                {
                    int index = dependent.Search(obj, (x, y) => x.Source.CompareTo(y));
                    if (index != -1)
                    {
                        while (index >= 1 && dependent[index - 1].Source == obj)
                        {
                            index--;
                        }

                        while (index < dependent.Length && dependent[index].Source == obj)
                        {
                            ulong dependantObj = dependent[index++].Target;
                            yield return(new ClrObject(dependantObj, GetObjectType(dependantObj)));
                        }
                    }
                }
            }

            if (type.IsCollectible)
            {
                ulong la = _helpers.DataReader.ReadPointer(type.LoaderAllocatorHandle);
                if (la != 0)
                {
                    yield return(new ClrObject(la, GetObjectType(la)));
                }
            }

            if (type.ContainsPointers)
            {
                GCDesc gcdesc = type.GCDesc;
                if (!gcdesc.IsEmpty)
                {
                    ulong size = GetObjectSize(obj, type);
                    if (carefully)
                    {
                        ClrSegment?seg = GetSegmentByAddress(obj);
                        if (seg is null || obj + size > seg.End || (!seg.IsLargeObjectSegment && size > MaxGen2ObjectSize))
                        {
                            yield break;
                        }
                    }

                    int    intSize = (int)size;
                    byte[] buffer  = ArrayPool <byte> .Shared.Rent(intSize);

                    try
                    {
                        int read = _helpers.DataReader.Read(obj, new Span <byte>(buffer, 0, intSize));
                        if (read > IntPtr.Size)
                        {
                            foreach ((ulong reference, int offset) in gcdesc.WalkObject(buffer, read))
                            {
                                yield return(new ClrObject(reference, GetObjectType(reference)));
                            }
                        }
                    }
                    finally
                    {
                        ArrayPool <byte> .Shared.Return(buffer);
                    }
                }
            }
        }