X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-x86.c;h=75a6a7a24ad36c4a9a0a6749dc65e8949c692720;hb=7f23a0c1f3b357cea793f429b52a918f45157855;hp=149e48a8a52731290d418066293418463b3376a3;hpb=3a0faf0d72dfe90cde98a46b267a2b380a244b8e;p=mono.git diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index 149e48a8a52..75a6a7a24ad 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -582,7 +582,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign * FIXME: The metadata calls might not be signal safe. */ int -mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) +mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) { int len, k, args_size = 0; int size, pad; @@ -595,7 +595,7 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit cinfo = (CallInfo*)g_newa (guint8*, len); memset (cinfo, 0, len); - cinfo = get_call_info_internal (NULL, cinfo, csig); + cinfo = get_call_info_internal (gsctx, cinfo, csig); arg_info [0].offset = offset; @@ -801,6 +801,10 @@ mono_arch_init (void) void mono_arch_cleanup (void) { + if (ss_trigger_page) + mono_vfree (ss_trigger_page, mono_pagesize ()); + if (bp_trigger_page) + mono_vfree (bp_trigger_page, mono_pagesize ()); DeleteCriticalSection (&mini_arch_mutex); } @@ -808,7 +812,7 @@ mono_arch_cleanup (void) * This function returns the optimizations supported on this cpu. */ guint32 -mono_arch_cpu_optimizazions (guint32 *exclude_mask) +mono_arch_cpu_optimizations (guint32 *exclude_mask) { #if !defined(__native_client__) int eax, ebx, ecx, edx; @@ -1245,6 +1249,8 @@ mono_arch_create_vars (MonoCompile *cfg) if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig->ret)) { cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG); } + + cfg->arch_eh_jit_info = 1; } /* @@ -1278,9 +1284,7 @@ static void emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) { MonoMethodSignature *tmp_sig; - - /* FIXME: Add support for signature tokens to AOT */ - cfg->disable_aot = TRUE; + int sig_reg; /* * mono_ArgIterator_Setup assumes the signature cookie is @@ -1293,7 +1297,13 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) tmp_sig->sentinelpos = 0; memcpy (tmp_sig->params, call->signature->params + call->signature->sentinelpos, tmp_sig->param_count * sizeof (MonoType*)); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig); + if (cfg->compile_aot) { + sig_reg = mono_alloc_ireg (cfg); + MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig); + MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg); + } else { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig); + } } #ifdef ENABLE_LLVM @@ -1475,7 +1485,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) /* Arguments are pushed in the reverse order */ for (i = n - 1; i >= 0; i --) { ArgInfo *ainfo = cinfo->args + i; - MonoType *t; + MonoType *orig_type, *t; int argsize; if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 1 && i == 0) { @@ -1493,6 +1503,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) t = sig->params [i - sig->hasthis]; else t = &mono_defaults.int_class->byval_arg; + orig_type = t; t = mini_type_get_underlying_type (cfg->generic_sharing_context, t); MONO_INST_NEW (cfg, arg, OP_X86_PUSH); @@ -1526,7 +1537,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) MONO_ADD_INS (cfg->cbb, arg); sp_offset += size; - emit_gc_param_slot_def (cfg, sp_offset, t); + emit_gc_param_slot_def (cfg, sp_offset, orig_type); } } else { argsize = 4; @@ -1565,11 +1576,16 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (cfg->compute_gc_maps) { if (argsize == 4) { /* FIXME: The == STACK_OBJ check might be fragile ? */ - if (sig->hasthis && i == 0 && call->args [i]->type == STACK_OBJ) + if (sig->hasthis && i == 0 && call->args [i]->type == STACK_OBJ) { /* this */ - emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.object_class->byval_arg); - else - emit_gc_param_slot_def (cfg, sp_offset, t); + if (call->need_unbox_trampoline) + /* The unbox trampoline transforms this into a managed pointer */ + emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.int_class->this_arg); + else + emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.object_class->byval_arg); + } else { + emit_gc_param_slot_def (cfg, sp_offset, orig_type); + } } else { /* i8/r8 */ for (j = 0; j < argsize; j += 4) @@ -1617,6 +1633,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) } call->stack_usage = cinfo->stack_usage; + call->stack_align_amount = cinfo->stack_align_amount; cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset); } @@ -2275,11 +2292,12 @@ mono_x86_have_tls_get (void) #ifdef __APPLE__ static gboolean have_tls_get = FALSE; static gboolean inited = FALSE; + guint32 *ins; if (inited) return have_tls_get; - guint32 *ins = (guint32*)pthread_getspecific; + ins = (guint32*)pthread_getspecific; /* * We're looking for these two instructions: * @@ -2292,11 +2310,28 @@ mono_x86_have_tls_get (void) inited = TRUE; return have_tls_get; +#elif defined(TARGET_ANDROID) + return FALSE; #else return TRUE; #endif } +static guint8* +mono_x86_emit_tls_set (guint8* code, int sreg, int tls_offset) +{ +#if defined(__APPLE__) + x86_prefix (code, X86_GS_PREFIX); + x86_mov_mem_reg (code, tls_gs_offset + (tls_offset * 4), sreg, 4); +#elif defined(TARGET_WIN32) + g_assert_not_reached (); +#else + x86_prefix (code, X86_GS_PREFIX); + x86_mov_mem_reg (code, tls_offset, sreg, 4); +#endif + return code; +} + /* * mono_x86_emit_tls_get: * @code: buffer to store code to @@ -2703,6 +2738,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) */ for (i = 0; i < 6; ++i) x86_nop (code); + /* + * Add an additional nop so skipping the bp doesn't cause the ip to point + * to another IL offset. + */ + x86_nop (code); break; } case OP_ADDCC: @@ -3118,6 +3158,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) MonoCallInst *call = (MonoCallInst*)ins; int pos = 0, i; + ins->flags |= MONO_INST_GC_CALLSITE; + ins->backend.pc_offset = code - cfg->native_code; + /* FIXME: no tracing support... */ if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE) code = mono_arch_instrument_epilog (cfg, mono_profiler_method_leave, code, FALSE); @@ -3146,7 +3189,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } /* Copy arguments on the stack to our argument area */ - for (i = 0; i < call->stack_usage; i += 4) { + for (i = 0; i < call->stack_usage - call->stack_align_amount; i += 4) { x86_mov_reg_membase (code, X86_EAX, X86_ESP, i, 4); x86_mov_membase_reg (code, X86_EBP, 8 + i, X86_EAX, 4); } @@ -3157,6 +3200,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0); x86_jump32 (code, 0); + ins->flags |= MONO_INST_GC_CALLSITE; cfg->disable_aot = TRUE; break; } @@ -5020,49 +5064,6 @@ mono_arch_emit_prolog (MonoCompile *cfg) alloc_size = cfg->stack_offset; pos = 0; - if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) { - /* Might need to attach the thread to the JIT or change the domain for the callback */ - if (appdomain_tls_offset != -1 && lmf_tls_offset != -1) { - guint8 *buf, *no_domain_branch; - - code = mono_x86_emit_tls_get (code, X86_EAX, appdomain_tls_offset); - x86_alu_reg_imm (code, X86_CMP, X86_EAX, GPOINTER_TO_UINT (cfg->domain)); - no_domain_branch = code; - x86_branch8 (code, X86_CC_NE, 0, 0); - code = mono_x86_emit_tls_get ( code, X86_EAX, lmf_tls_offset); - x86_test_reg_reg (code, X86_EAX, X86_EAX); - buf = code; - x86_branch8 (code, X86_CC_NE, 0, 0); - x86_patch (no_domain_branch, code); - x86_push_imm (code, cfg->domain); - code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach"); - x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4); - x86_patch (buf, code); -#ifdef TARGET_WIN32 - /* The TLS key actually contains a pointer to the MonoJitTlsData structure */ - /* FIXME: Add a separate key for LMF to avoid this */ - x86_alu_reg_imm (code, X86_ADD, X86_EAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf)); -#endif - } - else { - if (cfg->compile_aot) { - /* - * This goes before the saving of callee saved regs, so save the got reg - * ourselves. - */ - x86_push_reg (code, MONO_ARCH_GOT_REG); - code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL); - x86_push_imm (code, 0); - } else { - x86_push_imm (code, cfg->domain); - } - code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach"); - x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4); - if (cfg->compile_aot) - x86_pop_reg (code, MONO_ARCH_GOT_REG); - } - } - if (method->save_lmf) { pos += sizeof (MonoLMF); @@ -5100,8 +5101,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) * through the mono_lmf_addr TLS variable. */ /* %eax = previous_lmf */ - x86_prefix (code, X86_GS_PREFIX); - x86_mov_reg_mem (code, X86_EAX, lmf_tls_offset, 4); + code = mono_x86_emit_tls_get (code, X86_EAX, lmf_tls_offset); /* skip esp + method_info + lmf */ x86_alu_reg_imm (code, X86_SUB, X86_ESP, 12); cfa_offset += 12; @@ -5113,8 +5113,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) cfa_offset += 4; mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF); /* new lmf = ESP */ - x86_prefix (code, X86_GS_PREFIX); - x86_mov_mem_reg (code, lmf_tls_offset, X86_ESP, 4); + code = mono_x86_emit_tls_set (code, X86_ESP, lmf_tls_offset); } else { /* get the address of lmf for the current thread */ /* @@ -5360,8 +5359,7 @@ mono_arch_emit_epilog (MonoCompile *cfg) x86_mov_reg_membase (code, X86_ECX, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), 4); /* lmf = previous_lmf */ - x86_prefix (code, X86_GS_PREFIX); - x86_mov_mem_reg (code, lmf_tls_offset, X86_ECX, 4); + code = mono_x86_emit_tls_set (code, X86_ECX, lmf_tls_offset); } else { /* Find a spare register */ switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) { @@ -5453,7 +5451,7 @@ mono_arch_emit_epilog (MonoCompile *cfg) if (CALLCONV_IS_STDCALL (sig)) { MonoJitArgumentInfo *arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1)); - stack_to_pop = mono_arch_get_argument_info (sig, sig->param_count, arg_info); + stack_to_pop = mono_arch_get_argument_info (cfg->generic_sharing_context, sig, sig->param_count, arg_info); } else if (MONO_TYPE_ISSTRUCT (mono_method_signature (cfg->method)->ret) && (cinfo->ret.storage == ArgOnStack)) stack_to_pop = 4; else @@ -5600,41 +5598,31 @@ mono_arch_is_inst_imm (gint64 imm) return TRUE; } -/* - * Support for fast access to the thread-local lmf structure using the GS - * segment register on NPTL + kernel 2.6.x. - */ - -static gboolean tls_offset_inited = FALSE; - void -mono_arch_setup_jit_tls_data (MonoJitTlsData *tls) +mono_arch_finish_init (void) { - if (!tls_offset_inited) { - if (!getenv ("MONO_NO_TLS")) { + if (!getenv ("MONO_NO_TLS")) { #ifdef TARGET_WIN32 - /* - * We need to init this multiple times, since when we are first called, the key might not - * be initialized yet. - */ - appdomain_tls_offset = mono_domain_get_tls_key (); - lmf_tls_offset = mono_get_jit_tls_key (); - - /* Only 64 tls entries can be accessed using inline code */ - if (appdomain_tls_offset >= 64) - appdomain_tls_offset = -1; - if (lmf_tls_offset >= 64) - lmf_tls_offset = -1; + /* + * We need to init this multiple times, since when we are first called, the key might not + * be initialized yet. + */ + appdomain_tls_offset = mono_domain_get_tls_key (); + lmf_tls_offset = mono_get_jit_tls_key (); + + /* Only 64 tls entries can be accessed using inline code */ + if (appdomain_tls_offset >= 64) + appdomain_tls_offset = -1; + if (lmf_tls_offset >= 64) + lmf_tls_offset = -1; #else #if MONO_XEN_OPT - optimize_for_xen = access ("/proc/xen", F_OK) == 0; + optimize_for_xen = access ("/proc/xen", F_OK) == 0; #endif - tls_offset_inited = TRUE; - appdomain_tls_offset = mono_domain_get_tls_offset (); - lmf_tls_offset = mono_get_lmf_tls_offset (); - lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset (); + appdomain_tls_offset = mono_domain_get_tls_offset (); + lmf_tls_offset = mono_get_lmf_tls_offset (); + lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset (); #endif - } } } @@ -5921,9 +5909,9 @@ mono_arch_get_patch_offset (guint8 *code) { if ((code [0] == 0x8b) && (x86_modrm_mod (code [1]) == 0x2)) return 2; - else if ((code [0] == 0xba)) + else if (code [0] == 0xba) return 1; - else if ((code [0] == 0x68)) + else if (code [0] == 0x68) /* push IMM */ return 1; else if ((code [0] == 0xff) && (x86_modrm_reg (code [1]) == 0x6)) @@ -6203,7 +6191,9 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) case X86_EBP: return ctx->ebp; case X86_ESI: return ctx->esi; case X86_EDI: return ctx->edi; - default: g_assert_not_reached (); + default: + g_assert_not_reached (); + return 0; } } @@ -6623,44 +6613,15 @@ mono_arch_is_breakpoint_event (void *info, void *sigctx) #endif } -/* - * mono_arch_get_ip_for_breakpoint: - * - * See mini-amd64.c for docs. - */ -guint8* -mono_arch_get_ip_for_breakpoint (MonoJitInfo *ji, MonoContext *ctx) -{ - guint8 *ip = MONO_CONTEXT_GET_IP (ctx); - - return ip; -} - #define BREAKPOINT_SIZE 6 -/* - * mono_arch_get_ip_for_single_step: - * - * See mini-amd64.c for docs. - */ -guint8* -mono_arch_get_ip_for_single_step (MonoJitInfo *ji, MonoContext *ctx) -{ - guint8 *ip = MONO_CONTEXT_GET_IP (ctx); - - /* Size of x86_alu_reg_imm */ - ip += 6; - - return ip; -} - /* * mono_arch_skip_breakpoint: * * See mini-amd64.c for docs. */ void -mono_arch_skip_breakpoint (MonoContext *ctx) +mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji) { MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + BREAKPOINT_SIZE); }