Skip to content

Commit 1edb2d5

Browse files
committed
Initial work on collecting classes from dynamic assemblies.
1 parent 043dafa commit 1edb2d5

File tree

3 files changed

+116
-17
lines changed

3 files changed

+116
-17
lines changed

mono/metadata/appdomain.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef struct _MonoAppDomain MonoAppDomain;
2626
typedef struct _MonoJitInfo MonoJitInfo;
2727

2828
typedef void (*MonoDomainFunc) (MonoDomain *domain, void* user_data);
29+
typedef void(*MonoDomainAssemblyFunc) (MonoAssembly *assembly, void* user_data);
2930

3031
MONO_API MonoDomain*
3132
mono_init (const char *filename);
@@ -108,6 +109,9 @@ mono_domain_from_appdomain (MonoAppDomain *appdomain);
108109
MONO_API void
109110
mono_domain_foreach (MonoDomainFunc func, void* user_data);
110111

112+
MONO_API void
113+
mono_domain_assembly_foreach (MonoDomain* domain, MonoDomainAssemblyFunc func, void* user_data);
114+
111115
MONO_API MonoAssembly *
112116
mono_domain_assembly_open (MonoDomain *domain, const char *name);
113117

mono/metadata/domain.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,27 @@ mono_domain_foreach (MonoDomainFunc func, gpointer user_data)
982982
gc_free_fixed_non_heap_list (copy);
983983
}
984984

