Skip to content

Commit 1de54af

Browse files
committed
Refactor iteration over all MonoImage's by collecting them all in hash table and iterating over the hash table.
1 parent 1edb2d5 commit 1de54af

File tree

1 file changed

+85
-104
lines changed

1 file changed

+85
-104
lines changed

mono/metadata/unity-memory-info.c

Lines changed: 85 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,6 @@ typedef struct CollectMetadataContext
2020
MonoMetadataSnapshot* metadata;
2121
} CollectMetadataContext;
2222

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-
4923
static void ContextInsertClass(CollectMetadataContext* context, MonoClass* klass)
5024
{
5125
if (klass->inited && g_hash_table_lookup(context->allTypes, klass) == NULL)
@@ -82,29 +56,11 @@ static void CollectGenericClass(gpointer value, gpointer user_data)
8256
ContextInsertClass(context, genericClass->cached_class);
8357
}
8458

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)
9360
{
9461
int i;
9562
MonoTableInfo *tdef = &image->tables[MONO_TABLE_TYPEDEF];
9663

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-
10864
if (image->dynamic)
10965
{
11066
MonoDynamicImage* dynamicImage = (MonoDynamicImage*)image;
@@ -144,14 +100,6 @@ static void CollectImageMetaData(MonoImage* image, CollectMetadataContext* conte
144100
g_hash_table_foreach(image->ptr_cache, CollectHashMapClass, context);
145101
}
146102

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-
155103
static int FindClassIndex(GHashTable* hashTable, MonoClass* klass)
156104
{
157105
gpointer value = g_hash_table_lookup(hashTable, klass);
@@ -234,15 +182,15 @@ static void AddMetadataType(gpointer key, gpointer value, gpointer user_data)
234182
type->size = (klass->valuetype) != 0 ? (mono_class_instance_size(klass) - sizeof(MonoObject)) : mono_class_instance_size(klass);
235183
}
236184

237-
static void CollectMetadata(MonoMetadataSnapshot* metadata)
185+
static void CollectMetadata(MonoMetadataSnapshot* metadata, GHashTable* monoImages)
238186
{
239187
CollectMetadataContext context;
240188

241189
context.allTypes = g_hash_table_new(NULL, NULL);
242190
context.currentIndex = 0;
243191
context.metadata = metadata;
244192

245-
AllDomainAssembliesForeach(CollectAssemblyMetaData, &context);
193+
g_hash_table_foreach(monoImages, (GHFunc)CollectImageMetaData, &context);
246194

247195
mono_metadata_generic_class_foreach(CollectGenericClass, &context);
248196

@@ -310,22 +258,17 @@ static void CopyMemPoolChunk(void* chunkStart, void* chunkEnd, void* context)
310258
CopyHeapSection(context, chunkStart, chunkEnd);
311259
}
312260

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)
319262
{
320263
int* count = (int*)user_data;
321-
(*count) += MonoMemPoolNumChunks(assembly->image->mempool);
264+
(*count) += MonoMemPoolNumChunks(image->mempool);
322265
}
323266

324-
static int MonoImagesMemPoolNumChunks()
267+
static int MonoImagesMemPoolNumChunks(GHashTable* monoImages)
325268
{
326269
int count = 0;
327270

328-
AllDomainAssembliesForeach((GFunc)IncrementCountForImageMemPoolNumChunks, &count);
271+
g_hash_table_foreach(monoImages, (GHFunc)IncrementCountForImageMemPoolNumChunks, &count);
329272
return count;
330273
}
331274

@@ -334,9 +277,8 @@ static void AllocateMemoryForMemPool(MonoMemPool* pool, void *user_data)
334277
mono_mempool_foreach_block(pool, AllocateMemoryForMemPoolChunk, user_data);
335278
}
336279

