X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-compiler.h;h=f8481d004d10e34da4cf629fef17b4bf38190137;hb=4058c2be43ec605cdcc57e9d678251339349cb5f;hp=7becf4816ffd571052129646b5c7c39ae7db4275;hpb=0b65fb9d99f02f2a330b20eafcfe57fec34c0465;p=mono.git diff --git a/mono/utils/mono-compiler.h b/mono/utils/mono-compiler.h index 7becf4816ff..f8481d004d1 100644 --- a/mono/utils/mono-compiler.h +++ b/mono/utils/mono-compiler.h @@ -1,3 +1,7 @@ +/** + * \file + */ + #ifndef __UTILS_MONO_COMPILER_H__ #define __UTILS_MONO_COMPILER_H__ @@ -6,224 +10,22 @@ * compiler behaviours. */ #include +#if defined(HAVE_UNISTD_H) +#include +#endif #ifdef __GNUC__ -#define MONO_ATTR_USED __attribute__ ((used)) +#define MONO_ATTR_USED __attribute__ ((__used__)) #else #define MONO_ATTR_USED #endif #ifdef __GNUC__ -#define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) __attribute__((format(printf,fmt_pos,arg_pos))) +#define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) __attribute__ ((__format__(__printf__,fmt_pos,arg_pos))) #else #define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) #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 -#else -#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1 -#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 @@ -268,7 +70,14 @@ typedef SSIZE_T ssize_t; #endif /* _MSC_VER */ -#if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN +#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(HOST_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN #if MONO_LLVM_LOADED #define MONO_LLVM_INTERNAL MONO_API #else @@ -278,8 +87,11 @@ typedef SSIZE_T ssize_t; #define MONO_LLVM_INTERNAL #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)) +#define MONO_ALWAYS_INLINE __attribute__ ((__always_inline__)) #elif defined(_MSC_VER) #define MONO_ALWAYS_INLINE __forceinline #else @@ -287,7 +99,7 @@ typedef SSIZE_T ssize_t; #endif #ifdef __GNUC__ -#define MONO_NEVER_INLINE __attribute__((noinline)) +#define MONO_NEVER_INLINE __attribute__ ((__noinline__)) #elif defined(_MSC_VER) #define MONO_NEVER_INLINE __declspec(noinline) #else @@ -295,7 +107,7 @@ typedef SSIZE_T ssize_t; #endif #ifdef __GNUC__ -#define MONO_COLD __attribute__((cold)) +#define MONO_COLD __attribute__ ((__cold__)) #else #define MONO_COLD #endif @@ -304,5 +116,54 @@ typedef SSIZE_T ssize_t; #define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif +#if defined(__has_feature) +#if __has_feature(thread_sanitizer) +#define MONO_HAS_CLANG_THREAD_SANITIZER 1 +#else +#define MONO_HAS_CLANG_THREAD_SANITIZER 0 +#endif +#else +#define MONO_HAS_CLANG_THREAD_SANITIZER 0 +#endif + +/* Used to tell Clang's ThreadSanitizer to not report data races that occur within a certain function */ +#if MONO_HAS_CLANG_THREAD_SANITIZER +#define MONO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize("thread"))) +#else +#define MONO_NO_SANITIZE_THREAD +#endif + +/* Used when building with Android NDK's unified headers */ +#if defined(HOST_ANDROID) && defined (ANDROID_UNIFIED_HEADERS) +#if __ANDROID_API__ < 21 + +typedef int32_t __mono_off32_t; + +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +#if !defined(mmap) +/* Unified headers before API 21 do not declare mmap when LARGE_FILES are used (via -D_FILE_OFFSET_BITS=64) + * which is always the case when Mono build targets Android. The problem here is that the unified headers + * map `mmap` to `mmap64` if large files are enabled but this api exists only in API21 onwards. Therefore + * we must carefully declare the 32-bit mmap here without changing the ABI along the way. Carefully because + * in this instance off_t is redeclared to be 64-bit and that's not what we want. + */ +void* mmap (void*, size_t, int, int, int, __mono_off32_t); +#endif /* !mmap */ + +#ifdef HAVE_SYS_SENDFILE_H +#include +#endif + +#if !defined(sendfile) +/* The same thing as with mmap happens with sendfile */ +ssize_t sendfile (int out_fd, int in_fd, __mono_off32_t* offset, size_t count); +#endif /* !sendfile */ + +#endif /* __ANDROID_API__ < 21 */ +#endif /* HOST_ANDROID && ANDROID_UNIFIED_HEADERS */ + #endif /* __UTILS_MONO_COMPILER_H__*/