Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mono/metadata/Makefile.am1
-rw-r--r--mono/metadata/appdomain.c18
-rw-r--r--mono/metadata/assembly-load-context.c25
-rw-r--r--mono/metadata/assembly.c14
-rw-r--r--mono/metadata/domain-internals.h54
-rw-r--r--mono/metadata/domain.c118
-rw-r--r--mono/metadata/loader-internals.h119
-rw-r--r--mono/metadata/memory-manager.c211
-rw-r--r--mono/metadata/object.c28
-rw-r--r--mono/metadata/reflection-cache.h40
-rw-r--r--mono/metadata/reflection.c83
-rw-r--r--mono/metadata/sre.c7
-rw-r--r--mono/mini/interp/interp.c21
-rw-r--r--mono/mini/interp/transform.c3
-rw-r--r--mono/mini/method-to-ir.c5
-rw-r--r--mono/mini/mini-runtime.c2
-rw-r--r--mono/mini/monovm.h2
-rw-r--r--msvc/libmonoruntime-common.targets1
-rw-r--r--msvc/libmonoruntime-common.targets.filters5
19 files changed, 525 insertions, 232 deletions
diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am
index 76fa995d570..aa593365235 100644
--- a/mono/metadata/Makefile.am
+++ b/mono/metadata/Makefile.am
@@ -427,6 +427,7 @@ common_sources = \
callspec.h \
callspec.c \
abi.c \
+ memory-manager.c \
native-library.c \
native-library.h \
native-library-qcall.c \
diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c
index 88686b60828..0c3e89d9864 100644
--- a/mono/metadata/appdomain.c
+++ b/mono/metadata/appdomain.c
@@ -1052,10 +1052,11 @@ gboolean
mono_domain_owns_vtable_slot (MonoDomain *domain, gpointer vtable_slot)
{
gboolean res;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
- mono_domain_lock (domain);
- res = mono_mempool_contains_addr (domain->mp, vtable_slot);
- mono_domain_unlock (domain);
+ mono_mem_manager_lock (memory_manager);
+ res = mono_mempool_contains_addr (memory_manager->mp, vtable_slot);
+ mono_mem_manager_unlock (memory_manager);
return res;
}
@@ -3229,6 +3230,7 @@ unload_thread_main (void *arg)
{
unload_data *data = (unload_data*)arg;
MonoDomain *domain = data->domain;
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
int i;
gsize result = 1; // failure
@@ -3261,6 +3263,7 @@ unload_thread_main (void *arg)
mono_loader_lock ();
mono_domain_lock (domain);
+ mono_mem_manager_lock (memory_manager);
/*
* We need to make sure that we don't have any remsets
* pointing into static data of the to-be-freed domain because
@@ -3270,17 +3273,18 @@ unload_thread_main (void *arg)
* now be null we won't do any unnecessary copies and after
* the collection there won't be any more remsets.
*/
- for (i = 0; i < domain->class_vtable_array->len; ++i)
- zero_static_data ((MonoVTable *)g_ptr_array_index (domain->class_vtable_array, i));
+ for (i = 0; i < memory_manager->class_vtable_array->len; ++i)
+ zero_static_data ((MonoVTable *)g_ptr_array_index (memory_manager->class_vtable_array, i));
#if !HAVE_BOEHM_GC
mono_gc_collect (0);
#endif
- for (i = 0; i < domain->class_vtable_array->len; ++i)
- clear_cached_vtable ((MonoVTable *)g_ptr_array_index (domain->class_vtable_array, i));
+ for (i = 0; i < memory_manager->class_vtable_array->len; ++i)
+ clear_cached_vtable ((MonoVTable *)g_ptr_array_index (memory_manager->class_vtable_array, i));
deregister_reflection_info_roots (domain);
mono_assembly_cleanup_domain_bindings (domain->domain_id);
+ mono_mem_manager_unlock (memory_manager);
mono_domain_unlock (domain);
mono_loader_unlock ();
diff --git a/mono/metadata/assembly-load-context.c b/mono/metadata/assembly-load-context.c
index ec46fbc2b52..90b8d5e26e4 100644
--- a/mono/metadata/assembly-load-context.c
+++ b/mono/metadata/assembly-load-context.c
@@ -23,6 +23,9 @@ mono_alc_init (MonoAssemblyLoadContext *alc, MonoDomain *domain, gboolean collec
alc->domain = domain;
alc->loaded_images = li;
alc->loaded_assemblies = NULL;
+ alc->memory_manager = mono_mem_manager_create_singleton (alc, domain, collectible);
+ alc->generic_memory_managers = g_ptr_array_new ();
+ mono_coop_mutex_init (&alc->memory_managers_lock);
alc->unloading = FALSE;
alc->collectible = collectible;
alc->pinvoke_scopes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -151,6 +154,16 @@ mono_alc_cleanup (MonoAssemblyLoadContext *alc)
mono_alc_cleanup_assemblies (alc);
+ mono_mem_manager_free_singleton (alc->memory_manager, FALSE);
+ alc->memory_manager = NULL;
+
+ /*for (int i = 0; i < alc->generic_memory_managers->len; i++) {
+ MonoGenericMemoryManager *memory_manager = (MonoGenericMemoryManager *)alc->generic_memory_managers->pdata [i];
+ mono_mem_manager_free_generic (memory_manager, FALSE);
+ }*/
+ g_ptr_array_free (alc->generic_memory_managers, TRUE);
+ mono_coop_mutex_destroy (&alc->memory_managers_lock);
+
mono_gchandle_free_internal (alc->gchandle);
alc->gchandle = NULL;
@@ -180,6 +193,18 @@ mono_alc_assemblies_unlock (MonoAssemblyLoadContext *alc)
mono_coop_mutex_unlock (&alc->assemblies_lock);
}
+void
+mono_alc_memory_managers_lock (MonoAssemblyLoadContext *alc)
+{
+ mono_coop_mutex_lock (&alc->memory_managers_lock);
+}
+
+void
+mono_alc_memory_managers_unlock (MonoAssemblyLoadContext *alc)
+{
+ mono_coop_mutex_unlock (&alc->memory_managers_lock);
+}
+
gpointer
ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalInitializeNativeALC (gpointer this_gchandle_ptr, MonoBoolean is_default_alc, MonoBoolean collectible, MonoError *error)
{
diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c
index bc47b92d97f..973555e68e9 100644
--- a/mono/metadata/assembly.c
+++ b/mono/metadata/assembly.c
@@ -4339,6 +4339,7 @@ assembly_binding_info_parsed (MonoAssemblyBindingInfo *info, void *user_data)
GSList *tmp;
MonoAssemblyBindingInfo *info_tmp;
MonoDomain *domain = (MonoDomain*)user_data;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain); // linked with mono_domain_parse_assembly_bindings
if (!domain)
return;
@@ -4355,14 +4356,14 @@ assembly_binding_info_parsed (MonoAssemblyBindingInfo *info, void *user_data)
return;
}
- info_copy = (MonoAssemblyBindingInfo *)mono_mempool_alloc0 (domain->mp, sizeof (MonoAssemblyBindingInfo));
+ info_copy = (MonoAssemblyBindingInfo *)mono_mem_manager_alloc0_nolock (memory_manager, sizeof (MonoAssemblyBindingInfo));
memcpy (info_copy, info, sizeof (MonoAssemblyBindingInfo));
if (info->name)
- info_copy->name = mono_mempool_strdup (domain->mp, info->name);
+ info_copy->name = mono_mempool_strdup (memory_manager->mp, info->name);
if (info->culture)
- info_copy->culture = mono_mempool_strdup (domain->mp, info->culture);
+ info_copy->culture = mono_mempool_strdup (memory_manager->mp, info->culture);
- domain->assembly_bindings = g_slist_append_mempool (domain->mp, domain->assembly_bindings, info_copy);
+ domain->assembly_bindings = g_slist_append_mempool (memory_manager->mp, domain->assembly_bindings, info_copy);
}
static int
@@ -4425,7 +4426,11 @@ mono_domain_parse_assembly_bindings (MonoDomain *domain, int amajor, int aminor,
{
if (domain->assembly_bindings_parsed)
return;
+
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain); // linked with assembly_binding_info_parsed
+
mono_domain_lock (domain);
+ mono_mem_manager_lock (memory_manager);
if (!domain->assembly_bindings_parsed) {
gchar *domain_config_file_path = mono_portability_find_file (domain_config_file_name, TRUE);
@@ -4439,6 +4444,7 @@ mono_domain_parse_assembly_bindings (MonoDomain *domain, int amajor, int aminor,
g_free (domain_config_file_path);
}
+ mono_mem_manager_unlock (memory_manager);
mono_domain_unlock (domain);
}
diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h
index 1ba9e6cbc57..f31a9a73ead 100644
--- a/mono/metadata/domain-internals.h
+++ b/mono/metadata/domain-internals.h
@@ -339,8 +339,7 @@ struct _MonoDomain {
* must taken first.
*/
MonoCoopMutex lock;
- MonoMemPool *mp;
- MonoCodeManager *code_mp;
+
/*
* keep all the managed objects close to each other for the precise GC
* For the Boehm GC we additionally keep close also other GC-tracked pointers.
@@ -366,14 +365,7 @@ struct _MonoDomain {
#define MONO_DOMAIN_FIRST_GC_TRACKED env
MonoGHashTable *env;
MonoGHashTable *ldstr_table;
- /* hashtables for Reflection handles */
- MonoGHashTable *type_hash;
- MonoConcGHashTable *refobject_hash;
- /* maps class -> type initialization exception object */
- MonoGHashTable *type_init_exception_hash;
- /* maps delegate trampoline addr -> delegate object */
- MonoGHashTable *delegate_hash_table;
-#define MONO_DOMAIN_LAST_GC_TRACKED delegate_hash_table
+#define MONO_DOMAIN_LAST_GC_TRACKED ldstr_table
guint32 state;
/* Needed by Thread:GetDomainID() */
gint32 domain_id;
@@ -388,7 +380,6 @@ struct _MonoDomain {
GSList *domain_assemblies;
MonoAssembly *entry_assembly;
char *friendly_name;
- GPtrArray *class_vtable_array;
/* maps remote class key -> MonoRemoteClass */
GHashTable *proxy_vtable_hash;
/* Protected by 'jit_code_hash_lock' */
@@ -418,7 +409,7 @@ struct _MonoDomain {
* This must be a GHashTable, since these objects can't be finalized
* if the hashtable contains a GC visible reference to them.
*/
- GHashTable *finalizable_objects_hash;
+ GHashTable *finalizable_objects_hash; // TODO: this needs to be moved for unloadability with non-sgen gc
/* Protects the three hashes above */
mono_mutex_t finalizable_objects_hash_lock;
@@ -455,7 +446,7 @@ struct _MonoDomain {
/* Cache function pointers for architectures */
/* that require wrappers */
- GHashTable *ftnptrs_hash;
+ GHashTable *ftnptrs_hash; // TODO: need to move?
/* Maps MonoMethod* to weak links to DynamicMethod objects */
GHashTable *method_to_dyn_method;
@@ -470,6 +461,11 @@ struct _MonoDomain {
MonoAssemblyLoadContext *default_alc;
MonoCoopMutex alcs_lock; /* Used when accessing 'alcs' */
#endif
+
+#ifndef ENABLE_NETCORE
+ // Holds domain code memory
+ MonoMemoryManager *memory_manager;
+#endif
};
typedef struct {
@@ -565,6 +561,8 @@ mono_make_shadow_copy (const char *filename, MonoError *error);
gboolean
mono_is_shadow_copy_enabled (MonoDomain *domain, const gchar *dir_name);
+// TODO: remove these on netcore, we should always be explicit about allocating from ALCs
+//#ifndef ENABLE_NETCORE
gpointer
mono_domain_alloc (MonoDomain *domain, guint size);
@@ -575,11 +573,6 @@ mono_domain_alloc0 (MonoDomain *domain, guint size);
#define mono_domain_alloc0(domain, size) (g_cast (mono_domain_alloc0 ((domain), (size))))
-gpointer
-mono_domain_alloc0_lock_free (MonoDomain *domain, guint size);
-
-#define mono_domain_alloc0_lock_free(domain, size) (g_cast (mono_domain_alloc0_lock_free ((domain), (size))))
-
void*
mono_domain_code_reserve (MonoDomain *domain, int size);
@@ -595,6 +588,12 @@ mono_domain_code_commit (MonoDomain *domain, void *data, int size, int newsize);
void
mono_domain_code_foreach (MonoDomain *domain, MonoCodeManagerFunc func, void *user_data);
+//#endif
+
+gpointer
+mono_domain_alloc0_lock_free (MonoDomain *domain, guint size);
+
+#define mono_domain_alloc0_lock_free(domain, size) (g_cast (mono_domain_alloc0_lock_free ((domain), (size))))
void
mono_domain_unset (void);
@@ -664,8 +663,6 @@ void mono_domain_set_options_from_config (MonoDomain *domain);
int mono_framework_version (void);
-void mono_reflection_cleanup_domain (MonoDomain *domain);
-
void mono_assembly_cleanup_domain_bindings (guint32 domain_id);
MonoJitInfo* mono_jit_info_table_find_internal (MonoDomain *domain, gpointer addr, gboolean try_aot, gboolean allow_trampolines);
@@ -721,6 +718,23 @@ mono_domain_ambient_alc (MonoDomain *domain)
return mono_domain_default_alc (domain);
}
+static inline MonoMemoryManager *
+mono_domain_memory_manager (MonoDomain *domain)
+{
+#ifdef ENABLE_NETCORE
+ return (MonoMemoryManager *)mono_domain_default_alc (domain)->memory_manager;
+#else
+ return domain->memory_manager;
+#endif
+}
+
+static inline MonoMemoryManager *
+mono_domain_ambient_memory_manager (MonoDomain *domain)
+{
+ // FIXME: All callers of mono_domain_ambient_memory_manager should get a MemoryManager from their callers or context
+ return mono_domain_memory_manager (domain);
+}
+
G_END_DECLS
#endif /* __MONO_METADATA_DOMAIN_INTERNALS_H__ */
diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c
index f79975aca2c..7671bea8e62 100644
--- a/mono/metadata/domain.c
+++ b/mono/metadata/domain.c
@@ -432,14 +432,15 @@ mono_domain_create (void)
MONO_PROFILER_RAISE (domain_loading, (domain));
- domain->mp = mono_mempool_new ();
- domain->code_mp = mono_code_manager_new ();
+#ifndef ENABLE_NETCORE
+ domain->memory_manager = (MonoMemoryManager *)mono_mem_manager_create_singleton (NULL, domain, TRUE);
+#endif
+
domain->lock_free_mp = lock_free_mempool_new ();
domain->env = mono_g_hash_table_new_type_internal ((GHashFunc)mono_string_hash_internal, (GCompareFunc)mono_string_equal_internal, MONO_HASH_KEY_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Environment Variable Table");
domain->domain_assemblies = NULL;
domain->assembly_bindings = NULL;
domain->assembly_bindings_parsed = FALSE;
- domain->class_vtable_array = g_ptr_array_new ();
domain->proxy_vtable_hash = g_hash_table_new ((GHashFunc)mono_ptrarray_hash, (GCompareFunc)mono_ptrarray_equal);
mono_jit_code_hash_init (&domain->jit_code_hash);
domain->ldstr_table = mono_g_hash_table_new_type_internal ((GHashFunc)mono_string_hash_internal, (GCompareFunc)mono_string_equal_internal, MONO_HASH_KEY_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain String Pool Table");
@@ -1086,15 +1087,6 @@ mono_domain_assembly_open_internal (MonoDomain *domain, MonoAssemblyLoadContext
return ass;
}
-static void
-unregister_vtable_reflection_type (MonoVTable *vtable)
-{
- MonoObject *type = (MonoObject *)vtable->type;
-
- if (type->vtable->klass != mono_defaults.runtimetype_class)
- MONO_GC_UNREGISTER_ROOT_IF_MOVING (vtable->type);
-}
-
/**
* mono_domain_free:
* \param domain the domain to release
@@ -1146,23 +1138,7 @@ mono_domain_free (MonoDomain *domain, gboolean force)
mono_g_hash_table_destroy (domain->env);
domain->env = NULL;
- mono_reflection_cleanup_domain (domain);
-
- /* This must be done before type_hash is freed */
- if (domain->class_vtable_array) {
- int i;
- for (i = 0; i < domain->class_vtable_array->len; ++i)
- unregister_vtable_reflection_type ((MonoVTable *)g_ptr_array_index (domain->class_vtable_array, i));
- }
-
- if (domain->type_hash) {
- mono_g_hash_table_destroy (domain->type_hash);
- domain->type_hash = NULL;
- }
- if (domain->type_init_exception_hash) {
- mono_g_hash_table_destroy (domain->type_init_exception_hash);
- domain->type_init_exception_hash = NULL;
- }
+ mono_mem_manager_free_objects_singleton ((MonoSingletonMemoryManager *)domain->memory_manager);
for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
MonoAssembly *ass = (MonoAssembly *)tmp->data;
@@ -1230,8 +1206,6 @@ mono_domain_free (MonoDomain *domain, gboolean force)
g_free (domain->friendly_name);
domain->friendly_name = NULL;
- g_ptr_array_free (domain->class_vtable_array, TRUE);
- domain->class_vtable_array = NULL;
g_hash_table_destroy (domain->proxy_vtable_hash);
domain->proxy_vtable_hash = NULL;
mono_internal_hash_table_destroy (&domain->jit_code_hash);
@@ -1249,25 +1223,15 @@ mono_domain_free (MonoDomain *domain, gboolean force)
domain->jit_info_table = NULL;
g_assert (!domain->jit_info_free_queue);
- /* collect statistics */
- code_alloc = mono_code_manager_size (domain->code_mp, &code_size);
+ // Collect statistics
+ code_alloc = mono_code_manager_size (domain->memory_manager->code_mp, &code_size);
total_domain_code_alloc += code_alloc;
max_domain_code_alloc = MAX (max_domain_code_alloc, code_alloc);
max_domain_code_size = MAX (max_domain_code_size, code_size);
- if (debug_domain_unload) {
- mono_mempool_invalidate (domain->mp);
- mono_code_manager_invalidate (domain->code_mp);
- } else {
-#ifndef DISABLE_PERFCOUNTERS
- /* FIXME: use an explicit subtraction method as soon as it's available */
- mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, -1 * mono_mempool_get_allocated (domain->mp));
-#endif
- mono_mempool_destroy (domain->mp);
- domain->mp = NULL;
- mono_code_manager_destroy (domain->code_mp);
- domain->code_mp = NULL;
- }
+ mono_mem_manager_free_singleton ((MonoSingletonMemoryManager *)domain->memory_manager, debug_domain_unload);
+ domain->memory_manager = NULL;
+
lock_free_mempool_free (domain->lock_free_mp);
domain->lock_free_mp = NULL;
@@ -1367,41 +1331,27 @@ mono_domain_get_friendly_name (MonoDomain *domain)
/*
* mono_domain_alloc:
*
- * LOCKING: Acquires the domain lock.
+ * LOCKING: Acquires the default memory manager lock.
*/
gpointer
(mono_domain_alloc) (MonoDomain *domain, guint size)
{
- gpointer res;
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
- mono_domain_lock (domain);
-#ifndef DISABLE_PERFCOUNTERS
- mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
-#endif
- res = mono_mempool_alloc (domain->mp, size);
- mono_domain_unlock (domain);
-
- return res;
+ return mono_mem_manager_alloc (memory_manager, size);
}
/*
* mono_domain_alloc0:
*
- * LOCKING: Acquires the domain lock.
+ * LOCKING: Acquires the default memory manager lock.
*/
gpointer
(mono_domain_alloc0) (MonoDomain *domain, guint size)
{
- gpointer res;
-
- mono_domain_lock (domain);
-#ifndef DISABLE_PERFCOUNTERS
- mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
-#endif
- res = mono_mempool_alloc0 (domain->mp, size);
- mono_domain_unlock (domain);
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
- return res;
+ return mono_mem_manager_alloc0 (memory_manager, size);
}
gpointer
@@ -1413,48 +1363,40 @@ gpointer
/*
* mono_domain_code_reserve:
*
- * LOCKING: Acquires the domain lock.
+ * LOCKING: Acquires the default memory manager lock.
*/
void*
(mono_domain_code_reserve) (MonoDomain *domain, int size)
{
- gpointer res;
-
- mono_domain_lock (domain);
- res = mono_code_manager_reserve (domain->code_mp, size);
- mono_domain_unlock (domain);
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
- return res;
+ return mono_mem_manager_code_reserve (memory_manager, size);
}
/*
* mono_domain_code_reserve_align:
*
- * LOCKING: Acquires the domain lock.
+ * LOCKING: Acquires the default memory manager lock.
*/
void*
(mono_domain_code_reserve_align) (MonoDomain *domain, int size, int alignment)
{
- gpointer res;
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
- mono_domain_lock (domain);
- res = mono_code_manager_reserve_align (domain->code_mp, size, alignment);
- mono_domain_unlock (domain);
-
- return res;
+ return mono_mem_manager_code_reserve_align (memory_manager, size, alignment);
}
/*
* mono_domain_code_commit:
*
- * LOCKING: Acquires the domain lock.
+ * LOCKING: Acquires the default memory manager lock.
*/
void
mono_domain_code_commit (MonoDomain *domain, void *data, int size, int newsize)
{
- mono_domain_lock (domain);
- mono_code_manager_commit (domain->code_mp, data, size, newsize);
- mono_domain_unlock (domain);
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
+
+ mono_mem_manager_code_commit (memory_manager, data, size, newsize);
}
/*
@@ -1463,15 +1405,15 @@ mono_domain_code_commit (MonoDomain *domain, void *data, int size, int newsize)
*
* The @func callback MUST not take any locks. If it really needs to, it must respect
* the locking rules of the runtime: http://www.mono-project.com/Mono:Runtime:Documentation:ThreadSafety
- * LOCKING: Acquires the domain lock.
+ * LOCKING: Acquires the default memory manager lock.
*/
void
mono_domain_code_foreach (MonoDomain *domain, MonoCodeManagerFunc func, void *user_data)
{
- mono_domain_lock (domain);
- mono_code_manager_foreach (domain->code_mp, func, user_data);
- mono_domain_unlock (domain);
+ MonoMemoryManager *memory_manager = mono_domain_memory_manager (domain);
+
+ mono_mem_manager_code_foreach (memory_manager, func, user_data);
}
/**
diff --git a/mono/metadata/loader-internals.h b/mono/metadata/loader-internals.h
index f61cad569fa..9a5e5045930 100644
--- a/mono/metadata/loader-internals.h
+++ b/mono/metadata/loader-internals.h
@@ -8,10 +8,14 @@
#include <glib.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/image.h>
+#include <mono/metadata/mempool-internals.h>
+#include <mono/metadata/mono-conc-hash.h>
+#include <mono/metadata/mono-hash.h>
#include <mono/metadata/object-forward.h>
-#include <mono/utils/mono-forward.h>
-#include <mono/utils/mono-error.h>
+#include <mono/utils/mono-codeman.h>
#include <mono/utils/mono-coop-mutex.h>
+#include <mono/utils/mono-error.h>
+#include <mono/utils/mono-forward.h>
#ifdef ENABLE_NETCORE
#if defined(TARGET_OSX)
@@ -25,6 +29,11 @@
typedef struct _MonoLoadedImages MonoLoadedImages;
typedef struct _MonoAssemblyLoadContext MonoAssemblyLoadContext;
+typedef struct _MonoMemoryManager MonoMemoryManager;
+typedef struct _MonoSingletonMemoryManager MonoSingletonMemoryManager;
+#ifdef ENABLE_NETCORE
+typedef struct _MonoGenericMemoryManager MonoGenericMemoryManager;
+#endif
struct _MonoBundledSatelliteAssembly {
const char *name;
@@ -45,22 +54,23 @@ struct _MonoDllMap {
#endif
#ifdef ENABLE_NETCORE
-/* FIXME: this probably belongs somewhere else */
struct _MonoAssemblyLoadContext {
MonoDomain *domain;
MonoLoadedImages *loaded_images;
GSList *loaded_assemblies;
// If taking this with the domain assemblies_lock, always take this second
MonoCoopMutex assemblies_lock;
- /* Handle of the corresponding managed object. If the ALC is
- * collectible, the handle is weak, otherwise it's strong.
- */
+ // Holds ALC-specific memory
+ MonoSingletonMemoryManager *memory_manager;
+ GPtrArray *generic_memory_managers;
+ // Protects generic_memory_managers; if taking this with the domain alcs_lock, always take this second
+ MonoCoopMutex memory_managers_lock;
+ // Handle of the corresponding managed object. If the ALC is
+ // collectible, the handle is weak, otherwise it's strong.
MonoGCHandle gchandle;
// Whether the ALC can be unloaded; should only be set at creation
gboolean collectible;
- // Set to TRUE when the unloading process has begun, ensures nothing else will use that ALC
- // Maybe remove this? for now, should be helpful for debugging
- // Alternatively, check for it in the various ALC functions and error if it's true when calling them
+ // Set to TRUE when the unloading process has begun
gboolean unloading;
// Used in native-library.c for the hash table below; do not access anywhere else
MonoCoopMutex pinvoke_lock;
@@ -69,6 +79,52 @@ struct _MonoAssemblyLoadContext {
};
#endif /* ENABLE_NETCORE */
+struct _MonoMemoryManager {
+ MonoDomain *domain;
+ // Whether the MemoryManager can be unloaded on netcore; should only be set at creation
+ gboolean collectible;
+ // Whether this is a singleton or generic MemoryManager
+ gboolean is_generic;
+ // Whether the MemoryManager is in the process of being freed
+ gboolean freeing;
+
+ // If taking this with the loader lock, always take this second
+ // Currently unused, we take the domain lock instead
+ MonoCoopMutex lock;
+
+ MonoMemPool *mp;
+ MonoCodeManager *code_mp;
+
+ GPtrArray *class_vtable_array;
+
+ // !!! REGISTERED AS GC ROOTS !!!
+ // Hashtables for Reflection handles
+ MonoGHashTable *type_hash;
+ MonoConcGHashTable *refobject_hash;
+ // Maps class -> type initializaiton exception object
+ MonoGHashTable *type_init_exception_hash;
+ // Maps delegate trampoline addr -> delegate object
+ //MonoGHashTable *delegate_hash_table;
+ // End of GC roots
+};
+
+struct _MonoSingletonMemoryManager {
+ MonoMemoryManager memory_manager;
+
+ // Parent ALC, NULL on framework
+ MonoAssemblyLoadContext *alc;
+};
+
+#ifdef ENABLE_NETCORE
+struct _MonoGenericMemoryManager {
+ MonoMemoryManager memory_manager;
+
+ // Parent ALCs
+ int n_alcs;
+ MonoAssemblyLoadContext **alcs;
+};
+#endif
+
void
mono_global_loader_data_lock (void);
@@ -108,6 +164,12 @@ mono_alc_assemblies_lock (MonoAssemblyLoadContext *alc);
void
mono_alc_assemblies_unlock (MonoAssemblyLoadContext *alc);
+void
+mono_alc_memory_managers_lock (MonoAssemblyLoadContext *alc);
+
+void
+mono_alc_memory_managers_unlock (MonoAssemblyLoadContext *alc);
+
gboolean
mono_alc_is_default (MonoAssemblyLoadContext *alc);
@@ -140,4 +202,43 @@ mono_alc_get_loaded_images (MonoAssemblyLoadContext *alc);
MONO_API void
mono_loader_save_bundled_library (int fd, uint64_t offset, uint64_t size, const char *destfname);
+MonoSingletonMemoryManager *
+mono_mem_manager_create_singleton (MonoAssemblyLoadContext *alc, MonoDomain *domain, gboolean collectible);
+
+void
+mono_mem_manager_free_singleton (MonoSingletonMemoryManager *memory_manager, gboolean debug_unload);
+
+void
+mono_mem_manager_free_objects_singleton (MonoSingletonMemoryManager *memory_manager);
+
+void
+mono_mem_manager_lock (MonoMemoryManager *memory_manager);
+
+void
+mono_mem_manager_unlock (MonoMemoryManager *memory_manager);
+
+void *
+mono_mem_manager_alloc (MonoMemoryManager *memory_manager, guint size);
+
+void *
+mono_mem_manager_alloc_nolock (MonoMemoryManager *memory_manager, guint size);
+
+void *
+mono_mem_manager_alloc0 (MonoMemoryManager *memory_manager, guint size);
+
+void *
+mono_mem_manager_alloc0_nolock (MonoMemoryManager *memory_manager, guint size);
+
+void *
+mono_mem_manager_code_reserve (MonoMemoryManager *memory_manager, int size);
+
+void *
+mono_mem_manager_code_reserve_align (MonoMemoryManager *memory_manager, int size, int newsize);
+
+void
+mono_mem_manager_code_commit (MonoMemoryManager *memory_manager, void *data, int size, int newsize);
+
+void
+mono_mem_manager_code_foreach (MonoMemoryManager *memory_manager, MonoCodeManagerFunc func, void *user_data);
+
#endif
diff --git a/mono/metadata/memory-manager.c b/mono/metadata/memory-manager.c
new file mode 100644
index 00000000000..4d2b55d7141
--- /dev/null
+++ b/mono/metadata/memory-manager.c
@@ -0,0 +1,211 @@
+#include <mono/metadata/loader-internals.h>
+#include <mono/metadata/gc-internals.h>
+#include <mono/metadata/reflection-cache.h>
+#include <mono/metadata/mono-hash-internals.h>
+
+static void
+memory_manager_init (MonoMemoryManager *memory_manager, MonoDomain *domain, gboolean collectible)
+{
+ memory_manager->domain = domain;
+ memory_manager->freeing = FALSE;
+
+ mono_coop_mutex_init_recursive (&memory_manager->lock);
+
+ memory_manager->mp = mono_mempool_new ();
+ memory_manager->code_mp = mono_code_manager_new ();
+
+ memory_manager->class_vtable_array = g_ptr_array_new ();
+
+ // TODO: make these not linked to the domain for debugging
+ memory_manager->type_hash = mono_g_hash_table_new_type_internal ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Reflection Type Table");
+ memory_manager->refobject_hash = mono_conc_g_hash_table_new_type (mono_reflected_hash, mono_reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Reflection Object Table");
+ memory_manager->type_init_exception_hash = mono_g_hash_table_new_type_internal (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Type Initialization Exception Table");
+}
+
+MonoSingletonMemoryManager *
+mono_mem_manager_create_singleton (MonoAssemblyLoadContext *alc, MonoDomain *domain, gboolean collectible)
+{
+ MonoSingletonMemoryManager *mem_manager = g_new0 (MonoSingletonMemoryManager, 1);
+ memory_manager_init ((MonoMemoryManager *)mem_manager, domain, collectible);
+
+ mem_manager->memory_manager.is_generic = FALSE;
+ mem_manager->alc = alc;
+
+ return mem_manager;
+}
+
+static void
+cleanup_refobject_hash (gpointer key, gpointer value, gpointer user_data)
+{
+ free_reflected_entry ((ReflectedEntry *)key);
+}
+
+static void
+unregister_vtable_reflection_type (MonoVTable *vtable)
+{
+ MonoObject *type = (MonoObject *)vtable->type;
+
+ if (type->vtable->klass != mono_defaults.runtimetype_class)
+ MONO_GC_UNREGISTER_ROOT_IF_MOVING (vtable->type);
+}
+
+// First phase of deletion
+static void
+memory_manager_delete_objects (MonoMemoryManager *memory_manager)
+{
+ memory_manager->freeing = TRUE;
+
+ // Must be done before type_hash is freed
+ for (int i = 0; i < memory_manager->class_vtable_array->len; i++)
+ unregister_vtable_reflection_type ((MonoVTable *)g_ptr_array_index (memory_manager->class_vtable_array, i));
+
+ g_ptr_array_free (memory_manager->class_vtable_array, TRUE);
+ memory_manager->class_vtable_array = NULL;
+ mono_g_hash_table_destroy (memory_manager->type_hash);
+ memory_manager->type_hash = NULL;
+ mono_conc_g_hash_table_foreach (memory_manager->refobject_hash, cleanup_refobject_hash, NULL);
+ mono_conc_g_hash_table_destroy (memory_manager->refobject_hash);
+ memory_manager->refobject_hash = NULL;
+ mono_g_hash_table_destroy (memory_manager->type_init_exception_hash);
+ memory_manager->type_init_exception_hash = NULL;
+}
+
+// Full deletion
+static void
+memory_manager_delete (MonoMemoryManager *memory_manager, gboolean debug_unload)
+{
+ // Scan here to assert no lingering references in vtables?
+
+ if (!memory_manager->freeing)
+ memory_manager_delete_objects (memory_manager);
+
+ mono_coop_mutex_destroy (&memory_manager->lock);
+
+ if (debug_unload) {
+ mono_mempool_invalidate (memory_manager->mp);
+ mono_code_manager_invalidate (memory_manager->code_mp);
+ } else {
+#ifndef DISABLE_PERFCOUNTERS
+ /* FIXME: use an explicit subtraction method as soon as it's available */
+ mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, -1 * mono_mempool_get_allocated (memory_manager->mp));
+#endif
+ mono_mempool_destroy (memory_manager->mp);
+ memory_manager->mp = NULL;
+ mono_code_manager_destroy (memory_manager->code_mp);
+ memory_manager->code_mp = NULL;
+ }
+}
+
+void
+mono_mem_manager_free_objects_singleton (MonoSingletonMemoryManager *memory_manager)
+{
+ g_assert (!memory_manager->memory_manager.freeing);
+
+ memory_manager_delete_objects (&memory_manager->memory_manager);
+}
+
+void
+mono_mem_manager_free_singleton (MonoSingletonMemoryManager *memory_manager, gboolean debug_unload)
+{
+ g_assert (!memory_manager->memory_manager.is_generic);
+
+ memory_manager_delete (&memory_manager->memory_manager, debug_unload);
+ g_free (memory_manager);
+}
+
+void
+mono_mem_manager_lock (MonoMemoryManager *memory_manager)
+{
+ //mono_coop_mutex_lock (&memory_manager->lock);
+ mono_domain_lock (memory_manager->domain);
+}
+
+void
+mono_mem_manager_unlock (MonoMemoryManager *memory_manager)
+{
+ //mono_coop_mutex_unlock (&memory_manager->lock);
+ mono_domain_unlock (memory_manager->domain);
+}
+
+void *
+mono_mem_manager_alloc (MonoMemoryManager *memory_manager, guint size)
+{
+ void *res;
+
+ mono_mem_manager_lock (memory_manager);
+ res = mono_mem_manager_alloc_nolock (memory_manager, size);
+ mono_mem_manager_unlock (memory_manager);
+
+ return res;
+}
+
+void *
+mono_mem_manager_alloc_nolock (MonoMemoryManager *memory_manager, guint size)
+{
+#ifndef DISABLE_PERFCOUNTERS
+ mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
+#endif
+ return mono_mempool_alloc (memory_manager->mp, size);
+}
+
+void *
+mono_mem_manager_alloc0 (MonoMemoryManager *memory_manager, guint size)
+{
+ void *res;
+
+ mono_mem_manager_lock (memory_manager);
+ res = mono_mem_manager_alloc0_nolock (memory_manager, size);
+ mono_mem_manager_unlock (memory_manager);
+
+ return res;
+}
+
+void *
+mono_mem_manager_alloc0_nolock (MonoMemoryManager *memory_manager, guint size)
+{
+#ifndef DISABLE_PERFCOUNTERS
+ mono_atomic_fetch_add_i32 (&mono_perfcounters->loader_bytes, size);
+#endif
+ return mono_mempool_alloc0 (memory_manager->mp, size);
+}
+
+
+void *
+mono_mem_manager_code_reserve (MonoMemoryManager *memory_manager, int size)
+{
+ void *res;
+
+ mono_mem_manager_lock (memory_manager);
+ res = mono_code_manager_reserve (memory_manager->code_mp, size);
+ mono_mem_manager_unlock (memory_manager);
+
+ return res;
+}
+
+void *
+mono_mem_manager_code_reserve_align (MonoMemoryManager *memory_manager, int size, int alignment)
+{
+ void *res;
+
+ mono_mem_manager_lock (memory_manager);
+ res = mono_code_manager_reserve_align (memory_manager->code_mp, size, alignment);
+ mono_mem_manager_unlock (memory_manager);
+
+ return res;
+}
+
+void
+mono_mem_manager_code_commit (MonoMemoryManager *memory_manager, void *data, int size, int newsize)
+{
+ mono_mem_manager_lock (memory_manager);
+ mono_code_manager_commit (memory_manager->code_mp, data, size, newsize);
+ mono_mem_manager_unlock (memory_manager);
+}
+
+void
+mono_mem_manager_code_foreach (MonoMemoryManager *memory_manager, MonoCodeManagerFunc func, void *user_data)
+{
+ mono_mem_manager_lock (memory_manager);
+ mono_code_manager_foreach (memory_manager->code_mp, func, user_data);
+ mono_mem_manager_unlock (memory_manager);
+}
diff --git a/mono/metadata/object.c b/mono/metadata/object.c
index 4cf15fde2f2..fcc7c5886e4 100644
--- a/mono/metadata/object.c
+++ b/mono/metadata/object.c
@@ -331,6 +331,7 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
ERROR_DECL (error);
MonoDomain *domain = vtable->domain;
MonoClass *klass = vtable->klass;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
MonoException *ex;
gchar *full_name;
@@ -342,10 +343,9 @@ get_type_init_exception_for_vtable (MonoVTable *vtable)
* in the hash.
*/
ex = NULL;
- mono_domain_lock (domain);
- if (domain->type_init_exception_hash)
- ex = (MonoException *)mono_g_hash_table_lookup (domain->type_init_exception_hash, klass);
- mono_domain_unlock (domain);
+ mono_mem_manager_lock (memory_manager);
+ ex = (MonoException *)mono_g_hash_table_lookup (memory_manager->type_init_exception_hash, klass);
+ mono_mem_manager_unlock (memory_manager);
if (!ex) {
const char *klass_name_space = m_class_get_name_space (klass);
@@ -446,6 +446,7 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
return TRUE;
MonoClass *klass = vtable->klass;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
MonoImage *klass_image = m_class_get_image (klass);
if (!mono_runtime_run_module_cctor(klass_image, vtable->domain, error)) {
@@ -593,11 +594,9 @@ mono_runtime_class_init_full (MonoVTable *vtable, MonoError *error)
* Store the exception object so it could be thrown on subsequent
* accesses.
*/
- mono_domain_lock (domain);
- if (!domain->type_init_exception_hash)
- domain->type_init_exception_hash = mono_g_hash_table_new_type_internal (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Type Initialization Exception Table");
- mono_g_hash_table_insert_internal (domain->type_init_exception_hash, klass, exc_to_throw);
- mono_domain_unlock (domain);
+ mono_mem_manager_lock (memory_manager);
+ mono_g_hash_table_insert_internal (memory_manager->type_init_exception_hash, klass, exc_to_throw);
+ mono_mem_manager_unlock (memory_manager);
}
if (last_domain)
@@ -1997,6 +1996,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
MonoVTable *vt;
MonoClassRuntimeInfo *runtime_info;
MonoClassField *field;
+ MonoMemoryManager *memory_manager;
char *t;
int i, vtable_slots;
size_t imt_table_bytes;
@@ -2283,7 +2283,10 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *klass, MonoErro
/* class_vtable_array keeps an array of created vtables
*/
- g_ptr_array_add (domain->class_vtable_array, vt);
+ memory_manager = mono_domain_ambient_memory_manager (domain);
+ mono_mem_manager_lock (memory_manager);
+ g_ptr_array_add (memory_manager->class_vtable_array, vt);
+ mono_mem_manager_unlock (memory_manager);
/* klass->runtime_info is protected by the loader lock, both when
* it it enlarged and when it is stored info.
*/
@@ -2705,6 +2708,7 @@ mono_remote_class (MonoDomain *domain, MonoStringHandle class_name, MonoClass *p
MonoRemoteClass *rc;
gpointer* key, *mp_key;
char *name;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
error_init (error);
@@ -2719,7 +2723,9 @@ mono_remote_class (MonoDomain *domain, MonoStringHandle class_name, MonoClass *p
return rc;
}
- name = mono_string_to_utf8_mp (domain->mp, MONO_HANDLE_RAW (class_name), error);
+ mono_mem_manager_lock (memory_manager);
+ name = mono_string_to_utf8_mp (memory_manager->mp, MONO_HANDLE_RAW (class_name), error);
+ mono_mem_manager_unlock (memory_manager);
if (!is_ok (error)) {
g_free (key);
mono_domain_unlock (domain);
diff --git a/mono/metadata/reflection-cache.h b/mono/metadata/reflection-cache.h
index 6a792961c98..02e5bd37bf7 100644
--- a/mono/metadata/reflection-cache.h
+++ b/mono/metadata/reflection-cache.h
@@ -35,8 +35,8 @@ alloc_reflected_entry (MonoDomain *domain)
{
if (!mono_gc_is_moving ())
return g_new0 (ReflectedEntry, 1);
- else
- return (ReflectedEntry *)mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry));
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
+ return (ReflectedEntry *)mono_mem_manager_alloc_nolock (memory_manager, sizeof (ReflectedEntry));
}
static inline void
@@ -50,23 +50,21 @@ static inline MonoObject*
cache_object (MonoDomain *domain, MonoClass *klass, gpointer item, MonoObject* o)
{
MonoObject *obj;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
ReflectedEntry pe;
pe.item = item;
pe.refclass = klass;
- mono_domain_lock (domain);
- if (!domain->refobject_hash)
- domain->refobject_hash = mono_conc_g_hash_table_new_type (mono_reflected_hash, mono_reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Reflection Object Table");
-
- obj = (MonoObject*) mono_conc_g_hash_table_lookup (domain->refobject_hash, &pe);
+ mono_mem_manager_lock (memory_manager);
+ obj = (MonoObject *)mono_conc_g_hash_table_lookup (memory_manager->refobject_hash, &pe);
if (obj == NULL) {
ReflectedEntry *e = alloc_reflected_entry (domain);
e->item = item;
e->refclass = klass;
- mono_conc_g_hash_table_insert (domain->refobject_hash, e, o);
+ mono_conc_g_hash_table_insert (memory_manager->refobject_hash, e, o);
obj = o;
}
- mono_domain_unlock (domain);
+ mono_mem_manager_unlock (memory_manager);
return obj;
}
@@ -74,23 +72,21 @@ cache_object (MonoDomain *domain, MonoClass *klass, gpointer item, MonoObject* o
static inline MonoObjectHandle
cache_object_handle (MonoDomain *domain, MonoClass *klass, gpointer item, MonoObjectHandle o)
{
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
ReflectedEntry pe;
pe.item = item;
pe.refclass = klass;
- mono_domain_lock (domain);
- if (!domain->refobject_hash)
- domain->refobject_hash = mono_conc_g_hash_table_new_type (mono_reflected_hash, mono_reflected_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Reflection Object Table");
-
- MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, (MonoObject*)mono_conc_g_hash_table_lookup (domain->refobject_hash, &pe));
+ mono_mem_manager_lock (memory_manager);
+ MonoObjectHandle obj = MONO_HANDLE_NEW (MonoObject, (MonoObject *)mono_conc_g_hash_table_lookup (memory_manager->refobject_hash, &pe));
if (MONO_HANDLE_IS_NULL (obj)) {
ReflectedEntry *e = alloc_reflected_entry (domain);
e->item = item;
e->refclass = klass;
- mono_conc_g_hash_table_insert (domain->refobject_hash, e, MONO_HANDLE_RAW (o));
+ mono_conc_g_hash_table_insert (memory_manager->refobject_hash, e, MONO_HANDLE_RAW (o));
MONO_HANDLE_ASSIGN (obj, o);
}
- mono_domain_unlock (domain);
+ mono_mem_manager_unlock (memory_manager);
return obj;
}
@@ -100,14 +96,18 @@ cache_object_handle (MonoDomain *domain, MonoClass *klass, gpointer item, MonoOb
static inline MonoObjectHandle
check_object_handle (MonoDomain* domain, MonoClass *klass, gpointer item)
{
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
+ MonoObjectHandle obj_handle;
ReflectedEntry e;
e.item = item;
e.refclass = klass;
- MonoConcGHashTable *hash = domain->refobject_hash;
- if (!hash)
- return MONO_HANDLE_NEW (MonoObject, NULL);
- return MONO_HANDLE_NEW (MonoObject, (MonoObject*)mono_conc_g_hash_table_lookup (hash, &e));
+ mono_mem_manager_lock (memory_manager);
+ MonoConcGHashTable *hash = memory_manager->refobject_hash;
+ obj_handle = MONO_HANDLE_NEW (MonoObject, (MonoObject *)mono_conc_g_hash_table_lookup (hash, &e));
+ mono_mem_manager_unlock (memory_manager);
+
+ return obj_handle;
}
diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c
index 49c907829eb..d6097f37572 100644
--- a/mono/metadata/reflection.c
+++ b/mono/metadata/reflection.c
@@ -184,36 +184,22 @@ mono_reflected_hash (gconstpointer a) {
static void
clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
{
- mono_domain_lock (domain);
- if (domain->refobject_hash) {
- ReflectedEntry pe;
- gpointer orig_pe, orig_value;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
- pe.item = o;
- pe.refclass = klass;
+ mono_mem_manager_lock (memory_manager);
- if (mono_conc_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
- mono_conc_g_hash_table_remove (domain->refobject_hash, &pe);
- free_reflected_entry ((ReflectedEntry*)orig_pe);
- }
- }
- mono_domain_unlock (domain);
-}
+ gpointer orig_pe, orig_value;
+ ReflectedEntry pe;
+ pe.item = o;
+ pe.refclass = klass;
-static void
-cleanup_refobject_hash (gpointer key, gpointer value, gpointer user_data)
-{
- free_reflected_entry ((ReflectedEntry*)key);
-}
-void
-mono_reflection_cleanup_domain (MonoDomain *domain)
-{
- if (domain->refobject_hash) {
- mono_conc_g_hash_table_foreach (domain->refobject_hash, cleanup_refobject_hash, NULL);
- mono_conc_g_hash_table_destroy (domain->refobject_hash);
- domain->refobject_hash = NULL;
+ if (mono_conc_g_hash_table_lookup_extended (memory_manager->refobject_hash, &pe, &orig_pe, &orig_value)) {
+ mono_conc_g_hash_table_remove (memory_manager->refobject_hash, &pe);
+ free_reflected_entry ((ReflectedEntry *)orig_pe);
}
+
+ mono_mem_manager_unlock (memory_manager);
}
/**
@@ -459,6 +445,7 @@ mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *err
g_assert (type != NULL);
klass = mono_class_from_mono_type_internal (type);
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
/*we must avoid using @type as it might have come
* from a mono_metadata_type_dup and the caller
@@ -500,15 +487,9 @@ mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *err
}
mono_loader_lock (); /*FIXME mono_class_init_internal and mono_class_vtable acquire it*/
- mono_domain_lock (domain);
- if (!domain->type_hash)
- domain->type_hash = mono_g_hash_table_new_type_internal ((GHashFunc)mono_metadata_type_hash,
- (GCompareFunc)mono_metadata_type_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DOMAIN, domain, "Domain Reflection Type Table");
- if ((res = (MonoReflectionType *)mono_g_hash_table_lookup (domain->type_hash, type))) {
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return res;
- }
+ mono_mem_manager_lock (memory_manager);
+ if ((res = (MonoReflectionType *)mono_g_hash_table_lookup (memory_manager->type_hash, type)))
+ goto leave;
/*Types must be normalized so a generic instance of the GTD get's the same inner type.
* For example in: Foo<A,B>; Bar<A> : Foo<A, Bar<A>>
@@ -520,15 +501,10 @@ mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *err
norm_type = mono_type_normalize (type);
if (norm_type != type) {
res = mono_type_get_object_checked (domain, norm_type, error);
- if (!is_ok (error)) {
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return NULL;
- }
- mono_g_hash_table_insert_internal (domain->type_hash, type, res);
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return res;
+ goto_if_nok (error, leave);
+
+ mono_g_hash_table_insert_internal (memory_manager->type_hash, type, res);
+ goto leave;
}
if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !m_class_was_typebuilder (type->data.generic_class->container_class)) {
@@ -549,31 +525,26 @@ mono_type_get_object_checked (MonoDomain *domain, MonoType *type, MonoError *err
/* I would have expected ReflectionTypeLoadException, but evidently .NET throws TLE in this case. */
mono_error_set_type_load_class (error, klass, "TypeBuilder.CreateType() not called for generic class %s", full_name);
g_free (full_name);
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return NULL;
+ res = NULL;
+ goto leave;
}
if (mono_class_has_ref_info (klass) && !m_class_was_typebuilder (klass) && !type->byref) {
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return &mono_class_get_ref_info_raw (klass)->type; /* FIXME use handles */
+ res = &mono_class_get_ref_info_raw (klass)->type; /* FIXME use handles */
+ goto leave;
}
/* This is stored in vtables/JITted code so it has to be pinned */
res = (MonoReflectionType *)mono_object_new_pinned (domain, mono_defaults.runtimetype_class, error);
- if (!is_ok (error)) {
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return NULL;
- }
+ goto_if_nok (error, leave);
res->type = type;
- mono_g_hash_table_insert_internal (domain->type_hash, type, res);
+ mono_g_hash_table_insert_internal (memory_manager->type_hash, type, res);
if (type->type == MONO_TYPE_VOID && !type->byref)
domain->typeof_void = (MonoObject*)res;
- mono_domain_unlock (domain);
+leave:
+ mono_mem_manager_unlock (memory_manager);
mono_loader_unlock ();
return res;
}
diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c
index d2ee825173f..ad482f98330 100644
--- a/mono/metadata/sre.c
+++ b/mono/metadata/sre.c
@@ -4086,12 +4086,15 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilderHandle ref_
*
* Together with this we must ensure the contents of all instances to match the created type.
*/
- if (domain->type_hash && mono_class_is_gtd (klass)) {
+ if (mono_class_is_gtd (klass)) {
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (domain);
struct remove_instantiations_user_data data;
data.klass = klass;
data.error = error;
mono_error_assert_ok (error);
- mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of_and_ensure_contents, &data);
+ mono_mem_manager_lock (memory_manager);
+ mono_g_hash_table_foreach_remove (memory_manager->type_hash, remove_instantiations_of_and_ensure_contents, &data);
+ mono_mem_manager_unlock (memory_manager);
goto_if_nok (error, failure);
}
diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c
index 195156b0f6c..555ea5af0f1 100644
--- a/mono/mini/interp/interp.c
+++ b/mono/mini/interp/interp.c
@@ -671,17 +671,17 @@ typedef struct {
InterpMethod *target_imethod;
} InterpVTableEntry;
-/* domain lock must be held */
+/* memory manager lock must be held */
static GSList*
-append_imethod (MonoDomain *domain, GSList *list, InterpMethod *imethod, InterpMethod *target_imethod)
+append_imethod (MonoMemoryManager *memory_manager, GSList *list, InterpMethod *imethod, InterpMethod *target_imethod)
{
GSList *ret;
InterpVTableEntry *entry;
- entry = (InterpVTableEntry*) mono_mempool_alloc (domain->mp, sizeof (InterpVTableEntry));
+ entry = (InterpVTableEntry*) mono_mem_manager_alloc_nolock (memory_manager, sizeof (InterpVTableEntry));
entry->imethod = imethod;
entry->target_imethod = target_imethod;
- ret = g_slist_append_mempool (domain->mp, list, entry);
+ ret = g_slist_append_mempool (memory_manager->mp, list, entry);
return ret;
}
@@ -726,6 +726,7 @@ static InterpMethod* // Inlining causes additional stack use in caller.
get_virtual_method_fast (InterpMethod *imethod, MonoVTable *vtable, int offset)
{
gpointer *table;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (vtable->domain);
#ifndef DISABLE_REMOTING
/* FIXME Remoting */
@@ -747,14 +748,14 @@ get_virtual_method_fast (InterpMethod *imethod, MonoVTable *vtable, int offset)
if (!table [offset]) {
InterpMethod *target_imethod = get_virtual_method (imethod, vtable);
/* Lazily initialize the method table slot */
- mono_domain_lock (vtable->domain);
+ mono_mem_manager_lock (memory_manager);
if (!table [offset]) {
if (imethod->method->is_inflated || offset < 0)
- table [offset] = append_imethod (vtable->domain, NULL, imethod, target_imethod);
+ table [offset] = append_imethod (memory_manager, NULL, imethod, target_imethod);
else
table [offset] = (gpointer) ((gsize)target_imethod | 0x1);
}
- mono_domain_unlock (vtable->domain);
+ mono_mem_manager_unlock (memory_manager);
}
if ((gsize)table [offset] & 0x1) {
@@ -766,10 +767,10 @@ get_virtual_method_fast (InterpMethod *imethod, MonoVTable *vtable, int offset)
if (!target_imethod) {
target_imethod = get_virtual_method (imethod, vtable);
- mono_domain_lock (vtable->domain);
+ mono_mem_manager_lock (memory_manager);
if (!get_target_imethod ((GSList*)table [offset], imethod))
- table [offset] = append_imethod (vtable->domain, (GSList*)table [offset], imethod, target_imethod);
- mono_domain_unlock (vtable->domain);
+ table [offset] = append_imethod (memory_manager, (GSList*)table [offset], imethod, target_imethod);
+ mono_mem_manager_unlock (memory_manager);
}
return target_imethod;
}
diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c
index c25771f3031..f699f3d4c40 100644
--- a/mono/mini/interp/transform.c
+++ b/mono/mini/interp/transform.c
@@ -1046,8 +1046,9 @@ static void
interp_generate_ipe_throw_with_msg (TransformData *td, MonoError *error_msg)
{
MonoJitICallInfo *info = &mono_get_jit_icall_info ()->mono_throw_invalid_program;
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (td->rtm->domain);
- char *msg = mono_mempool_strdup (td->rtm->domain->mp, mono_error_get_message (error_msg));
+ char *msg = mono_mempool_strdup (memory_manager->mp, mono_error_get_message (error_msg));
interp_add_ins (td, MINT_MONO_LDPTR);
td->last_ins->data [0] = get_data_item_index (td, msg);
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 3f03487e6b2..f3c0a844b1a 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -2317,7 +2317,10 @@ static void
emit_invalid_program_with_msg (MonoCompile *cfg, MonoError *error_msg, MonoMethod *caller, MonoMethod *callee)
{
g_assert (!is_ok (error_msg));
- char *str = mono_mempool_strdup (cfg->domain->mp, mono_error_get_message (error_msg));
+ MonoMemoryManager *memory_manager = mono_domain_ambient_memory_manager (cfg->domain);
+ mono_mem_manager_lock (memory_manager);
+ char *str = mono_mempool_strdup (memory_manager->mp, mono_error_get_message (error_msg));
+ mono_mem_manager_unlock (memory_manager);
MonoInst *iargs[1];
if (cfg->compile_aot)
EMIT_NEW_LDSTRLITCONST (cfg, iargs [0], str);
diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c
index 24f54029812..57f0da61742 100644
--- a/mono/mini/mini-runtime.c
+++ b/mono/mini/mini-runtime.c
@@ -4583,7 +4583,7 @@ mini_init (const char *filename, const char *runtime_version)
if (mono_aot_only) {
/* This helps catch code allocation requests */
- mono_code_manager_set_read_only (domain->code_mp);
+ mono_code_manager_set_read_only (mono_domain_ambient_memory_manager (domain)->code_mp);
mono_marshal_use_aot_wrappers (TRUE);
}
diff --git a/mono/mini/monovm.h b/mono/mini/monovm.h
index 7cb16e0ce88..09fc3d3850f 100644
--- a/mono/mini/monovm.h
+++ b/mono/mini/monovm.h
@@ -17,4 +17,4 @@ monovm_execute_assembly (int argc, const char **argv, const char *managedAssembl
MONO_API int
monovm_shutdown (int *latchedExitCode);
-#endif // _MONO_MINI_MONOVM_H_ \ No newline at end of file
+#endif // _MONO_MINI_MONOVM_H_
diff --git a/msvc/libmonoruntime-common.targets b/msvc/libmonoruntime-common.targets
index 9debec84a0e..6006f787009 100644
--- a/msvc/libmonoruntime-common.targets
+++ b/msvc/libmonoruntime-common.targets
@@ -73,6 +73,7 @@
<ClCompile Include="$(MonoSourceLocation)\mono\metadata\marshal-ilgen.c" />
<ClInclude Include="$(MonoSourceLocation)\mono\metadata\marshal-ilgen.h" />
<ClInclude Include="$(MonoSourceLocation)\mono\metadata\marshal-internals.h" />
+ <ClCompile Include="$(MonoSourceLocation)\mono\metadata\memory-manager.c" />
<ClCompile Include="$(MonoSourceLocation)\mono\metadata\mempool.c" />
<ClInclude Include="$(MonoSourceLocation)\mono\metadata\mempool.h" />
<ClInclude Include="$(MonoSourceLocation)\mono\metadata\mempool-internals.h" />
diff --git a/msvc/libmonoruntime-common.targets.filters b/msvc/libmonoruntime-common.targets.filters
index b25559f1fb1..26ae534a071 100644
--- a/msvc/libmonoruntime-common.targets.filters
+++ b/msvc/libmonoruntime-common.targets.filters
@@ -558,7 +558,10 @@
</ClCompile>
<ClInclude Include="$(MonoSourceLocation)\mono\metadata\native-library.h">
<Filter>Header Files$(MonoRuntimeFilterSubFolder)\common</Filter>
- </ClInclude>
+ </ClInclude>
+ <ClCompile Include="$MonoSourceLocation)\mono\metadata\memory-manager.c">
+ <Filter>Source Files$MonoRuntimeFilterSubfolder\common</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup Label="config_sources">
<ClInclude Include="$(MonoSourceLocation)\mono\metadata\mono-config-dirs.h">