Reorganize the AOT file format once more, get rid of most globals, store them as...
authorZoltan Varga <vargaz@gmail.com>
Mon, 3 Jan 2011 17:49:19 +0000 (18:49 +0100)
committerZoltan Varga <vargaz@gmail.com>
Mon, 3 Jan 2011 17:55:52 +0000 (18:55 +0100)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/mini.h

index 2ca0017d20501e2b524f734372d6d033bf7c0b76..cd3528a93d71db8bc06fe8693ad69ea8cd32cb27 100644 (file)
@@ -377,6 +377,14 @@ emit_string_symbol (MonoAotCompile *acfg, const char *name, const char *value)
        img_writer_emit_string (acfg->w, value);
 }
 
+static void
+emit_local_string_symbol (MonoAotCompile *acfg, const char *name, const char *value)
+{
+       img_writer_emit_section_change (acfg->w, RODATA_SECT, 1);
+       img_writer_emit_label (acfg->w, name);
+       img_writer_emit_string (acfg->w, value);
+}
+
 static G_GNUC_UNUSED void
 emit_uleb128 (MonoAotCompile *acfg, guint32 value)
 {
@@ -3844,7 +3852,6 @@ emit_plt (MonoAotCompile *acfg)
        sprintf (symbol, "plt");
 
        emit_section_change (acfg, ".text", 0);
-       emit_global (acfg, symbol, TRUE);
        emit_alignment (acfg, 16);
        emit_label (acfg, symbol);
        emit_label (acfg, acfg->plt_symbol);
@@ -3956,7 +3963,6 @@ emit_plt (MonoAotCompile *acfg)
        emit_symbol_size (acfg, acfg->plt_symbol, ".");
 
        sprintf (symbol, "plt_end");
-       emit_global (acfg, symbol, TRUE);
        emit_label (acfg, symbol);
 
        g_hash_table_destroy (cache);
@@ -4191,7 +4197,6 @@ emit_trampolines (MonoAotCompile *acfg)
                                g_assert_not_reached ();
                        }
 
-                       emit_global (acfg, symbol, TRUE);
                        emit_alignment (acfg, AOT_FUNC_ALIGNMENT);
                        emit_label (acfg, symbol);
 
@@ -5010,13 +5015,11 @@ emit_code (MonoAotCompile *acfg)
 
        sprintf (symbol, "methods_end");
        emit_section_change (acfg, ".text", 0);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
        sprintf (symbol, "code_offsets");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5056,7 +5059,6 @@ emit_info (MonoAotCompile *acfg)
 
        sprintf (symbol, "method_info_offsets");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5420,7 +5422,6 @@ emit_extra_methods (MonoAotCompile *acfg)
        /* Emit the table */
        sprintf (symbol, "extra_method_table");
        emit_section_change (acfg, RODATA_SECT, 0);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5449,7 +5450,6 @@ emit_extra_methods (MonoAotCompile *acfg)
         */
        sprintf (symbol, "extra_method_info_offsets");
        emit_section_change (acfg, RODATA_SECT, 0);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5481,7 +5481,6 @@ emit_exception_info (MonoAotCompile *acfg)
 
        sprintf (symbol, "ex_info_offsets");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5505,7 +5504,6 @@ emit_unwind_info (MonoAotCompile *acfg)
        emit_section_change (acfg, RODATA_SECT, 1);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
