Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Memoryprofiler] Exposing required mono API for backend migration #1206

Merged
merged 8 commits into from
Jul 29, 2019
4 changes: 1 addition & 3 deletions mono/metadata/mempool.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,10 +442,8 @@ mono_mempool_foreach_block(MonoMemPool* pool, mono_mempool_block_proc callback,

while (current)
{
gpointer start = (guint8*)current + SIZEOF_MEM_POOL;
gpointer end = (guint8*)current + current->size;

callback(start, end, user_data);
callback(current, end, user_data);
joncham marked this conversation as resolved.
Show resolved Hide resolved
current = current->next;
}
}
Expand Down
111 changes: 111 additions & 0 deletions mono/metadata/unity-memory-info.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,117 @@ static void CollectMonoImageFromAssembly(MonoAssembly *assembly, void *user_data
CollectMonoImage(assembly->image, monoImages);
}



typedef struct ClassReportContext {
ClassReportFunc callback;
void *user_data;
} ClassReportContext;

static void
ReportHashMapClasses(gpointer key, gpointer value, gpointer user_data)
{
ClassReportContext *context = (ClassReportContext *)user_data;
MonoClass *klass = (MonoClass *)value;
if (klass->inited)
context->callback(klass, context->user_data);
}

static void
ReportHashMapListClasses(gpointer key, gpointer value, gpointer user_data)
{
ClassReportContext *context = (ClassReportContext *)user_data;
GSList *list = (GSList *)value;

while (list != NULL) {
MonoClass *klass = (MonoClass *)list->data;

if (klass->inited)
context->callback(klass, context->user_data);

list = g_slist_next(list);
}
}

static void
ReportClassesFromAssembly(MonoAssembly *assembly, void *user_data)
{
MonoImage *image = mono_assembly_get_image(assembly);
int i;
MonoTableInfo *tdef = &image->tables[MONO_TABLE_TYPEDEF];
GSList *list;
ClassReportContext *context = (ClassReportContext*)user_data;

if (image->dynamic) {
GHashTableIter iter;
gpointer key;
MonoDynamicImage *dynamicImage = (MonoDynamicImage *)image;
g_hash_table_iter_init(&iter, dynamicImage->typeref);

while (g_hash_table_iter_next(&iter, &key, NULL)) {
MonoType *monoType = (MonoType *)key;
MonoClass *klass = mono_class_from_mono_type(monoType);

if (klass && klass->inited)
context->callback(klass, context->user_data);
}
}

/* Some classes are only in this list.
They are added in reflection_setup_internal_class_internal.
*/
list = image->reflection_info_unregister_classes;

while (list) {
MonoClass *klass = (MonoClass *)list->data;

if (klass && klass->inited)
context->callback(klass, context->user_data);

list = list->next;
}

for (i = 1; i < tdef->rows; ++i) {
MonoClass *klass;
MonoError error;

guint32 token = (i + 1) | MONO_TOKEN_TYPE_DEF;

klass = mono_class_get_checked(image, token, &error);

if (klass && klass->inited)
context->callback(klass, context->user_data);
}

if (image->array_cache)
g_hash_table_foreach(image->array_cache, ReportHashMapListClasses, user_data);

if (image->szarray_cache)
g_hash_table_foreach(image->szarray_cache, ReportHashMapClasses, user_data);

if (image->ptr_cache)
g_hash_table_foreach(image->ptr_cache, ReportHashMapClasses, user_data);
}

static void
ReportGenericClasses(MonoGenericClass *genericClass, gpointer user_data)
{
ClassReportContext *context = (ClassReportContext *)user_data;

if (genericClass->cached_class != NULL)
context->callback(genericClass->cached_class, context->user_data);
}

void
mono_unity_class_for_each(ClassReportFunc callback, void *user_data)
{
ClassReportContext reportContext;
reportContext.callback = callback;
reportContext.user_data = user_data;
mono_domain_assembly_foreach(mono_domain_get(), ReportClassesFromAssembly, &reportContext);
mono_metadata_generic_class_foreach(ReportGenericClasses, &reportContext);
}

MonoManagedMemorySnapshot* mono_unity_capture_memory_snapshot()
{
GC_disable();
Expand Down
7 changes: 7 additions & 0 deletions mono/metadata/unity-memory-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ typedef struct MonoManagedMemorySnapshot
void* additionalUserInformation;
} MonoManagedMemorySnapshot;

typedef struct _MonoClass MonoClass;

typedef void(*ClassReportFunc) (MonoClass* klass, void *user_data);

MONO_API void
mono_unity_class_for_each(ClassReportFunc callback, void* user_data);

MONO_API MonoManagedMemorySnapshot* mono_unity_capture_memory_snapshot();
MONO_API void mono_unity_free_captured_memory_snapshot(MonoManagedMemorySnapshot* snapshot);

Expand Down
Loading