@@ -20,32 +20,6 @@ typedef struct CollectMetadataContext
20
20
MonoMetadataSnapshot * metadata ;
21
21
} CollectMetadataContext ;
22
22
23
- typedef struct AllDomainAssembliesForeachData
24
- {
25
- MonoDomainAssemblyFunc func ;
26
- void * user_data ;
27
-
28
- } AllDomainAssembliesForeachData ;
29
-
30
- static void AllDomainAssembliesForeachHelper (MonoDomain * domain , void * user_data )
31
- {
32
- AllDomainAssembliesForeachData * data = (AllDomainAssembliesForeachData * )user_data ;
33
-
34
- mono_domain_assembly_foreach (domain , data -> func , data -> user_data );
35
- }
36
-
37
- static void AllDomainAssembliesForeach (MonoDomainAssemblyFunc func , void * user_data )
38
- {
39
- AllDomainAssembliesForeachData data ;
40
-
41
- data .func = func ;
42
- data .user_data = user_data ;
43
-
44
- AllDomainAssembliesForeachHelper (mono_domain_get (), & data );
45
-
46
- // mono_domain_foreach(AllDomainAssembliesForeachHelper, &data);
47
- }
48
-
49
23
static void ContextInsertClass (CollectMetadataContext * context , MonoClass * klass )
50
24
{
51
25
if (klass -> inited && g_hash_table_lookup (context -> allTypes , klass ) == NULL )
@@ -82,29 +56,11 @@ static void CollectGenericClass(gpointer value, gpointer user_data)
82
56
ContextInsertClass (context , genericClass -> cached_class );
83
57
}
84
58
85
- MonoClass * MonoLookupDynamiClass (MonoImage * image , guint32 token , MonoGenericContext * context , MonoError * error )
86
- {
87
- MonoClass * handle_class ;
88
- error_init (error );
89
- return (MonoClass * )mono_reflection_lookup_dynamic_token (image , token , FALSE, & handle_class , context , error );
90
- }
91
-
92
- static void CollectImageMetaData (MonoImage * image , CollectMetadataContext * context )
59
+ static void CollectImageMetaData (MonoImage * image , gpointer value , CollectMetadataContext * context )
93
60
{
94
61
int i ;
95
62
MonoTableInfo * tdef = & image -> tables [MONO_TABLE_TYPEDEF ];
96
63
97
- if (image -> module_count > 0 )
98
- {
99
- for (i = 0 ; i < image -> module_count ; ++ i )
100
- {
101
- MonoImage * moduleImage = image -> modules [i ];
102
-
103
- if (moduleImage )
104
- CollectImageMetaData (moduleImage , context );
105
- }
106
- }
107
-
108
64
if (image -> dynamic )
109
65
{
110
66
MonoDynamicImage * dynamicImage = (MonoDynamicImage * )image ;
@@ -144,14 +100,6 @@ static void CollectImageMetaData(MonoImage* image, CollectMetadataContext* conte
144
100
g_hash_table_foreach (image -> ptr_cache , CollectHashMapClass , context );
145
101
}
146
102
147
- static void CollectAssemblyMetaData (MonoAssembly * assembly , void * user_data )
148
- {
149
- MonoImage * image = mono_assembly_get_image (assembly );
150
- CollectMetadataContext * context = (CollectMetadataContext * )user_data ;
151
-
152
- CollectImageMetaData (image , context );
153
- }
154
-
155
103
static int FindClassIndex (GHashTable * hashTable , MonoClass * klass )
156
104
{
157
105
gpointer value = g_hash_table_lookup (hashTable , klass );
@@ -234,15 +182,15 @@ static void AddMetadataType(gpointer key, gpointer value, gpointer user_data)
234
182
type -> size = (klass -> valuetype ) != 0 ? (mono_class_instance_size (klass ) - sizeof (MonoObject )) : mono_class_instance_size (klass );
235
183
}
236
184
237
- static void CollectMetadata (MonoMetadataSnapshot * metadata )
185
+ static void CollectMetadata (MonoMetadataSnapshot * metadata , GHashTable * monoImages )
238
186
{
239
187
CollectMetadataContext context ;
240
188
241
189
context .allTypes = g_hash_table_new (NULL , NULL );
242
190
context .currentIndex = 0 ;
243
191
context .metadata = metadata ;
244
192
245
- AllDomainAssembliesForeach ( CollectAssemblyMetaData , & context );
193
+ g_hash_table_foreach ( monoImages , ( GHFunc ) CollectImageMetaData , & context );
246
194
247
195
mono_metadata_generic_class_foreach (CollectGenericClass , & context );
248
196
@@ -310,22 +258,17 @@ static void CopyMemPoolChunk(void* chunkStart, void* chunkEnd, void* context)
310
258
CopyHeapSection (context , chunkStart , chunkEnd );
311
259
}
312
260
313
- static void AddImageMemoryPoolChunkCount (MonoAssembly * assembly , MonoManagedHeap * heap )
314
- {
315
- heap -> sectionCount += MonoMemPoolNumChunks (assembly -> image -> mempool );
316
- }
317
-
318
- static void IncrementCountForImageMemPoolNumChunks (MonoAssembly * assembly , void * user_data )
261
+ static void IncrementCountForImageMemPoolNumChunks (MonoImage * image , gpointer * value , void * user_data )
319
262
{
320
263
int * count = (int * )user_data ;
321
- (* count ) += MonoMemPoolNumChunks (assembly -> image -> mempool );
264
+ (* count ) += MonoMemPoolNumChunks (image -> mempool );
322
265
}
323
266
324
- static int MonoImagesMemPoolNumChunks ()
267
+ static int MonoImagesMemPoolNumChunks (GHashTable * monoImages )
325
268
{
326
269
int count = 0 ;
327
270
328
- AllDomainAssembliesForeach (( GFunc )IncrementCountForImageMemPoolNumChunks , & count );
271
+ g_hash_table_foreach ( monoImages , ( GHFunc )IncrementCountForImageMemPoolNumChunks , & count );
329
272
return count ;
330
273
}
331
274
@@ -334,9 +277,8 @@ static void AllocateMemoryForMemPool(MonoMemPool* pool, void *user_data)
334
277
mono_mempool_foreach_block (pool , AllocateMemoryForMemPoolChunk , user_data );
335
278
}
336
279
337
- static void AllocateMemoryForImageMemPool (MonoAssembly * assembly , void * user_data )
280
+ static void AllocateMemoryForImageMemPool (MonoImage * image , gpointer value , void * user_data )
338
281
{
339
- MonoImage * image = assembly -> image ;
340
282
mono_image_lock (image );
341
283
AllocateMemoryForMemPool (image -> mempool , user_data );
342
284
mono_image_unlock (image );
@@ -347,40 +289,23 @@ static void CopyMemPool(MonoMemPool *pool, SectionIterationContext *context)
347
289
mono_mempool_foreach_block (pool , CopyMemPoolChunk , context );
348
290
}
349
291
350
- static void CopyImageMemPool (MonoAssembly * assembly , SectionIterationContext * context )
292
+ static void CopyImageMemPool (MonoImage * image , gpointer value , SectionIterationContext * context )
351
293
{
352
- MonoImage * image = assembly -> image ;
353
-
354
294
mono_image_lock (image );
355
295
CopyMemPool (image -> mempool , context );
356
296
mono_image_unlock (image );
357
297
}
358
298
359
- static void MonoImagesCountCallback (MonoAssembly * assembly , void * user_data )
360
- {
361
- int * count = (int * )user_data ;
362
- (* count )++ ;
363
- }
364
-
365
- static int MonoImagesCount ()
299
+ static void AllocateMemoryForImageClassCache (MonoImage * image , gpointer * value , void * user_data )
366
300
{
367
- int count = 0 ;
368
- AllDomainAssembliesForeach ((GFunc )MonoImagesCountCallback , & count );
369
- return count ;
370
- }
371
-
372
- static void AllocateMemoryForImageClassCache (MonoAssembly * assembly , void * user_data )
373
- {
374
- MonoImage * image = assembly -> image ;
375
301
mono_image_lock (image );
376
302
377
303
AllocateMemoryForSection (user_data , image -> class_cache .table , ((uint8_t * )image -> class_cache .table ) + image -> class_cache .size );
378
304
mono_image_unlock (image );
379
305
}
380
306
381
- static void CopyImageClassCache (MonoAssembly * assembly , SectionIterationContext * context )
307
+ static void CopyImageClassCache (MonoImage * image , gpointer value , SectionIterationContext * context )
382
308
{
383
- MonoImage * image = assembly -> image ;
384
309
mono_image_lock (image );
385
310
386
311
CopyHeapSection (context , image -> class_cache .table , ((uint8_t * )image -> class_cache .table ) + image -> class_cache .size );
@@ -411,9 +336,19 @@ static void CopyImageSetMemPool(MonoImageSet* imageSet, void *user_data)
411
336
CopyMemPool (imageSet -> mempool , user_data );
412
337
}
413
338
414
- static void * CaptureHeapInfo (void * monoManagedHeap )
339
+ typedef struct
340
+ {
341
+ MonoManagedHeap * heap ;
342
+ GHashTable * monoImages ;
343
+
344
+ } CaptureHeapInfoData ;
345
+
346
+ static void * CaptureHeapInfo (void * user )
415
347
{
416
- MonoManagedHeap * heap = (MonoManagedHeap * )monoManagedHeap ;
348
+ CaptureHeapInfoData * data = (CaptureHeapInfoData * )user ;
349
+ MonoManagedHeap * heap = data -> heap ;
350
+ GHashTable * monoImages = data -> monoImages ;
351
+
417
352
MonoDomain * domain = mono_domain_get ();
418
353
MonoDomain * rootDomain = mono_get_root_domain ();
419
354
SectionIterationContext iterationContext ;
@@ -424,9 +359,9 @@ static void* CaptureHeapInfo(void* monoManagedHeap)
424
359
heap -> sectionCount += MonoMemPoolNumChunks (rootDomain -> mp );
425
360
heap -> sectionCount += MonoMemPoolNumChunks (domain -> mp );
426
361
// Increment count for each image mem pool chunk
427
- heap -> sectionCount += MonoImagesMemPoolNumChunks ();
362
+ heap -> sectionCount += MonoImagesMemPoolNumChunks (monoImages );
428
363
// Increment count for each image->class_cache hash table.
429
- heap -> sectionCount += MonoImagesCount ( );
364
+ heap -> sectionCount += g_hash_table_size ( monoImages );
430
365
// Increment count for each image set mem pool chunk
431
366
heap -> sectionCount += MonoImageSetsMemPoolNumChunks ();
432
367
@@ -444,9 +379,9 @@ static void* CaptureHeapInfo(void* monoManagedHeap)
444
379
mono_mempool_foreach_block (domain -> mp , AllocateMemoryForMemPoolChunk , & iterationContext );
445
380
mono_domain_unlock (domain );
446
381
// Allocate memory for each image mem pool chunk
447
- AllDomainAssembliesForeach (( GFunc )AllocateMemoryForImageMemPool , & iterationContext );
382
+ g_hash_table_foreach ( monoImages , ( GHFunc )AllocateMemoryForImageMemPool , & iterationContext );
448
383
// Allocate memory for each image->class_cache hash table.
449
- AllDomainAssembliesForeach (( GFunc )AllocateMemoryForImageClassCache , & iterationContext );
384
+ g_hash_table_foreach ( monoImages , ( GHFunc )AllocateMemoryForImageClassCache , & iterationContext );
450
385
// Allocate memory for each image->class_cache hash table.
451
386
mono_metadata_image_set_foreach ((GFunc )AllocateMemoryForImageSetMemPool , & iterationContext );
452
387
@@ -482,7 +417,7 @@ static void VerifyHeapSectionIsStillValid(void* context, void* sectionStart, voi
482
417
iterationContext -> currentSection ++ ;
483
418
}
484
419
485
- static gboolean MonoManagedHeapStillValid (MonoManagedHeap * heap )
420
+ static gboolean MonoManagedHeapStillValid (MonoManagedHeap * heap , GHashTable * monoImages )
486
421
{
487
422
MonoDomain * rootDomain = mono_get_root_domain ();
488
423
MonoDomain * domain = mono_domain_get ();
@@ -493,8 +428,8 @@ static gboolean MonoManagedHeapStillValid(MonoManagedHeap* heap)
493
428
currentSectionCount = GC_get_heap_section_count ();
494
429
currentSectionCount += MonoMemPoolNumChunks (rootDomain -> mp );
495
430
currentSectionCount += MonoMemPoolNumChunks (domain -> mp );
496
- currentSectionCount += MonoImagesMemPoolNumChunks ();
497
- currentSectionCount += MonoImagesCount ( ); // image->class_cache hash table.
431
+ currentSectionCount += MonoImagesMemPoolNumChunks (monoImages );
432
+ currentSectionCount += g_hash_table_size ( monoImages ); // image->class_cache hash table.
498
433
currentSectionCount += MonoImageSetsMemPoolNumChunks ();
499
434
500
435
if (heap -> sectionCount != currentSectionCount )
@@ -519,18 +454,23 @@ static gboolean MonoManagedHeapStillValid(MonoManagedHeap* heap)
519
454
// allocated for their copies.
520
455
// 5) Start the world again.
521
456
522
- static void CaptureManagedHeap (MonoManagedHeap * heap )
457
+ static void CaptureManagedHeap (MonoManagedHeap * heap , GHashTable * monoImages )
523
458
{
524
459
MonoDomain * rootDomain = mono_get_root_domain ();
525
460
MonoDomain * domain = mono_domain_get ();
526
461
SectionIterationContext iterationContext ;
527
462
463
+ CaptureHeapInfoData data ;
464
+
465
+ data .heap = heap ;
466
+ data .monoImages = monoImages ;
467
+
528
468
while (TRUE)
529
469
{
530
- GC_call_with_alloc_lock (CaptureHeapInfo , heap );
470
+ GC_call_with_alloc_lock (CaptureHeapInfo , & data );
531
471
GC_stop_world_external ();
532
472
533
- if (MonoManagedHeapStillValid (heap ))
473
+ if (MonoManagedHeapStillValid (heap , monoImages ))
534
474
break ;
535
475
536
476
GC_start_world_external ();
@@ -543,8 +483,8 @@ static void CaptureManagedHeap(MonoManagedHeap* heap)
543
483
GC_foreach_heap_section (& iterationContext , CopyHeapSection );
544
484
mono_mempool_foreach_block (rootDomain -> mp , CopyMemPoolChunk , & iterationContext );
545
485
mono_mempool_foreach_block (domain -> mp , CopyMemPoolChunk , & iterationContext );
546
- AllDomainAssembliesForeach (( GFunc )CopyImageMemPool , & iterationContext );
547
- AllDomainAssembliesForeach (( GFunc )CopyImageClassCache , & iterationContext );
486
+ g_hash_table_foreach ( monoImages , ( GHFunc )CopyImageMemPool , & iterationContext );
487
+ g_hash_table_foreach ( monoImages , ( GHFunc )CopyImageClassCache , & iterationContext );
548
488
mono_metadata_image_set_foreach ((GFunc )CopyImageSetMemPool , & iterationContext );
549
489
550
490
GC_start_world_external ();
@@ -605,14 +545,24 @@ static gboolean ManagedHeapContainsAddress(MonoManagedHeap* heap, uint64_t addre
605
545
return FALSE;
606
546
}
607
547
608
- static void VerifySnapshot (MonoManagedMemorySnapshot * snapshot )
548
+ static void VerifySnapshot (MonoManagedMemorySnapshot * snapshot , GHashTable * monoImages )
609
549
{
610
550
uint32_t i ;
611
551
FILE * file ;
552
+ GHashTableIter iter ;
553
+ gpointer key ;
612
554
MonoMetadataSnapshot * meta = & snapshot -> metadata ;
613
555
614
556
file = fopen ("MonoMemorySnapshotLog.txt" , "w" );
615
557
558
+ g_hash_table_iter_init (& iter , monoImages );
559
+
560
+ while (g_hash_table_iter_next (& iter , & key , NULL ))
561
+ {
562
+ MonoImage * image = (MonoImage * )key ;
563
+ fprintf (file , "MonoImage [0x%016llX] dynamic: %i name: '%s'\n" , (void * )image , image -> dynamic , image -> name );
564
+ }
565
+
616
566
/* Verify that we have collected memory sections for all types */
617
567
for (i = 0 ; i < meta -> typeCount ; ++ i )
618
568
{
@@ -627,20 +577,51 @@ static void VerifySnapshot(MonoManagedMemorySnapshot* snapshot)
627
577
fclose (file );
628
578
}
629
579
580
+ static void CollectMonoImage (MonoImage * image , GHashTable * monoImages )
581
+ {
582
+ if (g_hash_table_lookup (monoImages , image ) == NULL )
583
+ g_hash_table_insert (monoImages , image , image );
584
+
585
+ if (image -> module_count > 0 )
586
+ {
587
+ int i ;
588
+
589
+ for (i = 0 ; i < image -> module_count ; ++ i )
590
+ {
591
+ MonoImage * moduleImage = image -> modules [i ];
592
+
593
+ if (moduleImage )
594
+ CollectMonoImage (moduleImage , monoImages );
595
+ }
596
+ }
597
+ }
598
+
599
+ static void CollectMonoImageFromAssembly (MonoAssembly * assembly , void * user_data )
600
+ {
601
+ GHashTable * monoImages = (GHashTable * )user_data ;
602
+ CollectMonoImage (assembly -> image , monoImages );
603
+ }
604
+
630
605
MonoManagedMemorySnapshot * mono_unity_capture_memory_snapshot ()
631
606
{
632
607
MonoManagedMemorySnapshot * snapshot ;
633
608
snapshot = g_new0 (MonoManagedMemorySnapshot , 1 );
634
609
635
- CollectMetadata (& snapshot -> metadata );
636
- CaptureManagedHeap (& snapshot -> heap );
610
+ GHashTable * monoImages = g_hash_table_new (NULL , NULL );
611
+
612
+ mono_domain_assembly_foreach (mono_domain_get (), CollectMonoImageFromAssembly , monoImages );
613
+
614
+ CollectMetadata (& snapshot -> metadata , monoImages );
615
+ CaptureManagedHeap (& snapshot -> heap , monoImages );
637
616
CaptureGCHandleTargets (& snapshot -> gcHandles );
638
617
FillRuntimeInformation (& snapshot -> runtimeInformation );
639
618
640
619
#if _DEBUG
641
- VerifySnapshot (snapshot );
620
+ VerifySnapshot (snapshot , monoImages );
642
621
#endif
643
622
623
+ g_hash_table_destroy (monoImages );
624
+
644
625
return snapshot ;
645
626
}
646
627
0 commit comments