[aot] Rewrite the AOT profiler. (#4176)
[mono.git] / mono / utils / mono-compiler.h
index 2b3b86e2ef2e305dd8de427b6eb4902b999283de..8d83f5d672e2cae2bc7ed2a9099c42e9c0599016 100644 (file)
 #define MONO_ATTR_USED
 #endif
 
-#ifdef HAVE_KW_THREAD
-
-#define MONO_HAVE_FAST_TLS
-#define MONO_FAST_TLS_SET(x,y) x = y
-#define MONO_FAST_TLS_GET(x) x
-#define MONO_FAST_TLS_INIT(x)
-#define MONO_FAST_TLS_DECLARE(x) static __thread gpointer x MONO_TLS_FAST MONO_ATTR_USED;
-
-#if HAVE_TLS_MODEL_ATTR
-
-#if defined(__PIC__) && !defined(PIC)
-/*
- * Must be compiling -fPIE, for executables.  Build PIC
- * but with initial-exec.
- * http://bugs.gentoo.org/show_bug.cgi?id=165547
- */
-#define PIC
-#define PIC_INITIAL_EXEC
-#endif
-
-/* 
- * Define this if you want a faster libmono, which cannot be loaded dynamically as a 
- * module.
- */
-//#define PIC_INITIAL_EXEC
-
-#if defined(PIC)
-
-#ifdef PIC_INITIAL_EXEC
-#define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
-#else
-#if defined (__powerpc__)
-/* local dynamic requires a call to __tls_get_addr to look up the
-   TLS block address via the Dynamic Thread Vector. In this case Thread
-   Pointer relative offsets can't be used as this modules TLS was
-   allocated separately (none contiguoiusly) from the initial TLS
-   block.
-
-   For now we will disable this. */
-#define MONO_TLS_FAST
-#else
-#define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
-#endif
-#endif
-
-#else
-
-#define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
-
-#endif
-
-#else
-#define MONO_TLS_FAST 
-#endif
-
-#if defined(__GNUC__) && defined(__i386__)
-#if defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) do { int tmp; __asm ("call 1f; 1: popl %0; addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %0; movl " #var "@gotntpoff(%0), %1" : "=r" (tmp), "=r" (offset)); } while (0)
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
-#endif
-#elif defined(__x86_64__)
-#if defined(PIC)
-// This only works if libmono is linked into the application
-#define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (foo)); offset = foo; } while (0)
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
-#endif
-#elif defined(__ia64__) && !defined(__INTEL_COMPILER)
-#if defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @ltoff(@tprel(" #var "#)), gp ;; ld8 %0 = [%0]\n" : "=r" (offset))
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
-#endif
-#elif defined(__arm__) && defined(__ARM_EABI__) && !defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("    ldr     %0, 1f; b 2f; 1: .word " #var "(tpoff); 2:" : "=r" (offset))
-#elif defined(__aarch64__) && !defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       __asm ( "mov %0, #0\n add %0, %0, #:tprel_hi12:" #var "\n add %0, %0, #:tprel_lo12_nc:" #var "\n" \
-                       : "=r" (offset))
-#elif defined(__mono_ppc__) && defined(__GNUC__)
-#if defined(PIC)
-#ifdef PIC_INITIAL_EXEC
-
-#if defined(__mono_ppc64__)
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       do { long off; \
-       __asm ( "ld     %0," #var "@got@tprel(2)\n" \
-       : "=r" (off)); \
-       (offset) = off; } while (0)
-#else
-/* must be powerpc32 */
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       __asm ( "lwz    %0," #var "@got@tprel(30)\n" \
-       : "=r" (offset))
-#endif
-
-#else
-
-/* local dynamic requires a call to __tls_get_addr to look up the
-   TLS block address via the Dynamic Thread Vector. In this case Thread
-   Pointer relative offsets can't be used as this modules TLS was
-   allocated separately (none contiguoiusly) from the initial TLS
-   block.
-
-   For now we will disable this. */
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-
-#endif
-#else
-/* Must be local-exec TLS */
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       __asm ( "lis    %0," #var "@tprel@ha\n" \
-               "addi   %0,%0, " #var "@tprel@l\n" \
-       : "=r" (offset))
-#endif
-#elif defined(__s390x__)
-# if defined(__PIC__)
-#  if !defined(__PIE__)
-// This only works if libmono is linked into the application
-#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                \
-                                               __asm__ ("basr  %%r1,0\n\t"                     \
-                                                        "j     0f\n\t"                         \
-                                                        ".quad " #var "@TLSGD\n"               \
-                                                        "0:\n\t"                               \
-                                                        "lg    %%r2,4(%%r1)\n\t"               \
-                                                        "brasl %%r14,__tls_get_offset@PLT:tls_gdcall:"#var"\n\t" \
-                                                        "lgr   %0,%%r2\n\t"                    \
-                                                       : "=r" (foo) :                          \
-                                                       : "1", "2", "14", "cc");                \
-                                               offset = foo; } while (0)
-#  elif __PIE__ == 1
-#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                        \
-                                               __asm__ ("lg    %0," #var "@GOTNTPOFF(%%r12)\n\t"       \
-                                                        : "=r" (foo));                                 \
-                                               offset = foo; } while (0)
-#  elif __PIE__ == 2
-#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                \
-                                               __asm__ ("larl  %%r1," #var "@INDNTPOFF\n\t"    \
-                                                        "lg    %0,0(%%r1)\n\t"                 \
-                                                        : "=r" (foo) :                         \
-                                                        : "1", "cc");                          \
-                                               offset = foo; } while (0)
-#  endif
-# else
-#  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                         \
-                                               __asm__ ("basr  %%r1,0\n\t"             \
-                                                        "j     0f\n\t"                 \
-                                                        ".quad " #var "@NTPOFF\n"      \
-                                                        "0:\n\t"                       \
-                                                        "lg    %0,4(%%r1)\n\t"         \
-                                                       : "=r" (foo) : : "1");          \
-                                               offset = foo; } while (0)
-# endif
+#ifdef __GNUC__
+#define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) __attribute__((format(printf,fmt_pos,arg_pos)))
 #else
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
+#define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos)
 #endif
 
