static gboolean debug_assembly_unload = FALSE;
-#define mono_images_lock() if (mutex_inited) EnterCriticalSection (&images_mutex)
-#define mono_images_unlock() if (mutex_inited) LeaveCriticalSection (&images_mutex)
+#define mono_images_lock() if (mutex_inited) mono_mutex_lock (&images_mutex)
+#define mono_images_unlock() if (mutex_inited) mono_mutex_unlock (&images_mutex)
static gboolean mutex_inited;
-static CRITICAL_SECTION images_mutex;
+static mono_mutex_t images_mutex;
typedef struct ImageUnloadHook ImageUnloadHook;
struct ImageUnloadHook {
gpointer user_data;
};
-GSList *image_unload_hooks;
+static GSList *image_unload_hooks;
void
mono_install_image_unload_hook (MonoImageUnloadFunc func, gpointer user_data)
const int top = iinfo->cli_section_count;
MonoSectionTable *tables = iinfo->cli_section_tables;
int i;
-
+
+ if (image->metadata_only)
+ return addr;
+
for (i = 0; i < top; i++){
if ((addr >= tables->st_virtual_address) &&
(addr < tables->st_virtual_address + tables->st_raw_data_size)){
void
mono_images_init (void)
{
- InitializeCriticalSection (&images_mutex);
+ mono_mutex_init_recursive (&images_mutex);
loaded_images_hash = g_hash_table_new (g_str_hash, g_str_equal);
loaded_images_refonly_hash = g_hash_table_new (g_str_hash, g_str_equal);
GHashTableIter iter;
MonoImage *image;
- DeleteCriticalSection (&images_mutex);
+ mono_mutex_destroy (&images_mutex);
g_hash_table_iter_init (&iter, loaded_images_hash);
while (g_hash_table_iter_next (&iter, NULL, (void**)&image))
{
MonoCLIImageInfo *iinfo = image->image_info;
MonoSectionTable *sect;
- gboolean writable;
g_return_val_if_fail (section < iinfo->cli_section_count, FALSE);
sect = &iinfo->cli_section_tables [section];
- writable = sect->st_flags & SECT_FLAGS_MEM_WRITE;
-
if (sect->st_raw_data_ptr + sect->st_raw_data_size > image->raw_data_len)
return FALSE;
#ifdef HOST_WIN32
{
const char *heap_tables = image->heap_tables.data;
const guint32 *rows;
- guint64 valid_mask, sorted_mask;
+ guint64 valid_mask;
int valid = 0, table;
int heap_sizes;
image->idx_blob_wide = ((heap_sizes & 0x04) == 4);
valid_mask = read64 (heap_tables + 8);
- sorted_mask = read64 (heap_tables + 16);
rows = (const guint32 *) (heap_tables + 24);
for (table = 0; table < 64; table++){
continue;
}
if (table > MONO_TABLE_LAST) {
- g_warning("bits in valid must be zero above 0x2d (II - 23.1.6)");
+ g_warning("bits in valid must be zero above 0x37 (II - 23.1.6)");
} else {
image->tables [table].rows = read32 (rows);
}
- /*if ((sorted_mask & ((guint64) 1 << table)) == 0){
- g_print ("table %s (0x%02x) is sorted\n", mono_meta_table_name (table), table);
- }*/
rows++;
valid++;
}
MonoTableInfo *t, *mt;
t = &image->tables [MONO_TABLE_TYPEDEF];
mt = &image->tables [MONO_TABLE_METHOD];
- if (image->dynamic) {
+ if (image_is_dynamic (image)) {
/* FIXME: */
image->checked_module_cctor = TRUE;
return;
void
mono_image_init (MonoImage *image)
{
+ mono_mutex_init_recursive (&image->lock);
+ mono_mutex_init_recursive (&image->szarray_cache_lock);
+
image->mempool = mono_mempool_new_size (512);
mono_internal_hash_table_init (&image->class_cache,
g_direct_hash,
class_key_extract,
class_next_value);
- image->field_cache = g_hash_table_new (NULL, NULL);
+ image->field_cache = mono_conc_hashtable_new (&image->lock, NULL, NULL);
image->typespec_cache = g_hash_table_new (NULL, NULL);
image->memberref_signatures = g_hash_table_new (NULL, NULL);
image->method_signatures = g_hash_table_new (NULL, NULL);
image->property_hash = mono_property_hash_new ();
- InitializeCriticalSection (&image->lock);
- InitializeCriticalSection (&image->szarray_cache_lock);
}
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
mono_image_load_cli_data (MonoImage *image)
{
MonoCLIImageInfo *iinfo;
- MonoDotNetHeader *header;
iinfo = image->image_info;
- header = &iinfo->cli_header;
/* Load the CLI header */
if (!load_cli_header (image, iinfo))
if (care_about_pecoff == FALSE)
goto done;
- if (!mono_verifier_verify_pe_data (image, &errors))
- goto invalid_image;
+ if (!image->metadata_only) {
+ if (!mono_verifier_verify_pe_data (image, &errors))
+ goto invalid_image;
+
+ if (!mono_image_load_pe_data (image))
+ goto invalid_image;
+ }
- if (!mono_image_load_pe_data (image))
- goto invalid_image;
-
if (care_about_cli == FALSE) {
goto done;
}
static MonoImage *
do_mono_image_open (const char *fname, MonoImageOpenStatus *status,
- gboolean care_about_cli, gboolean care_about_pecoff, gboolean refonly)
+ gboolean care_about_cli, gboolean care_about_pecoff, gboolean refonly, gboolean metadata_only)
{
MonoCLIImageInfo *iinfo;
MonoImage *image;
image->image_info = iinfo;
image->name = mono_path_resolve_symlinks (fname);
image->ref_only = refonly;
+ image->metadata_only = metadata_only;
image->ref_count = 1;
/* if MONO_SECURITY_MODE_CORE_CLR is set then determine if this image is platform code */
image->core_clr_platform_code = mono_security_core_clr_determine_platform_image (image);
}
mono_images_unlock ();
- image = do_mono_image_open (fname, status, TRUE, TRUE, refonly);
+ image = do_mono_image_open (fname, status, TRUE, TRUE, refonly, FALSE);
if (image == NULL)
return NULL;
{
g_return_val_if_fail (fname != NULL, NULL);
- return(do_mono_image_open (fname, status, FALSE, TRUE, FALSE));
+ return do_mono_image_open (fname, status, FALSE, TRUE, FALSE, FALSE);
}
/**
{
g_return_val_if_fail (fname != NULL, NULL);
- return(do_mono_image_open (fname, status, FALSE, FALSE, FALSE));
+ return do_mono_image_open (fname, status, FALSE, FALSE, FALSE, FALSE);
+}
+
+/*
+ * mono_image_open_metadata_only:
+ *
+ * Open an image which contains metadata only without a PE header.
+ */
+MonoImage *
+mono_image_open_metadata_only (const char *fname, MonoImageOpenStatus *status)
+{
+ return do_mono_image_open (fname, status, TRUE, TRUE, FALSE, TRUE);
}
void
* assemblies, so we can't release these references in mono_assembly_close () since the
* MonoImage might outlive its associated MonoAssembly.
*/
- if (image->references && !image->dynamic) {
+ if (image->references && !image_is_dynamic (image)) {
for (i = 0; i < image->nreferences; i++) {
if (image->references [i] && image->references [i] != REFERENCE_MISSING) {
if (!mono_assembly_close_except_image_pools (image->references [i]))
if (image->methodref_cache)
g_hash_table_destroy (image->methodref_cache);
mono_internal_hash_table_destroy (&image->class_cache);
- g_hash_table_destroy (image->field_cache);
+ mono_conc_hashtable_destroy (image->field_cache);
if (image->array_cache) {
g_hash_table_foreach (image->array_cache, free_array_cache_entry, NULL);
g_hash_table_destroy (image->array_cache);
}
free_hash (image->native_wrapper_cache);
+ free_hash (image->native_wrapper_aot_cache);
+ free_hash (image->native_wrapper_check_cache);
+ free_hash (image->native_wrapper_aot_check_cache);
+ free_hash (image->native_func_wrapper_cache);
free_hash (image->managed_wrapper_cache);
free_hash (image->delegate_begin_invoke_cache);
free_hash (image->delegate_end_invoke_cache);
free_hash (image->thunk_invoke_cache);
free_hash (image->var_cache_slow);
free_hash (image->mvar_cache_slow);
+ free_hash (image->var_cache_constrained);
+ free_hash (image->mvar_cache_constrained);
free_hash (image->wrapper_param_names);
- free_hash (image->native_wrapper_aot_cache);
free_hash (image->pinvoke_scopes);
free_hash (image->pinvoke_scope_filenames);
- free_hash (image->gsharedvt_types);
+ for (i = 0; i < image->gshared_types_len; ++i)
+ free_hash (image->gshared_types [i]);
+ g_free (image->gshared_types);
/* The ownership of signatures is not well defined */
g_hash_table_destroy (image->memberref_signatures);
if (image->modules_loaded)
g_free (image->modules_loaded);
- DeleteCriticalSection (&image->szarray_cache_lock);
- DeleteCriticalSection (&image->lock);
+ mono_mutex_destroy (&image->szarray_cache_lock);
+ mono_mutex_destroy (&image->lock);
/*g_print ("destroy image %p (dynamic: %d)\n", image, image->dynamic);*/
- if (image->dynamic) {
+ if (image_is_dynamic (image)) {
/* Dynamic images are GC_MALLOCed */
g_free ((char*)image->module_name);
mono_dynamic_image_free ((MonoDynamicImage*)image);
{
int i;
- if (image->references && !image->dynamic) {
+ if (image->references && !image_is_dynamic (image)) {
for (i = 0; i < image->nreferences; i++) {
if (image->references [i] && image->references [i] != REFERENCE_MISSING)
mono_assembly_close_finish (image->references [i]);
mono_perfcounters->loader_bytes -= mono_mempool_get_allocated (image->mempool);
#endif
- if (!image->dynamic) {
+ if (!image_is_dynamic (image)) {
if (debug_assembly_unload)
mono_mempool_invalidate (image->mempool);
else {
if (fileidx < 1 || fileidx > t->rows)
return NULL;
- mono_loader_lock ();
+ mono_image_lock (image);
if (image->files && image->files [fileidx - 1]) {
- mono_loader_unlock ();
+ mono_image_unlock (image);
return image->files [fileidx - 1];
}
- if (!image->files)
- image->files = g_new0 (MonoImage*, t->rows);
-
fname_id = mono_metadata_decode_row_col (t, fileidx - 1, MONO_FILE_NAME);
fname = mono_metadata_string_heap (image, fname_id);
base_dir = g_path_get_dirname (image->name);
name = g_build_filename (base_dir, fname, NULL);
res = mono_image_open (name, NULL);
- if (res) {
+ if (!res)
+ goto done;
+
+ mono_image_lock (image);
+ if (image->files && image->files [fileidx - 1]) {
+ MonoImage *old = res;
+ res = image->files [fileidx - 1];
+ mono_loader_unlock ();
+ mono_image_close (old);
+ } else {
int i;
/* g_print ("loaded file %s from %s (%p)\n", name, image->name, image->assembly); */
res->assembly = image->assembly;
res->modules [i]->assembly = image->assembly;
}
+ if (!image->files)
+ image->files = g_new0 (MonoImage*, t->rows);
image->files [fileidx - 1] = res;
+ mono_loader_unlock ();
+ /* vtable fixup can't happen with the image lock held */
#ifdef HOST_WIN32
if (res->is_module_handle)
mono_image_fixup_vtable (res);
#endif
}
- mono_loader_unlock ();
+
+done:
g_free (name);
g_free (base_dir);
return res;
const char *pubkey;
guint32 len, tok;
- if (image->dynamic) {
+ if (image_is_dynamic (image)) {
if (size)
*size = ((MonoDynamicImage*)image)->public_key_len;
return (char*)((MonoDynamicImage*)image)->public_key;
gboolean
mono_image_is_dynamic (MonoImage *image)
{
- return image->dynamic;
+ return image_is_dynamic (image);
}
/**
mono_image_append_class_to_reflection_info_set (MonoClass *class)
{
MonoImage *image = class->image;
- g_assert (image->dynamic);
+ g_assert (image_is_dynamic (image));
mono_image_lock (image);
image->reflection_info_unregister_classes = g_slist_prepend_mempool (image->mempool, image->reflection_info_unregister_classes, class);
mono_image_unlock (image);