-       emit_global (acfg, symbol, FALSE);
 
        for (i = 0; i < acfg->unwind_ops->len; ++i) {
                guint32 index = GPOINTER_TO_UINT (g_ptr_array_index (acfg->unwind_ops, i));
@@ -5538,7 +5536,6 @@ emit_class_info (MonoAotCompile *acfg)
 
        sprintf (symbol, "class_info_offsets");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5599,7 +5596,6 @@ emit_class_name_table (MonoAotCompile *acfg)
        /* Emit the table */
        sprintf (symbol, "class_name_table");
        emit_section_change (acfg, RODATA_SECT, 0);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5634,9 +5630,8 @@ emit_image_table (MonoAotCompile *acfg)
         * So we emit it at once, and reference its elements by an index.
         */
 
-       sprintf (symbol, "mono_image_table");
+       sprintf (symbol, "image_table");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5719,7 +5714,6 @@ emit_got_info (MonoAotCompile *acfg)
        /* Emit got_info_offsets table */
        sprintf (symbol, "got_info_offsets");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
@@ -5855,16 +5849,14 @@ emit_globals (MonoAotCompile *acfg)
 {
        char *build_info;
 
-       emit_string_symbol (acfg, "mono_assembly_guid" , acfg->image->guid);
-
-       emit_string_symbol (acfg, "mono_aot_version", MONO_AOT_FILE_VERSION);
+       emit_local_string_symbol (acfg, "assembly_guid" , acfg->image->guid);
 
        if (acfg->aot_opts.bind_to_runtime_version) {
                build_info = mono_get_runtime_build_info ();
-               emit_string_symbol (acfg, "mono_runtime_version", build_info);
+               emit_local_string_symbol (acfg, "runtime_version", build_info);
                g_free (build_info);
        } else {
-               emit_string_symbol (acfg, "mono_runtime_version", "");
+               emit_local_string_symbol (acfg, "runtime_version", "");
        }
 
        /* 
@@ -5930,7 +5922,6 @@ emit_mem_end (MonoAotCompile *acfg)
 
        sprintf (symbol, "mem_end");
        emit_section_change (acfg, ".text", 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 }
@@ -5961,9 +5952,13 @@ emit_file_info (MonoAotCompile *acfg)
 
        /* The data emitted here must match MonoAotFileInfo. */
 
+       emit_int32 (acfg, MONO_AOT_FILE_VERSION);
+       emit_int32 (acfg, 0);
+
        /* 
-        * We emit these as data to avoid making these symbols global, which leads to
-        * various problems
+        * We emit pointers to our data structures instead of emitting global symbols which
+        * point to them, to reduce the number of globals, and because using globals leads to
+        * various problems (i.e. arm/thumb).
         */
        emit_pointer (acfg, acfg->got_symbol);
        emit_pointer (acfg, "methods");
@@ -5975,6 +5970,37 @@ emit_file_info (MonoAotCompile *acfg)
        } else {
                emit_pointer (acfg, NULL);
        }
+       emit_pointer (acfg, "blob");
+       emit_pointer (acfg, "class_name_table");
+       emit_pointer (acfg, "class_info_offsets");
+       emit_pointer (acfg, "method_info_offsets");
+       emit_pointer (acfg, "ex_info_offsets");
+       emit_pointer (acfg, "code_offsets");
+       emit_pointer (acfg, "extra_method_info_offsets");
+       emit_pointer (acfg, "extra_method_table");
+       emit_pointer (acfg, "got_info_offsets");
+       emit_pointer (acfg, "methods_end");
+       emit_pointer (acfg, "unwind_info");
+       emit_pointer (acfg, "mem_end");
+       emit_pointer (acfg, "image_table");
+       emit_pointer (acfg, "plt");
+       emit_pointer (acfg, "plt_end");
+       emit_pointer (acfg, "assembly_guid");
+       emit_pointer (acfg, "runtime_version");
+       if (acfg->num_trampoline_got_entries) {
+               emit_pointer (acfg, "specific_trampolines");
+               emit_pointer (acfg, "static_rgctx_trampolines");
+               emit_pointer (acfg, "imt_thunks");
+       } else {
+               emit_pointer (acfg, NULL);
+               emit_pointer (acfg, NULL);
+               emit_pointer (acfg, NULL);
+       }
+       if (acfg->thumb_mixed) {
+               emit_pointer (acfg, "thumb_end");
+       } else {
+               emit_pointer (acfg, NULL);
+       }
 
        emit_int32 (acfg, acfg->plt_got_offset_base);
        emit_int32 (acfg, (int)(acfg->got_offset * sizeof (gpointer)));
@@ -5999,7 +6025,6 @@ emit_blob (MonoAotCompile *acfg)
 
        sprintf (symbol, "blob");
        emit_section_change (acfg, RODATA_SECT, 1);
-       emit_global (acfg, symbol, FALSE);
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
index 9bdffb17b484b67b77475d25c308f400d0235e3e..c38f2ff0a6bb0564e22b16b722759470b6270483 100644 (file)
@@ -964,6 +964,65 @@ find_symbol (MonoDl *module, gpointer *globals, const char *name, gpointer *valu
        }
 }
 
