[checked-build] Add compile flag to disable checked-build tests selectively
authorLudovic Henry <ludovic@xamarin.com>
Wed, 20 Jan 2016 20:12:33 +0000 (20:12 +0000)
committerLudovic Henry <ludovic@xamarin.com>
Thu, 21 Jan 2016 11:37:55 +0000 (11:37 +0000)
configure.ac
mono/utils/checked-build.c
mono/utils/checked-build.h

index 82421f3593ade89387572920be92d4c9d78b9fce..9e6e66c189c4cdaaa37a47fcaecc0e4396d474a3 100644 (file)
@@ -3530,6 +3530,29 @@ AC_ARG_WITH(checked_build, [  --with-checked-build=yes|no      Enable checked bu
        fi
 ], [with_checked_build=no])
 
+if test x$with_checked_build != xno ; then
+       DISABLED_CHECKED_BUILD_TEST=none
+
+       AC_ARG_ENABLE(checked_build_test, [  --enable-checked-build-test=LIST      drop support for LIST checked build tests. LIST is a comma-separated list from: gc, metadata, thread.],
+       [
+               for feature in `echo "$enable_checked_build_test" | sed -e "s/,/ /g"`; do
+                       eval "mono_checked_build_test_disable_$feature='yes'"
+               done
+               DISABLED_CHECKED_BUILD_TEST=$enable_checked_build_test
+       ],[])
+
+       if test "x$mono_checked_build_test_disable_gc" = "xyes"; then
+               AC_DEFINE(DISABLE_CHECKED_BUILD_GC, 1, [Disable GC checked build])
+       fi
+
+       if test "x$mono_checked_build_test_disable_metadata" = "xyes"; then
+               AC_DEFINE(DISABLE_CHECKED_BUILD_METADATA, 1, [Disable metadata checked build])
+       fi
+
+       if test "x$mono_checked_build_test_disable_thread" = "xyes"; then
+               AC_DEFINE(DISABLE_CHECKED_BUILD_THREAD, 1, [Disable thread checked build])
+       fi
+fi
 
 AC_CHECK_HEADER([malloc.h], 
                [AC_DEFINE([HAVE_USR_INCLUDE_MALLOC_H], [1], 
index eedb554789203998a8c9680618106473994a3789..624d1b88b8eb595500bcdad638d007d56f026ffe 100644 (file)
@@ -7,6 +7,7 @@
  * (C) 2015 Xamarin
  */
 #include <config.h>
+
 #ifdef CHECKED_BUILD
 
 #include <mono/utils/checked-build.h>
 #include <mono/metadata/reflection-internals.h>
 #include <glib.h>
 
+#ifdef HAVE_BACKTRACE_SYMBOLS
+#include <execinfo.h>
+#endif
+
+typedef struct {
+       GPtrArray *transitions;
+       guint32 in_gc_critical_region;
+} CheckState;
+
+static MonoNativeTlsKey thread_status;
+
+void
+checked_build_init (void)
+{
+       mono_native_tls_alloc (&thread_status, NULL);
+}
+
+static CheckState*
+get_state (void)
+{
+       CheckState *state = mono_native_tls_get_value (thread_status);
+       if (!state) {
+               state = g_new0 (CheckState, 1);
+               state->transitions = g_ptr_array_new ();
+               mono_native_tls_set_value (thread_status, state);
+       }
+
+       return state;
+}
+
+#if !defined(DISABLE_CHECKED_BUILD_THREAD)
+
 #define MAX_NATIVE_BT 6
 #define MAX_NATIVE_BT_PROBE (MAX_NATIVE_BT + 5)
 #define MAX_TRANSITIONS 3
 
-
 #ifdef HAVE_BACKTRACE_SYMBOLS
-#include <execinfo.h>
 
 //XXX We should collect just the IPs and lazily symbolificate them.
 static int
@@ -78,39 +109,12 @@ translate_backtrace (gpointer native_trace[], int size)
 
 #endif
 
-
-typedef struct {
-       GPtrArray *transitions;
-       guint32 in_gc_critical_region;
-} CheckState;
-
 typedef struct {
        const char *name;
        int from_state, next_state, suspend_count, suspend_count_delta, size;
        gpointer backtrace [MAX_NATIVE_BT_PROBE];
 } ThreadTransition;
 
-static MonoNativeTlsKey thread_status;
-
-void
-checked_build_init (void)
-{
-       mono_native_tls_alloc (&thread_status, NULL);
-}
-
-static CheckState*
-get_state (void)
-{
-       CheckState *state = mono_native_tls_get_value (thread_status);
-       if (!state) {
-               state = g_new0 (CheckState, 1);
-               state->transitions = g_ptr_array_new ();
-               mono_native_tls_set_value (thread_status, state);
-       }
-
-       return state;
-}
-
 static void
 free_transition (ThreadTransition *t)
 {
@@ -139,6 +143,10 @@ checked_build_thread_transition (const char *transition, void *info, int from_st
        g_ptr_array_add (state->transitions, t);
 }
 
+#endif /* !defined(DISABLE_CHECKED_BUILD_THREAD) */
+
+#if !defined(DISABLE_CHECKED_BUILD_GC)
+
 static void
 assertion_fail (const char *msg, ...)
 {
@@ -265,6 +273,10 @@ assert_in_gc_critical_region (void)
                assertion_fail("Expected GC critical region");
 }
 
+#endif /* !defined(DISABLE_CHECKED_BUILD_GC) */
+
+#if !defined(DISABLE_CHECKED_BUILD_METADATA)
+
 // check_metadata_store et al: The goal of these functions is to verify that if there is a pointer from one mempool into
 // another, that the pointed-to memory is protected by the reference count mechanism for MonoImages.
 //
@@ -598,4 +610,6 @@ check_metadata_store_local (void *from, void *to)
     check_mempool_may_reference_mempool (from, to, TRUE);
 }
 
+#endif /* !defined(DISABLE_CHECKED_BUILD_METADATA) */
+
 #endif /* CHECKED_BUILD */
index b2e90d0469f008ea6963e770560aa055837934e8..28932d8c630204ff83e6bae5d3cd46cb49f2c062 100644 (file)
 // The current reason why this is needed is for pointers to constant strings, which the checker cannot verify yet.
 #define CHECKED_METADATA_WRITE_PTR_EXEMPT(ptr, val) do { (ptr) = (val); } while (0)
 
-#ifdef CHECKED_BUILD
+#if defined(CHECKED_BUILD)
 
 #define g_assert_checked g_assert
 
+/*
+This can be called by embedders
+*/
+#define MONO_REQ_API_ENTRYPOINT
+
+/*
+The JIT will generate code that will land on this function
+*/
+#define MONO_REQ_RUNTIME_ENTRYPOINT
+
+#define CHECKED_MONO_INIT() do { checked_build_init (); } while (0)
+
+void checked_build_init (void);
+
+#else
+
+#define g_assert_checked(...)
+
+#define MONO_REQ_API_ENTRYPOINT
+#define MONO_REQ_RUNTIME_ENTRYPOINT
+
+#define CHECKED_MONO_INIT()
+
+#endif /* CHECKED_BUILD */
+
+#if defined(CHECKED_BUILD) && !defined(DISABLE_CHECKED_BUILD_GC)
+
 /*
 GC runtime modes rules:
 
@@ -101,6 +128,31 @@ Functions that can be called from both coop or preept modes.
                assert_in_gc_critical_region(); \
        } while(0)
 
+void assert_gc_safe_mode (void);
+void assert_gc_unsafe_mode (void);
+void assert_gc_neutral_mode (void);
+
+void* critical_gc_region_begin(void);
+void critical_gc_region_end(void* token);
+void assert_not_in_gc_critical_region(void);
+void assert_in_gc_critical_region (void);
+
+#else
+
+#define MONO_REQ_GC_SAFE_MODE
+#define MONO_REQ_GC_UNSAFE_MODE
+#define MONO_REQ_GC_NEUTRAL_MODE
+
+#define MONO_PREPARE_GC_CRITICAL_REGION
+#define MONO_FINISH_GC_CRITICAL_REGION
+
+#define MONO_REQ_GC_NOT_CRITICAL
+#define MONO_REQ_GC_CRITICAL
+
+#endif /* defined(CHECKED_BUILD) && !defined(DISABLE_CHECKED_BUILD_GC) */
+
+#if defined(CHECKED_BUILD) && !defined(DISABLE_CHECKED_BUILD_METADATA)
+
 // Use when writing a pointer from one image or imageset to another.
 #define CHECKED_METADATA_WRITE_PTR(ptr, val) do {    \
     check_metadata_store (&(ptr), (val));    \
@@ -119,61 +171,29 @@ Functions that can be called from both coop or preept modes.
     mono_atomic_store_release (&(ptr), (val));    \
 } while (0);
 
-/*
-This can be called by embedders
-*/
-#define MONO_REQ_API_ENTRYPOINT
+void check_metadata_store(void *from, void *to);
+void check_metadata_store_local(void *from, void *to);
 
-/*
-The JIT will generate code that will land on this function
-*/
-#define MONO_REQ_RUNTIME_ENTRYPOINT
+#else
 
-#define CHECKED_MONO_INIT() do { checked_build_init (); } while (0)
+#define CHECKED_METADATA_WRITE_PTR(ptr, val) do { (ptr) = (val); } while (0)
+#define CHECKED_METADATA_WRITE_PTR_LOCAL(ptr, val) do { (ptr) = (val); } while (0)
+#define CHECKED_METADATA_WRITE_PTR_ATOMIC(ptr, val) do { mono_atomic_store_release (&(ptr), (val)); } while (0)
+
+#endif /* defined(CHECKED_BUILD) && !defined(DISABLE_CHECKED_BUILD_METADATA) */
+
+#if defined(CHECKED_BUILD) && !defined(DISABLE_CHECKED_BUILD_THREAD)
 
 #define CHECKED_BUILD_THREAD_TRANSITION(transition, info, from_state, suspend_count, next_state, suspend_count_delta) do {     \
        checked_build_thread_transition (transition, info, from_state, suspend_count, next_state, suspend_count_delta); \
 } while (0)
 
-void assert_gc_safe_mode (void);
-void assert_gc_unsafe_mode (void);
-void assert_gc_neutral_mode (void);
-
-void* critical_gc_region_begin(void);
-void critical_gc_region_end(void* token);
-void assert_not_in_gc_critical_region(void);
-void assert_in_gc_critical_region (void);
-
-void checked_build_init (void);
 void checked_build_thread_transition(const char *transition, void *info, int from_state, int suspend_count, int next_state, int suspend_count_delta);
 
-void check_metadata_store(void *from, void *to);
-void check_metadata_store_local(void *from, void *to);
-
 #else
 
-#define g_assert_checked(...)
-
-#define MONO_REQ_GC_SAFE_MODE
-#define MONO_REQ_GC_UNSAFE_MODE
-#define MONO_REQ_GC_NEUTRAL_MODE
-#define MONO_REQ_API_ENTRYPOINT
-#define MONO_REQ_RUNTIME_ENTRYPOINT
-
-#define MONO_PREPARE_GC_CRITICAL_REGION
-#define MONO_FINISH_GC_CRITICAL_REGION
-
-#define MONO_REQ_GC_NOT_CRITICAL
-#define MONO_REQ_GC_CRITICAL
-
-
-#define CHECKED_MONO_INIT()
 #define CHECKED_BUILD_THREAD_TRANSITION(transition, info, from_state, suspend_count, next_state, suspend_count_delta)
 
-#define CHECKED_METADATA_WRITE_PTR(ptr, val) do { (ptr) = (val); } while (0)
-#define CHECKED_METADATA_WRITE_PTR_LOCAL(ptr, val) do { (ptr) = (val); } while (0)
-#define CHECKED_METADATA_WRITE_PTR_ATOMIC(ptr, val) do { mono_atomic_store_release (&(ptr), (val)); } while (0)
-
-#endif /* CHECKED_BUILD */
+#endif /* defined(CHECKED_BUILD) && !defined(DISABLE_CHECKED_BUILD_THREAD) */
 
-#endif
+#endif /* __CHECKED_BUILD_H__ */