From 7226ce4ed4d7696d5b0cae748f68635b668f7091 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 13 Dec 2016 02:34:28 +0300 Subject: [PATCH] Fix GC_noop6 definition to avoid its calls to be optimized away (fix commits e3ec4a5, 1586a21) * 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 PARALLEL_MARK (or GC_PTHREADS and not GC_WIN32_THREADS), otherwise call GC_noop1(0); add comment. --- include/private/gc_priv.h | 10 ++++++++++ mark.c | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index a1a52f7e..3c6f0433 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -171,6 +171,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 2b88cb05..31566666 100644 --- a/mark.c +++ b/mark.c @@ -24,11 +24,18 @@ /* 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. */ +# if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) \ + || defined(PARALLEL_MARK) + AO_compiler_barrier(); /* to serve as a special side-effect */ +# else + GC_noop1(0); +# endif } /* Single argument version, robust against whole program analysis. */ -- 2.40.0