1 #include <mono/metadata/loader-internals.h>
2 #include <mono/metadata/gc-internals.h>
3 #include <mono/metadata/reflection-cache.h>
4 #include <mono/metadata/mono-hash-internals.h>
7 memory_manager_init (MonoMemoryManager
*memory_manager
, MonoDomain
*domain
, gboolean collectible
)
9 memory_manager
->domain
= domain
;
10 memory_manager
->freeing
= FALSE
;
12 mono_coop_mutex_init_recursive (&memory_manager
->lock
);
14 memory_manager
->mp
= mono_mempool_new ();
15 memory_manager
->code_mp
= mono_code_manager_new ();
17 memory_manager
->class_vtable_array
= g_ptr_array_new ();
19 // TODO: make these not linked to the domain for debugging
20 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");
21 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");
22 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");
25 MonoSingletonMemoryManager
*
26 mono_mem_manager_create_singleton (MonoAssemblyLoadContext
*alc
, MonoDomain
*domain
, gboolean collectible
)
28 MonoSingletonMemoryManager
*mem_manager
= g_new0 (MonoSingletonMemoryManager
, 1);
29 memory_manager_init ((MonoMemoryManager
*)mem_manager
, domain
, collectible
);
31 mem_manager
->memory_manager
.is_generic
= FALSE
;
32 mem_manager
->alc
= alc
;
38 cleanup_refobject_hash (gpointer key
, gpointer value
, gpointer user_data
)
40 free_reflected_entry ((ReflectedEntry
*)key
);
44 unregister_vtable_reflection_type (MonoVTable
*vtable
)
46 MonoObject
*type
= (MonoObject
*)vtable
->type
;
48 if (type
->vtable
->klass
!= mono_defaults
.runtimetype_class
)
49 MONO_GC_UNREGISTER_ROOT_IF_MOVING (vtable
->type
);
52 // First phase of deletion
54 memory_manager_delete_objects (MonoMemoryManager
*memory_manager
)
56 memory_manager
->freeing
= TRUE
;
58 // Must be done before type_hash is freed
59 for (int i
= 0; i
< memory_manager
->class_vtable_array
->len
; i
++)
60 unregister_vtable_reflection_type ((MonoVTable
*)g_ptr_array_index (memory_manager
->class_vtable_array
, i
));
62 g_ptr_array_free (memory_manager
->class_vtable_array
, TRUE
);
63 memory_manager
->class_vtable_array
= NULL
;
64 mono_g_hash_table_destroy (memory_manager
->type_hash
);
65 memory_manager
->type_hash
= NULL
;
66 mono_conc_g_hash_table_foreach (memory_manager
->refobject_hash
, cleanup_refobject_hash
, NULL
);
67 mono_conc_g_hash_table_destroy (memory_manager
->refobject_hash
);
68 memory_manager
->refobject_hash
= NULL
;
69 mono_g_hash_table_destroy (memory_manager
->type_init_exception_hash
);
70 memory_manager
->type_init_exception_hash
= NULL
;
75 memory_manager_delete (MonoMemoryManager
*memory_manager
, gboolean debug_unload
)
77 // Scan here to assert no lingering references in vtables?
79 if (!memory_manager
->freeing
)
80 memory_manager_delete_objects (memory_manager
);
82 mono_coop_mutex_destroy (&memory_manager
->lock
);
85 mono_mempool_invalidate (memory_manager
->mp
);
86 mono_code_manager_invalidate (memory_manager
->code_mp
);
88 #ifndef DISABLE_PERFCOUNTERS
89 /* FIXME: use an explicit subtraction method as soon as it's available */
90 mono_atomic_fetch_add_i32 (&mono_perfcounters
->loader_bytes
, -1 * mono_mempool_get_allocated (memory_manager
->mp
));
92 mono_mempool_destroy (memory_manager
->mp
);
93 memory_manager
->mp
= NULL
;
94 mono_code_manager_destroy (memory_manager
->code_mp
);
95 memory_manager
->code_mp
= NULL
;
100 mono_mem_manager_free_objects_singleton (MonoSingletonMemoryManager
*memory_manager
)
102 g_assert (!memory_manager
->memory_manager
.freeing
);
104 memory_manager_delete_objects (&memory_manager
->memory_manager
);
108 mono_mem_manager_free_singleton (MonoSingletonMemoryManager
*memory_manager
, gboolean debug_unload
)
110 g_assert (!memory_manager
->memory_manager
.is_generic
);
112 memory_manager_delete (&memory_manager
->memory_manager
, debug_unload
);
113 g_free (memory_manager
);
117 mono_mem_manager_lock (MonoMemoryManager
*memory_manager
)
119 //mono_coop_mutex_lock (&memory_manager->lock);
120 mono_domain_lock (memory_manager
->domain
);
124 mono_mem_manager_unlock (MonoMemoryManager
*memory_manager
)
126 //mono_coop_mutex_unlock (&memory_manager->lock);
127 mono_domain_unlock (memory_manager
->domain
);
131 mono_mem_manager_alloc (MonoMemoryManager
*memory_manager
, guint size
)
135 mono_mem_manager_lock (memory_manager
);
136 res
= mono_mem_manager_alloc_nolock (memory_manager
, size
);
137 mono_mem_manager_unlock (memory_manager
);
143 mono_mem_manager_alloc_nolock (MonoMemoryManager
*memory_manager
, guint size
)
145 #ifndef DISABLE_PERFCOUNTERS
146 mono_atomic_fetch_add_i32 (&mono_perfcounters
->loader_bytes
, size
);
148 return mono_mempool_alloc (memory_manager
->mp
, size
);
152 mono_mem_manager_alloc0 (MonoMemoryManager
*memory_manager
, guint size
)
156 mono_mem_manager_lock (memory_manager
);
157 res
= mono_mem_manager_alloc0_nolock (memory_manager
, size
);
158 mono_mem_manager_unlock (memory_manager
);
164 mono_mem_manager_alloc0_nolock (MonoMemoryManager
*memory_manager
, guint size
)
166 #ifndef DISABLE_PERFCOUNTERS
167 mono_atomic_fetch_add_i32 (&mono_perfcounters
->loader_bytes
, size
);
169 return mono_mempool_alloc0 (memory_manager
->mp
, size
);
173 mono_mem_manager_strdup (MonoMemoryManager
*memory_manager
, const char *s
)
177 mono_mem_manager_lock (memory_manager
);
178 res
= mono_mempool_strdup (memory_manager
->mp
, s
);
179 mono_mem_manager_unlock (memory_manager
);
185 (mono_mem_manager_code_reserve
) (MonoMemoryManager
*memory_manager
, int size
)
189 mono_mem_manager_lock (memory_manager
);
190 res
= mono_code_manager_reserve (memory_manager
->code_mp
, size
);
191 mono_mem_manager_unlock (memory_manager
);
197 mono_mem_manager_code_reserve_align (MonoMemoryManager
*memory_manager
, int size
, int alignment
)
201 mono_mem_manager_lock (memory_manager
);
202 res
= mono_code_manager_reserve_align (memory_manager
->code_mp
, size
, alignment
);
203 mono_mem_manager_unlock (memory_manager
);
209 mono_mem_manager_code_commit (MonoMemoryManager
*memory_manager
, void *data
, int size
, int newsize
)
211 mono_mem_manager_lock (memory_manager
);
212 mono_code_manager_commit (memory_manager
->code_mp
, data
, size
, newsize
);
213 mono_mem_manager_unlock (memory_manager
);
217 * mono_mem_manager_code_foreach:
218 * Iterate over the code thunks of the code manager of @memory_manager.
220 * The @func callback MUST not take any locks. If it really needs to, it must respect
221 * the locking rules of the runtime: http://www.mono-project.com/Mono:Runtime:Documentation:ThreadSafety
222 * LOCKING: Acquires the memory manager lock.
225 mono_mem_manager_code_foreach (MonoMemoryManager
*memory_manager
, MonoCodeManagerFunc func
, void *user_data
)
227 mono_mem_manager_lock (memory_manager
);
228 mono_code_manager_foreach (memory_manager
->code_mp
, func
, user_data
);
229 mono_mem_manager_unlock (memory_manager
);