985+
MONO_API void
986+
mono_domain_assembly_foreach (MonoDomain* domain, MonoDomainFunc func, void* user_data)
987+
{
988+
MonoAssembly* assembly;
989+
GSList *iter;
990+
991+
/* Skipping internal assembly builders created by remoting,
992+
as it is done in ves_icall_System_AppDomain_GetAssemblies
993+
*/
994+
mono_domain_assemblies_lock(domain);
995+
for (iter = domain->domain_assemblies; iter; iter = iter->next)
996+
{
997+
assembly = (MonoAssembly *)iter->data;
998+
if (assembly->corlib_internal)
999+
continue;
1000+
1001+
func(assembly, user_data);
1002+
}
1003+
mono_domain_assemblies_unlock(domain);
1004+
}
1005+
9851006
/* FIXME: maybe we should integrate this with mono_assembly_open? */
9861007
/**
9871008
* mono_domain_assembly_open:

mono/metadata/unity-memory-info.c

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@ 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+
2349
static void ContextInsertClass(CollectMetadataContext* context, MonoClass* klass)
2450
{
2551
if (klass->inited && g_hash_table_lookup(context->allTypes, klass) == NULL)
@@ -56,27 +82,74 @@ static void CollectGenericClass(gpointer value, gpointer user_data)
5682
ContextInsertClass(context, genericClass->cached_class);
5783
}
5884

59-
static void CollectAssemblyMetaData(MonoAssembly *assembly, void *user_data)
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)
6093
{
6194
int i;
62-
CollectMetadataContext* context = (CollectMetadataContext*)user_data;
63-
MonoImage* image = mono_assembly_get_image(assembly);
6495
MonoTableInfo *tdef = &image->tables[MONO_TABLE_TYPEDEF];
6596

66-
for (i = 0; i < tdef->rows - 1; ++i)
97+
if (image->module_count > 0)
6798
{
68-
MonoClass* klass = mono_class_get(image, (i + 2) | MONO_TOKEN_TYPE_DEF);
69-
ContextInsertClass(context, klass);
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+
if (image->dynamic)
109+
{
110+
MonoDynamicImage* dynamicImage = (MonoDynamicImage*)image;
111+
GList* types = g_hash_table_get_keys(dynamicImage->typeref);
112+
GList* type;
113+
114+
for (type = types; type != NULL; type = type->next)
115+
{
116+
MonoType* monoType = (MonoType*)type->data;
117+
MonoClass* klass = mono_type_get_class(monoType);
118+
119+
if (klass)
120+
ContextInsertClass(context, klass);
121+
}
122+
}
123+
124+
for (i = 1; i < tdef->rows; ++i)
125+
{
126+
MonoClass *klass;
127+
MonoError error;
128+
129+
guint32 token = (i + 1) | MONO_TOKEN_TYPE_DEF;
130+
131+
klass = mono_class_get_checked(image, token, &error);
132+
133+
if (klass)
134+
ContextInsertClass(context, klass);
70135
}
71136

72137
if (image->array_cache)
73-
g_hash_table_foreach(image->array_cache, CollectHashMapListClasses, user_data);
138+
g_hash_table_foreach(image->array_cache, CollectHashMapListClasses, context);
74139

75140
if (image->szarray_cache)
76-
g_hash_table_foreach(image->szarray_cache, CollectHashMapClass, user_data);
141+
g_hash_table_foreach(image->szarray_cache, CollectHashMapClass, context);
77142

78143
if (image->ptr_cache)
79-
g_hash_table_foreach(image->ptr_cache, CollectHashMapClass, user_data);
144+
g_hash_table_foreach(image->ptr_cache, CollectHashMapClass, context);
145+
}
146+
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);
80153
}
81154

82155
static int FindClassIndex(GHashTable* hashTable, MonoClass* klass)
@@ -169,7 +242,7 @@ static void CollectMetadata(MonoMetadataSnapshot* metadata)
169242
context.currentIndex = 0;
170243
context.metadata = metadata;
171244

172-
mono_assembly_foreach((GFunc)CollectAssemblyMetaData, &context);
245+
AllDomainAssembliesForeach(CollectAssemblyMetaData, &context);
173246

174247
mono_metadata_generic_class_foreach(CollectGenericClass, &context);
175248

@@ -251,7 +324,8 @@ static void IncrementCountForImageMemPoolNumChunks(MonoAssembly *assembly, void
251324
static int MonoImagesMemPoolNumChunks()
252325
{
253326
int count = 0;
254-
mono_assembly_foreach((GFunc)IncrementCountForImageMemPoolNumChunks, &count);
327+
328+
AllDomainAssembliesForeach((GFunc)IncrementCountForImageMemPoolNumChunks, &count);
255329
return count;
256330
}
257331

@@ -291,7 +365,7 @@ static void MonoImagesCountCallback(MonoAssembly *assembly, void *user_data)
291365
static int MonoImagesCount()
292366
{
293367
int count = 0;
294-
mono_assembly_foreach((GFunc)MonoImagesCountCallback, &count);
368+
AllDomainAssembliesForeach((GFunc)MonoImagesCountCallback, &count);
295369
return count;
296370
}
297371

@@ -370,9 +444,9 @@ static void* CaptureHeapInfo(void* monoManagedHeap)
370444
mono_mempool_foreach_block(domain->mp, AllocateMemoryForMemPoolChunk, &iterationContext);
371445
mono_domain_unlock(domain);
372446
// Allocate memory for each image mem pool chunk
373-
mono_assembly_foreach((GFunc)AllocateMemoryForImageMemPool, &iterationContext);
447+
AllDomainAssembliesForeach((GFunc)AllocateMemoryForImageMemPool, &iterationContext);
374448
// Allocate memory for each image->class_cache hash table.
375-
mono_assembly_foreach((GFunc)AllocateMemoryForImageClassCache, &iterationContext);
449+
AllDomainAssembliesForeach((GFunc)AllocateMemoryForImageClassCache, &iterationContext);
376450
// Allocate memory for each image->class_cache hash table.
377451
mono_metadata_image_set_foreach((GFunc)AllocateMemoryForImageSetMemPool, &iterationContext);
378452

@@ -469,8 +543,8 @@ static void CaptureManagedHeap(MonoManagedHeap* heap)
469543
GC_foreach_heap_section(&iterationContext, CopyHeapSection);
470544
mono_mempool_foreach_block(rootDomain->mp, CopyMemPoolChunk, &iterationContext);
471545
mono_mempool_foreach_block(domain->mp, CopyMemPoolChunk, &iterationContext);
472-
mono_assembly_foreach((GFunc)CopyImageMemPool, &iterationContext);
473-
mono_assembly_foreach((GFunc)CopyImageClassCache, &iterationContext);
546+
AllDomainAssembliesForeach((GFunc)CopyImageMemPool, &iterationContext);
547+
AllDomainAssembliesForeach((GFunc)CopyImageClassCache, &iterationContext);
474548
mono_metadata_image_set_foreach((GFunc)CopyImageSetMemPool, &iterationContext);
475549

476550
GC_start_world_external();
@@ -546,7 +620,7 @@ static void VerifySnapshot(MonoManagedMemorySnapshot* snapshot)
546620

547621
if (!ManagedHeapContainsAddress(&snapshot->heap, type->typeInfoAddress))
548622
{
549-
fprintf(file, "The memory for type '%s' @ 0x%016X is not the part the snapshot.\n", type->name, type->typeInfoAddress);
623+
fprintf(file, "The memory for type '%s' @ 0x%016llX is not the part the snapshot.\n", type->name, type->typeInfoAddress);
550624
}
551625
}
552626

0 commit comments

Comments
 (0)