Commit 4c7726b1 by Bryce McKinlay Committed by Bryce McKinlay

Makefile.am, [...]: Imported GC 6.1 Alpha 1 and merged local changes.

	* Makefile.am, acinclude.m4, configure.in: Imported GC 6.1 Alpha 1
	and merged local changes.

From-SVN: r46283
parent 107abb2f
2001-10-16 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* Makefile.am, acinclude.m4, configure.in: Imported GC 6.1 Alpha 1 and
merged local changes.
2001-09-26 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* solaris_threads.c (MAX_ORIG_STACK_SIZE) [I386]: Provide special
......
......@@ -42,7 +42,7 @@ libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s \
mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s \
sparc_sunos4_mach_dep.s
sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
AM_CXXFLAGS = @GC_CFLAGS@
AM_CFLAGS = @GC_CFLAGS@
......@@ -51,7 +51,9 @@ check_PROGRAMS = gctest
# The following hack produces a warning from automake, but we need it in order
# to build a file from a subdirectory. FIXME.
test.o: tests/test.c
$(COMPILE) -c $<
$(COMPILE) -c tests/test.c
# Using $< in the above seems to fail with the HP/UX on Itanium make.
gctest_OBJECTS = test.o
gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
gctest_LDFLAGS = -shared-libgcc
......
......@@ -5,6 +5,8 @@
# Primary targets:
# gc.a - builds basic library
# libgc.a - builds library for use with g++ "-fgc-keyword" extension
# -fgc-keyword was never really available. Historical
# interest only.
# c++ - adds C++ interface to library
# cords - adds cords (heavyweight strings) to library
# test - prints porting information, then builds basic version of gc.a,
......
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Makefile.in generated automatically by automake 1.4-p1 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
......@@ -120,7 +120,7 @@ libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS)
libgcjgc_la_DEPENDENCIES = @addobjs@
libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s
EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
AM_CXXFLAGS = @GC_CFLAGS@
......@@ -128,6 +128,8 @@ AM_CXXFLAGS = @GC_CFLAGS@
AM_CFLAGS = @GC_CFLAGS@
check_PROGRAMS = gctest
# Using $< in the above seems to fail with the HP/UX on Itanium make.
gctest_OBJECTS = test.o
gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
gctest_LDFLAGS = -shared-libgcc
......@@ -548,7 +550,7 @@ mostlyclean distclean maintainer-clean
# The following hack produces a warning from automake, but we need it in order
# to build a file from a subdirectory. FIXME.
test.o: tests/test.c
$(COMPILE) -c $<
$(COMPILE) -c tests/test.c
$(all_objs) : include/private/gcconfig.h include/private/gc_priv.h \
include/private/gc_hdrs.h include/gc.h include/gc_gcj.h include/gc_mark.h
......
......@@ -114,10 +114,10 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D\
"WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\
"WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c
"GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\Release/
......@@ -296,10 +296,10 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD"\
/D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\
"WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\
"GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\
/Fd"$(INTDIR)/" /c
CPP_OBJS=.\Debug/
CPP_SBRS=.\Debug/
......@@ -430,9 +430,9 @@ test.c : tests\test.c
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /YX /c
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
"ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS"\
"ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS"\
/Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\gctest\Release/
CPP_SBRS=.\.
......@@ -516,9 +516,9 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
/D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR"$(INTDIR)/"\
/D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR"$(INTDIR)/"\
/Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
CPP_OBJS=.\gctest\Debug/
CPP_SBRS=.\gctest\Debug/
......
......@@ -55,7 +55,7 @@ AC_CANONICAL_SYSTEM
mkinstalldirs="`cd $ac_aux_dir && pwd`/mkinstalldirs"
AC_SUBST(mkinstalldirs)
AM_INIT_AUTOMAKE(gc, 6.0, no-define)
AM_INIT_AUTOMAKE(gc, 6.1a1, no-define)
# FIXME: We temporarily define our own version of AC_PROG_CC. This is
# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
......
......@@ -774,6 +774,7 @@ signed_word size;
if (HBLK_IS_FREE(hhdr)) {
GC_printf1("Duplicate large block deallocation of 0x%lx\n",
(unsigned long) hbp);
ABORT("Duplicate large block deallocation");
}
GC_ASSERT(IS_MAPPED(hhdr));
......
......@@ -91,7 +91,7 @@ case "$THREADS" in
;;
*-*-freebsd*)
AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.")
AC_DEFINE(FREEBSD_THREADS)
AC_DEFINE(GC_FREEBSD_THREADS)
INCLUDES="$INCLUDES -pthread"
THREADLIBS=-pthread
;;
......@@ -153,6 +153,12 @@ case "$host" in
alpha*-*-*)
machdep="alpha_mach_dep.lo"
;;
alpha-*-openbsd*)
if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled)
AM_DISABLE_SHARED
fi
;;
i?86-*-solaris2.[[89]]*)
AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED)
;;
......@@ -171,6 +177,9 @@ case "$host" in
sparc-sun-solaris2.3*)
AC_DEFINE(SUNOS53_SHARED_LIB)
;;
ia64-*-hpux*)
machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
;;
esac
if test x"$machdep" = x; then
machdep="mach_dep.lo"
......
......@@ -40,7 +40,7 @@ ptr_t p;
register word sz = GC_size((ptr_t) ohdr);
if (HBLKPTR((ptr_t)ohdr) != HBLKPTR((ptr_t)body)
|| sz < sizeof (oh)) {
|| sz < DEBUG_BYTES + EXTRA_BYTES) {
return(FALSE);
}
if (ohdr -> oh_sz == sz) {
......@@ -890,6 +890,28 @@ struct closure {
(*(cl -> cl_fn))((GC_PTR)((char *)obj + sizeof(oh)), cl -> cl_data);
}
/* Set ofn and ocd to reflect the values we got back. */
static void store_old (obj, my_old_fn, my_old_cd, ofn, ocd)
GC_PTR obj;
GC_finalization_proc my_old_fn;
struct closure * my_old_cd;
GC_finalization_proc *ofn;
GC_PTR *ocd;
{
if (0 != my_old_fn) {
if (my_old_fn != GC_debug_invoke_finalizer) {
GC_err_printf1("Debuggable object at 0x%lx had non-debug finalizer.\n",
obj);
/* This should probably be fatal. */
} else {
if (ofn) *ofn = my_old_cd -> cl_fn;
if (ocd) *ocd = my_old_cd -> cl_data;
}
} else {
if (ofn) *ofn = 0;
if (ocd) *ocd = 0;
}
}
# ifdef __STDC__
void GC_debug_register_finalizer(GC_PTR obj, GC_finalization_proc fn,
......@@ -904,14 +926,21 @@ struct closure {
GC_PTR *ocd;
# endif
{
GC_finalization_proc my_old_fn;
GC_PTR my_old_cd;
ptr_t base = GC_base(obj);
if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
GC_err_printf1(
"GC_register_finalizer called with non-base-pointer 0x%lx\n",
obj);
}
GC_register_finalizer(base, GC_debug_invoke_finalizer,
GC_make_closure(fn,cd), ofn, ocd);
if (0 == fn) {
GC_register_finalizer(base, 0, 0, &my_old_fn, &my_old_cd);
} else {
GC_register_finalizer(base, GC_debug_invoke_finalizer,
GC_make_closure(fn,cd), &my_old_fn, &my_old_cd);
}
store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
}
# ifdef __STDC__
......@@ -929,14 +958,22 @@ struct closure {
GC_PTR *ocd;
# endif
{
GC_finalization_proc my_old_fn;
GC_PTR my_old_cd;
ptr_t base = GC_base(obj);
if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
GC_err_printf1(
"GC_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
obj);
}
GC_register_finalizer_no_order(base, GC_debug_invoke_finalizer,
GC_make_closure(fn,cd), ofn, ocd);
if (0 == fn) {
GC_register_finalizer_no_order(base, 0, 0, &my_old_fn, &my_old_cd);
} else {
GC_register_finalizer_no_order(base, GC_debug_invoke_finalizer,
GC_make_closure(fn,cd), &my_old_fn,
&my_old_cd);
}
store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
}
# ifdef __STDC__
......@@ -954,14 +991,22 @@ struct closure {
GC_PTR *ocd;
# endif
{
GC_finalization_proc my_old_fn;
GC_PTR my_old_cd;
ptr_t base = GC_base(obj);
if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
GC_err_printf1(
"GC_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
obj);
}
GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer,
GC_make_closure(fn,cd), ofn, ocd);
if (0 == fn) {
GC_register_finalizer_ignore_self(base, 0, 0, &my_old_fn, &my_old_cd);
} else {
GC_register_finalizer_ignore_self(base, GC_debug_invoke_finalizer,
GC_make_closure(fn,cd), &my_old_fn,
&my_old_cd);
}
store_old(obj, my_old_fn, (struct closure *)my_old_cd, ofn, ocd);
}
#ifdef GC_ADD_CALLER
......
......@@ -27,7 +27,7 @@ are GPL'ed, but with an exception that should cover all uses in the
collector. (If you are concerned about such things, I recommend you look
at the notice in config.guess or ltmain.sh.)
This is version 6.0 of a conservative garbage collector for C and C++.
This is version 6.1alpha1 of a conservative garbage collector for C and C++.
You might find a more recent version of this at
......
......@@ -1360,7 +1360,7 @@ Since 6.0alpha8:
it on untested platforms.
- Integrated initial GNU HURD port. (Thanks to Chris Lingard and Igor
Khavkine.)
- A few more fixes for Digital Mars compiler.
- A few more fixes for Digital Mars compiler (Walter Bright).
- Fixed gcc version recognition. Renamed OPERATOR_NEW_ARRAY to
GC_OPERATOR_NEW_ARRAY. Changed GC_OPERATOR_NEW_ARRAY to be the default.
It can be overridden with -DGC_NO_OPERATOR_NEW_ARRAY. (Thanks to
......@@ -1378,16 +1378,47 @@ Since 6.0alpha9:
- Fixed a stack clearing problem that resulted in SIGILL with a
misaligned stack pointer for multithreaded SPARC builds.
- Integrated another HURD patch (thanks to Igor Khavkine).
Since 6.0:
- Non-debug, atomic allocations could result in bogus smashed object
reports with debugging on. (Thanks to Patrick Doyle for the small
test case.)
- Fixed GC_get_register_stack_base (Itanium only) to work around a glibc
2.2.4 bug.
- Initial port to HP/UX on Itanium. Thread support and both 32 and 64
bit ABIs appear to work. Parallel mark support doesn't yet, due to
some inline assembly code issues. Thread local allocation does appear
to work.
- ifdef'ed out glibc2.1/Itanium workaround. I suspect nobody is using
that combination anymore.
- Added a patch to make new_gc_alloc.h usable with gcc3.0. (Thanks to
Dimitris Vyzovitis for the patch.)
- Debugged 64-bit support on HP/UX PA-RISC.
- Turned on dynamic loading support for FreeBSD/ELF. (Thanks to Peter
Housel.)
- Unregistering of finalizers with debugging allocation was broken.
(Thanks to Jani Kajala for the test case.)
- Old finalizers were not returned correctly from GC_debug_register_finalizer.
- Disabled MPROTECT_VDB for Linux/M68K based on a report that it doesn't work.
- Cleaned up some statistics gathering code in reclaim.c (Thanks to Walter
Bright.)
- Added some support for OpenBSD/ELF/Linux. (Thanks to Suzuki Toshiya.)
- Added Jakub Jelinek's patch to use dl_iterate_phdr for dynamic library
traversal to dyn_load.c. Changed it to weakly reference dl_iterate_phdr,
so that the old code is stilll used with old versions of glibc.
- Cleaned up feature test macros for various threads packages and
integrated (partially functional) FreeBSD threads code from Loren Rittle.
It's likely that the cleanup broke something, since it touched lots of
code. It's also likelly that it fixed some unreported bugs in the
less common thread implementations, since some of the original code
didn't stand up to close scrutiny. Support for the next pthreads
implementation should be easier to add.
To do:
- There seem to be outstanding issues on Solaris/X86, possibly with
finding the data segment starting address. Information/patches would
ne appreciated.
- New_gc_alloc.h is apparently no longer compatible with the latest C++
standard library in gcc3.0. (This isn't technically a bug, since it only
claimed compatibility with the SGI STL. But we may need a new C++ STL
allocator interface.)
be appreciated.
- Very large root set sizes (> 16 MB or so) could cause the collector
to abort with an unexpected mark stack overflow. (Thanks again to
Peter Chubb.) NOT YET FIXED. Workaround is to increase the initial
......
......@@ -26,15 +26,18 @@
* None of this is safe with dlclose and incremental collection.
* But then not much of anything is safe in the presence of dlclose.
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
/* Can't test LINUX, since this must be define before other includes */
# define _GNU_SOURCE
#endif
#if !defined(MACOS) && !defined(_WIN32_WCE)
# include <sys/types.h>
#endif
#include "private/gc_priv.h"
/* BTL: avoid circular redefinition of dlopen if SOLARIS_THREADS defined */
# if (defined(LINUX_THREADS) || defined(SOLARIS_THREADS) \
|| defined(HPUX_THREADS) || defined(IRIX_THREADS)) && defined(dlopen) \
&& !defined(GC_USE_LD_WRAP)
/* BTL: avoid circular redefinition of dlopen if GC_SOLARIS_THREADS defined */
# if (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)) \
&& defined(dlopen) && !defined(GC_USE_LD_WRAP)
/* To support threads in Solaris, gc.h interposes on dlopen by */
/* defining "dlopen" to be "GC_dlopen", which is implemented below. */
/* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */
......@@ -53,6 +56,7 @@
!(defined(ALPHA) && defined(OSF1)) && \
!defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
!defined(RS6000) && !defined(SCO_ELF) && \
!(defined(FREEBSD) && defined(__ELF__)) && \
!(defined(NETBSD) && defined(__ELF__)) && !defined(HURD)
--> We only know how to find data segments of dynamic libraries for the
--> above. Additional SVR4 variants might not be too
......@@ -124,7 +128,7 @@ GC_FirstDLOpenedLinkMap()
#endif /* SUNOS5DL ... */
/* BTL: added to fix circular dlopen definition if SOLARIS_THREADS defined */
/* BTL: added to fix circular dlopen definition if GC_SOLARIS_THREADS defined */
# if defined(GC_must_restore_redefined_dlopen)
# define dlopen GC_dlopen
# endif
......@@ -171,7 +175,7 @@ static ptr_t GC_first_common()
# if defined(SUNOS4) || defined(SUNOS5DL)
/* Add dynamic library data sections to the root set. */
# if !defined(PCR) && !defined(SOLARIS_THREADS) && defined(THREADS)
# if !defined(PCR) && !defined(GC_SOLARIS_THREADS) && defined(THREADS)
# ifndef SRC_M3
--> fix mutual exclusion with dlopen
# endif /* We assume M3 programs don't call dlopen for now */
......@@ -243,6 +247,7 @@ void GC_register_dynamic_libraries()
# endif /* SUNOS */
#if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
(defined(FREEBSD) && defined(__ELF__)) || \
(defined(NETBSD) && defined(__ELF__)) || defined(HURD)
......@@ -417,13 +422,91 @@ static char *parse_map_entry(char *buf_ptr, word *start, word *end,
return buf_ptr;
}
#else /* !USE_PROC_FOR_LIBRARIES */
#endif /* USE_PROC_FOR_LIBRARIES */
#if !defined(USE_PROC_FOR_LIBRARIES)
/* The following is the preferred way to walk dynamic libraries */
/* For glibc 2.2.4+. Unfortunately, it doesn't work for older */
/* versions. Thanks to Jakub Jelinek for most of the code. */
#include <stddef.h>
#include <elf.h>
#include <link.h>
# if defined(LINUX) /* Are others OK here, too? */ \
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
/* We have the header files for a glibc that includes dl_iterate_phdr. */
/* It may still not be available in the library on the target system. */
/* Thus we also treat it as a weak symbol. */
#define HAVE_DL_ITERATE_PHDR
static int GC_register_dynlib_callback(info, size, ptr)
struct dl_phdr_info * info;
size_t size;
void * ptr;
{
const ElfW(Phdr) * p;
char * start;
register int i;
/* Make sure struct dl_phdr_info is at least as big as we need. */
if (size < offsetof (struct dl_phdr_info, dlpi_phnum)
+ sizeof (info->dlpi_phnum))
return -1;
/* Skip the first object - it is the main program. */
if (*(int *)ptr == 0)
{
*(int *)ptr = 1;
return 0;
}
p = info->dlpi_phdr;
for( i = 0; i < (int)(info->dlpi_phnum); ((i++),(p++)) ) {
switch( p->p_type ) {
case PT_LOAD:
{
if( !(p->p_flags & PF_W) ) break;
start = ((char *)(p->p_vaddr)) + info->dlpi_addr;
GC_add_roots_inner(start, start + p->p_memsz, TRUE);
}
break;
default:
break;
}
}
return 0;
}
/* Return TRUE if we succeed, FALSE if dl_iterate_phdr wasn't there. */
#pragma weak dl_iterate_phdr
GC_bool GC_register_dynamic_libraries_dl_iterate_phdr()
{
int tmp = 0;
if (dl_iterate_phdr) {
dl_iterate_phdr(GC_register_dynlib_callback, &tmp);
return TRUE;
} else {
return FALSE;
}
}
# else /* !LINUX || version(glibc) < 2.2.4 */
/* Dynamic loading code for Linux running ELF. Somewhat tested on
* Linux/x86, untested but hopefully should work on Linux/Alpha.
* This code was derived from the Solaris/ELF support. Thanks to
* whatever kind soul wrote that. - Patrick Bridges */
/* This doesn't necessarily work in all cases, e.g. with preloaded
* dynamic libraries. */
#if defined(NETBSD)
# include <sys/exec_elf.h>
#else
......@@ -431,6 +514,8 @@ static char *parse_map_entry(char *buf_ptr, word *start, word *end,
#endif
#include <link.h>
# endif
/* Newer versions of Linux/Alpha and Linux/x86 define this macro. We
* define it for those older versions that don't. */
# ifndef ElfW
......@@ -472,9 +557,15 @@ GC_FirstDLOpenedLinkMap()
void GC_register_dynamic_libraries()
{
struct link_map *lm = GC_FirstDLOpenedLinkMap();
struct link_map *lm;
# ifdef HAVE_DL_ITERATE_PHDR
if (GC_register_dynamic_libraries_dl_iterate_phdr()) {
return;
}
# endif
lm = GC_FirstDLOpenedLinkMap();
for (lm = GC_FirstDLOpenedLinkMap();
lm != (struct link_map *) 0; lm = lm->l_next)
{
......@@ -648,7 +739,7 @@ void GC_register_dynamic_libraries()
extern GC_bool GC_is_heap_base (ptr_t p);
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
extern void GC_get_next_stack(char *start, char **lo, char **hi);
void GC_cond_add_roots(char *base, char * limit)
{
......@@ -863,7 +954,7 @@ void GC_register_dynamic_libraries()
/* Check if this is the end of the list or if some error occured */
if (status != 0) {
# ifdef HPUX_THREADS
# ifdef GC_HPUX_THREADS
/* I've seen errno values of 0. The man page is not clear */
/* as to whether errno should get set on a -1 return. */
break;
......
......@@ -207,7 +207,7 @@ signed_word * log_size_ptr;
UNLOCK();
ENABLE_SIGNALS();
# endif
new_dl == GC_oom_fn(sizeof(struct disappearing_link));
new_dl = GC_oom_fn(sizeof(struct disappearing_link));
if (0 == new_dl) {
GC_finalization_failures++;
return(0);
......@@ -433,7 +433,7 @@ finalization_mark_proc * mp;
UNLOCK();
ENABLE_SIGNALS();
# endif
new_fo == GC_oom_fn(sizeof(struct finalizable_object));
new_fo = GC_oom_fn(sizeof(struct finalizable_object));
if (0 == new_fo) {
GC_finalization_failures++;
return;
......
......@@ -114,10 +114,10 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "SILENT" /D "GC_BUILD" /D\
"WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\
"WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c
"GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\Release/
CPP_SBRS=.\Release/
......@@ -296,10 +296,10 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "SILENT" /D "GC_BUILD"\
/D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D\
"WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\
"GC_WIN32_THREADS" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch" /YX /Fo"$(INTDIR)/"\
/Fd"$(INTDIR)/" /c
CPP_OBJS=.\Debug/
CPP_SBRS=.\Debug/
......@@ -430,9 +430,9 @@ test.c : tests\test.c
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /YX /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /YX /c
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D\
"ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS"\
"ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS"\
/Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /c
CPP_OBJS=.\gctest\Release/
CPP_SBRS=.\.
......@@ -516,9 +516,9 @@ CLEAN :
CPP=cl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR /YX /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR /YX /c
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\
/D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "WIN32_THREADS" /FR"$(INTDIR)/"\
/D "ALL_INTERIOR_POINTERS" /D "__STDC__" /D "GC_WIN32_THREADS" /FR"$(INTDIR)/"\
/Fp"$(INTDIR)/gctest.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
CPP_OBJS=.\gctest\Debug/
CPP_SBRS=.\gctest\Debug/
......
......@@ -24,8 +24,7 @@
#include "private/gc_priv.h"
# if defined(LINUX_THREADS) || defined(SOLARIS_THREADS) \
|| defined(HPUX_THREADS) || defined(IRIX_THREADS)
# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)
# if defined(dlopen) && !defined(GC_USE_LD_WRAP)
/* To support various threads pkgs, gc.h interposes on dlopen by */
......@@ -90,7 +89,7 @@
# endif
return(result);
}
# endif /* LINUX_THREADS || SOLARIS_THREADS || ... */
# endif /* GC_PTHREADS || GC_SOLARIS_THREADS ... */
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Makefile.in generated automatically by automake 1.4-p1 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
......
......@@ -30,13 +30,9 @@
# define _GC_H
#if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS)
# define SOLARIS_THREADS
#endif
/*
* Some tests for old macros. These violate our namespace rules and will
* disappear shortly.
* disappear shortly. Use the GC_ names.
*/
#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS)
# define GC_SOLARIS_THREADS
......@@ -72,6 +68,16 @@
/* depend on this were previously included. */
#endif
#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
# define GC_SOLARIS_THREADS
#endif
# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
# define GC_PTHREADS
# endif
# define __GC
# include <stddef.h>
# ifdef _WIN32_WCE
......@@ -80,7 +86,7 @@
typedef long ptrdiff_t; /* ptrdiff_t is not defined */
# endif
#if defined(__MINGW32__) && defined(WIN32_THREADS)
#if defined(__MINGW32__) && defined(GC_WIN32_THREADS)
# ifdef GC_BUILD
# define GC_API __declspec(dllexport)
# else
......@@ -815,16 +821,12 @@ GC_API void (*GC_is_visible_print_proc)
/* thread library calls. We do that here by macro defining them. */
#if !defined(GC_USE_LD_WRAP) && \
(defined(GC_LINUX_THREADS) || defined(GC_HPUX_THREADS) || \
defined(GC_IRIX_THREADS) || defined(GC_SOLARIS_PTHREADS) || \
defined(GC_SOLARIS_THREADS) || defined(GC_OSF1_THREADS))
(defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS))
# include "gc_pthread_redirects.h"
#endif
# if defined(PCR) || defined(GC_SOLARIS_THREADS) || \
defined(GC_SOLARIS_PTHREADS) || defined(GC_WIN32_THREADS) || \
defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
defined(GC_HPUX_THREADS)
defined(GC_PTHREADS) || defined(GC_WIN32_THREADS)
/* Any flavor of threads except SRC_M3. */
/* This returns a list of objects, linked through their first */
/* word. Its use can greatly reduce lock contention problems, since */
......@@ -839,7 +841,7 @@ extern void GC_thr_init(); /* Needed for Solaris/X86 */
#endif /* THREADS && !SRC_M3 */
#if defined(WIN32_THREADS) && defined(_WIN32_WCE)
#if defined(GC_WIN32_THREADS) && defined(_WIN32_WCE)
# include <windows.h>
/*
......
......@@ -47,8 +47,6 @@
/* The following allocators signal an out of memory condition with */
/* return GC_oom_fn(bytes); */
extern void * (*GC_oom_action)(void);
/* The following function must be called before the gcj allocators */
/* can be invoked. */
/* mp_index and mp are the index and mark_proc (see gc_mark.h) */
......
......@@ -50,7 +50,20 @@
#ifndef GC_ALLOC_H
#include "gc.h"
#include <stack> // A more portable way to get stl_alloc.h .
#if (__GNUC__ < 3)
# include <stack> // A more portable way to get stl_alloc.h .
#else
# include <bits/stl_alloc.h>
# ifndef __STL_BEGIN_NAMESPACE
# define __STL_BEGIN_NAMESPACE namespace std {
# define __STL_END_NAMESPACE };
# endif
#ifndef __STL_USE_STD_ALLOCATORS
#define __STL_USE_STD_ALLOCATORS
#endif
#endif
#define GC_ALLOC_H
......
......@@ -76,7 +76,7 @@
# define LOCK() RT0u__inCritical++
# define UNLOCK() RT0u__inCritical--
# endif
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
# include <thread.h>
# include <signal.h>
extern mutex_t GC_allocate_ml;
......@@ -261,8 +261,8 @@
# define USE_PTHREAD_LOCKS
# endif
# if defined(LINUX_THREADS) || defined(OSF1_THREADS) \
|| defined(HPUX_THREADS)
# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
&& !defined(GC_IRIX_THREADS)
# define NO_THREAD (pthread_t)(-1)
# include <pthread.h>
# if defined(PARALLEL_MARK)
......@@ -412,8 +412,8 @@
# ifdef GC_ASSERTIONS
extern pthread_t GC_mark_lock_holder;
# endif
# endif /* LINUX_THREADS || OSF1_THREADS || HPUX_THREADS */
# if defined(IRIX_THREADS)
# endif /* GC_PTHREADS with linux_threads.c implementation */
# if defined(GC_IRIX_THREADS)
# include <pthread.h>
/* This probably should never be included, but I can't test */
/* on Irix anymore. */
......@@ -439,8 +439,8 @@
GC_collecting = 1; \
}
# define EXIT_GC() GC_collecting = 0;
# endif /* IRIX_THREADS */
# ifdef WIN32_THREADS
# endif /* GC_IRIX_THREADS */
# ifdef GC_WIN32_THREADS
# include <windows.h>
GC_API CRITICAL_SECTION GC_allocate_ml;
# define LOCK() EnterCriticalSection(&GC_allocate_ml);
......
......@@ -443,18 +443,21 @@ struct hblk; /* See below. */
/* clear on that point). Standard malloc implementations are usually */
/* neither interruptable nor thread-safe, and thus correspond to */
/* empty definitions. */
/* It probably doesn't make any sense to declare these to be nonempty */
/* if the code is being optimized, since signal safety relies on some */
/* ordering constraints that are typically not obeyed by optimizing */
/* compilers. */
# ifdef PCR
# define DISABLE_SIGNALS() \
PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask)
# define ENABLE_SIGNALS() \
PCR_Th_SetSigMask(&GC_old_sig_mask, NIL)
# else
# if defined(SRC_M3) || defined(AMIGA) || defined(SOLARIS_THREADS) \
# if defined(THREADS) || defined(AMIGA) \
|| defined(MSWIN32) || defined(MSWINCE) || defined(MACOS) \
|| defined(DJGPP) || defined(NO_SIGNALS) || defined(IRIX_THREADS) \
|| defined(LINUX_THREADS)
|| defined(DJGPP) || defined(NO_SIGNALS)
/* Also useful for debugging. */
/* Should probably use thr_sigsetmask for SOLARIS_THREADS. */
/* Should probably use thr_sigsetmask for GC_SOLARIS_THREADS. */
# define DISABLE_SIGNALS()
# define ENABLE_SIGNALS()
# else
......@@ -479,9 +482,8 @@ struct hblk; /* See below. */
PCR_allSigsBlocked, \
PCR_waitForever);
# else
# if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
|| defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(HPUX_THREADS)
# if defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \
|| defined(GC_PTHREADS)
void GC_stop_world();
void GC_start_world();
# define STOP_WORLD() GC_stop_world()
......@@ -566,7 +568,8 @@ extern GC_warn_proc GC_current_warn_proc;
# ifdef SMALL_CONFIG
# define CPP_LOG_HBLKSIZE 10
# else
# if CPP_WORDSZ == 32
# if (CPP_WORDSZ == 32) || (defined(HPUX) && defined(HP_PA))
/* HPUX/PA seems to use 4K pages with the 64 bit ABI */
# define CPP_LOG_HBLKSIZE 12
# else
# define CPP_LOG_HBLKSIZE 13
......@@ -1903,8 +1906,7 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
/* some other reason. */
# endif /* PARALLEL_MARK */
# if defined(LINUX_THREADS) || defined(IRIX_THREADS) \
|| defined(HPUX_THREADS) || defined(OSF1_THREADS)
# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS)
/* We define the thread suspension signal here, so that we can refer */
/* to it in the dirty bit implementation, if necessary. Ideally we */
/* would allocate a (real-time ?) signal using the standard mechanism.*/
......@@ -1912,16 +1914,16 @@ void GC_err_puts GC_PROTO((GC_CONST char *s));
/* in Linux glibc, but it's not exported.) Thus we continue to use */
/* the same hard-coded signals we've always used. */
# if !defined(SIG_SUSPEND)
# if defined(LINUX_THREADS)
# if defined(GC_LINUX_THREADS)
# if defined(SPARC) && !defined(SIGPWR)
/* SPARC/Linux doesn't properly define SIGPWR in <signal.h>.
* It is aliased to SIGLOST in asm/signal.h, though. */
# define SIG_SUSPEND SIGLOST
# else
/* Linuxthreads uses SIGUSR1 and SIGUSR2. */
/* Linuxthreads itself uses SIGUSR1 and SIGUSR2. */
# define SIG_SUSPEND SIGPWR
# endif
# else /* !LINUX_THREADS */
# else /* !GC_LINUX_THREADS */
# define SIG_SUSPEND _SIGRTMIN + 6
# endif
# endif /* !SIG_SUSPEND */
......
......@@ -33,6 +33,11 @@
# define NETBSD
# endif
/* And one for OpenBSD: */
# if defined(__OpenBSD__)
# define OPENBSD
# endif
/* Determine the machine type: */
# if defined(sun) && defined(mc68000)
# define M68K
......@@ -44,25 +49,23 @@
# define HP
# define mach_type_known
# endif
# if defined(__OpenBSD__) && defined(m68k)
# if defined(OPENBSD) && defined(m68k)
# define M68K
# define OPENBSD
# define mach_type_known
# endif
# if defined(__OpenBSD__) && defined(__sparc__)
# if defined(OPENBSD) && defined(__sparc__)
# define SPARC
# define OPENBSD
# define mach_type_known
# endif
# if defined(__NetBSD__) && defined(m68k)
# if defined(NETBSD) && defined(m68k)
# define M68K
# define mach_type_known
# endif
# if defined(__NetBSD__) && defined(__powerpc__)
# if defined(NETBSD) && defined(__powerpc__)
# define POWERPC
# define mach_type_known
# endif
# if defined(__NetBSD__) && defined(__arm32__)
# if defined(NETBSD) && defined(__arm32__)
# define ARM32
# define mach_type_known
# endif
......@@ -161,6 +164,11 @@
# endif
# define mach_type_known
# endif
# if defined(__ia64) && defined(_HPUX_SOURCE)
# define IA64
# define HPUX
# define mach_type_known
# endif
# if defined(__BEOS__) && defined(_X86_)
# define I386
# define BEOS
......@@ -196,7 +204,7 @@
# endif
# if defined(__alpha) || defined(__alpha__)
# define ALPHA
# if !defined(LINUX) && !defined(NETBSD)
# if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD)
# define OSF1 /* a.k.a Digital Unix */
# endif
# define mach_type_known
......@@ -386,7 +394,7 @@
/* RS6000 ==> IBM RS/6000 AIX3.X */
/* RT ==> IBM PC/RT */
/* HP_PA ==> HP9000/700 & /800 */
/* HP/UX, LINUX */
/* HP/UX, LINUX */
/* SPARC ==> SPARC v7/v8/v9 */
/* (SUNOS4, SUNOS5, LINUX, */
/* DRSNX variants) */
......@@ -398,8 +406,11 @@
/* running Amdahl UTS4 */
/* or a 390 running LINUX */
/* ARM32 ==> Intel StrongARM */
/* IA64 ==> Intel IA64 */
/* IA64 ==> Intel IPF */
/* (e.g. Itanium) */
/* (LINUX and HPUX) */
/* IA64_32 ==> IA64 w/32 bit ABI */
/* (HPUX) */
/* SH ==> Hitachi SuperH */
/* (LINUX & MSWINCE) */
......@@ -533,7 +544,7 @@
# ifdef LINUX
# define OS_TYPE "LINUX"
# define STACKBOTTOM ((ptr_t)0xf0000000)
# define MPROTECT_VDB
/* # define MPROTECT_VDB - Reported to not work 9/17/01 */
# ifdef __ELF__
# define DYNAMIC_LOADING
# include <features.h>
......@@ -891,7 +902,7 @@
/* with 2GB physical memory will usually move the user */
/* address space limit, and hence initial SP to 0x80000000. */
# endif
# if !defined(LINUX_THREADS) || !defined(REDIRECT_MALLOC)
# if !defined(GC_LINUX_THREADS) || !defined(REDIRECT_MALLOC)
# define MPROTECT_VDB
# else
/* We seem to get random errors in incremental mode, */
......@@ -1008,6 +1019,9 @@
# define OS_TYPE "FREEBSD"
# define MPROTECT_VDB
# define FREEBSD_STACKBOTTOM
# ifdef __ELF__
# define DYNAMIC_LOADING
# endif
# endif
# ifdef NETBSD
# define OS_TYPE "NETBSD"
......@@ -1164,7 +1178,6 @@
# ifdef HP_PA
# define MACH_TYPE "HP_PA"
# define OS_TYPE "HPUX"
# ifdef __LP64__
# define CPP_WORDSZ 64
# define ALIGNMENT 8
......@@ -1173,8 +1186,7 @@
# define ALIGNMENT 4
# define ALIGN_DOUBLE
# endif
# if !defined(GC_HPUX_THREADS) && !defined(HPUX_THREADS) \
&& !defined(GC_LINUX_THREADS) && !defined(LINUX_THREADS)
# if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS)
# ifndef LINUX /* For now. */
# define MPROTECT_VDB
# endif
......@@ -1189,6 +1201,7 @@
# endif
# define STACK_GROWS_UP
# ifdef HPUX
# define OS_TYPE "HPUX"
extern int __data_start;
# define DATASTART ((ptr_t)(&__data_start))
# if 0
......@@ -1240,6 +1253,19 @@
# define CPP_WORDSZ 64
# define DYNAMIC_LOADING
# endif
# ifdef OPENBSD
# define OS_TYPE "OPENBSD"
# define HEURISTIC2
# define CPP_WORDSZ 64
# ifdef __ELF__ /* since OpenBSD/Alpha 2.9 */
# define DATASTART GC_data_start
# define ELFCLASS32 32
# define ELFCLASS64 64
# define ELF_CLASS ELFCLASS64
# else /* ECOFF, until OpenBSD/Alpha 2.7 */
# define DATASTART ((ptr_t) 0x140000000)
# endif
# endif
# ifdef OSF1
# define OS_TYPE "OSF1"
# define DATASTART ((ptr_t) 0x140000000)
......@@ -1282,9 +1308,6 @@
# ifdef IA64
# define MACH_TYPE "IA64"
# define ALIGN_DOUBLE
/* Requires 16 byte alignment for malloc */
# define ALIGNMENT 8
# define USE_GENERIC_PUSH_REGS
/* We need to get preserved registers in addition to register */
/* windows. That's easiest to do with setjmp. */
......@@ -1294,11 +1317,47 @@
/* setting mark bits. */
# endif
# ifdef HPUX
--> needs work
# ifdef _ILP32
# define CPP_WORDSZ 32
# define ALIGN_DOUBLE
/* Requires 8 byte alignment for malloc */
# define ALIGNMENT 4
# else
# ifndef _LP64
---> unknown ABI
# endif
# define CPP_WORDSZ 64
# define ALIGN_DOUBLE
/* Requires 16 byte alignment for malloc */
# define ALIGNMENT 8
# endif
# define OS_TYPE "HPUX"
extern int __data_start;
# define DATASTART ((ptr_t)(&__data_start))
/* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */
/* to this. Note that the GC must be initialized before the */
/* first putenv call. */
extern char ** environ;
# define STACKBOTTOM ((ptr_t)environ)
# define DYNAMIC_LOADING
# include <unistd.h>
# define GETPAGESIZE() sysconf(_SC_PAGE_SIZE)
/* The following was empirically determined, and is probably */
/* not very robust. */
/* Note that the backing store base seems to be at a nice */
/* address minus one page. */
# define BACKING_STORE_DISPLACEMENT 0x1000000
# define BACKING_STORE_ALIGNMENT 0x1000
# define BACKING_STORE_BASE \
(ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1) \
& ~(BACKING_STORE_ALIGNMENT - 1))
# endif
# ifdef LINUX
# define CPP_WORDSZ 64
# define ALIGN_DOUBLE
/* Requires 16 byte alignment for malloc */
# define ALIGNMENT 8
# define OS_TYPE "LINUX"
# define CPP_WORDSZ 64
/* The following works on NUE and older kernels: */
/* # define STACKBOTTOM ((ptr_t) 0xa000000000000000l) */
/* This does not work on NUE: */
......@@ -1579,57 +1638,33 @@
((word*)x)[1] = 0;
# endif /* CLEAR_DOUBLE */
/* Internally to the collector we test only the XXX_THREADS macros */
/* not the GC_XXX_THREADS versions. Here we make sure the latter */
/* are treated as equivalent. */
#if defined(GC_SOLARIS_THREADS) && !defined(_SOLARIS_THREADS)
# define _SOLARIS_THREADS
#endif
#if defined(GC_SOLARIS_THREADS) && !defined(_SOLARIS_PTHREADS)
# define _SOLARIS_PTHREADS
#endif
#if defined(GC_IRIX_THREADS) && !defined(IRIX_THREADS)
# define IRIX_THREADS
#endif
#if defined(GC_LINUX_THREADS) && !defined(LINUX_THREADS)
# define LINUX_THREADS
#endif
#if defined(GC_WIN32_THREADS) && !defined(WIN32_THREADS)
# define WIN32_THREADS
#endif
#if defined(GC_HPUX_THREADS) && !defined(HPUX_THREADS)
# define HPUX_THREADS
#endif
#if defined(GC_OSF1_THREADS) && !defined(OSF1_THREADS)
# define OSF1_THREADS
#endif
/* Internally we use SOLARIS_THREADS to test for either old or pthreads. */
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS)
# define SOLARIS_THREADS
/* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */
# if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
# define GC_SOLARIS_THREADS
# endif
# if defined(IRIX_THREADS) && !defined(IRIX5)
# if defined(GC_IRIX_THREADS) && !defined(IRIX5)
--> inconsistent configuration
# endif
# if defined(LINUX_THREADS) && !defined(LINUX)
# if defined(GC_LINUX_THREADS) && !defined(LINUX)
--> inconsistent configuration
# endif
# if defined(SOLARIS_THREADS) && !defined(SUNOS5)
# if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5)
--> inconsistent configuration
# endif
# if defined(HPUX_THREADS) && !defined(HPUX)
# if defined(GC_HPUX_THREADS) && !defined(HPUX)
--> inconsistent configuration
# endif
# if defined(WIN32_THREADS) && !defined(MSWIN32)
/* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect the necessary code */
/* is mostly there, but nobody has actually made sure the right combination of pieces is */
/* compiled in, etc. */
# if defined(GC_WIN32_THREADS) && !defined(MSWIN32)
/* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect */
/* the necessary code is mostly there, but nobody has actually made */
/* sure the right combination of pieces is compiled in, etc. */
--> inconsistent configuration
# endif
# if defined(PCR) || defined(SRC_M3) || \
defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \
defined(IRIX_THREADS) || defined(LINUX_THREADS) || \
defined(HPUX_THREADS) || defined(OSF1_THREADS)
defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) || \
defined(GC_PTHREADS)
# define THREADS
# endif
......
......@@ -21,11 +21,11 @@
* HP/UX 11.
*
* Note that there is a lot of code duplication between linux_threads.c
* and hpux_irix_threads.c; any changes made here may need to be reflected
* and irix_threads.c; any changes made here may need to be reflected
* there too.
*/
# if defined(GC_IRIX_THREADS) || defined(IRIX_THREADS)
# if defined(GC_IRIX_THREADS)
# include "private/gc_priv.h"
# include <pthread.h>
......@@ -725,5 +725,5 @@ yield:
int GC_no_Irix_threads;
#endif
# endif /* IRIX_THREADS */
# endif /* GC_IRIX_THREADS */
......@@ -50,13 +50,14 @@
/* ANSI C requires that a compilation unit contains something */
# if defined(GC_LINUX_THREADS) || defined(LINUX_THREADS) \
|| defined(GC_HPUX_THREADS) || defined(HPUX_THREADS) \
|| defined(GC_OSF1_THREADS) || defined(OSF1_THREADS) \
# include "gc.h"
# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
&& !defined(GC_IRIX_THREADS)
# include "private/gc_priv.h"
# if defined(HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
&& !defined(USE_HPUX_TLS)
# define USE_HPUX_TLS
# endif
......@@ -449,7 +450,7 @@ GC_PTR GC_local_gcj_malloc(size_t bytes,
*/
#ifndef SIG_THR_RESTART
# if defined(HPUX_THREADS) || defined(GC_OSF1_THREADS)
# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
# define SIG_THR_RESTART _SIGRTMIN + 5
# else
# define SIG_THR_RESTART SIGXCPU
......@@ -458,16 +459,19 @@ GC_PTR GC_local_gcj_malloc(size_t bytes,
sem_t GC_suspend_ack_sem;
#if !defined(HPUX_THREADS) && !defined(GC_OSF1_THREADS)
#if 0
/*
To make sure that we're using LinuxThreads and not some other thread
package, we generate a dummy reference to `pthread_kill_other_threads_np'
(was `__pthread_initial_thread_bos' but that disappeared),
which is a symbol defined in LinuxThreads, but (hopefully) not in other
thread packages.
We no longer do this, since this code is now portable enough that it might
actually work for something else.
*/
void (*dummy_var_to_force_linux_threads)() = pthread_kill_other_threads_np;
#endif /* !HPUX_THREADS */
#endif /* 0 */
#if defined(SPARC) || defined(IA64)
extern word GC_save_regs_in_stack();
......@@ -530,6 +534,24 @@ static void start_mark_threads()
if (0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
ABORT("pthread_attr_setdetachstate failed");
# ifdef HPUX
/* Default stack size is usually too small: fix it. */
/* Otherwise marker threads or GC may run out of */
/* space. */
# define MIN_STACK_SIZE (8*HBLKSIZE*sizeof(word))
{
size_t old_size;
int code;
if (pthread_attr_getstacksize(&attr, &old_size) != 0)
ABORT("pthread_attr_getstacksize failed\n");
if (old_size < MIN_STACK_SIZE) {
if (pthread_attr_setstacksize(&attr, MIN_STACK_SIZE) != 0)
ABORT("pthread_attr_getstacksize failed\n");
}
}
# endif /* HPUX */
# ifdef CONDPRINT
if (GC_print_stats) {
GC_printf1("Starting %ld marker threads\n", GC_markers - 1);
......@@ -970,7 +992,7 @@ int GC_segment_is_thread_stack(ptr_t lo, ptr_t hi)
}
#endif /* USE_PROC_FOR_LIBRARIES */
#ifdef LINUX_THREADS
#ifdef GC_LINUX_THREADS
/* Return the number of processors, or i<= 0 if it can't be determined. */
int GC_get_nprocs()
{
......@@ -1006,7 +1028,7 @@ int GC_get_nprocs()
}
return result;
}
#endif /* LINUX_THREADS */
#endif /* GC_LINUX_THREADS */
/* We hold the allocation lock. */
void GC_thr_init()
......@@ -1064,13 +1086,13 @@ void GC_thr_init()
if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string);
}
if (GC_nprocs <= 0) {
# if defined(HPUX_THREADS)
# if defined(GC_HPUX_THREADS)
GC_nprocs = pthread_num_processors_np();
# endif
# if defined(OSF1_THREADS)
# if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS)
GC_nprocs = 1;
# endif
# ifdef LINUX_THREADS
# if defined(GC_LINUX_THREADS)
GC_nprocs = GC_get_nprocs();
# endif
}
......@@ -1585,7 +1607,7 @@ void GC_lock()
pthread_t GC_mark_lock_holder = NO_THREAD;
#endif
#ifdef IA64
#if 0
/* Ugly workaround for a linux threads bug in the final versions */
/* of glibc2.1. Pthread_mutex_trylock sets the mutex owner */
/* field even when it fails to acquire the mutex. This causes */
......@@ -1692,5 +1714,5 @@ void GC_notify_all_marker()
#endif /* PARALLEL_MARK */
# endif /* LINUX_THREADS */
# endif /* GC_LINUX_THREADS and friends */
......@@ -492,8 +492,9 @@ ptr_t cold_gc_frame;
/* On IA64, we also need to flush register windows. But they end */
/* up on the other side of the stack segment. */
/* Returns the backing store pointer for the register stack. */
/* We implement this as a separate file in HP/UX. */
# ifdef IA64
# ifdef __GNUC__
# ifdef LINUX
asm(" .text");
asm(" .psr abi64");
asm(" .psr lsb");
......@@ -510,12 +511,25 @@ ptr_t cold_gc_frame;
asm(" mov r8=ar.bsp");
asm(" br.ret.sptk.few rp");
asm(" .endp GC_save_regs_in_stack");
# else
void GC_save_regs_in_stack() {
asm(" flushrs");
asm(" ;;");
asm(" mov r8=ar.bsp");
asm(" br.ret.sptk.few rp");
# endif /* LINUX */
# if 0 /* Other alternatives that don't work on HP/UX */
word GC_save_regs_in_stack() {
# if USE_BUILTINS
__builtin_ia64_flushrs();
return __builtin_ia64_bsp();
# else
# ifdef HPUX
_asm(" flushrs");
_asm(" ;;");
_asm(" mov r8=ar.bsp");
_asm(" br.ret.sptk.few rp");
# else
asm(" flushrs");
asm(" ;;");
asm(" mov r8=ar.bsp");
asm(" br.ret.sptk.few rp");
# endif
# endif
}
# endif
# endif
......
......@@ -315,7 +315,7 @@ DCL_LOCK_STATE;
/* It might help to manually inline the GC_malloc call here. */
/* But any decent compiler should reduce the extra procedure call */
/* to at most a jump instruction in this case. */
# if defined(I386) && defined(SOLARIS_THREADS)
# if defined(I386) && defined(GC_SOLARIS_THREADS)
/*
* Thread initialisation can call malloc before
* we're ready for it.
......@@ -324,7 +324,7 @@ DCL_LOCK_STATE;
* inopportune times.
*/
if (!GC_is_initialized) return sbrk(lb);
# endif /* I386 && SOLARIS_THREADS */
# endif /* I386 && GC_SOLARIS_THREADS */
return((GC_PTR)REDIRECT_MALLOC(lb));
}
......@@ -360,7 +360,7 @@ DCL_LOCK_STATE;
h = HBLKPTR(p);
hhdr = HDR(h);
# if defined(REDIRECT_MALLOC) && \
(defined(SOLARIS_THREADS) || defined(LINUX_THREADS) \
(defined(GC_SOLARIS_THREADS) || defined(GC_LINUX_THREADS) \
|| defined(__MINGW32__)) /* Should this be MSWIN32 in general? */
/* For Solaris, we have to redirect malloc calls during */
/* initialization. For the others, this seems to happen */
......
......@@ -568,11 +568,11 @@ ptr_t cold_gc_frame;
*/
# if !defined(USE_GENERIC_PUSH_REGS)
GC_push_current_stack(cold_gc_frame);
/* IN the threads case, this only pushes collector frames. */
/* In the threads case, this only pushes collector frames. */
/* In the USE_GENERIC_PUSH_REGS case, this is done inside */
/* GC_push_regs, so that we catch callee-save registers saved */
/* inside the GC_push_regs frame. */
/* In the case of linux threads on Ia64, the hot section of */
/* In the case of linux threads on IA64, the hot section of */
/* the main stack is marked here, but the register stack */
/* backing store is handled in the threads-specific code. */
# endif
......
......@@ -22,7 +22,7 @@
#define I_HIDE_POINTERS /* To make GC_call_with_alloc_lock visible */
#include "private/gc_pmark.h"
#ifdef SOLARIS_THREADS
#ifdef GC_SOLARIS_THREADS
# include <sys/syscall.h>
#endif
#if defined(MSWIN32) || defined(MSWINCE)
......@@ -41,29 +41,27 @@
/* Critical section counter is defined in the M3 runtime */
/* That's all we use. */
# else
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
mutex_t GC_allocate_ml; /* Implicitly initialized. */
# else
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
# if !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL))
__declspec(dllexport) CRITICAL_SECTION GC_allocate_ml;
# else
CRITICAL_SECTION GC_allocate_ml;
# endif
# else
# if defined(IRIX_THREADS) \
|| (defined(LINUX_THREADS) && defined(USE_SPIN_LOCK))
pthread_t GC_lock_holder = NO_THREAD;
# else
# if defined(HPUX_THREADS) \
|| defined(LINUX_THREADS) && !defined(USE_SPIN_LOCK)
# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS)
# if defined(USE_SPIN_LOCK)
pthread_t GC_lock_holder = NO_THREAD;
# else
pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER;
pthread_t GC_lock_holder = NO_THREAD;
/* Used only for assertions, and to prevent */
/* recursive reentry in the system call wrapper. */
# else
# endif
# else
--> declare allocator lock here
# endif
# endif
# endif
# endif
......@@ -524,20 +522,18 @@ void GC_init_inner()
# if defined(SEARCH_FOR_DATA_START)
GC_init_linux_data_start();
# endif
# if defined(NETBSD) && defined(__ELF__)
# if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
GC_init_netbsd_elf();
# endif
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(HPUX_THREADS) || defined(SOLARIS_THREADS)
# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)
GC_thr_init();
# endif
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
/* We need dirty bits in order to find live stack sections. */
GC_dirty_init();
# endif
# if !defined(THREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
|| defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(HPUX_THREADS)
# if !defined(THREADS) || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) \
|| defined(GC_SOLARIS_THREADS)
if (GC_stackbottom == 0) {
GC_stackbottom = GC_get_stack_base();
# if defined(LINUX) && defined(IA64)
......@@ -652,7 +648,7 @@ void GC_enable_incremental GC_PROTO(())
if (GC_is_win32s()) goto out;
}
# endif /* MSWIN32 */
# ifndef SOLARIS_THREADS
# ifndef GC_SOLARIS_THREADS
GC_dirty_init();
# endif
if (!GC_is_initialized) {
......@@ -753,7 +749,7 @@ size_t len;
register int result;
while (bytes_written < len) {
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
result = syscall(SYS_write, fd, buf + bytes_written,
len - bytes_written);
# else
......
......@@ -247,6 +247,7 @@ int kind;
ABORT("HBLK SZ inconsistency");
}
# endif
if (GC_debugging_started) clear = TRUE;
/* Allocate a new heap block */
h = GC_allochblk(sz, kind, 0);
......
......@@ -71,10 +71,6 @@
# define NEED_FIND_LIMIT
# endif
# if defined(IRIX_THREADS) || defined(HPUX_THREADS)
# define NEED_FIND_LIMIT
# endif
# if (defined(SUNOS4) && defined(DYNAMIC_LOADING)) && !defined(PCR)
# define NEED_FIND_LIMIT
# endif
......@@ -219,7 +215,7 @@ static void *tiny_sbrk(ptrdiff_t increment)
#define sbrk tiny_sbrk
# endif /* ECOS */
#if defined(NETBSD) && defined(__ELF__)
#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__)
ptr_t GC_data_start;
void GC_init_netbsd_elf()
......@@ -562,7 +558,7 @@ ptr_t GC_get_stack_base()
/* signal mask. */
(void) sigemptyset(&act.sa_mask);
# ifdef IRIX_THREADS
# ifdef GC_IRIX_THREADS
/* Older versions have a bug related to retrieving and */
/* and setting a handler at the same time. */
(void) sigaction(SIGSEGV, 0, &old_segv_act);
......@@ -576,7 +572,7 @@ ptr_t GC_get_stack_base()
/* don't have to worry in the threads case. */
(void) sigaction(SIGBUS, &act, &old_bus_act);
# endif
# endif /* IRIX_THREADS */
# endif /* GC_IRIX_THREADS */
# else
old_segv_handler = signal(SIGSEGV, h);
# ifdef SIGBUS
......@@ -680,7 +676,12 @@ ptr_t GC_get_stack_base()
ptr_t GC_get_register_stack_base(void)
{
if (0 != &__libc_ia64_register_backing_store_base) {
if (0 != &__libc_ia64_register_backing_store_base
&& 0 != __libc_ia64_register_backing_store_base) {
/* Glibc 2.2.4 has a bug such that for dynamically linked */
/* executables __libc_ia64_register_backing_store_base is */
/* defined but ininitialized during constructor calls. */
/* Hence we check for both nonzero address and value. */
return __libc_ia64_register_backing_store_base;
} else {
word result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT;
......@@ -1090,7 +1091,7 @@ void GC_register_data_segments()
{
# if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \
&& !defined(MACOSX)
# if defined(REDIRECT_MALLOC) && defined(SOLARIS_THREADS)
# if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
/* As of Solaris 2.3, the Solaris threads implementation */
/* allocates the data structure for the initial thread with */
/* sbrk at process startup. It needs to be scanned, so that */
......@@ -1651,9 +1652,8 @@ void GC_default_push_other_roots GC_PROTO((void))
# endif /* SRC_M3 */
# if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
|| defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(HPUX_THREADS)
# if defined(GC_SOLARIS_THREADS) || defined(GC_PTHREADS) || \
defined(GC_WIN32_THREADS)
extern void GC_push_all_stacks();
......@@ -1662,11 +1662,11 @@ void GC_default_push_other_roots GC_PROTO((void))
GC_push_all_stacks();
}
# endif /* SOLARIS_THREADS || ... */
# endif /* GC_SOLARIS_THREADS || GC_PTHREADS */
void (*GC_push_other_roots) GC_PROTO((void)) = GC_default_push_other_roots;
#endif
#endif /* THREADS */
/*
* Routines for accessing dirty bits on virtual pages.
......@@ -2410,7 +2410,7 @@ void GC_dirty_init()
# if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) \
|| defined(OSF1) || defined(HURD)
/* SUNOS5SIGS includes HPUX */
# if defined(IRIX_THREADS)
# if defined(GC_IRIX_THREADS)
sigaction(SIGSEGV, 0, &oldact);
sigaction(SIGSEGV, &act, 0);
# else
......@@ -2548,7 +2548,7 @@ word len;
((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE);
}
#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(LINUX_THREADS) \
#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(GC_LINUX_THREADS) \
&& !defined(GC_USE_LD_WRAP)
/* Replacement for UNIX system call. */
/* Other calls that write to the heap */
......@@ -2572,7 +2572,7 @@ word len;
GC_begin_syscall();
GC_unprotect_range(buf, (word)nbyte);
# if defined(IRIX5) || defined(LINUX_THREADS)
# if defined(IRIX5) || defined(GC_LINUX_THREADS)
/* Indirect system call may not always be easily available. */
/* We could call _read, but that would interfere with the */
/* libpthread interception of read. */
......@@ -2598,7 +2598,7 @@ word len;
GC_end_syscall();
return(result);
}
#endif /* !MSWIN32 && !MSWINCE && !LINUX_THREADS */
#endif /* !MSWIN32 && !MSWINCE && !GC_LINUX_THREADS */
#ifdef GC_USE_LD_WRAP
/* We use the GNU ld call wrapping facility. */
......@@ -2671,7 +2671,7 @@ word n;
word GC_proc_buf_size = INITIAL_BUF_SZ;
char *GC_proc_buf;
#ifdef SOLARIS_THREADS
#ifdef GC_SOLARIS_THREADS
/* We don't have exact sp values for threads. So we count on */
/* occasionally declaring stack pages to be fresh. Thus we */
/* need a real implementation of GC_is_fresh. We can't clear */
......@@ -2726,7 +2726,7 @@ void GC_dirty_init()
ABORT("/proc ioctl failed");
}
GC_proc_buf = GC_scratch_alloc(GC_proc_buf_size);
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
GC_fresh_pages = (struct hblk **)
GC_scratch_alloc(MAX_FRESH_PAGES * sizeof (struct hblk *));
if (GC_fresh_pages == 0) {
......@@ -2744,7 +2744,7 @@ struct hblk *h;
{
}
#ifdef SOLARIS_THREADS
#ifdef GC_SOLARIS_THREADS
# define READ(fd,buf,nbytes) syscall(SYS_read, fd, buf, nbytes)
#else
# define READ(fd,buf,nbytes) read(fd, buf, nbytes)
......@@ -2783,7 +2783,7 @@ int dummy;
/* Punt: */
memset(GC_grungy_pages, 0xff, sizeof (page_hash_table));
memset(GC_written_pages, 0xff, sizeof(page_hash_table));
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
BZERO(GC_fresh_pages,
MAX_FRESH_PAGES * sizeof (struct hblk *));
# endif
......@@ -2813,7 +2813,7 @@ int dummy;
register word index = PHT_HASH(h);
set_pht_entry_from_index(GC_grungy_pages, index);
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
{
register int slot = FRESH_PAGE_SLOT(h);
......@@ -2831,7 +2831,7 @@ int dummy;
}
/* Update GC_written_pages. */
GC_or_pages(GC_written_pages, GC_grungy_pages);
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
/* Make sure that old stacks are considered completely clean */
/* unless written again. */
GC_old_stacks_are_fresh();
......@@ -2847,7 +2847,7 @@ struct hblk *h;
register GC_bool result;
result = get_pht_entry_from_index(GC_grungy_pages, index);
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
if (result && PAGE_IS_FRESH(h)) result = FALSE;
/* This happens only if page was declared fresh since */
/* the read_dirty call, e.g. because it's in an unused */
......@@ -2865,7 +2865,7 @@ struct hblk *h;
register GC_bool result;
result = get_pht_entry_from_index(GC_written_pages, index);
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
if (result && PAGE_IS_FRESH(h)) result = FALSE;
# endif
return(result);
......@@ -2879,7 +2879,7 @@ word n;
register word index;
# ifdef SOLARIS_THREADS
# ifdef GC_SOLARIS_THREADS
register word i;
if (GC_fresh_pages != 0) {
......
......@@ -702,7 +702,8 @@ COUNT_DECL
if (report_if_found) {
GC_reclaim_check(hbp, hhdr, sz);
} else {
*flh = GC_reclaim_generic(hbp, hhdr, sz, ok -> ok_init,
*flh = GC_reclaim_generic(hbp, hhdr, sz,
(ok -> ok_init || GC_debugging_started),
*flh MEM_FOUND_ADDR);
}
}
......@@ -774,8 +775,12 @@ COUNT_DECL
/* Routines to gather and print heap block info */
/* intended for debugging. Otherwise should be called */
/* with lock. */
static size_t number_of_blocks;
static size_t total_bytes;
struct Print_stats
{
size_t number_of_blocks;
size_t total_bytes;
};
#ifdef USE_MARK_BYTES
......@@ -834,25 +839,30 @@ hdr * hhdr;
{
register hdr * hhdr = HDR(h);
register size_t bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
struct Print_stats *ps;
GC_printf3("(%lu:%lu,%lu)", (unsigned long)(hhdr -> hb_obj_kind),
(unsigned long)bytes,
(unsigned long)(GC_n_set_marks(hhdr)));
bytes += HBLKSIZE-1;
bytes &= ~(HBLKSIZE-1);
total_bytes += bytes;
number_of_blocks++;
ps = (struct Print_stats *)dummy;
ps->total_bytes += bytes;
ps->number_of_blocks++;
}
void GC_print_block_list()
{
struct Print_stats pstats;
GC_printf0("(kind(0=ptrfree,1=normal,2=unc.,3=stubborn):size_in_bytes, #_marks_set)\n");
number_of_blocks = 0;
total_bytes = 0;
GC_apply_to_all_blocks(GC_print_block_descr, (word)0);
pstats.number_of_blocks = 0;
pstats.total_bytes = 0;
GC_apply_to_all_blocks(GC_print_block_descr, (word)&pstats);
GC_printf2("\nblocks = %lu, bytes = %lu\n",
(unsigned long)number_of_blocks,
(unsigned long)total_bytes);
(unsigned long)pstats.number_of_blocks,
(unsigned long)pstats.total_bytes);
}
#endif /* NO_DEBUGGING */
......
......@@ -17,7 +17,7 @@
*/
/* Boehm, September 14, 1994 4:44 pm PDT */
# if defined(GC_SOLARIS_PTHREADS) || defined(_SOLARIS_PTHREADS)
# if defined(GC_SOLARIS_PTHREADS)
# include "private/gc_priv.h"
# include <pthread.h>
# include <thread.h>
......@@ -175,5 +175,5 @@ GC_pthread_create(pthread_t *new_thread,
int GC_no_sunOS_pthreads;
#endif
# endif /* SOLARIS_THREADS */
# endif /* GC_SOLARIS_PTHREADS */
......@@ -16,7 +16,7 @@
*/
/* Boehm, September 14, 1994 4:44 pm PDT */
# if defined(GC_SOLARIS_THREADS) || defined(SOLARIS_THREADS)
# if defined(GC_SOLARIS_THREADS)
# include "private/gc_priv.h"
# include "private/solaris_threads.h"
......@@ -949,7 +949,7 @@ GC_thr_create(void *stack_base, size_t stack_size,
return(result);
}
# else /* SOLARIS_THREADS */
# else /* !GC_SOLARIS_THREADS */
#ifndef LINT
int GC_no_sunOS_threads;
......
......@@ -11,7 +11,7 @@
* modified is included with the above copyright notice.
*/
#if defined(LINUX_THREADS) || defined(GC_LINUX_THREADS)
#if defined(GC_LINUX_THREADS)
#include "private/gc_priv.h" /* For GC_compare_and_exchange, GC_memory_barrier */
#include "private/specific.h"
......@@ -105,4 +105,4 @@ void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid,
return entry -> value;
}
#endif /* LINUX_THREADS */
#endif /* GC_LINUX_THREADS */
......@@ -59,16 +59,16 @@
# define GC_printf1 printf
# endif
# ifdef SOLARIS_THREADS
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
# include <thread.h>
# include <synch.h>
# endif
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
# if defined(GC_PTHREADS)
# include <pthread.h>
# endif
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
# ifndef MSWINCE
# include <process.h>
# define GC_CreateThread(a,b,c,d,e,f) ((HANDLE) _beginthreadex(a,b,c,d,e,f))
......@@ -447,7 +447,7 @@ struct {
*/
#ifdef THREADS
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
unsigned __stdcall tiny_reverse_test(void * arg)
# else
void * tiny_reverse_test(void * arg)
......@@ -457,8 +457,7 @@ struct {
return 0;
}
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(SOLARIS_PTHREADS) || defined(HPUX_THREADS)
# if defined(GC_PTHREADS)
void fork_a_thread()
{
pthread_t t;
......@@ -475,7 +474,7 @@ struct {
}
}
# elif defined(WIN32_THREADS)
# elif defined(GC_WIN32_THREADS)
void fork_a_thread()
{
unsigned thread_id;
......@@ -493,7 +492,7 @@ struct {
}
}
/* # elif defined(SOLARIS_THREADS) */
/* # elif defined(GC_SOLARIS_THREADS) */
# else
......@@ -649,15 +648,15 @@ VOLATILE int dropped_something = 0;
# ifdef PCR
PCR_ThCrSec_EnterSys();
# endif
# ifdef SOLARIS_THREADS
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
static mutex_t incr_lock;
mutex_lock(&incr_lock);
# endif
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
# if defined(GC_PTHREADS)
static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&incr_lock);
# endif
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
EnterCriticalSection(&incr_cs);
# endif
if ((int)(GC_word)client_data != t -> level) {
......@@ -668,13 +667,13 @@ VOLATILE int dropped_something = 0;
# ifdef PCR
PCR_ThCrSec_ExitSys();
# endif
# ifdef SOLARIS_THREADS
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
mutex_unlock(&incr_lock);
# endif
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) || defined(HPUX_THREADS)
# if defined(GC_PTHREADS)
pthread_mutex_unlock(&incr_lock);
# endif
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
LeaveCriticalSection(&incr_cs);
# endif
}
......@@ -740,16 +739,15 @@ int n;
# ifdef PCR
PCR_ThCrSec_EnterSys();
# endif
# ifdef SOLARIS_THREADS
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
static mutex_t incr_lock;
mutex_lock(&incr_lock);
# endif
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(HPUX_THREADS)
# if defined(GC_PTHREADS)
static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&incr_lock);
# endif
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
EnterCriticalSection(&incr_cs);
# endif
/* Losing a count here causes erroneous report of failure. */
......@@ -758,14 +756,13 @@ int n;
# ifdef PCR
PCR_ThCrSec_ExitSys();
# endif
# ifdef SOLARIS_THREADS
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
mutex_unlock(&incr_lock);
# endif
# if defined(IRIX_THREADS) || defined(LINUX_THREADS) \
|| defined(HPUX_THREADS)
# if defined(GC_PTHREADS)
pthread_mutex_unlock(&incr_lock);
# endif
# ifdef WIN32_THREADS
# ifdef GC_WIN32_THREADS
LeaveCriticalSection(&incr_cs);
# endif
}
......@@ -825,7 +822,7 @@ int n;
chktree(t -> rchild, n-1);
}
# if defined(SOLARIS_THREADS) && !defined(_SOLARIS_PTHREADS)
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
thread_key_t fl_key;
void * alloc8bytes()
......@@ -866,9 +863,7 @@ void * alloc8bytes()
#else
# if defined(GC_SOLARIS_PTHREADS) || defined(GC_IRIX_THREADS) \
|| defined(GC_LINUX_THREADS) || defined(GC_HPUX_THREADS) \
|| defined(GC_SOLARIS_THREADS)
# if defined(GC_PTHREADS)
pthread_key_t fl_key;
void * alloc8bytes()
......@@ -1319,9 +1314,8 @@ void SetMinimumStack(long minSize)
#if !defined(PCR) && !defined(GC_SOLARIS_THREADS) \
&& !defined(GC_WIN32_THREADS) \
&& !defined(GC_IRIX_THREADS) && !defined(GC_LINUX_THREADS) \
&& !defined(GC_HPUX_THREADS) || defined(LINT)
&& !defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) \
|| defined(LINT)
#if defined(MSWIN32) && !defined(__MINGW32__)
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPTSTR cmd, int n)
#else
......@@ -1557,8 +1551,7 @@ test()
}
#endif
#if defined(GC_SOLARIS_THREADS) || defined(GC_IRIX_THREADS) \
|| defined(GC_HPUX_THREADS) || defined(GC_LINUX_THREADS)
#if defined(GC_SOLARIS_THREADS) || defined(GC_PTHREADS)
void * thr_run_one_test(void * arg)
{
run_one_test();
......@@ -1569,7 +1562,7 @@ void * thr_run_one_test(void * arg)
# define GC_free GC_debug_free
#endif
#ifdef GC_SOLARIS_THREADS
#if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
main()
{
thread_t th1;
......@@ -1606,6 +1599,11 @@ main()
return(0);
}
#else /* pthreads */
#ifndef GC_PTHREADS
--> bad news
#endif
main()
{
pthread_t th1;
......@@ -1618,8 +1616,15 @@ main()
/* Since the initial cant always grow later. */
*((volatile char *)&code - 1024*1024) = 0; /* Require 1 Mb */
# endif /* GC_IRIX_THREADS */
# if defined(GC_HPUX_THREADS)
/* Default stack size is too small, especially with the 64 bit ABI */
/* Increase it. */
if (pthread_default_stacksize_np(1024*1024, 0) != 0) {
(void)GC_printf0("pthread_default_stacksize_np failed.\n");
}
# endif /* GC_HPUX_THREADS */
pthread_attr_init(&attr);
# if defined(GC_IRIX_THREADS) || defined(GC_HPUX_THREADS)
# if defined(GC_IRIX_THREADS)
pthread_attr_setstacksize(&attr, 1000000);
# endif
n_tests = 0;
......@@ -1656,5 +1661,5 @@ main()
GC_printf1("Completed %d collections\n", GC_gc_no);
return(0);
}
#endif /* pthreads */
#endif /* SOLARIS_THREADS || IRIX_THREADS || LINUX_THREADS || HPUX_THREADS */
#endif /* GC_PTHREADS */
#endif /* GC_SOLARIS_THREADS || GC_PTHREADS */
......@@ -9,21 +9,16 @@ int main()
"-Wl,--wrap -Wl,pthread_detach "
"-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n");
# endif
# if defined(LINUX_THREADS)
printf("-lpthread\n");
# if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \
|| defined(GC_FREEBSD_THREADS)
printf("-lpthread\n");
# endif
# if defined(IRIX_THREADS)
printf("-lpthread\n");
# endif
# if defined(HPUX_THREADS)
# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
printf("-lpthread -lrt\n");
# endif
# ifdef SOLARIS_THREADS
# if defined(GC_SOLARIS_THREADS)
printf("-lthread -ldl\n");
# endif
# ifdef GC_OSF1_THREADS
printf("-lpthread -lrt\n");
# endif
return 0;
}
#define GC_VERSION_MAJOR 6
#define GC_VERSION_MINOR 0
#define GC_ALPHA_VERSION GC_NOT_ALPHA
#define GC_VERSION_MINOR 1
#define GC_ALPHA_VERSION 1
# define GC_NOT_ALPHA 0xff
......
#if defined(GC_WIN32_THREADS) || defined(WIN32_THREADS)
#if defined(GC_WIN32_THREADS)
#include "private/gc_priv.h"
......@@ -614,4 +614,4 @@ BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
# endif /* !MSWINCE */
#endif /* WIN32_THREADS */
#endif /* GC_WIN32_THREADS */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment