sync with w3m-0.2.2-inu-1.1/gc
This commit is contained in:
+34
-12
@@ -10,13 +10,20 @@
|
||||
# c++ interface to gc.a
|
||||
# cord/de - builds dumb editor based on cords.
|
||||
ABI_FLAG=
|
||||
# ABI_FLAG should be the cc flag that specifies the ABI. On most
|
||||
# platforms this will be the empty string. Possible values:
|
||||
# +DD64 for 64-bit executable on HP/UX.
|
||||
# -n32, -n64, -o32 for SGI/MIPS ABIs.
|
||||
|
||||
AS_ABI_FLAG=$(ABI_FLAG)
|
||||
# ABI flag for assembler. On HP/UX this is +A64 for 64 bit
|
||||
# executables.
|
||||
|
||||
CC=cc $(ABI_FLAG)
|
||||
CXX=g++ $(ABI_FLAG)
|
||||
AS=as $(ABI_FLAG)
|
||||
AS=as $(AS_ABI_FLAG)
|
||||
# The above doesn't work with gas, which doesn't run cpp.
|
||||
# Define AS as `gcc -c -x assembler-with-cpp' instead.
|
||||
# Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64)
|
||||
# if you use something other than the default ABI on your machine.
|
||||
|
||||
# Redefining srcdir allows object code for the nonPCR version of the collector
|
||||
# to be generated in different directories.
|
||||
@@ -54,12 +61,15 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# gc.h before performing thr_ or dl* or GC_ operations.)
|
||||
# Must also define -D_REENTRANT.
|
||||
# -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads.
|
||||
# Define SOLARIS_THREADS as well.
|
||||
# (Internally this define GC_SOLARIS_THREADS as well.)
|
||||
# -DGC_IRIX_THREADS enables support for Irix pthreads. See README.irix.
|
||||
# -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads.
|
||||
# Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp.
|
||||
# -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads.
|
||||
# see README.linux. -D_REENTRANT may also be required.
|
||||
# -DGC_OSF1_THREADS enables support for Tru64 pthreads. Untested.
|
||||
# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. Untested.
|
||||
# Appeared to run into some underlying thread problems.
|
||||
# -DALL_INTERIOR_POINTERS allows all pointers to the interior
|
||||
# of objects to be recognized. (See gc_priv.h for consequences.)
|
||||
# Alternatively, GC_all_interior_pointers can be set at process
|
||||
@@ -136,8 +146,8 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# Works for Solaris and Irix.
|
||||
# -DUSE_MUNMAP causes memory to be returned to the OS under the right
|
||||
# circumstances. This currently disables VM-based incremental collection.
|
||||
# This is currently experimental, and works only under some Unix and
|
||||
# Linux versions.
|
||||
# This is currently experimental, and works only under some Unix,
|
||||
# Linux and Windows versions.
|
||||
# -DMMAP_STACKS (for Solaris threads) Use mmap from /dev/zero rather than
|
||||
# GC_scratch_alloc() to get stack memory.
|
||||
# -DPRINT_BLACK_LIST Whenever a black list entry is added, i.e. whenever
|
||||
@@ -191,8 +201,8 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# 15% or so.
|
||||
# -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style
|
||||
# prefetch instructions. Same restrictions as USE_I686_PREFETCH.
|
||||
# UNTESTED!!
|
||||
# -DGC_USE_LD_WRAP in combination with the gld flags listed in README.linux
|
||||
# Minimally tested. Didn't appear to be an obvious win on a K6-2/500.
|
||||
# -DGC_USE_LD_WRAP in combination with the old flags listed in README.linux
|
||||
# causes the collector some system and pthread calls in a more transparent
|
||||
# fashion than the usual macro-based approach. Requires GNU ld, and
|
||||
# currently probably works only with Linux.
|
||||
@@ -209,6 +219,14 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# These may otherwise alter its configuration, or turn off GC altogether.
|
||||
# I don't know of a reason to disable this, except possibly if the
|
||||
# resulting process runs as a privileged user?
|
||||
# -DUSE_GLOBAL_ALLOC. Win32 only. Use GlobalAlloc instead of
|
||||
# VirtualAlloc to allocate the heap. May be needed to work around
|
||||
# a Windows NT/2000 issue. Incompatible with USE_MUNMAP.
|
||||
# See README.win32 for details.
|
||||
# -DMAKE_BACK_GRAPH. Enable GC_PRINT_BACK_HEIGHT environment variable.
|
||||
# See README.environment for details. Experimental. Limited platform
|
||||
# support. Implies DBG_HDRS_ALL. All allocation should be done using
|
||||
# the debug interface.
|
||||
# -DSTUBBORN_ALLOC allows allocation of "hard to change" objects, and thus
|
||||
# makes incremental collection easier. Was enabled by default until 6.0.
|
||||
# Rarely used, to my knowledge.
|
||||
@@ -219,9 +237,9 @@ AR= ar
|
||||
RANLIB= ranlib
|
||||
|
||||
|
||||
OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o
|
||||
OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o backgraph.o
|
||||
|
||||
CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c
|
||||
CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c backgraph.c
|
||||
|
||||
CORD_SRCS= cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c include/cord.h include/ec.h include/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC
|
||||
|
||||
@@ -242,7 +260,8 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \
|
||||
include/gc_local_alloc.h include/private/dbg_mlc.h \
|
||||
include/private/specific.h powerpc_macosx_mach_dep.s \
|
||||
include/leak_detector.h include/gc_amiga_redirects.h \
|
||||
include/gc_pthread_redirects.h $(CORD_SRCS)
|
||||
include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \
|
||||
$(CORD_SRCS)
|
||||
|
||||
DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
|
||||
doc/README.amiga doc/README.cords doc/debugging.html \
|
||||
@@ -251,7 +270,7 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
|
||||
doc/README.win32 doc/barrett_diagram doc/README \
|
||||
doc/README.contributors doc/README.changes doc/gc.man \
|
||||
doc/README.environment doc/tree.html doc/gcdescr.html \
|
||||
doc/README.autoconf doc/README.macros
|
||||
doc/README.autoconf doc/README.macros doc/README.ews4800
|
||||
|
||||
TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
|
||||
tests/leak_test.c tests/thread_leak_test.c
|
||||
@@ -435,6 +454,9 @@ mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ul
|
||||
./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
|
||||
./if_mach SPARC OPENBSD $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
|
||||
./if_mach SPARC NETBSD $(AS) -o mach_dep.o $(srcdir)/sparc_netbsd_mach_dep.s
|
||||
./if_mach IA64 "" as $(AS_ABI_FLAG) -o ia64_save_regs_in_stack.o $(srcdir)/ia64_save_regs_in_stack.s
|
||||
./if_mach IA64 "" $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
|
||||
./if_mach IA64 "" ld -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o
|
||||
./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
|
||||
|
||||
mark_rts.o: $(srcdir)/mark_rts.c $(UTILS)
|
||||
|
||||
+6
-3
@@ -42,7 +42,8 @@ libgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
|
||||
dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
|
||||
linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
|
||||
obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \
|
||||
solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c
|
||||
solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \
|
||||
backgraph.c
|
||||
|
||||
# Include THREADLIBS here to ensure that the correct versions of
|
||||
# linuxthread semaphore functions get linked:
|
||||
@@ -53,7 +54,7 @@ libgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
|
||||
EXTRA_libgc_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@
|
||||
@@ -62,7 +63,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 = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
|
||||
TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
|
||||
|
||||
+34
-12
@@ -10,13 +10,20 @@
|
||||
# c++ interface to gc.a
|
||||
# cord/de - builds dumb editor based on cords.
|
||||
ABI_FLAG=
|
||||
# ABI_FLAG should be the cc flag that specifies the ABI. On most
|
||||
# platforms this will be the empty string. Possible values:
|
||||
# +DD64 for 64-bit executable on HP/UX.
|
||||
# -n32, -n64, -o32 for SGI/MIPS ABIs.
|
||||
|
||||
AS_ABI_FLAG=$(ABI_FLAG)
|
||||
# ABI flag for assembler. On HP/UX this is +A64 for 64 bit
|
||||
# executables.
|
||||
|
||||
CC=cc $(ABI_FLAG)
|
||||
CXX=g++ $(ABI_FLAG)
|
||||
AS=as $(ABI_FLAG)
|
||||
AS=as $(AS_ABI_FLAG)
|
||||
# The above doesn't work with gas, which doesn't run cpp.
|
||||
# Define AS as `gcc -c -x assembler-with-cpp' instead.
|
||||
# Under Irix 6, you will have to specify the ABI (-o32, -n32, or -64)
|
||||
# if you use something other than the default ABI on your machine.
|
||||
|
||||
# Redefining srcdir allows object code for the nonPCR version of the collector
|
||||
# to be generated in different directories.
|
||||
@@ -54,12 +61,15 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# gc.h before performing thr_ or dl* or GC_ operations.)
|
||||
# Must also define -D_REENTRANT.
|
||||
# -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads.
|
||||
# Define SOLARIS_THREADS as well.
|
||||
# (Internally this define GC_SOLARIS_THREADS as well.)
|
||||
# -DGC_IRIX_THREADS enables support for Irix pthreads. See README.irix.
|
||||
# -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads.
|
||||
# Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp.
|
||||
# -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads.
|
||||
# see README.linux. -D_REENTRANT may also be required.
|
||||
# -DGC_OSF1_THREADS enables support for Tru64 pthreads. Untested.
|
||||
# -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads. Untested.
|
||||
# Appeared to run into some underlying thread problems.
|
||||
# -DALL_INTERIOR_POINTERS allows all pointers to the interior
|
||||
# of objects to be recognized. (See gc_priv.h for consequences.)
|
||||
# Alternatively, GC_all_interior_pointers can be set at process
|
||||
@@ -136,8 +146,8 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# Works for Solaris and Irix.
|
||||
# -DUSE_MUNMAP causes memory to be returned to the OS under the right
|
||||
# circumstances. This currently disables VM-based incremental collection.
|
||||
# This is currently experimental, and works only under some Unix and
|
||||
# Linux versions.
|
||||
# This is currently experimental, and works only under some Unix,
|
||||
# Linux and Windows versions.
|
||||
# -DMMAP_STACKS (for Solaris threads) Use mmap from /dev/zero rather than
|
||||
# GC_scratch_alloc() to get stack memory.
|
||||
# -DPRINT_BLACK_LIST Whenever a black list entry is added, i.e. whenever
|
||||
@@ -191,8 +201,8 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# 15% or so.
|
||||
# -DUSE_3DNOW_PREFETCH causes the collector to issue AMD 3DNow style
|
||||
# prefetch instructions. Same restrictions as USE_I686_PREFETCH.
|
||||
# UNTESTED!!
|
||||
# -DGC_USE_LD_WRAP in combination with the gld flags listed in README.linux
|
||||
# Minimally tested. Didn't appear to be an obvious win on a K6-2/500.
|
||||
# -DGC_USE_LD_WRAP in combination with the old flags listed in README.linux
|
||||
# causes the collector some system and pthread calls in a more transparent
|
||||
# fashion than the usual macro-based approach. Requires GNU ld, and
|
||||
# currently probably works only with Linux.
|
||||
@@ -209,6 +219,14 @@ HOSTCFLAGS=$(CFLAGS)
|
||||
# These may otherwise alter its configuration, or turn off GC altogether.
|
||||
# I don't know of a reason to disable this, except possibly if the
|
||||
# resulting process runs as a privileged user?
|
||||
# -DUSE_GLOBAL_ALLOC. Win32 only. Use GlobalAlloc instead of
|
||||
# VirtualAlloc to allocate the heap. May be needed to work around
|
||||
# a Windows NT/2000 issue. Incompatible with USE_MUNMAP.
|
||||
# See README.win32 for details.
|
||||
# -DMAKE_BACK_GRAPH. Enable GC_PRINT_BACK_HEIGHT environment variable.
|
||||
# See README.environment for details. Experimental. Limited platform
|
||||
# support. Implies DBG_HDRS_ALL. All allocation should be done using
|
||||
# the debug interface.
|
||||
# -DSTUBBORN_ALLOC allows allocation of "hard to change" objects, and thus
|
||||
# makes incremental collection easier. Was enabled by default until 6.0.
|
||||
# Rarely used, to my knowledge.
|
||||
@@ -219,9 +237,9 @@ AR= ar
|
||||
RANLIB= ranlib
|
||||
|
||||
|
||||
OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o
|
||||
OBJS= alloc.o reclaim.o allchblk.o misc.o mach_dep.o os_dep.o mark_rts.o headers.o mark.o obj_map.o blacklst.o finalize.o new_hblk.o dbg_mlc.o malloc.o stubborn.o checksums.o solaris_threads.o irix_threads.o linux_threads.o typd_mlc.o ptr_chck.o mallocx.o solaris_pthreads.o gcj_mlc.o specific.o gc_dlopen.o backgraph.o
|
||||
|
||||
CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c
|
||||
CSRCS= reclaim.c allchblk.c misc.c alloc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c pcr_interface.c blacklst.c finalize.c new_hblk.c real_malloc.c dyn_load.c dbg_mlc.c malloc.c stubborn.c checksums.c solaris_threads.c irix_threads.c linux_threads.c typd_mlc.c ptr_chck.c mallocx.c solaris_pthreads.c gcj_mlc.c specific.c gc_dlopen.c backgraph.c
|
||||
|
||||
CORD_SRCS= cord/cordbscs.c cord/cordxtra.c cord/cordprnt.c cord/de.c cord/cordtest.c include/cord.h include/ec.h include/private/cord_pos.h cord/de_win.c cord/de_win.h cord/de_cmds.h cord/de_win.ICO cord/de_win.RC
|
||||
|
||||
@@ -242,7 +260,8 @@ SRCS= $(CSRCS) mips_sgi_mach_dep.s rs6000_mach_dep.s alpha_mach_dep.s \
|
||||
include/gc_local_alloc.h include/private/dbg_mlc.h \
|
||||
include/private/specific.h powerpc_macosx_mach_dep.s \
|
||||
include/leak_detector.h include/gc_amiga_redirects.h \
|
||||
include/gc_pthread_redirects.h $(CORD_SRCS)
|
||||
include/gc_pthread_redirects.h ia64_save_regs_in_stack.s \
|
||||
$(CORD_SRCS)
|
||||
|
||||
DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
|
||||
doc/README.amiga doc/README.cords doc/debugging.html \
|
||||
@@ -251,7 +270,7 @@ DOC_FILES= README.QUICK doc/README.Mac doc/README.MacOSX doc/README.OS2 \
|
||||
doc/README.win32 doc/barrett_diagram doc/README \
|
||||
doc/README.contributors doc/README.changes doc/gc.man \
|
||||
doc/README.environment doc/tree.html doc/gcdescr.html \
|
||||
doc/README.autoconf doc/README.macros
|
||||
doc/README.autoconf doc/README.macros doc/README.ews4800
|
||||
|
||||
TESTS= tests/test.c tests/test_cpp.cc tests/trace_test.c \
|
||||
tests/leak_test.c tests/thread_leak_test.c
|
||||
@@ -435,6 +454,9 @@ mach_dep.o: $(srcdir)/mach_dep.c $(srcdir)/mips_sgi_mach_dep.s $(srcdir)/mips_ul
|
||||
./if_mach SPARC SUNOS4 $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
|
||||
./if_mach SPARC OPENBSD $(AS) -o mach_dep.o $(srcdir)/sparc_sunos4_mach_dep.s
|
||||
./if_mach SPARC NETBSD $(AS) -o mach_dep.o $(srcdir)/sparc_netbsd_mach_dep.s
|
||||
./if_mach IA64 "" as $(AS_ABI_FLAG) -o ia64_save_regs_in_stack.o $(srcdir)/ia64_save_regs_in_stack.s
|
||||
./if_mach IA64 "" $(CC) -c -o mach_dep1.o $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
|
||||
./if_mach IA64 "" ld -r -o mach_dep.o mach_dep1.o ia64_save_regs_in_stack.o
|
||||
./if_not_there mach_dep.o $(CC) -c $(SPECIALCFLAGS) $(srcdir)/mach_dep.c
|
||||
|
||||
mark_rts.o: $(srcdir)/mark_rts.c $(UTILS)
|
||||
|
||||
@@ -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,
|
||||
|
||||
+8
-16
@@ -86,8 +86,6 @@ CXXINCLUDES = @CXXINCLUDES@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXTRA_TEST_LIBS = @EXTRA_TEST_LIBS@
|
||||
GCJ = @GCJ@
|
||||
GCJFLAGS = @GCJFLAGS@
|
||||
GC_CFLAGS = @GC_CFLAGS@
|
||||
INCLUDES = @INCLUDES@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
@@ -96,10 +94,8 @@ MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MY_CFLAGS = @MY_CFLAGS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
STRIP = @STRIP@
|
||||
THREADLIBS = @THREADLIBS@
|
||||
VERSION = @VERSION@
|
||||
addobjs = @addobjs@
|
||||
@@ -121,7 +117,7 @@ MULTICLEAN = true
|
||||
|
||||
toolexeclib_LTLIBRARIES = $(target_all)
|
||||
EXTRA_LTLIBRARIES = libgc.la
|
||||
libgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c
|
||||
libgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c backgraph.c
|
||||
|
||||
|
||||
# Include THREADLIBS here to ensure that the correct versions of
|
||||
@@ -130,7 +126,7 @@ libgc_la_LIBADD = @addobjs@ $(THREADLIBS)
|
||||
libgc_la_DEPENDENCIES = @addobjs@
|
||||
libgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
|
||||
|
||||
EXTRA_libgc_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_libgc_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@
|
||||
@@ -138,6 +134,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 = ./libgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
|
||||
TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
|
||||
@@ -159,7 +157,7 @@ CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host
|
||||
|
||||
MAKEOVERRIDES =
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/$gc_basedir/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
|
||||
|
||||
@@ -173,7 +171,7 @@ dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \
|
||||
irix_threads.lo linux_threads.lo malloc.lo mallocx.lo mark.lo \
|
||||
mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo \
|
||||
ptr_chck.lo real_malloc.lo reclaim.lo solaris_pthreads.lo \
|
||||
solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo
|
||||
solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo backgraph.lo
|
||||
check_PROGRAMS = gctest$(EXEEXT)
|
||||
gctest_DEPENDENCIES = ./libgc.la
|
||||
gctest_LDFLAGS =
|
||||
@@ -182,7 +180,7 @@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CF
|
||||
CCLD = $(CC)
|
||||
DIST_COMMON = Makefile.am Makefile.in acinclude.m4 aclocal.m4 \
|
||||
config.guess config.sub configure configure.in install-sh ltconfig \
|
||||
ltmain.sh
|
||||
ltmain.sh mkinstalldirs
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@@ -194,7 +192,7 @@ OBJECTS = $(libgc_la_OBJECTS)
|
||||
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .lo .o .obj .s
|
||||
.SUFFIXES: .S .c .lo .o .s
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
|
||||
|
||||
@@ -238,11 +236,6 @@ uninstall-toolexeclibLTLIBRARIES:
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
# FIXME: We should only use cygpath when building on Windows,
|
||||
# and only if it is available.
|
||||
.c.obj:
|
||||
$(COMPILE) -c `cygpath -w $<`
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
@@ -251,7 +244,6 @@ uninstall-toolexeclibLTLIBRARIES:
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
clean-compile:
|
||||
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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));
|
||||
|
||||
+31
-2
@@ -78,7 +78,7 @@ char * GC_copyright[] =
|
||||
{"Copyright 1988,1989 Hans-J. Boehm and Alan J. Demers ",
|
||||
"Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. ",
|
||||
"Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. ",
|
||||
"Copyright (c) 1999-2000 by Hewlett-Packard Company. All rights reserved. ",
|
||||
"Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved. ",
|
||||
"THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY",
|
||||
" EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.",
|
||||
"See source code for details." };
|
||||
@@ -97,6 +97,8 @@ word GC_free_space_divisor = 3;
|
||||
extern GC_bool GC_collection_in_progress();
|
||||
/* Collection is in progress, or was abandoned. */
|
||||
|
||||
extern GC_bool GC_print_back_height;
|
||||
|
||||
int GC_never_stop_func GC_PROTO((void)) { return(0); }
|
||||
|
||||
CLOCK_TYPE GC_start_time; /* Time at which we stopped world. */
|
||||
@@ -434,7 +436,7 @@ GC_stop_func stop_func;
|
||||
{
|
||||
register int i;
|
||||
int dummy;
|
||||
# ifdef PRINTTIMES
|
||||
# if defined(PRINTTIMES) || defined(CONDPRINT)
|
||||
CLOCK_TYPE start_time, current_time;
|
||||
# endif
|
||||
|
||||
@@ -442,6 +444,9 @@ GC_stop_func stop_func;
|
||||
# ifdef PRINTTIMES
|
||||
GET_TIME(start_time);
|
||||
# endif
|
||||
# if defined(CONDPRINT) && !defined(PRINTTIMES)
|
||||
if (GC_print_stats) GET_TIME(start_time);
|
||||
# endif
|
||||
# ifdef CONDPRINT
|
||||
if (GC_print_stats) {
|
||||
GC_printf1("--> Marking for collection %lu ",
|
||||
@@ -451,6 +456,11 @@ GC_stop_func stop_func;
|
||||
(unsigned long) WORDS_TO_BYTES(GC_words_wasted));
|
||||
}
|
||||
# endif
|
||||
# ifdef MAKE_BACK_GRAPH
|
||||
if (GC_print_back_height) {
|
||||
GC_build_back_graph();
|
||||
}
|
||||
# endif
|
||||
|
||||
/* Mark from all roots. */
|
||||
/* Minimize junk left in my registers and on the stack */
|
||||
@@ -504,6 +514,14 @@ GC_stop_func stop_func;
|
||||
GET_TIME(current_time);
|
||||
GC_printf1("World-stopped marking took %lu msecs\n",
|
||||
MS_TIME_DIFF(current_time,start_time));
|
||||
# else
|
||||
# ifdef CONDPRINT
|
||||
if (GC_print_stats) {
|
||||
GET_TIME(current_time);
|
||||
GC_printf1("World-stopped marking took %lu msecs\n",
|
||||
MS_TIME_DIFF(current_time,start_time));
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
START_WORLD();
|
||||
return(TRUE);
|
||||
@@ -610,6 +628,17 @@ void GC_finish_collection()
|
||||
GET_TIME(finalize_time);
|
||||
# endif
|
||||
|
||||
if (GC_print_back_height) {
|
||||
# ifdef MAKE_BACK_GRAPH
|
||||
GC_traverse_back_graph();
|
||||
# else
|
||||
# ifndef SMALL_CONFIG
|
||||
GC_err_printf0("Back height not available: "
|
||||
"Rebuild collector with -DMAKE_BACK_GRAPH\n");
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Clear free list mark bits, in case they got accidentally marked */
|
||||
/* (or GC_find_leak is set and they were intentionally marked). */
|
||||
/* Also subtract memory remaining from GC_mem_found count. */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# $Id: alpha_mach_dep.s,v 1.3 2001/11/15 00:32:13 a-ito Exp $
|
||||
# $Id: alpha_mach_dep.s,v 1.4 2001/12/20 00:37:29 ukai Exp $
|
||||
.arch ev6
|
||||
|
||||
.text
|
||||
|
||||
+447
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* Copyright (c) 2001 by Hewlett-Packard Company. All rights reserved.
|
||||
*
|
||||
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
|
||||
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
|
||||
*
|
||||
* Permission is hereby granted to use or copy this program
|
||||
* for any purpose, provided the above notices are retained on all copies.
|
||||
* Permission to modify the code and to distribute modified code is granted,
|
||||
* provided the above notices are retained, and a notice that the code was
|
||||
* modified is included with the above copyright notice.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implements a full, though not well-tuned, representation of the
|
||||
* backwards points-to graph. This is used to test for non-GC-robust
|
||||
* data structures; the code is not used during normal garbage collection.
|
||||
*
|
||||
* One restriction is that we drop all back-edges from nodes with very
|
||||
* high in-degree, and simply add them add them to a list of such
|
||||
* nodes. They are then treated as permanent roots. Id this by itself
|
||||
* doesn't introduce a space leak, then such nodes can't contribute to
|
||||
* a growing space leak.
|
||||
*/
|
||||
|
||||
#ifdef MAKE_BACK_GRAPH
|
||||
|
||||
#define MAX_IN 10 /* Maximum in-degree we handle directly */
|
||||
|
||||
#include "private/dbg_mlc.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#if !defined(DBG_HDRS_ALL) || (ALIGNMENT != CPP_WORDSZ/8) || !defined(UNIX_LIKE)
|
||||
# error Configuration doesnt support MAKE_BACK_GRAPH
|
||||
#endif
|
||||
|
||||
/* We store single back pointers directly in the object's oh_bg_ptr field. */
|
||||
/* If there is more than one ptr to an object, we store q | FLAG_MANY, */
|
||||
/* where q is a pointer to a back_edges object. */
|
||||
/* Every once in a while we use a back_edges object even for a single */
|
||||
/* pointer, since we need the other fields in the back_edges structure to */
|
||||
/* be present in some fraction of the objects. Otherwise we get serious */
|
||||
/* performance issues. */
|
||||
#define FLAG_MANY 2
|
||||
|
||||
typedef struct back_edges_struct {
|
||||
word n_edges; /* Number of edges, including those in continuation */
|
||||
/* structures. */
|
||||
unsigned short flags;
|
||||
# define RETAIN 1 /* Directly points to a reachable object; */
|
||||
/* retain for next GC. */
|
||||
unsigned short height_gc_no;
|
||||
/* If height > 0, then the GC_gc_no value when it */
|
||||
/* was computed. If it was computed this cycle, then */
|
||||
/* it is current. If it was computed during the */
|
||||
/* last cycle, then it represents the old height, */
|
||||
/* which is only saved for live objects referenced by */
|
||||
/* dead ones. This may grow due to refs from newly */
|
||||
/* dead objects. */
|
||||
signed_word height;
|
||||
/* Longest path through unreachable nodes to this node */
|
||||
/* that we found using depth first search. */
|
||||
|
||||
# define HEIGHT_UNKNOWN ((signed_word)(-2))
|
||||
# define HEIGHT_IN_PROGRESS ((signed_word)(-1))
|
||||
ptr_t edges[MAX_IN];
|
||||
struct back_edges_struct *cont;
|
||||
/* Pointer to continuation structure; we use only the */
|
||||
/* edges field in the continuation. */
|
||||
/* also used as free list link. */
|
||||
} back_edges;
|
||||
|
||||
/* Allocate a new back edge structure. Should be more sophisticated */
|
||||
/* if this were production code. */
|
||||
#define MAX_BACK_EDGE_STRUCTS 100000
|
||||
static back_edges *back_edge_space = 0;
|
||||
int GC_n_back_edge_structs = 0; /* Serves as pointer to never used */
|
||||
/* back_edges space. */
|
||||
static back_edges *avail_back_edges = 0;
|
||||
/* Pointer to free list of deallocated */
|
||||
/* back_edges structures. */
|
||||
|
||||
static back_edges * new_back_edges(void)
|
||||
{
|
||||
if (0 == back_edge_space) {
|
||||
back_edge_space = (back_edges *)
|
||||
sbrk(MAX_BACK_EDGE_STRUCTS*sizeof(back_edges));
|
||||
}
|
||||
if (0 != avail_back_edges) {
|
||||
back_edges * result = avail_back_edges;
|
||||
avail_back_edges = result -> cont;
|
||||
result -> cont = 0;
|
||||
return result;
|
||||
}
|
||||
if (GC_n_back_edge_structs >= MAX_BACK_EDGE_STRUCTS - 1) {
|
||||
ABORT("needed too much space for back edges: adjust "
|
||||
"MAX_BACK_EDGE_STRUCTS");
|
||||
}
|
||||
return back_edge_space + (GC_n_back_edge_structs++);
|
||||
}
|
||||
|
||||
/* Deallocate p and its associated continuation structures. */
|
||||
static void deallocate_back_edges(back_edges *p)
|
||||
{
|
||||
back_edges *last = p;
|
||||
|
||||
while (0 != last -> cont) last = last -> cont;
|
||||
last -> cont = avail_back_edges;
|
||||
avail_back_edges = p;
|
||||
}
|
||||
|
||||
/* Table of objects that are currently on the depth-first search */
|
||||
/* stack. Only objects with in-degree one are in this table. */
|
||||
/* Other objects are identified using HEIGHT_IN_PROGRESS. */
|
||||
/* This data structure NEEDS IMPROVEMENT. */
|
||||
#define MAX_IN_PROGRESS 10000
|
||||
static ptr_t * in_progress_space = 0;
|
||||
static int n_in_progress = 0;
|
||||
|
||||
static void push_in_progress(ptr_t p)
|
||||
{
|
||||
if (in_progress_space == 0)
|
||||
in_progress_space = sbrk(MAX_IN_PROGRESS * sizeof(ptr_t));
|
||||
if (n_in_progress == MAX_IN_PROGRESS)
|
||||
ABORT("Exceeded MAX_IN_PROGRESS");
|
||||
in_progress_space[n_in_progress++] = p;
|
||||
}
|
||||
|
||||
static GC_bool is_in_progress(ptr_t p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_in_progress; ++i) {
|
||||
if (in_progress_space[i] == p) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void pop_in_progress(ptr_t p)
|
||||
{
|
||||
--n_in_progress;
|
||||
GC_ASSERT(in_progress_space[n_in_progress] == p);
|
||||
}
|
||||
|
||||
#define GET_OH_BG_PTR(p) \
|
||||
(ptr_t)REVEAL_POINTER(((oh *)(p)) -> oh_bg_ptr)
|
||||
#define SET_OH_BG_PTR(p,q) (((oh *)(p)) -> oh_bg_ptr) = HIDE_POINTER(q)
|
||||
|
||||
/* Execute s once for each predecessor q of p in the points-to graph. */
|
||||
/* s should be a bracketed statement. We declare q. */
|
||||
#define FOR_EACH_PRED(q, p, s) \
|
||||
{ \
|
||||
ptr_t q = GET_OH_BG_PTR(p); \
|
||||
if (!((word)q & FLAG_MANY)) { \
|
||||
if (q && !((word)q & 1)) s \
|
||||
/* !((word)q & 1) checks for a misnterpreted freelist link */ \
|
||||
} else { \
|
||||
back_edges *orig_be_ = (back_edges *)((word)q & ~FLAG_MANY); \
|
||||
back_edges *be_ = orig_be_; \
|
||||
int total_, local_; \
|
||||
int n_edges_ = be_ -> n_edges; \
|
||||
for (total_ = 0, local_ = 0; total_ < n_edges_; ++local_, ++total_) { \
|
||||
if (local_ == MAX_IN) { \
|
||||
be_ = be_ -> cont; \
|
||||
local_ = 0; \
|
||||
} \
|
||||
q = be_ -> edges[local_]; s \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Ensure that p has a back_edges structure associated with it. */
|
||||
static void ensure_struct(ptr_t p)
|
||||
{
|
||||
ptr_t old_back_ptr = GET_OH_BG_PTR(p);
|
||||
|
||||
if (!((word)old_back_ptr & FLAG_MANY)) {
|
||||
back_edges *be = new_back_edges();
|
||||
be -> flags = 0;
|
||||
if (0 == old_back_ptr) {
|
||||
be -> n_edges = 0;
|
||||
} else {
|
||||
be -> n_edges = 1;
|
||||
be -> edges[0] = old_back_ptr;
|
||||
}
|
||||
be -> height = HEIGHT_UNKNOWN;
|
||||
be -> height_gc_no = GC_gc_no - 1;
|
||||
GC_ASSERT(be >= back_edge_space);
|
||||
SET_OH_BG_PTR(p, (word)be | FLAG_MANY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the (forward) edge from p to q to the backward graph. Both p */
|
||||
/* q are pointers to the object base, i.e. pointers to an oh. */
|
||||
static void add_edge(ptr_t p, ptr_t q)
|
||||
{
|
||||
ptr_t old_back_ptr = GET_OH_BG_PTR(q);
|
||||
back_edges * be, *be_cont;
|
||||
word i;
|
||||
static unsigned random_number = 13;
|
||||
# define GOT_LUCKY_NUMBER (((++random_number) & 0x7f) == 0)
|
||||
/* A not very random number we use to occasionally allocate a */
|
||||
/* back_edges structure even for a single backward edge. This */
|
||||
/* prevents us from repeatedly tracing back through very long */
|
||||
/* chains, since we will have some place to store height and */
|
||||
/* in_progress flags along the way. */
|
||||
|
||||
GC_ASSERT(p == GC_base(p) && q == GC_base(q));
|
||||
if (!GC_HAS_DEBUG_INFO(q) || !GC_HAS_DEBUG_INFO(p)) {
|
||||
/* This is really a misinterpreted free list link, since we saw */
|
||||
/* a pointer to a free list. Dont overwrite it! */
|
||||
return;
|
||||
}
|
||||
if (0 == old_back_ptr) {
|
||||
SET_OH_BG_PTR(q, p);
|
||||
if (GOT_LUCKY_NUMBER) ensure_struct(q);
|
||||
return;
|
||||
}
|
||||
/* Check whether it was already in the list of predecessors. */
|
||||
FOR_EACH_PRED(pred, q, { if (p == pred) return; });
|
||||
ensure_struct(q);
|
||||
old_back_ptr = GET_OH_BG_PTR(q);
|
||||
be = (back_edges *)((word)old_back_ptr & ~FLAG_MANY);
|
||||
for (i = be -> n_edges, be_cont = be; i > MAX_IN;
|
||||
be_cont = be_cont -> cont, i -= MAX_IN) {}
|
||||
if (i == MAX_IN) {
|
||||
be_cont -> cont = new_back_edges();
|
||||
be_cont = be_cont -> cont;
|
||||
i = 0;
|
||||
}
|
||||
be_cont -> edges[i] = p;
|
||||
be -> n_edges++;
|
||||
if (be -> n_edges == 100) {
|
||||
# if 0
|
||||
if (GC_print_stats) {
|
||||
GC_err_printf0("The following object has in-degree >= 100:\n");
|
||||
GC_print_heap_obj(q);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*per_object_func)(ptr_t p, word n_words, word gc_descr);
|
||||
|
||||
static void per_object_helper(struct hblk *h, word fn)
|
||||
{
|
||||
hdr * hhdr = HDR(h);
|
||||
word sz = hhdr -> hb_sz;
|
||||
word descr = hhdr -> hb_descr;
|
||||
per_object_func f = (per_object_func)fn;
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
f((ptr_t)(h -> hb_body + i), sz, descr);
|
||||
i += sz;
|
||||
} while (i + sz <= BYTES_TO_WORDS(HBLKSIZE));
|
||||
}
|
||||
|
||||
void GC_apply_to_each_object(per_object_func f)
|
||||
{
|
||||
GC_apply_to_all_blocks(per_object_helper, (word)f);
|
||||
}
|
||||
|
||||
static void reset_back_edge(ptr_t p, word n_words, word gc_descr)
|
||||
{
|
||||
/* Skip any free list links, or dropped blocks */
|
||||
if (GC_HAS_DEBUG_INFO(p)) {
|
||||
ptr_t old_back_ptr = GET_OH_BG_PTR(p);
|
||||
if ((word)old_back_ptr & FLAG_MANY) {
|
||||
back_edges *be = (back_edges *)((word)old_back_ptr & ~FLAG_MANY);
|
||||
if (!(be -> flags & RETAIN)) {
|
||||
deallocate_back_edges(be);
|
||||
SET_OH_BG_PTR(p, 0);
|
||||
} else {
|
||||
word *currentp;
|
||||
|
||||
GC_ASSERT(GC_is_marked(p));
|
||||
|
||||
/* Back edges may point to objects that will not be retained. */
|
||||
/* Delete them for now, but remember the height. */
|
||||
/* Some will be added back at next GC. */
|
||||
be -> n_edges = 0;
|
||||
if (0 != be -> cont) {
|
||||
deallocate_back_edges(be -> cont);
|
||||
be -> cont = 0;
|
||||
}
|
||||
|
||||
GC_ASSERT(GC_is_marked(p));
|
||||
|
||||
/* We only retain things for one GC cycle at a time. */
|
||||
be -> flags &= ~RETAIN;
|
||||
}
|
||||
} else /* Simple back pointer */ {
|
||||
/* Clear to avoid dangling pointer. */
|
||||
SET_OH_BG_PTR(p, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void add_back_edges(ptr_t p, word n_words, word gc_descr)
|
||||
{
|
||||
word *currentp = (word *)(p + sizeof(oh));
|
||||
|
||||
/* For now, fix up non-length descriptors conservatively. */
|
||||
if((gc_descr & GC_DS_TAGS) != GC_DS_LENGTH) {
|
||||
gc_descr = WORDS_TO_BYTES(n_words);
|
||||
}
|
||||
while (currentp < (word *)(p + gc_descr)) {
|
||||
word current = *currentp++;
|
||||
if (current >= (word)GC_least_plausible_heap_addr &&
|
||||
current <= (word)GC_greatest_plausible_heap_addr) {
|
||||
ptr_t target = GC_base((GC_PTR)current);
|
||||
if (0 != target) {
|
||||
add_edge(p, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rebuild the reprentation of the backward reachability graph. */
|
||||
/* Does not examine mark bits. Can be called before GC. */
|
||||
void GC_build_back_graph(void)
|
||||
{
|
||||
GC_apply_to_each_object(add_back_edges);
|
||||
}
|
||||
|
||||
/* Return an approximation to the length of the longest simple path */
|
||||
/* through unreachable objects to p. We refer to this as the height */
|
||||
/* of p. */
|
||||
static word backwards_height(ptr_t p)
|
||||
{
|
||||
word result;
|
||||
ptr_t back_ptr = GET_OH_BG_PTR(p);
|
||||
back_edges *be;
|
||||
|
||||
if (0 == back_ptr) return 1;
|
||||
if (!((word)back_ptr & FLAG_MANY)) {
|
||||
if (is_in_progress(p)) return 0; /* DFS back edge, i.e. we followed */
|
||||
/* an edge to an object already */
|
||||
/* on our stack: ignore */
|
||||
push_in_progress(p);
|
||||
result = backwards_height(back_ptr)+1;
|
||||
pop_in_progress(p);
|
||||
return result;
|
||||
}
|
||||
be = (back_edges *)((word)back_ptr & ~FLAG_MANY);
|
||||
if (be -> height >= 0 && be -> height_gc_no == GC_gc_no)
|
||||
return be -> height;
|
||||
/* Ignore back edges in DFS */
|
||||
if (be -> height == HEIGHT_IN_PROGRESS) return 0;
|
||||
result = (be -> height > 0? be -> height : 1);
|
||||
be -> height = HEIGHT_IN_PROGRESS;
|
||||
FOR_EACH_PRED(q, p, {
|
||||
word this_height;
|
||||
if (GC_is_marked(q) && !(FLAG_MANY & (word)GET_OH_BG_PTR(p))) {
|
||||
if (GC_print_stats)
|
||||
GC_printf2("Found bogus pointer from 0x%lx to 0x%lx\n", q, p);
|
||||
/* Reachable object "points to" unreachable one. */
|
||||
/* Could be caused by our lax treatment of GC descriptors. */
|
||||
this_height = 1;
|
||||
} else {
|
||||
this_height = backwards_height(q);
|
||||
}
|
||||
if (this_height >= result) result = this_height + 1;
|
||||
});
|
||||
be -> height = result;
|
||||
be -> height_gc_no = GC_gc_no;
|
||||
return result;
|
||||
}
|
||||
|
||||
word GC_max_height;
|
||||
ptr_t GC_deepest_obj;
|
||||
|
||||
/* Compute the maximum height of every unreachable predecessor p of a */
|
||||
/* reachable object. Arrange to save the heights of all such objects p */
|
||||
/* so that they can be used in calculating the height of objects in the */
|
||||
/* next GC. */
|
||||
/* Set GC_max_height to be the maximum height we encounter, and */
|
||||
/* GC_deepest_obj to be the corresponding object. */
|
||||
static void update_max_height(ptr_t p, word n_words, word gc_descr)
|
||||
{
|
||||
if (GC_is_marked(p) && GC_HAS_DEBUG_INFO(p)) {
|
||||
int i;
|
||||
word p_height = 0;
|
||||
ptr_t p_deepest_obj = 0;
|
||||
ptr_t back_ptr;
|
||||
back_edges *be = 0;
|
||||
|
||||
/* If we remembered a height last time, use it as a minimum. */
|
||||
/* It may have increased due to newly unreachable chains pointing */
|
||||
/* to p, but it can't have decreased. */
|
||||
back_ptr = GET_OH_BG_PTR(p);
|
||||
if (0 != back_ptr && ((word)back_ptr & FLAG_MANY)) {
|
||||
be = (back_edges *)((word)back_ptr & ~FLAG_MANY);
|
||||
if (be -> height != HEIGHT_UNKNOWN) p_height = be -> height;
|
||||
}
|
||||
FOR_EACH_PRED(q, p, {
|
||||
if (!GC_is_marked(q) && GC_HAS_DEBUG_INFO(q)) {
|
||||
word q_height;
|
||||
|
||||
q_height = backwards_height(q);
|
||||
if (q_height > p_height) {
|
||||
p_height = q_height;
|
||||
p_deepest_obj = q;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (p_height > 0) {
|
||||
/* Remember the height for next time. */
|
||||
if (be == 0) {
|
||||
ensure_struct(p);
|
||||
back_ptr = GET_OH_BG_PTR(p);
|
||||
be = (back_edges *)((word)back_ptr & ~FLAG_MANY);
|
||||
}
|
||||
be -> flags |= RETAIN;
|
||||
be -> height = p_height;
|
||||
be -> height_gc_no = GC_gc_no;
|
||||
}
|
||||
if (p_height > GC_max_height) {
|
||||
GC_max_height = p_height;
|
||||
GC_deepest_obj = p_deepest_obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GC_traverse_back_graph(void)
|
||||
{
|
||||
static word max_max_height = 0;
|
||||
GC_max_height = 0;
|
||||
GC_apply_to_each_object(update_max_height);
|
||||
GC_printf2("Maximum backwards height of reachable objects at GC %lu is %ld\n",
|
||||
(unsigned long) GC_gc_no, GC_max_height);
|
||||
if (GC_max_height > max_max_height) {
|
||||
max_max_height = GC_max_height;
|
||||
GC_printf0("The following unreachable object is last in a longest chain "
|
||||
"of unreachable objects:\n");
|
||||
GC_print_heap_obj(GC_deepest_obj);
|
||||
}
|
||||
if (GC_print_stats) {
|
||||
GC_printf1("Needed max total of %ld back-edge structs\n",
|
||||
GC_n_back_edge_structs);
|
||||
}
|
||||
GC_apply_to_each_object(reset_back_edge);
|
||||
GC_deepest_obj = 0;
|
||||
}
|
||||
|
||||
#endif /* MAKE_BACK_GRAPH */
|
||||
Vendored
+108
-59
@@ -40,6 +40,8 @@ ac_help="$ac_help
|
||||
--enable-parallel-mark parallelize marking and free list construction"
|
||||
ac_help="$ac_help
|
||||
--with-ecos enable runtime eCos target support"
|
||||
ac_help="$ac_help
|
||||
--enable-shared[=PKGS] build shared libraries [default=no]"
|
||||
ac_help="$ac_help
|
||||
--enable-full-debug include full support for pointer backtracing etc."
|
||||
|
||||
@@ -601,7 +603,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:605: checking host system type" >&5
|
||||
echo "configure:607: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
@@ -622,7 +624,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$host" 1>&6
|
||||
|
||||
echo $ac_n "checking target system type""... $ac_c" 1>&6
|
||||
echo "configure:626: checking target system type" >&5
|
||||
echo "configure:628: checking target system type" >&5
|
||||
|
||||
target_alias=$target
|
||||
case "$target_alias" in
|
||||
@@ -640,7 +642,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$target" 1>&6
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:644: checking build system type" >&5
|
||||
echo "configure:646: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@@ -675,7 +677,7 @@ test "$host_alias" != "$target_alias" &&
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
||||
echo "configure:679: checking for a BSD compatible install" >&5
|
||||
echo "configure:681: checking for a BSD compatible install" >&5
|
||||
if test -z "$INSTALL"; then
|
||||
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@@ -728,7 +730,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
|
||||
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
||||
|
||||
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
|
||||
echo "configure:732: checking whether build environment is sane" >&5
|
||||
echo "configure:734: checking whether build environment is sane" >&5
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftestfile
|
||||
@@ -785,7 +787,7 @@ test "$program_suffix" != NONE &&
|
||||
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
|
||||
|
||||
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
|
||||
echo "configure:789: checking whether ${MAKE-make} sets \${MAKE}" >&5
|
||||
echo "configure:791: checking whether ${MAKE-make} sets \${MAKE}" >&5
|
||||
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@@ -818,12 +820,12 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
|
||||
echo "configure:822: checking for Cygwin environment" >&5
|
||||
echo "configure:824: checking for Cygwin environment" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 827 "configure"
|
||||
#line 829 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
int main() {
|
||||
@@ -834,7 +836,7 @@ int main() {
|
||||
return __CYGWIN__;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:838: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:840: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_cygwin=yes
|
||||
else
|
||||
@@ -851,19 +853,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6
|
||||
CYGWIN=
|
||||
test "$ac_cv_cygwin" = yes && CYGWIN=yes
|
||||
echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
|
||||
echo "configure:855: checking for mingw32 environment" >&5
|
||||
echo "configure:857: checking for mingw32 environment" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 860 "configure"
|
||||
#line 862 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
int main() {
|
||||
return __MINGW32__;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:867: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:869: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_mingw32=yes
|
||||
else
|
||||
@@ -951,7 +953,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:955: checking host system type" >&5
|
||||
echo "configure:957: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
@@ -972,7 +974,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$host" 1>&6
|
||||
|
||||
echo $ac_n "checking target system type""... $ac_c" 1>&6
|
||||
echo "configure:976: checking target system type" >&5
|
||||
echo "configure:978: checking target system type" >&5
|
||||
|
||||
target_alias=$target
|
||||
case "$target_alias" in
|
||||
@@ -990,7 +992,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$target" 1>&6
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:994: checking build system type" >&5
|
||||
echo "configure:996: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@@ -1026,7 +1028,7 @@ fi
|
||||
|
||||
missing_dir=`cd $ac_aux_dir && pwd`
|
||||
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
|
||||
echo "configure:1030: checking for working aclocal" >&5
|
||||
echo "configure:1032: checking for working aclocal" >&5
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
@@ -1039,7 +1041,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
|
||||
echo "configure:1043: checking for working autoconf" >&5
|
||||
echo "configure:1045: checking for working autoconf" >&5
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
@@ -1052,7 +1054,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for working automake""... $ac_c" 1>&6
|
||||
echo "configure:1056: checking for working automake" >&5
|
||||
echo "configure:1058: checking for working automake" >&5
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
@@ -1065,7 +1067,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
|
||||
echo "configure:1069: checking for working autoheader" >&5
|
||||
echo "configure:1071: checking for working autoheader" >&5
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
@@ -1078,7 +1080,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
|
||||
echo "configure:1082: checking for working makeinfo" >&5
|
||||
echo "configure:1084: checking for working makeinfo" >&5
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
@@ -1104,7 +1106,7 @@ fi
|
||||
# Extract the first word of "gcc", so it can be a program name with args.
|
||||
set dummy gcc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1108: checking for $ac_word" >&5
|
||||
echo "configure:1110: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1134,7 +1136,7 @@ if test -z "$CC"; then
|
||||
# Extract the first word of "cc", so it can be a program name with args.
|
||||
set dummy cc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1138: checking for $ac_word" >&5
|
||||
echo "configure:1140: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1183,7 +1185,7 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
||||
echo "configure:1187: checking whether we are using GNU C" >&5
|
||||
echo "configure:1189: checking whether we are using GNU C" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1192,7 +1194,7 @@ else
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1196: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1198: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
ac_cv_prog_gcc=yes
|
||||
else
|
||||
ac_cv_prog_gcc=no
|
||||
@@ -1207,7 +1209,7 @@ if test $ac_cv_prog_gcc = yes; then
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
||||
echo "configure:1211: checking whether ${CC-cc} accepts -g" >&5
|
||||
echo "configure:1213: checking whether ${CC-cc} accepts -g" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1244,7 +1246,7 @@ do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1248: checking for $ac_word" >&5
|
||||
echo "configure:1250: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1277,7 +1279,7 @@ test -n "$CXX" || CXX="gcc"
|
||||
test -z "$CXX" && { echo "configure: error: no acceptable c++ found in \$PATH" 1>&2; exit 1; }
|
||||
|
||||
echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
|
||||
echo "configure:1281: checking whether we are using GNU C++" >&5
|
||||
echo "configure:1283: checking whether we are using GNU C++" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1286,7 +1288,7 @@ else
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1290: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1292: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
ac_cv_prog_gxx=yes
|
||||
else
|
||||
ac_cv_prog_gxx=no
|
||||
@@ -1301,7 +1303,7 @@ if test $ac_cv_prog_gxx = yes; then
|
||||
ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS=
|
||||
echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
|
||||
echo "configure:1305: checking whether ${CXX-g++} accepts -g" >&5
|
||||
echo "configure:1307: checking whether ${CXX-g++} accepts -g" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1334,7 +1336,7 @@ fi
|
||||
# NEWLIB_CONFIGURE, which doesn't work because that means that it will
|
||||
# be run before AC_CANONICAL_HOST.
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:1338: checking build system type" >&5
|
||||
echo "configure:1340: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@@ -1355,7 +1357,7 @@ echo "$ac_t""$build" 1>&6
|
||||
# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}as; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1359: checking for $ac_word" >&5
|
||||
echo "configure:1361: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1387,7 +1389,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ar; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1391: checking for $ac_word" >&5
|
||||
echo "configure:1393: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1419,7 +1421,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1423: checking for $ac_word" >&5
|
||||
echo "configure:1425: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1451,7 +1453,7 @@ if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||
set dummy ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1455: checking for $ac_word" >&5
|
||||
echo "configure:1457: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1496,7 +1498,7 @@ fi
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
||||
echo "configure:1500: checking for a BSD compatible install" >&5
|
||||
echo "configure:1502: checking for a BSD compatible install" >&5
|
||||
if test -z "$INSTALL"; then
|
||||
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@@ -1550,7 +1552,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
||||
|
||||
|
||||
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
|
||||
echo "configure:1554: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
||||
echo "configure:1556: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
||||
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
|
||||
if test "${enable_maintainer_mode+set}" = set; then
|
||||
enableval="$enable_maintainer_mode"
|
||||
@@ -1588,7 +1590,7 @@ if false; then
|
||||
|
||||
|
||||
echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
|
||||
echo "configure:1592: checking for executable suffix" >&5
|
||||
echo "configure:1594: checking for executable suffix" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1598,7 +1600,7 @@ else
|
||||
rm -f conftest*
|
||||
echo 'int main () { return 0; }' > conftest.$ac_ext
|
||||
ac_cv_exeext=
|
||||
if { (eval echo configure:1602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
|
||||
if { (eval echo configure:1604: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
|
||||
for file in conftest.*; do
|
||||
case $file in
|
||||
*.c | *.o | *.obj) ;;
|
||||
@@ -1711,7 +1713,7 @@ fi
|
||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||
set dummy ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1715: checking for $ac_word" >&5
|
||||
echo "configure:1717: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1750,7 +1752,7 @@ ac_prog=ld
|
||||
if test "$ac_cv_prog_gcc" = yes; then
|
||||
# Check if gcc -print-prog-name=ld gives a path.
|
||||
echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
|
||||
echo "configure:1754: checking for ld used by GCC" >&5
|
||||
echo "configure:1756: checking for ld used by GCC" >&5
|
||||
ac_prog=`($CC -print-prog-name=ld) 2>&5`
|
||||
case "$ac_prog" in
|
||||
# Accept absolute paths.
|
||||
@@ -1774,10 +1776,10 @@ echo "configure:1754: checking for ld used by GCC" >&5
|
||||
esac
|
||||
elif test "$with_gnu_ld" = yes; then
|
||||
echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
|
||||
echo "configure:1778: checking for GNU ld" >&5
|
||||
echo "configure:1780: checking for GNU ld" >&5
|
||||
else
|
||||
echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
|
||||
echo "configure:1781: checking for non-GNU ld" >&5
|
||||
echo "configure:1783: checking for non-GNU ld" >&5
|
||||
fi
|
||||
if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@@ -1812,7 +1814,7 @@ else
|
||||
fi
|
||||
test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
|
||||
echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
|
||||
echo "configure:1816: checking if the linker ($LD) is GNU ld" >&5
|
||||
echo "configure:1818: checking if the linker ($LD) is GNU ld" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1828,7 +1830,7 @@ echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
|
||||
|
||||
|
||||
echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
|
||||
echo "configure:1832: checking for BSD-compatible nm" >&5
|
||||
echo "configure:1834: checking for BSD-compatible nm" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1864,7 +1866,7 @@ NM="$ac_cv_path_NM"
|
||||
echo "$ac_t""$NM" 1>&6
|
||||
|
||||
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
|
||||
echo "configure:1868: checking whether ln -s works" >&5
|
||||
echo "configure:1870: checking whether ln -s works" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -1918,8 +1920,8 @@ test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
|
||||
case "$lt_target" in
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 1922 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo configure:1923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
echo '#line 1924 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo configure:1925: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
case "`/usr/bin/file conftest.o`" in
|
||||
*32-bit*)
|
||||
LD="${LD-ld} -32"
|
||||
@@ -1940,19 +1942,19 @@ case "$lt_target" in
|
||||
SAVE_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -belf"
|
||||
echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
|
||||
echo "configure:1944: checking whether the C compiler needs -belf" >&5
|
||||
echo "configure:1946: checking whether the C compiler needs -belf" >&5
|
||||
if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1949 "configure"
|
||||
#line 1951 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
int main() {
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:1958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
lt_cv_cc_needs_belf=yes
|
||||
else
|
||||
@@ -2068,7 +2070,7 @@ fi
|
||||
|
||||
|
||||
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
|
||||
echo "configure:2072: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
||||
echo "configure:2074: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
||||
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
|
||||
if test "${enable_maintainer_mode+set}" = set; then
|
||||
enableval="$enable_maintainer_mode"
|
||||
@@ -2101,7 +2103,7 @@ if false; then
|
||||
|
||||
|
||||
echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
|
||||
echo "configure:2105: checking for executable suffix" >&5
|
||||
echo "configure:2107: checking for executable suffix" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@@ -2111,7 +2113,7 @@ else
|
||||
rm -f conftest*
|
||||
echo 'int main () { return 0; }' > conftest.$ac_ext
|
||||
ac_cv_exeext=
|
||||
if { (eval echo configure:2115: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
|
||||
if { (eval echo configure:2117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
|
||||
for file in conftest.*; do
|
||||
case $file in
|
||||
*.c | *.o | *.obj) ;;
|
||||
@@ -2134,14 +2136,14 @@ ac_exeext=$EXEEXT
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for threads package to use""... $ac_c" 1>&6
|
||||
echo "configure:2138: checking for threads package to use" >&5
|
||||
echo "configure:2140: checking for threads package to use" >&5
|
||||
# Check whether --enable-threads or --disable-threads was given.
|
||||
if test "${enable_threads+set}" = set; then
|
||||
enableval="$enable_threads"
|
||||
THREADS=$enableval
|
||||
else
|
||||
echo $ac_n "checking for thread model used by GCC""... $ac_c" 1>&6
|
||||
echo "configure:2145: checking for thread model used by GCC" >&5
|
||||
echo "configure:2147: checking for thread model used by GCC" >&5
|
||||
THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
|
||||
if test -z "$THREADS"; then
|
||||
THREADS=no
|
||||
@@ -2227,7 +2229,7 @@ EOF
|
||||
*-*-freebsd*)
|
||||
echo "configure: warning: "FreeBSD does not yet fully support threads with Boehm GC."" 1>&2
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define FREEBSD_THREADS 1
|
||||
#define GC_FREEBSD_THREADS 1
|
||||
EOF
|
||||
|
||||
INCLUDES="$INCLUDES -pthread"
|
||||
@@ -2261,7 +2263,7 @@ esac
|
||||
|
||||
|
||||
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
|
||||
echo "configure:2265: checking for dlopen in -ldl" >&5
|
||||
echo "configure:2267: checking for dlopen in -ldl" >&5
|
||||
ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
|
||||
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@@ -2269,7 +2271,7 @@ else
|
||||
ac_save_LIBS="$LIBS"
|
||||
LIBS="-ldl $LIBS"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2273 "configure"
|
||||
#line 2275 "configure"
|
||||
#include "confdefs.h"
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
@@ -2280,7 +2282,7 @@ int main() {
|
||||
dlopen()
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:2286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||
else
|
||||
@@ -2340,6 +2342,40 @@ case "$host" in
|
||||
# alpha*-*-*)
|
||||
# machdep="alpha_mach_dep.lo"
|
||||
# ;;
|
||||
i?86-*-solaris2.[89]*)
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define SOLARIS25_PROC_VDB_BUG_FIXED 1
|
||||
EOF
|
||||
|
||||
;;
|
||||
alpha-*-openbsd*)
|
||||
if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
|
||||
echo "configure: warning: OpenBSD/Alpha without dlopen(). Shared library support is disabled" 1>&2
|
||||
# Check whether --enable-shared or --disable-shared was given.
|
||||
if test "${enable_shared+set}" = set; then
|
||||
enableval="$enable_shared"
|
||||
p=${PACKAGE-default}
|
||||
case "$enableval" in
|
||||
yes) enable_shared=yes ;;
|
||||
no) enable_shared=no ;;
|
||||
*)
|
||||
enable_shared=no
|
||||
# Look at the argument we got. We use all the common list separators.
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
|
||||
for pkg in $enableval; do
|
||||
if test "X$pkg" = "X$p"; then
|
||||
enable_shared=yes
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
enable_shared=no
|
||||
fi
|
||||
|
||||
fi
|
||||
;;
|
||||
mipstx39-*-elf*)
|
||||
machdep="mips_ultrix_mach_dep.lo"
|
||||
cat >> confdefs.h <<\EOF
|
||||
@@ -2366,6 +2402,9 @@ EOF
|
||||
#define SUNOS53_SHARED_LIB 1
|
||||
EOF
|
||||
|
||||
;;
|
||||
ia64-*-*)
|
||||
machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
|
||||
;;
|
||||
esac
|
||||
if test x"$machdep" = x; then
|
||||
@@ -2458,7 +2497,17 @@ EOF
|
||||
EOF
|
||||
|
||||
case $host in
|
||||
ia64-*-linux* )
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define MAKE_BACK_GRAPH 1
|
||||
EOF
|
||||
|
||||
;;
|
||||
x86-*-linux* | i586-*-linux* | i686-*-linux* )
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define MAKE_BACK_GRAPH 1
|
||||
EOF
|
||||
|
||||
echo "configure: warning: "Client must not use -fomit-frame-pointer."" 1>&2
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define SAVE_CALL_COUNT 8
|
||||
|
||||
+17
-1
@@ -96,7 +96,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
|
||||
;;
|
||||
@@ -157,6 +157,15 @@ case "$host" in
|
||||
# alpha*-*-*)
|
||||
# machdep="alpha_mach_dep.lo"
|
||||
# ;;
|
||||
i?86-*-solaris2.[[89]]*)
|
||||
AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED)
|
||||
;;
|
||||
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
|
||||
;;
|
||||
mipstx39-*-elf*)
|
||||
machdep="mips_ultrix_mach_dep.lo"
|
||||
AC_DEFINE(STACKBASE, __stackbase)
|
||||
@@ -172,6 +181,9 @@ case "$host" in
|
||||
sparc-sun-solaris2.3*)
|
||||
AC_DEFINE(SUNOS53_SHARED_LIB)
|
||||
;;
|
||||
ia64-*-*)
|
||||
machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
|
||||
;;
|
||||
esac
|
||||
if test x"$machdep" = x; then
|
||||
machdep="mach_dep.lo"
|
||||
@@ -232,7 +244,11 @@ AC_ARG_ENABLE(full-debug,
|
||||
AC_DEFINE(KEEP_BACK_PTRS)
|
||||
AC_DEFINE(DBG_HDRS_ALL)
|
||||
case $host in
|
||||
ia64-*-linux* )
|
||||
AC_DEFINE(MAKE_BACK_GRAPH)
|
||||
;;
|
||||
x86-*-linux* | i586-*-linux* | i686-*-linux* )
|
||||
AC_DEFINE(MAKE_BACK_GRAPH)
|
||||
AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
|
||||
AC_DEFINE(SAVE_CALL_COUNT, 8)
|
||||
;;
|
||||
|
||||
+58
-7
@@ -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) {
|
||||
@@ -245,6 +245,9 @@ word integer;
|
||||
LOCK();
|
||||
# ifdef KEEP_BACK_PTRS
|
||||
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
|
||||
# endif
|
||||
# ifdef MAKE_BACK_GRAPH
|
||||
((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0);
|
||||
# endif
|
||||
((oh *)p) -> oh_string = string;
|
||||
((oh *)p) -> oh_int = integer;
|
||||
@@ -274,6 +277,9 @@ word integer;
|
||||
/* inconsistent while we're in the handler. */
|
||||
# ifdef KEEP_BACK_PTRS
|
||||
((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
|
||||
# endif
|
||||
# ifdef MAKE_BACK_GRAPH
|
||||
((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0);
|
||||
# endif
|
||||
((oh *)p) -> oh_string = string;
|
||||
((oh *)p) -> oh_int = integer;
|
||||
@@ -861,6 +867,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,
|
||||
@@ -875,14 +903,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__
|
||||
@@ -900,14 +935,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__
|
||||
@@ -925,14 +968,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
|
||||
|
||||
+1
-1
@@ -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.1alpha2 of a conservative garbage collector for C and C++.
|
||||
|
||||
You might find a more recent version of this at
|
||||
|
||||
|
||||
+61
-6
@@ -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,71 @@ 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.
|
||||
Since 6.0alpha1:
|
||||
- No longer wrap read by default in multithreaded applications. It was
|
||||
pointed out on the libgcj list that this holds the allocation lock for
|
||||
way too long if the read blocks. For now, reads into the heap are
|
||||
broken with incremental collection. It's possible to turn this back on
|
||||
if you make sure that read calls don't block (e.g. by calling select
|
||||
first).
|
||||
- Fix ifdef in Solaris_threads.h to refer to GC_SOLARIS_THREADS.
|
||||
- Added check for environment variable GC_IGNORE_GCJ_INFO.
|
||||
- Added printing of stop-the-world GC times if GC_PRINT_STATS environment
|
||||
variable is set.
|
||||
- The calloc definition in leak_detector.h was missing parentheses, and
|
||||
realloc was missing a second argument to GC_REALLOC. (Thanks to Elrond.)
|
||||
- Added GC_PRINT_BACK_HEIGHT environment variable and associated
|
||||
code, mostly in the new file backgraph.c. See doc/README.environment.
|
||||
- Added -DUSE_GLOBAL_ALLOC to work around a Windows NT issue. (Thanks to
|
||||
Jonathan Clark.)
|
||||
- Integrated port to NEC EWS4800 (MIPS-based workstation, with somewhat
|
||||
different address-space layout). This may help for other machines with
|
||||
holes in the data segment. (Thanks to Hironori Sakamoto.)
|
||||
- Changed the order in which GC_push_roots and friends push things onto
|
||||
the mark stack. GC_push_all calls need to come first, since we can't
|
||||
necessarily recovere if thos overflow the mark stack. (Thanks to
|
||||
Matthew Flatt for tracking down the problem.)
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
The garbage collector looks at a number of environment variables which are
|
||||
the used to affect its operation. These are examined only on Un*x-like
|
||||
then used to affect its operation. These are examined only on Un*x-like
|
||||
platforms.
|
||||
|
||||
GC_INITIAL_HEAP_SIZE=<bytes> - Initial heap size in bytes. May speed up
|
||||
@@ -32,6 +32,27 @@ GC_NPROCS=<n> - Linux w/threads only. Explicitly sets the number of processors
|
||||
GC_NO_BLACKLIST_WARNING - Prevents the collector from issuing
|
||||
"Needed to allocate blacklisted block at ..." warnings.
|
||||
|
||||
GC_IGNORE_GCJ_INFO - Ignore the type descriptors implicitly supplied by
|
||||
GC_gcj_malloc and friends. This is useful for debugging
|
||||
descriptor generation problems, and possibly for
|
||||
temporarily working around such problems. It forces a
|
||||
fully conservative scan of all heap objects except
|
||||
those known to be pointerfree, and may thus have other
|
||||
adverse effects.
|
||||
|
||||
GC_PRINT_BACK_HEIGHT - Print max length of chain through unreachable objects
|
||||
ending in a reachable one. If this number remains
|
||||
bounded, then the program is "GC robust". This ensures
|
||||
that a fixed number of misidentified pointers can only
|
||||
result in a bounded space leak. This currently only
|
||||
works if debugging allocation is used throughout.
|
||||
It increases GC space and time requirements appreciably.
|
||||
This feature is still somewhat experimental, and requires
|
||||
that the collector have been built with MAKE_BACK_GRAPH
|
||||
defined. For details, see Boehm, "Bounding Space Usage
|
||||
of Conservative Garbage Collectors", POPL 2001, or
|
||||
http://lib.hpl.hp.com/techpubs/2001/HPL-2001-251.html .
|
||||
|
||||
The following turn on runtime flags that are also program settable. Checked
|
||||
only during initialization. We expect that they will usually be set through
|
||||
other means, but this may help with debugging and testing:
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
GC on EWS4800
|
||||
-------------
|
||||
|
||||
1. About EWS4800
|
||||
EWS4800 is 32bit/64bit workstation.
|
||||
|
||||
Vender: NEC Corporation
|
||||
OS: UX/4800 R9.* - R13.* (SystemV R4.2)
|
||||
CPU: R4000, R4400, R10000 (MIPS)
|
||||
|
||||
2. Compiler
|
||||
|
||||
32bit:
|
||||
Use ANSI C compiler.
|
||||
CC = /usr/abiccs/bin/cc
|
||||
|
||||
64bit:
|
||||
Use 64bit ANSI C compiler.
|
||||
CC = /usr/ccs64/bin/cc
|
||||
AR = /usr/ccs64/bin/ar
|
||||
|
||||
3. ELF file format
|
||||
*** Caution: The following infomation is empirical. ***
|
||||
|
||||
32bit:
|
||||
ELF file has an unique format. (See a.out(4) and end(3C).)
|
||||
|
||||
&_start
|
||||
: text segment
|
||||
&etext
|
||||
DATASTART
|
||||
: data segment (initialized)
|
||||
&edata
|
||||
DATASTART2
|
||||
: data segment (uninitialized)
|
||||
&end
|
||||
|
||||
Here, DATASTART and DATASTART2 are macros of GC, and are defined as
|
||||
the following equations. (See include/private/gcconfig.h.)
|
||||
The algorithm for DATASTART is similar with the function
|
||||
GC_SysVGetDataStart() in os_dep.c.
|
||||
|
||||
DATASTART = ((&etext + 0x3ffff) & ~0x3ffff) + (&etext & 0xffff)
|
||||
|
||||
Dynamically linked:
|
||||
DATASTART2 = (&_gp + 0x8000 + 0x3ffff) & ~0x3ffff
|
||||
|
||||
Statically linked:
|
||||
DATASTART2 = &edata
|
||||
|
||||
GC has to check addresses both between DATASTART and &edata, and
|
||||
between DATASTART2 and &end. If a program accesses between &etext
|
||||
and DATASTART, or between &edata and DATASTART2, the segmentation
|
||||
error occurs and the program stops.
|
||||
|
||||
If a program is statically linked, there is not a gap between
|
||||
&edata and DATASTART2. The global symbol &_DYNAMIC_LINKING is used
|
||||
for the detection.
|
||||
|
||||
64bit:
|
||||
ELF file has a simple format. (See end(3C).)
|
||||
|
||||
_ftext
|
||||
: text segment
|
||||
_etext
|
||||
_fdata = DATASTART
|
||||
: data segment (initialized)
|
||||
_edata
|
||||
_fbss
|
||||
: data segment (uninitialized)
|
||||
_end = DATAEND
|
||||
|
||||
--
|
||||
Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||
|
||||
+10
-3
@@ -1,8 +1,8 @@
|
||||
The collector has at various times been compiled under Windows 95 & NT,
|
||||
with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, with
|
||||
the GNU win32 environment, with Borland 4.5, and recently with
|
||||
Watcom C. It is likely that some of these have been broken in the
|
||||
meantime. Patches are appreciated.
|
||||
the GNU win32 environment, with Borland 4.5, with Watcom C, and recently
|
||||
with the Digital Mars compiler. It is likely that some of these have been
|
||||
broken in the meantime. Patches are appreciated.
|
||||
|
||||
It runs under both win32s and win32, but with different semantics.
|
||||
Under win32, all writable pages outside of the heaps and stack are
|
||||
@@ -45,6 +45,13 @@ window colors.)
|
||||
In general -DREDIRECT_MALLOC is unlikely to work unless the
|
||||
application is completely statically linked.
|
||||
|
||||
The collector normally allocates memory from the OS with VirtualAlloc.
|
||||
This appears to cause problems under Windows NT and Windows 2000 (but
|
||||
not Windows 95/98) if the memory is later passed to CreateDIBitmap.
|
||||
To work around this problem, build the collector with -DUSE_GLOBAL_ALLOC.
|
||||
This is currently incompatible with -DUSE_MUNMAP. (Thanks to Jonathan
|
||||
Clark for tracking this down.)
|
||||
|
||||
For Microsoft development tools, rename NT_MAKEFILE as
|
||||
MAKEFILE. (Make sure that the CPU environment variable is defined
|
||||
to be i386.) In order to use the gc_cpp.h C++ interface, all
|
||||
|
||||
@@ -209,6 +209,8 @@ down the problem:
|
||||
<OL>
|
||||
<LI> If you are using the incremental collector try turning it off for
|
||||
debugging.
|
||||
<LI> If you are using shared libraries, try linking statically. If that works,
|
||||
ensure that DYNAMIC_LOADING is defined on your platform.
|
||||
<LI> Try to reproduce the problem with fully debuggable unoptimized code.
|
||||
This will eliminate the last possibility, as well as making debugging easier.
|
||||
<LI> Try replacing any suspect typed allocation and <TT>GC_malloc_atomic</tt>
|
||||
|
||||
+101
-10
@@ -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)
|
||||
{
|
||||
@@ -649,7 +740,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)
|
||||
{
|
||||
@@ -864,7 +955,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;
|
||||
|
||||
+3
-2
@@ -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;
|
||||
@@ -838,3 +838,4 @@ void GC_notify_or_invoke_finalizers GC_PROTO((void))
|
||||
# endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -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/
|
||||
|
||||
+2
-3
@@ -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 ... */
|
||||
|
||||
|
||||
|
||||
|
||||
+26
-6
@@ -54,6 +54,7 @@ ptr_t * GC_gcjdebugobjfreelist;
|
||||
void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
|
||||
{
|
||||
register int i;
|
||||
GC_bool ignore_gcj_info;
|
||||
DCL_LOCK_STATE;
|
||||
|
||||
GC_init(); /* In case it's not already done. */
|
||||
@@ -65,6 +66,12 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
|
||||
return;
|
||||
}
|
||||
GC_gcj_malloc_initialized = TRUE;
|
||||
ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
|
||||
# ifdef CONDPRINT
|
||||
if (GC_print_stats && ignore_gcj_info) {
|
||||
GC_printf0("Gcj-style type information is disabled!\n");
|
||||
}
|
||||
# endif
|
||||
GC_mark_procs[mp_index] = (GC_mark_proc)mp;
|
||||
if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index");
|
||||
/* Set up object kind gcj-style indirect descriptor. */
|
||||
@@ -75,9 +82,17 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
|
||||
GC_gcj_kind = GC_n_kinds++;
|
||||
GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist;
|
||||
GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0;
|
||||
GC_obj_kinds[GC_gcj_kind].ok_descriptor =
|
||||
(((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) | GC_DS_PER_OBJECT);
|
||||
GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE;
|
||||
if (ignore_gcj_info) {
|
||||
/* Use a simple length-based descriptor, thus forcing a fully */
|
||||
/* conservative scan. */
|
||||
GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH);
|
||||
GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE;
|
||||
} else {
|
||||
GC_obj_kinds[GC_gcj_kind].ok_descriptor =
|
||||
(((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS))
|
||||
| GC_DS_PER_OBJECT);
|
||||
GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE;
|
||||
}
|
||||
GC_obj_kinds[GC_gcj_kind].ok_init = TRUE;
|
||||
/* Set up object kind for objects that require mark proc call. */
|
||||
GC_gcjdebugobjfreelist = (ptr_t *)
|
||||
@@ -88,9 +103,14 @@ void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
|
||||
GC_gcj_debug_kind = GC_n_kinds++;
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist;
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0;
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor =
|
||||
GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */);
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE;
|
||||
if (ignore_gcj_info) {
|
||||
GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH);
|
||||
GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE;
|
||||
} else {
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor =
|
||||
GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */);
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE;
|
||||
}
|
||||
GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE;
|
||||
UNLOCK();
|
||||
ENABLE_SIGNALS();
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
.text
|
||||
.align 16
|
||||
.global GC_save_regs_in_stack
|
||||
.proc GC_save_regs_in_stack
|
||||
GC_save_regs_in_stack:
|
||||
.body
|
||||
flushrs
|
||||
;;
|
||||
mov r8=ar.bsp
|
||||
br.ret.sptk.few rp
|
||||
.endp GC_save_regs_in_stack
|
||||
|
||||
+15
-13
@@ -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) */
|
||||
|
||||
@@ -44,9 +44,7 @@
|
||||
#endif /* SOLARIS_THREADS || SOLARIS_PTHREADS */
|
||||
|
||||
|
||||
#if !defined(GC_USE_LD_WRAP) && \
|
||||
(defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) \
|
||||
|| defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS))
|
||||
#if !defined(GC_USE_LD_WRAP) && defined(GC_PTHREADS) && !defined(GC_SOLARIS_PTHREADS)
|
||||
/* We treat these similarly. */
|
||||
# include <pthread.h>
|
||||
# include <signal.h>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define GC_DEBUG
|
||||
#include "gc.h"
|
||||
#define malloc(n) GC_MALLOC(n)
|
||||
#define calloc(m,n) GC_MALLOC(m*n)
|
||||
#define calloc(m,n) GC_MALLOC((m)*(n))
|
||||
#define free(p) GC_FREE(p)
|
||||
#define realloc(p,n) GC_REALLOC(n)
|
||||
#define realloc(p,n) GC_REALLOC((p),(n))
|
||||
#define CHECK_LEAKS() GC_gcollect()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
/* Stored both one past the end of user object, and one before */
|
||||
/* the end of the object as seen by the allocator. */
|
||||
|
||||
# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST)
|
||||
# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) \
|
||||
|| defined(MAKE_BACK_GRAPH)
|
||||
/* Pointer "source"s that aren't real locations. */
|
||||
/* Used in oh_back_ptr fields and as "source" */
|
||||
/* argument to some marking functions. */
|
||||
@@ -60,28 +61,42 @@
|
||||
|
||||
/* Object header */
|
||||
typedef struct {
|
||||
# ifdef KEEP_BACK_PTRS
|
||||
GC_hidden_pointer oh_back_ptr;
|
||||
/* We make sure that we only store even valued */
|
||||
/* pointers here, so that the hidden version has */
|
||||
/* the least significant bit set. We never */
|
||||
/* overwrite a value with the least significant */
|
||||
/* bit clear, thus ensuring that we never overwrite */
|
||||
/* a free list link field. */
|
||||
/* Note that blocks dropped by black-listing will */
|
||||
/* also have the lsb clear once debugging has */
|
||||
/* started. */
|
||||
/* The following are special back pointer values. */
|
||||
/* Note that the "hidden" (i.e. bitwise */
|
||||
/* complemented version) of these is actually */
|
||||
/* stored. */
|
||||
# if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
|
||||
/* We potentially keep two different kinds of back */
|
||||
/* pointers. KEEP_BACK_PTRS stores a single back */
|
||||
/* pointer in each reachable object to allow reporting */
|
||||
/* of why an object was retained. MAKE_BACK_GRAPH */
|
||||
/* builds a graph containing the inverse of all */
|
||||
/* "points-to" edges including those involving */
|
||||
/* objects that have just become unreachable. This */
|
||||
/* allows detection of growing chains of unreachable */
|
||||
/* objects. It may be possible to eventually combine */
|
||||
/* both, but for now we keep them separate. Both */
|
||||
/* kinds of back pointers are hidden using the */
|
||||
/* following macros. In both cases, the plain version */
|
||||
/* is constrained to have an least significant bit of 1,*/
|
||||
/* to allow it to be distinguished from a free list */
|
||||
/* link. This means the plain version must have an */
|
||||
/* lsb of 0. */
|
||||
/* Note that blocks dropped by black-listing will */
|
||||
/* also have the lsb clear once debugging has */
|
||||
/* started. */
|
||||
/* We're careful never to overwrite a value with lsb 0. */
|
||||
# if ALIGNMENT == 1
|
||||
/* Fudge back pointer to be even. */
|
||||
# define HIDE_BACK_PTR(p) HIDE_POINTER(~1 & (GC_word)(p))
|
||||
# else
|
||||
# define HIDE_BACK_PTR(p) HIDE_POINTER(p)
|
||||
# endif
|
||||
# ifdef ALIGN_DOUBLE
|
||||
|
||||
# ifdef KEEP_BACK_PTRS
|
||||
GC_hidden_pointer oh_back_ptr;
|
||||
# endif
|
||||
# ifdef MAKE_BACK_GRAPH
|
||||
GC_hidden_pointer oh_bg_ptr;
|
||||
# endif
|
||||
# if defined(ALIGN_DOUBLE) && \
|
||||
(defined(KEEP_BACK_PTRS) != defined(MAKE_BACK_GRAPH))
|
||||
word oh_dummy;
|
||||
# endif
|
||||
# endif
|
||||
@@ -139,9 +154,9 @@ typedef struct {
|
||||
GC_bool GC_has_other_debug_info(/* p */);
|
||||
#endif
|
||||
|
||||
#ifdef KEEP_BACK_PTRS
|
||||
#if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
|
||||
# define GC_HAS_DEBUG_INFO(p) \
|
||||
((((oh *)p)->oh_back_ptr & 1) && GC_has_other_debug_info(p))
|
||||
((*((word *)p) & 1) && GC_has_other_debug_info(p))
|
||||
#else
|
||||
# define GC_HAS_DEBUG_INFO(p) GC_has_other_debug_info(p)
|
||||
#endif
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -136,7 +136,8 @@ extern mse * GC_mark_stack;
|
||||
/* Set *new_hdr_p to corr. hdr. */
|
||||
#ifdef __STDC__
|
||||
# ifdef PRINT_BLACK_LIST
|
||||
ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, word source);
|
||||
ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p,
|
||||
ptr_t source);
|
||||
# else
|
||||
ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p);
|
||||
# endif
|
||||
|
||||
@@ -396,7 +396,8 @@ struct hblk; /* See below. */
|
||||
+ GC_page_size-1)
|
||||
# else
|
||||
# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
|
||||
(defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC))
|
||||
(defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
|
||||
(defined(SUNOS5) && !defined(USE_MMAP))
|
||||
# define GET_MEM(bytes) HBLKPTR((size_t) \
|
||||
calloc(1, (size_t)bytes + GC_page_size) \
|
||||
+ GC_page_size-1)
|
||||
@@ -443,18 +444,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 +483,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 +569,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 +1907,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 +1915,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 */
|
||||
|
||||
+160
-71
@@ -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
|
||||
@@ -75,9 +78,12 @@
|
||||
# endif
|
||||
# define mach_type_known
|
||||
# endif
|
||||
# if defined(mips) || defined(__mips)
|
||||
# if defined(mips) || defined(__mips) || defined(_mips)
|
||||
# define MIPS
|
||||
# if !defined(LINUX)
|
||||
# if defined(nec_ews) || defined(_nec_ews)
|
||||
# define EWS4800
|
||||
# endif
|
||||
# if !defined(LINUX) && !defined(EWS4800)
|
||||
# if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__)
|
||||
# define ULTRIX
|
||||
# else
|
||||
@@ -161,6 +167,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 +207,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 +397,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 +409,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 +547,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>
|
||||
@@ -715,8 +729,12 @@
|
||||
extern char * GC_SysVGetDataStart();
|
||||
# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, &_etext)
|
||||
# define DATAEND (&_end)
|
||||
# ifndef USE_MMAP
|
||||
# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
|
||||
# define USE_MMAP
|
||||
/* Otherwise we now use calloc. Mmap may result in the */
|
||||
/* heap interleaved with thread stacks, which can result in */
|
||||
/* excessive blacklisting. Sbrk is unusable since it */
|
||||
/* doesn't interact correctly with the system malloc. */
|
||||
# endif
|
||||
# ifdef USE_MMAP
|
||||
# define HEAP_START (ptr_t)0x40000000
|
||||
@@ -838,21 +856,29 @@
|
||||
# endif
|
||||
# ifdef SUNOS5
|
||||
# define OS_TYPE "SUNOS5"
|
||||
extern int etext, _start;
|
||||
extern int _etext, _end;
|
||||
extern char * GC_SysVGetDataStart();
|
||||
# define DATASTART GC_SysVGetDataStart(0x1000, &etext)
|
||||
# define DATASTART GC_SysVGetDataStart(0x1000, &_etext)
|
||||
# define DATAEND (&_end)
|
||||
/* # define STACKBOTTOM ((ptr_t)(&_start)) worked through 2.7, */
|
||||
/* but reportedly breaks under 2.8. It appears that the stack */
|
||||
/* base is a property of the executable, so this should not break */
|
||||
/* old executables. */
|
||||
/* HEURISTIC2 probably works, but this appears to be preferable. */
|
||||
# include <sys/vmparam.h>
|
||||
# include <sys/vm.h>
|
||||
# define STACKBOTTOM USRSTACK
|
||||
/** At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
|
||||
/*# define PROC_VDB*/
|
||||
/* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
|
||||
/* It appears to be fixed in 2.8 and 2.9. */
|
||||
# ifdef SOLARIS25_PROC_VDB_BUG_FIXED
|
||||
# define PROC_VDB
|
||||
# endif
|
||||
# define DYNAMIC_LOADING
|
||||
# ifndef USE_MMAP
|
||||
# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
|
||||
# define USE_MMAP
|
||||
/* Otherwise we now use calloc. Mmap may result in the */
|
||||
/* heap interleaved with thread stacks, which can result in */
|
||||
/* excessive blacklisting. Sbrk is unusable since it */
|
||||
/* doesn't interact correctly with the system malloc. */
|
||||
# endif
|
||||
# ifdef USE_MMAP
|
||||
# define HEAP_START (ptr_t)0x40000000
|
||||
@@ -888,7 +914,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, */
|
||||
@@ -1003,8 +1029,17 @@
|
||||
# endif
|
||||
# ifdef FREEBSD
|
||||
# define OS_TYPE "FREEBSD"
|
||||
# define MPROTECT_VDB
|
||||
# ifndef GC_FREEBSD_THREADS
|
||||
# define MPROTECT_VDB
|
||||
# endif
|
||||
# define SIG_SUSPEND SIGUSR1
|
||||
# define SIG_THR_RESTART SIGUSR2
|
||||
# define FREEBSD_STACKBOTTOM
|
||||
# ifdef __ELF__
|
||||
# define DYNAMIC_LOADING
|
||||
# endif
|
||||
extern char etext;
|
||||
# define DATASTART ((ptr_t)(&etext))
|
||||
# endif
|
||||
# ifdef NETBSD
|
||||
# define OS_TYPE "NETBSD"
|
||||
@@ -1015,7 +1050,7 @@
|
||||
# ifdef BSDI
|
||||
# define OS_TYPE "BSDI"
|
||||
# endif
|
||||
# if defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
|
||||
# if defined(OPENBSD) || defined(NETBSD) \
|
||||
|| defined(THREE86BSD) || defined(BSDI)
|
||||
# define HEURISTIC2
|
||||
extern char etext;
|
||||
@@ -1083,6 +1118,29 @@
|
||||
/* instead. But some kernel versions seem to give the wrong */
|
||||
/* value from /proc. */
|
||||
# endif /* Linux */
|
||||
# ifdef EWS4800
|
||||
# define HEURISTIC2
|
||||
# if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64)
|
||||
extern int _fdata[], _end[];
|
||||
# define DATASTART ((ptr_t)_fdata)
|
||||
# define DATAEND ((ptr_t)_end)
|
||||
# define CPP_WORDSZ _MIPS_SZPTR
|
||||
# define ALIGNMENT (_MIPS_SZPTR/8)
|
||||
# else
|
||||
extern int etext, edata, end;
|
||||
extern int _DYNAMIC_LINKING, _gp;
|
||||
# define DATASTART ((ptr_t)((((word)&etext + 0x3ffff) & ~0x3ffff) \
|
||||
+ ((word)&etext & 0xffff)))
|
||||
# define DATAEND (&edata)
|
||||
# define DATASTART2 (&_DYNAMIC_LINKING \
|
||||
? (ptr_t)(((word)&_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \
|
||||
: (ptr_t)&edata)
|
||||
# define DATAEND2 (&end)
|
||||
# define ALIGNMENT 4
|
||||
# endif
|
||||
# define OS_TYPE "EWS4800"
|
||||
# define USE_GENERIC_PUSH_REGS 1
|
||||
# endif
|
||||
# ifdef ULTRIX
|
||||
# define HEURISTIC2
|
||||
# define DATASTART (ptr_t)0x10000000
|
||||
@@ -1161,7 +1219,6 @@
|
||||
|
||||
# ifdef HP_PA
|
||||
# define MACH_TYPE "HP_PA"
|
||||
# define OS_TYPE "HPUX"
|
||||
# ifdef __LP64__
|
||||
# define CPP_WORDSZ 64
|
||||
# define ALIGNMENT 8
|
||||
@@ -1170,8 +1227,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
|
||||
@@ -1186,6 +1242,7 @@
|
||||
# endif
|
||||
# define STACK_GROWS_UP
|
||||
# ifdef HPUX
|
||||
# define OS_TYPE "HPUX"
|
||||
extern int __data_start;
|
||||
# define DATASTART ((ptr_t)(&__data_start))
|
||||
# if 0
|
||||
@@ -1242,6 +1299,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)
|
||||
@@ -1284,9 +1354,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. */
|
||||
@@ -1296,11 +1363,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: */
|
||||
@@ -1315,7 +1418,13 @@
|
||||
# define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom)
|
||||
# define SEARCH_FOR_DATA_START
|
||||
# define DATASTART GC_data_start
|
||||
# define DYNAMIC_LOADING
|
||||
# ifdef __GNUC__
|
||||
# define DYNAMIC_LOADING
|
||||
# else
|
||||
/* In the Intel compiler environment, we seem to end up with */
|
||||
/* statically linked executables and an undefined reference */
|
||||
/* to _DYNAMIC */
|
||||
# endif
|
||||
# define MPROTECT_VDB
|
||||
/* Requires Linux 2.3.47 or later. */
|
||||
extern int _end;
|
||||
@@ -1581,57 +1690,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 GC_SOLARIS_THREADS to test for either old or pthreads. */
|
||||
# if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
|
||||
# define GC_SOLARIS_THREADS
|
||||
# endif
|
||||
|
||||
/* Internally we use SOLARIS_THREADS to test for either old or pthreads. */
|
||||
# if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS)
|
||||
# define 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
|
||||
|
||||
@@ -1656,4 +1741,8 @@
|
||||
/* include assembly code to do it well. */
|
||||
# endif
|
||||
|
||||
# if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
|
||||
# define DBG_HDRS_ALL
|
||||
# endif
|
||||
|
||||
# endif /* GCCONFIG_H */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifdef SOLARIS_THREADS
|
||||
#ifdef GC_SOLARIS_THREADS
|
||||
|
||||
/* The set of all known threads. We intercept thread creation and */
|
||||
/* joins. We never actually create detached threads. We allocate all */
|
||||
@@ -30,5 +30,5 @@
|
||||
extern size_t GC_page_sz;
|
||||
extern void GC_thr_init(void);
|
||||
|
||||
# endif /* SOLARIS_THREADS */
|
||||
# endif /* GC_SOLARIS_THREADS */
|
||||
|
||||
|
||||
+3
-3
@@ -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 */
|
||||
|
||||
|
||||
+47
-14
@@ -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);
|
||||
@@ -969,7 +991,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()
|
||||
{
|
||||
@@ -1005,7 +1027,7 @@ int GC_get_nprocs()
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif /* LINUX_THREADS */
|
||||
#endif /* GC_LINUX_THREADS */
|
||||
|
||||
/* We hold the allocation lock. */
|
||||
void GC_thr_init()
|
||||
@@ -1063,13 +1085,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
|
||||
}
|
||||
@@ -1249,6 +1271,17 @@ int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
|
||||
/* cant have been recycled by pthreads. */
|
||||
UNLOCK();
|
||||
result = REAL_FUNC(pthread_join)(thread, retval);
|
||||
# if defined (GC_FREEBSD_THREADS)
|
||||
/* On FreeBSD, the wrapped pthread_join() sometimes returns (what
|
||||
appears to be) a spurious EINTR which caused the test and real code
|
||||
to gratuitously fail. Having looked at system pthread library source
|
||||
code, I see how this return code may be generated. In one path of
|
||||
code, pthread_join() just returns the errno setting of the thread
|
||||
being joined. This does not match the POSIX specification or the
|
||||
local man pages thus I have taken the liberty to catch this one
|
||||
spurious return value properly conditionalized on GC_FREEBSD_THREADS. */
|
||||
if (result == EINTR) result = 0;
|
||||
# endif
|
||||
if (result == 0) {
|
||||
LOCK();
|
||||
/* Here the pthread thread id may have been recycled. */
|
||||
@@ -1584,7 +1617,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 */
|
||||
@@ -1691,5 +1724,5 @@ void GC_notify_all_marker()
|
||||
|
||||
#endif /* PARALLEL_MARK */
|
||||
|
||||
# endif /* LINUX_THREADS */
|
||||
# endif /* GC_LINUX_THREADS and friends */
|
||||
|
||||
|
||||
+25
-9
@@ -429,7 +429,7 @@ ptr_t cold_gc_frame;
|
||||
*i = 0;
|
||||
}
|
||||
# if defined(POWERPC) || defined(MSWIN32) || defined(MSWINCE) \
|
||||
|| defined(UTS4) || defined(LINUX)
|
||||
|| defined(UTS4) || defined(LINUX) || defined(EWS4800)
|
||||
(void) setjmp(regs);
|
||||
# else
|
||||
(void) _setjmp(regs);
|
||||
@@ -492,8 +492,11 @@ 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. */
|
||||
# ifdef IA64
|
||||
# ifdef __GNUC__
|
||||
/* We now implement this as a separate assembly file, since inline */
|
||||
/* assembly code here doesn't work with either the Intel or HP */
|
||||
/* compilers. */
|
||||
# if 0
|
||||
# ifdef LINUX
|
||||
asm(" .text");
|
||||
asm(" .psr abi64");
|
||||
asm(" .psr lsb");
|
||||
@@ -510,12 +513,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
|
||||
|
||||
+3
-3
@@ -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 */
|
||||
|
||||
@@ -838,7 +838,7 @@ long GC_markers = 2; /* Normally changed by thread-library- */
|
||||
/* -specific code. */
|
||||
|
||||
/* Mark using the local mark stack until the global mark stack is empty */
|
||||
/* and ther are no active workers. Update GC_first_nonempty to reflect */
|
||||
/* and there are no active workers. Update GC_first_nonempty to reflect */
|
||||
/* progress. */
|
||||
/* Caller does not hold mark lock. */
|
||||
/* Caller has already incremented GC_helper_count. We decrement it, */
|
||||
@@ -918,7 +918,7 @@ void GC_mark_local(mse *local_mark_stack, int id)
|
||||
return;
|
||||
}
|
||||
/* else there's something on the stack again, or */
|
||||
/* another help may push something. */
|
||||
/* another helper may push something. */
|
||||
GC_active_count++;
|
||||
GC_ASSERT(GC_active_count > 0);
|
||||
GC_release_mark_lock();
|
||||
@@ -950,8 +950,10 @@ void GC_do_parallel_mark()
|
||||
|
||||
GC_acquire_mark_lock();
|
||||
GC_ASSERT(I_HOLD_LOCK());
|
||||
GC_ASSERT(!GC_help_wanted);
|
||||
GC_ASSERT(GC_active_count == 0);
|
||||
/* This could be a GC_ASSERT, but it seems safer to keep it on */
|
||||
/* all the time, especially since it's cheap. */
|
||||
if (GC_help_wanted || GC_active_count != 0 || GC_helper_count != 0)
|
||||
ABORT("Tried to start parallel mark in bad state");
|
||||
# ifdef PRINTSTATS
|
||||
GC_printf1("Starting marking for mark phase number %lu\n",
|
||||
(unsigned long)GC_mark_no);
|
||||
@@ -1374,11 +1376,11 @@ ptr_t cold_gc_frame;
|
||||
return;
|
||||
}
|
||||
# ifdef STACK_GROWS_DOWN
|
||||
GC_push_all_eager(bottom, cold_gc_frame);
|
||||
GC_push_all(cold_gc_frame - sizeof(ptr_t), top);
|
||||
GC_push_all_eager(bottom, cold_gc_frame);
|
||||
# else /* STACK_GROWS_UP */
|
||||
GC_push_all_eager(cold_gc_frame, top);
|
||||
GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t));
|
||||
GC_push_all_eager(cold_gc_frame, top);
|
||||
# endif /* STACK_GROWS_UP */
|
||||
} else {
|
||||
GC_push_all_eager(bottom, top);
|
||||
|
||||
+19
-18
@@ -252,7 +252,7 @@ GC_bool tmp;
|
||||
n_root_sets++;
|
||||
}
|
||||
|
||||
static roots_were_cleared = FALSE;
|
||||
static GC_bool roots_were_cleared = FALSE;
|
||||
|
||||
void GC_clear_roots GC_PROTO((void))
|
||||
{
|
||||
@@ -521,16 +521,6 @@ ptr_t cold_gc_frame;
|
||||
{
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* push registers - i.e., call GC_push_one(r) for each
|
||||
* register contents r.
|
||||
*/
|
||||
# ifdef USE_GENERIC_PUSH_REGS
|
||||
GC_generic_push_regs(cold_gc_frame);
|
||||
# else
|
||||
GC_push_regs(); /* usually defined in machine_dep.c */
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Next push static data. This must happen early on, since it's
|
||||
* not robust against mark stack overflow.
|
||||
@@ -564,19 +554,30 @@ ptr_t cold_gc_frame;
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Now traverse stacks.
|
||||
* Now traverse stacks, and mark from register contents.
|
||||
* These must be done last, since they can legitimately overflow
|
||||
* the mark stack.
|
||||
*/
|
||||
# if !defined(USE_GENERIC_PUSH_REGS)
|
||||
# ifdef USE_GENERIC_PUSH_REGS
|
||||
GC_generic_push_regs(cold_gc_frame);
|
||||
/* Also pushes stack, so that we catch callee-save registers */
|
||||
/* saved inside the GC_push_regs frame. */
|
||||
# else
|
||||
/*
|
||||
* push registers - i.e., call GC_push_one(r) for each
|
||||
* register contents r.
|
||||
*/
|
||||
GC_push_regs(); /* usually defined in machine_dep.c */
|
||||
GC_push_current_stack(cold_gc_frame);
|
||||
/* 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 threads case, this only pushes collector frames. */
|
||||
/* 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
|
||||
if (GC_push_other_roots != 0) (*GC_push_other_roots)();
|
||||
/* In the threads case, this also pushes thread stacks. */
|
||||
/* Note that without interior pointer recognition lots */
|
||||
/* of stuff may have been pushed already, and this */
|
||||
/* should be careful about mark stack overflows. */
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
|
||||
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
|
||||
* Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved.
|
||||
*
|
||||
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
|
||||
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
|
||||
@@ -22,7 +23,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 +42,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
|
||||
@@ -99,6 +98,8 @@ GC_bool GC_quiet = 0;
|
||||
|
||||
GC_bool GC_print_stats = 0;
|
||||
|
||||
GC_bool GC_print_back_height = 0;
|
||||
|
||||
#ifdef FIND_LEAK
|
||||
int GC_find_leak = 1;
|
||||
#else
|
||||
@@ -499,6 +500,9 @@ void GC_init_inner()
|
||||
if (0 != GETENV("GC_DONT_GC")) {
|
||||
GC_dont_gc = 1;
|
||||
}
|
||||
if (0 != GETENV("GC_PRINT_BACK_HEIGHT")) {
|
||||
GC_print_back_height = 1;
|
||||
}
|
||||
# ifdef UNIX_LIKE
|
||||
if (0 != GETENV("GC_LOOP_ON_ABORT")) {
|
||||
GC_set_and_save_fault_handler(looping_handler);
|
||||
@@ -524,20 +528,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 +654,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 +755,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);
|
||||
|
||||
+46
-33
@@ -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()
|
||||
@@ -561,7 +557,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);
|
||||
@@ -575,7 +571,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
|
||||
@@ -670,7 +666,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;
|
||||
@@ -1079,7 +1080,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 */
|
||||
@@ -1090,6 +1091,9 @@ void GC_register_data_segments()
|
||||
GC_add_roots_inner(DATASTART, (char *)sbrk(0), FALSE);
|
||||
# else
|
||||
GC_add_roots_inner(DATASTART, (char *)(DATAEND), FALSE);
|
||||
# if defined(DATASTART2)
|
||||
GC_add_roots_inner(DATASTART2, (char *)(DATAEND2), FALSE);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# if !defined(PCR) && (defined(NEXT) || defined(MACOSX))
|
||||
@@ -1288,8 +1292,14 @@ void * os2_alloc(size_t bytes)
|
||||
SYSTEM_INFO GC_sysinfo;
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef MSWIN32
|
||||
|
||||
# ifdef USE_GLOBAL_ALLOC
|
||||
# define GLOBAL_ALLOC_TEST 1
|
||||
# else
|
||||
# define GLOBAL_ALLOC_TEST GC_win32s
|
||||
# endif
|
||||
|
||||
word GC_n_heap_bases = 0;
|
||||
|
||||
ptr_t GC_win32_get_mem(bytes)
|
||||
@@ -1297,7 +1307,7 @@ word bytes;
|
||||
{
|
||||
ptr_t result;
|
||||
|
||||
if (GC_win32s) {
|
||||
if (GLOBAL_ALLOC_TEST) {
|
||||
/* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE. */
|
||||
/* There are also unconfirmed rumors of other */
|
||||
/* problems, so we dodge the issue. */
|
||||
@@ -1640,9 +1650,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();
|
||||
|
||||
@@ -1651,11 +1660,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.
|
||||
@@ -2399,7 +2408,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
|
||||
@@ -2537,11 +2546,15 @@ 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(THREADS) \
|
||||
&& !defined(GC_USE_LD_WRAP)
|
||||
/* Replacement for UNIX system call. */
|
||||
/* Other calls that write to the heap */
|
||||
/* should be handled similarly. */
|
||||
/* Replacement for UNIX system call. */
|
||||
/* Other calls that write to the heap should be handled similarly. */
|
||||
/* Note that this doesn't work well for blocking reads: It will hold */
|
||||
/* tha allocation lock for the entur duration of the call. Multithreaded */
|
||||
/* clients should really ensure that it won't block, either by setting */
|
||||
/* the descriptor nonblocking, or by calling select or poll first, to */
|
||||
/* make sure that input is available. */
|
||||
# if defined(__STDC__) && !defined(SUNOS4)
|
||||
# include <unistd.h>
|
||||
# include <sys/uio.h>
|
||||
@@ -2561,7 +2574,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. */
|
||||
@@ -2587,9 +2600,9 @@ word len;
|
||||
GC_end_syscall();
|
||||
return(result);
|
||||
}
|
||||
#endif /* !MSWIN32 && !MSWINCE && !LINUX_THREADS */
|
||||
#endif /* !MSWIN32 && !MSWINCE && !GC_LINUX_THREADS */
|
||||
|
||||
#ifdef GC_USE_LD_WRAP
|
||||
#if defined(GC_USE_LD_WRAP) && !defined(THREADS)
|
||||
/* We use the GNU ld call wrapping facility. */
|
||||
/* This requires that the linker be invoked with "--wrap read". */
|
||||
/* This can be done by passing -Wl,"--wrap read" to gcc. */
|
||||
@@ -2660,7 +2673,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 */
|
||||
@@ -2715,7 +2728,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) {
|
||||
@@ -2733,7 +2746,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)
|
||||
@@ -2772,7 +2785,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
|
||||
@@ -2802,7 +2815,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);
|
||||
|
||||
@@ -2820,7 +2833,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();
|
||||
@@ -2836,7 +2849,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 */
|
||||
@@ -2854,7 +2867,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);
|
||||
@@ -2868,7 +2881,7 @@ word n;
|
||||
|
||||
register word index;
|
||||
|
||||
# ifdef SOLARIS_THREADS
|
||||
# ifdef GC_SOLARIS_THREADS
|
||||
register word i;
|
||||
|
||||
if (GC_fresh_pages != 0) {
|
||||
|
||||
+20
-10
@@ -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 */
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
* Modified Peter C. for Solaris Posix Threads.
|
||||
*/
|
||||
/* Boehm, September 14, 1994 4:44 pm PDT */
|
||||
/* $Id: solaris_pthreads.c,v 1.3 2001/11/15 00:32:13 a-ito Exp $ */
|
||||
/* $Id: solaris_pthreads.c,v 1.4 2001/12/20 00:37:29 ukai Exp $ */
|
||||
|
||||
# if defined(GC_SOLARIS_PTHREADS) || defined(_SOLARIS_PTHREADS)
|
||||
# if defined(GC_SOLARIS_PTHREADS)
|
||||
# include "private/gc_priv.h"
|
||||
# include <pthread.h>
|
||||
# include <thread.h>
|
||||
@@ -176,5 +176,5 @@ GC_pthread_create(pthread_t *new_thread,
|
||||
int GC_no_sunOS_pthreads;
|
||||
#endif
|
||||
|
||||
# endif /* SOLARIS_THREADS */
|
||||
# endif /* GC_SOLARIS_PTHREADS */
|
||||
|
||||
|
||||
+13
-2
@@ -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"
|
||||
@@ -621,7 +621,18 @@ GC_thread GC_lookup_thread(thread_t id)
|
||||
return(p);
|
||||
}
|
||||
|
||||
/* Solaris 2/Intel uses an initial stack size limit slightly bigger than the
|
||||
SPARC default of 8 MB. Account for this to warn only if the user has
|
||||
raised the limit beyond the default.
|
||||
|
||||
This is identical to DFLSSIZ defined in <sys/vm_machparam.h>. This file
|
||||
is installed in /usr/platform/`uname -m`/include, which is not in the
|
||||
default include directory list, so copy the definition here. */
|
||||
#ifdef I386
|
||||
# define MAX_ORIG_STACK_SIZE (8 * 1024 * 1024 + ((USRSTACK) & 0x3FFFFF))
|
||||
#else
|
||||
# define MAX_ORIG_STACK_SIZE (8 * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
word GC_get_orig_stack_size() {
|
||||
struct rlimit rl;
|
||||
@@ -938,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;
|
||||
|
||||
+2
-2
@@ -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 */
|
||||
|
||||
+46
-39
@@ -20,7 +20,7 @@
|
||||
|
||||
# undef GC_BUILD
|
||||
|
||||
#ifdef DBG_HDRS_ALL
|
||||
#if defined(DBG_HDRS_ALL) || defined(MAKE_BACK_GRAPH)
|
||||
# define GC_DEBUG
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
@@ -1346,7 +1340,7 @@ void SetMinimumStack(long minSize)
|
||||
# endif
|
||||
GC_INIT(); /* Only needed if gc is dynamic library. */
|
||||
(void) GC_set_warn_proc(warn_proc);
|
||||
# if defined(MPROTECT_VDB) || defined(PROC_VDB)
|
||||
# if (defined(MPROTECT_VDB) || defined(PROC_VDB)) && !defined(MAKE_BACK_GRAPH)
|
||||
GC_enable_incremental();
|
||||
(void) GC_printf0("Switched to incremental mode\n");
|
||||
# if defined(MPROTECT_VDB)
|
||||
@@ -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;
|
||||
@@ -1578,7 +1571,9 @@ main()
|
||||
|
||||
n_tests = 0;
|
||||
GC_INIT(); /* Only needed if gc is dynamic library. */
|
||||
GC_enable_incremental();
|
||||
# ifndef MAKE_BACK_GRAPH
|
||||
GC_enable_incremental();
|
||||
# endif
|
||||
(void) GC_set_warn_proc(warn_proc);
|
||||
if (thr_keycreate(&fl_key, GC_free) != 0) {
|
||||
(void)GC_printf1("Key creation failed %lu\n", (unsigned long)code);
|
||||
@@ -1606,6 +1601,11 @@ main()
|
||||
return(0);
|
||||
}
|
||||
#else /* pthreads */
|
||||
|
||||
#ifndef GC_PTHREADS
|
||||
--> bad news
|
||||
#endif
|
||||
|
||||
main()
|
||||
{
|
||||
pthread_t th1;
|
||||
@@ -1618,12 +1618,19 @@ 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) || defined(GC_FREEBSD_THREADS)
|
||||
pthread_attr_setstacksize(&attr, 1000000);
|
||||
# endif
|
||||
n_tests = 0;
|
||||
# if defined(MPROTECT_VDB) && !defined(PARALLEL_MARK) &&!defined(REDIRECT_MALLOC)
|
||||
# if defined(MPROTECT_VDB) && !defined(PARALLEL_MARK) &&!defined(REDIRECT_MALLOC) && !defined(MAKE_BACK_GRAPH)
|
||||
GC_enable_incremental();
|
||||
(void) GC_printf0("Switched to incremental mode\n");
|
||||
(void) GC_printf0("Emulating dirty bits with mprotect/signals\n");
|
||||
@@ -1656,5 +1663,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 */
|
||||
|
||||
+5
-10
@@ -9,20 +9,15 @@ 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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#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 2
|
||||
|
||||
# define GC_NOT_ALPHA 0xff
|
||||
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
#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 */
|
||||
|
||||
Reference in New Issue
Block a user