+static gboolean
+check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, char **out_msg)
+{
+       char *build_info;
+       char *msg = NULL;
+       gboolean usable = TRUE;
+       gboolean full_aot;
+       guint8 *blob;
+
+       if (strcmp (assembly->image->guid, info->assembly_guid)) {
+               msg = g_strdup_printf ("doesn't match assembly");
+               usable = FALSE;
+       }
+
+       build_info = mono_get_runtime_build_info ();
+       if (strlen (info->runtime_version) > 0 && strcmp (info->runtime_version, build_info)) {
+               msg = g_strdup_printf ("compiled against runtime version '%s' while this runtime has version '%s'", info->runtime_version, build_info);
+               usable = FALSE;
+       }
+       g_free (build_info);
+
+       full_aot = info->flags & MONO_AOT_FILE_FLAG_FULL_AOT;
+
+       if (mono_aot_only && !full_aot) {
+               msg = g_strdup_printf ("not compiled with --aot=full");
+               usable = FALSE;
+       }
+       if (!mono_aot_only && full_aot) {
+               msg = g_strdup_printf ("compiled with --aot=full");
+               usable = FALSE;
+       }
+#ifdef TARGET_ARM
+       /* mono_arch_find_imt_method () requires this */
+       if ((info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
+               msg = g_strdup_printf ("compiled against LLVM");
+               usable = FALSE;
+       }
+#endif
+       if (mini_get_debug_options ()->mdb_optimizations && !(info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) {
+               msg = g_strdup_printf ("not compiled for debugging");
+               usable = FALSE;
+       }
+
+       blob = info->blob;
+
+       if (info->gc_name_index != -1) {
+               char *gc_name = (char*)&blob [info->gc_name_index];
+               const char *current_gc_name = mono_gc_get_gc_name ();
+
+               if (strcmp (current_gc_name, gc_name) != 0) {
+                       msg = g_strdup_printf ("compiled against GC %s, while the current runtime uses GC %s.\n", gc_name, current_gc_name);
+                       usable = FALSE;
+               }
+       }
+
+       *out_msg = msg;
+       return usable;
+}
+
 static void
 load_aot_module (MonoAssembly *assembly, gpointer user_data)
 {
@@ -971,15 +1030,11 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        MonoAotModule *amodule;
        MonoDl *sofile;
        gboolean usable = TRUE;
-       char *saved_guid = NULL;
-       char *aot_version = NULL;
-       char *runtime_version, *build_info;
-       char *opt_flags = NULL;
+       char *version_symbol = NULL;
        char *msg = NULL;
        gpointer *globals;
-       gboolean full_aot = FALSE;
-       MonoAotFileInfo *file_info = NULL;
-       int i;
+       MonoAotFileInfo *info = NULL;
+       int i, version;
        guint8 *blob;
 
        if (mono_compile_aot)
@@ -1035,66 +1090,22 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                return;
        }
 
-       find_symbol (sofile, globals, "mono_assembly_guid", (gpointer *) &saved_guid);
-       find_symbol (sofile, globals, "mono_aot_version", (gpointer *) &aot_version);
-       find_symbol (sofile, globals, "mono_aot_opt_flags", (gpointer *)&opt_flags);
-       find_symbol (sofile, globals, "mono_runtime_version", (gpointer *)&runtime_version);
-
-       if (!aot_version || strcmp (aot_version, MONO_AOT_FILE_VERSION)) {
-               msg = g_strdup_printf ("wrong file format version (expected %s got %s)", MONO_AOT_FILE_VERSION, aot_version);
-               usable = FALSE;
-       }
-       else {
-               if (!saved_guid || strcmp (assembly->image->guid, saved_guid)) {
-                       msg = g_strdup_printf ("doesn't match assembly");
-                       usable = FALSE;
-               }
-       }
-
-       build_info = mono_get_runtime_build_info ();
-       if (!runtime_version || ((strlen (runtime_version) > 0 && strcmp (runtime_version, build_info)))) {
-               msg = g_strdup_printf ("compiled against runtime version '%s' while this runtime has version '%s'", runtime_version, build_info);
-               usable = FALSE;
-       }
-       g_free (build_info);
-
-       find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&file_info);
-       g_assert (file_info);
-
-       full_aot = ((MonoAotFileInfo*)file_info)->flags & MONO_AOT_FILE_FLAG_FULL_AOT;
-
-       if (mono_aot_only && !full_aot) {
-               fprintf (stderr, "Can't use AOT image '%s' in aot-only mode because it is not compiled with --aot=full.\n", aot_name);
-               exit (1);
-       }
-       if (!mono_aot_only && full_aot) {
-               msg = g_strdup_printf ("compiled with --aot=full");
-               usable = FALSE;
-       }
+       find_symbol (sofile, globals, "mono_aot_version", (gpointer *) &version_symbol);
+       find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&info);
 
