From a57bf2d2629b58ca15314e13751bf8f2a940c0f4 Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Sat, 11 Jun 2011 22:05:19 -0300 Subject: [PATCH] Extract the code to emit a memory barrier. Add a memory_barrier_kind field to MonoInst::backend. --- mono/mini/method-to-ir.c | 28 +++++++++++++++++++++++++--- mono/mini/mini.h | 1 + mono/utils/mono-memory-model.h | 8 ++++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index bdc41212741..19210fe71ff 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include "mini.h" @@ -4275,6 +4276,17 @@ mini_emit_inst_for_ctor (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignat } static MonoInst* +emit_memory_barrier (MonoCompile *cfg, int kind) +{ + MonoInst *ins = NULL; + MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER); + MONO_ADD_INS (cfg->cbb, ins); + ins->backend.memory_barrier_kind = kind; + + return ins; +} + +static MonoInst* mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) { MonoInst *ins = NULL; @@ -4444,9 +4456,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign MONO_ADD_INS (cfg->cbb, ins); return ins; } else if (strcmp (cmethod->name, "MemoryBarrier") == 0) { - MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER); - MONO_ADD_INS (cfg->cbb, ins); - return ins; + return emit_memory_barrier (cfg, FullBarrier); } } else if (cmethod->klass == mono_defaults.monitor_class) { #if defined(MONO_ARCH_MONITOR_OBJECT_REG) @@ -7548,6 +7558,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b ins_flag = 0; MONO_ADD_INS (bblock, ins); *sp++ = ins; + if (ins->flags & MONO_INST_VOLATILE) { + /* Volatile loads have acquire semantics, see 12.6.7 in Ecma 335 */ + /* FIXME it's questionable if acquire semantics require full barrier or just LoadLoad*/ + emit_memory_barrier (cfg, FullBarrier); + } ++ip; break; case CEE_STIND_REF: @@ -7564,6 +7579,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b NEW_STORE_MEMBASE (cfg, ins, stind_to_store_membase (*ip), sp [0]->dreg, 0, sp [1]->dreg); ins->flags |= ins_flag; ins_flag = 0; + + if (ins->flags & MONO_INST_VOLATILE) { + /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */ + /* FIXME it's questionable if acquire semantics require full barrier or just LoadLoad*/ + emit_memory_barrier (cfg, FullBarrier); + } + MONO_ADD_INS (bblock, ins); if (cfg->gen_write_barriers && *ip == CEE_STIND_REF && method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER && !((sp [1]->opcode == OP_PCONST) && (sp [1]->inst_p0 == 0))) diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 26e51a2b243..b3e0d9ae411 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -776,6 +776,7 @@ struct MonoInst { MonoInst *spill_var; /* for OP_ICONV_TO_R8_RAW and OP_FCONV_TO_R8_X */ guint16 source_opcode; /*OP_XCONV_R8_TO_I4 needs to know which op was used to do proper widening*/ int pc_offset; /* OP_GC_LIVERANGE_START/END */ + int memory_barrier_kind; /* see mono-memory-model.h for valid values */ } backend; MonoClass *klass; diff --git a/mono/utils/mono-memory-model.h b/mono/utils/mono-memory-model.h index 6fbaeaf6455..8bedf068139 100644 --- a/mono/utils/mono-memory-model.h +++ b/mono/utils/mono-memory-model.h @@ -11,7 +11,7 @@ #define _MONO_UTILS_MONO_MEMMODEL_H_ #include -#include "utils/mono-membar.h" +#include /* In order to allow for fast concurrent code, we must use fencing to properly order @@ -29,9 +29,9 @@ Each arch must define which ones needs fencing. We assume 3 kinds of barriers are available: load, store and memory (load+store). TODO: Add support for weaker forms of CAS such as present on ARM. -TODO: replace all explicit uses of memory barriers with macros from this section. This will make -a nicer read of lazy init code. -TODO: if we find places where a data depencency could replace barriers, add macros here to help with it +TODO: replace all explicit uses of memory barriers with macros from this section. This will make a nicer read of lazy init code. +TODO: if we find places where a data depencency could replace barriers, add macros here to help with it +TODO: some arch with strong consistency, such as x86, support weaker access. We might need to expose more kinds of barriers once we exploit this. */ #define MEMORY_BARRIER mono_memory_barrier -- 2.11.4.GIT