public HeapBuilder(IHeapHelpers helper, SOSDac sos) { HeapHelpers = helper; if (sos.GetCommonMethodTables(out _mts)) { CanWalkHeap = ArrayMethodTable != 0 && StringMethodTable != 0 && ExceptionMethodTable != 0 && FreeMethodTable != 0 && ObjectMethodTable != 0; } if (sos.GetGcHeapData(out GCInfo gcdata)) { if (gcdata.MaxGeneration != 2) { throw new NotSupportedException($"The GC reported a max generation of {gcdata.MaxGeneration} which this build of ClrMD does not support."); } IsServer = gcdata.ServerMode != 0; LogicalHeapCount = gcdata.HeapCount; CanWalkHeap &= gcdata.GCStructuresValid != 0; } else { CanWalkHeap = false; } }
public ClrmdSegment(ClrmdHeap heap, IHeapHelpers helpers, ISegmentData data) { if (helpers is null) { throw new ArgumentNullException(nameof(helpers)); } if (data is null) { throw new ArgumentNullException(nameof(data)); } _helpers = helpers; _clrmdHeap = heap; LogicalHeap = data.LogicalHeap; IsLargeObjectSegment = data.IsLargeObjectSegment; IsPinnedObjectSegment = data.IsPinnedObjectSegment; IsEphemeralSegment = data.IsEphemeralSegment; ObjectRange = new MemoryRange(data.Start, data.End); ReservedMemory = new MemoryRange(data.CommittedEnd, data.ReservedEnd); CommittedMemory = new MemoryRange(data.BaseAddress, data.CommittedEnd); Generation0 = MemoryRange.CreateFromLength(data.Gen0Start, data.Gen0Length); Generation1 = MemoryRange.CreateFromLength(data.Gen1Start, data.Gen1Length); Generation2 = MemoryRange.CreateFromLength(data.Gen2Start, data.Gen2Length); _markers = new ulong[MarkerCount]; }
public ClrmdSegment(ClrmdHeap heap, IHeapHelpers helpers, ISegmentData data) { if (helpers is null) { throw new ArgumentNullException(nameof(helpers)); } if (data is null) { throw new ArgumentNullException(nameof(data)); } _helpers = helpers; _clrmdHeap = heap; LogicalHeap = data.LogicalHeap; Start = data.Start; End = data.End; IsLargeObjectSegment = data.IsLargeObjectSegment; IsEphemeralSegment = data.IsEphemeralSegment; ReservedEnd = data.ReservedEnd; CommittedEnd = data.CommittedEnd; Gen0Start = data.Gen0Start; Gen0Length = data.Gen0Length; Gen1Start = data.Gen1Start; Gen1Length = data.Gen1Length; Gen2Start = data.Gen2Start; Gen2Length = data.Gen2Length; _markers = new ulong[MarkerCount]; }
public ImmutableArray <(ulong Source, ulong Target)> GetDependentHandles(IHeapHelpers helpers) { if (!_dependentHandles.IsDefault) { return(_dependentHandles); } var dependentHandles = helpers.EnumerateDependentHandleLinks().OrderBy(x => x.Source).ToImmutableArray(); _dependentHandles = dependentHandles; return(dependentHandles); }
public VolatileSyncBlockData(IHeapHelpers helpers) { // We don't care about a false return as that'll simply create empty arrays and sets, which is fine. helpers.GetSyncBlocks(out List <ComSyncBlock> comSyncBlock, out List <FullSyncBlock> fullSyncBlocks, out List <ulong> empty); if (comSyncBlock.Count > 0) { comSyncBlock.Sort((x, y) => x.Object.CompareTo(y.Object)); } if (fullSyncBlocks.Count > 0) { fullSyncBlocks.Sort((x, y) => x.Object.CompareTo(y.Object)); } ComOnlySyncBlocks = comSyncBlock.ToImmutableArray(); FullSyncBlocks = fullSyncBlocks.ToImmutableArray(); EmptySyncBlocks = empty.ToImmutableHashSet(); }
public ClrmdHeap(ClrRuntime runtime, IHeapData data) { if (data is null) { throw new ArgumentNullException(nameof(data)); } _helpers = data.HeapHelpers; Runtime = runtime; CanWalkHeap = data.CanWalkHeap; IsServer = data.IsServer; LogicalHeapCount = data.LogicalHeapCount; // Prepopulate a few important method tables. This should never fail. FreeType = _helpers.Factory.CreateSystemType(this, data.FreeMethodTable, "Free"); ObjectType = _helpers.Factory.CreateSystemType(this, data.ObjectMethodTable, "System.Object"); StringType = _helpers.Factory.CreateSystemType(this, data.StringMethodTable, "System.String"); ExceptionType = _helpers.Factory.CreateSystemType(this, data.ExceptionMethodTable, "System.Exception"); }
public VolatileHeapData(ClrHeap parent, IHeapHelpers _helpers) { _helpers.CreateSegments(parent, out ImmutableArray <ClrSegment> segments, out ImmutableArray <MemoryRange> allocContext, out ImmutableArray <FinalizerQueueSegment> fqRoots, out ImmutableArray <FinalizerQueueSegment> fqObjects); // Segments must be in sorted order. We won't check all of them but we will at least check the beginning and end if (segments.Length > 0 && segments[0].Start > segments[segments.Length - 1].Start) { Segments = segments.Sort((x, y) => x.Start.CompareTo(y.Start)); } else { Segments = segments; } FQRoots = fqRoots; FQObjects = fqObjects; AllocationContext = allocContext.ToDictionary(k => k.Start, v => v.End); }