Fix GC_noop6 definition to avoid its calls to be optimized away
authorIvan Maidanski <ivmai@mail.ru>
Mon, 12 Dec 2016 23:34:28 +0000 (02:34 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 12 Dec 2016 23:34:28 +0000 (02:34 +0300)
* include/private/gc_priv.h (GC_ATTR_NOINLINE): New macro (effective
for GCC/Clang and MS VC currently).
* mark.c (GC_noop6): Use GC_ATTR_NOINLINE attribute; call
AO_compiler_barrier if available, otherwise call GC_noop1(0); add
comment.

include/private/gc_priv.h
mark.c

index 3d80ac4..a92fba0 100644 (file)
@@ -192,6 +192,16 @@ typedef char * ptr_t;   /* A generic pointer to which we can add        */
 # define GC_INLINE static
 #endif
 
+#ifndef GC_ATTR_NOINLINE
+# if __GNUC__ >= 4
+#   define GC_ATTR_NOINLINE __attribute__((__noinline__))
+# elif _MSC_VER >= 14
+#   define GC_ATTR_NOINLINE __declspec(noinline)
+# else
+#   define GC_ATTR_NOINLINE /* empty */
+# endif
+#endif
+
 #ifndef GC_API_OSCALL
   /* This is used to identify GC routines called by name from OS.       */
 # if defined(__GNUC__)
diff --git a/mark.c b/mark.c
index f631ab5..1fd7a66 100644 (file)
--- a/mark.c
+++ b/mark.c
 
 /* Make arguments appear live to compiler.  Put here to minimize the    */
 /* risk of inlining.  Used to minimize junk left in registers.          */
+GC_ATTR_NOINLINE
 void GC_noop6(word arg1 GC_ATTR_UNUSED, word arg2 GC_ATTR_UNUSED,
               word arg3 GC_ATTR_UNUSED, word arg4 GC_ATTR_UNUSED,
               word arg5 GC_ATTR_UNUSED, word arg6 GC_ATTR_UNUSED)
 {
-  /* Empty */
+  /* Avoid GC_noop6 calls to be optimized away. */
+# ifdef AO_compiler_barrier
+    AO_compiler_barrier(); /* to serve as a special side-effect */
+# else
+    GC_noop1(0);
+# endif
 }
 
 /* Single argument version, robust against whole program analysis. */