2009-06-21 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Sat, 20 Jun 2009 22:05:48 +0000 (22:05 -0000)
committerZoltan Varga <vargaz@gmail.com>
Sat, 20 Jun 2009 22:05:48 +0000 (22:05 -0000)
* aot-compiler.c: Emit sizes for most symbols, only emit runtime-invoke
wrappers into the mscorlib image, Emit a unique plt symbol for each
image, emit symbols for plt entries.

* image-writer.c (img_writer_emit_symbol_size): New function to emit
a .size directive.

svn path=/trunk/mono/; revision=136557

mono/mini/ChangeLog
mono/mini/aot-compiler.c
mono/mini/image-writer.c
mono/mini/image-writer.h

index 12d11277e0fbfda4bc3c41879d029d0c1223669b..cb59bc4812f06411f0acbc000629461bb99cc8d8 100644 (file)
@@ -1,3 +1,12 @@
+2009-06-21  Zoltan Varga  <vargaz@gmail.com>
+
+       * aot-compiler.c: Emit sizes for most symbols, only emit runtime-invoke
+       wrappers into the mscorlib image, Emit a unique plt symbol for each
+       image, emit symbols for plt entries.
+
+       * image-writer.c (img_writer_emit_symbol_size): New function to emit
+       a .size directive.
+       
 2009-06-20  Zoltan Varga  <vargaz@gmail.com>
 
        * aot-compiler.c (add_wrappers): Avoid calling 
index ebe23401849a7fca42bc81d8381cd93326474982..e5c080a31a2001487cbd10491c38951c7b5c5464 100644 (file)
@@ -156,6 +156,7 @@ typedef struct MonoAotCompile {
        GPtrArray *unwind_ops;
        guint32 unwind_info_offset;
        char *got_symbol;
+       char *plt_symbol;
        GHashTable *method_label_hash;
        const char *temp_prefix;
        guint32 label_generator;
@@ -319,6 +320,12 @@ emit_global (MonoAotCompile *acfg, const char *name, gboolean func)
        }
 }
 
+static void
+emit_symbol_size (MonoAotCompile *acfg, const char *name, const char *end_label)
+{
+       img_writer_emit_symbol_size (acfg->w, name, end_label);
+}
+
 static void
 emit_string_symbol (MonoAotCompile *acfg, const char *name, const char *value)
 {
@@ -602,7 +609,7 @@ arch_emit_plt_entry (MonoAotCompile *acfg, int index)
                } else {
                        /* Need to make sure this is 9 bytes long */
                        emit_byte (acfg, '\xe9');
-                       emit_symbol_diff (acfg, "plt", ".", -4);
+                       emit_symbol_diff (acfg, acfg->plt_symbol, ".", -4);
                        emit_int32 (acfg, acfg->plt_got_info_offsets [index]);
                }
 #elif defined(TARGET_AMD64)
@@ -1710,62 +1717,6 @@ add_wrappers (MonoAotCompile *acfg)
         * names.
         */
 
-       /* FIXME: Collect these automatically */
-
-       /* Runtime invoke wrappers */
-
-       /* void runtime-invoke () [.cctor] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
-       csig->ret = &mono_defaults.void_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* void runtime-invoke () [Finalize] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
-       csig->hasthis = 1;
-       csig->ret = &mono_defaults.void_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* void runtime-invoke (string) [exception ctor] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
-       csig->hasthis = 1;
-       csig->ret = &mono_defaults.void_class->byval_arg;
-       csig->params [0] = &mono_defaults.string_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* void runtime-invoke (string, string) [exception ctor] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
-       csig->hasthis = 1;
-       csig->ret = &mono_defaults.void_class->byval_arg;
-       csig->params [0] = &mono_defaults.string_class->byval_arg;
-       csig->params [1] = &mono_defaults.string_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* string runtime-invoke () [Exception.ToString ()] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
-       csig->hasthis = 1;
-       csig->ret = &mono_defaults.string_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* void runtime-invoke (string, Exception) [exception ctor] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
-       csig->hasthis = 1;
-       csig->ret = &mono_defaults.void_class->byval_arg;
-       csig->params [0] = &mono_defaults.string_class->byval_arg;
-       csig->params [1] = &mono_defaults.exception_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* Assembly runtime-invoke (string, bool) [DoAssemblyResolve] */
-       csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
-       csig->hasthis = 1;
-       csig->ret = &(mono_class_from_name (
-                                                                               mono_defaults.corlib, "System.Reflection", "Assembly"))->byval_arg;
-       csig->params [0] = &mono_defaults.string_class->byval_arg;
-       csig->params [1] = &mono_defaults.boolean_class->byval_arg;
-       add_method (acfg, get_runtime_invoke_sig (csig));
-
-       /* runtime-invoke used by finalizers */
-       add_method (acfg, mono_marshal_get_runtime_invoke (mono_class_get_method_from_name_flags (mono_defaults.object_class, "Finalize", 0, 0), TRUE));
-
        for (i = 0; i < acfg->image->tables [MONO_TABLE_METHOD].rows; ++i) {
                MonoMethod *method;
                guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1);
