2 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3 * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
4 * Copyright (c) 1996 by Silicon Graphics. All rights reserved.
5 * Copyright (c) 2000-2004 Hewlett-Packard Development Company, L.P.
7 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
10 * Permission is hereby granted to use or copy this program
11 * for any purpose, provided the above notices are retained on all copies.
12 * Permission to modify the code and to distribute modified code is granted,
13 * provided the above notices are retained, and a notice that the code was
14 * modified is included with the above copyright notice.
18 * This header is private to the gc. It is almost always included from
19 * gc_priv.h. However it is possible to include it by itself if just the
20 * configuration macros are needed. In that
21 * case, a few declarations relying on types declared in gc_priv.h will be
29 # undef CLOCKS_PER_SEC
33 # undef REDIRECT_REALLOC
39 # define PTR_T_DEFINED
42 #if !defined(sony_news)
43 # include <stddef.h> /* For size_t, etc. */
46 /* Note: Only wrap our own declarations, and not the included headers. */
47 /* In this case, wrap our entire file, but temporarily unwrap/rewrap */
48 /* around #includes. Types and macros do not need such wrapping, only */
49 /* the declared global data and functions. */
51 # define EXTERN_C_BEGIN extern "C" {
52 # define EXTERN_C_END } /* extern "C" */
54 # define EXTERN_C_BEGIN /* empty */
55 # define EXTERN_C_END /* empty */
60 /* Convenient internal macro to test version of Clang. */
61 #if defined(__clang__) && defined(__clang_major__)
62 # define GC_CLANG_PREREQ(major, minor) \
63 ((__clang_major__ << 16) + __clang_minor__ >= ((major) << 16) + (minor))
64 # define GC_CLANG_PREREQ_FULL(major, minor, patchlevel) \
65 (GC_CLANG_PREREQ(major, (minor) + 1) \
66 || (__clang_major__ == (major) && __clang_minor__ == (minor) \
67 && __clang_patchlevel__ >= (patchlevel)))
69 # define GC_CLANG_PREREQ(major, minor) 0 /* FALSE */
70 # define GC_CLANG_PREREQ_FULL(major, minor, patchlevel) 0
74 /* A macro (based on a tricky expression) to prevent false warnings */
75 /* like "Array compared to 0", "Comparison of identical expressions", */
76 /* "Untrusted loop bound" output by some static code analysis tools. */
77 /* The argument should not be a literal value. The result is */
78 /* converted to word type. (Actually, GC_word is used instead of */
79 /* word type as the latter might be undefined at the place of use.) */
80 # define COVERT_DATAFLOW(w) (~(GC_word)(w)^(~(GC_word)0))
82 # define COVERT_DATAFLOW(w) ((GC_word)(w))
85 /* Machine dependent parameters. Some tuning parameters can be found */
86 /* near the top of gc_private.h. */
88 /* Machine specific parts contributed by various people. See README file. */
90 #if defined(__ANDROID__) && !defined(HOST_ANDROID)
91 /* __ANDROID__ macro is defined by Android NDK gcc. */
92 # define HOST_ANDROID 1
95 #if defined(TIZEN) && !defined(HOST_TIZEN)
99 #if defined(__SYMBIAN32__) && !defined(SYMBIAN)
102 # pragma data_seg(".data2")
106 /* First a unified test for Linux: */
107 # if (defined(linux) || defined(__linux__) || defined(HOST_ANDROID)) \
108 && !defined(LINUX) && !defined(__native_client__)
112 /* And one for NetBSD: */
113 # if defined(__NetBSD__)
117 /* And one for OpenBSD: */
118 # if defined(__OpenBSD__)
122 /* And one for FreeBSD: */
123 # if (defined(__FreeBSD__) || defined(__DragonFly__) \
124 || defined(__FreeBSD_kernel__)) && !defined(FREEBSD) \
125 && !defined(SN_TARGET_ORBIS) /* Orbis compiler defines __FreeBSD__ */
129 /* And one for Darwin: */
130 # if defined(macosx) || (defined(__APPLE__) && defined(__MACH__))
133 # include <TargetConditionals.h>
137 /* Determine the machine type: */
138 # if defined(__native_client__)
140 # if !defined(__portable_native_client__) && !defined(__arm__)
142 # define mach_type_known
144 /* Here we will rely upon arch-specific defines. */
147 # if defined(__aarch64__)
149 # if !defined(LINUX) && !defined(DARWIN) && !defined(FREEBSD) \
150 && !defined(NETBSD) && !defined(NN_BUILD_TARGET_PLATFORM_NX) \
153 # define mach_type_known
156 # if defined(__arm) || defined(__arm__) || defined(__thumb__)
159 # define mach_type_known
160 # elif !defined(LINUX) && !defined(NETBSD) && !defined(FREEBSD) \
161 && !defined(OPENBSD) && !defined(DARWIN) && !defined(_WIN32) \
162 && !defined(__CEGCC__) && !defined(NN_PLATFORM_CTR) \
163 && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) \
166 # define mach_type_known
169 # if defined(sun) && defined(mc68000) && !defined(CPPCHECK)
170 # error SUNOS4 no longer supported
172 # if defined(hp9000s300) && !defined(CPPCHECK)
173 # error M68K based HP machines no longer supported
175 # if defined(OPENBSD) && defined(m68k)
177 # define mach_type_known
179 # if defined(OPENBSD) && defined(__sparc__)
181 # define mach_type_known
183 # if defined(OPENBSD) && defined(__arm__)
185 # define mach_type_known
187 # if defined(OPENBSD) && defined(__aarch64__)
189 # define mach_type_known
191 # if defined(OPENBSD) && defined(__sh__)
193 # define mach_type_known
195 # if defined(NETBSD) && (defined(m68k) || defined(__m68k__))
197 # define mach_type_known
199 # if defined(NETBSD) && defined(__powerpc__)
201 # define mach_type_known
203 # if defined(NETBSD) && (defined(__arm32__) || defined(__arm__))
205 # define mach_type_known
207 # if defined(NETBSD) && defined(__aarch64__)
209 # define mach_type_known
211 # if defined(NETBSD) && defined(__sh__)
213 # define mach_type_known
215 # if defined(vax) || defined(__vax__)
222 # define mach_type_known
224 # if defined(NETBSD) && defined(__vax__)
226 # define mach_type_known
228 # if defined(mips) || defined(__mips) || defined(_mips)
230 # if defined(nec_ews) || defined(_nec_ews)
233 # if !defined(LINUX) && !defined(EWS4800) && !defined(NETBSD) \
235 # if defined(ultrix) || defined(__ultrix)
238 # define IRIX5 /* or IRIX 6.X */
241 # if defined(NETBSD) && defined(__MIPSEL__)
244 # define mach_type_known
246 # if defined(__QNX__)
248 # define mach_type_known
250 # if defined(__NIOS2__) || defined(__NIOS2) || defined(__nios2__)
251 # define NIOS2 /* Altera NIOS2 */
252 # define mach_type_known
254 # if defined(__or1k__)
255 # define OR1K /* OpenRISC/or1k */
256 # define mach_type_known
258 # if defined(DGUX) && (defined(i386) || defined(__i386__))
263 # define mach_type_known
265 # if defined(sequent) && (defined(i386) || defined(__i386__))
268 # define mach_type_known
270 # if (defined(sun) || defined(__sun)) && (defined(i386) || defined(__i386__))
273 # define mach_type_known
275 # if (defined(sun) || defined(__sun)) && defined(__amd64)
278 # define mach_type_known
280 # if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__)
283 # define mach_type_known
285 # if defined(ibm032) && !defined(CPPCHECK)
286 # error IBM PC/RT no longer supported
288 # if (defined(sun) || defined(__sun)) && (defined(sparc) || defined(__sparc))
289 /* Test for SunOS 5.x */
295 # define mach_type_known
296 # elif defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \
297 && !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD)
300 # define mach_type_known
305 # define mach_type_known
307 # if defined(NETBSD) && defined(__sparc__)
309 # define mach_type_known
311 # if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386)
312 /* The above test may need refinement */
314 # if defined(_SCO_ELF)
319 # define mach_type_known
321 # if defined(_AUX_SOURCE) && !defined(CPPCHECK)
322 # error A/UX no longer supported
324 # if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
325 || defined(hppa) || defined(__hppa__)
327 # if !defined(LINUX) && !defined(HPUX) && !defined(OPENBSD)
330 # define mach_type_known
332 # if defined(__ia64) && (defined(_HPUX_SOURCE) || defined(__HP_aCC))
337 # define mach_type_known
339 # if (defined(__BEOS__) || defined(__HAIKU__)) && defined(_X86_)
342 # define mach_type_known
344 # if defined(__HAIKU__) && (defined(__amd64__) || defined(__x86_64__))
347 # define mach_type_known
349 # if defined(OPENBSD) && defined(__amd64__)
351 # define mach_type_known
353 # if defined(LINUX) && (defined(i386) || defined(__i386__))
355 # define mach_type_known
357 # if defined(LINUX) && defined(__x86_64__)
359 # define mach_type_known
361 # if defined(LINUX) && (defined(__ia64__) || defined(__ia64))
363 # define mach_type_known
365 # if defined(LINUX) && defined(__aarch64__)
367 # define mach_type_known
369 # if defined(LINUX) && (defined(__arm) || defined(__arm__))
371 # define mach_type_known
373 # if defined(LINUX) && defined(__cris__)
377 # define mach_type_known
379 # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) \
380 || defined(powerpc64) || defined(__powerpc64__))
382 # define mach_type_known
384 # if defined(LINUX) && defined(__mc68000__)
386 # define mach_type_known
388 # if defined(LINUX) && (defined(sparc) || defined(__sparc__))
390 # define mach_type_known
392 # if defined(LINUX) && defined(__sh__)
394 # define mach_type_known
396 # if defined(LINUX) && defined(__avr32__)
398 # define mach_type_known
400 # if defined(LINUX) && defined(__m32r__)
402 # define mach_type_known
404 # if defined(__alpha) || defined(__alpha__)
406 # if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) \
408 # define OSF1 /* a.k.a Digital Unix */
410 # define mach_type_known
412 # if defined(_AMIGA) && !defined(AMIGA)
417 # define mach_type_known
419 # if defined(THINK_C) \
420 || (defined(__MWERKS__) && !defined(__powerc) && !defined(SYMBIAN))
423 # define mach_type_known
425 # if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__) \
429 # define mach_type_known
431 # if defined(OPENBSD) && defined(__powerpc__)
433 # define mach_type_known
436 # if defined(__ppc__) || defined(__ppc64__)
438 # define mach_type_known
439 # elif defined(__x86_64__) || defined(__x86_64)
441 # define mach_type_known
442 # elif defined(__i386__)
444 # define mach_type_known
445 # elif defined(__arm__)
447 # define mach_type_known
448 # elif defined(__aarch64__)
450 # define mach_type_known
453 # if defined(__rtems__) && (defined(i386) || defined(__i386__))
456 # define mach_type_known
458 # if defined(NeXT) && defined(mc68000)
461 # define mach_type_known
463 # if defined(NeXT) && (defined(i386) || defined(__i386__))
466 # define mach_type_known
468 # if defined(OPENBSD) && (defined(i386) || defined(__i386__))
470 # define mach_type_known
472 # if defined(NETBSD) && (defined(i386) || defined(__i386__))
474 # define mach_type_known
476 # if defined(NETBSD) && defined(__x86_64__)
478 # define mach_type_known
480 # if defined(FREEBSD) && (defined(i386) || defined(__i386__))
482 # define mach_type_known
484 # if (defined(FREEBSD) || defined(SN_TARGET_ORBIS)) \
485 && (defined(__amd64__) || defined(__x86_64__))
487 # define mach_type_known
489 # if defined(FREEBSD) && defined(__sparc__)
491 # define mach_type_known
493 # if defined(FREEBSD) && (defined(powerpc) || defined(__powerpc__))
495 # define mach_type_known
497 # if defined(FREEBSD) && defined(__arm__)
499 # define mach_type_known
501 # if defined(FREEBSD) && defined(__aarch64__)
503 # define mach_type_known
505 # if defined(FREEBSD) && (defined(mips) || defined(__mips) || defined(_mips))
507 # define mach_type_known
509 # if defined(bsdi) && (defined(i386) || defined(__i386__))
512 # define mach_type_known
514 # if !defined(mach_type_known) && defined(__386BSD__)
517 # define mach_type_known
519 # if defined(_CX_UX) && defined(_M88K)
522 # define mach_type_known
524 # if defined(DGUX) && defined(m88k)
527 # define mach_type_known
529 # if defined(_WIN32_WCE) || defined(__CEGCC__) || defined(__MINGW32CE__)
530 /* SH3, SH4, MIPS already defined for corresponding architectures */
531 # if defined(SH3) || defined(SH4)
534 # if defined(x86) || defined(__i386__)
537 # if defined(_M_ARM) || defined(ARM) || defined(_ARM_)
541 # define mach_type_known
543 # if ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300)) \
544 || (defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) \
545 && !defined(__INTERIX) && !defined(SYMBIAN))
546 # if defined(__LP64__) || defined(_M_X64)
548 # elif defined(_M_ARM)
550 # elif defined(_M_ARM64)
559 # define MSWIN32 /* or Win64 */
561 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
562 # define MSWINRT_FLAVOR
565 # define mach_type_known
567 # if defined(_MSC_VER) && defined(_M_IA64)
569 # define MSWIN32 /* Really win64, but we don't treat 64-bit */
570 /* variants as a different platform. */
573 # if defined(__DJGPP__)
576 # define DJGPP /* MSDOS running the DJGPP port of GCC */
578 # define mach_type_known
580 # if defined(__CYGWIN32__) || defined(__CYGWIN__)
581 # if defined(__LP64__)
587 # define mach_type_known
589 # if defined(__INTERIX)
592 # define mach_type_known
594 # if defined(__MINGW32__) && !defined(mach_type_known)
597 # define mach_type_known
599 # if defined(__BORLANDC__)
602 # define mach_type_known
604 # if defined(_UTS) && !defined(mach_type_known)
607 # define mach_type_known
609 # if defined(__pj__) && !defined(CPPCHECK)
610 # error PicoJava no longer supported
611 /* The implementation had problems, and I haven't heard of users */
612 /* in ages. If you want it resurrected, let me know. */
614 # if defined(__embedded__) && defined(PPC)
617 # define mach_type_known
620 # if defined(__WATCOMC__) && defined(__386__)
622 # if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW)
623 # if defined(__OS2__)
626 # if defined(__WINDOWS_386__) || defined(__NT__)
633 # define mach_type_known
635 # if defined(__s390__) && defined(LINUX)
637 # define mach_type_known
639 # if defined(__GNU__)
640 # if defined(__i386__)
641 /* The Debian Hurd running on generic PC */
644 # define mach_type_known
647 # if defined(__TANDEM)
648 /* Nonstop S-series */
649 /* FIXME: Should recognize Integrity series? */
652 # define mach_type_known
654 # if defined(__hexagon__) && defined(LINUX)
656 # define mach_type_known
658 # if defined(__tile__) && defined(LINUX)
664 # define mach_type_known
666 # if defined(__riscv) && defined(LINUX)
668 # define mach_type_known
671 # if defined(SN_TARGET_PSP2)
672 # define mach_type_known
675 # if defined(NN_PLATFORM_CTR)
676 # define mach_type_known
679 # if defined(NN_BUILD_TARGET_PLATFORM_NX)
680 # define NINTENDO_SWITCH
681 # define mach_type_known
684 # if defined(SYMBIAN)
685 # define mach_type_known
688 # if defined(__EMSCRIPTEN__)
690 # define mach_type_known
693 /* Feel free to add more clauses here */
695 /* Or manually define the machine type here. A machine type is */
696 /* characterized by the architecture. Some */
697 /* machine types are further subdivided by OS. */
698 /* Macros such as LINUX, FREEBSD, etc. distinguish them. */
699 /* SYSV on an M68K actually means A/UX. */
700 /* The distinction in these cases is usually the stack starting address */
701 # if !defined(mach_type_known) && !defined(CPPCHECK)
702 # error The collector has not been ported to this machine/OS combination
704 /* Mapping is: M68K ==> Motorola 680X0 */
705 /* (NEXT, and SYSV (A/UX), */
706 /* MACOS and AMIGA variants) */
707 /* I386 ==> Intel 386 */
708 /* (SEQUENT, OS2, SCO, LINUX, NETBSD, */
709 /* FREEBSD, THREE86BSD, MSWIN32, */
710 /* BSDI, SOLARIS, NEXT and others) */
711 /* NS32K ==> Encore Multimax */
712 /* MIPS ==> R2000 through R14K */
713 /* (many variants) */
714 /* VAX ==> DEC VAX */
715 /* (BSD, ULTRIX variants) */
716 /* HP_PA ==> HP9000/700 & /800 */
718 /* SPARC ==> SPARC v7/v8/v9 */
719 /* (SOLARIS, LINUX, DRSNX variants) */
720 /* ALPHA ==> DEC Alpha */
721 /* (OSF1 and LINUX variants) */
722 /* M88K ==> Motorola 88XX0 */
723 /* (CX_UX and DGUX) */
724 /* S370 ==> 370-like machine */
725 /* running Amdahl UTS4 */
726 /* S390 ==> 390-like machine */
728 /* AARCH64 ==> ARM AArch64 */
729 /* (LP64 and ILP32 variants) */
730 /* ARM32 ==> Intel StrongARM */
731 /* IA64 ==> Intel IPF */
733 /* (LINUX and HPUX) */
734 /* SH ==> Hitachi SuperH */
735 /* (LINUX & MSWINCE) */
736 /* X86_64 ==> AMD x86-64 */
737 /* POWERPC ==> IBM/Apple PowerPC */
738 /* (MACOS(<=9),DARWIN(incl.MACOSX),*/
739 /* LINUX, NETBSD, AIX, NOSYS */
741 /* Handles 32 and 64-bit variants. */
742 /* CRIS ==> Axis Etrax */
743 /* M32R ==> Renesas M32R */
744 /* HEXAGON ==> Qualcomm Hexagon */
745 /* TILEPRO ==> Tilera TILEPro */
746 /* TILEGX ==> Tilera TILE-Gx */
750 * For each architecture and OS, the following need to be defined:
752 * CPP_WORDSZ is a simple integer constant representing the word size.
753 * in bits. We assume byte addressability, where a byte has 8 bits.
754 * We also assume CPP_WORDSZ is either 32 or 64.
755 * (We care about the length of pointers, not hardware
756 * bus widths. Thus a 64 bit processor with a C compiler that uses
757 * 32 bit pointers should use CPP_WORDSZ of 32, not 64. Default is 32.)
759 * MACH_TYPE is a string representation of the machine type.
760 * OS_TYPE is analogous for the OS.
762 * ALIGNMENT is the largest N, such that
763 * all pointer are guaranteed to be aligned on N byte boundaries.
764 * defining it to be 1 will always work, but perform poorly.
766 * DATASTART is the beginning of the data segment.
767 * On some platforms SEARCH_FOR_DATA_START is defined.
768 * The latter will cause GC_data_start to
769 * be set to an address determined by accessing data backwards from _end
770 * until an unmapped page is found. DATASTART will be defined to be
772 * On UNIX-like systems, the collector will scan the area between DATASTART
773 * and DATAEND for root pointers.
775 * DATAEND, if not "end", where "end" is defined as "extern int end[]".
776 * RTH suggests gaining access to linker script synth'd values with
777 * this idiom instead of "&end", where "end" is defined as "extern int end".
778 * Otherwise, "GCC will assume these are in .sdata/.sbss" and it will, e.g.,
779 * cause failures on alpha*-*-* with -msmall-data or -fpic or mips-*-*
780 * without any special options.
782 * STACKBOTTOM is the cold end of the stack, which is usually the
783 * highest address in the stack.
784 * Under PCR or OS/2, we have other ways of finding thread stacks.
785 * For each machine, the following should:
786 * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
787 * 2) define exactly one of
788 * STACKBOTTOM (should be defined to be an expression)
792 * If STACKBOTTOM is defined, then its value will be used directly (as the
793 * stack bottom). If LINUX_STACKBOTTOM is defined, then it will be determined
794 * with a method appropriate for most Linux systems. Currently we look
795 * first for __libc_stack_end (currently only if USE_LIBC_PRIVATES is
796 * defined), and if that fails read it from /proc. (If USE_LIBC_PRIVATES
797 * is not defined and NO_PROC_STAT is defined, we revert to HEURISTIC2.)
798 * If either of the last two macros are defined, then STACKBOTTOM is computed
799 * during collector startup using one of the following two heuristics:
800 * HEURISTIC1: Take an address inside GC_init's frame, and round it up to
801 * the next multiple of STACK_GRAN.
802 * HEURISTIC2: Take an address inside GC_init's frame, increment it repeatedly
803 * in small steps (decrement if STACK_GROWS_UP), and read the value
804 * at each location. Remember the value when the first
805 * Segmentation violation or Bus error is signaled. Round that
806 * to the nearest plausible page boundary, and use that instead
809 * Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines,
810 * the value of environ is a pointer that can serve as STACKBOTTOM.
811 * I expect that HEURISTIC2 can be replaced by this approach, which
812 * interferes far less with debugging. However it has the disadvantage
813 * that it's confused by a putenv call before the collector is initialized.
814 * This could be dealt with by intercepting putenv ...
816 * If no expression for STACKBOTTOM can be found, and neither of the above
817 * heuristics are usable, the collector can still be used with all of the above
818 * undefined, provided one of the following is done:
819 * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s)
820 * without reference to STACKBOTTOM. This is appropriate for use in
821 * conjunction with thread packages, since there will be multiple stacks.
822 * (Allocating thread stacks in the heap, and treating them as ordinary
823 * heap data objects is also possible as a last resort. However, this is
824 * likely to introduce significant amounts of excess storage retention
825 * unless the dead parts of the thread stacks are periodically cleared.)
826 * 2) Client code may set GC_stackbottom before calling any GC_ routines.
827 * If the author of the client code controls the main program, this is
828 * easily accomplished by introducing a new main program, setting
829 * GC_stackbottom to the address of a local variable, and then calling
830 * the original main program. The new main program would read something
831 * like (provided real_main() is not inlined by the compiler):
835 * main(argc, argv, envp)
837 * char **argv, **envp;
839 * volatile int dummy;
841 * GC_stackbottom = (ptr_t)(&dummy);
842 * return(real_main(argc, argv, envp));
846 * Each architecture may also define the style of virtual dirty bit
847 * implementation to be used:
848 * MPROTECT_VDB: Write protect the heap and catch faults.
849 * GWW_VDB: Use win32 GetWriteWatch primitive.
850 * PROC_VDB: Use the SVR4 /proc primitives to read dirty bits.
852 * The first and second one may be combined, in which case a runtime
853 * selection will be made, based on GetWriteWatch availability.
855 * An architecture may define DYNAMIC_LOADING if dyn_load.c
856 * defined GC_register_dynamic_libraries() for the architecture.
858 * An architecture may define PREFETCH(x) to preload the cache with *x.
859 * This defaults to GCC built-in operation (or a no-op for other compilers).
861 * GC_PREFETCH_FOR_WRITE(x) is used if *x is about to be written.
863 * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
864 * clear the two words at GC_malloc-aligned address x. By default,
865 * word stores of 0 are used instead.
867 * HEAP_START may be defined as the initial address hint for mmap-based
871 /* If available, we can use __builtin_unwind_init() to push the */
872 /* relevant registers onto the stack. */
873 # if GC_GNUC_PREREQ(2, 8) \
874 && !defined(__INTEL_COMPILER) && !defined(__PATHCC__) \
875 && !defined(__FUJITSU) /* for FX10 system */ \
876 && !(defined(POWERPC) && defined(DARWIN)) /* for MacOS X 10.3.9 */ \
878 && !defined(__ARMCC_VERSION) /* does not exist in armcc gnu emu */ \
879 && !defined(__clang__) /* since no-op in clang (3.0) */
880 # define HAVE_BUILTIN_UNWIND_INIT
884 # define MACH_TYPE "SYMBIAN"
885 # define OS_TYPE "SYMBIAN"
886 # define CPP_WORDSZ 32
888 # define DATASTART (ptr_t)ALIGNMENT /* cannot be null */
889 # define DATAEND (ptr_t)ALIGNMENT
892 # define STACK_GRAN 0x1000000
895 # define MACH_TYPE "M68K"
898 # define OS_TYPE "OPENBSD"
901 extern ptr_t GC_data_start;
902 # define DATASTART GC_data_start
903 # define DYNAMIC_LOADING
906 # define DATASTART ((ptr_t)(etext))
910 # define OS_TYPE "NETBSD"
913 extern ptr_t GC_data_start;
914 # define DATASTART GC_data_start
915 # define DYNAMIC_LOADING
918 # define DATASTART ((ptr_t)(etext))
922 # define OS_TYPE "LINUX"
923 # define LINUX_STACKBOTTOM
924 # if !defined(REDIRECT_MALLOC)
925 # define MPROTECT_VDB
928 # define DYNAMIC_LOADING
930 # include <features.h>
932 # if defined(__GLIBC__) && __GLIBC__ >= 2
933 # define SEARCH_FOR_DATA_START
935 extern char **__environ;
936 # define DATASTART ((ptr_t)(&__environ))
937 /* hideous kludge: __environ is the first */
938 /* word in crt0.o, and delimits the start */
939 /* of the data segment, no matter which */
940 /* ld options were passed through. */
941 /* We could use _etext instead, but that */
942 /* would include .rodata, which may */
943 /* contain large read-only data tables */
944 /* that we'd rather not scan. */
945 # endif /* !GLIBC2 */
947 # define DATAEND ((ptr_t)(_end))
950 # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
954 # define OS_TYPE "AMIGA"
955 /* STACKBOTTOM and DATASTART handled specially */
957 # define DATAEND /* not needed */
958 # define GETPAGESIZE() 4096
966 # define OS_TYPE "MACOS"
967 /* see os_dep.c for details of global data segments. */
968 # define STACKBOTTOM ((ptr_t)LMGetCurStackBase())
969 # define DATAEND /* not needed */
970 # define GETPAGESIZE() 4096
973 # define OS_TYPE "NEXT"
974 # define DATASTART ((ptr_t)get_etext())
975 # define DATASTART_IS_FUNC
976 # define STACKBOTTOM ((ptr_t)0x4000000)
977 # define DATAEND /* not needed */
982 # define MACH_TYPE "POWERPC"
984 # define ALIGNMENT 2 /* Still necessary? Could it be 4? */
990 # define OS_TYPE "MACOS"
991 /* see os_dep.c for details of global data segments. */
992 # define STACKBOTTOM ((ptr_t)LMGetCurStackBase())
993 # define DATAEND /* not needed */
996 # if defined(__powerpc64__)
998 # define CPP_WORDSZ 64
1000 # define HBLKSIZE 4096
1003 # define ALIGNMENT 4
1005 # define OS_TYPE "LINUX"
1006 /* HEURISTIC1 has been reliably reported to fail for a 32-bit */
1007 /* executable on a 64 bit kernel. */
1008 # if defined(__bg__)
1009 /* The Linux Compute Node Kernel (used on BlueGene systems) */
1010 /* does not support LINUX_STACKBOTTOM way. */
1012 # define NO_PTHREAD_GETATTR_NP
1014 # define LINUX_STACKBOTTOM
1016 # define DYNAMIC_LOADING
1017 # define SEARCH_FOR_DATA_START
1019 # define DATAEND ((ptr_t)(_end))
1022 # define OS_TYPE "DARWIN"
1023 # define DYNAMIC_LOADING
1024 # if defined(__ppc64__)
1025 # define ALIGNMENT 8
1026 # define CPP_WORDSZ 64
1027 # define STACKBOTTOM ((ptr_t)0x7fff5fc00000)
1028 # define CACHE_LINE_SIZE 64
1030 # define HBLKSIZE 4096
1033 # define ALIGNMENT 4
1034 # define STACKBOTTOM ((ptr_t)0xc0000000)
1036 /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
1037 /* These aren't used when dyld support is enabled (it is by default). */
1038 # define DATASTART ((ptr_t)get_etext())
1039 # define DATAEND ((ptr_t)get_end())
1040 # define USE_MMAP_ANON
1041 # define MPROTECT_VDB
1043 # include <unistd.h>
1045 # define GETPAGESIZE() (unsigned)getpagesize()
1046 # if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
1047 /* The performance impact of prefetches is untested */
1048 # define PREFETCH(x) \
1049 __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
1050 # define GC_PREFETCH_FOR_WRITE(x) \
1051 __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
1053 /* There seems to be some issues with trylock hanging on darwin. */
1054 /* This should be looked into some more. */
1055 # define NO_PTHREAD_TRYLOCK
1058 # define OS_TYPE "OPENBSD"
1059 # define ALIGNMENT 4
1060 # ifndef GC_OPENBSD_THREADS
1062 # include <sys/param.h>
1063 # include <uvm/uvm_extern.h>
1065 /* USRSTACK is defined in <machine/vmparam.h> but that is */
1066 /* protected by _KERNEL in <uvm/uvm_param.h> file. */
1068 # define STACKBOTTOM ((ptr_t)USRSTACK)
1073 extern int __data_start[];
1074 # define DATASTART ((ptr_t)__data_start)
1076 # define DATAEND ((ptr_t)(&_end))
1077 # define DYNAMIC_LOADING
1080 # if defined(__powerpc64__)
1081 # define ALIGNMENT 8
1082 # define CPP_WORDSZ 64
1084 # define HBLKSIZE 4096
1087 # define ALIGNMENT 4
1089 # define OS_TYPE "FREEBSD"
1090 # ifndef GC_FREEBSD_THREADS
1091 # define MPROTECT_VDB
1093 # define SIG_SUSPEND SIGUSR1
1094 # define SIG_THR_RESTART SIGUSR2
1095 # define FREEBSD_STACKBOTTOM
1096 # define DYNAMIC_LOADING
1097 extern char etext[];
1098 # define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1099 # define DATASTART_USES_BSDGETDATASTART
1102 # define ALIGNMENT 4
1103 # define OS_TYPE "NETBSD"
1105 extern ptr_t GC_data_start;
1106 # define DATASTART GC_data_start
1107 # define DYNAMIC_LOADING
1109 # ifdef SN_TARGET_PS3
1111 # define CPP_WORDSZ 32
1112 # define ALIGNMENT 4
1114 extern int __bss_start;
1115 # define DATASTART ((ptr_t)(__bss_start))
1116 # define DATAEND ((ptr_t)(_end))
1117 # define STACKBOTTOM ((ptr_t)ps3_get_stack_bottom())
1118 # define NO_PTHREAD_TRYLOCK
1119 /* Current GC LOCK() implementation for PS3 explicitly */
1120 /* use pthread_mutex_lock for some reason. */
1123 # define OS_TYPE "AIX"
1124 # undef ALIGNMENT /* in case it's defined */
1126 /* DOB: some AIX installs stupidly define IA64 in */
1127 /* /usr/include/sys/systemcfg.h */
1129 # define ALIGNMENT 8
1130 # define CPP_WORDSZ 64
1131 # define STACKBOTTOM ((ptr_t)0x1000000000000000)
1133 # define ALIGNMENT 4
1134 # define CPP_WORDSZ 32
1135 # define STACKBOTTOM ((ptr_t)((ulong)&errno))
1137 # define USE_MMAP_ANON
1138 /* From AIX linker man page:
1139 _text Specifies the first location of the program.
1140 _etext Specifies the first location after the program.
1141 _data Specifies the first location of the data.
1142 _edata Specifies the first location after the initialized data
1143 _end or end Specifies the first location after all data.
1145 extern int _data[], _end[];
1146 # define DATASTART ((ptr_t)((ulong)_data))
1147 # define DATAEND ((ptr_t)((ulong)_end))
1149 # define DYNAMIC_LOADING
1150 /* For really old versions of AIX, this may have to be removed. */
1154 # define ALIGNMENT 4
1155 # define OS_TYPE "NOSYS"
1156 extern void __end[], __dso_handle[];
1157 # define DATASTART ((ptr_t)__dso_handle) /* OK, that's ugly. */
1158 # define DATAEND ((ptr_t)(__end))
1159 /* Stack starts at 0xE0000000 for the simulator. */
1161 # define STACK_GRAN 0x10000000
1167 # define OS_TYPE "NACL"
1168 # if defined(__GLIBC__)
1169 # define DYNAMIC_LOADING
1171 # define DATASTART ((ptr_t)0x10020000)
1173 # define DATAEND ((ptr_t)_end)
1175 # define STACK_GRAN 0x10000
1177 # define NO_PTHREAD_GETATTR_NP
1178 # define USE_MMAP_ANON
1179 # define GETPAGESIZE() 65536
1180 # define MAX_NACL_GC_THREADS 1024
1184 # define MACH_TYPE "VAX"
1185 # define ALIGNMENT 4 /* Pointers are longword aligned by 4.2 C compiler */
1186 extern char etext[];
1187 # define DATASTART ((ptr_t)(etext))
1189 # define OS_TYPE "BSD"
1191 /* HEURISTIC2 may be OK, but it's hard to test. */
1194 # define OS_TYPE "ULTRIX"
1195 # define STACKBOTTOM ((ptr_t)0x7fffc800)
1200 # define MACH_TYPE "SPARC"
1201 # if defined(__arch64__) || defined(__sparcv9)
1202 # define ALIGNMENT 8
1203 # define CPP_WORDSZ 64
1204 # define ELF_CLASS ELFCLASS64
1206 # define ALIGNMENT 4 /* Required by hardware */
1207 # define CPP_WORDSZ 32
1209 /* Don't define USE_ASM_PUSH_REGS. We do use an asm helper, but */
1210 /* not to push the registers on the mark stack. */
1212 # define OS_TYPE "SOLARIS"
1213 extern int _etext[];
1215 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1216 # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1217 # define DATASTART_IS_FUNC
1218 # define DATAEND ((ptr_t)(_end))
1219 # if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1221 /* Otherwise we now use calloc. Mmap may result in the */
1222 /* heap interleaved with thread stacks, which can result in */
1223 /* excessive blacklisting. Sbrk is unusable since it */
1224 /* doesn't interact correctly with the system malloc. */
1227 # define HEAP_START (ptr_t)0x40000000
1229 # define HEAP_START DATAEND
1232 /* HEURISTIC1 reportedly no longer works under 2.7. */
1233 /* HEURISTIC2 probably works, but this appears to be preferable.*/
1234 /* Apparently USRSTACK is defined to be USERLIMIT, but in some */
1235 /* installations that's undefined. We work around this with a */
1238 # include <sys/vmparam.h>
1239 # include <unistd.h>
1242 /* This should work everywhere, but doesn't. */
1243 # define STACKBOTTOM ((ptr_t)USRSTACK)
1247 # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
1248 /* getpagesize() appeared to be missing from at least one */
1249 /* Solaris 5.4 installation. Weird. */
1250 # define DYNAMIC_LOADING
1253 # define OS_TYPE "DRSNX"
1255 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1256 # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
1257 # define DATASTART_IS_FUNC
1258 # define MPROTECT_VDB
1259 # define STACKBOTTOM ((ptr_t)0xdfff0000)
1260 # define DYNAMIC_LOADING
1263 # define OS_TYPE "LINUX"
1265 # define DYNAMIC_LOADING
1266 # elif !defined(CPPCHECK)
1267 # error Linux SPARC a.out not supported
1270 extern int _etext[];
1271 # define DATAEND ((ptr_t)(_end))
1273 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1275 # define DATASTART GC_SysVGetDataStart(0x100000, (ptr_t)_etext)
1277 # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
1279 # define DATASTART_IS_FUNC
1280 # define LINUX_STACKBOTTOM
1283 # define OS_TYPE "OPENBSD"
1284 # ifndef GC_OPENBSD_THREADS
1286 # include <sys/param.h>
1287 # include <uvm/uvm_extern.h>
1290 # define STACKBOTTOM ((ptr_t)USRSTACK)
1295 extern int __data_start[];
1296 # define DATASTART ((ptr_t)__data_start)
1298 # define DATAEND ((ptr_t)(&_end))
1299 # define DYNAMIC_LOADING
1302 # define OS_TYPE "NETBSD"
1305 extern ptr_t GC_data_start;
1306 # define DATASTART GC_data_start
1307 # define DYNAMIC_LOADING
1309 extern char etext[];
1310 # define DATASTART ((ptr_t)(etext))
1314 # define OS_TYPE "FREEBSD"
1315 # define SIG_SUSPEND SIGUSR1
1316 # define SIG_THR_RESTART SIGUSR2
1317 # define FREEBSD_STACKBOTTOM
1318 # define DYNAMIC_LOADING
1319 extern char etext[];
1320 extern char edata[];
1321 # if !defined(CPPCHECK)
1324 # define NEED_FIND_LIMIT
1325 # define DATASTART ((ptr_t)(&etext))
1326 void * GC_find_limit(void *, int);
1327 # define DATAEND (ptr_t)GC_find_limit(DATASTART, TRUE)
1328 # define DATAEND_IS_FUNC
1329 # define GC_HAVE_DATAREGION2
1330 # define DATASTART2 ((ptr_t)(&edata))
1331 # define DATAEND2 ((ptr_t)(&end))
1336 # define MACH_TYPE "I386"
1337 # if (defined(__LP64__) || defined(_WIN64)) && !defined(CPPCHECK)
1338 # error This should be handled as X86_64
1340 # define CPP_WORDSZ 32
1341 # define ALIGNMENT 4
1342 /* Appears to hold for all "32 bit" compilers */
1343 /* except Borland. The -a4 option fixes */
1344 /* Borland. For Watcom the option is -zp4. */
1347 # define OS_TYPE "SEQUENT"
1349 # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
1350 # define STACKBOTTOM ((ptr_t)0x3ffff000)
1352 # if defined(__EMSCRIPTEN__)
1353 # define OS_TYPE "EMSCRIPTEN"
1354 # define DATASTART (ptr_t)ALIGNMENT
1355 # define DATAEND (ptr_t)ALIGNMENT
1356 /* Since JavaScript/asm.js/WebAssembly is not able to access the */
1357 /* function call stack or the local data stack, it's not possible */
1358 /* for GC to perform its stack walking operation to find roots on */
1359 /* the stack. To work around that, the clients generally only do */
1360 /* BDWGC steps when the stack is empty so it is known that there */
1361 /* are no objects that would be found on the stack, and BDWGC is */
1362 /* compiled with stack walking disabled. */
1363 # define STACK_NOT_SCANNED
1365 # if defined(__QNX__)
1366 # define OS_TYPE "QNX"
1367 # define SA_RESTART 0
1369 extern char etext[];
1371 # define DATASTART ((ptr_t)etext)
1372 # define DATAEND ((ptr_t)_end)
1375 # define OS_TYPE "HAIKU"
1379 # define GETPAGESIZE() (unsigned)B_PAGE_SIZE
1381 # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
1382 # define DYNAMIC_LOADING
1383 # define MPROTECT_VDB
1386 # define OS_TYPE "SOLARIS"
1387 extern int _etext[], _end[];
1388 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1389 # define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
1390 # define DATASTART_IS_FUNC
1391 # define DATAEND ((ptr_t)(_end))
1392 /* # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7, */
1393 /* but reportedly breaks under 2.8. It appears that the stack */
1394 /* base is a property of the executable, so this should not */
1395 /* break old executables. */
1396 /* HEURISTIC2 probably works, but this appears to be preferable.*/
1397 /* Apparently USRSTACK is defined to be USERLIMIT, but in some */
1398 /* installations that's undefined. We work around this with a */
1401 # include <sys/vmparam.h>
1404 /* This should work everywhere, but doesn't. */
1405 # define STACKBOTTOM ((ptr_t)USRSTACK)
1409 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
1410 /* It appears to be fixed in 2.8 and 2.9. */
1411 # ifdef SOLARIS25_PROC_VDB_BUG_FIXED
1415 # define MPROTECT_VDB
1417 # define DYNAMIC_LOADING
1418 # if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
1420 /* Otherwise we now use calloc. Mmap may result in the */
1421 /* heap interleaved with thread stacks, which can result in */
1422 /* excessive blacklisting. Sbrk is unusable since it */
1423 /* doesn't interact correctly with the system malloc. */
1426 # define HEAP_START (ptr_t)0x40000000
1428 # define HEAP_START DATAEND
1432 # define OS_TYPE "SCO"
1434 # define DATASTART ((ptr_t)((((word)(etext)) + 0x3fffff) & ~0x3fffff) \
1435 + ((word)(etext) & 0xfff))
1436 # define STACKBOTTOM ((ptr_t)0x7ffffffc)
1439 # define OS_TYPE "SCO_ELF"
1441 # define DATASTART ((ptr_t)(etext))
1442 # define STACKBOTTOM ((ptr_t)0x08048000)
1443 # define DYNAMIC_LOADING
1444 # define ELF_CLASS ELFCLASS32
1447 # define OS_TYPE "DGUX"
1448 extern int _etext, _end;
1449 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
1450 # define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)(&_etext))
1451 # define DATASTART_IS_FUNC
1452 # define DATAEND ((ptr_t)(&_end))
1453 # define STACK_GROWS_DOWN
1456 # include <unistd.h>
1458 # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
1459 # define DYNAMIC_LOADING
1463 # define MAP_FAILED (void *) ((word)-1)
1464 # define HEAP_START (ptr_t)0x40000000
1467 # define OS_TYPE "LINUX"
1468 # define LINUX_STACKBOTTOM
1469 # if !defined(REDIRECT_MALLOC)
1470 # define MPROTECT_VDB
1472 /* We seem to get random errors in incremental mode, */
1473 /* possibly because Linux threads is itself a malloc client */
1474 /* and can't deal with the signals. */
1476 # define HEAP_START (ptr_t)0x1000
1477 /* This encourages mmap to give us low addresses, */
1478 /* thus allowing the heap to grow to ~3 GB. */
1480 # define DYNAMIC_LOADING
1482 # include <features.h>
1484 # if defined(__GLIBC__) && __GLIBC__ >= 2 \
1485 || defined(HOST_ANDROID) || defined(HOST_TIZEN)
1486 # define SEARCH_FOR_DATA_START
1488 extern char **__environ;
1489 # define DATASTART ((ptr_t)(&__environ))
1490 /* hideous kludge: __environ is the first */
1491 /* word in crt0.o, and delimits the start */
1492 /* of the data segment, no matter which */
1493 /* ld options were passed through. */
1494 /* We could use _etext instead, but that */
1495 /* would include .rodata, which may */
1496 /* contain large read-only data tables */
1497 /* that we'd rather not scan. */
1500 # define DATAEND ((ptr_t)(_end))
1501 # if !defined(GC_NO_SIGSETJMP) && (defined(HOST_TIZEN) \
1502 || (defined(HOST_ANDROID) \
1503 && !(GC_GNUC_PREREQ(4, 8) || GC_CLANG_PREREQ(3, 2) \
1504 || __ANDROID_API__ >= 18)))
1505 /* Older Android NDK releases lack sigsetjmp in x86 libc */
1506 /* (setjmp is used instead to find data_start). The bug */
1507 /* is fixed in Android NDK r8e (so, ok to use sigsetjmp */
1508 /* if gcc4.8+, clang3.2+ or Android API level 18+). */
1509 # define GC_NO_SIGSETJMP 1
1513 # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
1515 # ifdef USE_I686_PREFETCH
1516 # define PREFETCH(x) \
1517 __asm__ __volatile__ ("prefetchnta %0" : : "m"(*(char *)(x)))
1518 /* Empirically prefetcht0 is much more effective at reducing */
1519 /* cache miss stalls for the targeted load instructions. But it */
1520 /* seems to interfere enough with other cache traffic that the */
1521 /* net result is worse than prefetchnta. */
1522 # ifdef FORCE_WRITE_PREFETCH
1523 /* Using prefetches for write seems to have a slight negative */
1524 /* impact on performance, at least for a PIII/500. */
1525 # define GC_PREFETCH_FOR_WRITE(x) \
1526 __asm__ __volatile__ ("prefetcht0 %0" : : "m"(*(char *)(x)))
1528 # define GC_NO_PREFETCH_FOR_WRITE
1530 # elif defined(USE_3DNOW_PREFETCH)
1531 # define PREFETCH(x) \
1532 __asm__ __volatile__ ("prefetch %0" : : "m"(*(char *)(x)))
1533 # define GC_PREFETCH_FOR_WRITE(x) \
1534 __asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x)))
1536 # if defined(__GLIBC__) && !defined(__UCLIBC__)
1537 /* Workaround lock elision implementation for some glibc. */
1538 # define GLIBC_2_19_TSX_BUG
1540 # include <gnu/libc-version.h> /* for gnu_get_libc_version() */
1545 # define OS_TYPE "CYGWIN32"
1546 # define WOW64_THREAD_CONTEXT_WORKAROUND
1547 # define DATASTART ((ptr_t)GC_DATASTART) /* From gc.h */
1548 # define DATAEND ((ptr_t)GC_DATAEND)
1549 # ifdef USE_WINALLOC
1552 # /* MPROTECT_VDB does not work, it leads to a spurious exit. */
1554 # define NEED_FIND_LIMIT
1555 # define USE_MMAP_ANON
1560 # define OS_TYPE "INTERIX"
1561 extern int _data_start__[];
1562 extern int _bss_end__[];
1563 # define DATASTART ((ptr_t)_data_start__)
1564 # define DATAEND ((ptr_t)_bss_end__)
1565 # define STACKBOTTOM ({ ptr_t rv; \
1566 __asm__ __volatile__ ("movl %%fs:4, %%eax" \
1569 # define USE_MMAP_ANON
1572 # define OS_TYPE "OS2"
1573 /* STACKBOTTOM and DATASTART are handled specially in */
1574 /* os_dep.c. OS2 actually has the right */
1576 # define DATAEND /* not needed */
1579 # define OS_TYPE "MSWIN32"
1580 # define WOW64_THREAD_CONTEXT_WORKAROUND
1581 /* STACKBOTTOM and DATASTART are handled specially in */
1583 # define MPROTECT_VDB
1585 # define DATAEND /* not needed */
1588 # define OS_TYPE "MSWINCE"
1589 # define DATAEND /* not needed */
1592 # define OS_TYPE "DJGPP"
1594 # include "stubinfo.h"
1598 extern int __djgpp_stack_limit;
1599 # define DATASTART ((ptr_t)((((word)(etext)) + 0x1ff) & ~0x1ff))
1600 /* #define STACKBOTTOM ((ptr_t)((word)_stubinfo+_stubinfo->size+_stklen)) */
1601 # define STACKBOTTOM ((ptr_t)((word)__djgpp_stack_limit + _stklen))
1602 /* This may not be right. */
1605 # define OS_TYPE "OPENBSD"
1606 # ifndef GC_OPENBSD_THREADS
1608 # include <sys/param.h>
1609 # include <uvm/uvm_extern.h>
1612 # define STACKBOTTOM ((ptr_t)USRSTACK)
1617 extern int __data_start[];
1618 # define DATASTART ((ptr_t)__data_start)
1620 # define DATAEND ((ptr_t)(&_end))
1621 # define DYNAMIC_LOADING
1624 # define OS_TYPE "FREEBSD"
1625 # ifndef GC_FREEBSD_THREADS
1626 # define MPROTECT_VDB
1629 # define SIG_SUSPEND (32+6)
1630 # define SIG_THR_RESTART (32+5)
1632 # define DATAEND ((ptr_t)(_end))
1634 # define SIG_SUSPEND SIGUSR1
1635 # define SIG_THR_RESTART SIGUSR2
1636 /* SIGTSTP and SIGCONT could be used alternatively. */
1638 # define FREEBSD_STACKBOTTOM
1640 # define DYNAMIC_LOADING
1642 extern char etext[];
1643 # define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1644 # define DATASTART_USES_BSDGETDATASTART
1647 # define OS_TYPE "NETBSD"
1649 # define DYNAMIC_LOADING
1653 # define OS_TYPE "THREE86BSD"
1656 # define OS_TYPE "BSDI"
1658 # if defined(NETBSD) || defined(THREE86BSD) || defined(BSDI)
1660 extern char etext[];
1661 # define DATASTART ((ptr_t)(etext))
1664 # define OS_TYPE "NEXT"
1665 # define DATASTART ((ptr_t)get_etext())
1666 # define DATASTART_IS_FUNC
1667 # define STACKBOTTOM ((ptr_t)0xc0000000)
1668 # define DATAEND /* not needed */
1671 # define OS_TYPE "RTEMS"
1673 # include <sys/unistd.h>
1676 void *rtems_get_stack_bottom(void);
1677 # define InitStackBottom rtems_get_stack_bottom()
1678 # define DATASTART ((ptr_t)etext)
1679 # define STACKBOTTOM ((ptr_t)InitStackBottom)
1680 # define SIG_SUSPEND SIGUSR1
1681 # define SIG_THR_RESTART SIGUSR2
1684 # define OS_TYPE "DOS4GW"
1685 extern long __nullarea;
1687 extern char *_STACKTOP;
1688 /* Depending on calling conventions Watcom C either precedes */
1689 /* or does not precedes with underscore names of C-variables. */
1690 /* Make sure startup code variables always have the same names. */
1691 #pragma aux __nullarea "*";
1692 #pragma aux _end "*";
1693 # define STACKBOTTOM ((ptr_t)_STACKTOP)
1694 /* confused? me too. */
1695 # define DATASTART ((ptr_t)(&__nullarea))
1696 # define DATAEND ((ptr_t)(&_end))
1699 # define OS_TYPE "HURD"
1700 # define STACK_GROWS_DOWN
1702 # define SIG_SUSPEND SIGUSR1
1703 # define SIG_THR_RESTART SIGUSR2
1704 # define SEARCH_FOR_DATA_START
1706 # define DATAEND ((ptr_t)(_end))
1707 /* # define MPROTECT_VDB Not quite working yet? */
1708 # define DYNAMIC_LOADING
1709 # define USE_MMAP_ANON
1712 # define OS_TYPE "DARWIN"
1713 # define DARWIN_DONT_PARSE_STACK 1
1714 # define DYNAMIC_LOADING
1715 /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
1716 /* These aren't used when dyld support is enabled (it is by default). */
1717 # define DATASTART ((ptr_t)get_etext())
1718 # define DATAEND ((ptr_t)get_end())
1719 # define STACKBOTTOM ((ptr_t)0xc0000000)
1720 # define USE_MMAP_ANON
1721 # define MPROTECT_VDB
1723 # include <unistd.h>
1725 # define GETPAGESIZE() (unsigned)getpagesize()
1726 /* There seems to be some issues with trylock hanging on darwin. */
1727 /* This should be looked into some more. */
1728 # define NO_PTHREAD_TRYLOCK
1729 # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
1730 /* iPhone/iPad simulator */
1731 # define NO_DYLD_BIND_FULLY_IMAGE
1733 # endif /* DARWIN */
1737 # define MACH_TYPE "NS32K"
1738 # define ALIGNMENT 4
1739 extern char **environ;
1740 # define DATASTART ((ptr_t)(&environ))
1741 /* hideous kludge: environ is the first */
1742 /* word in crt0.o, and delimits the start */
1743 /* of the data segment, no matter which */
1744 /* ld options were passed through. */
1745 # define STACKBOTTOM ((ptr_t)0xfffff000) /* for Encore */
1749 # define MACH_TYPE "MIPS"
1751 # define OS_TYPE "LINUX"
1752 # define DYNAMIC_LOADING
1754 # pragma weak __data_start
1755 extern int __data_start[];
1756 # define DATASTART ((ptr_t)(__data_start))
1757 # define DATAEND ((ptr_t)(_end))
1759 # define CPP_WORDSZ _MIPS_SZPTR
1760 # define ALIGNMENT (_MIPS_SZPTR/8)
1762 # define ALIGNMENT 4
1765 # define HBLKSIZE 4096
1767 # if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
1768 # define LINUX_STACKBOTTOM
1770 # define STACKBOTTOM ((ptr_t)0x7fff8000)
1775 # if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
1776 extern int _fdata[], _end[];
1777 # define DATASTART ((ptr_t)_fdata)
1778 # define DATAEND ((ptr_t)_end)
1779 # define CPP_WORDSZ _MIPS_SZPTR
1780 # define ALIGNMENT (_MIPS_SZPTR/8)
1782 extern int etext[], edata[];
1783 # if !defined(CPPCHECK)
1786 extern int _DYNAMIC_LINKING[], _gp[];
1787 # define DATASTART ((ptr_t)((((word)(etext) + 0x3ffff) & ~0x3ffff) \
1788 + ((word)(etext) & 0xffff)))
1789 # define DATAEND ((ptr_t)(edata))
1790 # define GC_HAVE_DATAREGION2
1791 # define DATASTART2 (_DYNAMIC_LINKING \
1792 ? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
1794 # define DATAEND2 ((ptr_t)(end))
1795 # define ALIGNMENT 4
1797 # define OS_TYPE "EWS4800"
1801 # define DATASTART ((ptr_t)0x10000000)
1802 /* Could probably be slightly higher since */
1803 /* startup code allocates lots of stuff. */
1804 # define OS_TYPE "ULTRIX"
1805 # define ALIGNMENT 4
1809 extern int _fdata[];
1810 # define DATASTART ((ptr_t)(_fdata))
1812 # define HEAP_START (ptr_t)0x30000000
1814 # define HEAP_START DATASTART
1816 /* Lowest plausible heap address. */
1817 /* In the MMAP case, we map there. */
1818 /* In either case it is used to identify */
1819 /* heap sections so they're not */
1820 /* considered as roots. */
1821 # define OS_TYPE "IRIX5"
1822 /*# define MPROTECT_VDB DOB: this should work, but there is evidence */
1823 /* of recent breakage. */
1825 # define CPP_WORDSZ _MIPS_SZPTR
1826 # define ALIGNMENT (_MIPS_SZPTR/8)
1828 # define ALIGNMENT 4
1830 # define DYNAMIC_LOADING
1833 # define OS_TYPE "MSWINCE"
1834 # define ALIGNMENT 4
1835 # define DATAEND /* not needed */
1838 # define OS_TYPE "NETBSD"
1839 # define ALIGNMENT 4
1842 extern ptr_t GC_data_start;
1843 # define DATASTART GC_data_start
1844 # define NEED_FIND_LIMIT
1845 # define DYNAMIC_LOADING
1847 # define DATASTART ((ptr_t)0x10000000)
1848 # define STACKBOTTOM ((ptr_t)0x7ffff000)
1852 # define OS_TYPE "OPENBSD"
1853 # define CPP_WORDSZ 64 /* all OpenBSD/mips platforms are 64-bit */
1854 # define ALIGNMENT 8
1855 # ifndef GC_OPENBSD_THREADS
1857 # include <sys/param.h>
1858 # include <uvm/uvm_extern.h>
1861 # define STACKBOTTOM ((ptr_t)USRSTACK)
1866 extern int __data_start[];
1867 # define DATASTART ((ptr_t)__data_start)
1869 # define DATAEND ((ptr_t)(&_end))
1870 # define DYNAMIC_LOADING
1873 # define OS_TYPE "FREEBSD"
1874 # define ALIGNMENT 4
1875 # ifndef GC_FREEBSD_THREADS
1876 # define MPROTECT_VDB
1878 # define SIG_SUSPEND SIGUSR1
1879 # define SIG_THR_RESTART SIGUSR2
1880 # define FREEBSD_STACKBOTTOM
1881 # define DYNAMIC_LOADING
1882 extern char etext[];
1883 # define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
1884 # define DATASTART_USES_BSDGETDATASTART
1885 # endif /* FreeBSD */
1886 # if defined(NONSTOP)
1887 # define CPP_WORDSZ 32
1888 # define OS_TYPE "NONSTOP"
1889 # define ALIGNMENT 4
1890 # define DATASTART ((ptr_t)0x08000000)
1891 extern char **environ;
1892 # define DATAEND ((ptr_t)(environ - 0x10))
1893 # define STACKBOTTOM ((ptr_t)0x4fffffff)
1898 # define CPP_WORDSZ 32
1899 # define MACH_TYPE "NIOS2"
1901 # define OS_TYPE "LINUX"
1902 # define DYNAMIC_LOADING
1904 extern int __data_start[];
1905 # define DATASTART ((ptr_t)(__data_start))
1906 # define DATAEND ((ptr_t)(_end))
1907 # define ALIGNMENT 4
1909 # define HBLKSIZE 4096
1911 # define LINUX_STACKBOTTOM
1916 # define CPP_WORDSZ 32
1917 # define MACH_TYPE "OR1K"
1919 # define OS_TYPE "LINUX"
1920 # define DYNAMIC_LOADING
1922 extern int __data_start[];
1923 # define DATASTART ((ptr_t)(__data_start))
1924 # define DATAEND ((ptr_t)(_end))
1925 # define ALIGNMENT 4
1927 # define HBLKSIZE 4096
1929 # define LINUX_STACKBOTTOM
1934 # define MACH_TYPE "HP_PA"
1936 # define CPP_WORDSZ 64
1937 # define ALIGNMENT 8
1939 # define CPP_WORDSZ 32
1940 # define ALIGNMENT 4
1942 # if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) \
1943 && !defined(OPENBSD) && !defined(LINUX) /* For now. */
1944 # define MPROTECT_VDB
1946 # define STACK_GROWS_UP
1948 # define OS_TYPE "HPUX"
1949 extern int __data_start[];
1950 # define DATASTART ((ptr_t)(__data_start))
1951 # ifdef USE_HPUX_FIXED_STACKBOTTOM
1952 /* The following appears to work for 7xx systems running HP/UX */
1953 /* 9.xx. Furthermore, it might result in much faster */
1954 /* collections than HEURISTIC2, which may involve scanning */
1955 /* segments that directly precede the stack. It is not the */
1956 /* default, since it may not work on older machine/OS */
1957 /* combinations. (Thanks to Raymond X.T. Nijssen for uncovering */
1959 # define STACKBOTTOM ((ptr_t)0x7b033000) /* from /etc/conf/h/param.h */
1961 /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */
1962 /* to this. Note that the GC must be initialized before the */
1963 /* first putenv call. */
1964 extern char ** environ;
1965 # define STACKBOTTOM ((ptr_t)environ)
1967 # define DYNAMIC_LOADING
1969 # include <unistd.h>
1971 # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE)
1973 # define PREFETCH(x) do { \
1974 register long addr = (long)(x); \
1975 (void) _asm ("LDW", 0, 0, addr, 0); \
1980 # define OS_TYPE "LINUX"
1981 # define LINUX_STACKBOTTOM
1982 # define DYNAMIC_LOADING
1983 # define SEARCH_FOR_DATA_START
1985 # define DATAEND ((ptr_t)(&_end))
1988 # define OS_TYPE "OPENBSD"
1989 # ifndef GC_OPENBSD_THREADS
1991 # include <sys/param.h>
1992 # include <uvm/uvm_extern.h>
1995 # define STACKBOTTOM ((ptr_t)USRSTACK)
2000 extern int __data_start[];
2001 # define DATASTART ((ptr_t)__data_start)
2003 # define DATAEND ((ptr_t)(&_end))
2004 # define DYNAMIC_LOADING
2009 # define MACH_TYPE "ALPHA"
2010 # define ALIGNMENT 8
2011 # define CPP_WORDSZ 64
2013 # define OS_TYPE "NETBSD"
2015 extern ptr_t GC_data_start;
2016 # define DATASTART GC_data_start
2017 # define ELFCLASS32 32
2018 # define ELFCLASS64 64
2019 # define ELF_CLASS ELFCLASS64
2020 # define DYNAMIC_LOADING
2023 # define OS_TYPE "OPENBSD"
2024 # define ELF_CLASS ELFCLASS64
2025 # ifndef GC_OPENBSD_THREADS
2027 # include <sys/param.h>
2028 # include <uvm/uvm_extern.h>
2031 # define STACKBOTTOM ((ptr_t)USRSTACK)
2036 extern int __data_start[];
2037 # define DATASTART ((ptr_t)__data_start)
2039 # define DATAEND ((ptr_t)(&_end))
2040 # define DYNAMIC_LOADING
2043 # define OS_TYPE "FREEBSD"
2044 /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */
2045 # define SIG_SUSPEND SIGUSR1
2046 # define SIG_THR_RESTART SIGUSR2
2047 /* SIGTSTP and SIGCONT could be used alternatively. */
2048 # define FREEBSD_STACKBOTTOM
2049 # define DYNAMIC_LOADING
2050 /* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */
2051 extern char etext[];
2052 extern char edata[];
2053 # if !defined(CPPCHECK)
2056 # define NEED_FIND_LIMIT
2057 # define DATASTART ((ptr_t)(&etext))
2058 void * GC_find_limit(void *, int);
2059 # define DATAEND (ptr_t)GC_find_limit(DATASTART, TRUE)
2060 # define DATAEND_IS_FUNC
2061 # define GC_HAVE_DATAREGION2
2062 # define DATASTART2 ((ptr_t)(&edata))
2063 # define DATAEND2 ((ptr_t)(&end))
2066 # define OS_TYPE "OSF1"
2067 # define DATASTART ((ptr_t)0x140000000)
2069 # define DATAEND ((ptr_t)(&_end))
2070 extern char ** environ;
2071 /* round up from the value of environ to the nearest page boundary */
2072 /* Probably breaks if putenv is called before collector */
2073 /* initialization. */
2074 # define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1))
2075 /* # define HEURISTIC2 */
2076 /* Normally HEURISTIC2 is too conservative, since */
2077 /* the text segment immediately follows the stack. */
2078 /* Hence we give an upper pound. */
2079 /* This is currently unused, since we disabled HEURISTIC2 */
2080 extern int __start[];
2081 # define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
2082 # ifndef GC_OSF1_THREADS
2083 /* Unresolved signal issues with threads. */
2084 # define MPROTECT_VDB
2086 # define DYNAMIC_LOADING
2089 # define OS_TYPE "LINUX"
2090 # define LINUX_STACKBOTTOM
2092 # define SEARCH_FOR_DATA_START
2093 # define DYNAMIC_LOADING
2095 # define DATASTART ((ptr_t)0x140000000)
2098 # define DATAEND ((ptr_t)(_end))
2099 # if !defined(REDIRECT_MALLOC)
2100 # define MPROTECT_VDB
2101 /* Has only been superficially tested. May not */
2102 /* work on all versions. */
2108 # define MACH_TYPE "IA64"
2111 # define CPP_WORDSZ 32
2112 /* Requires 8 byte alignment for malloc */
2113 # define ALIGNMENT 4
2115 # if !defined(_LP64) && !defined(CPPCHECK)
2118 # define CPP_WORDSZ 64
2119 /* Requires 16 byte alignment for malloc */
2120 # define ALIGNMENT 8
2122 # define OS_TYPE "HPUX"
2123 extern int __data_start[];
2124 # define DATASTART ((ptr_t)(__data_start))
2125 /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */
2126 /* to this. Note that the GC must be initialized before the */
2127 /* first putenv call. */
2128 extern char ** environ;
2129 # define STACKBOTTOM ((ptr_t)environ)
2130 # define HPUX_STACKBOTTOM
2131 # define DYNAMIC_LOADING
2133 # include <unistd.h>
2135 # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE)
2136 /* The following was empirically determined, and is probably */
2137 /* not very robust. */
2138 /* Note that the backing store base seems to be at a nice */
2139 /* address minus one page. */
2140 # define BACKING_STORE_DISPLACEMENT 0x1000000
2141 # define BACKING_STORE_ALIGNMENT 0x1000
2142 extern ptr_t GC_register_stackbottom;
2143 # define BACKING_STORE_BASE GC_register_stackbottom
2144 /* Known to be wrong for recent HP/UX versions!!! */
2147 # define CPP_WORDSZ 64
2148 # define ALIGNMENT 8
2149 # define OS_TYPE "LINUX"
2150 /* The following works on NUE and older kernels: */
2151 /* # define STACKBOTTOM ((ptr_t) 0xa000000000000000l) */
2152 /* This does not work on NUE: */
2153 # define LINUX_STACKBOTTOM
2154 /* We also need the base address of the register stack */
2155 /* backing store. */
2156 extern ptr_t GC_register_stackbottom;
2157 # define BACKING_STORE_BASE GC_register_stackbottom
2158 # define SEARCH_FOR_DATA_START
2160 # define DYNAMIC_LOADING
2162 /* In the Intel compiler environment, we seem to end up with */
2163 /* statically linked executables and an undefined reference */
2166 # if !defined(REDIRECT_MALLOC)
2167 # define MPROTECT_VDB
2168 /* Requires Linux 2.3.47 or later. */
2171 # define DATAEND ((ptr_t)(_end))
2173 # ifndef __INTEL_COMPILER
2174 # define PREFETCH(x) \
2175 __asm__ (" lfetch [%0]": : "r"(x))
2176 # define GC_PREFETCH_FOR_WRITE(x) \
2177 __asm__ (" lfetch.excl [%0]": : "r"(x))
2178 # define CLEAR_DOUBLE(x) \
2179 __asm__ (" stf.spill [%0]=f0": : "r"((void *)(x)))
2182 # include <ia64intrin.h>
2184 # define PREFETCH(x) __lfetch(__lfhint_none, (x))
2185 # define GC_PREFETCH_FOR_WRITE(x) __lfetch(__lfhint_nta, (x))
2186 # define CLEAR_DOUBLE(x) __stf_spill((void *)(x), 0)
2187 # endif /* __INTEL_COMPILER */
2191 /* FIXME: This is a very partial guess. There is no port, yet. */
2192 # define OS_TYPE "MSWIN32"
2193 /* STACKBOTTOM and DATASTART are handled specially in */
2195 # define DATAEND /* not needed */
2196 # if defined(_WIN64)
2197 # define CPP_WORDSZ 64
2199 # define CPP_WORDSZ 32 /* Is this possible? */
2201 # define ALIGNMENT 8
2206 # define MACH_TYPE "M88K"
2207 # define ALIGNMENT 4
2210 # define OS_TYPE "CX_UX"
2211 # define DATASTART ((ptr_t)((((word)(etext) + 0x3fffff) & ~0x3fffff) \
2215 # define OS_TYPE "DGUX"
2216 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2217 # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext)
2218 # define DATASTART_IS_FUNC
2220 # define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
2224 /* If this still works, and if anyone cares, this should probably */
2225 /* be moved to the S390 category. */
2226 # define MACH_TYPE "S370"
2227 # define ALIGNMENT 4 /* Required by hardware */
2229 # define OS_TYPE "UTS4"
2231 extern int _etext[];
2233 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2234 # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext)
2235 # define DATASTART_IS_FUNC
2236 # define DATAEND ((ptr_t)(_end))
2242 # define MACH_TYPE "S390"
2244 # define ALIGNMENT 4
2245 # define CPP_WORDSZ 32
2247 # define ALIGNMENT 8
2248 # define CPP_WORDSZ 64
2250 # define HBLKSIZE 4096
2254 # define OS_TYPE "LINUX"
2255 # define LINUX_STACKBOTTOM
2256 # define DYNAMIC_LOADING
2257 extern int __data_start[] __attribute__((__weak__));
2258 # define DATASTART ((ptr_t)(__data_start))
2259 extern int _end[] __attribute__((__weak__));
2260 # define DATAEND ((ptr_t)(_end))
2261 # define CACHE_LINE_SIZE 256
2262 # define GETPAGESIZE() 4096
2267 # define MACH_TYPE "AARCH64"
2269 # define CPP_WORDSZ 32
2270 # define ALIGNMENT 4
2272 # define CPP_WORDSZ 64
2273 # define ALIGNMENT 8
2276 # define HBLKSIZE 4096
2279 # define OS_TYPE "LINUX"
2280 # define LINUX_STACKBOTTOM
2281 # if !defined(REDIRECT_MALLOC)
2282 # define MPROTECT_VDB
2284 # define DYNAMIC_LOADING
2285 # if defined(HOST_ANDROID)
2286 # define SEARCH_FOR_DATA_START
2288 extern int __data_start[];
2289 # define DATASTART ((ptr_t)__data_start)
2292 # define DATAEND ((ptr_t)(&_end))
2296 # define OS_TYPE "DARWIN"
2297 # define DARWIN_DONT_PARSE_STACK 1
2298 # define DYNAMIC_LOADING
2299 # define DATASTART ((ptr_t)get_etext())
2300 # define DATAEND ((ptr_t)get_end())
2301 # define STACKBOTTOM ((ptr_t)0x16fdfffff)
2302 # define USE_MMAP_ANON
2303 # define MPROTECT_VDB
2305 # include <unistd.h>
2307 # define GETPAGESIZE() (unsigned)getpagesize()
2308 /* FIXME: There seems to be some issues with trylock hanging on */
2309 /* darwin. This should be looked into some more. */
2310 # define NO_PTHREAD_TRYLOCK
2311 # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
2312 # define NO_DYLD_BIND_FULLY_IMAGE
2316 # define OS_TYPE "FREEBSD"
2317 # ifndef GC_FREEBSD_THREADS
2318 # define MPROTECT_VDB
2320 # define FREEBSD_STACKBOTTOM
2321 # define DYNAMIC_LOADING
2322 extern char etext[];
2323 # define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
2324 # define DATASTART_USES_BSDGETDATASTART
2327 # define OS_TYPE "NETBSD"
2329 extern ptr_t GC_data_start;
2330 # define DATASTART GC_data_start
2331 # define ELF_CLASS ELFCLASS64
2332 # define DYNAMIC_LOADING
2335 # define OS_TYPE "OPENBSD"
2336 # define ELF_CLASS ELFCLASS64
2337 # ifndef GC_OPENBSD_THREADS
2339 # include <sys/param.h>
2340 # include <uvm/uvm_extern.h>
2343 # define STACKBOTTOM ((ptr_t)USRSTACK)
2348 extern int __data_start[];
2349 # define DATASTART ((ptr_t)__data_start)
2351 # define DATAEND ((ptr_t)(&_end))
2352 # define DYNAMIC_LOADING
2354 # ifdef NINTENDO_SWITCH
2355 extern int __bss_end[];
2356 # define NO_HANDLE_FORK 1
2357 # define DATASTART (ptr_t)ALIGNMENT /* cannot be null */
2358 # define DATAEND (ptr_t)(&__bss_end)
2359 void *switch_get_stack_bottom(void);
2360 # define STACKBOTTOM ((ptr_t)switch_get_stack_bottom())
2362 # ifdef MSWIN32 /* UWP */
2363 # define OS_TYPE "MSWIN32"
2364 /* TODO: Enable GWW_VDB and/or MPROTECT_VDB */
2366 # define DATAEND /* not needed */
2370 /* __data_start is usually defined in the target linker script. */
2371 extern int __data_start[];
2372 # define DATASTART ((ptr_t)__data_start)
2373 extern void *__stack_base__;
2374 # define STACKBOTTOM ((ptr_t)__stack_base__)
2380 # define MACH_TYPE "NACL"
2382 # define MACH_TYPE "ARM32"
2384 # define CPP_WORDSZ 32
2385 # define ALIGNMENT 4
2387 # define OS_TYPE "NETBSD"
2390 extern ptr_t GC_data_start;
2391 # define DATASTART GC_data_start
2392 # define DYNAMIC_LOADING
2394 extern char etext[];
2395 # define DATASTART ((ptr_t)(etext))
2399 # define OS_TYPE "LINUX"
2400 # define LINUX_STACKBOTTOM
2401 # if !defined(REDIRECT_MALLOC)
2402 # define MPROTECT_VDB
2404 # define DYNAMIC_LOADING
2406 # include <features.h>
2408 # if defined(__GLIBC__) && __GLIBC__ >= 2 \
2409 || defined(HOST_ANDROID) || defined(HOST_TIZEN)
2410 # define SEARCH_FOR_DATA_START
2412 extern char **__environ;
2413 # define DATASTART ((ptr_t)(&__environ))
2414 /* hideous kludge: __environ is the first */
2415 /* word in crt0.o, and delimits the start */
2416 /* of the data segment, no matter which */
2417 /* ld options were passed through. */
2418 /* We could use _etext instead, but that */
2419 /* would include .rodata, which may */
2420 /* contain large read-only data tables */
2421 /* that we'd rather not scan. */
2424 # define DATAEND ((ptr_t)(_end))
2427 # define OS_TYPE "MSWINCE"
2428 # define DATAEND /* not needed */
2432 # define OS_TYPE "FREEBSD"
2433 # ifndef GC_FREEBSD_THREADS
2434 # define MPROTECT_VDB
2436 # define SIG_SUSPEND SIGUSR1
2437 # define SIG_THR_RESTART SIGUSR2
2438 # define FREEBSD_STACKBOTTOM
2439 # define DYNAMIC_LOADING
2440 extern char etext[];
2441 # define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
2442 # define DATASTART_USES_BSDGETDATASTART
2446 # define OS_TYPE "DARWIN"
2447 # define DARWIN_DONT_PARSE_STACK 1
2448 # define DYNAMIC_LOADING
2449 # define DATASTART ((ptr_t)get_etext())
2450 # define DATAEND ((ptr_t)get_end())
2451 # define STACKBOTTOM ((ptr_t)0x30000000)
2452 # define USE_MMAP_ANON
2453 # define MPROTECT_VDB
2455 # include <unistd.h>
2457 # define GETPAGESIZE() (unsigned)getpagesize()
2458 /* FIXME: There seems to be some issues with trylock hanging on */
2459 /* darwin. This should be looked into some more. */
2460 # define NO_PTHREAD_TRYLOCK
2461 # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
2462 # define NO_DYLD_BIND_FULLY_IMAGE
2466 # define OS_TYPE "OPENBSD"
2467 # ifndef GC_OPENBSD_THREADS
2469 # include <sys/param.h>
2470 # include <uvm/uvm_extern.h>
2473 # define STACKBOTTOM ((ptr_t)USRSTACK)
2478 extern int __data_start[];
2479 # define DATASTART ((ptr_t)__data_start)
2481 # define DATAEND ((ptr_t)(&_end))
2482 # define DYNAMIC_LOADING
2484 # ifdef SN_TARGET_PSP2
2485 # define NO_HANDLE_FORK 1
2486 # define DATASTART (ptr_t)ALIGNMENT
2487 # define DATAEND (ptr_t)ALIGNMENT
2488 void *psp2_get_stack_bottom(void);
2489 # define STACKBOTTOM ((ptr_t)psp2_get_stack_bottom())
2491 # ifdef NN_PLATFORM_CTR
2492 extern unsigned char Image$$ZI$$ZI$$Base[];
2493 # define DATASTART (ptr_t)(Image$$ZI$$ZI$$Base)
2494 extern unsigned char Image$$ZI$$ZI$$Limit[];
2495 # define DATAEND (ptr_t)(Image$$ZI$$ZI$$Limit)
2496 void *n3ds_get_stack_bottom(void);
2497 # define STACKBOTTOM ((ptr_t)n3ds_get_stack_bottom())
2499 # ifdef MSWIN32 /* UWP */
2500 # define OS_TYPE "MSWIN32"
2501 /* TODO: Enable GWW_VDB and/or MPROTECT_VDB */
2503 # define DATAEND /* not needed */
2507 /* __data_start is usually defined in the target linker script. */
2508 extern int __data_start[];
2509 # define DATASTART ((ptr_t)(__data_start))
2510 /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S */
2511 extern void *__stack_base__;
2512 # define STACKBOTTOM ((ptr_t)(__stack_base__))
2517 # define MACH_TYPE "CRIS"
2518 # define CPP_WORDSZ 32
2519 # define ALIGNMENT 1
2521 # define OS_TYPE "LINUX"
2522 # define DYNAMIC_LOADING
2523 # define LINUX_STACKBOTTOM
2524 # define SEARCH_FOR_DATA_START
2526 # define DATAEND ((ptr_t)(_end))
2530 # if defined(SH) && !defined(SH4)
2531 # define MACH_TYPE "SH"
2532 # define ALIGNMENT 4
2534 # define OS_TYPE "MSWINCE"
2535 # define DATAEND /* not needed */
2538 # define OS_TYPE "LINUX"
2539 # define LINUX_STACKBOTTOM
2540 # define DYNAMIC_LOADING
2541 # define SEARCH_FOR_DATA_START
2543 # define DATAEND ((ptr_t)(_end))
2546 # define OS_TYPE "NETBSD"
2548 extern ptr_t GC_data_start;
2549 # define DATASTART GC_data_start
2550 # define DYNAMIC_LOADING
2553 # define OS_TYPE "OPENBSD"
2554 # ifndef GC_OPENBSD_THREADS
2556 # include <sys/param.h>
2557 # include <uvm/uvm_extern.h>
2560 # define STACKBOTTOM ((ptr_t)USRSTACK)
2565 extern int __data_start[];
2566 # define DATASTART ((ptr_t)__data_start)
2568 # define DATAEND ((ptr_t)(&_end))
2569 # define DYNAMIC_LOADING
2574 # define MACH_TYPE "SH4"
2575 # define ALIGNMENT 4
2577 # define OS_TYPE "MSWINCE"
2578 # define DATAEND /* not needed */
2583 # define MACH_TYPE "AVR32"
2584 # define CPP_WORDSZ 32
2585 # define ALIGNMENT 4
2587 # define OS_TYPE "LINUX"
2588 # define DYNAMIC_LOADING
2589 # define LINUX_STACKBOTTOM
2590 # define SEARCH_FOR_DATA_START
2592 # define DATAEND ((ptr_t)(_end))
2597 # define CPP_WORDSZ 32
2598 # define MACH_TYPE "M32R"
2599 # define ALIGNMENT 4
2601 # define OS_TYPE "LINUX"
2602 # define LINUX_STACKBOTTOM
2603 # define DYNAMIC_LOADING
2604 # define SEARCH_FOR_DATA_START
2606 # define DATAEND ((ptr_t)(_end))
2611 # define MACH_TYPE "X86_64"
2613 # define ALIGNMENT 4
2614 # define CPP_WORDSZ 32
2616 # define ALIGNMENT 8
2617 # define CPP_WORDSZ 64
2620 # define HBLKSIZE 4096
2622 # ifndef CACHE_LINE_SIZE
2623 # define CACHE_LINE_SIZE 64
2625 # ifdef SN_TARGET_ORBIS
2626 # define DATASTART (ptr_t)ALIGNMENT
2627 # define DATAEND (ptr_t)ALIGNMENT
2628 void *ps4_get_stack_bottom(void);
2629 # define STACKBOTTOM ((ptr_t)ps4_get_stack_bottom())
2632 # define OS_TYPE "OPENBSD"
2633 # define ELF_CLASS ELFCLASS64
2634 # ifndef GC_OPENBSD_THREADS
2636 # include <sys/param.h>
2637 # include <uvm/uvm_extern.h>
2640 # define STACKBOTTOM ((ptr_t)USRSTACK)
2645 extern int __data_start[];
2647 # define DATASTART ((ptr_t)__data_start)
2648 # define DATAEND ((ptr_t)(&_end))
2649 # define DYNAMIC_LOADING
2652 # define OS_TYPE "LINUX"
2653 # define LINUX_STACKBOTTOM
2654 # if !defined(REDIRECT_MALLOC)
2655 # define MPROTECT_VDB
2657 /* We seem to get random errors in incremental mode, */
2658 /* possibly because Linux threads is itself a malloc client */
2659 /* and can't deal with the signals. */
2661 # define DYNAMIC_LOADING
2663 # include <features.h>
2665 # define SEARCH_FOR_DATA_START
2667 # define DATAEND ((ptr_t)(_end))
2668 # if defined(__GLIBC__) && !defined(__UCLIBC__)
2669 /* A workaround for GCF (Google Cloud Function) which does */
2670 /* not support mmap() for "/dev/zero". Should not cause any */
2671 /* harm to other targets. */
2672 # define USE_MMAP_ANON
2673 /* At present, there's a bug in GLibc getcontext() on */
2674 /* Linux/x64 (it clears FPU exception mask). We define this */
2675 /* macro to workaround it. */
2676 /* TODO: This seems to be fixed in GLibc v2.14. */
2677 # define GETCONTEXT_FPU_EXCMASK_BUG
2678 /* Workaround lock elision implementation for some glibc. */
2679 # define GLIBC_2_19_TSX_BUG
2681 # include <gnu/libc-version.h> /* for gnu_get_libc_version() */
2686 # define OS_TYPE "DARWIN"
2687 # define DARWIN_DONT_PARSE_STACK 1
2688 # define DYNAMIC_LOADING
2689 /* XXX: see get_end(3), get_etext() and get_end() should not be used. */
2690 /* These aren't used when dyld support is enabled (it is by default) */
2691 # define DATASTART ((ptr_t)get_etext())
2692 # define DATAEND ((ptr_t)get_end())
2693 # define STACKBOTTOM ((ptr_t)0x7fff5fc00000)
2694 # define USE_MMAP_ANON
2695 # define MPROTECT_VDB
2697 # include <unistd.h>
2699 # define GETPAGESIZE() (unsigned)getpagesize()
2700 /* There seems to be some issues with trylock hanging on darwin. */
2701 /* This should be looked into some more. */
2702 # define NO_PTHREAD_TRYLOCK
2703 # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE)
2704 /* iPhone/iPad simulator */
2705 # define NO_DYLD_BIND_FULLY_IMAGE
2709 # define OS_TYPE "FREEBSD"
2710 # ifndef GC_FREEBSD_THREADS
2711 # define MPROTECT_VDB
2714 # define SIG_SUSPEND (32+6)
2715 # define SIG_THR_RESTART (32+5)
2717 # define DATAEND ((ptr_t)(_end))
2719 # define SIG_SUSPEND SIGUSR1
2720 # define SIG_THR_RESTART SIGUSR2
2721 /* SIGTSTP and SIGCONT could be used alternatively. */
2723 # define FREEBSD_STACKBOTTOM
2724 # define DYNAMIC_LOADING
2725 extern char etext[];
2726 # define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext)
2727 # define DATASTART_USES_BSDGETDATASTART
2730 # define OS_TYPE "NETBSD"
2732 extern ptr_t GC_data_start;
2733 # define DATASTART GC_data_start
2734 # define DYNAMIC_LOADING
2737 # define OS_TYPE "HAIKU"
2741 # define GETPAGESIZE() (unsigned)B_PAGE_SIZE
2743 # define SEARCH_FOR_DATA_START
2744 # define DYNAMIC_LOADING
2745 # define MPROTECT_VDB
2748 # define OS_TYPE "SOLARIS"
2749 # define ELF_CLASS ELFCLASS64
2750 extern int _etext[], _end[];
2751 ptr_t GC_SysVGetDataStart(size_t, ptr_t);
2752 # define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext)
2753 # define DATASTART_IS_FUNC
2754 # define DATAEND ((ptr_t)(_end))
2755 /* # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7, */
2756 /* but reportedly breaks under 2.8. It appears that the stack */
2757 /* base is a property of the executable, so this should not */
2758 /* break old executables. */
2759 /* HEURISTIC2 probably works, but this appears to be preferable.*/
2760 /* Apparently USRSTACK is defined to be USERLIMIT, but in some */
2761 /* installations that's undefined. We work around this with a */
2764 # include <sys/vmparam.h>
2767 /* This should work everywhere, but doesn't. */
2768 # define STACKBOTTOM ((ptr_t)USRSTACK)
2772 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
2773 /* It appears to be fixed in 2.8 and 2.9. */
2774 # ifdef SOLARIS25_PROC_VDB_BUG_FIXED
2778 # define MPROTECT_VDB
2780 # define DYNAMIC_LOADING
2781 # if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
2783 /* Otherwise we now use calloc. Mmap may result in the */
2784 /* heap interleaved with thread stacks, which can result in */
2785 /* excessive blacklisting. Sbrk is unusable since it */
2786 /* doesn't interact correctly with the system malloc. */
2789 # define HEAP_START (ptr_t)0x40000000
2791 # define HEAP_START DATAEND
2795 # define OS_TYPE "CYGWIN32"
2796 # ifdef USE_WINALLOC
2799 # if defined(THREAD_LOCAL_ALLOC)
2800 /* TODO: For an unknown reason, thread-local allocations */
2801 /* lead to spurious process exit after the fault handler is */
2804 # define MPROTECT_VDB
2807 # define USE_MMAP_ANON
2813 # define DATASTART (ptr_t)ALIGNMENT
2814 # define DATAEND (ptr_t)ALIGNMENT
2815 LONG64 durango_get_stack_bottom(void);
2816 # define STACKBOTTOM ((ptr_t)durango_get_stack_bottom())
2817 # define GETPAGESIZE() 4096
2821 /* The following is from sys/mman.h: */
2822 # define PROT_NONE 0
2823 # define PROT_READ 1
2824 # define PROT_WRITE 2
2825 # define PROT_EXEC 4
2826 # define MAP_PRIVATE 2
2827 # define MAP_FIXED 0x10
2828 # define MAP_FAILED ((void *)-1)
2831 # define OS_TYPE "MSWIN32"
2832 /* STACKBOTTOM and DATASTART are handled specially in */
2834 # if !defined(__GNUC__) || defined(__INTEL_COMPILER) \
2835 || GC_GNUC_PREREQ(4, 7)
2836 /* Older GCC has not supported SetUnhandledExceptionFilter */
2837 /* properly on x64 (e.g. SEH unwinding information missed). */
2838 # define MPROTECT_VDB
2842 # define DATAEND /* not needed */
2845 # endif /* X86_64 */
2848 # define CPP_WORDSZ 32
2849 # define MACH_TYPE "HEXAGON"
2850 # define ALIGNMENT 4
2852 # define OS_TYPE "LINUX"
2853 # define LINUX_STACKBOTTOM
2854 # if !defined(REDIRECT_MALLOC)
2855 # define MPROTECT_VDB
2857 # define DYNAMIC_LOADING
2859 # include <features.h>
2861 # if defined(__GLIBC__)
2862 # define SEARCH_FOR_DATA_START
2863 # elif !defined(CPPCHECK)
2864 # error Unknown Hexagon libc configuration
2867 # define DATAEND ((ptr_t)(_end))
2872 # define CPP_WORDSZ 32
2873 # define MACH_TYPE "TILEPro"
2874 # define ALIGNMENT 4
2875 # define PREFETCH(x) __insn_prefetch(x)
2876 # define CACHE_LINE_SIZE 64
2878 # define OS_TYPE "LINUX"
2879 extern int __data_start[];
2880 # define DATASTART ((ptr_t)__data_start)
2881 # define LINUX_STACKBOTTOM
2882 # define DYNAMIC_LOADING
2887 # define CPP_WORDSZ (__SIZEOF_POINTER__ * 8)
2888 # define MACH_TYPE "TILE-Gx"
2889 # define ALIGNMENT __SIZEOF_POINTER__
2890 # if CPP_WORDSZ < 64
2891 # define CLEAR_DOUBLE(x) (*(long long *)(x) = 0)
2893 # define PREFETCH(x) __insn_prefetch_l1(x)
2894 # define CACHE_LINE_SIZE 64
2896 # define OS_TYPE "LINUX"
2897 extern int __data_start[];
2898 # define DATASTART ((ptr_t)__data_start)
2899 # define LINUX_STACKBOTTOM
2900 # define DYNAMIC_LOADING
2905 # define MACH_TYPE "RISC-V"
2906 # define CPP_WORDSZ __riscv_xlen /* 32 or 64 */
2907 # define ALIGNMENT (CPP_WORDSZ/8)
2909 # define OS_TYPE "LINUX"
2910 extern int __data_start[];
2911 # define DATASTART ((ptr_t)__data_start)
2912 # define LINUX_STACKBOTTOM
2913 # define DYNAMIC_LOADING
2917 #if defined(__GLIBC__) && !defined(DONT_USE_LIBC_PRIVATES)
2918 /* Use glibc's stack-end marker. */
2919 # define USE_LIBC_PRIVATES
2922 #if defined(LINUX_STACKBOTTOM) && defined(NO_PROC_STAT) \
2923 && !defined(USE_LIBC_PRIVATES)
2924 /* This combination will fail, since we have no way to get */
2925 /* the stack bottom. Use HEURISTIC2 instead. */
2926 # undef LINUX_STACKBOTTOM
2928 /* This may still fail on some architectures like IA64. */
2932 #if defined(USE_MMAP_ANON) && !defined(USE_MMAP)
2934 #elif defined(LINUX) && defined(USE_MMAP)
2935 /* The kernel may do a somewhat better job merging mappings etc. */
2936 /* with anonymous mappings. */
2937 # define USE_MMAP_ANON
2940 #if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
2941 && !defined(USE_PROC_FOR_LIBRARIES)
2942 /* Nptl allocates thread stacks with mmap, which is fine. But it */
2943 /* keeps a cache of thread stacks. Thread stacks contain the */
2944 /* thread control blocks. These in turn contain a pointer to */
2945 /* (sizeof (void *) from the beginning of) the dtv for thread-local */
2946 /* storage, which is calloc allocated. If we don't scan the cached */
2947 /* thread stacks, we appear to lose the dtv. This tends to */
2948 /* result in something that looks like a bogus dtv count, which */
2949 /* tends to result in a memset call on a block that is way too */
2950 /* large. Sometimes we're lucky and the process just dies ... */
2951 /* There seems to be a similar issue with some other memory */
2952 /* allocated by the dynamic loader. */
2953 /* This should be avoidable by either: */
2954 /* - Defining USE_PROC_FOR_LIBRARIES here. */
2955 /* That performs very poorly, precisely because we end up */
2956 /* scanning cached stacks. */
2957 /* - Have calloc look at its callers. */
2958 /* In spite of the fact that it is gross and disgusting. */
2959 /* In fact neither seems to suffice, probably in part because */
2960 /* even with USE_PROC_FOR_LIBRARIES, we don't scan parts of stack */
2961 /* segments that appear to be out of bounds. Thus we actually */
2962 /* do both, which seems to yield the best results. */
2963 # define USE_PROC_FOR_LIBRARIES
2966 #ifndef STACK_GROWS_UP
2967 # define STACK_GROWS_DOWN
2971 # define CPP_WORDSZ 32
2979 # if !defined(CPPCHECK)
2982 # define DATAEND ((ptr_t)(end))
2985 /* Workaround for Android NDK clang 3.5+ (as of NDK r10e) which does */
2986 /* not provide correct _end symbol. Unfortunately, alternate __end__ */
2987 /* symbol is provided only by NDK "bfd" linker. */
2988 #if defined(HOST_ANDROID) && defined(__clang__) \
2989 && !defined(BROKEN_UUENDUU_SYM)
2991 # pragma weak __end__
2992 extern int __end__[];
2993 # define DATAEND (__end__ != 0 ? (ptr_t)__end__ : (ptr_t)_end)
2996 #if (defined(SVR4) || defined(HOST_ANDROID) || defined(HOST_TIZEN)) \
2997 && !defined(GETPAGESIZE)
2999 # include <unistd.h>
3001 # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
3005 # if defined(SOLARIS) || defined(IRIX5) || defined(LINUX) \
3006 || defined(NETBSD) || defined(FREEBSD) || defined(HPUX)
3008 # include <unistd.h>
3011 # define GETPAGESIZE() (unsigned)getpagesize()
3014 #if defined(HOST_ANDROID) && !(__ANDROID_API__ >= 23) \
3015 && ((defined(MIPS) && (CPP_WORDSZ == 32)) \
3016 || defined(ARM32) || defined(I386) /* but not x32 */)
3017 /* tkill() exists only on arm32/mips(32)/x86. */
3018 /* NDK r11+ deprecates tkill() but keeps it for Mono clients. */
3019 # define USE_TKILL_ON_ANDROID
3022 #if defined(SOLARIS) || defined(DRSNX) || defined(UTS4)
3023 /* OS has SVR4 generic features. */
3024 /* Probably others also qualify. */
3028 #if defined(SOLARIS) || defined(DRSNX)
3029 /* OS has SOLARIS style semi-undocumented interface */
3030 /* to dynamic loader. */
3032 /* OS has SOLARIS style signal handlers. */
3040 #if defined(FREEBSD) && (defined(__DragonFly__) || __FreeBSD__ >= 4 \
3041 || (__FreeBSD_kernel__ >= 4))
3045 #if !defined(GC_EXPLICIT_SIGNALS_UNBLOCK) && defined(SUNOS5SIGS) \
3046 && !defined(GC_NO_PTHREAD_SIGMASK)
3047 # define GC_EXPLICIT_SIGNALS_UNBLOCK
3050 #if !defined(NO_SIGNALS_UNBLOCK_IN_MAIN) && defined(GC_NO_PTHREAD_SIGMASK)
3051 # define NO_SIGNALS_UNBLOCK_IN_MAIN
3054 #if !defined(NO_MARKER_SPECIAL_SIGMASK) \
3055 && (defined(NACL) || defined(GC_WIN32_PTHREADS))
3056 /* Either there is no pthread_sigmask(), or GC marker thread cannot */
3057 /* steal and drop user signal calls. */
3058 # define NO_MARKER_SPECIAL_SIGMASK
3061 #ifdef GC_NETBSD_THREADS
3062 # define SIGRTMIN 33
3063 # define SIGRTMAX 63
3064 /* It seems to be necessary to wait until threads have restarted. */
3065 /* But it is unclear why that is the case. */
3066 # define GC_NETBSD_THREADS_WORKAROUND
3069 #ifdef GC_OPENBSD_THREADS
3071 # include <sys/param.h>
3073 /* Prior to 5.2 release, OpenBSD had user threads and required */
3074 /* special handling. */
3075 # if OpenBSD < 201211
3076 # define GC_OPENBSD_UTHREADS 1
3078 #endif /* GC_OPENBSD_THREADS */
3080 #if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
3081 || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
3082 || defined(DGUX) || defined(BSD) || defined(HAIKU) || defined(HURD) \
3083 || defined(AIX) || defined(DARWIN) || defined(OSF1)
3084 # define UNIX_LIKE /* Basic Unix-like system calls work. */
3087 #if defined(CPPCHECK)
3089 # define CPP_WORDSZ (__SIZEOF_POINTER__ * 8)
3090 #elif CPP_WORDSZ != 32 && CPP_WORDSZ != 64
3091 # error Bad word size
3094 #if !defined(ALIGNMENT) && !defined(CPPCHECK)
3095 # error Undefined ALIGNMENT
3099 # undef DYNAMIC_LOADING
3104 # undef MPROTECT_VDB
3108 #if !defined(STACKBOTTOM) && (defined(ECOS) || defined(NOSYS)) \
3109 && !defined(CPPCHECK)
3110 # error Undefined STACKBOTTOM
3113 #ifdef IGNORE_DYNAMIC_LOADING
3114 # undef DYNAMIC_LOADING
3117 #if defined(SMALL_CONFIG) && !defined(GC_DISABLE_INCREMENTAL)
3118 /* Presumably not worth the space it takes. */
3119 # define GC_DISABLE_INCREMENTAL
3122 #if (defined(MSWIN32) || defined(MSWINCE)) && !defined(USE_WINALLOC)
3123 /* USE_WINALLOC is only an option for Cygwin. */
3124 # define USE_WINALLOC 1
3131 #if defined(DARWIN) || defined(FREEBSD) || defined(HAIKU) \
3132 || defined(IRIX5) || defined(LINUX) || defined(NETBSD) \
3133 || defined(OPENBSD) || defined(SOLARIS) \
3134 || ((defined(CYGWIN32) || defined(USE_MMAP) || defined(USE_MUNMAP)) \
3135 && !defined(USE_WINALLOC))
3136 /* Try both sbrk and mmap, in that order. */
3137 # define MMAP_SUPPORTED
3140 /* Xbox One (DURANGO) may not need to be this aggressive, but the */
3141 /* default is likely too lax under heavy allocation pressure. */
3142 /* The platform does not have a virtual paging system, so it does not */
3143 /* have a large virtual address space that a standard x64 platform has. */
3144 #if defined(USE_MUNMAP) && !defined(MUNMAP_THRESHOLD) \
3145 && (defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \
3146 || defined(SN_TARGET_PSP2) || defined(MSWIN_XBOX1))
3147 # define MUNMAP_THRESHOLD 2
3150 #if defined(GC_DISABLE_INCREMENTAL) || defined(DEFAULT_VDB)
3152 # undef MPROTECT_VDB
3157 #ifdef GC_DISABLE_INCREMENTAL
3161 #ifdef USE_GLOBAL_ALLOC
3162 /* Cannot pass MEM_WRITE_WATCH to GlobalAlloc(). */
3166 #if defined(BASE_ATOMIC_OPS_EMULATED)
3167 /* GC_write_fault_handler() cannot use lock-based atomic primitives */
3168 /* as this could lead to a deadlock. */
3169 # undef MPROTECT_VDB
3172 #if defined(USE_PROC_FOR_LIBRARIES) && defined(GC_LINUX_THREADS)
3173 /* Incremental GC is incompatible with /proc roots. */
3174 # undef MPROTECT_VDB
3177 #if defined(MPROTECT_VDB) && defined(GC_PREFER_MPROTECT_VDB)
3178 /* Choose MPROTECT_VDB manually (if multiple strategies available). */
3181 /* #undef GWW_VDB - handled in os_dep.c */
3185 /* Multi-VDB mode is not implemented. */
3186 # undef MPROTECT_VDB
3189 #if defined(MPROTECT_VDB) && !defined(MSWIN32) && !defined(MSWINCE)
3190 # include <signal.h> /* for SA_SIGINFO, SIGBUS */
3193 #if defined(SIGBUS) && !defined(HAVE_SIGBUS) && !defined(CPPCHECK)
3194 # define HAVE_SIGBUS
3198 # define NO_SA_SIGACTION
3201 #if defined(NO_SA_SIGACTION) && defined(MPROTECT_VDB) && !defined(DARWIN) \
3202 && !defined(MSWIN32) && !defined(MSWINCE)
3203 # undef MPROTECT_VDB
3206 #if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) \
3207 && !defined(GWW_VDB) && !defined(DEFAULT_VDB) \
3208 && !defined(GC_DISABLE_INCREMENTAL)
3209 # define DEFAULT_VDB
3212 #if ((defined(UNIX_LIKE) && (defined(DARWIN) || defined(HAIKU) \
3213 || defined(HURD) || defined(OPENBSD) \
3215 || defined(AVR32) || defined(MIPS) \
3216 || defined(NIOS2) || defined(OR1K))) \
3217 || (defined(LINUX) && !defined(__gnu_linux__)) \
3218 || (defined(RTEMS) && defined(I386)) || defined(HOST_ANDROID)) \
3219 && !defined(NO_GETCONTEXT)
3220 # define NO_GETCONTEXT 1
3224 # if GC_GNUC_PREREQ(3, 0) && !defined(NO_PREFETCH)
3225 # define PREFETCH(x) __builtin_prefetch((x), 0, 0)
3227 # define PREFETCH(x) (void)0
3231 #ifndef GC_PREFETCH_FOR_WRITE
3232 # if GC_GNUC_PREREQ(3, 0) && !defined(GC_NO_PREFETCH_FOR_WRITE)
3233 # define GC_PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1)
3235 # define GC_PREFETCH_FOR_WRITE(x) (void)0
3239 #ifndef CACHE_LINE_SIZE
3240 # define CACHE_LINE_SIZE 32 /* Wild guess */
3244 # ifdef GC_ASSERTIONS
3245 # define STATIC /* ignore to aid debugging (or profiling) */
3247 # define STATIC static
3251 #if defined(LINUX) && (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64) \
3252 || !defined(SMALL_CONFIG))
3253 # define NEED_PROC_MAPS
3256 #if defined(LINUX) || defined(HURD) || defined(__GLIBC__)
3257 # define REGISTER_LIBRARIES_EARLY
3258 /* We sometimes use dl_iterate_phdr, which may acquire an internal */
3259 /* lock. This isn't safe after the world has stopped. So we must */
3260 /* call GC_register_dynamic_libraries before stopping the world. */
3261 /* For performance reasons, this may be beneficial on other */
3262 /* platforms as well, though it should be avoided in win32. */
3265 #if defined(SEARCH_FOR_DATA_START)
3266 extern ptr_t GC_data_start;
3267 # define DATASTART GC_data_start
3271 # define HEAP_START ((ptr_t)0)
3274 #ifndef CLEAR_DOUBLE
3275 # define CLEAR_DOUBLE(x) (((word*)(x))[0] = 0, ((word*)(x))[1] = 0)
3278 #if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
3279 && !defined(INCLUDE_LINUX_THREAD_DESCR)
3280 /* Will not work, since libc and the dynamic loader use thread */
3281 /* locals, sometimes as the only reference. */
3282 # define INCLUDE_LINUX_THREAD_DESCR
3285 #if !defined(CPPCHECK)
3286 # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
3287 # error Inconsistent configuration
3289 # if defined(GC_LINUX_THREADS) && !defined(LINUX) && !defined(NACL)
3290 # error Inconsistent configuration
3292 # if defined(GC_NETBSD_THREADS) && !defined(NETBSD)
3293 # error Inconsistent configuration
3295 # if defined(GC_FREEBSD_THREADS) && !defined(FREEBSD)
3296 # error Inconsistent configuration
3298 # if defined(GC_SOLARIS_THREADS) && !defined(SOLARIS)
3299 # error Inconsistent configuration
3301 # if defined(GC_HPUX_THREADS) && !defined(HPUX)
3302 # error Inconsistent configuration
3304 # if defined(GC_AIX_THREADS) && !defined(_AIX)
3305 # error Inconsistent configuration
3307 # if defined(GC_WIN32_THREADS) && !defined(CYGWIN32) && !defined(MSWIN32) \
3308 && !defined(MSWINCE) && !defined(MSWIN_XBOX1)
3309 # error Inconsistent configuration
3311 # if defined(GC_WIN32_PTHREADS) && defined(CYGWIN32)
3312 # error Inconsistent configuration
3314 #endif /* !CPPCHECK */
3316 #if defined(PCR) || defined(GC_WIN32_THREADS) || defined(GC_PTHREADS) \
3317 || ((defined(NN_PLATFORM_CTR) || defined(NINTENDO_SWITCH) \
3318 || defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \
3319 || defined(SN_TARGET_PSP2)) && defined(GC_THREADS))
3323 #if defined(PARALLEL_MARK) && !defined(THREADS) && !defined(CPPCHECK)
3324 # error Invalid config: PARALLEL_MARK requires GC_THREADS
3327 #if defined(GWW_VDB) && !defined(USE_WINALLOC) && !defined(CPPCHECK)
3328 # error Invalid config: GWW_VDB requires USE_WINALLOC
3331 #if (((defined(MSWIN32) || defined(MSWINCE)) && !defined(__GNUC__)) \
3332 || (defined(MSWIN32) && defined(I386)) /* for Win98 */ \
3333 || (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))) \
3334 && !defined(NO_CRT) && !defined(NO_WRAP_MARK_SOME)
3335 /* Under rare conditions, we may end up marking from nonexistent */
3336 /* memory. Hence we need to be prepared to recover by running */
3337 /* GC_mark_some with a suitable handler in place. */
3338 /* TODO: Probably replace __GNUC__ above with ndef GC_PTHREADS. */
3339 /* FIXME: Should we really need it for WinCE? If yes then */
3340 /* WRAP_MARK_SOME should be also defined for CeGCC which requires */
3341 /* CPU/OS-specific code in mark_ex_handler and GC_mark_some (for */
3342 /* manual stack unwinding and exception handler installation). */
3343 # define WRAP_MARK_SOME
3346 #if defined(PARALLEL_MARK) && !defined(DEFAULT_STACK_MAYBE_SMALL) \
3347 && (defined(HPUX) || defined(GC_DGUX386_THREADS) \
3348 || defined(NO_GETCONTEXT) /* e.g. musl */)
3349 /* TODO: Test default stack size in configure. */
3350 # define DEFAULT_STACK_MAYBE_SMALL
3353 #ifdef PARALLEL_MARK
3354 /* The minimum stack size for a marker thread. */
3355 # define MIN_STACK_SIZE (8 * HBLKSIZE * sizeof(word))
3358 #if defined(HOST_ANDROID) && !defined(THREADS) \
3359 && !defined(USE_GET_STACKBASE_FOR_MAIN)
3360 /* Always use pthread_attr_getstack on Android ("-lpthread" option is */
3361 /* not needed to be specified manually) since GC_linux_main_stack_base */
3362 /* causes app crash if invoked inside Dalvik VM. */
3363 # define USE_GET_STACKBASE_FOR_MAIN
3366 /* Outline pthread primitives to use in GC_get_[main_]stack_base. */
3367 #if ((defined(FREEBSD) && defined(__GLIBC__)) /* kFreeBSD */ \
3368 || defined(LINUX) || defined(NETBSD) || defined(HOST_ANDROID)) \
3369 && !defined(NO_PTHREAD_GETATTR_NP)
3370 # define HAVE_PTHREAD_GETATTR_NP 1
3371 #elif defined(FREEBSD) && !defined(__GLIBC__) \
3372 && !defined(NO_PTHREAD_ATTR_GET_NP)
3373 # define HAVE_PTHREAD_NP_H 1 /* requires include pthread_np.h */
3374 # define HAVE_PTHREAD_ATTR_GET_NP 1
3377 #if defined(UNIX_LIKE) && defined(THREADS) && !defined(NO_CANCEL_SAFE) \
3378 && !defined(HOST_ANDROID)
3379 /* Make the code cancellation-safe. This basically means that we */
3380 /* ensure that cancellation requests are ignored while we are in */
3381 /* the collector. This applies only to Posix deferred cancellation; */
3382 /* we don't handle Posix asynchronous cancellation. */
3383 /* Note that this only works if pthread_setcancelstate is */
3384 /* async-signal-safe, at least in the absence of asynchronous */
3385 /* cancellation. This appears to be true for the glibc version, */
3386 /* though it is not documented. Without that assumption, there */
3387 /* seems to be no way to safely wait in a signal handler, which */
3388 /* we need to do for thread suspension. */
3389 /* Also note that little other code appears to be cancellation-safe. */
3390 /* Hence it may make sense to turn this off for performance. */
3391 # define CANCEL_SAFE
3395 # define IF_CANCEL(x) x
3397 # define IF_CANCEL(x) /* empty */
3400 #if !defined(CAN_HANDLE_FORK) && !defined(NO_HANDLE_FORK) \
3401 && !defined(HAVE_NO_FORK) \
3402 && ((defined(GC_PTHREADS) && !defined(NACL) \
3403 && !defined(GC_WIN32_PTHREADS) && !defined(USE_WINALLOC)) \
3404 || (defined(DARWIN) && defined(MPROTECT_VDB)) || defined(HANDLE_FORK))
3405 /* Attempts (where supported and requested) to make GC_malloc work in */
3406 /* a child process fork'ed from a multi-threaded parent. */
3407 # define CAN_HANDLE_FORK
3410 #if defined(CAN_HANDLE_FORK) && !defined(CAN_CALL_ATFORK) \
3411 && !defined(HURD) && !defined(SN_TARGET_ORBIS) && !defined(HOST_TIZEN) \
3412 && (!defined(HOST_ANDROID) || __ANDROID_API__ >= 21)
3413 /* Have working pthread_atfork(). */
3414 # define CAN_CALL_ATFORK
3417 #if !defined(CAN_HANDLE_FORK) && !defined(HAVE_NO_FORK) \
3418 && (defined(MSWIN32) || defined(MSWINCE) || defined(DOS4GW) \
3419 || defined(OS2) || defined(SYMBIAN) /* and probably others ... */)
3420 # define HAVE_NO_FORK
3423 #if !defined(USE_MARK_BITS) && !defined(USE_MARK_BYTES) \
3424 && defined(PARALLEL_MARK)
3425 /* Minimize compare-and-swap usage. */
3426 # define USE_MARK_BYTES
3429 #if (defined(MSWINCE) && !defined(__CEGCC__) || defined(MSWINRT_FLAVOR)) \
3430 && !defined(NO_GETENV)
3434 #if (defined(NO_GETENV) || defined(MSWINCE)) && !defined(NO_GETENV_WIN32)
3435 # define NO_GETENV_WIN32
3438 #if !defined(MSGBOX_ON_ERROR) && !defined(NO_MSGBOX_ON_ERROR) \
3439 && !defined(SMALL_CONFIG) && defined(MSWIN32) \
3440 && !defined(MSWINRT_FLAVOR) && !defined(MSWIN_XBOX1)
3441 /* Show Windows message box with "OK" button on a GC fatal error. */
3442 /* Client application is terminated once the user clicks the button. */
3443 # define MSGBOX_ON_ERROR
3447 # if defined(_WIN64) && !defined(__GNUC__)
3448 # define STRTOULL _strtoui64
3449 # elif defined(_LLP64) || defined(__LLP64__) || defined(_WIN64)
3450 # define STRTOULL strtoull
3452 /* strtoul() fits since sizeof(long) >= sizeof(word). */
3453 # define STRTOULL strtoul
3455 #endif /* !STRTOULL */
3458 # if defined(_WIN64) && !defined(__GNUC__)
3459 # define GC_WORD_C(val) val##ui64
3460 # elif defined(_LLP64) || defined(__LLP64__) || defined(_WIN64)
3461 # define GC_WORD_C(val) val##ULL
3463 # define GC_WORD_C(val) ((word)val##UL)
3465 #endif /* !GC_WORD_C */
3467 #if defined(__has_feature)
3468 /* __has_feature() is supported. */
3469 # if __has_feature(address_sanitizer) && !defined(ADDRESS_SANITIZER)
3470 # define ADDRESS_SANITIZER
3472 # if __has_feature(memory_sanitizer) && !defined(MEMORY_SANITIZER)
3473 # define MEMORY_SANITIZER
3475 # if __has_feature(thread_sanitizer) && !defined(THREAD_SANITIZER)
3476 # define THREAD_SANITIZER
3479 # ifdef __SANITIZE_ADDRESS__
3481 # define ADDRESS_SANITIZER
3483 #endif /* !__has_feature */
3486 # define ASM_CLEAR_CODE /* Stack clearing is crucial, and we */
3487 /* include assembly code to do it well. */
3490 /* Can we save call chain in objects for debugging? */
3491 /* SET NFRAMES (# of saved frames) and NARGS (#of args for each */
3492 /* frame) to reasonable values for the platform. */
3493 /* Set SAVE_CALL_CHAIN if we can. SAVE_CALL_COUNT can be specified */
3494 /* at build time, though we feel free to adjust it slightly. */
3495 /* Define NEED_CALLINFO if we either save the call stack or */
3496 /* GC_ADD_CALLER is defined. */
3497 /* GC_CAN_SAVE_CALL_STACKS is set in gc.h. */
3499 # define CAN_SAVE_CALL_ARGS
3501 #if (defined(I386) || defined(X86_64)) \
3502 && (defined(LINUX) || defined(__GLIBC__))
3503 /* SAVE_CALL_CHAIN is supported if the code is compiled to save */
3504 /* frame pointers by default, i.e. no -fomit-frame-pointer flag. */
3505 # define CAN_SAVE_CALL_ARGS
3508 #if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
3509 && defined(GC_CAN_SAVE_CALL_STACKS)
3510 # define SAVE_CALL_CHAIN
3512 #ifdef SAVE_CALL_CHAIN
3513 # if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS)
3514 # define NARGS SAVE_CALL_NARGS
3516 # define NARGS 0 /* Number of arguments to save for each call. */
3519 #ifdef SAVE_CALL_CHAIN
3520 # if !defined(SAVE_CALL_COUNT) || defined(CPPCHECK)
3521 # define NFRAMES 6 /* Number of frames to save. Even for */
3522 /* alignment reasons. */
3524 # define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1)
3526 # define NEED_CALLINFO
3527 #endif /* SAVE_CALL_CHAIN */
3528 #ifdef GC_ADD_CALLER
3531 # define NEED_CALLINFO
3534 #if (defined(FREEBSD) || (defined(DARWIN) && !defined(_POSIX_C_SOURCE)) \
3535 || (defined(SOLARIS) && (!defined(_XOPEN_SOURCE) \
3536 || defined(__EXTENSIONS__))) \
3537 || defined(LINUX)) && !defined(HAVE_DLADDR)
3538 # define HAVE_DLADDR 1
3541 #if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
3542 # define DBG_HDRS_ALL 1
3545 #if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
3546 # define POINTER_SHIFT 0
3549 #if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
3550 # define POINTER_MASK ((word)(-1))
3553 #if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
3554 # define FIXUP_POINTER(p) (p = ((p) & POINTER_MASK) << POINTER_SHIFT)
3557 #if defined(FIXUP_POINTER)
3558 # define NEED_FIXUP_POINTER
3560 # define FIXUP_POINTER(p)
3563 #if !defined(MARK_BIT_PER_GRANULE) && !defined(MARK_BIT_PER_OBJ)
3564 # define MARK_BIT_PER_GRANULE /* Usually faster */
3567 /* Some static sanity tests. */
3568 #if !defined(CPPCHECK)
3569 # if defined(MARK_BIT_PER_GRANULE) && defined(MARK_BIT_PER_OBJ)
3570 # error Define only one of MARK_BIT_PER_GRANULE and MARK_BIT_PER_OBJ
3572 # if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
3573 # error Only one of STACK_GROWS_UP and STACK_GROWS_DOWN should be defined
3575 # if !defined(STACK_GROWS_UP) && !defined(STACK_GROWS_DOWN)
3576 # error One of STACK_GROWS_UP and STACK_GROWS_DOWN should be defined
3578 # if defined(REDIRECT_MALLOC) && defined(THREADS) && !defined(LINUX) \
3579 && !defined(REDIRECT_MALLOC_IN_HEADER)
3580 # error REDIRECT_MALLOC with THREADS works at most on Linux
3582 #endif /* !CPPCHECK */
3585 /* This relies on some type definitions from gc_priv.h, from */
3586 /* where it's normally included. */
3588 /* How to get heap memory from the OS: */
3589 /* Note that sbrk()-like allocation is preferred, since it */
3590 /* usually makes it possible to merge consecutively allocated */
3591 /* chunks. It also avoids unintended recursion with */
3592 /* REDIRECT_MALLOC macro defined. */
3593 /* GET_MEM() argument should be of size_t type and have */
3594 /* no side-effect. GET_MEM() returns HBLKSIZE-aligned chunk; */
3595 /* 0 is taken to mean failure. */
3596 /* In case of MMAP_SUPPORTED, the argument must also be */
3597 /* a multiple of a physical page size. */
3598 /* GET_MEM is currently not assumed to retrieve 0 filled space, */
3599 /* though we should perhaps take advantage of the case in which */
3601 struct hblk; /* See gc_priv.h. */
3603 char * real_malloc(size_t bytes);
3604 # define GET_MEM(bytes) HBLKPTR(real_malloc(SIZET_SAT_ADD(bytes, \
3608 void * os2_alloc(size_t bytes);
3609 # define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc( \
3610 SIZET_SAT_ADD(bytes, \
3613 # elif defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) \
3614 || (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) \
3615 || (defined(SOLARIS) && !defined(USE_MMAP)) || defined(RTEMS) \
3616 || defined(__CC_ARM)
3617 # define GET_MEM(bytes) HBLKPTR((size_t)calloc(1, \
3618 SIZET_SAT_ADD(bytes, \
3621 # elif defined(MSWIN_XBOX1)
3622 ptr_t GC_durango_get_mem(size_t bytes);
3623 # define GET_MEM(bytes) (struct hblk *)GC_durango_get_mem(bytes)
3624 # elif defined(MSWIN32) || defined(CYGWIN32)
3625 ptr_t GC_win32_get_mem(size_t bytes);
3626 # define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
3627 # elif defined(MACOS)
3628 # if defined(USE_TEMPORARY_MEMORY)
3629 Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory);
3630 # define GET_MEM(bytes) HBLKPTR(GC_MacTemporaryNewPtr( \
3631 SIZET_SAT_ADD(bytes, \
3632 GC_page_size), true) \
3635 # define GET_MEM(bytes) HBLKPTR(NewPtrClear(SIZET_SAT_ADD(bytes, \
3639 # elif defined(MSWINCE)
3640 ptr_t GC_wince_get_mem(size_t bytes);
3641 # define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
3642 # elif defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
3643 void *GC_amiga_get_mem(size_t bytes);
3644 # define GET_MEM(bytes) HBLKPTR((size_t)GC_amiga_get_mem( \
3645 SIZET_SAT_ADD(bytes, \
3648 # elif defined(SN_TARGET_ORBIS)
3649 void *ps4_get_mem(size_t bytes);
3650 # define GET_MEM(bytes) (struct hblk*)ps4_get_mem(bytes)
3651 # elif defined(SN_TARGET_PS3)
3652 void *ps3_get_mem(size_t bytes);
3653 # define GET_MEM(bytes) (struct hblk*)ps3_get_mem(bytes)
3654 # elif defined(SN_TARGET_PSP2)
3655 void *psp2_get_mem(size_t bytes);
3656 # define GET_MEM(bytes) (struct hblk*)psp2_get_mem(bytes)
3657 # elif defined(NINTENDO_SWITCH)
3658 void *switch_get_mem(size_t bytes);
3659 # define GET_MEM(bytes) (struct hblk*)switch_get_mem(bytes)
3660 # elif defined(HAIKU)
3661 ptr_t GC_haiku_get_mem(size_t bytes);
3662 # define GET_MEM(bytes) (struct hblk*)GC_haiku_get_mem(bytes)
3664 ptr_t GC_unix_get_mem(size_t bytes);
3665 # define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
3667 #endif /* GC_PRIVATE_H */
3671 #endif /* GCCONFIG_H */