Skip to content

Commit 042dab8

Browse files
committed
track (most) native modules per image and clean up when image is unloaded
one dlopen per module and image trust OS to do ref counting.
1 parent 2bcc60e commit 042dab8

File tree

4 files changed

+59
-26
lines changed

4 files changed

+59
-26
lines changed

mono/metadata/image.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,12 @@ mono_image_close_except_pools_all (MonoImage**images, int image_count)
19321932
}
19331933
}
19341934

1935+
static void
1936+
remove_cached_module(gpointer key, gpointer value, gpointer user_data)
1937+
{
1938+
mono_dl_close((MonoDl*)value);
1939+
}
1940+
19351941
/*
19361942
* Returns whether mono_image_close_finish() must be called as well.
19371943
* We must unload images in two steps because clearing the domain in
@@ -2072,6 +2078,10 @@ mono_image_close_except_pools (MonoImage *image)
20722078
g_hash_table_foreach (image->name_cache, free_hash_table, NULL);
20732079
g_hash_table_destroy (image->name_cache);
20742080
}
2081+
if (image->module_map) {
2082+
g_hash_table_foreach (image->module_map, remove_cached_module, NULL);
2083+
g_hash_table_destroy (image->module_map);
2084+
}
20752085

20762086
free_hash (image->delegate_bound_static_invoke_cache);
20772087
free_hash (image->runtime_invoke_vcall_cache);

mono/metadata/loader.c

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ static gint32 signatures_size;
7575
MonoNativeTlsKey loader_lock_nest_id;
7676

7777
static void dllmap_cleanup (void);
78-
static void cached_module_cleanup(void);
78+
static void embedded_module_cleanup (void);
79+
80+
void mono_image_lock(MonoImage *image);
81+
void mono_image_unlock(MonoImage *image);
7982

8083
/* Class lazy loading functions */
8184
GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, "System", "AppDomainUnloadedException")
@@ -122,7 +125,7 @@ void
122125
mono_loader_cleanup (void)
123126
{
124127
dllmap_cleanup ();
125-
cached_module_cleanup ();
128+
embedded_module_cleanup ();
126129

127130
mono_native_tls_free (loader_lock_nest_id);
128131

@@ -1109,10 +1112,10 @@ dllmap_cleanup (void)
11091112
global_dll_map = NULL;
11101113
}
11111114

1112-
static GHashTable *global_module_map;
1115+
static GHashTable *embedded_module_map;
11131116

11141117
static MonoDl*
1115-
cached_module_load (const char *name, int flags, char **err)
1118+
cached_module_load (MonoImage* image, const char *name, int flags, char **err)
11161119
{
11171120
MonoDl *res;
11181121
const char *name_remap;
@@ -1121,46 +1124,63 @@ cached_module_load (const char *name, int flags, char **err)
11211124
*err = NULL;
11221125
if (name_remap = mono_unity_remap_path (name))
11231126
name = name_remap;
1127+
11241128
global_loader_data_lock ();
1125-
if (!global_module_map)
1126-
global_module_map = g_hash_table_new (g_str_hash, g_str_equal);
1127-
res = (MonoDl *)g_hash_table_lookup (global_module_map, name);
1129+
if (embedded_module_map)
1130+
{
1131+
res = (MonoDl *)g_hash_table_lookup(embedded_module_map, name);
1132+
if (res) {
1133+
global_loader_data_unlock();
1134+
return res;
1135+
}
1136+
}
1137+
global_loader_data_unlock ();
1138+
1139+
mono_image_lock (image);
1140+
if (!image->module_map)
1141+
image->module_map = g_hash_table_new (g_str_hash, g_str_equal);
1142+
res = (MonoDl *)g_hash_table_lookup (image->module_map, name);
11281143
if (res) {
1129-
global_loader_data_unlock ();
1144+
mono_image_unlock (image);
11301145
g_free((void*)name_remap);
11311146
return res;
11321147
}
11331148
res = mono_dl_open (name, flags, err);
11341149
if (res)
1135-
g_hash_table_insert (global_module_map, g_strdup (name), res);
1136-
global_loader_data_unlock ();
1150+
g_hash_table_insert (image->module_map, g_strdup (name), res);
1151+
mono_image_unlock (image);
1152+
11371153
g_free((void*)name_remap);
11381154
return res;
11391155
}
11401156

