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);
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;
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;
#include <mono/utils/mono-memory-model.h>
#include "mini.h"
+#include "mini-runtime.h"
#include "ir-emit.h"
#include "jit-icalls.h"
/*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);
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);
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;
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);
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]);
}
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);
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;
/* 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) {