X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Faot-compiler.c;h=deaac7afec024e171c19ade086218cb322b05b53;hb=bfb5185aabc1e197f35e9d9b2d03a657cc41be51;hp=ab59c11c3652001b10b56d5fae86d392a7a6a075;hpb=6c4bc5f9d7d8ab7d4baa7a3a09b9b68c921d2630;p=mono.git diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index ab59c11c365..deaac7afec0 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -10,17 +10,6 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) */ -/* Remaining AOT-only work: - * - optimize the trampolines, generate more code in the arch files. - * - make things more consistent with how elf works, for example, use ELF - * relocations. - * Remaining generics sharing work: - * - optimize the size of the data which is encoded. - * - optimize the runtime loading of data: - * - the trampoline code calls mono_jit_info_table_find () to find the rgctx, - * which loads the debugging+exception handling info for the method. This is a - * huge waste of time and code, since the rgctx structure is currently empty. - */ #include "config.h" #include #ifdef HAVE_UNISTD_H @@ -42,7 +31,6 @@ #include #include - #include #include #include @@ -64,6 +52,7 @@ #include #include "mini.h" +#include "seq-points.h" #include "image-writer.h" #include "dwarfwriter.h" #include "mini-gc.h" @@ -82,18 +71,6 @@ #define TV_GETTIME(tv) tv = mono_100ns_ticks () #define TV_ELAPSED(start,end) (((end) - (start)) / 10) -#ifdef TARGET_WIN32 -#define SHARED_EXT ".dll" -#elif defined(__ppc__) && defined(TARGET_MACH) -#define SHARED_EXT ".dylib" -#elif defined(TARGET_MACH) && defined(TARGET_X86) && !defined(__native_client_codegen__) -#define SHARED_EXT ".dylib" -#elif defined(TARGET_MACH) && defined(TARGET_AMD64) && !defined(__native_client_codegen__) -#define SHARED_EXT ".dylib" -#else -#define SHARED_EXT ".so" -#endif - #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)) @@ -1274,6 +1251,11 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg) g_assert (code - buf == 8); emit_bytes (acfg, buf, code - buf); } + + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_SPECIFIC] = 16; + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_STATIC_RGCTX] = 16; + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_IMT_THUNK] = 72; + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_GSHAREDVT_ARG] = 16; #elif defined(TARGET_ARM64) arm64_emit_specific_trampoline_pages (acfg); #endif @@ -1941,14 +1923,14 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size) code = buf; /* Load the mscorlib got address */ - ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r30); + ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r30); /* Load the parameter from the GOT */ ppc_load (code, ppc_r0, offset * sizeof (gpointer)); - ppc_ldptr_indexed (code, ppc_r11, ppc_r11, ppc_r0); + ppc_ldptr_indexed (code, ppc_r12, ppc_r12, ppc_r0); /* Load and check key */ labels [1] = code; - ppc_ldptr (code, ppc_r0, 0, ppc_r11); + ppc_ldptr (code, ppc_r0, 0, ppc_r12); ppc_cmp (code, 0, sizeof (gpointer) == 8 ? 1 : 0, ppc_r0, MONO_ARCH_IMT_REG); labels [2] = code; ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0); @@ -1959,18 +1941,18 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size) ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0); /* Loop footer */ - ppc_addi (code, ppc_r11, ppc_r11, 2 * sizeof (gpointer)); + ppc_addi (code, ppc_r12, ppc_r12, 2 * sizeof (gpointer)); labels [4] = code; ppc_b (code, 0); mono_ppc_patch (labels [4], labels [1]); /* Match */ mono_ppc_patch (labels [2], code); - ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r11); - /* r11 now contains the value of the vtable slot */ + ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r12); + /* r12 now contains the value of the vtable slot */ /* this is not a function descriptor on ppc64 */ - ppc_ldptr (code, ppc_r11, 0, ppc_r11); - ppc_mtctr (code, ppc_r11); + ppc_ldptr (code, ppc_r12, 0, ppc_r12); + ppc_mtctr (code, ppc_r12); ppc_bcctr (code, PPC_BR_ALWAYS, 0); /* Fail */ @@ -3371,8 +3353,9 @@ add_wrappers (MonoAotCompile *acfg) if (info && !has_nullable) { /* Supported by the dynamic runtime-invoke wrapper */ skip = TRUE; - g_free (info); } + if (info) + mono_arch_dyn_call_free (info); } #endif @@ -4878,13 +4861,14 @@ 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); + #ifdef TARGET_MACH // This is so that we don't accidentally create a local symbol (which starts with 'L') - if (!prefix || !*prefix) + if ((!prefix || !*prefix) && name1 [0] == 'L') prefix = "_"; #endif - name1 = mono_method_full_name (method, TRUE); len = strlen (name1); name2 = malloc (strlen (prefix) + len + 16); memcpy (name2, prefix, strlen (prefix)); @@ -5007,7 +4991,9 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint case MONO_PATCH_INFO_MSCORLIB_GOT_ADDR: case MONO_PATCH_INFO_JIT_TLS_ID: case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR: + break; case MONO_PATCH_INFO_CASTCLASS_CACHE: + encode_value (patch_info->data.index, p, &p); break; case MONO_PATCH_INFO_METHOD_REL: encode_value ((gint)patch_info->data.offset, p, &p); @@ -5337,7 +5323,7 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg) { MonoMethod *method; int i, k, buf_size, method_index; - guint32 debug_info_size; + guint32 debug_info_size, seq_points_size; guint8 *code; MonoMethodHeader *header; guint8 *p, *buf, *debug_info; @@ -5361,7 +5347,9 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg) seq_points = cfg->seq_point_info; - buf_size = header->num_clauses * 256 + debug_info_size + 2048 + (seq_points ? (seq_points->len * 128) : 0) + cfg->gc_map_size; + seq_points_size = (cfg->gen_seq_points)? seq_point_info_get_write_size (seq_points) : 0; + + buf_size = header->num_clauses * 256 + debug_info_size + 2048 + seq_points_size + cfg->gc_map_size; p = buf = g_malloc (buf_size); use_unwind_ops = cfg->unwind_ops != NULL; @@ -5389,6 +5377,15 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg) encode_value (table->num_holes, p, &p); } + if (jinfo->has_arch_eh_info) { + /* + * In AOT mode, the code length is calculated from the address of the previous method, + * which could include alignment padding, so calculating the start of the epilog as + * code_len - epilog_size is correct any more. Save the real code len as a workaround. + */ + encode_value (jinfo->code_size, p, &p); + } + /* Exception table */ if (cfg->compile_llvm) { /* @@ -5558,27 +5555,9 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg) } } - if (seq_points) { - int il_offset, native_offset, last_il_offset, last_native_offset, j; - - encode_value (seq_points->len, p, &p); - last_il_offset = last_native_offset = 0; - for (i = 0; i < seq_points->len; ++i) { - SeqPoint *sp = &seq_points->seq_points [i]; - il_offset = sp->il_offset; - native_offset = sp->native_offset; - encode_value (il_offset - last_il_offset, p, &p); - encode_value (native_offset - last_native_offset, p, &p); - last_il_offset = il_offset; - last_native_offset = native_offset; + if (seq_points) + p += seq_point_info_write (seq_points, p); - encode_value (sp->flags, p, &p); - encode_value (sp->next_len, p, &p); - for (j = 0; j < sp->next_len; ++j) - encode_value (sp->next [j], p, &p); - } - } - g_assert (debug_info_size < buf_size); encode_value (debug_info_size, p, &p); @@ -5773,41 +5752,16 @@ emit_plt (MonoAotCompile *acfg) plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i)); ji = plt_entry->ji; - if (acfg->llvm) { - /* - * If the target is directly callable, alias the plt symbol to point to - * the method code. - * FIXME: Use this to simplify emit_and_reloc_code (). - * FIXME: Avoid the got slot. - * FIXME: Add support to the binary writer. - */ - if (ji && is_direct_callable (acfg, NULL, ji) && !acfg->use_bin_writer) { - MonoCompile *callee_cfg = g_hash_table_lookup (acfg->method_to_cfg, ji->data.method); - - if (callee_cfg) { - if (acfg->thumb_mixed && !callee_cfg->compile_llvm) { - /* LLVM calls the PLT entries using bl, so emit a stub */ - emit_set_thumb_mode (acfg); - fprintf (acfg->fp, "\n.thumb_func\n"); - emit_label (acfg, plt_entry->llvm_symbol); - fprintf (acfg->fp, "bx pc\n"); - fprintf (acfg->fp, "nop\n"); - emit_set_arm_mode (acfg); - fprintf (acfg->fp, "b %s\n", callee_cfg->asm_symbol); - } else { - fprintf (acfg->fp, "\n.set %s, %s\n", plt_entry->llvm_symbol, callee_cfg->asm_symbol); - } - continue; - } - } - } - debug_sym = plt_entry->debug_sym; if (acfg->thumb_mixed && !plt_entry->jit_used) /* Emit only a thumb version */ continue; + /* Skip plt entries not actually called */ + if (!plt_entry->jit_used && !plt_entry->llvm_used) + continue; + if (acfg->llvm && !acfg->thumb_mixed) emit_label (acfg, plt_entry->llvm_symbol); @@ -5847,9 +5801,6 @@ emit_plt (MonoAotCompile *acfg) plt_entry = g_hash_table_lookup (acfg->plt_offset_to_entry, GUINT_TO_POINTER (i)); ji = plt_entry->ji; - if (ji && is_direct_callable (acfg, NULL, ji) && !acfg->use_bin_writer) - continue; - /* Skip plt entries not actually called by LLVM code */ if (!plt_entry->llvm_used) continue; @@ -6462,9 +6413,10 @@ add_token_info_hash (gpointer key, gpointer value, gpointer user_data) { MonoMethod *method = (MonoMethod*)key; MonoJumpInfoToken *ji = (MonoJumpInfoToken*)value; - MonoJumpInfoToken *new_ji = g_new0 (MonoJumpInfoToken, 1); MonoAotCompile *acfg = user_data; + MonoJumpInfoToken *new_ji; + new_ji = mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfoToken)); new_ji->image = ji->image; new_ji->token = ji->token; g_hash_table_insert (acfg->token_info_hash, method, new_ji); @@ -6683,6 +6635,8 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) mono_acfg_lock (acfg); g_hash_table_foreach (cfg->token_info_hash, add_token_info_hash, acfg); mono_acfg_unlock (acfg); + g_hash_table_destroy (cfg->token_info_hash); + cfg->token_info_hash = NULL; /* * Check for absolute addresses. @@ -7021,6 +6975,21 @@ mono_aot_get_method_name (MonoCompile *cfg) return get_debug_sym (cfg->orig_method, "", llvm_acfg->method_label_hash); } +gboolean +mono_aot_is_direct_callable (MonoJumpInfo *patch_info) +{ + return is_direct_callable (llvm_acfg, NULL, patch_info); +} + +void +mono_aot_mark_unused_llvm_plt_entry (MonoJumpInfo *patch_info) +{ + MonoPltEntry *plt_entry; + + plt_entry = get_plt_entry (llvm_acfg, patch_info); + plt_entry->llvm_used = FALSE; +} + char* mono_aot_get_plt_symbol (MonoJumpInfoType type, gconstpointer data) { @@ -7116,7 +7085,7 @@ emit_llvm_file (MonoAotCompile *acfg) tempbc = g_strdup_printf ("%s.bc", acfg->tmpbasename); - mono_llvm_emit_aot_module (tempbc, acfg->final_got_size); + mono_llvm_emit_aot_module (tempbc, g_path_get_basename (acfg->image->name), acfg->final_got_size); g_free (tempbc); /* @@ -8654,7 +8623,7 @@ compile_asm (MonoAotCompile *acfg) if (acfg->aot_opts.outfile) outfile_name = g_strdup_printf ("%s", acfg->aot_opts.outfile); else - outfile_name = g_strdup_printf ("%s%s", acfg->image->name, SHARED_EXT); + outfile_name = g_strdup_printf ("%s%s", acfg->image->name, MONO_SOLIB_EXT); tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name); @@ -8674,7 +8643,7 @@ compile_asm (MonoAotCompile *acfg) g_free (command); - /*com = g_strdup_printf ("strip --strip-unneeded %s%s", acfg->image->name, SHARED_EXT); + /*com = g_strdup_printf ("strip --strip-unneeded %s%s", acfg->image->name, MONO_SOLIB_EXT); printf ("Stripping the binary: %s\n", com); system (com); g_free (com);*/ @@ -8739,7 +8708,7 @@ acfg_create (MonoAssembly *ass, guint32 opts) acfg->patch_to_got_offset_by_type [i] = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal); acfg->got_patches = g_ptr_array_new (); acfg->method_to_cfg = g_hash_table_new (NULL, NULL); - acfg->token_info_hash = g_hash_table_new_full (NULL, NULL, NULL, g_free); + acfg->token_info_hash = g_hash_table_new_full (NULL, NULL, NULL, NULL); acfg->method_to_pinvoke_import = g_hash_table_new_full (NULL, NULL, NULL, g_free); acfg->image_hash = g_hash_table_new (NULL, NULL); acfg->image_table = g_ptr_array_new (); @@ -8871,7 +8840,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) MonoDebugOptions *opt = mini_get_debug_options (); opt->mdb_optimizations = TRUE; - opt->gen_seq_points = TRUE; + opt->gen_seq_points_debug_data = TRUE; if (!mono_debug_enabled ()) { aot_printerrf (acfg, "The soft-debug AOT option requires the --debug option.\n"); @@ -9025,7 +8994,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) if (acfg->aot_opts.outfile) outfile_name = g_strdup_printf ("%s", acfg->aot_opts.outfile); else - outfile_name = g_strdup_printf ("%s%s", acfg->image->name, SHARED_EXT); + outfile_name = g_strdup_printf ("%s%s", acfg->image->name, MONO_SOLIB_EXT); /* * Can't use g_file_open_tmp () as it will be deleted at exit, and