-#ifdef TARGET_ARM
-       /* mono_arch_find_imt_method () requires this */
-       if ((((MonoAotFileInfo*)file_info)->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
-               msg = g_strdup_printf ("compiled against LLVM");
-               usable = FALSE;
+       if (version_symbol) {
+               /* Old file format */
+               version = atoi (version_symbol);
+       } else {
+               g_assert (info);
+               version = info->version;
        }
-#endif
 
-       if (mini_get_debug_options ()->mdb_optimizations && !(file_info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) {
-               msg = g_strdup_printf ("not compiled for debugging");
+       if (version != MONO_AOT_FILE_VERSION) {
+               msg = g_strdup_printf ("wrong file format version (expected %d got %d)", MONO_AOT_FILE_VERSION, version);
                usable = FALSE;
-       }
-
-       find_symbol (sofile, globals, "blob", (gpointer*)&blob);
-
-       if (usable && ((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) {
-                       msg = g_strdup_printf ("compiled against GC %s, while the current runtime uses GC %s.\n", gc_name, current_gc_name);
-                       usable = FALSE;
-               }
+       } else {
+               usable = check_usable (assembly, info, &msg);
        }
 
        if (!usable) {
@@ -1112,11 +1123,13 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                return;
        }
 
+       blob = info->blob;
+
        amodule = g_new0 (MonoAotModule, 1);
        amodule->aot_name = aot_name;
        amodule->assembly = assembly;
 
-       memcpy (&amodule->info, file_info, sizeof (*file_info));
+       memcpy (&amodule->info, info, sizeof (*info));
 
        amodule->got = amodule->info.got;
        amodule->got [0] = assembly->image;
@@ -1130,7 +1143,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                guint32 table_len, i;
                char *table = NULL;
 
-               find_symbol (sofile, globals, "mono_image_table", (gpointer *)&table);
+               table = info->image_table;
                g_assert (table);
 
                table_len = *(guint32*)table;
@@ -1166,34 +1179,30 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                }
        }
 
-       /* Read method and method_info tables */
-       find_symbol (sofile, globals, "code_offsets", (gpointer*)&amodule->code_offsets);
-       amodule->code = amodule->info.methods;
+       amodule->code_offsets = info->code_offsets;
+       amodule->code = info->methods;
 #ifdef TARGET_ARM
        /* Mask out thumb interop bit */
        amodule->code = (void*)((mgreg_t)amodule->code & ~1);
 #endif
-       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, "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);
-       find_symbol (sofile, globals, "extra_method_info_offsets", (gpointer *)&amodule->extra_method_info_offsets);
-       find_symbol (sofile, globals, "got_info_offsets", (gpointer*)&amodule->got_info_offsets);
-       find_symbol (sofile, globals, "specific_trampolines", (gpointer*)&(amodule->trampolines [MONO_AOT_TRAMP_SPECIFIC]));
-       find_symbol (sofile, globals, "static_rgctx_trampolines", (gpointer*)&(amodule->trampolines [MONO_AOT_TRAMP_STATIC_RGCTX]));
-       find_symbol (sofile, globals, "imt_thunks", (gpointer*)&(amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK]));
-       find_symbol (sofile, globals, "unwind_info", (gpointer)&amodule->unwind_info);
-       find_symbol (sofile, globals, "mem_end", (gpointer*)&amodule->mem_end);
-       find_symbol (sofile, globals, "thumb_end", (gpointer*)&amodule->thumb_end);
-
+       amodule->code_end = info->methods_end;
+       amodule->method_info_offsets = info->method_info_offsets;
+       amodule->ex_info_offsets = info->ex_info_offsets;
+       amodule->class_info_offsets = info->class_info_offsets;
+       amodule->class_name_table = info->class_name_table;
+       amodule->extra_method_table = info->extra_method_table;
+       amodule->extra_method_info_offsets = info->extra_method_info_offsets;
+       amodule->got_info_offsets = info->got_info_offsets;
+       amodule->unwind_info = info->unwind_info;
+       amodule->mem_end = info->mem_end;
        amodule->mem_begin = amodule->code;
-
-       find_symbol (sofile, globals, "plt", (gpointer*)&amodule->plt);
-       find_symbol (sofile, globals, "plt_end", (gpointer*)&amodule->plt_end);
-
-       amodule->mono_eh_frame = amodule->info.mono_eh_frame;
+       amodule->plt = info->plt;
+       amodule->plt_end = info->plt_end;
+       amodule->mono_eh_frame = info->mono_eh_frame;
+       amodule->trampolines [MONO_AOT_TRAMP_SPECIFIC] = info->specific_trampolines;
+       amodule->trampolines [MONO_AOT_TRAMP_STATIC_RGCTX] = info->static_rgctx_trampolines;
+       amodule->trampolines [MONO_AOT_TRAMP_IMT_THUNK] = info->imt_thunks;
+       amodule->thumb_end = info->thumb_end;
 
        if (make_unreadable) {
 #ifndef TARGET_WIN32
index 1b82bb99e40fc790cef28fd54c9a2e6c67c4aa1f..16c14c59925d4d2d5aa431c0f1fe435394cc8632 100644 (file)
@@ -111,7 +111,7 @@ typedef gint64 mgreg_t;
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION "71"
+#define MONO_AOT_FILE_VERSION 72
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -149,10 +149,44 @@ typedef enum {
 /* This structure is stored in the AOT file */
 typedef struct MonoAotFileInfo
 {
+       /* The version number of the AOT file format, should match MONO_AOT_FILE_VERSION */
+       guint32 version;
+       /* For alignment */
+       guint32 dummy;
+
        /* All the pointers should be at the start to avoid alignment problems */
+
+       /* Mono's Global Offset Table */
        gpointer got;
+       /* Compiled code for methods */
        gpointer methods;
+       /* Mono EH Frame created by llc when using LLVM */
        gpointer mono_eh_frame;
+       /* Data blob */
+       gpointer blob;
+       gpointer class_name_table;
+       gpointer class_info_offsets;
+       gpointer method_info_offsets;
+       gpointer ex_info_offsets;
+       gpointer code_offsets;
+       gpointer extra_method_info_offsets;
+       gpointer extra_method_table;
+       gpointer got_info_offsets;
+       gpointer methods_end;
+       gpointer unwind_info;
+       gpointer mem_end;
+       gpointer image_table;
+       /* Start of Mono's Program Linkage Table */
+       gpointer plt;
+       /* End of Mono's Program Linkage Table */
+       gpointer plt_end;
+       /* The GUID of the assembly which the AOT image was generated from */
+       gpointer assembly_guid;
+       gpointer runtime_version;
+       gpointer specific_trampolines;
+       gpointer static_rgctx_trampolines;
+       gpointer imt_thunks;
+       gpointer thumb_end;
 
        guint32 plt_got_offset_base;
        guint32 got_size;