1 | /* |
2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. |
3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. |
4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. |
5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. |
6 | * All rights reserved. |
7 | * |
8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
10 | * |
11 | * Permission is hereby granted to use or copy this program |
12 | * for any purpose, provided the above notices are retained on all copies. |
13 | * Permission to modify the code and to distribute modified code is granted, |
14 | * provided the above notices are retained, and a notice that the code was |
15 | * modified is included with the above copyright notice. |
16 | */ |
17 | |
18 | /* This should never be included directly; it is included only from gc.h. */ |
19 | /* We separate it only to make gc.h more suitable as documentation. */ |
20 | #if defined(GC_H) |
21 | |
22 | /* Some tests for old macros. These violate our namespace rules and */ |
23 | /* will disappear shortly. Use the GC_ names. */ |
24 | #if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) \ |
25 | || defined(_SOLARIS_PTHREADS) || defined(GC_SOLARIS_PTHREADS) |
26 | /* We no longer support old style Solaris threads. */ |
27 | /* GC_SOLARIS_THREADS now means pthreads. */ |
28 | # ifndef GC_SOLARIS_THREADS |
29 | # define GC_SOLARIS_THREADS |
30 | # endif |
31 | #endif |
32 | #if defined(IRIX_THREADS) |
33 | # define GC_IRIX_THREADS |
34 | #endif |
35 | #if defined(DGUX_THREADS) && !defined(GC_DGUX386_THREADS) |
36 | # define GC_DGUX386_THREADS |
37 | #endif |
38 | #if defined(AIX_THREADS) |
39 | # define GC_AIX_THREADS |
40 | #endif |
41 | #if defined(HPUX_THREADS) |
42 | # define GC_HPUX_THREADS |
43 | #endif |
44 | #if defined(OSF1_THREADS) |
45 | # define GC_OSF1_THREADS |
46 | #endif |
47 | #if defined(LINUX_THREADS) |
48 | # define GC_LINUX_THREADS |
49 | #endif |
50 | #if defined(WIN32_THREADS) |
51 | # define GC_WIN32_THREADS |
52 | #endif |
53 | #if defined(RTEMS_THREADS) |
54 | # define GC_RTEMS_PTHREADS |
55 | #endif |
56 | #if defined(USE_LD_WRAP) |
57 | # define GC_USE_LD_WRAP |
58 | #endif |
59 | |
60 | #if defined(GC_WIN32_PTHREADS) && !defined(GC_WIN32_THREADS) |
61 | /* Using pthreads-w32 library. */ |
62 | # define GC_WIN32_THREADS |
63 | #endif |
64 | |
65 | #if defined(GC_AIX_THREADS) || defined(GC_DARWIN_THREADS) \ |
66 | || defined(GC_DGUX386_THREADS) || defined(GC_FREEBSD_THREADS) \ |
67 | || defined(GC_GNU_THREADS) || defined(GC_HPUX_THREADS) \ |
68 | || defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) \ |
69 | || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) \ |
70 | || defined(GC_OSF1_THREADS) || defined(GC_SOLARIS_THREADS) \ |
71 | || defined(GC_WIN32_THREADS) || defined(GC_RTEMS_PTHREADS) |
72 | # ifndef GC_THREADS |
73 | # define GC_THREADS |
74 | # endif |
75 | #elif defined(GC_THREADS) |
76 | # if defined(__linux__) |
77 | # define GC_LINUX_THREADS |
78 | # endif |
79 | # if !defined(__linux__) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \ |
80 | || defined(hppa) || defined(__HPPA)) \ |
81 | || (defined(__ia64) && defined(_HPUX_SOURCE)) |
82 | # define GC_HPUX_THREADS |
83 | # endif |
84 | # if !defined(__linux__) && (defined(__alpha) || defined(__alpha__)) |
85 | # define GC_OSF1_THREADS |
86 | # endif |
87 | # if defined(__mips) && !defined(__linux__) |
88 | # define GC_IRIX_THREADS |
89 | # endif |
90 | # if defined(__sparc) && !defined(__linux__) \ |
91 | || defined(sun) && (defined(i386) || defined(__i386__) \ |
92 | || defined(__amd64__)) |
93 | # define GC_SOLARIS_THREADS |
94 | # elif defined(__APPLE__) && defined(__MACH__) |
95 | # define GC_DARWIN_THREADS |
96 | # elif defined(__OpenBSD__) |
97 | # define GC_OPENBSD_THREADS |
98 | # elif !defined(GC_LINUX_THREADS) && !defined(GC_HPUX_THREADS) \ |
99 | && !defined(GC_OSF1_THREADS) && !defined(GC_IRIX_THREADS) |
100 | /* FIXME: Should we really need for FreeBSD and NetBSD to check */ |
101 | /* that no other GC_xxx_THREADS macro is set? */ |
102 | # if defined(__FreeBSD__) || defined(__DragonFly__) |
103 | # define GC_FREEBSD_THREADS |
104 | # elif defined(__NetBSD__) |
105 | # define GC_NETBSD_THREADS |
106 | # endif |
107 | # endif |
108 | # if defined(DGUX) && (defined(i386) || defined(__i386__)) |
109 | # define GC_DGUX386_THREADS |
110 | # endif |
111 | # if defined(_AIX) |
112 | # define GC_AIX_THREADS |
113 | # endif |
114 | # if (defined(_WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) \ |
115 | || defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__CEGCC__) \ |
116 | || defined(_WIN32_WCE) || defined(__MINGW32__)) \ |
117 | && !defined(GC_WIN32_THREADS) |
118 | /* Either posix or native Win32 threads. */ |
119 | # define GC_WIN32_THREADS |
120 | # endif |
121 | # if defined(__rtems__) && (defined(i386) || defined(__i386__)) |
122 | # define GC_RTEMS_PTHREADS |
123 | # endif |
124 | # if defined(__gnu_hurd__) |
125 | # define GC_GNU_THREADS |
126 | # define GC_PTHREADS |
127 | # endif |
128 | #endif /* GC_THREADS */ |
129 | |
130 | #undef GC_PTHREADS |
131 | #if (!defined(GC_WIN32_THREADS) || defined(GC_WIN32_PTHREADS) \ |
132 | || defined(__CYGWIN32__) || defined(__CYGWIN__)) && defined(GC_THREADS) |
133 | /* Posix threads. */ |
134 | # define GC_PTHREADS |
135 | #endif |
136 | |
137 | #if !defined(_PTHREADS) && defined(GC_NETBSD_THREADS) |
138 | # define _PTHREADS |
139 | #endif |
140 | |
141 | #if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE) |
142 | # define _POSIX4A_DRAFT10_SOURCE 1 |
143 | #endif |
144 | |
145 | #if !defined(_REENTRANT) && defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) |
146 | /* Better late than never. This fails if system headers that depend */ |
147 | /* on this were previously included. */ |
148 | # define _REENTRANT |
149 | #endif |
150 | |
151 | #define __GC |
152 | #if !defined(_WIN32_WCE) || defined(__GNUC__) |
153 | # include <stddef.h> |
154 | # if defined(__MINGW32__) && !defined(_WIN32_WCE) |
155 | # include <stdint.h> |
156 | /* We mention uintptr_t. */ |
157 | /* Perhaps this should be included in pure msft environments */ |
158 | /* as well? */ |
159 | # endif |
160 | #else /* _WIN32_WCE */ |
161 | /* Yet more kludges for WinCE. */ |
162 | # include <stdlib.h> /* size_t is defined here */ |
163 | # ifndef _PTRDIFF_T_DEFINED |
164 | /* ptrdiff_t is not defined */ |
165 | # define _PTRDIFF_T_DEFINED |
166 | typedef long ptrdiff_t; |
167 | # endif |
168 | #endif /* _WIN32_WCE */ |
169 | |
170 | #if !defined(GC_NOT_DLL) && !defined(GC_DLL) \ |
171 | && ((defined(_DLL) && !defined(__GNUC__)) \ |
172 | || (defined(DLL_EXPORT) && defined(GC_BUILD))) |
173 | # define GC_DLL |
174 | #endif |
175 | |
176 | #if defined(GC_DLL) && !defined(GC_API) |
177 | |
178 | # if defined(__MINGW32__) || defined(__CEGCC__) |
179 | # ifdef GC_BUILD |
180 | # define GC_API __declspec(dllexport) |
181 | # else |
182 | # define GC_API __declspec(dllimport) |
183 | # endif |
184 | |
185 | # elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \ |
186 | || defined(__CYGWIN__) |
187 | # ifdef GC_BUILD |
188 | # define GC_API extern __declspec(dllexport) |
189 | # else |
190 | # define GC_API __declspec(dllimport) |
191 | # endif |
192 | |
193 | # elif defined(__WATCOMC__) |
194 | # ifdef GC_BUILD |
195 | # define GC_API extern __declspec(dllexport) |
196 | # else |
197 | # define GC_API extern __declspec(dllimport) |
198 | # endif |
199 | |
200 | # elif defined(__SYMBIAN32__) |
201 | # ifdef GC_BUILD |
202 | # define GC_API extern EXPORT_C |
203 | # else |
204 | # define GC_API extern IMPORT_C |
205 | # endif |
206 | |
207 | # elif defined(__GNUC__) |
208 | /* Only matters if used in conjunction with -fvisibility=hidden option. */ |
209 | # if defined(GC_BUILD) && (__GNUC__ >= 4 \ |
210 | || defined(GC_VISIBILITY_HIDDEN_SET)) |
211 | # define GC_API extern __attribute__((__visibility__("default"))) |
212 | # endif |
213 | # endif |
214 | #endif /* GC_DLL */ |
215 | |
216 | #ifndef GC_API |
217 | # define GC_API extern |
218 | #endif |
219 | |
220 | #ifndef GC_CALL |
221 | # define GC_CALL |
222 | #endif |
223 | |
224 | #ifndef GC_CALLBACK |
225 | # define GC_CALLBACK GC_CALL |
226 | #endif |
227 | |
228 | #ifndef GC_ATTR_MALLOC |
229 | /* 'malloc' attribute should be used for all malloc-like functions */ |
230 | /* (to tell the compiler that a function may be treated as if any */ |
231 | /* non-NULL pointer it returns cannot alias any other pointer valid */ |
232 | /* when the function returns). If the client code violates this rule */ |
233 | /* by using custom GC_oom_func then define GC_OOM_FUNC_RETURNS_ALIAS. */ |
234 | # ifdef GC_OOM_FUNC_RETURNS_ALIAS |
235 | # define GC_ATTR_MALLOC /* empty */ |
236 | # elif defined(__GNUC__) && (__GNUC__ > 3 \ |
237 | || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) |
238 | # define GC_ATTR_MALLOC __attribute__((__malloc__)) |
239 | # elif defined(_MSC_VER) && _MSC_VER >= 14 |
240 | # define GC_ATTR_MALLOC __declspec(noalias) __declspec(restrict) |
241 | # else |
242 | # define GC_ATTR_MALLOC |
243 | # endif |
244 | #endif |
245 | |
246 | #ifndef GC_ATTR_ALLOC_SIZE |
247 | /* 'alloc_size' attribute improves __builtin_object_size correctness. */ |
248 | /* Only single-argument form of 'alloc_size' attribute is used. */ |
249 | # if defined(__GNUC__) && (__GNUC__ > 4 \ |
250 | || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && !defined(__ICC)) \ |
251 | || __clang_major__ > 3 \ |
252 | || (__clang_major__ == 3 && __clang_minor__ >= 2)) |
253 | # define GC_ATTR_ALLOC_SIZE(argnum) __attribute__((__alloc_size__(argnum))) |
254 | # else |
255 | # define GC_ATTR_ALLOC_SIZE(argnum) |
256 | # endif |
257 | #endif |
258 | |
259 | #ifndef GC_ATTR_NONNULL |
260 | # if defined(__GNUC__) && __GNUC__ >= 4 |
261 | # define GC_ATTR_NONNULL(argnum) __attribute__((__nonnull__(argnum))) |
262 | # else |
263 | # define GC_ATTR_NONNULL(argnum) /* empty */ |
264 | # endif |
265 | #endif |
266 | |
267 | #ifndef GC_ATTR_DEPRECATED |
268 | # ifdef GC_BUILD |
269 | # undef GC_ATTR_DEPRECATED |
270 | # define GC_ATTR_DEPRECATED /* empty */ |
271 | # elif defined(__GNUC__) && __GNUC__ >= 4 |
272 | # define GC_ATTR_DEPRECATED __attribute__((__deprecated__)) |
273 | # elif defined(_MSC_VER) && _MSC_VER >= 12 |
274 | # define GC_ATTR_DEPRECATED __declspec(deprecated) |
275 | # else |
276 | # define GC_ATTR_DEPRECATED /* empty */ |
277 | # endif |
278 | #endif |
279 | |
280 | #if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720 |
281 | # define GC_ADD_CALLER |
282 | # define GC_RETURN_ADDR (GC_word)__return_address |
283 | #endif |
284 | |
285 | #if defined(__linux__) || defined(__GLIBC__) |
286 | # if !defined(__native_client__) |
287 | # include <features.h> |
288 | # endif |
289 | # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \ |
290 | && !defined(__ia64__) && !defined(__UCLIBC__) \ |
291 | && !defined(GC_HAVE_BUILTIN_BACKTRACE) |
292 | # define GC_HAVE_BUILTIN_BACKTRACE |
293 | # endif |
294 | # if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) |
295 | # define GC_CAN_SAVE_CALL_STACKS |
296 | # endif |
297 | #endif /* GLIBC */ |
298 | |
299 | #if defined(_MSC_VER) && _MSC_VER >= 1200 /* version 12.0+ (MSVC 6.0+) */ \ |
300 | && !defined(_AMD64_) && !defined(_M_X64) && !defined(_WIN32_WCE) \ |
301 | && !defined(GC_HAVE_NO_BUILTIN_BACKTRACE) \ |
302 | && !defined(GC_HAVE_BUILTIN_BACKTRACE) |
303 | # define GC_HAVE_BUILTIN_BACKTRACE |
304 | #endif |
305 | |
306 | #if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS) |
307 | # define GC_CAN_SAVE_CALL_STACKS |
308 | #endif |
309 | |
310 | #if defined(__sparc__) |
311 | # define GC_CAN_SAVE_CALL_STACKS |
312 | #endif |
313 | |
314 | /* If we're on a platform on which we can't save call stacks, but */ |
315 | /* gcc is normally used, we go ahead and define GC_ADD_CALLER. */ |
316 | /* We make this decision independent of whether gcc is actually being */ |
317 | /* used, in order to keep the interface consistent, and allow mixing */ |
318 | /* of compilers. */ |
319 | /* This may also be desirable if it is possible but expensive to */ |
320 | /* retrieve the call chain. */ |
321 | #if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \ |
322 | || defined(__FreeBSD__) || defined(__DragonFly__) \ |
323 | || defined(PLATFORM_ANDROID) || defined(__ANDROID__)) \ |
324 | && !defined(GC_CAN_SAVE_CALL_STACKS) |
325 | # define GC_ADD_CALLER |
326 | # if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) |
327 | /* gcc knows how to retrieve return address, but we don't know */ |
328 | /* how to generate call stacks. */ |
329 | # define GC_RETURN_ADDR (GC_word)__builtin_return_address(0) |
330 | # if (__GNUC__ >= 4) && (defined(__i386__) || defined(__amd64__) \ |
331 | || defined(__x86_64__) /* and probably others... */) |
332 | # define GC_RETURN_ADDR_PARENT \ |
333 | (GC_word)__builtin_extract_return_addr(__builtin_return_address(1)) |
334 | # endif |
335 | # else |
336 | /* Just pass 0 for gcc compatibility. */ |
337 | # define GC_RETURN_ADDR 0 |
338 | # endif |
339 | #endif /* !GC_CAN_SAVE_CALL_STACKS */ |
340 | |
341 | #ifdef GC_PTHREADS |
342 | |
343 | # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \ |
344 | || defined(__native_client__) || defined(GC_RTEMS_PTHREADS)) \ |
345 | && !defined(GC_NO_DLOPEN) |
346 | /* Either there is no dlopen() or we do not need to intercept it. */ |
347 | # define GC_NO_DLOPEN |
348 | # endif |
349 | |
350 | # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \ |
351 | || defined(GC_OPENBSD_THREADS) || defined(__native_client__)) \ |
352 | && !defined(GC_NO_PTHREAD_SIGMASK) |
353 | /* Either there is no pthread_sigmask() or no need to intercept it. */ |
354 | # define GC_NO_PTHREAD_SIGMASK |
355 | # endif |
356 | |
357 | # if defined(__native_client__) |
358 | /* At present, NaCl pthread_create() prototype does not have */ |
359 | /* "const" for its "attr" argument; also, NaCl pthread_exit() one */ |
360 | /* does not have "noreturn" attribute. */ |
361 | # ifndef GC_PTHREAD_CREATE_CONST |
362 | # define GC_PTHREAD_CREATE_CONST /* empty */ |
363 | # endif |
364 | # ifndef GC_PTHREAD_EXIT_ATTRIBUTE |
365 | # define GC_PTHREAD_EXIT_ATTRIBUTE /* empty */ |
366 | # endif |
367 | # endif |
368 | |
369 | # if !defined(GC_PTHREAD_EXIT_ATTRIBUTE) \ |
370 | && !defined(PLATFORM_ANDROID) && !defined(__ANDROID__) \ |
371 | && (defined(GC_LINUX_THREADS) || defined(GC_SOLARIS_THREADS)) |
372 | /* Intercept pthread_exit on Linux and Solaris. */ |
373 | # if defined(__GNUC__) /* since GCC v2.7 */ |
374 | # define GC_PTHREAD_EXIT_ATTRIBUTE __attribute__((__noreturn__)) |
375 | # elif defined(__NORETURN) /* used in Solaris */ |
376 | # define GC_PTHREAD_EXIT_ATTRIBUTE __NORETURN |
377 | # else |
378 | # define GC_PTHREAD_EXIT_ATTRIBUTE /* empty */ |
379 | # endif |
380 | # endif |
381 | |
382 | # if (!defined(GC_PTHREAD_EXIT_ATTRIBUTE) || defined(__native_client__)) \ |
383 | && !defined(GC_NO_PTHREAD_CANCEL) |
384 | /* Either there is no pthread_cancel() or no need to intercept it. */ |
385 | # define GC_NO_PTHREAD_CANCEL |
386 | # endif |
387 | |
388 | #endif /* GC_PTHREADS */ |
389 | |
390 | #endif |
391 | |