-#if defined(PIC) && !defined(PIC_INITIAL_EXEC)
-/* 
- * The above definitions do not seem to work if libmono is loaded dynamically as a module.
- * See bug #78767.
- */
-#undef MONO_THREAD_VAR_OFFSET
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-#endif
-
-#elif !defined(MONO_CROSS_COMPILE) && defined(PLATFORM_MACOSX) && (defined(__i386__) || defined(__x86_64__))
-
-#define MONO_HAVE_FAST_TLS 1
-#define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
-#define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
-#define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
-#define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
-#define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
-
-#define MONO_THREAD_VAR_OFFSET(x,y) ({ \
-       __typeof__(x) _x = (x);                 \
-       pthread_key_t _y;       \
-       (void) (&_x == &_y);            \
-       y = (gint32) x; })
-
-#elif !defined(MONO_CROSS_COMPILE) && (defined(PLATFORM_ANDROID) || defined(TARGET_IOS)) && defined(TARGET_ARM)
-
-#define MONO_HAVE_FAST_TLS
-#define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
-#define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
-#define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
-#define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
-
-#define MONO_THREAD_VAR_OFFSET(var, offset) do { offset = (int)var; } while (0)
-
-#else /* no HAVE_KW_THREAD */
-
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-
-/*Macros to facilitate user code*/
-#define MONO_FAST_TLS_INIT(x)
-#endif
-
-#if defined(MONO_HAVE_FAST_TLS) && !defined(MONO_FAST_TLS_ADDR)
-#define MONO_FAST_TLS_ADDR(x) (&(x))
-#endif
-
-
 /* Deal with Microsoft C compiler differences */
 #ifdef _MSC_VER
 
 #include <direct.h>
 #define mkdir(x)       _mkdir(x)
 
-/* GCC specific functions aren't available */
-#define __builtin_return_address(x)    NULL
-
 #define __func__ __FUNCTION__
 
 #include <BaseTsd.h>
@@ -265,6 +63,13 @@ typedef SSIZE_T ssize_t;
 
 #endif /* _MSC_VER */
 
+#ifdef _MSC_VER
+// Quiet Visual Studio linker warning, LNK4221, in cases when this source file intentional ends up empty.
+#define MONO_EMPTY_SOURCE_FILE(x) void __mono_win32_ ## x ## _quiet_lnk4221 (void) {}
+#else
+#define MONO_EMPTY_SOURCE_FILE(x)
+#endif
+
 #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN
 #if MONO_LLVM_LOADED
 #define MONO_LLVM_INTERNAL MONO_API
@@ -275,11 +80,8 @@ typedef SSIZE_T ssize_t;
 #define MONO_LLVM_INTERNAL 
 #endif
 
-#if HAVE_DEPRECATED
-#define MONO_DEPRECATED __attribute__ ((deprecated))
-#else
-#define MONO_DEPRECATED 
-#endif
+/* Used to mark internal functions used by the profiler modules */
+#define MONO_PROFILER_API MONO_API
 
 #ifdef __GNUC__
 #define MONO_ALWAYS_INLINE __attribute__((always_inline))
@@ -303,5 +105,9 @@ typedef SSIZE_T ssize_t;
 #define MONO_COLD
 #endif
 
+#if defined (__GNUC__) && defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
+#define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
 #endif /* __UTILS_MONO_COMPILER_H__*/