MonoDl *sofile;
JitInfoMap *async_jit_info_table;
+ CRITICAL_SECTION mutex;
} MonoAotModule;
typedef struct {
/* AOT RUNTIME */
/*****************************************************/
+static inline void
+amodule_lock (MonoAotModule *amodule)
+{
+ EnterCriticalSection (&amodule->mutex);
+}
+
+static inline void
+amodule_unlock (MonoAotModule *amodule)
+{
+ LeaveCriticalSection (&amodule->mutex);
+}
+
/*
* load_image:
*
amodule->method_to_code = g_hash_table_new (mono_aligned_addr_hash, NULL);
amodule->blob = blob;
+ InitializeCriticalSection (&amodule->mutex);
+
/* Read image table */
{
guint32 table_len, i;
amodule->trampolines [MONO_AOT_TRAMP_GSHAREDVT_ARG] = info->gsharedvt_arg_trampolines;
amodule->thumb_end = info->thumb_end;
-#ifdef MONOTOUCH
if (info->flags & MONO_AOT_FILE_FLAG_DIRECT_METHOD_ADDRESSES) {
/* Compute code_offsets from the method addresses */
amodule->code_offsets = g_malloc0 (amodule->info.nmethods * sizeof (gint32));
for (i = 0; i < amodule->info.nmethods; ++i) {
/* method_addresses () contains a table of branches, since the ios linker can update those correctly */
- void *addr = get_arm_bl_target ((guint32*)amodule->method_addresses + i);
+ void *addr = NULL;
+#ifdef TARGET_ARM
+ addr = get_arm_bl_target ((guint32*)amodule->method_addresses + i);
+#elif defined(TARGET_X86) || defined(TARGET_AMD64)
+ addr = mono_arch_get_call_target ((guint8*)amodule->method_addresses + (i * 5) + 5);
+#else
+ g_assert_not_reached ();
+#endif
+ g_assert (addr);
if (addr == amodule->method_addresses)
amodule->code_offsets [i] = 0xffffffff;
else
amodule->code_offsets [i] = (char*)addr - (char*)amodule->code;
}
}
-#endif
if (make_unreadable) {
#ifndef TARGET_WIN32
if (!amodule || !amodule->class_name_table)
return FALSE;
- mono_aot_lock ();
+ amodule_lock (amodule);
*klass = NULL;
if (nspace_table) {
*klass = g_hash_table_lookup (nspace_table, name);
if (*klass) {
- mono_aot_unlock ();
+ amodule_unlock (amodule);
return TRUE;
}
}
name_space2 = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
if (!strcmp (name, name2) && !strcmp (name_space, name_space2)) {
- mono_aot_unlock ();
+ amodule_unlock (amodule);
*klass = mono_class_get (image, token);
/* Add to cache */
if (*klass) {
- mono_aot_lock ();
+ amodule_lock (amodule);
nspace_table = g_hash_table_lookup (amodule->name_cache, name_space);
if (!nspace_table) {
nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (amodule->name_cache, (char*)name_space2, nspace_table);
}
g_hash_table_insert (nspace_table, (char*)name2, *klass);
- mono_aot_unlock ();
+ amodule_unlock (amodule);
}
return TRUE;
}
}
}
- mono_aot_unlock ();
+ amodule_unlock (amodule);
return TRUE;
}
/* Might be a wrapper/extra method */
if (!async) {
if (amodule->extra_methods) {
- mono_aot_lock ();
+ amodule_lock (amodule);
method = g_hash_table_lookup (amodule->extra_methods, GUINT_TO_POINTER (method_index));
- mono_aot_unlock ();
+ amodule_unlock (amodule);
} else {
method = NULL;
}
case MONO_PATCH_INFO_CLASS:
case MONO_PATCH_INFO_IID:
case MONO_PATCH_INFO_ADJUSTED_IID:
+ case MONO_PATCH_INFO_CLASS_INIT:
/* Shared */
ji->data.klass = decode_klass_ref (aot_module, p, &p);
if (!ji->data.klass)
goto cleanup;
break;
- case MONO_PATCH_INFO_CLASS_INIT:
case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
- ji->data.klass = decode_klass_ref (aot_module, p, &p);
- if (!ji->data.klass)
+ ji->data.del_tramp = mono_mempool_alloc0 (mp, sizeof (MonoClassMethodPair));
+ ji->data.del_tramp->klass = decode_klass_ref (aot_module, p, &p);
+ if (!ji->data.del_tramp->klass)
goto cleanup;
+ if (decode_value (p, &p)) {
+ ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p);
+ if (!ji->data.del_tramp->method)
+ goto cleanup;
+ }
break;
case MONO_PATCH_INFO_IMAGE:
ji->data.image = load_image (aot_module, decode_value (p, &p), TRUE);
code = &amodule->code [amodule->code_offsets [method_index] + 1];
}
- mono_aot_lock ();
- if (!amodule->methods_loaded)
- amodule->methods_loaded = g_new0 (guint32, amodule->info.nmethods / 32 + 1);
- mono_aot_unlock ();
+ if (!amodule->methods_loaded) {
+ amodule_lock (amodule);
+ if (!amodule->methods_loaded) {
+ guint32 *loaded;
+
+ loaded = g_new0 (guint32, amodule->info.nmethods / 32 + 1);
+ mono_memory_barrier ();
+ amodule->methods_loaded = loaded;
+ }
+ amodule_unlock (amodule);
+ }
if ((amodule->methods_loaded [method_index / 32] >> (method_index % 32)) & 0x1)
return code;
g_free (full_name);
}
- mono_aot_lock ();
+ amodule_lock (amodule);
InterlockedIncrement (&mono_jit_stats.methods_aot);
if (method && method->wrapper_type)
g_hash_table_insert (amodule->method_to_code, method, code);
- mono_aot_unlock ();
+ amodule_unlock (amodule);
if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION) {
MonoJitInfo *jinfo;
p = amodule->blob + key;
orig_p = p;
- mono_aot_lock ();
+ amodule_lock (amodule);
if (!amodule->method_ref_to_method)
amodule->method_ref_to_method = g_hash_table_new (NULL, NULL);
m = g_hash_table_lookup (amodule->method_ref_to_method, p);
- mono_aot_unlock ();
+ amodule_unlock (amodule);
if (!m) {
m = decode_resolve_method_ref_with_target (amodule, method, p, &p);
if (m) {
- mono_aot_lock ();
+ amodule_lock (amodule);
g_hash_table_insert (amodule->method_ref_to_method, orig_p, m);
- mono_aot_unlock ();
+ amodule_unlock (amodule);
}
}
if (m == method) {
method_index = mono_metadata_token_index (method->token) - 1;
} else if (method->is_inflated || !method->token) {
/* This hash table is used to avoid the slower search in the extra_method_table in the AOT image */
- mono_aot_lock ();
+ amodule_lock (amodule);
code = g_hash_table_lookup (amodule->method_to_code, method);
- mono_aot_unlock ();
+ amodule_unlock (amodule);
if (code)
return code;
return NULL;
/* Needed by find_jit_info */
- mono_aot_lock ();
+ amodule_lock (amodule);
if (!amodule->extra_methods)
amodule->extra_methods = g_hash_table_new (NULL, NULL);
g_hash_table_insert (amodule->extra_methods, GUINT_TO_POINTER (method_index), method);
- mono_aot_unlock ();
+ amodule_unlock (amodule);
} else {
/* Common case */
method_index = mono_metadata_token_index (method->token) - 1;
*
* Initialize the PLT table of the AOT module. Called lazily when the first AOT
* method in the module is loaded to avoid committing memory by writing to it.
- * LOCKING: Assumes the AOT lock is held.
+ * LOCKING: Assumes the AMODULE lock is held.
*/
static void
init_plt (MonoAotModule *amodule)