Line | Count | Source |
1 | | |
2 | | /* |
3 | | * Copyright (C) Igor Sysoev |
4 | | * Copyright (C) NGINX, Inc. |
5 | | */ |
6 | | |
7 | | #ifndef _NJS_CLANG_H_INCLUDED_ |
8 | | #define _NJS_CLANG_H_INCLUDED_ |
9 | | |
10 | | |
11 | | #include <stdarg.h> |
12 | | #include <stddef.h> /* offsetof(). */ |
13 | | |
14 | | |
15 | | #define njs_inline static inline __attribute__((always_inline)) |
16 | | #define njs_noinline __attribute__((noinline)) |
17 | | #define njs_cdecl |
18 | | |
19 | | |
20 | | #define njs_container_of(p, type, field) \ |
21 | 667M | (type *) ((u_char *) (p) - offsetof(type, field)) |
22 | | |
23 | | #define njs_nitems(x) \ |
24 | 2.03M | (sizeof(x) / sizeof((x)[0])) |
25 | | |
26 | | #define njs_max(val1, val2) \ |
27 | 21.7M | ((val1 < val2) ? (val2) : (val1)) |
28 | | |
29 | | #define njs_min(val1, val2) \ |
30 | 19.2M | ((val1 < val2) ? (val1) : (val2)) |
31 | | |
32 | | |
33 | | #if (NJS_HAVE_BUILTIN_EXPECT) |
34 | 5.11G | #define njs_expect(c, x) __builtin_expect((long) (x), (c)) |
35 | 1.44G | #define njs_fast_path(x) njs_expect(1, x) |
36 | 3.66G | #define njs_slow_path(x) njs_expect(0, x) |
37 | | |
38 | | #else |
39 | | #define njs_expect(c, x) (x) |
40 | | #define njs_fast_path(x) (x) |
41 | | #define njs_slow_path(x) (x) |
42 | | #endif |
43 | | |
44 | | |
45 | | #if (NJS_HAVE_BUILTIN_UNREACHABLE) |
46 | | #define njs_unreachable() __builtin_unreachable() |
47 | | |
48 | | #else |
49 | | #define njs_unreachable() |
50 | | #endif |
51 | | |
52 | | |
53 | | #if (NJS_HAVE_BUILTIN_PREFETCH) |
54 | 175M | #define njs_prefetch(a) __builtin_prefetch(a) |
55 | | |
56 | | #else |
57 | | #define njs_prefetch(a) |
58 | | #endif |
59 | | |
60 | | |
61 | | #if (NJS_HAVE_BUILTIN_CLZ) |
62 | 0 | #define njs_leading_zeros(x) (((x) == 0) ? 32 : __builtin_clz(x)) |
63 | | |
64 | | #else |
65 | | |
66 | | njs_inline uint32_t |
67 | | njs_leading_zeros(uint32_t x) |
68 | | { |
69 | | uint32_t n; |
70 | | |
71 | | /* |
72 | | * There is no sense to optimize this function, since almost |
73 | | * all platforms nowadays support the built-in instruction. |
74 | | */ |
75 | | |
76 | | if (x == 0) { |
77 | | return 32; |
78 | | } |
79 | | |
80 | | n = 0; |
81 | | |
82 | | while ((x & 0x80000000) == 0) { |
83 | | n++; |
84 | | x <<= 1; |
85 | | } |
86 | | |
87 | | return n; |
88 | | } |
89 | | |
90 | | #endif |
91 | | |
92 | | |
93 | | #if (NJS_HAVE_BUILTIN_CLZLL) |
94 | | #define njs_leading_zeros64(x) (((x) == 0) ? 64 : __builtin_clzll(x)) |
95 | | |
96 | | #else |
97 | | |
98 | | njs_inline uint64_t |
99 | | njs_leading_zeros64(uint64_t x) |
100 | | { |
101 | | uint64_t n; |
102 | | |
103 | | /* |
104 | | * There is no sense to optimize this function, since almost |
105 | | * all platforms nowadays support the built-in instruction. |
106 | | */ |
107 | | |
108 | | if (x == 0) { |
109 | | return 64; |
110 | | } |
111 | | |
112 | | n = 0; |
113 | | |
114 | | while ((x & 0x8000000000000000ULL) == 0) { |
115 | | n++; |
116 | | x <<= 1; |
117 | | } |
118 | | |
119 | | return n; |
120 | | } |
121 | | |
122 | | #endif |
123 | | |
124 | | |
125 | | #if (NJS_HAVE_GCC_ATTRIBUTE_VISIBILITY) |
126 | | #define NJS_EXPORT __attribute__((visibility("default"))) |
127 | | |
128 | | #else |
129 | | #define NJS_EXPORT |
130 | | #endif |
131 | | |
132 | | |
133 | | #if (NJS_HAVE_GCC_ATTRIBUTE_ALIGNED) |
134 | | #define njs_aligned(x) __attribute__((aligned(x))) |
135 | | |
136 | | #else |
137 | | #define njs_aligned(x) |
138 | | #endif |
139 | | |
140 | | |
141 | | #if (NJS_HAVE_GCC_ATTRIBUTE_PACKED) |
142 | | #define NJS_PACKED __attribute__((packed)) |
143 | | |
144 | | #else |
145 | | #define NJS_PACKED |
146 | | #endif |
147 | | |
148 | | |
149 | | #if (NJS_HAVE_GCC_ATTRIBUTE_FALLTHROUGH) |
150 | | #define NJS_FALLTHROUGH __attribute__((fallthrough)) |
151 | | |
152 | | #else |
153 | | #define NJS_FALLTHROUGH |
154 | | #endif |
155 | | |
156 | | |
157 | | #if (NJS_HAVE_GCC_ATTRIBUTE_MALLOC) |
158 | | #define NJS_MALLOC_LIKE __attribute__((__malloc__)) |
159 | | |
160 | | #else |
161 | | #define NJS_MALLOC_LIKE |
162 | | #endif |
163 | | |
164 | | |
165 | | #if (NJS_CLANG) |
166 | | /* Any __asm__ directive disables loop vectorization in GCC and Clang. */ |
167 | | #define njs_pragma_loop_disable_vectorization __asm__("") |
168 | | |
169 | | #else |
170 | | #define njs_pragma_loop_disable_vectorization |
171 | | #endif |
172 | | |
173 | | |
174 | 0 | #define njs_stringify(v) #v |
175 | | |
176 | | |
177 | | #if (NJS_HAVE_MEMORY_SANITIZER) |
178 | | #include <sanitizer/msan_interface.h> |
179 | | |
180 | | #define njs_msan_unpoison(ptr, size) __msan_unpoison(ptr, size) |
181 | | #else |
182 | | |
183 | | #define njs_msan_unpoison(ptr, size) |
184 | | #endif |
185 | | |
186 | | #if (NJS_HAVE_GCC_ATTRIBUTE_NO_SANITIZE) |
187 | | #define NJS_NOSANITIZE(options) __attribute__((no_sanitize(options))) |
188 | | #else |
189 | | #define NJS_NOSANITIZE(options) |
190 | | #endif |
191 | | |
192 | | |
193 | | njs_inline NJS_NOSANITIZE("float-cast-overflow") int64_t |
194 | | njs_unsafe_cast_double_to_int64(double num) |
195 | 16.6k | { |
196 | | /* |
197 | | * Casting NaN to integer is undefined behavior, |
198 | | * but it is fine in some cases where we do additional checks later. |
199 | | * For example: |
200 | | * int64_t i64 = njs_unsafe_cast_double_to_int64(num); |
201 | | * if (i64 == num) { |
202 | | * // num is integer |
203 | | * } |
204 | | * |
205 | | * We do this as inline function to avoid UndefinedBehaviorSanitizer |
206 | | * warnings. |
207 | | */ |
208 | 16.6k | return (int64_t) num; |
209 | 16.6k | } Unexecuted instantiation: njs_shell.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_arr.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_rbtree.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_mp.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_sprintf.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_value.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_atom.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_vm.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_vmcode.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_parser.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_variable.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_scope.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_generator.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_disassembler.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_module.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_extern.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_number.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_symbol.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_string.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_object.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_object_prop.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_array.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_json.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_function.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_regexp.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_date.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_error.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_array_buffer.c:njs_unsafe_cast_double_to_int64 njs_typed_array.c:njs_unsafe_cast_double_to_int64 Line | Count | Source | 195 | 16.6k | { | 196 | | /* | 197 | | * Casting NaN to integer is undefined behavior, | 198 | | * but it is fine in some cases where we do additional checks later. | 199 | | * For example: | 200 | | * int64_t i64 = njs_unsafe_cast_double_to_int64(num); | 201 | | * if (i64 == num) { | 202 | | * // num is integer | 203 | | * } | 204 | | * | 205 | | * We do this as inline function to avoid UndefinedBehaviorSanitizer | 206 | | * warnings. | 207 | | */ | 208 | 16.6k | return (int64_t) num; | 209 | 16.6k | } |
Unexecuted instantiation: njs_promise.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_iterator.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_async.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_builtin.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_regex.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_buffer.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_modules.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_dtoa.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_djb_hash.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_utf8.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_utf16.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_flathsh.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_trace.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_malloc.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_utils.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_chb.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_lexer.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_boolean.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_math.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_encoding.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_crypto_module.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_webcrypto_module.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_fs_module.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_query_string_module.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_str.c:njs_unsafe_cast_double_to_int64 Unexecuted instantiation: njs_random.c:njs_unsafe_cast_double_to_int64 |
210 | | |
211 | | |
212 | | #ifndef NJS_MAX_ALIGNMENT |
213 | | |
214 | | #if (NJS_SOLARIS) |
215 | | /* x86_64: 16, i386: 4, sparcv9: 16, sparcv8: 8. */ |
216 | | #define NJS_MAX_ALIGNMENT _MAX_ALIGNMENT |
217 | | |
218 | | #elif (NJS_WINDOWS) |
219 | | /* Win64: 16, Win32: 8. */ |
220 | | #define NJS_MAX_ALIGNMENT MEMORY_ALLOCATION_ALIGNMENT |
221 | | |
222 | | #elif (__amd64__) |
223 | 7.53M | #define NJS_MAX_ALIGNMENT 16 |
224 | | |
225 | | #elif (__i386__ || __i386) |
226 | | #define NJS_MAX_ALIGNMENT 4 |
227 | | |
228 | | #elif (__arm__) |
229 | | #define NJS_MAX_ALIGNMENT 16 |
230 | | |
231 | | #else |
232 | | #define NJS_MAX_ALIGNMENT 16 |
233 | | #endif |
234 | | |
235 | | #endif |
236 | | |
237 | | |
238 | | #define njs_align_size(size, a) \ |
239 | 46.7M | (((size) + ((size_t) (a) - 1)) & ~((size_t) (a) - 1)) |
240 | | |
241 | | |
242 | | #define njs_align_ptr(p, a) \ |
243 | 1.41M | (u_char *) (((uintptr_t) (p) + ((uintptr_t) (a) - 1)) \ |
244 | 1.41M | & ~((uintptr_t) (a) - 1)) |
245 | | |
246 | | #define njs_trunc_ptr(p, a) \ |
247 | | (u_char *) ((uintptr_t) (p) & ~((uintptr_t) (a) - 1)) |
248 | | |
249 | | |
250 | | #endif /* _NJS_CLANG_H_INCLUDED_ */ |