337-
static void AllocateMemoryForImageMemPool(MonoAssembly *assembly, void *user_data)
280+
static void AllocateMemoryForImageMemPool(MonoImage *image, gpointer value, void *user_data)
338281
{
339-
MonoImage* image = assembly->image;
340282
mono_image_lock(image);
341283
AllocateMemoryForMemPool(image->mempool, user_data);
342284
mono_image_unlock(image);
@@ -347,40 +289,23 @@ static void CopyMemPool(MonoMemPool *pool, SectionIterationContext *context)
347289
mono_mempool_foreach_block(pool, CopyMemPoolChunk, context);
348290
}
349291

350-
static void CopyImageMemPool(MonoAssembly *assembly, SectionIterationContext *context)
292+
static void CopyImageMemPool(MonoImage *image, gpointer value, SectionIterationContext *context)
351293
{
352-
MonoImage* image = assembly->image;
353-
354294
mono_image_lock(image);
355295
CopyMemPool(image->mempool, context);
356296
mono_image_unlock(image);
357297
}
358298

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)
366300
{
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;
375301
mono_image_lock(image);
376302

377303
AllocateMemoryForSection(user_data, image->class_cache.table, ((uint8_t*)image->class_cache.table) + image->class_cache.size);
378304
mono_image_unlock(image);
379305
}
380306

