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