@@ -1800,6 +1751,60 @@ add_wrappers (MonoAotCompile *acfg)
                MonoMethodDesc *desc;
                MonoMethod *orig_method;
 
+               /* Runtime invoke wrappers */
+
+               /* void runtime-invoke () [.cctor] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
+               csig->ret = &mono_defaults.void_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* void runtime-invoke () [Finalize] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
+               csig->hasthis = 1;
+               csig->ret = &mono_defaults.void_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* void runtime-invoke (string) [exception ctor] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
+               csig->hasthis = 1;
+               csig->ret = &mono_defaults.void_class->byval_arg;
+               csig->params [0] = &mono_defaults.string_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* void runtime-invoke (string, string) [exception ctor] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
+               csig->hasthis = 1;
+               csig->ret = &mono_defaults.void_class->byval_arg;
+               csig->params [0] = &mono_defaults.string_class->byval_arg;
+               csig->params [1] = &mono_defaults.string_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* string runtime-invoke () [Exception.ToString ()] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
+               csig->hasthis = 1;
+               csig->ret = &mono_defaults.string_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* void runtime-invoke (string, Exception) [exception ctor] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
+               csig->hasthis = 1;
+               csig->ret = &mono_defaults.void_class->byval_arg;
+               csig->params [0] = &mono_defaults.string_class->byval_arg;
+               csig->params [1] = &mono_defaults.exception_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* Assembly runtime-invoke (string, bool) [DoAssemblyResolve] */
+               csig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
+               csig->hasthis = 1;
+               csig->ret = &(mono_class_from_name (
+                                                                                       mono_defaults.corlib, "System.Reflection", "Assembly"))->byval_arg;
+               csig->params [0] = &mono_defaults.string_class->byval_arg;
+               csig->params [1] = &mono_defaults.boolean_class->byval_arg;
+               add_method (acfg, get_runtime_invoke_sig (csig));
+
+               /* runtime-invoke used by finalizers */
+               add_method (acfg, mono_marshal_get_runtime_invoke (mono_class_get_method_from_name_flags (mono_defaults.object_class, "Finalize", 0, 0), TRUE));
+
                /* JIT icall wrappers */
                /* FIXME: locking */
                g_hash_table_foreach (mono_get_jit_icall_info (), add_jit_icall_wrapper, acfg);
@@ -2271,12 +2276,52 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui
        }
 }
 
