X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=87d58290d812887d0936302d97e708acad7da54a;hb=cadf391beab4c0d0c4aada7acb8fcb7c2e702e87;hp=76adac07895b888867a6e4dd680952b838894803;hpb=977199d9e26d135f7db4daf1143bab777724ef60;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 76adac07895..87d58290d81 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include "mini.h" @@ -95,112 +96,9 @@ MonoBackend *current_backend; gpointer mono_realloc_native_code (MonoCompile *cfg) { -#if defined(__default_codegen__) return g_realloc (cfg->native_code, cfg->code_size); -#elif defined(__native_client_codegen__) - guint old_padding; - gpointer native_code; - guint alignment_check; - - /* Save the old alignment offset so we can re-align after the realloc. */ - old_padding = (guint)(cfg->native_code - cfg->native_code_alloc); - cfg->code_size = NACL_BUNDLE_ALIGN_UP (cfg->code_size); - - cfg->native_code_alloc = g_realloc ( cfg->native_code_alloc, - cfg->code_size + kNaClAlignment ); - - /* Align native_code to next nearest kNaClAlignment byte. */ - native_code = (guint)cfg->native_code_alloc + kNaClAlignment; - native_code = (guint)native_code & ~kNaClAlignmentMask; - - /* Shift the data to be 32-byte aligned again. */ - memmove (native_code, cfg->native_code_alloc + old_padding, cfg->code_size); - - alignment_check = (guint)native_code & kNaClAlignmentMask; - g_assert (alignment_check == 0); - return native_code; -#else - g_assert_not_reached (); - return cfg->native_code; -#endif -} - -#ifdef __native_client_codegen__ - -/* Prevent instructions from straddling a 32-byte alignment boundary. */ -/* Instructions longer than 32 bytes must be aligned internally. */ -/* IN: pcode, instlen */ -/* OUT: pcode */ -void mono_nacl_align_inst(guint8 **pcode, int instlen) { - int space_in_block; - - space_in_block = kNaClAlignment - ((uintptr_t)(*pcode) & kNaClAlignmentMask); - - if (G_UNLIKELY (instlen >= kNaClAlignment)) { - g_assert_not_reached(); - } else if (instlen > space_in_block) { - *pcode = mono_arch_nacl_pad(*pcode, space_in_block); - } -} - -/* Move emitted call sequence to the end of a kNaClAlignment-byte block. */ -/* IN: start pointer to start of call sequence */ -/* IN: pcode pointer to end of call sequence (current "IP") */ -/* OUT: start pointer to the start of the call sequence after padding */ -/* OUT: pcode pointer to the end of the call sequence after padding */ -void mono_nacl_align_call(guint8 **start, guint8 **pcode) { - const size_t MAX_NACL_CALL_LENGTH = kNaClAlignment; - guint8 copy_of_call[MAX_NACL_CALL_LENGTH]; - guint8 *temp; - - const size_t length = (size_t)((*pcode)-(*start)); - g_assert(length < MAX_NACL_CALL_LENGTH); - - memcpy(copy_of_call, *start, length); - temp = mono_nacl_pad_call(*start, (guint8)length); - memcpy(temp, copy_of_call, length); - (*start) = temp; - (*pcode) = temp + length; -} - -/* mono_nacl_pad_call(): Insert padding for Native Client call instructions */ -/* code pointer to buffer for emitting code */ -/* ilength length of call instruction */ -guint8 *mono_nacl_pad_call(guint8 *code, guint8 ilength) { - int freeSpaceInBlock = kNaClAlignment - ((uintptr_t)code & kNaClAlignmentMask); - int padding = freeSpaceInBlock - ilength; - - if (padding < 0) { - /* There isn't enough space in this block for the instruction. */ - /* Fill this block and start a new one. */ - code = mono_arch_nacl_pad(code, freeSpaceInBlock); - freeSpaceInBlock = kNaClAlignment; - padding = freeSpaceInBlock - ilength; - } - g_assert(ilength > 0); - g_assert(padding >= 0); - g_assert(padding < kNaClAlignment); - if (0 == padding) return code; - return mono_arch_nacl_pad(code, padding); } -guint8 *mono_nacl_align(guint8 *code) { - int padding = kNaClAlignment - ((uintptr_t)code & kNaClAlignmentMask); - if (padding != kNaClAlignment) code = mono_arch_nacl_pad(code, padding); - return code; -} - -void mono_nacl_fix_patches(const guint8 *code, MonoJumpInfo *ji) -{ - MonoJumpInfo *patch_info; - for (patch_info = ji; patch_info; patch_info = patch_info->next) { - unsigned char *ip = patch_info->ip.i + code; - ip = mono_arch_nacl_skip_nops(ip); - patch_info->ip.i = ip - code; - } -} -#endif /* __native_client_codegen__ */ - typedef struct { MonoExceptionClause *clause; MonoBasicBlock *basic_block; @@ -2330,12 +2228,6 @@ mono_postprocess_patches (MonoCompile *cfg) MonoJumpList *jlist; MonoDomain *domain = cfg->domain; unsigned char *ip = cfg->native_code + patch_info->ip.i; -#if defined(__native_client__) && defined(__native_client_codegen__) - /* When this jump target gets evaluated, the method */ - /* will be installed in the dynamic code section, */ - /* not at the location of cfg->native_code. */ - ip = nacl_inverse_modify_patch_target (cfg->native_code) + patch_info->ip.i; -#endif mono_domain_lock (domain); jlist = (MonoJumpList *)g_hash_table_lookup (domain_jit_info (domain)->jump_target_hash, patch_info->data.method); @@ -2373,15 +2265,6 @@ mono_codegen (MonoCompile *cfg) else code_domain = cfg->domain; -#if defined(__native_client_codegen__) && defined(__native_client__) - void *code_dest; - - /* This keeps patch targets from being transformed during - * ordinary method compilation, for local branches and jumps. - */ - nacl_allow_target_modification (FALSE); -#endif - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { cfg->spill_count = 0; /* we reuse dfn here */ @@ -2428,18 +2311,13 @@ mono_codegen (MonoCompile *cfg) } } -#ifdef __native_client_codegen__ - mono_nacl_fix_patches (cfg->native_code, cfg->patch_info); -#endif mono_arch_emit_exceptions (cfg); max_epilog_size = 0; /* we always allocate code in cfg->domain->code_mp to increase locality */ cfg->code_size = cfg->code_len + max_epilog_size; -#ifdef __native_client_codegen__ - cfg->code_size = NACL_BUNDLE_ALIGN_UP (cfg->code_size); -#endif + /* fixme: align to MONO_ARCH_CODE_ALIGNMENT */ #ifdef MONO_ARCH_HAVE_UNWIND_TABLE @@ -2462,9 +2340,7 @@ mono_codegen (MonoCompile *cfg) } else { code = (guint8 *)mono_domain_code_reserve (code_domain, cfg->code_size + cfg->thunk_area + unwindlen); } -#if defined(__native_client_codegen__) && defined(__native_client__) - nacl_allow_target_modification (TRUE); -#endif + if (cfg->thunk_area) { cfg->thunks_offset = cfg->code_size + unwindlen; cfg->thunks = code + cfg->thunks_offset; @@ -2473,17 +2349,7 @@ mono_codegen (MonoCompile *cfg) g_assert (code); memcpy (code, cfg->native_code, cfg->code_len); -#if defined(__default_codegen__) g_free (cfg->native_code); -#elif defined(__native_client_codegen__) - if (cfg->native_code_alloc) { - g_free (cfg->native_code_alloc); - cfg->native_code_alloc = 0; - } - else if (cfg->native_code) { - g_free (cfg->native_code); - } -#endif /* __native_client_codegen__ */ cfg->native_code = code; code = cfg->native_code + cfg->code_len; @@ -2525,20 +2391,6 @@ mono_codegen (MonoCompile *cfg) mono_arch_save_unwind_info (cfg); #endif -#if defined(__native_client_codegen__) && defined(__native_client__) - if (!cfg->compile_aot) { - if (cfg->method->dynamic) { - code_dest = nacl_code_manager_get_code_dest(cfg->dynamic_info->code_mp, cfg->native_code); - } else { - code_dest = nacl_domain_get_code_dest(cfg->domain, cfg->native_code); - } - } -#endif - -#if defined(__native_client_codegen__) - mono_nacl_fix_patches (cfg->native_code, cfg->patch_info); -#endif - #ifdef MONO_ARCH_HAVE_PATCH_CODE_NEW { MonoJumpInfo *ji; @@ -2568,7 +2420,11 @@ mono_codegen (MonoCompile *cfg) } } #else - mono_arch_patch_code (cfg, cfg->method, cfg->domain, cfg->native_code, cfg->patch_info, cfg->run_cctors); + mono_arch_patch_code (cfg, cfg->method, cfg->domain, cfg->native_code, cfg->patch_info, cfg->run_cctors, &cfg->error); + if (!is_ok (&cfg->error)) { + mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); + return; + } #endif if (cfg->method->dynamic) { @@ -3040,6 +2896,17 @@ is_open_method (MonoMethod *method) return FALSE; } +static void mono_insert_nop_in_empty_bb (MonoCompile *cfg) +{ + MonoBasicBlock *bb; + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { + if (bb->code) + continue; + MonoInst *nop; + MONO_INST_NEW (cfg, nop, OP_NOP); + MONO_ADD_INS (bb, nop); + } +} static void mono_create_gc_safepoint (MonoCompile *cfg, MonoBasicBlock *bblock) { @@ -3643,6 +3510,12 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl MONO_TIME_TRACK (mono_jit_stats.jit_method_to_ir, i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, 0, FALSE)); mono_cfg_dump_ir (cfg, "method-to-ir"); + if (cfg->gdump_ctx != NULL) { + /* workaround for graph visualization, as it doesn't handle empty basic blocks properly */ + mono_insert_nop_in_empty_bb (cfg); + mono_cfg_dump_ir (cfg, "mono_insert_nop_in_empty_bb"); + } + if (i < 0) { if (try_generic_shared && cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) { if (compile_aot) { @@ -3721,6 +3594,15 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl mono_cfg_dump_ir (cfg, "local_cprop"); } + if (cfg->flags & MONO_CFG_HAS_TYPE_CHECK) { + MONO_TIME_TRACK (mono_jit_stats.jit_decompose_typechecks, mono_decompose_typechecks (cfg)); + if (cfg->gdump_ctx != NULL) { + /* workaround for graph visualization, as it doesn't handle empty basic blocks properly */ + mono_insert_nop_in_empty_bb (cfg); + } + mono_cfg_dump_ir (cfg, "decompose_typechecks"); + } + /* * Should be done after cprop which can do strength reduction on * some of these ops, after propagating immediates. @@ -4216,7 +4098,9 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in mono_lookup_pinvoke_call (method, NULL, NULL); } nm = mono_marshal_get_native_wrapper (method, TRUE, mono_aot_only); - code = mono_get_addr_from_ftnptr (mono_compile_method (nm)); + gpointer compiled_method = mono_compile_method_checked (nm, error); + return_val_if_nok (error, NULL); + code = mono_get_addr_from_ftnptr (compiled_method); jinfo = mono_jit_info_table_find (target_domain, (char *)code); if (!jinfo) jinfo = mono_jit_info_table_find (mono_domain_get (), (char *)code); @@ -4230,7 +4114,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in if (method->klass->parent == mono_defaults.multicastdelegate_class) { if (*name == '.' && (strcmp (name, ".ctor") == 0)) { - MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("mono_delegate_ctor"); + MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("ves_icall_mono_delegate_ctor"); g_assert (mi); /* * We need to make sure this wrapper @@ -4246,15 +4130,21 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in } else if (*name == 'I' && (strcmp (name, "Invoke") == 0)) { if (mono_llvm_only) { nm = mono_marshal_get_delegate_invoke (method, NULL); - return mono_get_addr_from_ftnptr (mono_compile_method (nm)); + gpointer compiled_ptr = mono_compile_method_checked (nm, error); + mono_error_assert_ok (error); + return mono_get_addr_from_ftnptr (compiled_ptr); } return mono_create_delegate_trampoline (target_domain, method->klass); } else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0)) { nm = mono_marshal_get_delegate_begin_invoke (method); - return mono_get_addr_from_ftnptr (mono_compile_method (nm)); + gpointer compiled_ptr = mono_compile_method_checked (nm, error); + mono_error_assert_ok (error); + return mono_get_addr_from_ftnptr (compiled_ptr); } else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0)) { nm = mono_marshal_get_delegate_end_invoke (method); - return mono_get_addr_from_ftnptr (mono_compile_method (nm)); + gpointer compiled_ptr = mono_compile_method_checked (nm, error); + mono_error_assert_ok (error); + return mono_get_addr_from_ftnptr (compiled_ptr); } } @@ -4424,10 +4314,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in patch_info.data.method = method; g_hash_table_remove (domain_jit_info (target_domain)->jump_target_hash, method); -#if defined(__native_client_codegen__) && defined(__native_client__) - /* These patches are applied after a method has been installed, no target munging is needed. */ - nacl_allow_target_modification (FALSE); -#endif #ifdef MONO_ARCH_HAVE_PATCH_CODE_NEW for (tmp = jlist->list; tmp; tmp = tmp->next) { gpointer target = mono_resolve_patch_target (NULL, target_domain, (guint8 *)tmp->data, &patch_info, TRUE, error); @@ -4436,11 +4322,11 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in mono_arch_patch_code_new (NULL, target_domain, (guint8 *)tmp->data, &patch_info, target); } #else - for (tmp = jlist->list; tmp; tmp = tmp->next) - mono_arch_patch_code (NULL, NULL, target_domain, tmp->data, &patch_info, TRUE); -#endif -#if defined(__native_client_codegen__) && defined(__native_client__) - nacl_allow_target_modification (TRUE); + for (tmp = jlist->list; tmp; tmp = tmp->next) { + mono_arch_patch_code (NULL, NULL, target_domain, tmp->data, &patch_info, TRUE, error); + if (!is_ok (error)) + break; + } #endif } }