X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmethod-to-ir.c;h=8df37c178d64cab31e36c9db208bbe40d02f8163;hb=f0f4a22ae1693f1df4aef43d2153b47dabc65df2;hp=48ecab877814e1f11d7d07408830b69fb946a1ed;hpb=242987b59bcf188b5af86f4fab06cfbbb5914e3a;p=mono.git diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 48ecab87781..8df37c178d6 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -1070,6 +1070,7 @@ type_from_op (MonoCompile *cfg, MonoInst *ins, MonoInst *src1, MonoInst *src2) break; case STACK_PTR: case STACK_MP: + case STACK_OBJ: #if SIZEOF_VOID_P == 8 ins->opcode = OP_LCONV_TO_U; #else @@ -3972,6 +3973,8 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono /* Set target field */ /* Optimize away setting of NULL target */ if (!MONO_INS_IS_PCONST_NULL (target)) { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, target->dreg, 0); + MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException"); MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, MONO_STRUCT_OFFSET (MonoDelegate, target), target->dreg); if (cfg->gen_write_barriers) { dreg = alloc_preg (cfg); @@ -6132,9 +6135,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, prev_args = cfg->args; prev_arg_types = cfg->arg_types; prev_inlined_method = cfg->inlined_method; - cfg->inlined_method = cmethod; - cfg->ret_var_set = FALSE; - cfg->inline_depth ++; + prev_ret_var_set = cfg->ret_var_set; prev_real_offset = cfg->real_offset; prev_cbb_hash = cfg->cbb_hash; prev_cil_offset_to_bb = cfg->cil_offset_to_bb; @@ -6144,9 +6145,12 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, prev_cbb = cfg->cbb; prev_current_method = cfg->current_method; prev_generic_context = cfg->generic_context; - prev_ret_var_set = cfg->ret_var_set; prev_disable_inline = cfg->disable_inline; + cfg->inlined_method = cmethod; + cfg->ret_var_set = FALSE; + cfg->inline_depth ++; + if (ip && *ip == CEE_CALLVIRT && !(cmethod->flags & METHOD_ATTRIBUTE_STATIC)) virtual_ = TRUE; @@ -6666,7 +6670,7 @@ emit_stloc_ir (MonoCompile *cfg, MonoInst **sp, MonoMethodHeader *header, int n) if (coerce_op) { if (cfg->cbb->last_ins == sp [0] && sp [0]->opcode == coerce_op) { if (cfg->verbose_level > 2) - printf ("Found existing coercing that is enough\n"); + printf ("Found existing coercing is enough for stloc\n"); } else { MONO_INST_NEW (cfg, ins, coerce_op); ins->dreg = alloc_ireg (cfg); @@ -6693,6 +6697,30 @@ emit_stloc_ir (MonoCompile *cfg, MonoInst **sp, MonoMethodHeader *header, int n) } } +static void +emit_starg_ir (MonoCompile *cfg, MonoInst **sp, int n) +{ + MonoInst *ins; + guint32 coerce_op = mono_type_to_stloc_coerce (cfg->arg_types [n]); + + if (coerce_op) { + if (cfg->cbb->last_ins == sp [0] && sp [0]->opcode == coerce_op) { + if (cfg->verbose_level > 2) + printf ("Found existing coercing is enough for starg\n"); + } else { + MONO_INST_NEW (cfg, ins, coerce_op); + ins->dreg = alloc_ireg (cfg); + ins->sreg1 = sp [0]->dreg; + ins->type = STACK_I4; + ins->klass = mono_class_from_mono_type (cfg->arg_types [n]); + MONO_ADD_INS (cfg->cbb, ins); + *sp = mono_decompose_opcode (cfg, ins); + } + } + + EMIT_NEW_ARGSTORE (cfg, ins, n, *sp); +} + /* * ldloca inhibits many optimizations so try to get rid of it in common * cases. @@ -7258,7 +7286,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b seq_points = FALSE; } - if (cfg->gen_sdb_seq_points && cfg->method == method) { + if (cfg->method == method) + cfg->coverage_info = mono_profiler_coverage_alloc (cfg->method, header->code_size); + + if ((cfg->gen_sdb_seq_points && cfg->method == method) || cfg->coverage_info) { minfo = mono_debug_lookup_method (method); if (minfo) { MonoSymSeqPoint *sps; @@ -7353,9 +7384,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cfg->dont_inline = g_list_prepend (cfg->dont_inline, method); if (cfg->method == method) { - - cfg->coverage_info = mono_profiler_coverage_alloc (cfg->method, header->code_size); - /* ENTRY BLOCK */ NEW_BBLOCK (cfg, start_bblock); cfg->bb_entry = start_bblock; @@ -7746,33 +7774,33 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (sym_seq_points) mono_bitset_set_fast (seq_point_set_locs, ip - header->code); - } - - cfg->cbb->real_offset = cfg->real_offset; - if ((cfg->method == method) && cfg->coverage_info) { - guint32 cil_offset = ip - header->code; - gpointer counter = &cfg->coverage_info->data [cil_offset].count; - cfg->coverage_info->data [cil_offset].cil_code = ip; + if ((cfg->method == method) && cfg->coverage_info) { + guint32 cil_offset = ip - header->code; + gpointer counter = &cfg->coverage_info->data [cil_offset].count; + cfg->coverage_info->data [cil_offset].cil_code = ip; - if (mono_arch_opcode_supported (OP_ATOMIC_ADD_I4)) { - MonoInst *one_ins, *load_ins; + if (mono_arch_opcode_supported (OP_ATOMIC_ADD_I4)) { + MonoInst *one_ins, *load_ins; - EMIT_NEW_PCONST (cfg, load_ins, counter); - EMIT_NEW_ICONST (cfg, one_ins, 1); - MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_I4); - ins->dreg = mono_alloc_ireg (cfg); - ins->inst_basereg = load_ins->dreg; - ins->inst_offset = 0; - ins->sreg2 = one_ins->dreg; - ins->type = STACK_I4; - MONO_ADD_INS (cfg->cbb, ins); - } else { - EMIT_NEW_PCONST (cfg, ins, counter); - MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, ins->dreg, 0, 1); + EMIT_NEW_PCONST (cfg, load_ins, counter); + EMIT_NEW_ICONST (cfg, one_ins, 1); + MONO_INST_NEW (cfg, ins, OP_ATOMIC_ADD_I4); + ins->dreg = mono_alloc_ireg (cfg); + ins->inst_basereg = load_ins->dreg; + ins->inst_offset = 0; + ins->sreg2 = one_ins->dreg; + ins->type = STACK_I4; + MONO_ADD_INS (cfg->cbb, ins); + } else { + EMIT_NEW_PCONST (cfg, ins, counter); + MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, ins->dreg, 0, 1); + } } } + cfg->cbb->real_offset = cfg->real_offset; + if (cfg->verbose_level > 3) printf ("converting (in B%d: stack: %d) %s", cfg->cbb->block_num, (int)(sp - stack_start), mono_disasm_code_one (NULL, method, ip, NULL)); @@ -7866,7 +7894,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b CHECK_ARG (n); if (!dont_verify_stloc && target_type_is_incompatible (cfg, param_types [ip [1]], *sp)) UNVERIFIED; - EMIT_NEW_ARGSTORE (cfg, ins, n, *sp); + emit_starg_ir (cfg, sp, n); ip += 2; break; case CEE_LDLOC_S: @@ -8819,6 +8847,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } for (i = 0; i < n; ++i) EMIT_NEW_ARGSTORE (cfg, ins, i, sp [i]); + + mini_profiler_emit_tail_call (cfg, cmethod); + MONO_INST_NEW (cfg, ins, OP_BR); MONO_ADD_INS (cfg->cbb, ins); tblock = start_bblock->out_bb [0]; @@ -11753,6 +11784,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (sp != stack_start) UNVERIFIED; + mini_profiler_emit_leave (cfg, sp [0]); + MONO_INST_NEW (cfg, ins, OP_BR); ins->inst_target_bb = end_bblock; MONO_ADD_INS (cfg->cbb, ins); @@ -11807,7 +11840,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b cfg->dyn_call_var->flags |= MONO_INST_VOLATILE; } - /* Has to use a call inst since it local regalloc expects it */ + /* Has to use a call inst since local regalloc expects it */ MONO_INST_NEW_CALL (cfg, call, OP_DYN_CALL); ins = (MonoInst*)call; sp -= 2; @@ -11816,6 +11849,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MONO_ADD_INS (cfg->cbb, ins); cfg->param_area = MAX (cfg->param_area, cfg->backend->dyn_call_param_area); + /* OP_DYN_CALL might need to allocate a dynamically sized param area */ + cfg->flags |= MONO_CFG_HAS_ALLOCA; ip += 2; inline_costs += 10 * num_calls++; @@ -12347,7 +12382,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b CHECK_ARG (n); if (!dont_verify_stloc && target_type_is_incompatible (cfg, param_types [n], *sp)) UNVERIFIED; - EMIT_NEW_ARGSTORE (cfg, ins, n, *sp); + emit_starg_ir (cfg, sp, n); ip += 4; break; case CEE_LDLOC: