Avoid loading AOT images compiled against Boehm in an SGEN runtime, and vice versa...
authorZoltan Varga <vargaz@gmail.com>
Sat, 7 Aug 2010 01:40:04 +0000 (03:40 +0200)
committerZoltan Varga <vargaz@gmail.com>
Sat, 7 Aug 2010 01:40:25 +0000 (03:40 +0200)
mono/metadata/boehm-gc.c
mono/metadata/gc-internal.h
mono/metadata/null-gc.c
mono/metadata/sgen-gc.c
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini.h

index 79114c3822c33fae71b04d333957c3ae94b65104..504bdcb526e94b40f97f393f253c5272a349fe38 100644 (file)
@@ -817,6 +817,7 @@ create_allocator (int atype, int offset)
        mono_method_get_header (res)->init_locals = FALSE;
 
        info = mono_image_alloc0 (mono_defaults.corlib, sizeof (AllocatorWrapperInfo));
+       info->gc_name = "boehm";
        info->alloc_type = atype;
        mono_marshal_set_wrapper_info (res, info);
 
@@ -947,6 +948,12 @@ mono_gc_get_write_barrier (void)
 
 #endif
 
+const char *
+mono_gc_get_gc_name (void)
+{
+       return "boehm";
+}
+
 void*
 mono_gc_invoke_with_gc_lock (MonoGCLockedCallbackFunc func, void *data)
 {
index 8df916e3c8e47804d353fd8fd2de955b8afd37bd..e5385a8e4d5f14af54f48b7fd1a1ac208b3587a9 100644 (file)
@@ -158,6 +158,7 @@ void  mono_gc_finalize_threadpool_threads (void) MONO_INTERNAL;
 
 /* Accessible using mono_marshal_wrapper_info_from_wrapper () */
 typedef struct {
+       const char *gc_name;
        int alloc_type;
 } AllocatorWrapperInfo;
 
@@ -167,6 +168,9 @@ MonoMethod *mono_gc_get_managed_allocator_by_type (int atype) MONO_INTERNAL;
 
 guint32 mono_gc_get_managed_allocator_types (void) MONO_INTERNAL;
 
+/* Return a short string identifying the GC, indented to be saved in AOT images */
+const char *mono_gc_get_gc_name (void) MONO_INTERNAL;
+
 /* Fast write barriers */
 MonoMethod* mono_gc_get_write_barrier (void) MONO_INTERNAL;
 
index 816a7d3886ddf203e26b6fd9a5440024c3763893..b7140a29d4f9e5d80d40c05997535d4e2637bef9 100644 (file)
@@ -223,6 +223,12 @@ mono_gc_get_managed_allocator_types (void)
        return 0;
 }
 
+const char *
+mono_gc_get_gc_name (void)
+{
+       return "null";
+}
+
 void
 mono_gc_add_weak_track_handle (MonoObject *obj, guint32 gchandle)
 {
index 884963a17e1b7a7d98cc8cfbb12ebe40852afd9c..c02d6d309ea6e422299cd640b33c3daae32316f6 100644 (file)
@@ -6638,6 +6638,7 @@ create_allocator (int atype)
        mono_method_get_header (res)->init_locals = FALSE;
 
        info = mono_image_alloc0 (mono_defaults.corlib, sizeof (AllocatorWrapperInfo));
+       info->gc_name = "sgen";
        info->alloc_type = atype;
        mono_marshal_set_wrapper_info (res, info);
 
@@ -6645,6 +6646,12 @@ create_allocator (int atype)
 }
 #endif
 
+const char *
+mono_gc_get_gc_name (void)
+{
+       return "sgen";
+}
+
 static MonoMethod* alloc_method_cache [ATYPE_NUM];
 static MonoMethod *write_barrier_method;
 
index f0d18dc0590e04e20d22f2ad3acf71f050da8213..07e2c6c4c5d0dc3ad314c81c6722f5097afd627c 100644 (file)
@@ -1417,7 +1417,7 @@ add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
  * blob where the data was stored.
  */
 static guint32
-add_to_blob (MonoAotCompile *acfg, guint8 *data, guint32 data_len)
+add_to_blob (MonoAotCompile *acfg, const guint8 *data, guint32 data_len)
 {
        if (acfg->blob.alloc_size == 0)
                stream_init (&acfg->blob);
@@ -1724,6 +1724,7 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8
                case MONO_WRAPPER_ALLOC: {
                        AllocatorWrapperInfo *info = mono_marshal_get_wrapper_info (method);
 
+                       /* The GC name is saved once in MonoAotFileInfo */
                        g_assert (info->alloc_type != -1);
                        encode_value (info->alloc_type, p, &p);
                        break;
@@ -5742,6 +5743,15 @@ emit_file_info (MonoAotCompile *acfg)
 {
        char symbol [128];
        int i;
+       int gc_name_offset;
+       const char *gc_name;
+
+       /*
+        * The managed allocators are GC specific, so can't use an AOT image created by one GC
+        * in another.
+        */
+       gc_name = mono_gc_get_gc_name ();
+       gc_name_offset = add_to_blob (acfg, (guint8*)gc_name, strlen (gc_name) + 1);
 
        sprintf (symbol, "mono_aot_file_info");
        emit_section_change (acfg, ".data", 0);
@@ -5749,13 +5759,14 @@ emit_file_info (MonoAotCompile *acfg)
        emit_label (acfg, symbol);
        emit_global (acfg, symbol, FALSE);
 
-       /* The data emitted here must match MonoAotFileInfo in aot-runtime.c. */
+       /* The data emitted here must match MonoAotFileInfo. */
        emit_int32 (acfg, acfg->plt_got_offset_base);
        emit_int32 (acfg, (int)(acfg->got_offset * sizeof (gpointer)));
        emit_int32 (acfg, acfg->plt_offset);
        emit_int32 (acfg, acfg->nmethods);
        emit_int32 (acfg, acfg->flags);
        emit_int32 (acfg, acfg->opts);
+       emit_int32 (acfg, gc_name_offset);
 
        for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
                emit_int32 (acfg, acfg->num_trampolines [i]);
index 7a7d4530b1ef305dd657a2dbffb857196d60fcd8..c2290ed8f6a6a8fecbab2b290fbd1db6f69411dc 100644 (file)
@@ -963,6 +963,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        MonoAotFileInfo *file_info = NULL;
        int i;
        gpointer *got_addr;
+       guint8 *blob;
 
        if (mono_compile_aot)
                return;
@@ -1060,10 +1061,24 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                usable = FALSE;
        }
 
+       find_symbol (sofile, globals, "blob", (gpointer*)&blob);
+
+       if (((MonoAotFileInfo*)file_info)->gc_name_index != -1) {
+               char *gc_name = (char*)&blob [((MonoAotFileInfo*)file_info)->gc_name_index];
+               const char *current_gc_name = mono_gc_get_gc_name ();
+
+               if (strcmp (current_gc_name, gc_name) != 0) {
+                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module %s is compiled against GC %s, while the current runtime uses GC %s.\n", aot_name, gc_name, current_gc_name);
+                       usable = FALSE;
+               }
+       }
+
        if (!usable) {
                if (mono_aot_only) {
                        fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode.\n", aot_name);
                        exit (1);
+               } else {
+                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module %s is unusable.\n", aot_name);
                }
                g_free (aot_name);
                if (sofile)
@@ -1083,6 +1098,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        amodule->globals = globals;
        amodule->sofile = sofile;
        amodule->method_to_code = g_hash_table_new (mono_aligned_addr_hash, NULL);
+       amodule->blob = blob;
 
        /* Read image table */
        {
@@ -1131,7 +1147,6 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        find_symbol (sofile, globals, "methods_end", (gpointer*)&amodule->code_end);
        find_symbol (sofile, globals, "method_info_offsets", (gpointer*)&amodule->method_info_offsets);
        find_symbol (sofile, globals, "ex_info_offsets", (gpointer*)&amodule->ex_info_offsets);
-       find_symbol (sofile, globals, "blob", (gpointer*)&amodule->blob);
        find_symbol (sofile, globals, "class_info_offsets", (gpointer*)&amodule->class_info_offsets);
        find_symbol (sofile, globals, "class_name_table", (gpointer *)&amodule->class_name_table);
        find_symbol (sofile, globals, "extra_method_table", (gpointer *)&amodule->extra_method_table);
@@ -1321,7 +1336,7 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
 {
        int i;
        MonoClass *klass = vtable->klass;
-       MonoAotModule *aot_module = klass->image->aot_module;
+       MonoAotModule *amodule = klass->image->aot_module;
        guint8 *info, *p;
        MonoCachedClassInfo class_info;
        gboolean err;
@@ -1329,20 +1344,20 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
        MonoImage *image;
        gboolean no_aot_trampoline;
 
-       if (MONO_CLASS_IS_INTERFACE (klass) || klass->rank || !aot_module)
+       if (MONO_CLASS_IS_INTERFACE (klass) || klass->rank || !amodule)
                return NULL;
 
-       info = &aot_module->blob [mono_aot_get_offset (aot_module->class_info_offsets, mono_metadata_token_index (klass->type_token) - 1)];
+       info = &amodule->blob [mono_aot_get_offset (amodule->class_info_offsets, mono_metadata_token_index (klass->type_token) - 1)];
        p = info;
 
-       err = decode_cached_class_info (aot_module, &class_info, p, &p);
+       err = decode_cached_class_info (amodule, &class_info, p, &p);
        if (!err)
                return NULL;
 
        for (i = 0; i < slot; ++i)
-               decode_method_ref (aot_module, &token, NULL, NULL, p, &p);
+               decode_method_ref (amodule, &token, NULL, NULL, p, &p);
 
-       image = decode_method_ref (aot_module, &token, NULL, &no_aot_trampoline, p, &p);
+       image = decode_method_ref (amodule, &token, NULL, &no_aot_trampoline, p, &p);
        if (!image)
                return NULL;
        if (no_aot_trampoline)
@@ -1357,16 +1372,16 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
 gboolean
 mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res)
 {
-       MonoAotModule *aot_module = klass->image->aot_module;
+       MonoAotModule *amodule = klass->image->aot_module;
        guint8 *p;
        gboolean err;
 
-       if (klass->rank || !aot_module)
+       if (klass->rank || !amodule)
                return FALSE;
 
-       p = (guint8*)&aot_module->blob [mono_aot_get_offset (aot_module->class_info_offsets, mono_metadata_token_index (klass->type_token) - 1)];
+       p = (guint8*)&amodule->blob [mono_aot_get_offset (amodule->class_info_offsets, mono_metadata_token_index (klass->type_token) - 1)];
 
-       err = decode_cached_class_info (aot_module, res, p, &p);
+       err = decode_cached_class_info (amodule, res, p, &p);
        if (!err)
                return FALSE;
 
@@ -1386,7 +1401,7 @@ mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res)
 gboolean
 mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const char *name, MonoClass **klass)
 {
-       MonoAotModule *aot_module = image->aot_module;
+       MonoAotModule *amodule = image->aot_module;
        guint16 *table, *entry;
        guint16 table_size;
        guint32 hash;
@@ -1397,7 +1412,7 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
        guint32 cols [MONO_TYPEDEF_SIZE];
        GHashTable *nspace_table;
 
-       if (!aot_module || !aot_module->class_name_table)
+       if (!amodule || !amodule->class_name_table)
                return FALSE;
 
        mono_aot_lock ();
@@ -1405,9 +1420,9 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
        *klass = NULL;
 
        /* First look in the cache */
-       if (!aot_module->name_cache)
-               aot_module->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
-       nspace_table = g_hash_table_lookup (aot_module->name_cache, name_space);
+       if (!amodule->name_cache)
+               amodule->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
+       nspace_table = g_hash_table_lookup (amodule->name_cache, name_space);
        if (nspace_table) {
                *klass = g_hash_table_lookup (nspace_table, name);
                if (*klass) {
@@ -1416,8 +1431,8 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
                }
        }
 
-       table_size = aot_module->class_name_table [0];
-       table = aot_module->class_name_table + 1;
+       table_size = amodule->class_name_table [0];
+       table = amodule->class_name_table + 1;
 
        if (name_space [0] == '\0')
                full_name = g_strdup_printf ("%s", name);
@@ -1457,10 +1472,10 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
                                /* Add to cache */
                                if (*klass) {
                                        mono_aot_lock ();
-                                       nspace_table = g_hash_table_lookup (aot_module->name_cache, name_space);
+                                       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 (aot_module->name_cache, (char*)name_space2, nspace_table);
+                                               g_hash_table_insert (amodule->name_cache, (char*)name_space2, nspace_table);
                                        }
                                        g_hash_table_insert (nspace_table, (char*)name2, *klass);
                                        mono_aot_unlock ();
index efb9e867130e9e9da7d170dc21697ed7aaedda96..6e6c29b18417c3c89b29114beac96d7d751a82d6 100644 (file)
@@ -111,7 +111,7 @@ typedef gint64 mgreg_t;
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "68"
+#define MONO_AOT_FILE_VERSION "69"
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -155,6 +155,8 @@ typedef struct MonoAotFileInfo
        guint32 flags;
        /* Optimization flags used to compile the module */
        guint32 opts;
+       /* Index of the blob entry holding the GC used by this module */
+       gint32 gc_name_index;
 
        guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
        guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];