11411157
void
1142-
mono_loader_register_module (const char *name, MonoDl *module)
1158+
mono_loader_register_embedded_module (const char *name, MonoDl *module)
11431159
{
1144-
if (!global_module_map)
1145-
global_module_map = g_hash_table_new (g_str_hash, g_str_equal);
1146-
g_hash_table_insert (global_module_map, g_strdup (name), module);
1160+
global_loader_data_lock ();
1161+
if (!embedded_module_map)
1162+
embedded_module_map = g_hash_table_new(g_str_hash, g_str_equal);
1163+
g_hash_table_insert(embedded_module_map, g_strdup(name), module);
1164+
global_loader_data_unlock ();
11471165
}
11481166

11491167
static void
1150-
remove_cached_module(gpointer key, gpointer value, gpointer user_data)
1168+
remove_embedded_module (gpointer key, gpointer value, gpointer user_data)
11511169
{
11521170
mono_dl_close((MonoDl*)value);
11531171
}
11541172

11551173
static void
1156-
cached_module_cleanup(void)
1174+
embedded_module_cleanup (void)
11571175
{
1158-
if (global_module_map != NULL) {
1159-
g_hash_table_foreach(global_module_map, remove_cached_module, NULL);
1176+
global_loader_data_lock ();
1177+
if (embedded_module_map != NULL) {
1178+
g_hash_table_foreach(embedded_module_map, remove_embedded_module, NULL);
11601179

1161-
g_hash_table_destroy(global_module_map);
1162-
global_module_map = NULL;
1180+
g_hash_table_destroy(embedded_module_map);
1181+
embedded_module_map = NULL;
11631182
}
1183+
global_loader_data_unlock ();
11641184
}
11651185

11661186
static MonoDl *internal_module;
@@ -1347,7 +1367,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
13471367
}
13481368

13491369
if (!module && is_absolute) {
1350-
module = cached_module_load (file_name, MONO_DL_LAZY, &error_msg);
1370+
module = cached_module_load (image, file_name, MONO_DL_LAZY, &error_msg);
13511371
if (!module) {
13521372
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT,
13531373
"DllImport error loading library '%s': '%s'.",
@@ -1419,7 +1439,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
14191439
continue;
14201440

14211441
while ((full_name = mono_dl_build_path (mdirname, file_name, &iter))) {
1422-
module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg);
1442+
module = cached_module_load (image, full_name, MONO_DL_LAZY, &error_msg);
14231443
if (!module) {
14241444
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT,
14251445
"DllImport error loading library '%s': '%s'.",
@@ -1444,7 +1464,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
14441464
void *iter = NULL;
14451465
char *file_or_base = is_absolute ? base_name : file_name;
14461466
while ((full_name = mono_dl_build_path (dir_name, file_or_base, &iter))) {
1447-
module = cached_module_load (full_name, MONO_DL_LAZY, &error_msg);
1467+
module = cached_module_load (image, full_name, MONO_DL_LAZY, &error_msg);
14481468
if (!module) {
14491469
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT,
14501470
"DllImport error loading library '%s': '%s'.",
@@ -1460,7 +1480,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char
14601480
}
14611481

14621482
if (!module) {
1463-
module = cached_module_load (file_name, MONO_DL_LAZY, &error_msg);
1483+
module = cached_module_load (image, file_name, MONO_DL_LAZY, &error_msg);
14641484
if (!module) {
14651485
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT,
14661486
"DllImport error loading library '%s': '%s'.",

mono/metadata/metadata-internals.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,9 @@ struct _MonoImage {
373373
/* dll map entries */
374374
MonoDllMap *dll_map;
375375

376+
/* used to track native modules */
377+
GHashTable *module_map;
378+
376379
/* interfaces IDs from this image */
377380
/* protected by the classes lock */
378381
MonoBitSet *interface_bitset;
@@ -951,7 +954,7 @@ MonoImageSet *
951954
mono_find_image_set_owner (void *ptr);
952955

953956
MONO_API void
954-
mono_loader_register_module (const char *name, MonoDl *module);
957+
mono_loader_register_embedded_module (const char *name, MonoDl *module);
955958

956959
gboolean
957960
mono_assembly_is_problematic_version (const char *name, guint16 major, guint16 minor, guint16 build, guint16 revision);

mono/mini/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ save_library (int fd, uint64_t offset, uint64_t size, const char *destfname)
178178
}
179179
// Register the name with "." as this is how it will be found when embedded
180180
internal_path = g_build_filename (".", destfname, NULL);
181-
mono_loader_register_module (internal_path, lib);
181+
mono_loader_register_embedded_module (internal_path, lib);
182182
g_free (internal_path);
183183
bundle_library_paths = g_slist_append (bundle_library_paths, file);
184184

0 commit comments

Comments
 (0)