381-
static void CopyImageClassCache(MonoAssembly *assembly, SectionIterationContext *context)
307+
static void CopyImageClassCache(MonoImage *image, gpointer value, SectionIterationContext *context)
382308
{
383-
MonoImage* image = assembly->image;
384309
mono_image_lock(image);
385310

386311
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)
411336
CopyMemPool(imageSet->mempool, user_data);
412337
}
413338

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)
415347
{
416-
MonoManagedHeap* heap = (MonoManagedHeap*)monoManagedHeap;
348+
CaptureHeapInfoData* data = (CaptureHeapInfoData*)user;
349+
MonoManagedHeap* heap = data->heap;
350+
GHashTable* monoImages = data->monoImages;
351+
417352
MonoDomain* domain = mono_domain_get();
418353
MonoDomain* rootDomain = mono_get_root_domain();
419354
SectionIterationContext iterationContext;
@@ -424,9 +359,9 @@ static void* CaptureHeapInfo(void* monoManagedHeap)
424359
heap->sectionCount += MonoMemPoolNumChunks(rootDomain->mp);
425360
heap->sectionCount += MonoMemPoolNumChunks(domain->mp);
426361
// Increment count for each image mem pool chunk
427-
heap->sectionCount += MonoImagesMemPoolNumChunks();
362+
heap->sectionCount += MonoImagesMemPoolNumChunks(monoImages);
428363
// Increment count for each image->class_cache hash table.
429-
heap->sectionCount += MonoImagesCount();
364+
heap->sectionCount += g_hash_table_size(monoImages);
430365
// Increment count for each image set mem pool chunk
431366
heap->sectionCount += MonoImageSetsMemPoolNumChunks();
432367

@@ -444,9 +379,9 @@ static void* CaptureHeapInfo(void* monoManagedHeap)
444379
mono_mempool_foreach_block(domain->mp, AllocateMemoryForMemPoolChunk, &iterationContext);
445380
mono_domain_unlock(domain);
446381
// Allocate memory for each image mem pool chunk
447-
AllDomainAssembliesForeach((GFunc)AllocateMemoryForImageMemPool, &iterationContext);
382+
g_hash_table_foreach(monoImages, (GHFunc)AllocateMemoryForImageMemPool, &iterationContext);
448383
// Allocate memory for each image->class_cache hash table.
449-
AllDomainAssembliesForeach((GFunc)AllocateMemoryForImageClassCache, &iterationContext);
384+
g_hash_table_foreach(monoImages, (GHFunc)AllocateMemoryForImageClassCache, &iterationContext);
450385
// Allocate memory for each image->class_cache hash table.
451386
mono_metadata_image_set_foreach((GFunc)AllocateMemoryForImageSetMemPool, &iterationContext);
452387

@@ -482,7 +417,7 @@ static void VerifyHeapSectionIsStillValid(void* context, void* sectionStart, voi
482417
iterationContext->currentSection++;
483418
}
484419

485-
static gboolean MonoManagedHeapStillValid(MonoManagedHeap* heap)
420+
static gboolean MonoManagedHeapStillValid(MonoManagedHeap* heap, GHashTable* monoImages)
486421
{
487422
MonoDomain* rootDomain = mono_get_root_domain();
488423
MonoDomain* domain = mono_domain_get();
@@ -493,8 +428,8 @@ static gboolean MonoManagedHeapStillValid(MonoManagedHeap* heap)
493428
currentSectionCount = GC_get_heap_section_count();
494429
currentSectionCount += MonoMemPoolNumChunks(rootDomain->mp);
495430
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.
498433
currentSectionCount += MonoImageSetsMemPoolNumChunks();
499434

500435
if (heap->sectionCount != currentSectionCount)
@@ -519,18 +454,23 @@ static gboolean MonoManagedHeapStillValid(MonoManagedHeap* heap)
519454
// allocated for their copies.
520455
// 5) Start the world again.
521456

522-
static void CaptureManagedHeap(MonoManagedHeap* heap)
457+
static void CaptureManagedHeap(MonoManagedHeap* heap, GHashTable* monoImages)
523458
{
524459
MonoDomain* rootDomain = mono_get_root_domain();
525460
MonoDomain* domain = mono_domain_get();
526461
SectionIterationContext iterationContext;
527462

463+
CaptureHeapInfoData data;
464+
465+
data.heap = heap;
466+
data.monoImages = monoImages;
467+
528468
while (TRUE)
529469
{
530-
GC_call_with_alloc_lock(CaptureHeapInfo, heap);
470+
GC_call_with_alloc_lock(CaptureHeapInfo, &data);
531471
GC_stop_world_external();
532472

533-
if (MonoManagedHeapStillValid(heap))
473+
if (MonoManagedHeapStillValid(heap, monoImages))
534474
break;
535475

536476
GC_start_world_external();
@@ -543,8 +483,8 @@ static void CaptureManagedHeap(MonoManagedHeap* heap)
543483
GC_foreach_heap_section(&iterationContext, CopyHeapSection);
544484
mono_mempool_foreach_block(rootDomain->mp, CopyMemPoolChunk, &iterationContext);
545485
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);
548488
mono_metadata_image_set_foreach((GFunc)CopyImageSetMemPool, &iterationContext);
549489

550490
GC_start_world_external();
@@ -605,14 +545,24 @@ static gboolean ManagedHeapContainsAddress(MonoManagedHeap* heap, uint64_t addre
605545
return FALSE;
606546
}
607547

608-
static void VerifySnapshot(MonoManagedMemorySnapshot* snapshot)
548+
static void VerifySnapshot(MonoManagedMemorySnapshot* snapshot, GHashTable* monoImages)
609549
{
610550
uint32_t i;
611551
FILE* file;
552+
GHashTableIter iter;
553+
gpointer key;
612554
MonoMetadataSnapshot* meta = &snapshot->metadata;
613555

614556
file = fopen("MonoMemorySnapshotLog.txt", "w");
615557

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+
616566
/* Verify that we have collected memory sections for all types */
617567
for (i = 0; i < meta->typeCount; ++i)
618568
{
@@ -627,20 +577,51 @@ static void VerifySnapshot(MonoManagedMemorySnapshot* snapshot)
627577
fclose(file);
628578
}
629579

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+
630605
MonoManagedMemorySnapshot* mono_unity_capture_memory_snapshot()
631606
{
632607
MonoManagedMemorySnapshot* snapshot;
633608
snapshot = g_new0(MonoManagedMemorySnapshot, 1);
634609

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);
637616
CaptureGCHandleTargets(&snapshot->gcHandles);
638617
FillRuntimeInformation(&snapshot->runtimeInformation);
639618

640619
#if _DEBUG
641-
VerifySnapshot(snapshot);
620+
VerifySnapshot(snapshot, monoImages);
642621
#endif
643622

623+
g_hash_table_destroy(monoImages);
624+
644625
return snapshot;
645626
}
646627

0 commit comments

Comments
 (0)