+static char*
+get_debug_sym (MonoMethod *method, const char *prefix, GHashTable *cache)
+{
+       char *name1, *name2, *cached;
+       int i, j, len, count;
+               
+       name1 = mono_method_full_name (method, TRUE);
+       len = strlen (name1);
+       name2 = malloc (strlen (prefix) + len + 16);
+       memcpy (name2, prefix, strlen (prefix));
+       j = strlen (prefix);
+       for (i = 0; i < len; ++i) {
+               if (isalnum (name1 [i])) {
+                       name2 [j ++] = name1 [i];
+               } else if (name1 [i] == ' ' && name1 [i + 1] == '(' && name1 [i + 2] == ')') {
+                       i += 2;
+               } else if (name1 [i] == ',' && name1 [i + 1] == ' ') {
+                       name2 [j ++] = '_';
+                       i++;
+               } else if (name1 [i] == '(' || name1 [i] == ')' || name1 [i] == '>') {
+               } else
+                       name2 [j ++] = '_';
+       }
+       name2 [j] = '\0';
+
+       g_free (name1);
+
+       count = 0;
+       while (g_hash_table_lookup (cache, name2)) {
+               sprintf (name2 + j, "_%d", count);
+               count ++;
+       }
+
+       cached = g_strdup (name2);
+       g_hash_table_insert (cache, cached, cached);
+
+       return name2;
+}
+
 static void
 emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg)
 {
        MonoMethod *method;
        int method_index;
        guint8 *code;
+       char *debug_sym = NULL;
        char symbol [128];
        int func_alignment = AOT_FUNC_ALIGNMENT;
        MonoMethodHeader *header;
@@ -2314,47 +2359,17 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg)
        emit_label (acfg, symbol);
 
        if (acfg->aot_opts.write_symbols) {
-               char *name1, *name2, *cached;
-               int i, j, len, count;
-
                /* 
                 * Write a C style symbol for every method, this has two uses:
                 * - it works on platforms where the dwarf debugging info is not
                 *   yet supported.
                 * - it allows the setting of breakpoints of aot-ed methods.
                 */
-               name1 = mono_method_full_name (method, TRUE);
-               len = strlen (name1);
-               name2 = malloc (len + 1);
-               j = 0;
-               for (i = 0; i < len; ++i) {
-                       if (isalnum (name1 [i])) {
-                               name2 [j ++] = name1 [i];
-                       } else if (name1 [i] == ' ' && name1 [i + 1] == '(' && name1 [i + 2] == ')') {
-                               i += 2;
-                       } else if (name1 [i] == ',' && name1 [i + 1] == ' ') {
-                               name2 [j ++] = '_';
-                               i++;
-                       } else if (name1 [i] == '(' || name1 [i] == ')' || name1 [i] == '>') {
-                       } else
-                               name2 [j ++] = '_';
-               }
-               name2 [j] = '\0';
-
-               count = 0;
-               while (g_hash_table_lookup (acfg->method_label_hash, name2)) {
-                       sprintf (name2 + j, "_%d", count);
-                       count ++;
-               }
-
-               cached = g_strdup (name2);
-               g_hash_table_insert (acfg->method_label_hash, cached, cached);
+               debug_sym = get_debug_sym (method, "", acfg->method_label_hash);
 
                sprintf (symbol, "%sme_%x", acfg->temp_prefix, method_index);
-               emit_local_symbol (acfg, name2, symbol, TRUE);
-               emit_label (acfg, name2);
-               g_free (name1);
-               g_free (name2);
+               emit_local_symbol (acfg, debug_sym, symbol, TRUE);
+               emit_label (acfg, debug_sym);
        }
 
        if (cfg->verbose_level > 0)
@@ -2368,6 +2383,11 @@ emit_method_code (MonoAotCompile *acfg, MonoCompile *cfg)
 
        emit_line (acfg);
 
+       if (acfg->aot_opts.write_symbols) {
+               emit_symbol_size (acfg, debug_sym, ".");
+               g_free (debug_sym);
+       }
+
        sprintf (symbol, "%sme_%x", acfg->temp_prefix, method_index);
        emit_label (acfg, symbol);
 }
