X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-x86.c;h=7d6ca40ab66f8d9906d8a120f6e63187e797a3e3;hb=087d58e28bcffc141578a0166f63dfc1e8c0b05b;hp=e1a2c299943f90a4818b4c68b15f9a41162159ce;hpb=7790e3db2cb7858cab7c59c056609c22f83c4b71;p=mono.git diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index e1a2c299943..7d6ca40ab66 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -62,6 +62,9 @@ static CRITICAL_SECTION mini_arch_mutex; #define NOT_IMPLEMENTED g_assert_not_reached () +MonoBreakpointInfo +mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE]; + const char* mono_arch_regname (int reg) { switch (reg) { @@ -174,7 +177,7 @@ add_float (guint32 *gr, guint32 *stack_size, ArgInfo *ainfo, gboolean is_double) static void -add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, +add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, gboolean is_return, guint32 *gr, guint32 *fr, guint32 *stack_size) { @@ -185,7 +188,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, if (sig->pinvoke) size = mono_type_native_stack_size (&klass->byval_arg, NULL); else - size = mono_type_stack_size (&klass->byval_arg, NULL); + size = mini_type_stack_size (gsctx, &klass->byval_arg, NULL); #ifdef SMALL_STRUCTS_IN_REGS if (sig->pinvoke && is_return) { @@ -239,13 +242,14 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, * For x86 win32, see ???. */ static CallInfo* -get_call_info (MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) +get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) { guint32 i, gr, fr; MonoType *ret_type; int n = sig->hasthis + sig->param_count; guint32 stack_size = 0; CallInfo *cinfo; + MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL; if (mp) cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n)); @@ -258,6 +262,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) /* return value */ { ret_type = mono_type_get_underlying_type (sig->ret); + ret_type = mini_get_basic_type_from_generic (gsctx, ret_type); switch (ret_type->type) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_I1: @@ -300,7 +305,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) case MONO_TYPE_VALUETYPE: { guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0; - add_valuetype (sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize); + add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize); if (cinfo->ret.storage == ArgOnStack) /* The caller passes the address where the value is stored */ add_general (&gr, &stack_size, &cinfo->ret); @@ -353,6 +358,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) continue; } ptype = mono_type_get_underlying_type (sig->params [i]); + ptype = mini_get_basic_type_from_generic (gsctx, ptype); switch (ptype->type) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_I1: @@ -386,7 +392,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) } /* Fall through */ case MONO_TYPE_VALUETYPE: - add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size); + add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size); break; case MONO_TYPE_TYPEDBYREF: stack_size += sizeof (MonoTypedRef); @@ -449,7 +455,7 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit int offset = 8; CallInfo *cinfo; - cinfo = get_call_info (NULL, csig, FALSE); + cinfo = get_call_info (NULL, NULL, csig, FALSE); if (MONO_TYPE_ISSTRUCT (csig->ret) && (cinfo->ret.storage == ArgOnStack)) { frame_size += sizeof (gpointer); @@ -471,7 +477,7 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit size = mono_type_native_stack_size (csig->params [k], &align); else { int ialign; - size = mono_type_stack_size (csig->params [k], &ialign); + size = mini_type_stack_size (NULL, csig->params [k], &ialign); align = ialign; } @@ -777,7 +783,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) header = mono_method_get_header (cfg->method); sig = mono_method_signature (cfg->method); - cinfo = get_call_info (cfg->mempool, sig, FALSE); + cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE); cfg->frame_reg = MONO_ARCH_BASEREG; offset = 0; @@ -883,7 +889,7 @@ mono_arch_create_vars (MonoCompile *cfg) sig = mono_method_signature (cfg->method); - cinfo = get_call_info (cfg->mempool, sig, FALSE); + cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE); if (cinfo->ret.storage == ArgValuetypeInReg) cfg->ret_var_is_local = TRUE; @@ -970,7 +976,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, sig = call->signature; n = sig->param_count + sig->hasthis; - cinfo = get_call_info (cfg->mempool, sig, FALSE); + cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE); if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) sentinelpos = sig->sentinelpos + (is_virtual ? 1 : 0); @@ -1016,7 +1022,7 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, size = mono_type_native_stack_size (&in->klass->byval_arg, &align); else { int ialign; - size = mono_type_stack_size (&in->klass->byval_arg, &ialign); + size = mini_type_stack_size (cfg->generic_sharing_context, &in->klass->byval_arg, &ialign); align = ialign; } arg->opcode = OP_OUTARG_VT; @@ -1948,7 +1954,7 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code) case OP_VCALL: case OP_VCALL_REG: case OP_VCALL_MEMBASE: - cinfo = get_call_info (cfg->mempool, ((MonoCallInst*)ins)->signature, FALSE); + cinfo = get_call_info (cfg, cfg->mempool, ((MonoCallInst*)ins)->signature, FALSE); if (cinfo->ret.storage == ArgValuetypeInReg) { /* Pop the destination address from the stack */ x86_pop_reg (code, X86_ECX); @@ -2030,7 +2036,7 @@ emit_load_volatile_arguments (MonoCompile *cfg, guint8 *code) sig = mono_method_signature (method); - cinfo = get_call_info (cfg->mempool, sig, FALSE); + cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE); /* This is the opposite of the code in emit_prolog */ @@ -3604,7 +3610,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) int alloc_size, pos, max_offset, i; guint8 *code; - cfg->code_size = MAX (mono_method_get_header (method)->code_size * 4, 256); + cfg->code_size = MAX (mono_method_get_header (method)->code_size * 4, 1024); if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE) cfg->code_size += 512; @@ -3618,14 +3624,19 @@ mono_arch_emit_prolog (MonoCompile *cfg) pos = 0; if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) { - /* Might need to attach the thread to the JIT */ - if (lmf_tls_offset != -1) { - guint8 *buf; + /* 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 = 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 = 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); @@ -3909,7 +3920,7 @@ mono_arch_emit_epilog (MonoCompile *cfg) } /* Load returned vtypes into registers if needed */ - cinfo = get_call_info (cfg->mempool, sig, FALSE); + cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE); if (cinfo->ret.storage == ArgValuetypeInReg) { for (quad = 0; quad < 2; quad ++) { switch (cinfo->ret.pair_storage [quad]) { @@ -4119,7 +4130,7 @@ void mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_reg, int this_type, int vt_reg) { MonoCallInst *call = (MonoCallInst*)inst; - CallInfo *cinfo = get_call_info (cfg->mempool, inst->signature, FALSE); + CallInfo *cinfo = get_call_info (cfg, cfg->mempool, inst->signature, FALSE); /* add the this argument */ if (this_reg != -1) { @@ -4287,7 +4298,7 @@ MonoObject* mono_arch_find_this_argument (gpointer *regs, MonoMethod *method) { MonoMethodSignature *sig = mono_method_signature (method); - CallInfo *cinfo = get_call_info (NULL, sig, FALSE); + CallInfo *cinfo = get_call_info (NULL, NULL, sig, FALSE); int this_argument_offset; MonoObject *this_argument; @@ -4339,42 +4350,6 @@ mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethod ins->inst_i1 = args [1]; } #endif - } else if (cmethod->klass == mono_defaults.thread_class && - strcmp (cmethod->name, "MemoryBarrier") == 0) { - MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER); - } else if(cmethod->klass->image == mono_defaults.corlib && - (strcmp (cmethod->klass->name_space, "System.Threading") == 0) && - (strcmp (cmethod->klass->name, "Interlocked") == 0)) { - - if (strcmp (cmethod->name, "Increment") == 0 && fsig->params [0]->type == MONO_TYPE_I4) { - MonoInst *ins_iconst; - - MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_NEW_I4); - MONO_INST_NEW (cfg, ins_iconst, OP_ICONST); - ins_iconst->inst_c0 = 1; - - ins->inst_i0 = args [0]; - ins->inst_i1 = ins_iconst; - } else if (strcmp (cmethod->name, "Decrement") == 0 && fsig->params [0]->type == MONO_TYPE_I4) { - MonoInst *ins_iconst; - - MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_NEW_I4); - MONO_INST_NEW (cfg, ins_iconst, OP_ICONST); - ins_iconst->inst_c0 = -1; - - ins->inst_i0 = args [0]; - ins->inst_i1 = ins_iconst; - } else if (strcmp (cmethod->name, "Exchange") == 0 && fsig->params [0]->type == MONO_TYPE_I4) { - MONO_INST_NEW (cfg, ins, OP_ATOMIC_EXCHANGE_I4); - - ins->inst_i0 = args [0]; - ins->inst_i1 = args [1]; - } else if (strcmp (cmethod->name, "Add") == 0 && fsig->params [0]->type == MONO_TYPE_I4) { - MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_NEW_I4); - - ins->inst_i0 = args [0]; - ins->inst_i1 = args [1]; - } } return ins; @@ -4442,12 +4417,40 @@ mono_arch_get_patch_offset (guint8 *code) } } -gpointer* -mono_arch_get_vcall_slot_addr (guint8 *code, gpointer *regs) +gboolean +mono_breakpoint_clean_code (guint8 *code, guint8 *buf, int size) +{ + int i; + gboolean can_write = TRUE; + memcpy (buf, code, size); + for (i = 0; i < MONO_BREAKPOINT_ARRAY_SIZE; ++i) { + int idx = mono_breakpoint_info_index [i]; + guint8 *ptr; + if (idx < 1) + continue; + ptr = mono_breakpoint_info [idx].address; + if (ptr >= code && ptr < code + size) { + guint8 saved_byte = mono_breakpoint_info [idx].saved_byte; + can_write = FALSE; + /*g_print ("patching %p with 0x%02x (was: 0x%02x)\n", ptr, saved_byte, buf [ptr - code]);*/ + buf [ptr - code] = saved_byte; + } + } + return can_write; +} + +gpointer +mono_arch_get_vcall_slot (guint8 *code, gpointer *regs, int *displacement) { + guint8 buf [8]; guint8 reg = 0; gint32 disp = 0; + mono_breakpoint_clean_code (code - 8, buf, sizeof (buf)); + code = buf + 8; + + *displacement = 0; + /* go to the start of the call instruction * * address_byte = (m << 6) | (o << 3) | reg @@ -4501,7 +4504,19 @@ mono_arch_get_vcall_slot_addr (guint8 *code, gpointer *regs) return NULL; } - return (gpointer*)(((gint32)(regs [reg])) + disp); + *displacement = disp; + return regs [reg]; +} + +gpointer* +mono_arch_get_vcall_slot_addr (guint8 *code, gpointer *regs) +{ + gpointer vt; + int displacement; + vt = mono_arch_get_vcall_slot (code, regs, &displacement); + if (!vt) + return NULL; + return (gpointer*)((char*)vt + displacement); } gpointer @@ -4511,7 +4526,7 @@ mono_arch_get_this_arg_from_call (MonoMethodSignature *sig, gssize *regs, guint8 CallInfo *cinfo; gpointer res; - cinfo = get_call_info (NULL, sig, FALSE); + cinfo = get_call_info (NULL, NULL, sig, FALSE); /* * The stack looks like: