Extract the code to emit a memory barrier. Add a memory_barrier_kind field to MonoIns...
authorRodrigo Kumpera <kumpera@gmail.com>
Sun, 12 Jun 2011 01:05:19 +0000 (22:05 -0300)
committerRodrigo Kumpera <kumpera@gmail.com>
Sun, 12 Jun 2011 01:26:12 +0000 (22:26 -0300)
mono/mini/method-to-ir.c
mono/mini/mini.h
mono/utils/mono-memory-model.h

index 57d8f6df03d64207cdd255790d042e61d5629f62..4256b198f981c8b57e25c437de9c89fbb2ac0dbb 100644 (file)
@@ -51,6 +51,7 @@
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/profiler.h>
 #include <mono/utils/mono-compiler.h>
+#include <mono/utils/mono-memory-model.h>
 #include <mono/metadata/mono-basic-block.h>
 
 #include "mini.h"
@@ -4272,6 +4273,17 @@ mini_emit_inst_for_ctor (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignat
        return ins;
 }
 
+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)
 {
@@ -4442,9 +4454,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) {
 
@@ -7628,11 +7638,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        MONO_ADD_INS (bblock, ins);
                        *sp++ = ins;
                        if (ins->flags & MONO_INST_VOLATILE) {
-                               MonoInst *barrier;
-
                                /* Volatile loads have acquire semantics, see 12.6.7 in Ecma 335 */
-                               MONO_INST_NEW (cfg, barrier, OP_MEMORY_BARRIER);
-                               MONO_ADD_INS (cfg->cbb, barrier);
+                               /* FIXME it's questionable if acquire semantics require full barrier or just LoadLoad*/
+                               emit_memory_barrier (cfg, FullBarrier);
                        }
                        ++ip;
                        break;
@@ -7652,11 +7660,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        ins_flag = 0;
 
                        if (ins->flags & MONO_INST_VOLATILE) {
-                               MonoInst *barrier;
-
                                /* Volatile stores have release semantics, see 12.6.7 in Ecma 335 */
-                               MONO_INST_NEW (cfg, barrier, OP_MEMORY_BARRIER);
-                               MONO_ADD_INS (cfg->cbb, barrier);
+                               /* FIXME it's questionable if acquire semantics require full barrier or just LoadLoad*/
+                               emit_memory_barrier (cfg, FullBarrier);
                        }
 
                        MONO_ADD_INS (bblock, ins);
index aea2e754b6ff2f2f9647a4423a6cf4705278140d..e3d5e54e1c5c93095f291c11dc86554977c7e7a5 100644 (file)
@@ -735,6 +735,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;
index 6fbaeaf64553fa1eb99b56aef5ac90c8459020b7..8bedf0681398a774825eee2b747ceb4f08c736fa 100644 (file)
@@ -11,7 +11,7 @@
 #define _MONO_UTILS_MONO_MEMMODEL_H_
 
 #include <config.h>
-#include "utils/mono-membar.h"
+#include <mono/utils/mono-membar.h>
 
 /*
 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