@@ -21,21 +21,26 @@ public FreeBlock(ulong address, ulong size)
2121 public class GenerationInSegment
2222 {
2323 private List < ( ClrHandle handle , string typeDescription ) > _pinnedObjects ;
24- private readonly IReadOnlyList < FreeBlock > _freeBlocks ;
25-
26- public GenerationInSegment ( IReadOnlyList < FreeBlock > freeBlocks )
24+
25+ public GenerationInSegment ( ulong [ ] instances , IReadOnlyList < FreeBlock > freeBlocks , int count , ulong size )
2726 {
28- _freeBlocks = freeBlocks ;
27+ FreeBlocks = freeBlocks ;
28+ FreeBlocksCount = count ;
29+ FreeBlocksSize = size ;
30+ InstancesAddresses = instances ;
2931 _pinnedObjects = new List < ( ClrHandle , string ) > ( ) ;
3032 }
3133
3234 public int Generation { get ; set ; }
3335 public ulong Start { get ; set ; }
3436 public ulong End { get ; set ; }
3537 public ulong Length { get ; set ; }
38+ public ulong [ ] InstancesAddresses { get ; }
3639 public IReadOnlyList < ( ClrHandle handle , string typeDescription ) > PinnedObjects =>
3740 _pinnedObjects . OrderBy ( po => po . handle . Object ) . ToList ( ) ;
38- public IReadOnlyList < FreeBlock > FreeBlocks => _freeBlocks ;
41+ public IReadOnlyList < FreeBlock > FreeBlocks { get ; }
42+ public int FreeBlocksCount { get ; }
43+ public ulong FreeBlocksSize { get ; }
3944
4045 internal void AddPinnedObject ( ClrHandle pinnedObject )
4146 {
@@ -90,11 +95,12 @@ private bool IsAddressInGeneration(ulong address, GenerationInSegment generation
9095 }
9196 internal void AddGenerationInSegment (
9297 int generation , ulong start , ulong end , ulong length ,
98+ ulong [ ] instances , int count , ulong size ,
9399 IReadOnlyList < FreeBlock > freeBlocks
94100 )
95101 {
96102 _generations . Add (
97- new GenerationInSegment ( freeBlocks )
103+ new GenerationInSegment ( instances , freeBlocks , count , size )
98104 {
99105 Generation = generation ,
100106 Start = start ,
@@ -1243,7 +1249,7 @@ public IReadOnlyList<PinnedObjectsGeneration> ComputePinnedObjects()
12431249
12441250 return generations ;
12451251 }
1246- public IReadOnlyList < SegmentInfo > ComputeGCSegments ( )
1252+ public IReadOnlyList < SegmentInfo > ComputeGCSegments ( bool needPinned )
12471253 {
12481254 // merge ClrSegments
12491255 List < SegmentInfo > segments = new List < SegmentInfo > ( ) ;
@@ -1263,36 +1269,39 @@ public IReadOnlyList<SegmentInfo> ComputeGCSegments()
12631269 }
12641270
12651271 // dispatch pinned objects to the right segment/generation
1266- var pinnedObjectsCount = 0 ;
1267- foreach ( var gcHandle in _clr . EnumerateHandles ( ) )
1272+ if ( needPinned )
12681273 {
1269- if ( ! gcHandle . IsPinned )
1270- continue ;
1271-
1272- // address of the object pinned by the handle
1273- var address = gcHandle . Object ;
1274- var segment = _heap . GetSegmentByAddress ( address ) ;
1275- if ( segment != null )
1274+ var pinnedObjectsCount = 0 ;
1275+ foreach ( var gcHandle in _clr . EnumerateHandles ( ) )
12761276 {
1277- var generation = segment . GetGeneration ( address ) ;
1277+ if ( ! gcHandle . IsPinned )
1278+ continue ;
12781279
1279- // take care of LOH case
1280- if ( ( generation == 2 ) && ( segment . IsLarge ) )
1280+ // address of the object pinned by the handle
1281+ var address = gcHandle . Object ;
1282+ var segment = _heap . GetSegmentByAddress ( address ) ;
1283+ if ( segment != null )
12811284 {
1282- generation = 3 ;
1283- }
1285+ var generation = segment . GetGeneration ( address ) ;
12841286
1285- var genInSegment = GetGeneration ( segments , address ) ;
1287+ // take care of LOH case
1288+ if ( ( generation == 2 ) && ( segment . IsLarge ) )
1289+ {
1290+ generation = 3 ;
1291+ }
12861292
1287- Debug . Assert ( genInSegment != null ) ;
1288- Debug . Assert ( genInSegment . Generation == generation ) ;
1293+ var genInSegment = GetGeneration ( segments , address ) ;
12891294
1290- pinnedObjectsCount ++ ;
1291- genInSegment . AddPinnedObject ( gcHandle ) ;
1292- }
1293- else
1294- {
1295- // should never occur
1295+ Debug . Assert ( genInSegment != null ) ;
1296+ Debug . Assert ( genInSegment . Generation == generation ) ;
1297+
1298+ pinnedObjectsCount ++ ;
1299+ genInSegment . AddPinnedObject ( gcHandle ) ;
1300+ }
1301+ else
1302+ {
1303+ // should never occur
1304+ }
12961305 }
12971306 }
12981307
@@ -1319,14 +1328,16 @@ private GenerationInSegment GetGeneration(List<SegmentInfo> segments, ulong addr
13191328 }
13201329 private void MergeSegment ( ClrSegment segment , SegmentInfo info )
13211330 {
1322- var freeObjects = ComputeFreeBlocks ( segment ) ;
1331+ var freeObjects =
1332+ DispatchInstances ( segment , out var freeBlocksCount , out var freeBlocksSize , out var instances ) ;
13231333
13241334 // if LOH, just one generation in this segment
13251335 if ( segment . IsLarge )
13261336 {
13271337 // add only an LOH generation in segment info
13281338 info . AddGenerationInSegment (
13291339 3 , segment . Gen2Start , segment . Gen2Start + segment . Gen2Length , segment . Gen2Length ,
1340+ instances , freeBlocksCount , freeBlocksSize ,
13301341 FilterFreeBlocks ( freeObjects , segment . Gen2Start , segment . Gen2Start + segment . Gen2Length )
13311342 ) ;
13321343 return ;
@@ -1337,34 +1348,49 @@ private void MergeSegment(ClrSegment segment, SegmentInfo info)
13371348 {
13381349 info . AddGenerationInSegment (
13391350 0 , segment . Gen0Start , segment . Gen0Start + segment . Gen0Length , segment . Gen0Length ,
1351+ instances , freeBlocksCount , freeBlocksSize ,
13401352 FilterFreeBlocks ( freeObjects , segment . Gen0Start , segment . Gen0Start + segment . Gen0Length )
13411353 ) ;
13421354 info . AddGenerationInSegment (
13431355 1 , segment . Gen1Start , segment . Gen1Start + segment . Gen1Length , segment . Gen1Length ,
1356+ instances , freeBlocksCount , freeBlocksSize ,
13441357 FilterFreeBlocks ( freeObjects , segment . Gen1Start , segment . Gen1Start + segment . Gen1Length )
13451358 ) ;
13461359 }
13471360
13481361 // always add gen2
13491362 info . AddGenerationInSegment (
13501363 2 , segment . Gen2Start , segment . Gen2Start + segment . Gen2Length , segment . Gen2Length ,
1364+ instances , freeBlocksCount , freeBlocksSize ,
13511365 FilterFreeBlocks ( freeObjects , segment . Gen2Start , segment . Gen2Start + segment . Gen2Length )
13521366 ) ;
13531367 }
13541368
1355- private IReadOnlyList < FreeBlock > ComputeFreeBlocks ( ClrSegment segment )
1369+ private IReadOnlyList < FreeBlock > DispatchInstances ( ClrSegment segment ,
1370+ out int freeBlocksCount , out ulong freeBlocksSize , out ulong [ ] instanceAddresses )
13561371 {
1357- var freeBlocks = new List < FreeBlock > ( ) ;
1358-
1372+ freeBlocksSize = 0 ;
1373+ freeBlocksCount = 0 ;
1374+ var freeBlocks = new List < FreeBlock > ( 128 ) ;
1375+ var instances = new List < ulong > ( 128 ) ;
13591376 for ( ulong obj = segment . FirstObject ; obj != 0 ; obj = segment . NextObject ( obj ) )
13601377 {
13611378 var type = segment . Heap . GetObjectType ( obj ) ;
13621379 if ( type . IsFree )
13631380 {
1364- freeBlocks . Add ( new FreeBlock ( obj , type . GetSize ( obj ) ) ) ;
1381+ var blockSize = type . GetSize ( obj ) ;
1382+ freeBlocksSize += blockSize ;
1383+ freeBlocksCount ++ ;
1384+
1385+ freeBlocks . Add ( new FreeBlock ( obj , blockSize ) ) ;
1386+ }
1387+ else
1388+ {
1389+ instances . Add ( obj ) ;
13651390 }
13661391 }
13671392
1393+ instanceAddresses = instances . ToArray ( ) ;
13681394 return freeBlocks ;
13691395 }
13701396 private IReadOnlyList < FreeBlock > FilterFreeBlocks (
0 commit comments