racketcgc: use SenoraGC instead of Boehm GC by default

This new default for Unix and Mac OS X trades performance for
portability (hopefully), but for most users the switch affects only
for the build process, where `racketcgc` is used to build `racket`.

To continue using Boehm GC, configure with `--disable-sgc`.

For now, Boehm GC continues to be the default for Windows.
This commit is contained in:
Matthew Flatt 2014-08-11 14:52:08 +01:00
parent 2916fc34cc
commit a312f499cb
7 changed files with 100 additions and 65 deletions

View File

@ -29,9 +29,7 @@ To compile with MinGW tools, follow the Unix instructions below; do not
use `--enable-shared', because DLLs will be generated automatically.
The result is a Windows-style build, but without MzCOM. If you are using
a variant of MinGW without "libdelayimp.a", get the implementation of
"delayimp.c" from MinGW-w64 and compile it to "libdelayimp.a". When
compiling with MinGW-w64 for 64-bit mode, the `--enable-sgc' flag
to `configure' is currently required.
"delayimp.c" from MinGW-w64 and compile it to "libdelayimp.a".
To compile with Cygwin tools, follow the Unix instructions below, and be
sure to configure with `--enable-shared'. The result is a Unix-style
@ -286,17 +284,6 @@ Cross-compilation requires at least two flags to `configure':
This flag is needed because building and installing Racket requires
running (an intermediate version of) Racket.
A third `configure' flag is typical:
* `--enable-sgc', which uses a simpler garbage collector for the
intermediate variant of Racket that is normally used only to build
the final variant (see CGC vs 3m below).
Otherwise, you may need to set CC_FOR_BUILD to a compiler for the
build platform, so that helper executables can be created in the
process of building the intermediate Racket that is used to build
the final Racket.
Some less commonly needed `configure' flags:
* `--enable-stackup', if the target platform's stack grows up.
@ -312,7 +299,6 @@ the NDK, use (all on one line)
configure --host=arm-linux-androideabi
--enable-sysroot="[ndk]/platforms/android-[N]/arch-arm"
--enable-sgc
--enable-racket=racket
where [ndk] is the path to the installed NDK, [N] is a target version
@ -385,33 +371,29 @@ documentation for "config search paths" for more information.
========================================================================
At a minimum, to port Racket to a new platform, edit "racket/sconfig.h"
to provide a platform-specific compilation information. As distributed,
"racket/sconfig.h" contains configurations for the following platforms:
Windows (x86, x86_64)
Mac OS X (PPC, x86, x86_64)
Linux (x86, x86_64, PPC, 68k)
Cygwin (x86)
Solaris (x86, Sparc)
FreeBSD (x86, x86_64)
OpenBSD (x86)
NetBSD (x86)
If your platform is not supported by the Boehm garbage collector
(distributed with Racket source), provide the `--enable-sgc' flag to
`configure'.
to provide a platform-specific compilation information.
========================================================================
Additional Compilation Notes
========================================================================
Garbage Collector
CGC Build Options
-----------------
The conservative garbage collector distributed with Racket (in the "gc"
directory) has been modified slightly from Boehm's standard
distribution. Mostly, the change modify the way that object
finalization is handled.
As noted above in "CGC versus 3m", Racket builds a CGC variant in the
process of creating the normal 3m variant. Within the CGC variant, two
implementations are possible.
By default, Racket CGC is implemented with SenoraGC (in the "sgc"
directory), which is relativey portable. Provide `--disable-sgc` to
instead use the Boehm GC (in the "gc" directory), which should perform
better and was the default for Racket CGC through version 6.1.
The variant of the Boehm GC that is included with Racket has been
modified slightly from Boehm's standard distribution; mostly, the
changes modify the way that object finalization is handled.
[Currently, the Windows build still uses the Boehm GC by default.]
Floating point, x87, SSE, Extflonums, and the JIT
-------------------------------------------------

42
racket/src/configure vendored
View File

@ -1456,8 +1456,8 @@ Optional Features:
--enable-macprefix allow --prefix with a Mac OS X install
--enable-mac64 allow 64-bit Mac OS X build (enabled by default)
--enable-cgcdefault use CGC as default build (NOT RECOMMENDED)
--enable-sgc use Senora GC instead of the Boehm GC
--enable-sgcdebug use Senora GC for debugging
--enable-sgc use Senora GC instead of the Boehm GC (enabled by default)
--enable-sgcdebug use Senora GC for debugging (expensive debug mode)
--enable-backtrace 3m: support GC backtrace dumps (expensive debug mode)
--enable-pthread link with pthreads (usually auto-enabled if needed)
--enable-stackup assume "up" if stack direction cannot be determined
@ -2738,6 +2738,8 @@ fi
# Check whether --enable-sgc was given.
if test "${enable_sgc+set}" = set; then :
enableval=$enable_sgc;
else
enable_sgc=yes
fi
# Check whether --enable-sgcdebug was given.
@ -3007,7 +3009,7 @@ show_explicitly_disabled "${enable_places}" Places
show_explicitly_enabled "${enable_futures}" Futures
show_explicitly_disabled "${enable_futures}" Futures
show_explicitly_enabled "${enable_sgc}" SGC
show_explicitly_disabled "${enable_sgc}" SGC
show_explicitly_enabled "${enable_sgcdebug}" "SGC debug mode"
show_explicitly_enabled "${enable_backtrace}" "3m GC backtraces" "Note that this mode is not intended for normal Racket use"
@ -5496,8 +5498,8 @@ $as_echo_n "checking $msg... " >&6; }
#include <fcntl.h>
int main() {
void *p;
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
mprotect(p, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC);
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
mprotect(p, 2 << 16, PROT_READ | PROT_WRITE);
return 0;
}
_ACEOF
@ -5515,6 +5517,36 @@ $as_echo "$use_mprotect" >&6; }
$as_echo "#define HAVE_MMAP_MPROTECT 1" >>confdefs.h
fi
if test "${use_mprotect}" = "yes" && test "${enable_sgc}" != "yes" ; then
msg="mprotect with PROT_EXEC"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $msg" >&5
$as_echo_n "checking $msg... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/mman.h>
#include <fcntl.h>
int main() {
void *p;
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
if (mprotect(p, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC)) return 1;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
can_mprotect_exec=yes
else
can_mprotect_exec=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_mprotect_exec" >&5
$as_echo "$can_mprotect_exec" >&6; }
if test "${can_mprotect_exec}" = "no" ; then
echo "Senora GC is required due to mprotect() failure"
fi
fi
fi
if test "${check_page_size}" = "yes" ; then

View File

@ -66,8 +66,8 @@ AC_ARG_ENABLE(macprefix, [ --enable-macprefix allow --prefix with a Mac OS
AC_ARG_ENABLE(mac64, [ --enable-mac64 allow 64-bit Mac OS X build (enabled by default)], , enable_mac64=yes)
AC_ARG_ENABLE(cgcdefault, [ --enable-cgcdefault use CGC as default build (NOT RECOMMENDED)])
AC_ARG_ENABLE(sgc, [ --enable-sgc use Senora GC instead of the Boehm GC])
AC_ARG_ENABLE(sgcdebug,[ --enable-sgcdebug use Senora GC for debugging])
AC_ARG_ENABLE(sgc, [ --enable-sgc use Senora GC instead of the Boehm GC (enabled by default)], , enable_sgc=yes)
AC_ARG_ENABLE(sgcdebug,[ --enable-sgcdebug use Senora GC for debugging (expensive debug mode)])
AC_ARG_ENABLE(backtrace, [ --enable-backtrace 3m: support GC backtrace dumps (expensive debug mode)])
AC_ARG_ENABLE(pthread, [ --enable-pthread link with pthreads (usually auto-enabled if needed)])
@ -298,7 +298,7 @@ show_explicitly_disabled "${enable_places}" Places
show_explicitly_enabled "${enable_futures}" Futures
show_explicitly_disabled "${enable_futures}" Futures
show_explicitly_enabled "${enable_sgc}" SGC
show_explicitly_disabled "${enable_sgc}" SGC
show_explicitly_enabled "${enable_sgcdebug}" "SGC debug mode"
show_explicitly_enabled "${enable_backtrace}" "3m GC backtraces" "Note that this mode is not intended for normal Racket use"
@ -1104,14 +1104,32 @@ if test "${check_for_mprotect}" = "yes" ; then
#include <fcntl.h>
int main() {
void *p;
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
mprotect(p, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC);
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
mprotect(p, 2 << 16, PROT_READ | PROT_WRITE);
return 0;
}])], use_mprotect=yes, use_mprotect=no)
AC_MSG_RESULT($use_mprotect)
if test "${use_mprotect}" = "yes" ; then
AC_DEFINE(HAVE_MMAP_MPROTECT,1,[Have mmap and mprotect])
fi
if test "${use_mprotect}" = "yes" && test "${enable_sgc}" != "yes" ; then
[ msg="mprotect with PROT_EXEC" ]
AC_MSG_CHECKING($msg)
AC_LINK_IFELSE([AC_LANG_SOURCE([
#include <sys/mman.h>
#include <fcntl.h>
int main() {
void *p;
p = mmap(0, 2 << 16, PROT_READ | PROT_WRITE, MAP_PRIVATE, open("/dev/zero", O_RDWR), 0);
if (mprotect(p, 2 << 16, PROT_READ | PROT_WRITE | PROT_EXEC)) return 1;
return 0;
}])], can_mprotect_exec=yes, can_mprotect_exec=no)
AC_MSG_RESULT($can_mprotect_exec)
if test "${can_mprotect_exec}" = "no" ; then
echo "Senora GC is required due to mprotect() failure"
fi
fi
fi
if test "${check_page_size}" = "yes" ; then

View File

@ -1,17 +1,15 @@
SenoraGC is a relatively portable conservative GC for a slightly
cooperative environment.
cooperative environment. Its API is based on the Boehm GC.
The collector is intended mainly for debugging and memory tracing, but
it can also act as a reasonbaly efficient, general-purpose,
conservative collector. The standard Racket build uses SGC for
certain platforms where Boehm's GC hasn't been ported, yet (notably,
OSKit and BeOS).
The collector was originally intended for debugging and memory
tracing, but it can also act as a reasonbaly efficient,
general-purpose, conservative collector.
This collector is not recommended as a replacement for Boehm's GC if
you can get Boehm's to work at all. SenoraGC MIGHT be useful if, for
some reason, Boehm's collector does not work for your platform.
SenoraGC MIGHT be useful as a debugging collector if you can figure
out the [undocumented] debugging utilities.
If you intend to use the CGC variant of Racket instead of the (usual)
3m variant, then instead of SenoraGC, consider using the variant of
the Boehm GC that is distributed with Racket; it should perform
significantly better. Enable the Boehm GC by providing `--disable-sgc`
to `configure`.
Usage:
@ -24,6 +22,6 @@ actually done automatically for static variables, but it can't be done
portably in general. (See AUTO_STATIC_ROOTS_IF_POSSIBLE in the flags
section.)
GC space is allocated using malloc() and free(). Alternatively, the GC
can define malloc() and free() itself if platform-specific allocation
routines are supported.
GC space is allocated using mmap() where available, malloc()
otherwise. The GC can define malloc() and free() itself if
platform-specific allocation routines are supported.

View File

@ -315,8 +315,9 @@
/* SECTOR_SEGMENT_SIZE determines the alignment of collector blocks.
Since it should be a power of 2, LOG_SECTOR_SEGMENT_SIZE is
specified directly. A larger block size speeds up GC, but wastes
more unallocated bytes in same-size buckets. */
#define LOG_SECTOR_SEGMENT_SIZE 14
more unallocated bytes in same-size buckets. The block size must
be at least as large as the OS's page size. */
#define LOG_SECTOR_SEGMENT_SIZE 16
#define SECTOR_SEGMENT_SIZE (1 << LOG_SECTOR_SEGMENT_SIZE)
#define SECTOR_SEGMENT_MASK (~(SECTOR_SEGMENT_SIZE-1))
@ -328,7 +329,7 @@
/* Number of sector segments to be allocated at once with
malloc() to avoid waste when obtaining the proper alignment. */
#define SECTOR_SEGMENT_GROUP_SIZE 32
#define SECTOR_SEGMENT_GROUP_SIZE 16
/* Number of bits used in 32-bit level table for checking existence of
a sector. Creates a table of (1 << SECTOR_LOOKUP_SHIFT) pointers
@ -989,6 +990,10 @@ static void *ofm_malloc_zero(size_t len)
return mmap_sector((len >> LOG_SECTOR_SEGMENT_SIZE) + 1, 0);
}
/* Instead of calling mmap()/unmap() every time we need to
allocate/free a sector, use the allocation-cache layer from
"gc2" for non-executable pages: */
# define APAGE_SIZE SECTOR_SEGMENT_SIZE
# define NO_ALLOC_CACHE_FREE
# include "../gc2/my_qsort.c"

View File

@ -2086,9 +2086,9 @@ char *scheme_version(void)
# define VERSION_SUFFIX ""
#else
# ifdef USE_SENORA_GC
# define VERSION_SUFFIX " [cgc~]"
# else
# define VERSION_SUFFIX " [cgc]"
# else
# define VERSION_SUFFIX " [cgc/b]"
# endif
#endif

View File

@ -68,7 +68,7 @@ racket\src\README if you don't know about the two variants.)
If you can't run "build.bat" or don't want to, you have to perform
several steps: first builg RacketCGC, then build Racket3m, etc.
several steps: first build RacketCGC, then build Racket3m, etc.
Building RacketCGC and GRacketCGC
---------------------------------