@@ -2843,6 +2863,9 @@ emit_plt (MonoAotCompile *acfg)
 {
        char symbol [128];
        int i;
+       GHashTable *cache;
+
+       cache = g_hash_table_new (g_str_hash, g_str_equal);
 
        emit_line (acfg);
        sprintf (symbol, "plt");
@@ -2856,28 +2879,51 @@ emit_plt (MonoAotCompile *acfg)
        emit_alignment (acfg, 16);
 #endif
        emit_label (acfg, symbol);
+       emit_label (acfg, acfg->plt_symbol);
 
        for (i = 0; i < acfg->plt_offset; ++i) {
                char label [128];
+               char *debug_sym = NULL;
 
                sprintf (label, "%sp_%d", acfg->temp_prefix, i);
                emit_label (acfg, label);
 
+               if (acfg->aot_opts.write_symbols) {
+                       MonoJumpInfo *patch_info = g_hash_table_lookup (acfg->plt_offset_to_patch, GUINT_TO_POINTER (i));
+
+                       if (patch_info && patch_info->type == MONO_PATCH_INFO_METHOD) {
+                               char *debug_sym = get_debug_sym (patch_info->data.method, "plt_", cache);
+
+                               emit_local_symbol (acfg, debug_sym, NULL, TRUE);
+                               emit_label (acfg, debug_sym);
+                       }
+               }
+
                /* 
                 * The first plt entry is used to transfer code to the AOT loader. 
                 */
                arch_emit_plt_entry (acfg, i);
+
+               if (debug_sym) {
+                       emit_symbol_size (acfg, debug_sym, ".");
+                       g_free (debug_sym);
+               }
        }
 
+       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);
 }
 
 static G_GNUC_UNUSED void
 emit_trampoline (MonoAotCompile *acfg, const char *name, guint8 *code, 
                                 guint32 code_size, int got_offset, MonoJumpInfo *ji, GSList *unwind_ops)
 {
+       char start_symbol [256];
        char symbol [256];
        guint32 buf_size;
        MonoJumpInfo *patch_info;
@@ -2886,12 +2932,12 @@ emit_trampoline (MonoAotCompile *acfg, const char *name, guint8 *code,
 
        /* Emit code */
 
-       sprintf (symbol, "%s", name);
+       sprintf (start_symbol, "%s", name);
 
        emit_section_change (acfg, ".text", 0);
-       emit_global (acfg, symbol, TRUE);
+       emit_global (acfg, start_symbol, TRUE);
        emit_alignment (acfg, 16);
-       emit_label (acfg, symbol);
+       emit_label (acfg, start_symbol);
 
        sprintf (symbol, "%snamed_%s", acfg->temp_prefix, name);
        emit_label (acfg, symbol);
@@ -2902,6 +2948,8 @@ emit_trampoline (MonoAotCompile *acfg, const char *name, guint8 *code,
         */
        emit_and_reloc_code (acfg, NULL, code, code_size, ji, TRUE);
 
+       emit_symbol_size (acfg, start_symbol, ".");
+
        /* Emit info */
 
        /* Sort relocations */
@@ -4867,6 +4915,8 @@ acfg_free (MonoAotCompile *acfg)
                        g_free (acfg->cfgs [i]);
        g_free (acfg->cfgs);
        g_free (acfg->static_linking_symbol);
+       g_free (acfg->got_symbol);
+       g_free (acfg->plt_symbol);
        g_ptr_array_free (acfg->methods, TRUE);
        g_ptr_array_free (acfg->got_patches, TRUE);
        g_ptr_array_free (acfg->image_table, TRUE);
@@ -4926,6 +4976,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        acfg->num_trampolines [MONO_AOT_TRAMP_IMT_THUNK] = acfg->aot_opts.full_aot ? 128 : 0;
 
        acfg->got_symbol = g_strdup_printf ("mono_aot_%s_got", acfg->image->assembly->aname.name);
+       acfg->plt_symbol = g_strdup_printf ("mono_aot_%s_plt", acfg->image->assembly->aname.name);
 
        /* Get rid of characters which cannot occur in symbols */
        p = acfg->got_symbol;
index ba2ccff8c3a4735db9c6c9e30ba116893b13d79e..9fcbd03b6f3912dde0156b01b0a04fe6de72ed98 100644 (file)
@@ -1504,6 +1504,16 @@ asm_writer_emit_local_symbol (MonoImageWriter *acfg, const char *name, const cha
        asm_writer_emit_symbol_type (acfg, name, func);
 }
 
+static void
+asm_writer_emit_symbol_size (MonoImageWriter *acfg, const char *name, const char *end_label)
+{
+       asm_writer_emit_unset_mode (acfg);
+
+#ifndef TARGET_ASM_APPLE
+       fprintf (acfg->fp, "\t.size %s,%s-%s\n", name, end_label, name);
+#endif
+}
+
 static void
 asm_writer_emit_label (MonoImageWriter *acfg, const char *name)
 {
@@ -1747,6 +1757,13 @@ img_writer_emit_local_symbol (MonoImageWriter *acfg, const char *name, const cha
 #endif
 }
 
+void
+img_writer_emit_symbol_size (MonoImageWriter *acfg, const char *name, const char *end_label)
+{
+       if (!acfg->use_bin_writer)
+               asm_writer_emit_symbol_size (acfg, name, end_label);
+}
+
 void
 img_writer_emit_label (MonoImageWriter *acfg, const char *name)
 {
index d7e99b415620ef8889342b7067c523ae551befd1..01a2d1853dd737c64e350bee0f0621e4e3460168 100644 (file)
@@ -46,6 +46,8 @@ void img_writer_emit_global (MonoImageWriter *w, const char *name, gboolean func
 
 void img_writer_emit_local_symbol (MonoImageWriter *w, const char *name, const char *end_label, gboolean func) MONO_INTERNAL;
 
+void img_writer_emit_symbol_size (MonoImageWriter *w, const char *start, const char *end_label);
+
 void img_writer_emit_label (MonoImageWriter *w, const char *name) MONO_INTERNAL;
 
 void img_writer_emit_bytes (MonoImageWriter *w, const guint8* buf, int size) MONO_INTERNAL;