#define ENABLE_AOT_CACHE
#endif
+/* Number of got entries shared between the JIT and LLVM GOT */
+#define N_COMMON_GOT_ENTRIES 4
+
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
#define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
#define ROUND_DOWN(VALUE,SIZE) ((VALUE) & ~((SIZE) - 1))
/* Pointer to the Global Offset Table */
gpointer *got;
gpointer *llvm_got;
+ gpointer shared_got [N_COMMON_GOT_ENTRIES];
GHashTable *name_cache;
GHashTable *extra_methods;
/* Maps methods to their code */
#define mono_aot_page_unlock() mono_mutex_unlock (&aot_page_mutex)
static mono_mutex_t aot_page_mutex;
+static MonoAotModule *mscorlib_aot_module;
+
static void
init_plt (MonoAotModule *info);
compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **code_end);
static gboolean
-mono_aot_init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass **klass);
+init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass **klass);
/*****************************************************/
/* AOT RUNTIME */
#endif
}
+static void
+init_gots (MonoAotModule *amodule)
+{
+ int i;
+
+ if (amodule->got) {
+ for (i = 0; i < N_COMMON_GOT_ENTRIES; ++i)
+ amodule->got [i] = amodule->shared_got [i];
+ }
+ if (amodule->llvm_got) {
+ for (i = 0; i < N_COMMON_GOT_ENTRIES; ++i)
+ amodule->llvm_got [i] = amodule->shared_got [i];
+ }
+}
+
static void
load_aot_module (MonoAssembly *assembly, gpointer user_data)
{
memcpy (&amodule->info, info, sizeof (*info));
- amodule->got = amodule->info.got;
+ amodule->got = amodule->info.jit_got;
amodule->llvm_got = amodule->info.llvm_got;
amodule->globals = globals;
amodule->sofile = sofile;
amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK] = info->imt_thunks;
amodule->trampolines [MONO_AOT_TRAMP_GSHAREDVT_ARG] = info->gsharedvt_arg_trampolines;
+ if (!strcmp (assembly->aname.name, "mscorlib"))
+ mscorlib_aot_module = amodule;
+
/* 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) {
assembly->image->aot_module = amodule;
- amodule->got [0] = assembly->image;
+ amodule->shared_got [0] = assembly->image;
if (mono_aot_only) {
char *code;
/* The second got slot contains the mscorlib got addr */
MonoAotModule *mscorlib_amodule = mono_defaults.corlib->aot_module;
- amodule->got [1] = mscorlib_amodule->got;
+ amodule->shared_got [1] = mscorlib_amodule->got;
} else {
- amodule->got [1] = amodule->got;
+ amodule->shared_got [1] = amodule->got;
}
}
memset (&ji, 0, sizeof (ji));
ji.type = MONO_PATCH_INFO_GC_CARD_TABLE_ADDR;
- amodule->got [2] = mono_resolve_patch_target (NULL, mono_get_root_domain (), NULL, &ji, FALSE);
+ amodule->shared_got [2] = mono_resolve_patch_target (NULL, mono_get_root_domain (), NULL, &ji, FALSE);
memset (&ji, 0, sizeof (ji));
ji.type = MONO_PATCH_INFO_GC_NURSERY_START;
- amodule->got [3] = mono_resolve_patch_target (NULL, mono_get_root_domain (), NULL, &ji, FALSE);
+ amodule->shared_got [3] = mono_resolve_patch_target (NULL, mono_get_root_domain (), NULL, &ji, FALSE);
}
- if (amodule->llvm_got) {
- amodule->llvm_got [0] = amodule->got [0];
- amodule->llvm_got [1] = amodule->got [1];
- amodule->llvm_got [2] = amodule->got [2];
- amodule->llvm_got [3] = amodule->got [3];
- }
+ init_gots (amodule);
/*
* Since we store methoddef and classdef tokens when referring to methods/classes in
}
}
- res = mono_aot_init_method (amodule, method_index, method, &klass);
+ res = init_method (amodule, method_index, method, &klass);
if (!res)
goto cleanup;
}
static gboolean
-mono_aot_init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass **klass)
+init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, MonoClass **klass)
{
MonoDomain *domain = mono_domain_get ();
MonoMemPool *mp;
return load_function_full (amodule, name, NULL);
}
+static MonoAotModule*
+get_mscorlib_aot_module (void)
+{
+ MonoImage *image;
+ MonoAotModule *amodule;
+
+ image = mono_defaults.corlib;
+ if (image)
+ amodule = image->aot_module;
+ else
+ amodule = mscorlib_aot_module;
+ g_assert (amodule);
+ return amodule;
+}
+
/*
* Return the trampoline identified by NAME from the mscorlib AOT file.
* On ppc64, this returns a function descriptor.
gpointer
mono_aot_get_trampoline_full (const char *name, MonoTrampInfo **out_tinfo)
{
- MonoImage *image;
- MonoAotModule *amodule;
-
- image = mono_defaults.corlib;
- g_assert (image);
-
- amodule = image->aot_module;
- g_assert (amodule);
+ MonoAotModule *amodule = get_mscorlib_aot_module ();
return mono_create_ftnptr_malloc (load_function_full (amodule, name, out_tinfo));
}
static gpointer
get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotModule **out_amodule, guint32 *got_offset, guint32 *out_tramp_size)
{
- MonoAotModule *amodule;
- int index, tramp_size;
MonoImage *image;
+ MonoAotModule *amodule = get_mscorlib_aot_module ();
+ int index, tramp_size;
/* Currently, we keep all trampolines in the mscorlib AOT image */
image = mono_defaults.corlib;
- g_assert (image);
-
- mono_aot_lock ();
-
- amodule = image->aot_module;
- g_assert (amodule);
*out_amodule = amodule;
+ mono_aot_lock ();
+
#ifdef MONOTOUCH
#define MONOTOUCH_TRAMPOLINES_ERROR ". See http://docs.xamarin.com/ios/troubleshooting for instructions on how to fix this condition."
#else
#endif
if (amodule->trampoline_index [tramp_type] == amodule->info.num_trampolines [tramp_type]) {
g_error ("Ran out of trampolines of type %d in '%s' (%d)%s\n",
- tramp_type, image->name, amodule->info.num_trampolines [tramp_type], MONOTOUCH_TRAMPOLINES_ERROR);
+ tramp_type, image ? image->name : "mscorlib", amodule->info.num_trampolines [tramp_type], MONOTOUCH_TRAMPOLINES_ERROR);
}
index = amodule->trampoline_index [tramp_type] ++;