sync the repo
[hiphop-php.git] / hphp / util / portability.h
blob37e8b8102c7a1a40b19cbda24d3745b24a478400
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #pragma once
18 #if !defined(NO_FOLLY)
19 #include <folly/Likely.h> // defining LIKELY/UNLIKELY is part of this header
20 #include <folly/Portability.h>
21 #include <folly/CPortability.h> // FOLLY_DISABLE_ADDRESS_SANITIZER, FOLLY_EXPORT
22 #endif
24 //////////////////////////////////////////////////////////////////////
27 * Various macros to make certain things conditional on either
28 * compiler or architecture.
30 * Currently we don't *really* compile on anything other than gcc or
31 * sometimes clang, and there are some parts of the code using
32 * __attribute__ stuff directly, but some things go through these
33 * macros to make it maybe easier to change later.
36 //////////////////////////////////////////////////////////////////////
38 // TODO: does clang define __GNUC__ ?
39 #ifndef __GNUC__
40 # define __attribute__(x)
41 #endif
43 //////////////////////////////////////////////////////////////////////
45 #ifdef ATTRIBUTE_UNUSED
46 # undef ATTRIBUTE_UNUSED
47 #endif
48 #ifdef ATTRIBUTE_PRINTF
49 # undef ATTRIBUTE_PRINTF
50 #endif
51 #ifdef ATTRIBUTE_PRINTF_STRING
52 # undef ATTRIBUTE_PRINTF_STRING
53 #endif
55 #ifdef FOLLY_PRINTF_FORMAT
56 #define ATTRIBUTE_PRINTF_STRING FOLLY_PRINTF_FORMAT
57 #else
58 #define ATTRIBUTE_PRINTF_STRING
59 #endif
61 #define ATTRIBUTE_PRINTF(a1, a2) \
62 __attribute__((__format__ (__printf__, a1, a2)))
63 #define ATTRIBUTE_UNUSED __attribute__((__unused__))
64 #define ATTRIBUTE_USED __attribute__((__used__))
65 #ifndef NDEBUG
66 # define FLATTEN /*nop*/
67 # define ALWAYS_INLINE inline
68 # define INLINE_FLATTEN inline
69 #else
70 # define FLATTEN __attribute__((__flatten__))
71 # define ALWAYS_INLINE inline __attribute__((__always_inline__))
72 # define INLINE_FLATTEN inline __attribute__((__always_inline__,__flatten__))
73 #endif
74 #define NEVER_INLINE __attribute__((__noinline__))
75 #define UNUSED __attribute__((__unused__))
77 #ifdef __clang__
78 #define NO_OPT [[clang::optnone]]
79 #define EXTERNALLY_VISIBLE ATTRIBUTE_USED FOLLY_EXPORT
80 #else
81 #define NO_OPT __attribute__((__optimize__("O0")))
82 #define EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
83 #endif
85 #if defined(__GNUC__)
86 # define HHVM_ATTRIBUTE_WEAK __attribute__((__weak__))
87 #elif defined(__clang__)
88 # define HHVM_ATTRIBUTE_WEAK __attribute__((__weak_import__))
89 #else
90 # define HHVM_ATTRIBUTE_WEAK
91 #endif
93 #ifndef NDEBUG
94 # define DEBUG_ONLY /* nop */
95 #else
96 # define DEBUG_ONLY UNUSED
97 #endif
99 #ifndef NDEBUG
100 #define DEBUG_NOEXCEPT
101 #else
102 #define DEBUG_NOEXCEPT noexcept
103 #endif
107 * AARCH64 needs to create a walkable stack frame for
108 * getFrameRegs() when a FixupEntry isIndirect()
110 #ifdef __aarch64__
111 #define AARCH64_WALKABLE_FRAME() asm("" ::: "memory");
112 #else
113 #define AARCH64_WALKABLE_FRAME()
114 #endif
118 * We need to keep some unreferenced functions from being removed by
119 * the linker. There is no compile time mechanism for doing this, but
120 * by putting them in the same section as some other, referenced function
121 * in the same file, we can keep them around.
123 * So this macro should be used to mark at least one function that is
124 * referenced, and other functions that are not referenced in the same
125 * file.
127 * Note: this may not work properly with LTO. We'll revisit when/if we
128 * move to it.
130 # define KEEP_SECTION \
131 __attribute__((__section__(".text.keep")))
133 //////////////////////////////////////////////////////////////////////
134 // DECLARE_FRAME_POINTER
136 #if defined(__x86_64__)
138 # define DECLARE_FRAME_POINTER(fp) \
139 auto const fp = (ActRec*) __builtin_frame_address(0)
140 # define FRAME_POINTER_IS_ACCURATE
142 #elif defined(_M_X64)
144 // TODO: FIXME! Without this implemented properly, the JIT
145 // will fail "pretty spectacularly".
146 # define DECLARE_FRAME_POINTER(fp) \
147 always_assert(false); \
148 ActRec* fp = nullptr;
150 #elif defined(__AARCH64EL__)
152 # if defined(__clang__)
153 # define DECLARE_FRAME_POINTER(fp) ActRec* fp = (ActRec*) \
154 __builtin_frame_address(0)
155 #else
156 # define DECLARE_FRAME_POINTER(fp) ActRec* fp asm("x29")
157 #endif
159 #else
161 # error What are the stack and frame pointers called on your architecture?
163 #endif
165 //////////////////////////////////////////////////////////////////////
166 // CALLEE_SAVED_BARRIER
168 #ifdef __AARCH64EL__
169 #define CALLEE_SAVED_BARRIER()\
170 asm volatile("" : : : "x19", "x20", "x21", "x22", "x23", "x24", "x25",\
171 "x26", "x27", "x28", \
172 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15")
173 #else
174 #define CALLEE_SAVED_BARRIER()\
175 asm volatile("" : : : "rbx", "r12", "r13", "r14", "r15");
176 #endif
178 //////////////////////////////////////////////////////////////////////
180 // We reserve the exit status 127 to signal a failure. 127 is a valid
181 // exit code on all reasonable architectures: POSIX requires at least
182 // 8 unsigned bits and Windows 32 signed bits.
183 #define HPHP_EXIT_FAILURE 127
185 // When HHVM server fails to shutdown within a timeout, we forcefully
186 //exit the process with this exit code, similar to an unclean exit
187 // upon SIGTERM (signal 15).
188 #define HPHP_SHUTDOWN_TIMEOUT (128 + 15)
190 //////////////////////////////////////////////////////////////////////
192 #ifdef HHVM_FACEBOOK
193 #define USE_FOLLY_SYMBOLIZER 1
194 // Linking in libbfd is a gigantic PITA, but if folly symbolizer doesn't
195 // work on your platform, you'll need to figure it out.
196 #define HAVE_LIBBFD 1
197 #endif
199 #ifndef PACKAGE
200 // The value doesn't matter, but it must be defined before you include
201 // bfd.h
202 #define PACKAGE "hhvm"
203 #endif
205 //////////////////////////////////////////////////////////////////////
207 #define ASM_LOCAL_LABEL(x) ".L" x