[[!meta copyright="Copyright © 2010 Free Software Foundation, Inc."]]
[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable
id="license" text="Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license
is included in the section entitled [[GNU Free Documentation
License|/fdl]]."]]"""]]
.
`grubber:~tschwinge/tmp/boehm-gc/git/`.
It is used by [[GCC]], for example.
# Configuration
[[tschwinge]] reviewed its GNU/Hurd port's configuration on 2010-11-10, based
on CVS HEAD sources from 2010-11-16, converted to Git:
9abb37b2e581b415bb1f482085891a289c2c0be1.
* `configure.ac`
* `PARALLEL_MARK` is not enabled; doesn't make sense so far.
* `*-*-kfreebsd*-gnu` defines `USE_COMPILER_TLS`. What's this, and
why does not other config?
* TODO
[ if test "$enable_gc_debug" = "yes"; then
AC_MSG_WARN("Should define GC_DEBUG and use debug alloc. in clients.")
AC_DEFINE([KEEP_BACK_PTRS], 1,
[Define to save back-pointers in debugging headers.])
keep_back_ptrs=true
AC_DEFINE([DBG_HDRS_ALL], 1,
[Define to force debug headers on all objects.])
case $host in
x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
AC_DEFINE(MAKE_BACK_GRAPH)
AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
AC_DEFINE(SAVE_CALL_COUNT, 8)
;;
AM_CONDITIONAL([KEEP_BACK_PTRS], [test x"$keep_back_ptrs" = xtrue])
* `configure.host`
Nothing.
* `Makefile.am`, `include/include.am`, `cord/cord.am`, `doc/doc.am`,
`tests/tests.am`
Nothing.
* `include/gc_config_macros.h`
Should be OK.
* `include/private/gcconfig.h`
Hairy. But should be OK. Search for *HURD*, compare to *LINUX*,
*I386* case.
See `doc/porting.html` and `doc/README.macros` (and others) for
documentation.
*LINUX* has:
* `#define LINUX_STACKBOTTOM`
Defined instead of `STACKBOTTOM` to have the value read from `/proc/`.
* `#define HEAP_START (ptr_t)0x1000`
May want to define it for us, too?
* `#ifdef USE_I686_PREFETCH`, `USE_3DNOW_PREFETCH` --- [...]
Apparently these are optimization that we also could use. Have a
look at *LINUX* for *X86_64*, which uses `__builtin_prefetch`
(which Linux x86 could use, too?).
* TODO
#if defined(LINUX) && defined(USE_MMAP)
/* The kernel may do a somewhat better job merging mappings etc. */
/* with anonymous mappings. */
# define USE_MMAP_ANON
#endif
* TODO
#if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC)
/* Nptl allocates thread stacks with mmap, which is fine. But it */
/* keeps a cache of thread stacks. Thread stacks contain the */
/* thread control blocks. These in turn contain a pointer to */
/* (sizeof (void *) from the beginning of) the dtv for thread-local */
/* storage, which is calloc allocated. If we don't scan the cached */
/* thread stacks, we appear to lose the dtv. This tends to */
/* result in something that looks like a bogus dtv count, which */
/* tends to result in a memset call on a block that is way too */
/* large. Sometimes we're lucky and the process just dies ... */
/* There seems to be a similar issue with some other memory */
/* allocated by the dynamic loader. */
/* This should be avoidable by either: */
/* - Defining USE_PROC_FOR_LIBRARIES here. */
/* That performs very poorly, precisely because we end up */
/* scanning cached stacks. */
/* - Have calloc look at its callers. */
/* In spite of the fact that it is gross and disgusting. */
/* In fact neither seems to suffice, probably in part because */
/* even with USE_PROC_FOR_LIBRARIES, we don't scan parts of stack */
/* segments that appear to be out of bounds. Thus we actually */
/* do both, which seems to yield the best results. */
# define USE_PROC_FOR_LIBRARIES
#endif
* TODO
# if defined(GC_LINUX_THREADS) && defined(REDIRECT_MALLOC) \
&& !defined(INCLUDE_LINUX_THREAD_DESCR)
/* Will not work, since libc and the dynamic loader use thread */
/* locals, sometimes as the only reference. */
# define INCLUDE_LINUX_THREAD_DESCR
# endif
* TODO
# if defined(UNIX_LIKE) && defined(THREADS) && !defined(NO_CANCEL_SAFE) \
&& !defined(PLATFORM_ANDROID)
/* Make the code cancellation-safe. This basically means that we */
/* ensure that cancellation requests are ignored while we are in */
/* the collector. This applies only to Posix deferred cancellation;*/
/* we don't handle Posix asynchronous cancellation. */
/* Note that this only works if pthread_setcancelstate is */
/* async-signal-safe, at least in the absence of asynchronous */
/* cancellation. This appears to be true for the glibc version, */
/* though it is not documented. Without that assumption, there */
/* seems to be no way to safely wait in a signal handler, which */
/* we need to do for thread suspension. */
/* Also note that little other code appears to be cancellation-safe.*/
/* Hence it may make sense to turn this off for performance. */
# define CANCEL_SAFE
# endif
* `CAN_SAVE_CALL_ARGS` vs. -fomit-frame-pointer now being on by
default for Linux x86 IIRC? (Which is an [[!taglink
open_issue_gcc]] for not including us.)
* TODO
# if defined(REDIRECT_MALLOC) && defined(THREADS) && !defined(LINUX)
# error "REDIRECT_MALLOC with THREADS works at most on Linux."
# endif
*HURD* has:
* `#define STACK_GROWS_DOWN`
* `#define HEURISTIC2`
Defined instead of `STACKBOTTOM` to have the value probed.
Linux also has this:
#if defined(LINUX_STACKBOTTOM) && defined(NO_PROC_STAT) \
&& !defined(USE_LIBC_PRIVATES)
/* This combination will fail, since we have no way to get */
/* the stack base. Use HEURISTIC2 instead. */
# undef LINUX_STACKBOTTOM
# define HEURISTIC2
/* This may still fail on some architectures like IA64. */
/* We tried ... */
#endif
Being on [[glibc]], we could perhaps do similar as `USE_LIBC_PRIVATES`
instead of `HEURISTIC2`. Pro: avoid `SIGSEGV` (and general fragility)
during probing at startup (if I'm understanding this correctly). Con:
rely on glibc internals. Or we instead add support to parse
[[`/proc/`|hurd/translator/procfs]] (can even use the same as Linux?),
or use some other interface. [[!tag open_issue_glibc]]
* `#define SIG_SUSPEND SIGUSR1`, `#define SIG_THR_RESTART SIGUSR2`
* We don't `#define MPROTECT_VDB` (WIP comment); but Linux neither.
* Where does our `GETPAGESIZE` come from? Should we `#include
` like it is done for *LINUX*?
* `mach_dep.c`
* `#define NO_GETCONTEXT`
[[!taglink open_issue_glibc]], but this is not a real problem here,
because we can use the following GCC internal function without much
overhead:
* `GC_with_callee_saves_pushed`
The `HAVE_BUILTIN_UNWIND_INIT` case is ours.
* `os_dep.c`
* `read`
Sure that it doesn't internally (in [[glibc]]) use `malloc`. Probably
only / mostly (?) a problem for `--enable-redirect-malloc`
configurations? Linux with threads uses `readv`.
* TODO.
* `dyn_load.c`
For `DYNAMIC_LOADING`. TODO.
* `pthread_support.c`, `pthread_stop_world.c`
TODO.
* `libatomic_ops/`
* `configure.ac`
Nothing.
* `Makefile`, `src/Makefile`, `src/atomic_ops/Makefile`,
`src/atomic_ops/sysdeps/Makefile`, `doc/Makefile`, `tests/Makefile`
Nothing.
* `src/atomic_ops/sysdeps/gcc/x86.h`
Nothing.
# Testsuite
There are different configurations possible, but in general, the testsuite
restults of GNU/Linux and GNU/Hurd look very similar.
## `--enable-cplusplus --enable-gc-debug`
* GNU/Hurd is missing *Call chain at allocation: [...] output*.
`os_dep.c`:`GC_print_callers`
# TODO
* [[gcc/boehm_gc]]
* Port stuff to GCC / test it there.
* What are other applications to test boehm-gc? Also in combination
with [[libpthread]]?