From: Vlad Brezae Date: Fri, 27 Sep 2019 09:36:04 +0000 (+0300) Subject: [mini] Expand clr-memory-model effect (mono/mono#17093) X-Git-Tag: submit/tizen/20210909.063632~10331^2~5^2~437 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec694b21a629a54b69711a4503c27452a83c5e25;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [mini] Expand clr-memory-model effect (mono/mono#17093) * [mini] Add memory barriers to more stores inside objects We should now have membars for all stores of an object ref inside another object (for the stores done by the jit). Used by clr-memory-model debug option. * [mini] Add memory barrier for storing objref in static fields For clr-memory-model debug option. Commit migrated from https://github.com/mono/mono/commit/194506d495a2e2b7b2fad5dbb655f404cecb2c04 --- diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index fff6ff5..9aa0101 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -34,6 +34,8 @@ emit_array_generic_access (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst MonoType *etype = m_class_get_byval_arg (eklass); if (is_set) { EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, etype, args [2]->dreg, 0); + if (mini_debug_options.clr_memory_model && mini_type_is_reference (etype)) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, etype, addr->dreg, 0, load->dreg); if (mini_type_is_reference (etype)) mini_emit_write_barrier (cfg, addr, load); @@ -1199,6 +1201,9 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MONO_ADD_INS (cfg->cbb, f2i); } + if (is_ref && mini_debug_options.clr_memory_model) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); + MONO_INST_NEW (cfg, ins, opcode); ins->dreg = is_ref ? mono_alloc_ireg_ref (cfg) : mono_alloc_ireg (cfg); ins->inst_basereg = args [0]->dreg; @@ -1299,6 +1304,9 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MONO_ADD_INS (cfg->cbb, f2i_cmp); } + if (is_ref && mini_debug_options.clr_memory_model) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); + MONO_INST_NEW (cfg, ins, opcode); ins->dreg = is_ref ? alloc_ireg_ref (cfg) : alloc_ireg (cfg); ins->sreg1 = args [0]->dreg; diff --git a/src/mono/mono/mini/memory-access.c b/src/mono/mono/mini/memory-access.c index 93133a2..780010e 100644 --- a/src/mono/mono/mini/memory-access.c +++ b/src/mono/mono/mini/memory-access.c @@ -13,6 +13,7 @@ #include #include "mini.h" +#include "mini-runtime.h" #include "ir-emit.h" #include "jit-icalls.h" @@ -293,6 +294,9 @@ mini_emit_wb_aware_memcpy (MonoCompile *cfg, MonoClass *klass, MonoInst *iargs[4 /*tmp = dreg*/ EMIT_NEW_UNALU (cfg, iargs [0], OP_MOVE, dest_ptr_reg, destreg); + if ((need_wb & 0x1) && mini_debug_options.clr_memory_model) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); + while (size >= TARGET_SIZEOF_VOID_P) { MonoInst *load_inst; MONO_INST_NEW (cfg, load_inst, OP_LOAD_MEMBASE); @@ -390,6 +394,9 @@ mini_emit_memory_copy_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *src, NEW_LOAD_MEMBASE (cfg, load, OP_LOAD_MEMBASE, dreg, src->dreg, 0); MONO_ADD_INS (cfg->cbb, load); + if (mini_debug_options.clr_memory_model) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); + NEW_STORE_MEMBASE (cfg, store, OP_STORE_MEMBASE_REG, dest->dreg, 0, dreg); MONO_ADD_INS (cfg->cbb, store); @@ -486,7 +493,8 @@ mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoIn 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); - } + } else if (mini_debug_options.clr_memory_model && mini_type_is_reference (type)) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); if (ins_flag & MONO_INST_UNALIGNED) { MonoInst *addr, *mov, *tmp_var; diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index ac4bdf8..0fc7ca1 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -3530,6 +3530,8 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, target->dreg, 0); MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException"); } + if (mini_debug_options.clr_memory_model) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); 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); @@ -4228,6 +4230,8 @@ mini_emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboole EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), array_reg, offset, sp [2]->dreg); } else { MonoInst *addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], safety_checks); + if (mini_debug_options.clr_memory_model && mini_class_is_reference (klass)) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), addr->dreg, 0, sp [2]->dreg); if (mini_class_is_reference (klass)) mini_emit_write_barrier (cfg, addr, sp [2]); @@ -7746,6 +7750,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } addr = mini_emit_ldelema_ins (cfg, cmethod, sp, ip, TRUE); + if (mini_debug_options.clr_memory_model && val->type == STACK_OBJ) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, fsig->params [fsig->param_count - 1], addr->dreg, 0, val->dreg); if (cfg->gen_write_barriers && val->type == STACK_OBJ && !MONO_INS_IS_PCONST_NULL (val)) mini_emit_write_barrier (cfg, addr, val); @@ -8242,6 +8248,8 @@ calli_end: if (il_op == MONO_CEE_STIND_R4 && sp [1]->type == STACK_R8) sp [1] = convert_value (cfg, m_class_get_byval_arg (mono_defaults.single_class), sp [1]); + if (mini_debug_options.clr_memory_model && il_op == MONO_CEE_STIND_REF && method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER) + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); NEW_STORE_MEMBASE (cfg, ins, stind_to_store_membase (il_op), sp [0]->dreg, 0, sp [1]->dreg); ins->flags |= ins_flag; ins_flag = 0; @@ -9484,9 +9492,13 @@ calli_end: /* Generate IR to do the actual load/store operation */ - if ((il_op == MONO_CEE_STFLD || il_op == MONO_CEE_STSFLD) && (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); + if ((il_op == MONO_CEE_STFLD || il_op == MONO_CEE_STSFLD)) { + 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); + } else if (mini_debug_options.clr_memory_model && mini_type_is_reference (ftype)) { + mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); + } } if (il_op == MONO_CEE_LDSFLDA) {