X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmethod-to-ir.c;h=2883c23ea3cedd7fe144d4086ddeeb2ec41eef61;hb=e05343ddf556a554ff9584759ac24610001d711f;hp=8d64aabc8a8ca471c9f43b0e1a021418f1c9109b;hpb=4dee9cb05fb9f223fca4f8aa3b9119e63bb54c57;p=mono.git diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 8d64aabc8a8..2883c23ea3c 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -2863,6 +2863,8 @@ mini_emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value) if (!cfg->gen_write_barriers) return; + //method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER && !MONO_INS_IS_PCONST_NULL (sp [1]) + card_table = mono_gc_get_card_table (&card_table_shift_bits, &card_table_mask); mono_gc_get_nursery (&nursery_shift_bits, &nursery_size); @@ -6646,7 +6648,7 @@ mini_get_method (MonoCompile *cfg, MonoMethod *m, guint32 token, MonoClass *klas return method; } -static inline MonoClass* +MonoClass* mini_get_class (MonoMethod *method, guint32 token, MonoGenericContext *context) { MonoError error; @@ -8600,6 +8602,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b sp -= n; + if (cmethod && cmethod->klass->image == mono_defaults.corlib && !strcmp (cmethod->klass->name, "ThrowHelper")) + cfg->cbb->out_of_line = TRUE; + /* * We have the `constrained.' prefix opcode. */ @@ -9234,7 +9239,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } /* Common call */ - if (!(cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING)) + if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING) && !(cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING)) INLINE_FAILURE ("call"); ins = mono_emit_method_call_full (cfg, cmethod, fsig, tail_call, sp, virtual_ ? sp [0] : NULL, imt_arg, vtable_arg); @@ -9850,23 +9855,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b klass = mini_get_class (method, token, generic_context); CHECK_TYPELOAD (klass); sp -= 2; - if (generic_class_is_reference_type (cfg, klass)) { - MonoInst *store, *load; - int dreg = alloc_ireg_ref (cfg); - - NEW_LOAD_MEMBASE (cfg, load, OP_LOAD_MEMBASE, dreg, sp [1]->dreg, 0); - load->flags |= ins_flag; - MONO_ADD_INS (cfg->cbb, load); - - NEW_STORE_MEMBASE (cfg, store, OP_STORE_MEMBASE_REG, sp [0]->dreg, 0, dreg); - store->flags |= ins_flag; - MONO_ADD_INS (cfg->cbb, store); - - if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER) - mini_emit_write_barrier (cfg, sp [0], sp [1]); - } else { - mini_emit_stobj (cfg, sp [0], sp [1], klass, FALSE); - } + mini_emit_memory_copy (cfg, sp [0], sp [1], klass, FALSE, ins_flag); ins_flag = 0; ip += 5; break; @@ -9915,14 +9904,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } /* Optimize the ldobj+stobj combination */ - /* The reference case ends up being a load+store anyway */ - /* Skip this if the operation is volatile. */ - if (((ip [5] == CEE_STOBJ) && ip_in_bb (cfg, cfg->cbb, ip + 5) && read32 (ip + 6) == token) && !generic_class_is_reference_type (cfg, klass) && !(ins_flag & MONO_INST_VOLATILE)) { + if (((ip [5] == CEE_STOBJ) && ip_in_bb (cfg, cfg->cbb, ip + 5) && read32 (ip + 6) == token)) { CHECK_STACK (1); sp --; - mini_emit_stobj (cfg, sp [0], sp [1], klass, FALSE); + mini_emit_memory_copy (cfg, sp [0], sp [1], klass, FALSE, ins_flag); ip += 5 + 5; ins_flag = 0; @@ -10579,7 +10566,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b dreg = alloc_ireg_mp (cfg); EMIT_NEW_BIALU (cfg, ins, OP_PADD, dreg, sp [0]->dreg, offset_ins->dreg); wbarrier_ptr_ins = ins; - /* The decomposition will call mini_emit_stobj () which will emit a wbarrier if needed */ + /* The decomposition will call mini_emit_memory_copy () which will emit a wbarrier if needed */ EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, field->type, dreg, 0, sp [1]->dreg); } else { EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, field->type, sp [0]->dreg, foffset, sp [1]->dreg); @@ -11012,18 +10999,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b token = read32 (ip + 1); klass = mini_get_class (method, token, generic_context); CHECK_TYPELOAD (klass); - if (ins_flag & MONO_INST_VOLATILE) { - /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */ - mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); - } + /* FIXME: should check item at sp [1] is compatible with the type of the store. */ - EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, sp [0]->dreg, 0, sp [1]->dreg); - ins->flags |= ins_flag; - if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER && - generic_class_is_reference_type (cfg, klass) && !MONO_INS_IS_PCONST_NULL (sp [1])) { - /* insert call to write barrier */ - mini_emit_write_barrier (cfg, sp [0], sp [1]); - } + mini_emit_memory_store (cfg, &klass->byval_arg, sp [0], sp [1], ins_flag); ins_flag = 0; ip += 5; inline_costs += 1; @@ -11849,7 +11827,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b temp = mono_compile_create_var (cfg, &klass->byval_arg, OP_LOCAL); temp->backend.is_pinvoke = 1; EMIT_NEW_TEMPLOADA (cfg, dest, temp->inst_c0); - mini_emit_stobj (cfg, dest, src, klass, TRUE); + mini_emit_memory_copy (cfg, dest, src, klass, TRUE, 0); EMIT_NEW_TEMPLOAD (cfg, dest, temp->inst_c0); dest->type = STACK_VTYPE; @@ -11880,7 +11858,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } else { EMIT_NEW_RETLOADA (cfg, ins); } - mini_emit_stobj (cfg, ins, sp [0], klass, TRUE); + mini_emit_memory_copy (cfg, ins, sp [0], klass, TRUE, 0); if (sp != stack_start) UNVERIFIED; @@ -12633,56 +12611,21 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b ip += 6; break; case CEE_CPBLK: - case CEE_INITBLK: { - MonoInst *iargs [3]; CHECK_STACK (3); sp -= 3; - - /* Skip optimized paths for volatile operations. */ - if ((ip [1] == CEE_CPBLK) && !(ins_flag & MONO_INST_VOLATILE) && (cfg->opt & MONO_OPT_INTRINS) && (sp [2]->opcode == OP_ICONST) && ((n = sp [2]->inst_c0) <= sizeof (gpointer) * 5)) { - mini_emit_memcpy (cfg, sp [0]->dreg, 0, sp [1]->dreg, 0, sp [2]->inst_c0, 0); - } else if ((ip [1] == CEE_INITBLK) && !(ins_flag & MONO_INST_VOLATILE) && (cfg->opt & MONO_OPT_INTRINS) && (sp [2]->opcode == OP_ICONST) && ((n = sp [2]->inst_c0) <= sizeof (gpointer) * 5) && (sp [1]->opcode == OP_ICONST) && (sp [1]->inst_c0 == 0)) { - /* emit_memset only works when val == 0 */ - mini_emit_memset (cfg, sp [0]->dreg, 0, sp [2]->inst_c0, sp [1]->inst_c0, 0); - } else { - MonoInst *call; - iargs [0] = sp [0]; - iargs [1] = sp [1]; - iargs [2] = sp [2]; - if (ip [1] == CEE_CPBLK) { - /* - * FIXME: It's unclear whether we should be emitting both the acquire - * and release barriers for cpblk. It is technically both a load and - * store operation, so it seems like that's the sensible thing to do. - * - * FIXME: We emit full barriers on both sides of the operation for - * simplicity. We should have a separate atomic memcpy method instead. - */ - MonoMethod *memcpy_method = mini_get_memcpy_method (); - - if (ins_flag & MONO_INST_VOLATILE) - mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ); - - call = mono_emit_method_call (cfg, memcpy_method, iargs, NULL); - call->flags |= ins_flag; - - if (ins_flag & MONO_INST_VOLATILE) - mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ); - } else { - MonoMethod *memset_method = mini_get_memset_method (); - if (ins_flag & MONO_INST_VOLATILE) { - /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */ - mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); - } - call = mono_emit_method_call (cfg, memset_method, iargs, NULL); - call->flags |= ins_flag; - } - } + mini_emit_memory_copy_bytes (cfg, sp [0], sp [1], sp [2], ins_flag); + ip += 2; + ins_flag = 0; + inline_costs += 1; + break; + case CEE_INITBLK: + CHECK_STACK (3); + sp -= 3; + mini_emit_memory_init_bytes (cfg, sp [0], sp [1], sp [2], ins_flag); ip += 2; ins_flag = 0; inline_costs += 1; break; - } case CEE_NO_: CHECK_OPSIZE (3); if (ip [2] & 0x1) @@ -14386,7 +14329,6 @@ mono_spill_global_vars (MonoCompile *cfg, gboolean *need_local_opts) * - create a helper function for allocating a stack slot, taking into account * MONO_CFG_HAS_SPILLUP. * - merge r68207. - * - merge the ia64 switch changes. * - optimize mono_regstate2_alloc_int/float. * - fix the pessimistic handling of variables accessed in exception handler blocks. * - need to write a tree optimization pass, but the creation of trees is difficult, i.e.