Projects
openEuler:Mainline
gc
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 2
View file
_service:tar_scm:gc.spec
Changed
@@ -1,12 +1,14 @@ Name: gc -Version: 8.0.6 +Version: 8.2.2 Release: 1 Summary: A garbage collector for C and C++ License: BSD and GPLv1+ Url: http://www.hboehm.info/gc/ Source0: http://www.hboehm.info/gc/gc_source/gc-%{version}.tar.gz +Patch1: gc-8.0.6-sw.patch +Patch2: 0001-add-loongarch-architecture.patch -BuildRequires: gcc gcc-c++ libtool libatomic_ops-devel +BuildRequires: gcc gcc-c++ libtool %description The Boehm-Demers-Weiser conservative garbage collector can be @@ -58,6 +60,7 @@ %{_libdir}/libcord.so.1* %{_libdir}/libgc.so.1* %{_libdir}/libgccpp.so.1* +%{_libdir}/libgctba.so* %files devel %doc doc/README.environment doc/README.linux @@ -72,6 +75,24 @@ %changelog +* Thu Feb 2 2023 huyubiao <huyubiao@huawei.com> - 8.2.2-1 +- Update gc to 8.2.2 + +* Tue Nov 21 2022 doupengda <doupengda@loongson.cn> - 8.0.6-4 +- add loongarch64 support + +* Mon Nov 14 2022 wuzx<wuzx1226@qq.com> - 8.0.6-3 +- Type:feature +- CVE:NA +- SUG:NA +- DESC:Add sw64 architecture + +* Tue Oct 18 2022 Liu Zixian <liuzixian4@huawei.com> - 8.0.6-2 +- Type:cleancode +- ID:NA +- SUG:NA +- DESC:Remove unused BuildRequires + * Thu Dec 2 2021 wangjie <wangjie375@huawei.com> - 8.0.6-1 - Type:enhancement - ID:NA
View file
_service:tar_scm:0001-add-loongarch-architecture.patch
Added
@@ -0,0 +1,96 @@ +From 6ade473e440b2da11e6ecf6a69c4f1b309ab7624 Mon Sep 17 00:00:00 2001 +From: wang--ge <wang__ge@126.com> +Date: Tue, 12 Apr 2022 19:47:14 +0800 +Subject: PATCH add loongarch architecture + +--- + configure.ac | 2 +- + include/private/gcconfig.h | 31 +++++++++++++++++++++++++++++++ + os_dep.c | 2 +- + 3 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 2bc1282..7cc02a9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -208,7 +208,7 @@ case "$THREADS" in + *-*-aix* | *-*-android* | *-*-cygwin* | *-*-darwin* | *-*-dragonfly* | \ + *-*-freebsd* | *-*-haiku* | *-*-hpux11* | *-*-irix* | \ + *-*-kfreebsd*-gnu | *-*-gnu* | *-*-*linux* | *-*-msys* | *-*-nacl* | \ +- *-*-netbsd* | *-*-openbsd* | *-*-osf* | *-*-solaris*) ++ *-*-netbsd* | *-*-openbsd* | *-*-osf* | *-*-solaris* | loongarch*) + AC_DEFINE(GC_THREADS) + AC_DEFINE(_REENTRANT, 1, + Required define if using POSIX threads.) +diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h +index b4457c1..5826ad5 100644 +--- a/include/private/gcconfig.h ++++ b/include/private/gcconfig.h +@@ -226,6 +226,14 @@ EXTERN_C_BEGIN + # define VAX + # define mach_type_known + # endif ++# if defined(__loongarch64) ++# define LOONGARCH64 ++# define mach_type_known ++# endif ++# if defined(__loongarch64) ++# define LOONGARCH64 ++# define mach_type_known ++# endif + # if defined(mips) || defined(__mips) || defined(_mips) + # define MIPS + # if defined(nec_ews) || defined(_nec_ews) +@@ -518,6 +526,10 @@ EXTERN_C_BEGIN + # define AARCH64 + # define mach_type_known + # endif ++# if defined(FREEBSD) && (defined(__loongarch64) ) ++# define LOONGARCH64 ++# define mach_type_known ++# endif + # if defined(FREEBSD) && (defined(mips) || defined(__mips) || defined(_mips)) + # define MIPS + # define mach_type_known +@@ -1702,6 +1714,25 @@ EXTERN_C_BEGIN + # define STACKBOTTOM ((ptr_t)0xfffff000) /* for Encore */ + # endif + ++# ifdef LOONGARCH64 ++# define MACH_TYPE "LOONGARCH64" ++# ifdef LINUX ++# define OS_TYPE "LINUX" ++# define DYNAMIC_LOADING ++ extern int _end; ++# pragma weak __data_start ++ extern int __data_start; ++# define DATASTART ((ptr_t)(__data_start)) ++# define DATAEND ((ptr_t)(_end)) ++# define CPP_WORDSZ 64 ++# define ALIGNMENT (64/8) ++# ifndef HBLKSIZE ++# define HBLKSIZE 4096 ++# endif ++# define LINUX_STACKBOTTOM ++# endif ++# endif ++ + # ifdef LOONGARCH + # define MACH_TYPE "LoongArch" + # ifdef LINUX +diff --git a/os_dep.c b/os_dep.c +index e116ad0..947ac7f 100644 +--- a/os_dep.c ++++ b/os_dep.c +@@ -3239,7 +3239,7 @@ GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void) + # ifndef SEGV_ACCERR + # define SEGV_ACCERR 2 + # endif +-# if defined(AARCH64) || defined(ARM32) || defined(MIPS) \ ++# if defined(AARCH64) || defined(ARM32) || defined(MIPS) || defined(LOONGARCH64) \ + || __FreeBSD__ >= 7 + # define CODE_OK (si -> si_code == SEGV_ACCERR) + # elif defined(POWERPC) +-- +2.27.0 +
View file
_service:tar_scm:gc-8.0.6-sw.patch
Added
@@ -0,0 +1,207 @@ +diff -Naur gc-8.0.6.org/config.guess gc-8.0.6.sw/config.guess +--- gc-8.0.6.org/config.guess 2022-02-14 09:01:19.450000000 +0000 ++++ gc-8.0.6.sw/config.guess 2022-02-15 02:27:24.780000000 +0000 +@@ -973,6 +973,14 @@ EOF + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; ++ sw_64:Linux:*:*) ++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in ++ sw) UNAME_MACHINE=sw_64 ;; ++ esac ++ objdump --private-headers /bin/sh | grep -q ld.so.1 ++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi ++ GUESS=${UNAME_MACHINE}-sunway-linux-${LIBC} ++ ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; +diff -Naur gc-8.0.6.org/config.sub gc-8.0.6.sw/config.sub +--- gc-8.0.6.org/config.sub 2022-02-14 09:01:19.450000000 +0000 ++++ gc-8.0.6.sw/config.sub 2022-02-15 02:25:05.350000000 +0000 +@@ -1175,6 +1175,7 @@ case $cpu-$vendor in + case $cpu in + 1750a | 580 \ + | a29k \ ++ | sw_64 \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev4-8 | alphaev56 | alphaev678 \ +diff -Naur gc-8.0.6.org/extra/msvc_dbg.c gc-8.0.6.sw/extra/msvc_dbg.c +--- gc-8.0.6.org/extra/msvc_dbg.c 2022-02-14 09:01:19.470000000 +0000 ++++ gc-8.0.6.sw/extra/msvc_dbg.c 2022-02-15 02:32:56.220000000 +0000 +@@ -156,6 +156,9 @@ size_t GetStackFramesFromContext(HANDLE hProcess, HANDLE hThread, + #elif defined(_M_MRX000) + machineType = IMAGE_FILE_MACHINE_R4000; + stackFrame.AddrPC.Offset = context->Fir; ++#elif defined(_M_SW_64) ++ machineType = IMAGE_FILE_MACHINE_SW_64; ++ stackFrame.AddrPC.Offset = (unsigned long)context->Fir; + #elif defined(_M_ALPHA) + machineType = IMAGE_FILE_MACHINE_ALPHA; + stackFrame.AddrPC.Offset = (unsigned long)context->Fir; +@@ -165,6 +168,9 @@ size_t GetStackFramesFromContext(HANDLE hProcess, HANDLE hThread, + #elif defined(_M_IA64) + machineType = IMAGE_FILE_MACHINE_IA64; + stackFrame.AddrPC.Offset = context->StIIP; ++#elif defined(_M_SW_6464) ++ machineType = IMAGE_FILE_MACHINE_SW_6464; ++ stackFrame.AddrPC.Offset = context->Fir; + #elif defined(_M_ALPHA64) + machineType = IMAGE_FILE_MACHINE_ALPHA64; + stackFrame.AddrPC.Offset = context->Fir; +diff -Naur gc-8.0.6.org/include/gc_config_macros.h gc-8.0.6.sw/include/gc_config_macros.h +--- gc-8.0.6.org/include/gc_config_macros.h 2022-02-14 09:01:19.450000000 +0000 ++++ gc-8.0.6.sw/include/gc_config_macros.h 2022-02-15 02:37:26.990000000 +0000 +@@ -96,7 +96,7 @@ + # define GC_FREEBSD_THREADS + # elif defined(__NetBSD__) + # define GC_NETBSD_THREADS +-# elif defined(__alpha) || defined(__alpha__) /* && !Linux && !xBSD */ ++# elif defined(__alpha) || defined(__alpha__) || defined(__sw_64) || defined(__sw_64__) /* && !Linux && !xBSD */ + # define GC_OSF1_THREADS + # elif (defined(mips) || defined(__mips) || defined(_mips)) \ + && !(defined(nec_ews) || defined(_nec_ews) \ +diff -Naur gc-8.0.6.org/include/gc_tiny_fl.h gc-8.0.6.sw/include/gc_tiny_fl.h +--- gc-8.0.6.org/include/gc_tiny_fl.h 2022-02-14 09:01:19.440000000 +0000 ++++ gc-8.0.6.sw/include/gc_tiny_fl.h 2022-02-15 02:38:20.270000000 +0000 +@@ -49,7 +49,7 @@ + # if defined(__LP64__) || defined (_LP64) || defined(_WIN64) \ + || defined(__s390x__) \ + || (defined(__x86_64__) && !defined(__ILP32__)) \ +- || defined(__alpha__) || defined(__powerpc64__) \ ++ || defined(__alpha__) || defined(__sw_64__) || defined(__powerpc64__) \ + || defined(__arch64__) + # define GC_GRANULE_BYTES 16 + # define GC_GRANULE_WORDS 2 +diff -Naur gc-8.0.6.org/include/private/gc_priv.h gc-8.0.6.sw/include/private/gc_priv.h +--- gc-8.0.6.org/include/private/gc_priv.h 2022-02-14 09:01:19.440000000 +0000 ++++ gc-8.0.6.sw/include/private/gc_priv.h 2022-02-15 02:40:15.270000000 +0000 +@@ -925,7 +925,7 @@ EXTERN_C_BEGIN + /* SMALL_CONFIG: Want less block-level fragmentation. */ + #ifndef HBLKSIZE + # if defined(LARGE_CONFIG) || !defined(SMALL_CONFIG) +-# ifdef ALPHA ++# if defined ALPHA || defined SW_64 + # define CPP_LOG_HBLKSIZE 13 + # elif defined(SN_TARGET_PSP2) + # define CPP_LOG_HBLKSIZE 16 /* page size is set to 64 KB */ +diff -Naur gc-8.0.6.org/include/private/gcconfig.h gc-8.0.6.sw/include/private/gcconfig.h +--- gc-8.0.6.org/include/private/gcconfig.h 2022-02-14 09:01:19.440000000 +0000 ++++ gc-8.0.6.sw/include/private/gcconfig.h 2022-02-15 02:45:28.230000000 +0000 +@@ -418,6 +418,14 @@ EXTERN_C_BEGIN + # define M32R + # define mach_type_known + # endif ++# if defined(__sw_64) || defined(__sw_64__) ++# define SW_64 ++# if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) \ ++ && !defined(FREEBSD) ++# define OSF1 /* a.k.a Digital Unix */ ++# endif ++# define mach_type_known ++# endif + # if defined(__alpha) || defined(__alpha__) + # define ALPHA + # if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) \ +@@ -1924,6 +1932,100 @@ EXTERN_C_BEGIN + # endif + # endif /* HP_PA */ + ++# ifdef SW_64 ++# define MACH_TYPE "SW_64" ++# define ALIGNMENT 8 ++# define CPP_WORDSZ 64 ++# ifdef NETBSD ++# define OS_TYPE "NETBSD" ++# define HEURISTIC2 ++ extern ptr_t GC_data_start; ++# define DATASTART GC_data_start ++# define ELFCLASS32 32 ++# define ELFCLASS64 64 ++# define ELF_CLASS ELFCLASS64 ++# define DYNAMIC_LOADING ++# endif ++# ifdef OPENBSD ++# define OS_TYPE "OPENBSD" ++# define ELF_CLASS ELFCLASS64 ++# ifndef GC_OPENBSD_THREADS ++# define HEURISTIC2 ++# endif ++ extern int __data_start; ++# define DATASTART ((ptr_t)__data_start) ++ extern int _end; ++# define DATAEND ((ptr_t)(&_end)) ++# define DYNAMIC_LOADING ++# endif ++# ifdef FREEBSD ++# define OS_TYPE "FREEBSD" ++/* MPROTECT_VDB is not yet supported at all on FreeBSD/sw_64. */ ++# define SIG_SUSPEND SIGUSR1 ++# define SIG_THR_RESTART SIGUSR2 ++ /* SIGTSTP and SIGCONT could be used alternatively. */ ++# define FREEBSD_STACKBOTTOM ++# ifdef __ELF__ ++# define DYNAMIC_LOADING ++# endif ++/* Handle unmapped hole sw_64*-*-freebsd45* puts between etext and edata. */ ++ extern char etext; ++ extern char edata; ++# if !defined(CPPCHECK) ++ extern char end; ++# endif ++# define NEED_FIND_LIMIT ++# define DATASTART ((ptr_t)(&etext)) ++ void * GC_find_limit(void *, int); ++# define DATAEND (ptr_t)GC_find_limit(DATASTART, TRUE) ++# define DATAEND_IS_FUNC ++# define GC_HAVE_DATAREGION2 ++# define DATASTART2 ((ptr_t)(&edata)) ++# define DATAEND2 ((ptr_t)(&end)) ++# endif ++# ifdef OSF1 ++# define OS_TYPE "OSF1" ++# define DATASTART ((ptr_t)0x140000000) ++ extern int _end; ++# define DATAEND ((ptr_t)(&_end)) ++ extern char ** environ; ++ /* round up from the value of environ to the nearest page boundary */ ++ /* Probably breaks if putenv is called before collector */ ++ /* initialization. */ ++# define STACKBOTTOM ((ptr_t)(((word)(environ) | (getpagesize()-1))+1)) ++/* # define HEURISTIC2 */ ++ /* Normally HEURISTIC2 is too conservative, since */ ++ /* the text segment immediately follows the stack. */ ++ /* Hence we give an upper pound. */ ++ /* This is currently unused, since we disabled HEURISTIC2 */ ++ extern int __start; ++# define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1))) ++# ifndef GC_OSF1_THREADS ++ /* Unresolved signal issues with threads. */ ++# define MPROTECT_VDB ++# endif ++# define DYNAMIC_LOADING ++# endif ++# ifdef LINUX ++# define OS_TYPE "LINUX" ++# define LINUX_STACKBOTTOM ++# define COUNT_UNMAPPED_REGIONS ++# ifdef __ELF__ ++# define SEARCH_FOR_DATA_START ++# define DYNAMIC_LOADING ++# else ++# define DATASTART ((ptr_t)0x140000000) ++# endif ++ extern int _end; ++# define DATAEND ((ptr_t)(_end)) ++# if !defined(REDIRECT_MALLOC) ++# define MPROTECT_VDB ++ /* Has only been superficially tested. May not */ ++ /* work on all versions. */ ++# endif ++# endif ++# endif ++ + # ifdef ALPHA + # define MACH_TYPE "ALPHA" + # define ALIGNMENT 8
View file
_service
Changed
@@ -2,7 +2,7 @@ <service name="tar_scm"> <param name="scm">git</param> <param name="url">git@gitee.com:src-openeuler/gc.git</param> - <param name="revision">6ca06e84c45432afc4bb98b877ba4000d9ef2591</param> + <param name="revision">master</param> <param name="exclude">*</param> <param name="extract">*</param> </service>
View file
_service:tar_scm:gc-8.0.6.tar.gz/BCC_MAKEFILE
Deleted
@@ -1,81 +0,0 @@ -# Makefile for Borland C++ 5.5 on NT -# -bc= c:\Borland\BCC55 -bcbin= $(bc)\bin -bclib= $(bc)\lib -bcinclude= $(bc)\include - -gcinclude1 = .\include - -cc= $(bcbin)\bcc32 -rc= $(bcbin)\brc32 -lib= $(bcbin)\tlib -link= $(bcbin)\ilink32 -cflags= -O2 -R -v- -vi -H -H=gc.csm -I$(bcinclude);$(gcinclude1) -L$(bclib) \ - -w-pro -w-aus -w-par -w-ccc -w-inl -w-rch -a4 -defines= -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION \ - -DENABLE_DISCLAIM -DGC_ATOMIC_UNCOLLECTABLE -DJAVA_FINALIZATION \ - -DGC_GCJ_SUPPORT -DGC_OPERATOR_NEW_ARRAY -DUSE_MUNMAP - -.c.obj: - $(cc) @&&| - $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.c -| - -.cpp.obj: - $(cc) @&&| - $(cdebug) $(cflags) $(cvars) $(defines) -o$* -c $*.cpp -| - -.rc.res: - $(rc) -i$(bcinclude) -r -fo$* $*.rc - -XXXOBJS= XXXalloc.obj XXXreclaim.obj XXXallchblk.obj XXXmisc.obj \ - XXXmach_dep.obj XXXos_dep.obj XXXmark_rts.obj XXXheaders.obj XXXmark.obj \ - XXXobj_map.obj XXXblacklst.obj XXXfinalize.obj XXXnew_hblk.obj \ - XXXdbg_mlc.obj XXXmalloc.obj XXXdyn_load.obj \ - XXXtypd_mlc.obj XXXptr_chck.obj XXXgc_cpp.obj XXXmallocx.obj \ - XXXfnlz_mlc.obj XXXgcj_mlc.obj - -OBJS= $(XXXOBJS:XXX=) - -all: gctest.exe cord\de.exe test_cpp.exe - -$(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h MAKEFILE - -gc.lib: $(OBJS) - -del gc.lib - $(lib) $* @&&| - $(XXXOBJS:XXX=+) -| - -gctest.exe: tests\test.obj gc.lib - $(cc) @&&| - $(cflags) -W -e$* tests\test.obj gc.lib -| - -cord\tests\de.obj cord\tests\de_win.obj: include\cord.h \ - include\cord_pos.h cord\tests\de_win.h cord\tests\de_cmds.h - -cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\tests\de.obj \ - cord\tests\de_win.obj cord\tests\de_win.res gc.lib - $(cc) @&&| - $(cflags) -W -e$* cord\cordbscs.obj cord\cordxtra.obj \ - cord\tests\de.obj cord\tests\de_win.obj gc.lib -| - $(rc) cord\tests\de_win.res cord\de.exe - -gc_cpp.obj: gc_cpp.cc include\gc_cpp.h include\gc.h - -test_cpp.cpp: tests\test_cpp.cc - copy tests\test_cpp.cc test_cpp.cpp - -test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib - $(cc) @&&| - $(cflags) -W -e$* test_cpp.obj gc.lib -| - -clean: - -del *.obj *.res *.exe *.csm cord\*.obj cord\*.res cord\*.exe cord\*.csm - -del cord\*.tds cord\tests\*.obj cord\tests\*.res - -del *.log *.tds gc.lib tests\test.obj "gc.#0*"
View file
_service:tar_scm:gc-8.0.6.tar.gz/gc.mak
Deleted
@@ -1,2239 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Format Version 4.10 -# This has been hand-edited way too many times. -# A clean, manually generated makefile would be an improvement. - -# TARGTYPE "Win32 (x86) Application" 0x0101 -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -!IF "$(CFG)" == "" -CFG=gctest - Win32 Release -!MESSAGE No configuration specified. Defaulting to gctest - Win32 Release. -!ENDIF - -!IF "$(CFG)" != "gc - Win32 Release" && "$(CFG)" != "gc - Win32 Debug" &&\ - "$(CFG)" != "gctest - Win32 Release" && "$(CFG)" != "gctest - Win32 Debug" &&\ - "$(CFG)" != "cord - Win32 Release" && "$(CFG)" != "cord - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE on this makefile -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "gc.mak" CFG="cord - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "gc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "gc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "gctest - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "gctest - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE "cord - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "cord - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF -################################################################################ -# Begin Project -# PROP Target_Last_Scanned "gctest - Win32 Debug" - -!IF "$(CFG)" == "gc - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -OUTDIR=.\Release -INTDIR=.\Release - -ALL : ".\Release\gc.dll" ".\Release\gc.bsc" - -CLEAN : - -@erase ".\Release\allchblk.obj" - -@erase ".\Release\allchblk.sbr" - -@erase ".\Release\alloc.obj" - -@erase ".\Release\alloc.sbr" - -@erase ".\Release\blacklst.obj" - -@erase ".\Release\blacklst.sbr" - -@erase ".\Release\checksums.obj" - -@erase ".\Release\checksums.sbr" - -@erase ".\Release\dbg_mlc.obj" - -@erase ".\Release\dbg_mlc.sbr" - -@erase ".\Release\dyn_load.obj" - -@erase ".\Release\dyn_load.sbr" - -@erase ".\Release\finalize.obj" - -@erase ".\Release\finalize.sbr" - -@erase ".\Release\fnlz_mlc.obj" - -@erase ".\Release\fnlz_mlc.sbr" - -@erase ".\Release\gc.bsc" - -@erase ".\Release\gc_cpp.obj" - -@erase ".\Release\gc_cpp.sbr" - -@erase ".\Release\gc.dll" - -@erase ".\Release\gc.exp" - -@erase ".\Release\gc.lib" - -@erase ".\Release\headers.obj" - -@erase ".\Release\headers.sbr" - -@erase ".\Release\mach_dep.obj" - -@erase ".\Release\mach_dep.sbr" - -@erase ".\Release\malloc.obj" - -@erase ".\Release\malloc.sbr" - -@erase ".\Release\mallocx.obj" - -@erase ".\Release\mallocx.sbr" - -@erase ".\Release\mark.obj" - -@erase ".\Release\mark.sbr" - -@erase ".\Release\mark_rts.obj" - -@erase ".\Release\mark_rts.sbr" - -@erase ".\Release\misc.obj" - -@erase ".\Release\misc.sbr" - -@erase ".\Release\new_hblk.obj" - -@erase ".\Release\new_hblk.sbr" - -@erase ".\Release\obj_map.obj" - -@erase ".\Release\obj_map.sbr" - -@erase ".\Release\os_dep.obj" - -@erase ".\Release\os_dep.sbr" - -@erase ".\Release\ptr_chck.obj" - -@erase ".\Release\ptr_chck.sbr" - -@erase ".\Release\reclaim.obj" - -@erase ".\Release\reclaim.sbr" - -@erase ".\Release\typd_mlc.obj" - -@erase ".\Release\typd_mlc.sbr" - -@erase ".\Release\win32_threads.obj" - -@erase ".\Release\win32_threads.sbr" - -@erase ".\Release\msvc_dbg.copied.obj" - -@erase ".\Release\msvc_dbg.copied.sbr" - -@erase ".\msvc_dbg.copied.c" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -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 "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /FR /YX /c -CPP_PROJ=/nologo /MD /W3 /EHsc /O2 /I include /D "NDEBUG" /D "WIN32"\ - /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "ENABLE_DISCLAIM"\ - /D "GC_ATOMIC_UNCOLLECTABLE" /D "GC_THREADS" /D "JAVA_FINALIZATION"\ - /D "NO_EXECUTE_PERMISSION" /D "_CRT_SECURE_NO_DEPRECATE"\ - /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch"\ - /I./libatomic_ops/src /Fo"$(INTDIR)/" /c -CPP_OBJS=.\Release/ -CPP_SBRS=.\Release/ - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -MTL=mktyplib.exe -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /win32 -MTL_PROJ=/nologo /D "NDEBUG" /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/gc.bsc" -BSC32_SBRS=\ - ".\Release\allchblk.sbr"\ - ".\Release\alloc.sbr"\ - ".\Release\blacklst.sbr"\ - ".\Release\checksums.sbr"\ - ".\Release\dbg_mlc.sbr"\ - ".\Release\dyn_load.sbr"\ - ".\Release\finalize.sbr"\ - ".\Release\fnlz_mlc.sbr"\ - ".\Release\gc_cpp.sbr"\ - ".\Release\headers.sbr"\ - ".\Release\mach_dep.sbr"\ - ".\Release\malloc.sbr"\ - ".\Release\mallocx.sbr"\ - ".\Release\mark.sbr"\ - ".\Release\mark_rts.sbr"\ - ".\Release\misc.sbr"\ - ".\Release\new_hblk.sbr"\ - ".\Release\obj_map.sbr"\ - ".\Release\os_dep.sbr"\ - ".\Release\ptr_chck.sbr"\ - ".\Release\reclaim.sbr"\ - ".\Release\typd_mlc.sbr"\ - ".\Release\msvc_dbg.copied.sbr"\ - ".\Release\win32_threads.sbr" - -".\Release\gc.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ - /pdb:"$(OUTDIR)/gc.pdb" /machine:I386 /out:"$(OUTDIR)/gc.dll"\ - /implib:"$(OUTDIR)/gc.lib" -LINK32_OBJS=\ - ".\Release\allchblk.obj"\ - ".\Release\alloc.obj"\ - ".\Release\blacklst.obj"\ - ".\Release\checksums.obj"\ - ".\Release\dbg_mlc.obj"\ - ".\Release\dyn_load.obj"\ - ".\Release\finalize.obj"\ - ".\Release\fnlz_mlc.obj"\ - ".\Release\gc_cpp.obj"\ - ".\Release\headers.obj"\ - ".\Release\mach_dep.obj"\ - ".\Release\malloc.obj"\ - ".\Release\mallocx.obj"\ - ".\Release\mark.obj"\ - ".\Release\mark_rts.obj"\ - ".\Release\misc.obj"\ - ".\Release\new_hblk.obj"\ - ".\Release\obj_map.obj"\ - ".\Release\os_dep.obj"\ - ".\Release\ptr_chck.obj"\ - ".\Release\reclaim.obj"\ - ".\Release\typd_mlc.obj"\ - ".\Release\msvc_dbg.copied.obj"\ - ".\Release\win32_threads.obj" - -".\Release\gc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -OUTDIR=.\Debug -INTDIR=.\Debug - -ALL : ".\Debug\gc.dll" ".\Debug\gc.bsc" - -CLEAN : - -@erase ".\Debug\allchblk.obj" - -@erase ".\Debug\allchblk.sbr" - -@erase ".\Debug\alloc.obj" - -@erase ".\Debug\alloc.sbr" - -@erase ".\Debug\blacklst.obj" - -@erase ".\Debug\blacklst.sbr" - -@erase ".\Debug\checksums.obj" - -@erase ".\Debug\checksums.sbr" - -@erase ".\Debug\dbg_mlc.obj" - -@erase ".\Debug\dbg_mlc.sbr" - -@erase ".\Debug\dyn_load.obj" - -@erase ".\Debug\dyn_load.sbr" - -@erase ".\Debug\finalize.obj" - -@erase ".\Debug\finalize.sbr" - -@erase ".\Debug\fnlz_mlc.obj" - -@erase ".\Debug\fnlz_mlc.sbr" - -@erase ".\Debug\gc_cpp.obj" - -@erase ".\Debug\gc_cpp.sbr" - -@erase ".\Debug\gc.bsc" - -@erase ".\Debug\gc.dll" - -@erase ".\Debug\gc.exp" - -@erase ".\Debug\gc.lib" - -@erase ".\Debug\gc.map" - -@erase ".\Debug\gc.pdb" - -@erase ".\Debug\headers.obj" - -@erase ".\Debug\headers.sbr" - -@erase ".\Debug\mach_dep.obj" - -@erase ".\Debug\mach_dep.sbr" - -@erase ".\Debug\malloc.obj" - -@erase ".\Debug\malloc.sbr" - -@erase ".\Debug\mallocx.obj" - -@erase ".\Debug\mallocx.sbr" - -@erase ".\Debug\mark.obj" - -@erase ".\Debug\mark.sbr" - -@erase ".\Debug\mark_rts.obj" - -@erase ".\Debug\mark_rts.sbr" - -@erase ".\Debug\misc.obj" - -@erase ".\Debug\misc.sbr" - -@erase ".\Debug\new_hblk.obj" - -@erase ".\Debug\new_hblk.sbr" - -@erase ".\Debug\obj_map.obj" - -@erase ".\Debug\obj_map.sbr" - -@erase ".\Debug\os_dep.obj" - -@erase ".\Debug\os_dep.sbr" - -@erase ".\Debug\ptr_chck.obj" - -@erase ".\Debug\ptr_chck.sbr" - -@erase ".\Debug\reclaim.obj" - -@erase ".\Debug\reclaim.sbr" - -@erase ".\Debug\typd_mlc.obj" - -@erase ".\Debug\typd_mlc.sbr" - -@erase ".\Debug\vc40.idb" - -@erase ".\Debug\vc40.pdb" - -@erase ".\Debug\win32_threads.obj" - -@erase ".\Debug\win32_threads.sbr" - -@erase ".\Debug\msvc_dbg.copied.obj" - -@erase ".\Debug\msvc_dbg.copied.sbr" - -@erase ".\msvc_dbg.copied.c" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -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 "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "GC_THREADS" /FR /YX /c -CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /I include /D "_DEBUG"\ - /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /D "ENABLE_DISCLAIM"\ - /D "GC_ASSERTIONS" /D "GC_ATOMIC_UNCOLLECTABLE" /D "GC_THREADS"\ - /D "JAVA_FINALIZATION" /D "NO_EXECUTE_PERMISSION"\ - /D "_CRT_SECURE_NO_DEPRECATE" /FR"$(INTDIR)/" /Fp"$(INTDIR)/gc.pch"\ - /Fo"$(INTDIR)/" /I./libatomic_ops/src /Fd"$(INTDIR)/" /c -CPP_OBJS=.\Debug/ -CPP_SBRS=.\Debug/ - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -MTL=mktyplib.exe -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /win32 -MTL_PROJ=/nologo /D "_DEBUG" /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/gc.bsc" -BSC32_SBRS=\ - ".\Debug\allchblk.sbr"\ - ".\Debug\alloc.sbr"\ - ".\Debug\blacklst.sbr"\ - ".\Debug\checksums.sbr"\ - ".\Debug\dbg_mlc.sbr"\ - ".\Debug\dyn_load.sbr"\ - ".\Debug\finalize.sbr"\ - ".\Debug\fnlz_mlc.sbr"\ - ".\Debug\gc_cpp.sbr"\ - ".\Debug\headers.sbr"\ - ".\Debug\mach_dep.sbr"\ - ".\Debug\malloc.sbr"\ - ".\Debug\mallocx.sbr"\ - ".\Debug\mark.sbr"\ - ".\Debug\mark_rts.sbr"\ - ".\Debug\misc.sbr"\ - ".\Debug\new_hblk.sbr"\ - ".\Debug\obj_map.sbr"\ - ".\Debug\os_dep.sbr"\ - ".\Debug\ptr_chck.sbr"\ - ".\Debug\reclaim.sbr"\ - ".\Debug\typd_mlc.sbr"\ - ".\Debug\msvc_dbg.copied.sbr"\ - ".\Debug\win32_threads.sbr" - -".\Debug\gc.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ - /pdb:"$(OUTDIR)/gc.pdb" /map:"$(INTDIR)/gc.map" /debug /machine:I386\ - /out:"$(OUTDIR)/gc.dll" /implib:"$(OUTDIR)/gc.lib" -LINK32_OBJS=\ - ".\Debug\allchblk.obj"\ - ".\Debug\alloc.obj"\ - ".\Debug\blacklst.obj"\ - ".\Debug\checksums.obj"\ - ".\Debug\dbg_mlc.obj"\ - ".\Debug\dyn_load.obj"\ - ".\Debug\finalize.obj"\ - ".\Debug\fnlz_mlc.obj"\ - ".\Debug\gc_cpp.obj"\ - ".\Debug\headers.obj"\ - ".\Debug\mach_dep.obj"\ - ".\Debug\malloc.obj"\ - ".\Debug\mallocx.obj"\ - ".\Debug\mark.obj"\ - ".\Debug\mark_rts.obj"\ - ".\Debug\misc.obj"\ - ".\Debug\new_hblk.obj"\ - ".\Debug\obj_map.obj"\ - ".\Debug\os_dep.obj"\ - ".\Debug\ptr_chck.obj"\ - ".\Debug\reclaim.obj"\ - ".\Debug\typd_mlc.obj"\ - ".\Debug\msvc_dbg.copied.obj"\ - ".\Debug\win32_threads.obj" - -".\Debug\gc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "gctest - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "gctest\Release" -# PROP BASE Intermediate_Dir "gctest\Release" -# PROP BASE Target_Dir "gctest" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "gctest\Release" -# PROP Intermediate_Dir "gctest\Release" -# PROP Target_Dir "gctest" -OUTDIR=.\gctest\Release -INTDIR=.\gctest\Release - -ALL : "gc - Win32 Release" ".\Release\gctest.exe" - -CLEAN : - -@erase ".\gctest\Release\test.copied.obj" - -@erase ".\test.copied.c" - -@erase ".\Release\gctest.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -test.copied.c : tests\test.c - copy tests\test.c test.copied.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 "GC_THREADS" /YX /c -CPP_PROJ=/nologo /MD /W3 /EHsc /O2 /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS"\ - /D "ALL_INTERIOR_POINTERS" /D "ENABLE_DISCLAIM" /D "GC_THREADS"\ - /D "_CRT_SECURE_NO_DEPRECATE" /I./libatomic_ops/src /Fp"$(INTDIR)/gctest.pch"\ - /Fo"$(INTDIR)/" /c -CPP_OBJS=.\gctest\Release/ -CPP_SBRS=.\. - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -MTL=mktyplib.exe -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /win32 -MTL_PROJ=/nologo /D "NDEBUG" /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/gctest.bsc" -BSC32_SBRS=\ - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/gctest.exe" -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib /nologo /subsystem:windows /incremental:no\ - /pdb:"$(OUTDIR)/gctest.pdb" /machine:I386 /out:"Release/gctest.exe" -LINK32_OBJS=\ - ".\gctest\Release\test.copied.obj"\ - ".\Release\gc.lib" - -".\Release\gctest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "gctest - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "gctest\Debug" -# PROP BASE Intermediate_Dir "gctest\Debug" -# PROP BASE Target_Dir "gctest" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "gctest\Debug" -# PROP Intermediate_Dir "gctest\Debug" -# PROP Target_Dir "gctest" -OUTDIR=.\gctest\Debug -INTDIR=.\gctest\Debug - -ALL : "gc - Win32 Debug" ".\Debug\gctest.exe" ".\gctest\Debug\gctest.bsc" - -CLEAN : - -@erase ".\Debug\gctest.exe" - -@erase ".\gctest\Debug\gctest.bsc" - -@erase ".\gctest\Debug\gctest.map" - -@erase ".\gctest\Debug\gctest.pdb" - -@erase ".\gctest\Debug\test.copied.obj" - -@erase ".\gctest\Debug\test.copied.sbr" - -@erase ".\test.copied.c" - -@erase ".\gctest\Debug\vc40.idb" - -@erase ".\gctest\Debug\vc40.pdb" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -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 "GC_THREADS" /FR /YX /c -CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\ - /D "ALL_INTERIOR_POINTERS" /D "ENABLE_DISCLAIM" /D "GC_THREADS"\ - /D "_CRT_SECURE_NO_DEPRECATE" /FR"$(INTDIR)/"\ - /I./libatomic_ops/src /Fp"$(INTDIR)/gctest.pch" /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c -CPP_OBJS=.\gctest\Debug/ -CPP_SBRS=.\gctest\Debug/ - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -MTL=mktyplib.exe -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /win32 -MTL_PROJ=/nologo /D "_DEBUG" /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/gctest.bsc" -BSC32_SBRS=\ - ".\gctest\Debug\test.copied.sbr" - -".\gctest\Debug\gctest.bsc" : "$(OUTDIR)" $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no /map /debug /machine:I386 /out:"Debug/gctest.exe" -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib /nologo /subsystem:windows /incremental:no\ - /pdb:"$(OUTDIR)/gctest.pdb" /map:"$(INTDIR)/gctest.map" /debug /machine:I386\ - /out:"Debug/gctest.exe" -LINK32_OBJS=\ - ".\Debug\gc.lib"\ - ".\gctest\Debug\test.copied.obj" - -".\Debug\gctest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "cord - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "cord\Release" -# PROP BASE Intermediate_Dir "cord\Release" -# PROP BASE Target_Dir "cord" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "cord\Release" -# PROP Intermediate_Dir "cord\Release" -# PROP Target_Dir "cord" -OUTDIR=.\cord\Release -INTDIR=.\cord\Release - -ALL : "gc - Win32 Release" ".\Release\de.exe" - -CLEAN : - -@erase ".\cord\Release\cordbscs.obj" - -@erase ".\cord\Release\cordxtra.obj" - -@erase ".\cord\Release\de.obj" - -@erase ".\cord\Release\de_win.obj" - -@erase ".\cord\Release\de_win.res" - -@erase ".\Release\de.exe" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -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 "." /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /YX /c -CPP_PROJ=/nologo /MD /W3 /EHsc /O2 /I "." /I include /D "NDEBUG" /D "WIN32" /D "_WINDOWS"\ - /D "ALL_INTERIOR_POINTERS" /D "ENABLE_DISCLAIM"\ - /I./libatomic_ops/src /Fp"$(INTDIR)/cord.pch" /Fo"$(INTDIR)/" /c -CPP_OBJS=.\cord\Release/ -CPP_SBRS=.\. - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -MTL=mktyplib.exe -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /win32 -MTL_PROJ=/nologo /D "NDEBUG" /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -RSC_PROJ=/l 0x809 /fo"$(INTDIR)/de_win.res" /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/cord.bsc" -BSC32_SBRS=\ - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/de.exe" -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)/de.pdb"\ - /machine:I386 /out:"Release/de.exe" -LINK32_OBJS=\ - ".\cord\Release\cordbscs.obj"\ - ".\cord\Release\cordxtra.obj"\ - ".\cord\Release\de.obj"\ - ".\cord\Release\de_win.obj"\ - ".\cord\Release\de_win.res"\ - ".\Release\gc.lib" - -".\Release\de.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "cord\Debug" -# PROP BASE Intermediate_Dir "cord\Debug" -# PROP BASE Target_Dir "cord" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "cord\Debug" -# PROP Intermediate_Dir "cord\Debug" -# PROP Target_Dir "cord" -OUTDIR=.\cord\Debug -INTDIR=.\cord\Debug - -ALL : "gc - Win32 Debug" ".\Debug\de.exe" - -CLEAN : - -@erase ".\cord\Debug\cordbscs.obj" - -@erase ".\cord\Debug\cordxtra.obj" - -@erase ".\cord\Debug\de.obj" - -@erase ".\cord\Debug\de.pdb" - -@erase ".\cord\Debug\de_win.obj" - -@erase ".\cord\Debug\de_win.res" - -@erase ".\cord\Debug\vc40.idb" - -@erase ".\cord\Debug\vc40.pdb" - -@erase ".\Debug\de.exe" - -@erase ".\Debug\de.ilk" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -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 /I "." /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ALL_INTERIOR_POINTERS" /YX /c -CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /I "." /I include /D "_DEBUG" /D "WIN32" /D "_WINDOWS"\ - /D "ALL_INTERIOR_POINTERS" /D "ENABLE_DISCLAIM" /Fp"$(INTDIR)/cord.pch"\ - /I./libatomic_ops/src /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c -CPP_OBJS=.\cord\Debug/ -CPP_SBRS=.\. - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.c{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_SBRS)}.sbr: - $(CPP) $(CPP_PROJ) $< - -MTL=mktyplib.exe -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /win32 -MTL_PROJ=/nologo /D "_DEBUG" /win32 -RSC=rc.exe -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -RSC_PROJ=/l 0x809 /fo"$(INTDIR)/de_win.res" /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o"$(OUTDIR)/cord.bsc" -BSC32_SBRS=\ - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/de.exe" -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ - odbccp32.lib /nologo /subsystem:windows /incremental:yes\ - /pdb:"$(OUTDIR)/de.pdb" /debug /machine:I386 /out:"Debug/de.exe" -LINK32_OBJS=\ - ".\cord\Debug\cordbscs.obj"\ - ".\cord\Debug\cordxtra.obj"\ - ".\cord\Debug\de.obj"\ - ".\cord\Debug\de_win.obj"\ - ".\cord\Debug\de_win.res"\ - ".\Debug\gc.lib" - -".\Debug\de.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -################################################################################ -# Begin Target - -# Name "gc - Win32 Release" -# Name "gc - Win32 Debug" - -!IF "$(CFG)" == "gc - Win32 Release" - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -!ENDIF - -################################################################################ -# Begin Source File - -SOURCE=.\gc_cpp.cpp - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_RECLA=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - ".\include\gc_cpp.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_RECLA=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\gc_cpp.obj" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - -".\Release\gc_cpp.sbr" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_RECLA=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - ".\include\gc_cpp.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_RECLA=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\gc_cpp.obj" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - -".\Debug\gc_cpp.sbr" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\reclaim.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_RECLA=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_RECLA=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\reclaim.obj" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - -".\Release\reclaim.sbr" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_RECLA=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_RECLA=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\reclaim.obj" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - -".\Debug\reclaim.sbr" : $(SOURCE) $(DEP_CPP_RECLA) "$(INTDIR)" - - -!ENDIF - -# End Source File - -################################################################################ -# Begin Source File - -SOURCE=.\os_dep.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_OS_DE=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\STAT.H"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_OS_DE=\ - ".\il\PCR_IL.h"\ - ".\mm\PCR_MM.h"\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - ".\vd\PCR_VD.h"\ - - -".\Release\os_dep.obj" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)" - -".\Release\os_dep.sbr" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_OS_DE=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\STAT.H"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_OS_DE=\ - ".\il\PCR_IL.h"\ - ".\mm\PCR_MM.h"\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - ".\vd\PCR_VD.h"\ - - -".\Debug\os_dep.obj" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)" - -".\Debug\os_dep.sbr" : $(SOURCE) $(DEP_CPP_OS_DE) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\misc.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_MISC_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MISC_=\ - ".\il\PCR_IL.h"\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\misc.obj" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)" - -".\Release\misc.sbr" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_MISC_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MISC_=\ - ".\il\PCR_IL.h"\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\misc.obj" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)" - -".\Debug\misc.sbr" : $(SOURCE) $(DEP_CPP_MISC_) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\mark_rts.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_MARK_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MARK_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\mark_rts.obj" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)" - -".\Release\mark_rts.sbr" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_MARK_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MARK_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\mark_rts.obj" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)" - -".\Debug\mark_rts.sbr" : $(SOURCE) $(DEP_CPP_MARK_) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\mach_dep.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_MACH_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MACH_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\mach_dep.obj" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)" - -".\Release\mach_dep.sbr" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_MACH_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MACH_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\mach_dep.obj" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)" - -".\Debug\mach_dep.sbr" : $(SOURCE) $(DEP_CPP_MACH_) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\headers.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_HEADE=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_HEADE=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\headers.obj" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)" - -".\Release\headers.sbr" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_HEADE=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_HEADE=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\headers.obj" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)" - -".\Debug\headers.sbr" : $(SOURCE) $(DEP_CPP_HEADE) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\alloc.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_ALLOC=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_ALLOC=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\alloc.obj" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)" - -".\Release\alloc.sbr" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_ALLOC=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_ALLOC=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\alloc.obj" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)" - -".\Debug\alloc.sbr" : $(SOURCE) $(DEP_CPP_ALLOC) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\allchblk.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_ALLCH=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_ALLCH=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\allchblk.obj" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)" - -".\Release\allchblk.sbr" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_ALLCH=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_ALLCH=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\allchblk.obj" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)" - -".\Debug\allchblk.sbr" : $(SOURCE) $(DEP_CPP_ALLCH) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\obj_map.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_OBJ_M=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_OBJ_M=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\obj_map.obj" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)" - -".\Release\obj_map.sbr" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_OBJ_M=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_OBJ_M=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\obj_map.obj" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)" - -".\Debug\obj_map.sbr" : $(SOURCE) $(DEP_CPP_OBJ_M) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\new_hblk.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_NEW_H=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_NEW_H=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\new_hblk.obj" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)" - -".\Release\new_hblk.sbr" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_NEW_H=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_NEW_H=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\new_hblk.obj" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)" - -".\Debug\new_hblk.sbr" : $(SOURCE) $(DEP_CPP_NEW_H) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\mark.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_MARK_C=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MARK_C=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\mark.obj" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)" - -".\Release\mark.sbr" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_MARK_C=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MARK_C=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\mark.obj" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)" - -".\Debug\mark.sbr" : $(SOURCE) $(DEP_CPP_MARK_C) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\malloc.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_MALLO=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MALLO=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\malloc.obj" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)" - -".\Release\malloc.sbr" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_MALLO=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MALLO=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\malloc.obj" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)" - -".\Debug\malloc.sbr" : $(SOURCE) $(DEP_CPP_MALLO) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\mallocx.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_MALLX=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MALLX=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\mallocx.obj" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)" - -".\Release\mallocx.sbr" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_MALLX=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_MALLX=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\mallocx.obj" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)" - -".\Debug\mallocx.sbr" : $(SOURCE) $(DEP_CPP_MALLX) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\finalize.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_FINAL=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_FINAL=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\finalize.obj" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)" - -".\Release\finalize.sbr" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_FINAL=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_FINAL=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\finalize.obj" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)" - -".\Debug\finalize.sbr" : $(SOURCE) $(DEP_CPP_FINAL) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\dbg_mlc.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_DBG_M=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_DBG_M=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\dbg_mlc.obj" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - -".\Release\dbg_mlc.sbr" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_DBG_M=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_DBG_M=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\dbg_mlc.obj" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - -".\Debug\dbg_mlc.sbr" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\fnlz_mlc.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_DBG_M=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_DBG_M=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\fnlz_mlc.obj" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - -".\Release\fnlz_mlc.sbr" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_DBG_M=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_DBG_M=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\fnlz_mlc.obj" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - -".\Debug\fnlz_mlc.sbr" : $(SOURCE) $(DEP_CPP_DBG_M) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\blacklst.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_BLACK=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_BLACK=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\blacklst.obj" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)" - -".\Release\blacklst.sbr" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_BLACK=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_BLACK=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\blacklst.obj" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)" - -".\Debug\blacklst.sbr" : $(SOURCE) $(DEP_CPP_BLACK) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\typd_mlc.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_TYPD_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - ".\include\gc_typed.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_TYPD_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\typd_mlc.obj" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)" - -".\Release\typd_mlc.sbr" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_TYPD_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - ".\include\gc_typed.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_TYPD_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\typd_mlc.obj" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)" - -".\Debug\typd_mlc.sbr" : $(SOURCE) $(DEP_CPP_TYPD_) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ptr_chck.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_PTR_C=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_PTR_C=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\ptr_chck.obj" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)" - -".\Release\ptr_chck.sbr" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_PTR_C=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_pmark.h"\ - ".\include\gc_mark.h"\ - ".\include\gc_disclaim.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_PTR_C=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\ptr_chck.obj" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)" - -".\Debug\ptr_chck.sbr" : $(SOURCE) $(DEP_CPP_PTR_C) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\dyn_load.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_DYN_L=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\STAT.H"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_DYN_L=\ - ".\il\PCR_IL.h"\ - ".\mm\PCR_MM.h"\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\dyn_load.obj" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)" - -".\Release\dyn_load.sbr" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_DYN_L=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\STAT.H"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_DYN_L=\ - ".\il\PCR_IL.h"\ - ".\mm\PCR_MM.h"\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\dyn_load.obj" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)" - -".\Debug\dyn_load.sbr" : $(SOURCE) $(DEP_CPP_DYN_L) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\win32_threads.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_WIN32=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_WIN32=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\win32_threads.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - -".\Release\win32_threads.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_WIN32=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_WIN32=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\win32_threads.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - -".\Debug\win32_threads.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\extra\msvc_dbg.c - -msvc_dbg.copied.c : extra\msvc_dbg.c - copy extra\msvc_dbg.c msvc_dbg.copied.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_WIN32=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - ".\include\private\msvc_dbg.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_WIN32=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\msvc_dbg.copied.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - -".\Release\msvc_dbg.copied.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_WIN32=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - ".\include\private\msvc_dbg.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_WIN32=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\msvc_dbg.copied.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - -".\Debug\msvc_dbg.copied.sbr" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)" - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\checksums.c - -!IF "$(CFG)" == "gc - Win32 Release" - -DEP_CPP_CHECK=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_CHECK=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Release\checksums.obj" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)" - -".\Release\checksums.sbr" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gc - Win32 Debug" - -DEP_CPP_CHECK=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_CHECK=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -".\Debug\checksums.obj" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)" - -".\Debug\checksums.sbr" : $(SOURCE) $(DEP_CPP_CHECK) "$(INTDIR)" - - -!ENDIF - -# End Source File -# End Target -################################################################################ -# Begin Target - -# Name "gctest - Win32 Release" -# Name "gctest - Win32 Debug" - -!IF "$(CFG)" == "gctest - Win32 Release" - -!ELSEIF "$(CFG)" == "gctest - Win32 Debug" - -!ENDIF - -################################################################################ -# Begin Project Dependency - -# Project_Dep_Name "gc" - -!IF "$(CFG)" == "gctest - Win32 Release" - -"gc - Win32 Release" : - $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Release" - -!ELSEIF "$(CFG)" == "gctest - Win32 Debug" - -"gc - Win32 Debug" : - $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Debug" - -!ENDIF - -# End Project Dependency -################################################################################ -# Begin Source File - -SOURCE=.\tests\test.c -DEP_CPP_TEST_=\ - ".\include\private\gcconfig.h"\ - ".\include\gc.h"\ - ".\include\private\gc_hdrs.h"\ - ".\include\private\gc_priv.h"\ - ".\include\gc_typed.h"\ - {$(INCLUDE)}"\sys\TYPES.H"\ - -NODEP_CPP_TEST_=\ - ".\th\PCR_Th.h"\ - ".\th\PCR_ThCrSec.h"\ - ".\th\PCR_ThCtl.h"\ - - -!IF "$(CFG)" == "gctest - Win32 Release" - - -".\gctest\Release\test.copied.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "gctest - Win32 Debug" - - -".\gctest\Debug\test.copied.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" - -".\gctest\Debug\test.copied.sbr" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" - - -!ENDIF - -# End Source File -# End Target -################################################################################ -# Begin Target - -# Name "cord - Win32 Release" -# Name "cord - Win32 Debug" - -!IF "$(CFG)" == "cord - Win32 Release" - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - -!ENDIF - -################################################################################ -# Begin Project Dependency - -# Project_Dep_Name "gc" - -!IF "$(CFG)" == "cord - Win32 Release" - -"gc - Win32 Release" : - $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Release" - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - -"gc - Win32 Debug" : - $(MAKE) /$(MAKEFLAGS) /F ".\gc.mak" CFG="gc - Win32 Debug" - -!ENDIF - -# End Project Dependency -################################################################################ -# Begin Source File - -SOURCE=.\cord\tests\de_win.c -DEP_CPP_DE_WI=\ - ".\include\cord.h"\ - ".\cord\tests\de_cmds.h"\ - ".\cord\tests\de_win.h"\ - ".\include\cord_pos.h"\ - -NODEP_CPP_DE_WI=\ - ".\include\gc.h"\ - - -!IF "$(CFG)" == "cord - Win32 Release" - - -".\cord\Release\de_win.obj" : $(SOURCE) $(DEP_CPP_DE_WI) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - - -".\cord\Debug\de_win.obj" : $(SOURCE) $(DEP_CPP_DE_WI) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\cord\tests\de.c -DEP_CPP_DE_C2e=\ - ".\include\cord.h"\ - ".\cord\tests\de_cmds.h"\ - ".\cord\tests\de_win.h"\ - ".\include\cord_pos.h"\ - -NODEP_CPP_DE_C2e=\ - ".\include\gc.h"\ - - -!IF "$(CFG)" == "cord - Win32 Release" - - -".\cord\Release\de.obj" : $(SOURCE) $(DEP_CPP_DE_C2e) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - - -".\cord\Debug\de.obj" : $(SOURCE) $(DEP_CPP_DE_C2e) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\cord\cordxtra.c -DEP_CPP_CORDX=\ - ".\include\cord.h"\ - ".\include\ec.h"\ - ".\include\cord_pos.h"\ - -NODEP_CPP_CORDX=\ - ".\include\gc.h"\ - - -!IF "$(CFG)" == "cord - Win32 Release" - - -".\cord\Release\cordxtra.obj" : $(SOURCE) $(DEP_CPP_CORDX) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - - -".\cord\Debug\cordxtra.obj" : $(SOURCE) $(DEP_CPP_CORDX) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\cord\cordbscs.c -DEP_CPP_CORDB=\ - ".\include\cord.h"\ - ".\include\cord_pos.h"\ - -NODEP_CPP_CORDB=\ - ".\include\gc.h"\ - - -!IF "$(CFG)" == "cord - Win32 Release" - - -".\cord\Release\cordbscs.obj" : $(SOURCE) $(DEP_CPP_CORDB) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - - -".\cord\Debug\cordbscs.obj" : $(SOURCE) $(DEP_CPP_CORDB) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\cord\tests\de_win.rc - -!IF "$(CFG)" == "cord - Win32 Release" - - -".\cord\Release\de_win.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)/de_win.res" /i "cord" /d "NDEBUG" $(SOURCE) - - -!ELSEIF "$(CFG)" == "cord - Win32 Debug" - - -".\cord\Debug\de_win.res" : $(SOURCE) "$(INTDIR)" - $(RSC) /l 0x809 /fo"$(INTDIR)/de_win.res" /i "cord" /d "_DEBUG" $(SOURCE) - - -!ENDIF - -# End Source File -# End Target -# End Project -################################################################################
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_alloc_ptrs.h
Deleted
@@ -1,40 +0,0 @@ -/* - * Copyright (c) 1996-1998 by Silicon Graphics. 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 file should never be included by clients directly. */ - -#ifndef GC_ALLOC_PTRS_H -#define GC_ALLOC_PTRS_H - -#include "gc.h" - -#ifdef __cplusplus - extern "C" { -#endif - -GC_API void ** const GC_objfreelist_ptr; -GC_API void ** const GC_aobjfreelist_ptr; -GC_API void ** const GC_uobjfreelist_ptr; - -#ifdef GC_ATOMIC_UNCOLLECTABLE - GC_API void ** const GC_auobjfreelist_ptr; -#endif - -GC_API void GC_CALL GC_incr_bytes_allocd(size_t bytes); -GC_API void GC_CALL GC_incr_bytes_freed(size_t bytes); - -#ifdef __cplusplus - } /* extern "C" */ -#endif - -#endif /* GC_ALLOC_PTRS_H */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/new_gc_alloc.h
Deleted
@@ -1,517 +0,0 @@ -/* - * Copyright (c) 1996-1998 by Silicon Graphics. 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 is a revision of gc_allocator.h for SGI STL versions > 3.0. -// Unlike earlier versions, it supplements the standard (STL) alloc.h -// instead of replacing it. -// -// This is sloppy about variable names used in header files. -// It also doesn't yet understand the new header file names or -// namespaces. -// -// This assumes the collector has been compiled with -DGC_ATOMIC_UNCOLLECTABLE. -// The user should also consider -DREDIRECT_MALLOC=GC_uncollectable_malloc, -// to ensure that object allocated through malloc are traced. -// -// Some of this could be faster in the explicit deallocation case. -// In particular, we spend too much time clearing objects on the -// free lists. That could be avoided. -// -// This uses template classes with static members, and hence does not work -// with g++ 2.7.2 and earlier. -// -// Unlike its predecessor, this one simply defines -// gc_alloc -// single_client_gc_alloc -// traceable_alloc -// single_client_traceable_alloc -// -// It does not redefine alloc. Nor does it change the default allocator, -// though the user may wish to do so. (The argument against changing -// the default allocator is that it may introduce subtle link compatibility -// problems. The argument for changing it is that the usual default -// allocator is usually a very bad choice for a garbage collected environment.) -// - -#ifndef GC_NEW_ALLOC_H -#define GC_NEW_ALLOC_H - -#include "gc.h" - -#if GC_GNUC_PREREQ(3, 0) -# 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 -#else -# include <stack> // A more portable way to get stl_alloc.h file. -#endif - -/* A hack to deal with gcc 3.1. If you are using gcc3.1 and later, */ -/* you should probably really use gc_allocator.h instead. */ -#if GC_GNUC_PREREQ(3, 1) -# define simple_alloc __simple_alloc -#endif - -#include <stddef.h> -#include <string.h> - -// We can't include gc_priv.h, since that pulls in way too much stuff. -#include "gc_alloc_ptrs.h" - -#include "gc_mark.h" // for GC_generic_malloc - -#define GC_generic_malloc_words_small(lw, k) \ - GC_generic_malloc((lw) * sizeof(GC_word), k) - -#define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() - -// Object kinds; must match PTRFREE, NORMAL, UNCOLLECTABLE, and -// AUNCOLLECTABLE in gc_priv.h. - -enum { GC_PTRFREE = 0, GC_NORMAL = 1, GC_UNCOLLECTABLE = 2, - GC_AUNCOLLECTABLE = 3 }; - -enum { GC_max_fast_bytes = 255 }; - -enum { GC_byte_alignment = 8 }; - -#if defined(CPPCHECK) - const unsigned GC_bytes_per_word = sizeof(char *); - const unsigned GC_word_alignment = GC_byte_alignment/GC_bytes_per_word; -#else - enum { GC_bytes_per_word = sizeof(char *) }; - enum { GC_word_alignment = GC_byte_alignment/GC_bytes_per_word }; -#endif - -inline void * &GC_obj_link(void * p) -{ return *reinterpret_cast<void **>(p); } - -// Compute a number of words >= n+1 bytes. -// The +1 allows for pointers one past the end. -inline size_t GC_round_up(size_t n) -{ - return ((n + GC_byte_alignment)/GC_byte_alignment)*GC_word_alignment; -} - -// The same but don't allow for extra byte. -inline size_t GC_round_up_uncollectable(size_t n) -{ - return ((n + GC_byte_alignment - 1)/GC_byte_alignment)*GC_word_alignment; -} - -template <int dummy> -class GC_aux_template { -public: - // File local count of allocated words. Occasionally this is - // added into the global count. A separate count is necessary since the - // real one must be updated with a procedure call. - static size_t GC_bytes_recently_allocd; - - // Same for uncollectible memory. Not yet reflected in either - // GC_bytes_recently_allocd or GC_non_gc_bytes. - static size_t GC_uncollectable_bytes_recently_allocd; - - // Similar counter for explicitly deallocated memory. - static size_t GC_bytes_recently_freed; - - // Again for uncollectible memory. - static size_t GC_uncollectable_bytes_recently_freed; - - static void * GC_out_of_line_malloc(size_t nwords, int kind); -}; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_bytes_recently_allocd = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_uncollectable_bytes_recently_allocd = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_bytes_recently_freed = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_uncollectable_bytes_recently_freed = 0; - -template <int dummy> -void * GC_aux_template<dummy>::GC_out_of_line_malloc(size_t nwords, int kind) -{ - void * op = GC_generic_malloc_words_small(nwords, kind); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - - GC_word non_gc_bytes = GC_get_non_gc_bytes(); - GC_bytes_recently_allocd += GC_uncollectable_bytes_recently_allocd; - non_gc_bytes += GC_uncollectable_bytes_recently_allocd; - GC_uncollectable_bytes_recently_allocd = 0; - - GC_bytes_recently_freed += GC_uncollectable_bytes_recently_freed; - non_gc_bytes -= GC_uncollectable_bytes_recently_freed; - GC_uncollectable_bytes_recently_freed = 0; - GC_set_non_gc_bytes(non_gc_bytes); - - GC_incr_bytes_allocd(GC_bytes_recently_allocd); - GC_bytes_recently_allocd = 0; - - GC_incr_bytes_freed(GC_bytes_recently_freed); - GC_bytes_recently_freed = 0; - return op; -} - -typedef GC_aux_template<0> GC_aux; - -// A fast, single-threaded, garbage-collected allocator -// We assume the first word will be immediately overwritten. -// In this version, deallocation is not a no-op, and explicit -// deallocation is likely to help performance. -template <int dummy> -class single_client_gc_alloc_template { - public: - static void * allocate(size_t n) - { - size_t nwords = GC_round_up(n); - void ** flh; - void * op; - - if (n > GC_max_fast_bytes) { - op = GC_malloc(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - flh = &GC_objfreelist_ptrnwords; - op = *flh; - if (0 == op) { - return GC_aux::GC_out_of_line_malloc(nwords, GC_NORMAL); - } - *flh = GC_obj_link(op); - GC_aux::GC_bytes_recently_allocd += nwords * GC_bytes_per_word; - return op; - } - static void * ptr_free_allocate(size_t n) - { - size_t nwords = GC_round_up(n); - void ** flh; - void * op; - - if (n > GC_max_fast_bytes) { - op = GC_malloc_atomic(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - flh = &GC_aobjfreelist_ptrnwords; - op = *flh; - if (0 == op) { - return GC_aux::GC_out_of_line_malloc(nwords, GC_PTRFREE); - } - *flh = GC_obj_link(op); - GC_aux::GC_bytes_recently_allocd += nwords * GC_bytes_per_word; - return op; - } - static void deallocate(void *p, size_t n) - { - if (n > GC_max_fast_bytes) { - GC_free(p); - } else { - size_t nwords = GC_round_up(n); - void ** flh = &GC_objfreelist_ptrnwords; - - GC_obj_link(p) = *flh; - memset(reinterpret_cast<char *>(p) + GC_bytes_per_word, 0, - GC_bytes_per_word * (nwords - 1)); - *flh = p; - GC_aux::GC_bytes_recently_freed += nwords * GC_bytes_per_word; - } - } - static void ptr_free_deallocate(void *p, size_t n) - { - if (n > GC_max_fast_bytes) { - GC_free(p); - } else { - size_t nwords = GC_round_up(n); - void ** flh = &GC_aobjfreelist_ptrnwords; - - GC_obj_link(p) = *flh; - *flh = p; - GC_aux::GC_bytes_recently_freed += nwords * GC_bytes_per_word; - } - } -}; - -typedef single_client_gc_alloc_template<0> single_client_gc_alloc; - -// Once more, for uncollectible objects. -template <int dummy> -class single_client_traceable_alloc_template { - public: - static void * allocate(size_t n) - { - size_t nwords = GC_round_up_uncollectable(n); - void ** flh; - void * op; - - if (n > GC_max_fast_bytes) { - op = GC_malloc_uncollectable(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - flh = &GC_uobjfreelist_ptrnwords; - op = *flh; - if (0 == op) { - return GC_aux::GC_out_of_line_malloc(nwords, GC_UNCOLLECTABLE); - } - *flh = GC_obj_link(op); - GC_aux::GC_uncollectable_bytes_recently_allocd += - nwords * GC_bytes_per_word; - return op; - } - static void * ptr_free_allocate(size_t n) - { - size_t nwords = GC_round_up_uncollectable(n); - void ** flh; - void * op; - - if (n > GC_max_fast_bytes) { - op = GC_malloc_atomic_uncollectable(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - flh = &GC_auobjfreelist_ptrnwords; - op = *flh; - if (0 == op) { - return GC_aux::GC_out_of_line_malloc(nwords, GC_AUNCOLLECTABLE); - } - *flh = GC_obj_link(op); - GC_aux::GC_uncollectable_bytes_recently_allocd += - nwords * GC_bytes_per_word; - return op; - } - static void deallocate(void *p, size_t n) - { - if (n > GC_max_fast_bytes) { - GC_free(p); - } else { - size_t nwords = GC_round_up_uncollectable(n); - void ** flh = &GC_uobjfreelist_ptrnwords; - - GC_obj_link(p) = *flh; - *flh = p; - GC_aux::GC_uncollectable_bytes_recently_freed += - nwords * GC_bytes_per_word; - } - } - static void ptr_free_deallocate(void *p, size_t n) - { - if (n > GC_max_fast_bytes) { - GC_free(p); - } else { - size_t nwords = GC_round_up_uncollectable(n); - void ** flh = &GC_auobjfreelist_ptrnwords; - - GC_obj_link(p) = *flh; - *flh = p; - GC_aux::GC_uncollectable_bytes_recently_freed += - nwords * GC_bytes_per_word; - } - } -}; - -typedef single_client_traceable_alloc_template<0> single_client_traceable_alloc; - -template < int dummy > -class gc_alloc_template { - public: - static void * allocate(size_t n) { - void * op = GC_malloc(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - static void * ptr_free_allocate(size_t n) { - void * op = GC_malloc_atomic(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - static void deallocate(void *, size_t) { } - static void ptr_free_deallocate(void *, size_t) { } -}; - -typedef gc_alloc_template < 0 > gc_alloc; - -template < int dummy > -class traceable_alloc_template { - public: - static void * allocate(size_t n) { - void * op = GC_malloc_uncollectable(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - static void * ptr_free_allocate(size_t n) { - void * op = GC_malloc_atomic_uncollectable(n); - if (0 == op) - GC_ALLOCATOR_THROW_OR_ABORT(); - return op; - } - static void deallocate(void *p, size_t) { GC_free(p); } - static void ptr_free_deallocate(void *p, size_t) { GC_free(p); } -}; - -typedef traceable_alloc_template < 0 > traceable_alloc; - -// We want to specialize simple_alloc so that it does the right thing -// for all pointer-free types. At the moment there is no portable way to -// even approximate that. The following approximation should work for -// SGI compilers, and recent versions of g++. - -// GC_SPECIALIZE() is used internally. -#define GC_SPECIALIZE(T,alloc) \ - class simple_alloc<T, alloc> { \ - public: \ - static T *allocate(size_t n) \ - { reinterpret_cast<T*>(alloc::ptr_free_allocate(0 == n ? 1 \ - : n * sizeof(T))); } \ - static T *allocate(void) \ - { return reinterpret_cast<T*>(alloc::ptr_free_allocate(sizeof(T))); } \ - static void deallocate(T *p, size_t n) \ - { alloc::ptr_free_deallocate(p, 0 == n ? 1 : n * sizeof(T)); } \ - static void deallocate(T *p) \ - { alloc::ptr_free_deallocate(p, sizeof(T)); } \ - }; - -__STL_BEGIN_NAMESPACE - -GC_SPECIALIZE(char, gc_alloc) -GC_SPECIALIZE(int, gc_alloc) -GC_SPECIALIZE(unsigned, gc_alloc) -GC_SPECIALIZE(float, gc_alloc) -GC_SPECIALIZE(double, gc_alloc) - -GC_SPECIALIZE(char, traceable_alloc) -GC_SPECIALIZE(int, traceable_alloc) -GC_SPECIALIZE(unsigned, traceable_alloc) -GC_SPECIALIZE(float, traceable_alloc) -GC_SPECIALIZE(double, traceable_alloc) - -GC_SPECIALIZE(char, single_client_gc_alloc) -GC_SPECIALIZE(int, single_client_gc_alloc) -GC_SPECIALIZE(unsigned, single_client_gc_alloc) -GC_SPECIALIZE(float, single_client_gc_alloc) -GC_SPECIALIZE(double, single_client_gc_alloc) - -GC_SPECIALIZE(char, single_client_traceable_alloc) -GC_SPECIALIZE(int, single_client_traceable_alloc) -GC_SPECIALIZE(unsigned, single_client_traceable_alloc) -GC_SPECIALIZE(float, single_client_traceable_alloc) -GC_SPECIALIZE(double, single_client_traceable_alloc) - -__STL_END_NAMESPACE - -#ifdef __STL_USE_STD_ALLOCATORS - -__STL_BEGIN_NAMESPACE - -template <class _Tp> -struct _Alloc_traits<_Tp, gc_alloc > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, gc_alloc > _Alloc_type; - typedef __allocator<_Tp, gc_alloc > allocator_type; -}; - -inline bool operator==(const gc_alloc&, - const gc_alloc&) -{ - return true; -} - -inline bool operator!=(const gc_alloc&, - const gc_alloc&) -{ - return false; -} - -template <class _Tp> -struct _Alloc_traits<_Tp, single_client_gc_alloc > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, single_client_gc_alloc > _Alloc_type; - typedef __allocator<_Tp, single_client_gc_alloc > allocator_type; -}; - -inline bool operator==(const single_client_gc_alloc&, - const single_client_gc_alloc&) -{ - return true; -} - -inline bool operator!=(const single_client_gc_alloc&, - const single_client_gc_alloc&) -{ - return false; -} - -template <class _Tp> -struct _Alloc_traits<_Tp, traceable_alloc > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, traceable_alloc > _Alloc_type; - typedef __allocator<_Tp, traceable_alloc > allocator_type; -}; - -inline bool operator==(const traceable_alloc&, - const traceable_alloc&) -{ - return true; -} - -inline bool operator!=(const traceable_alloc&, - const traceable_alloc&) -{ - return false; -} - -template <class _Tp> -struct _Alloc_traits<_Tp, single_client_traceable_alloc > -{ - static const bool _S_instanceless = true; - typedef simple_alloc<_Tp, single_client_traceable_alloc > _Alloc_type; - typedef __allocator<_Tp, single_client_traceable_alloc > allocator_type; -}; - -inline bool operator==(const single_client_traceable_alloc&, - const single_client_traceable_alloc&) -{ - return true; -} - -inline bool operator!=(const single_client_traceable_alloc&, - const single_client_traceable_alloc&) -{ - return false; -} - -__STL_END_NAMESPACE - -#endif /* __STL_USE_STD_ALLOCATORS */ - -#endif /* GC_NEW_ALLOC_H */
View file
_service:tar_scm:gc-8.0.6.tar.gz/sparc_sunos4_mach_dep.s
Deleted
@@ -1,32 +0,0 @@ -! SPARCompiler 3.0 and later apparently no longer handles -! asm outside functions. So we need a separate .s file -! This is only set up for SunOS 4. -! Assumes this is called before the stack contents are -! examined. - - .seg "text" - .globl _GC_save_regs_in_stack - .globl _GC_push_regs -_GC_save_regs_in_stack: -_GC_push_regs: - ta 0x3 ! ST_FLUSH_WINDOWS - mov %sp,%o0 - retl - nop - - .globl _GC_clear_stack_inner -_GC_clear_stack_inner: - mov %sp,%o2 ! Save sp - add %sp,-8,%o3 ! p = sp-8 - clr %g1 ! g0,g1 = 0 - add %o1,-0x60,%sp ! Move sp out of the way, - ! so that traps still work. - ! Includes some extra words - ! so we can be sloppy below. -loop: - std %g0,%o3 ! *(long long *)p = 0 - cmp %o3,%o1 - bgu loop ! if (p > limit) goto loop - add %o3,-8,%o3 ! p -= 8 (delay slot) - retl - mov %o2,%sp ! Restore sp., delay slot
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/CMakeLists.txt
Deleted
@@ -1,47 +0,0 @@ -# -# Copyright (c) 1994 by Xerox Corporation. All rights reserved. -# Copyright (c) 1996 by Silicon Graphics. All rights reserved. -# Copyright (c) 1998 by Fergus Henderson. All rights reserved. -# Copyright (c) 2000-2010 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. -## - -ADD_DEFINITIONS(-DGC_NOT_DLL) - -# Compile some tests as C++ to test extern "C" in header files. -SET_SOURCE_FILES_PROPERTIES( - leak_test.c - test.c - PROPERTIES LANGUAGE CXX) - -ADD_EXECUTABLE(gctest WIN32 test.c) -TARGET_LINK_LIBRARIES(gctest gc-lib) -ADD_TEST(NAME gctest COMMAND gctest) - -ADD_EXECUTABLE(hugetest huge_test.c) -TARGET_LINK_LIBRARIES(hugetest gc-lib) -ADD_TEST(NAME hugetest COMMAND hugetest) - -ADD_EXECUTABLE(leaktest leak_test.c) -TARGET_LINK_LIBRARIES(leaktest gc-lib) -ADD_TEST(NAME leaktest COMMAND leaktest) - -ADD_EXECUTABLE(middletest middle.c) -TARGET_LINK_LIBRARIES(middletest gc-lib) -ADD_TEST(NAME middletest COMMAND middletest) - -ADD_EXECUTABLE(realloc_test realloc_test.c) -TARGET_LINK_LIBRARIES(realloc_test gc-lib) -ADD_TEST(NAME realloc_test COMMAND realloc_test) - -ADD_EXECUTABLE(smashtest smash_test.c) -TARGET_LINK_LIBRARIES(smashtest gc-lib) -ADD_TEST(NAME smashtest COMMAND smashtest)
View file
_service:tar_scm:gc-8.0.6.tar.gz/AUTHORS -> _service:tar_scm:gc-8.2.2.tar.gz/AUTHORS
Changed
@@ -55,6 +55,7 @@ Andrew Pinski <pinskia@physics.uc.edu> Andrew Stitcher <astitcher@redhat.com> Andrew Stone <andrew@stone.com> +Andrew Whatson <whatson@gmail.com> Andy Li <andy@onthewings.net> Andy Wingo <wingo@pobox.com> Anselm Baird-Smith <Anselm.BairdSmith@inria.fr> @@ -85,6 +86,7 @@ Brian Burton <bburton@users.sourceforge.net> Brian D. Carlstrom <bdc@clark.lcs.mit.edu> Brian F. Dennis <xjam@cork.cs.berkeley.edu> +Brian J. Cardiff <bcardiff@gmail.com> Brian Lewis <btlewis@eng.sun.com> Bruce A Henderson <woollybah@gmail.com> Bruce Hoult <bruce@hoult.org> @@ -128,17 +130,19 @@ David Grove <groved@us.ibm.com> David Leonard <leonard@users.sourceforge.net> David Miller <davem@davemloft.net> -David Mossberger +David Mosberger <davidm@hpl.hp.com> David Peroutka <djp@volny.cz> David Pickens <dsp@rci.rutgers.edu> David Stes <stes@d5e02b1d.kabel.telenet.be> David Terei <d@davidterei.com> David Van Horn <dvanhorn@ccs.neu.edu> Davide Angelocola <davide.angelocola@tiscali.it> +Davide Beatrici <git@davidebeatrici.dev> Demyan Kimitsa <demyan.kimitsa@gmail.com> Dick Porter <dick@acm.org> Dietmar Planitzer <dave.pl@ping.at> Dima Pasechnik <dimpase@gmail.com> +Dimitris Apostolou <dimitris.apostolou@icloud.com> Dimitris Vyzovitis <vyzo@media.mit.edu> Dimitry Andric <dim@freebsd.org> Djamel Magri <djamel.magri@googlemail.com> @@ -162,6 +166,7 @@ Gabor Drescher <gabor.drescher@cs.fau.de> Gary Leavens <leavens@eecs.ucf.edu> Geoff Norton <grompf@sublimeintervention.com> +George Koehler <kernigh@gmail.com> George Talbot <Gtalbot@ansarisbio.com> Gerard A Allan Glauco Masotti <glauco.masotti@libero.it> @@ -184,6 +189,7 @@ Ian Piumarta <piumarta@prof.inria.fr> Ian Searle <ians@eskimo.com> Igor Khavkine <i_khavki@alcor.concordia.ca> +Ilya Kurdyukov <ilyakurdyukov@altlinux.org> Ivan Demakov <ivan@tgrad.nsk.su> Ivan Maidanski <ivmai@mail.ru> Ivan R <iarspider@gmail.com> @@ -191,8 +197,10 @@ Jack Andrews <effbiae@gmail.com> Jacob Navia <jacob.navia@jacob.remcomp.fr> Jakub Jelinek <jakub@redhat.com> +Jakub Wojciech <jakub-w@riseup.net> James Clark <jjc@jclark.com> James Dominy +James Moran <jamesmo@unity3d.com> Jan Alexander Steffens <jan.steffens@gmail.com> Jan Wielemaker <J.Wielemaker@cs.vu.nl> Jani Kajala <jani@sumea.com> @@ -207,7 +215,7 @@ Jeffrey Mark Siskind Jeremy Fitzhardinge <jeremy@goop.org> Jesper Peterson <jep@mtiame.mtia.oz.au> -Jesse Hull +Jesse Hull <jhull@parc.xerox.com> Jesse Jones <jesjones@mindspring.com> Jesse Rosenstock <jmr@ugcs.caltech.edu> Ji-Yong Chung @@ -221,7 +229,8 @@ John Bowman <bowman@ualberta.ca> John Clements <clements@brinkerhoff.org> John David Anglin <dave.anglin@bell.net> -John Ellis <ellis@xerox.parc.com> +John Ellis <ellis@parc.xerox.com> +John Ericson <git@JohnEricson.me> John Merryweather Cooper <jmerry@mono-cvs.ximian.com> Jon Moore <jonm@apache.org> Jonas Echterhoff <jonas@unity3d.com> @@ -280,16 +289,21 @@ Martin Koeppe <mkoeppe@gmx.de> Martin Tauchmann <martintauchmann@bigfoot.com> Massimiliano Gubinelli <m.gubinelli@gmail.com> +Matheus Rambo <mrambo@grupodimed.com.br> Matt Austern <austern@google.com> Matthew Flatt <mflatt@plt-scheme.org> Matthias Andree <matthias.andree@gmx.de> Matthias Drochner <M.Drochner@fz-juelich.de> +Matthieu Herrb <matthieu@openbsd.org> Maurizio Vairani <maurizio.vairani@cloverinformatica.it> Max Mouratov <mmouratov@gmail.com> +Maximilian Downey Twiss <creatorsmithmdt@gmail.com> +Maya Rashish <coypu@sdf.org> Melissa O'Neill <oneill@cs.sfu.ca> Michael Arnoldus <chime@proinf.dk> Michael DeRoy <deroymichael@gmail.com> Michael Fox <mfox@cavium.com> +Michael Herring <khakionion@gmail.com> Michael Smith <msmith@spinnakernet.com> Michael Spertus <mps@geodesic.com> Michel Schinz <schinz@alphanet.ch> @@ -305,6 +319,7 @@ Nathanael Nerode <neroden@twcny.rr.com> Neale Ferguson <neale@mono-cvs.ximian.com> Neil Sharman <neil@cs.mu.oz.au> +Nguyen Thai Ngoc Duy <pclouds@gmail.com> Nicolas Cannasse <ncannasse@motion-twin.com> Niibe Yutaka <gniibe@fsij.org> Nikita Ermakov <coffe92@gmail.com> @@ -371,16 +386,20 @@ Samuel Martin <s.martin49@gmail.com> Samuel Thibault <samuel.thibault@gnu.org> Scott Ananian <cananian@lesser-magoo.lcs.mit.edu> +Scott Ferguson <scott.ferguson@unity3d.com> Scott Schwartz <schwartz@groucho.cse.psu.edu> Shawn Wagner <shawnw@speakeasy.org> Shea Levy <shea@shealevy.com> Shiro Kawai <shiro@lava.net> Simon Gornall <simon@gornall.net> +Simon Kainz <simon@familiekainz.at> Simon Posnjak <simon.posnjak@siol.net> Slava Sysoltsev <Viatcheslav.Sysoltsev@h-d-gmbh.de> Sorawee Porncharoenwase <sorawee.pwase@gmail.com> +ssrlive <ssrlivebox@gmail.com> Stefan Ring <stefanrin@gmail.com> Stefano Rivera <stefano@rivera.za.net> +Steve Youngs <steve@sxemacs.org> Sugioka Toshinobu <sugioka@itonet.co.jp> Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp> Sven Hartrumpf <Sven.Hartrumpf@fernuni-hagen.de> @@ -399,6 +418,7 @@ Thorsten Glaser <tg@debian.org> Tilman Vogel <Tilman.Vogel@web.de> Tim Bingham <tjb@zko.dec.com> +Tim Cannell <timcannell@unity3d.com> Tim Gates <tim.gates@iress.com> Timothy N. Newsham <newsham@wiliki.eng.hawaii.edu> Tom Tromey <tromey@cygnus.com> @@ -415,6 +435,7 @@ Vernon Lee <scorpion@rice.edu> Victor Ivrii <ivrii@math.toronto.edu> Victor Romero <romerosanchezv@gmail.com> +Vineet Gupta <vgupta@synopsys.com> Vitaly Magerya <vmagerya@gmail.com> Vladimir Tsichevski <wowa@jet.msk.su> Walter Bright <walter@walterbright.com> @@ -426,10 +447,12 @@ Xiaokun Zhu <xiaokun@aero.gla.ac.uk> Yann Dirson <dirson@debian.org> Yannis Bres <Yannis@bres.name> +Yasuhiro Kimura <yasu@utahime.org> Yuki Okumura <mjt@cltn.org> Yusuke Suzuki <utatane.tea@gmail.com> Yvan Roux <yvan.roux@linaro.org> Zach Saw <zach.saw@gmail.com> +Zhang Na <zhangna@loongson.cn> Zhiying Chen Zhong Shao <zhong.shao@yale.edu> Zoltan Varga <vargaz@gmail.com>
View file
_service:tar_scm:gc-8.0.6.tar.gz/CMakeLists.txt -> _service:tar_scm:gc-8.2.2.tar.gz/CMakeLists.txt
Changed
@@ -3,6 +3,7 @@ # Copyright (c) 1996 by Silicon Graphics. All rights reserved. # Copyright (c) 1998 by Fergus Henderson. All rights reserved. # Copyright (c) 2000-2010 by Hewlett-Packard Company. All rights reserved. +# Copyright (c) 2010-2021 Ivan Maidanski ## # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -21,232 +22,768 @@ # this will generate gc.sln # -SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required - -PROJECT(gc) - -INCLUDE(CTest) - -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -ADD_DEFINITIONS("-D_CRT_SECURE_NO_DEPRECATE - -DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION") - -#LIBATOMIC #TODO -#ADD_LIBRARY(atomic_ops STATIC ) -#SET_TARGET_PROPERTIES(atomic_ops PROPERTIES COMPILE_FLAGS -DNO_DEBUGGING) - - -#LIBGC - -INCLUDE_DIRECTORIES(include) -INCLUDE_DIRECTORIES(libatomic_ops/src) - -SET(SRC alloc.c reclaim.c allchblk.c misc.c mach_dep.c os_dep.c +cmake_minimum_required(VERSION 3.1) + +set(PACKAGE_VERSION 8.2.2) +# Version must match that in AC_INIT of configure.ac and that in README. +# Version must conform to: 0-9+.0-9+.0-9+ + +# Info (current:revision:age) for the Libtool versioning system. +# These values should match those in cord/cord.am and Makefile.am. +set(LIBCORD_VER_INFO 6:0:5) +set(LIBGC_VER_INFO 6:1:5) +set(LIBGCCPP_VER_INFO 6:0:5) + +option(enable_cplusplus "C++ support" OFF) +if (enable_cplusplus) + project(gc) +else() + project(gc C) +endif() + +include(CheckCCompilerFlag) +include(CheckCSourceCompiles) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckSymbolExists) +include(CMakePackageConfigHelpers) +include(CTest) +include(GNUInstallDirs) + +# Customize the build by passing "-D<option_name>=ON|OFF" in the command line. +option(BUILD_SHARED_LIBS "Build shared libraries" ON) +option(build_cord "Build cord library" ON) +option(build_tests "Build tests" OFF) +option(enable_docs "Build and install documentation" ON) +option(enable_threads "Support threads" ON) +option(enable_parallel_mark "Parallelize marking and free list construction" ON) +option(enable_thread_local_alloc "Turn on thread-local allocation optimization" ON) +option(enable_threads_discovery "Enable threads discovery in GC" ON) +option(enable_throw_bad_alloc_library "Turn on C++ gctba library build" ON) +option(enable_gcj_support "Support for gcj" ON) +option(enable_sigrt_signals "Use SIGRTMIN-based signals for thread suspend/resume" OFF) +option(enable_gc_debug "Support for pointer back-tracing" OFF) +option(disable_gc_debug "Disable debugging like GC_dump and its callees" OFF) +option(enable_java_finalization "Support for java finalization" ON) +option(enable_atomic_uncollectable "Support for atomic uncollectible allocation" ON) +option(enable_redirect_malloc "Redirect malloc and friends to GC routines" OFF) +option(enable_disclaim "Support alternative finalization interface" ON) +option(enable_large_config "Optimize for large heap or root set" OFF) +option(enable_gc_assertions "Enable collector-internal assertion checking" OFF) +option(enable_mmap "Use mmap instead of sbrk to expand the heap" OFF) +option(enable_munmap "Return page to the OS if empty for N collections" ON) +option(enable_dynamic_loading "Enable tracing of dynamic library data roots" ON) +option(enable_register_main_static_data "Perform the initial guess of data root sets" ON) +option(enable_checksums "Report erroneously cleared dirty bits" OFF) +option(enable_werror "Pass -Werror to the C compiler (treat warnings as errors)" OFF) +option(enable_single_obj_compilation "Compile all libgc source files into single .o" OFF) +option(enable_handle_fork "Attempt to ensure a usable collector after fork()" ON) +option(disable_handle_fork "Prohibit installation of pthread_atfork() handlers" OFF) +option(install_headers "Install header and pkg-config metadata files" ON) +option(without_libatomic_ops "Use atomic_ops.h in libatomic_ops/src" OFF) + +# Override the default build type to RelWithDebInfo (this instructs cmake to +# pass -O2 -g -DNDEBUG options to the compiler by default). +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE + STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY + STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel") +endif() + +# Convert VER_INFO values to SOVERSION ones. +if (BUILD_SHARED_LIBS) + # cord: + string(REGEX REPLACE "(.+):.+:.+" "\\1" cord_cur ${LIBCORD_VER_INFO}) + string(REGEX REPLACE ".+:(.+):.+" "\\1" cord_rev ${LIBCORD_VER_INFO}) + string(REGEX REPLACE ".+:.+:(.+)$" "\\1" cord_age ${LIBCORD_VER_INFO}) + math(EXPR CORD_SOVERSION "${cord_cur} - ${cord_age}") + set(CORD_VERSION_PROP "${CORD_SOVERSION}.${cord_age}.${cord_rev}") + message(STATUS "CORD_VERSION_PROP = ${CORD_VERSION_PROP}") + # gc: + string(REGEX REPLACE "(.+):.+:.+" "\\1" gc_cur ${LIBGC_VER_INFO}) + string(REGEX REPLACE ".+:(.+):.+" "\\1" gc_rev ${LIBGC_VER_INFO}) + string(REGEX REPLACE ".+:.+:(.+)$" "\\1" gc_age ${LIBGC_VER_INFO}) + math(EXPR GC_SOVERSION "${gc_cur} - ${gc_age}") + set(GC_VERSION_PROP "${GC_SOVERSION}.${gc_age}.${gc_rev}") + message(STATUS "GC_VERSION_PROP = ${GC_VERSION_PROP}") + # gccpp and gctba: + string(REGEX REPLACE "(.+):.+:.+" "\\1" gccpp_cur ${LIBGCCPP_VER_INFO}) + string(REGEX REPLACE ".+:(.+):.+" "\\1" gccpp_rev ${LIBGCCPP_VER_INFO}) + string(REGEX REPLACE ".+:.+:(.+)$" "\\1" gccpp_age ${LIBGCCPP_VER_INFO}) + math(EXPR GCCPP_SOVERSION "${gccpp_cur} - ${gccpp_age}") + set(GCCPP_VERSION_PROP "${GCCPP_SOVERSION}.${gccpp_age}.${gccpp_rev}") + message(STATUS "GCCPP_VERSION_PROP = ${GCCPP_VERSION_PROP}") +endif(BUILD_SHARED_LIBS) + +add_definitions("-DALL_INTERIOR_POINTERS -DNO_EXECUTE_PERMISSION") + +# Set struct packing alignment to word (instead of 1-byte). +if (BORLAND) + add_compile_options(/a4) +elseif (WATCOM) + add_compile_options(/zp4) +endif() + +# Output all warnings. +if (BORLAND) + # All warnings except for particular ones. + add_compile_options(/w /w-pro /w-aus /w-par /w-ccc /w-inl /w-rch) +elseif (MSVC) + # All warnings but ignoring "unreferenced formal parameter" and + # "conditional expression is constant" ones. + add_compile_options(/W4 /wd4100 /wd4127) + # Disable crt security warnings, since unfortunately they warn about all + # sorts of safe uses of strncpy. + add_definitions("-D_CRT_SECURE_NO_DEPRECATE") +elseif (WATCOM) + add_compile_options(/wx) +else() + # TODO add -Wpedantic -Wno-long-long + add_compile_options(-Wall -Wextra) +endif() + +include_directories(include) + +set(SRC alloc.c reclaim.c allchblk.c misc.c mach_dep.c os_dep.c mark_rts.c headers.c mark.c obj_map.c blacklst.c finalize.c new_hblk.c dbg_mlc.c malloc.c dyn_load.c typd_mlc.c ptr_chck.c mallocx.c) -SET(LIBS) -OPTION(enable_threads "TODO" NO) -IF(enable_threads) - FIND_PACKAGE(Threads REQUIRED) - MESSAGE("Thread Model: ${CMAKE_THREAD_LIBS_INIT}" ) - INCLUDE_DIRECTORIES(${Threads_INCLUDE_DIR}) - SET(LIBS ${LIBS} ${Threads_LIBRARIES}) -ENDIF(enable_threads) - -OPTION(enable_handle_fork "Attempt to ensure a usable collector after fork()" ON) - -OPTION(enable_thread_local_alloc "Turn on thread-local allocation optimization" ON) - -OPTION(enable_parallel_mark "Parallelize marking and free list construction" ON) - -#IF(Threads_FOUND) -# ADD_DEFINITIONS("") -#ELSE -# MESSAGE("Parallel mark requires enable_threads ON" ) -#ENDIF(Threads_FOUND) - -#OPTION(enable_cplusplus "install C++ support" ON) -SET(SRC ${SRC} gc_cpp.cc) - -SET(_HOST ${CMAKE_HOST_SYSTEM_PROCESSOR}--${CMAKE_SYSTEM}) #FIXME missing the vendor field. -STRING(TOLOWER ${_HOST} HOST) -MESSAGE("HOST = ${HOST}") - -# Thread Detection. Relying on cmake for lib and includes. -#TODO check cmake detection -IF(CMAKE_USE_PTHREADS_INIT) - SET(SRC ${SRC} gc_dlopen.c pthread_start.c pthread_stop_world.c - pthread_support.c) - # Common defines for most POSIX platforms. - IF( HOST MATCHES .*-.*-aix.*|.*-.*-android.*|.*-.*-cygwin.*|.*-.*-darwin.*|.*-.*-.*freebsd.*|.*-.*-haiku.*|.*-.*-gnu.*|.*-.*-hpux11.*|.*-.*-irix.*|.*-.*-.*linux.*|.*-.*-msys.*|.*-.*-nacl.*|.*-.*-netbsd.*|.*-.*-openbsd.*|.*-.*-osf.*|.*-.*-solaris.*) - ADD_DEFINITIONS("-DGC_THREADS -D_REENTRANT") - IF(enable_parallel_mark) - ADD_DEFINITIONS("-DPARALLEL_MARK") - ENDIF(enable_parallel_mark) - IF(enable_thread_local_alloc) - ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC") - SET(SRC ${SRC} specific.c thread_local_alloc.c) - ENDIF(enable_thread_local_alloc) - MESSAGE("Explicit GC_INIT() calls may be required.") - ENDIF() - IF ( HOST MATCHES .*-.*-hpux11.*) - MESSAGE("Only HP/UX 11 POSIX threads are supported.") - ADD_DEFINITIONS("-D_POSIX_C_SOURCE=199506L") #TODO test -DVAR=value. Alternative is COMPILE_DEFINITIONS property - ENDIF() - IF ( HOST MATCHES .*-.*-hpux10.*) - MESSAGE("HP/UX 10 POSIX threads are not supported.") - ENDIF() - IF ( HOST MATCHES .*-.*-netbsd.*) - MESSAGE("Only on NetBSD 2.0 or later.") - ADD_DEFINITIONS("-D_PTHREADS") - ENDIF() - IF( HOST MATCHES .*-.*-android.*) - # Android NDK does not provide pthread_atfork. - ELSEIF( HOST MATCHES .*-.*-aix.*|.*-.*-cygwin.*|.*-.*-freebsd.*|.*-.*-haiku.*|.*-.*-hpux11.*|.*-.*-irix.*|.*-.*-kfreebsd.*-gnu|.*-.*-.*linux.*|.*-.*-netbsd.*|.*-.*-openbsd.*|.*-.*-osf.*|.*-.*-solaris.*) - IF(enable_handle_fork) - ADD_DEFINITIONS("-DHANDLE_FORK") - ENDIF(enable_handle_fork) - ENDIF() - IF ( HOST MATCHES .*-.*-cygwin.*|.*-.*-msys.*) - SET(SRC ${SRC} win32_threads.c) - ENDIF() - IF ( HOST MATCHES .*-.*-darwin.*) - IF(enable_handle_fork) - # The incremental mode conflicts with fork handling. - IF(enable_parallel_mark) - ADD_DEFINITIONS("-DHANDLE_FORK") - ENDIF(enable_parallel_mark) - ENDIF(enable_handle_fork) - SET(SRC ${SRC} darwin_stop_world.c) - #TODO - #darwin_threads=true - ENDIF() -ENDIF(CMAKE_USE_PTHREADS_INIT) - -IF(CMAKE_USE_WIN32_THREADS_INIT) - ADD_DEFINITIONS("-DGC_THREADS") - IF(enable_parallel_mark) - ADD_DEFINITIONS("-DPARALLEL_MARK") - IF(enable_thread_local_alloc) - ADD_DEFINITIONS("-DTHREAD_LOCAL_ALLOC") - SET(SRC ${SRC} thread_local_alloc.c) - ENDIF(enable_thread_local_alloc) - ENDIF() - ADD_DEFINITIONS("-DEMPTY_GETENV_RESULTS") #TODO test - SET(SRC ${SRC} win32_threads.c) -ENDIF(CMAKE_USE_WIN32_THREADS_INIT) - -OPTION(enable_gcj_support "Support for gcj" ON) -IF(enable_gcj_support) - ADD_DEFINITIONS("-DGC_GCJ_SUPPORT") - IF(enable_threads) - ADD_DEFINITIONS("-DGC_ENABLE_SUSPEND_THREAD") - ENDIF(enable_threads) - SET(SRC ${SRC} gcj_mlc.c) -ENDIF(enable_gcj_support) - -OPTION(enable_disclaim "Support alternative finalization interface" ON) -IF(enable_disclaim) - ADD_DEFINITIONS("-DENABLE_DISCLAIM") - SET(SRC ${SRC} fnlz_mlc.c) -ENDIF(enable_disclaim) - -OPTION(enable_java_finalization "Support for java finalization" ON) -IF(enable_java_finalization) - ADD_DEFINITIONS("-DJAVA_FINALIZATION") -ENDIF(enable_java_finalization) - -OPTION(enable_atomic_uncollectable "Support for atomic uncollectible allocation" ON) -IF(enable_atomic_uncollectable) - ADD_DEFINITIONS("-DGC_ATOMIC_UNCOLLECTABLE") -ENDIF(enable_atomic_uncollectable) - -OPTION(enable_gc_debug "Support for pointer back-tracing" NO) -IF(enable_gc_debug) - ADD_DEFINITIONS("-DDBG_HDRS_ALL -DKEEP_BACK_PTRS") - IF (HOST MATCHES ia64-.*-linux.*|i586-.*-linux.*|i686-.*-linux.*|x86-.*-linux.*|x86_64-.*-linux.*) - ADD_DEFINITIONS("-DMAKE_BACK_GRAPH") - ADD_DEFINITIONS("-DSAVE_CALL_COUNT=8") - SET(SRC ${SRC} backgraph.c) - ENDIF() - IF (HOST MATCHES i.86-.*-dgux.*) - ADD_DEFINITIONS("-DMAKE_BACK_GRAPH") - SET(SRC ${SRC} backgraph.c) - ENDIF() -ENDIF(enable_gc_debug) - -OPTION(enable_redirect_malloc "Redirect malloc and friends to GC routines" NO) -IF(enable_redirect_malloc) - IF(enable_gc_debug) - ADD_DEFINITIONS("-DREDIRECT_MALLOC=GC_debug_malloc_replacement") - ADD_DEFINITIONS("-DREDIRECT_REALLOC=GC_debug_realloc_replacement") - ADD_DEFINITIONS("-DREDIRECT_FREE=GC_debug_free") - ELSE(enable_gc_debug) - ADD_DEFINITIONS("-DREDIRECT_MALLOC=GC_malloc") - ENDIF(enable_gc_debug) - ADD_DEFINITIONS("-DGC_USE_DLOPEN_WRAP") -ENDIF(enable_redirect_malloc) - -OPTION(enable_mmap "Use mmap instead of sbrk to expand the heap" NO) - -OPTION(enable_munmap "Return page to the OS if empty for N collections" ON) -IF(enable_munmap) - ADD_DEFINITIONS("-DUSE_MMAP -DUSE_MUNMAP") -ELSEIF(enable_mmap) - ADD_DEFINITIONS("-DUSE_MMAP") -ENDIF() - -OPTION(enable_dynamic_loading "Enable tracing of dynamic library data roots" ON) -IF(NOT enable_dynamic_loading) - ADD_DEFINITIONS("-DIGNORE_DYNAMIC_LOADING") -ENDIF() - -OPTION(enable_register_main_static_data "Perform the initial guess of data root sets" ON) -IF(NOT enable_register_main_static_data) - ADD_DEFINITIONS("-DGC_DONT_REGISTER_MAIN_STATIC_DATA") -ENDIF() - -OPTION(enable_large_config "Optimize for large heap or root set" NO) -IF(enable_large_config) - ADD_DEFINITIONS("-DLARGE_CONFIG") -ENDIF(enable_large_config) - -OPTION(enable_gc_assertions "Enable collector-internal assertion checking" NO) -IF(enable_gc_assertions) - ADD_DEFINITIONS("-DGC_ASSERTIONS") -ENDIF(enable_gc_assertions) - -OPTION(enable_threads_discovery "Enable threads discovery in GC" ON) -IF(NOT enable_threads_discovery) - ADD_DEFINITIONS("-DGC_NO_THREADS_DISCOVERY") -ENDIF() - -OPTION(enable_checksums "Report erroneously cleared dirty bits" NO) -IF(enable_checksums) - IF(enable_munmap OR enable_threads) - MESSAGE("CHECKSUMS not compatible with USE_MUNMAP or threads") - ENDIF() - ADD_DEFINITIONS("-DCHECKSUMS") - SET(SRC ${SRC} checksums.c) -ENDIF(enable_checksums) - -ADD_LIBRARY( gc-lib STATIC ${SRC}) -SET_TARGET_PROPERTIES(gc-lib PROPERTIES - COMPILE_DEFINITIONS GC_NOT_DLL) -#TODO TARGET_LINK_LIBRARIES(... ... ${LIBS}) - -ADD_LIBRARY( gcmt-dll SHARED ${SRC}) - -IF(WIN32) - ADD_EXECUTABLE(cord cord/cordbscs.c cord/cordxtra.c - cord/tests/de.c cord/tests/de_win.c) - SET_TARGET_PROPERTIES(cord PROPERTIES WIN32_EXECUTABLE TRUE) - SET_TARGET_PROPERTIES(cord PROPERTIES - COMPILE_DEFINITIONS GC_NOT_DLL) - TARGET_LINK_LIBRARIES(cord gc-lib) - TARGET_LINK_LIBRARIES(cord gdi32) -ENDIF(WIN32) - -ADD_SUBDIRECTORY(tests) +set(THREADDLLIBS_LIST) +set(NEED_LIB_RT) + +set(_HOST ${CMAKE_SYSTEM_PROCESSOR}-unknown-${CMAKE_SYSTEM}) +string(TOLOWER ${_HOST} HOST) +message(STATUS "TARGET = ${HOST}") + +if (enable_threads) + find_package(Threads REQUIRED) + message(STATUS "Thread library: ${CMAKE_THREAD_LIBS_INIT}") + if (without_libatomic_ops OR BORLAND OR MSVC OR WATCOM) + include_directories(libatomic_ops/src) + # Note: alternatively, use CFLAGS_EXTRA to pass -I<...>/libatomic_ops/src. + else() + # Assume the compiler supports GCC atomic intrinsics. + add_definitions("-DGC_BUILTIN_ATOMIC") + endif() + include_directories(${Threads_INCLUDE_DIR}) + set(THREADDLLIBS_LIST ${CMAKE_THREAD_LIBS_INIT}) + if (${CMAKE_DL_LIBS} MATCHES ^^-.*) + # Some cmake versions have a broken non-empty CMAKE_DL_LIBS omitting "-l". + # Assume CMAKE_DL_LIBS contains just one library. + set(THREADDLLIBS_LIST ${THREADDLLIBS_LIST} -l${CMAKE_DL_LIBS}) + else() + set(THREADDLLIBS_LIST ${THREADDLLIBS_LIST} ${CMAKE_DL_LIBS}) + endif() +endif(enable_threads) + +set(ATOMIC_OPS_LIBS "") # TODO: Assume libatomic_ops library is not needed. + +# Thread support detection. +if (CMAKE_USE_PTHREADS_INIT) + set(SRC ${SRC} gc_dlopen.c) + if (CYGWIN OR MSYS) + set(SRC ${SRC} win32_threads.c) + else() + set(SRC ${SRC} pthread_start.c pthread_stop_world.c pthread_support.c) + endif() + if (HOST MATCHES .*-.*-hpux10.*) + message(FATAL_ERROR "HP/UX 10 POSIX threads are not supported.") + endif() + # Common defines for POSIX platforms. + add_definitions("-DGC_THREADS -D_REENTRANT") + if (enable_parallel_mark) + add_definitions("-DPARALLEL_MARK") + endif() + if (enable_thread_local_alloc) + add_definitions("-DTHREAD_LOCAL_ALLOC") + set(SRC ${SRC} specific.c thread_local_alloc.c) + endif() + message("Explicit GC_INIT() calls may be required.") + if (HOST MATCHES .*-.*-hpux11.*) + message("Only HP/UX 11 POSIX threads are supported.") + add_definitions("-D_POSIX_C_SOURCE=199506L") + set(NEED_LIB_RT ON) + elseif (HOST MATCHES .*-.*-netbsd.*) + message("Only on NetBSD 2.0 or later.") + add_definitions("-D_PTHREADS") + set(NEED_LIB_RT ON) + endif() + if (MSYS) + # Does not provide process fork functionality. + elseif (APPLE) + # The incremental mode conflicts with fork handling (for now). + # Thus, HANDLE_FORK is not defined. + set(SRC ${SRC} darwin_stop_world.c) + elseif (enable_handle_fork AND NOT disable_handle_fork) + add_definitions("-DHANDLE_FORK") + endif() + if (enable_sigrt_signals) + add_definitions("-DGC_USESIGRT_SIGNALS") + endif() +elseif (CMAKE_USE_WIN32_THREADS_INIT) + add_definitions("-DGC_THREADS") + if (enable_parallel_mark) + add_definitions("-DPARALLEL_MARK") + endif() + if (enable_thread_local_alloc AND (enable_parallel_mark OR NOT BUILD_SHARED_LIBS)) + # Imply THREAD_LOCAL_ALLOC unless GC_DLL. + add_definitions("-DTHREAD_LOCAL_ALLOC") + set(SRC ${SRC} thread_local_alloc.c) + endif() + add_definitions("-DEMPTY_GETENV_RESULTS") + set(SRC ${SRC} win32_threads.c) +elseif (CMAKE_HP_PTHREADS_INIT OR CMAKE_USE_SPROC_INIT) + message(FATAL_ERROR "Unsupported thread package") +endif() + +# Check whether -lrt linker option is needed to use clock_gettime. +if (NOT NEED_LIB_RT) + check_function_exists(clock_gettime HAVE_CLOCK_GETTIME_DIRECTLY) + if (NOT HAVE_CLOCK_GETTIME_DIRECTLY) + # Use of clock_gettime() probably requires linking with "rt" library. + set(NEED_LIB_RT ON) + endif() +endif() + +# Locate and use "rt" library if needed (and the library is available). +if (NEED_LIB_RT) + find_library(LIBRT rt) + if (LIBRT) + set(THREADDLLIBS_LIST ${THREADDLLIBS_LIST} ${LIBRT}) + endif() +endif(NEED_LIB_RT) + +if (disable_handle_fork) + add_definitions("-DNO_HANDLE_FORK") +endif() + +if (enable_gcj_support) + add_definitions("-DGC_GCJ_SUPPORT") + if (enable_threads AND NOT (enable_thread_local_alloc AND HOST MATCHES .*-.*-kfreebsd.*-gnu)) + # FIXME: For a reason, gctest hangs up on kFreeBSD if both of + # THREAD_LOCAL_ALLOC and GC_ENABLE_SUSPEND_THREAD are defined. + add_definitions("-DGC_ENABLE_SUSPEND_THREAD") + endif() + set(SRC ${SRC} gcj_mlc.c) +endif(enable_gcj_support) + +if (enable_disclaim) + add_definitions("-DENABLE_DISCLAIM") + set(SRC ${SRC} fnlz_mlc.c) +endif() + +if (enable_java_finalization) + add_definitions("-DJAVA_FINALIZATION") +endif() + +if (enable_atomic_uncollectable) + add_definitions("-DGC_ATOMIC_UNCOLLECTABLE") +endif() + +if (enable_gc_debug) + add_definitions("-DDBG_HDRS_ALL -DKEEP_BACK_PTRS") + if (HOST MATCHES i.86-.*-dgux.*|ia64-.*-linux.*|i586-.*-linux.*|i686-.*-linux.*|x86-.*-linux.*|x86_64-.*-linux.*) + add_definitions("-DMAKE_BACK_GRAPH") + if (HOST MATCHES .*-.*-.*linux.*) + add_definitions("-DSAVE_CALL_COUNT=8") + endif() + set(SRC ${SRC} backgraph.c) + endif() +endif(enable_gc_debug) + +if (disable_gc_debug) + add_definitions("-DNO_DEBUGGING") +elseif (WINCE) + # Read environment variables from "<program>.gc.env" file. + add_definitions("-DGC_READ_ENV_FILE") +endif() + +if (enable_redirect_malloc) + if (enable_gc_debug) + add_definitions("-DREDIRECT_MALLOC=GC_debug_malloc_replacement") + add_definitions("-DREDIRECT_REALLOC=GC_debug_realloc_replacement") + add_definitions("-DREDIRECT_FREE=GC_debug_free") + else() + add_definitions("-DREDIRECT_MALLOC=GC_malloc") + endif() + add_definitions("-DGC_USE_DLOPEN_WRAP") +endif(enable_redirect_malloc) + +if (enable_munmap) + add_definitions("-DUSE_MMAP -DUSE_MUNMAP") +elseif (enable_mmap) + add_definitions("-DUSE_MMAP") +endif() + +if (NOT enable_dynamic_loading) + add_definitions("-DIGNORE_DYNAMIC_LOADING") +endif() + +if (NOT enable_register_main_static_data) + add_definitions("-DGC_DONT_REGISTER_MAIN_STATIC_DATA") +endif() + +if (enable_large_config) + add_definitions("-DLARGE_CONFIG") +endif() + +if (enable_gc_assertions) + add_definitions("-DGC_ASSERTIONS") +endif() + +if (NOT enable_threads_discovery) + add_definitions("-DGC_NO_THREADS_DISCOVERY") +endif() + +if (enable_checksums) + if (enable_munmap OR enable_threads) + message(FATAL_ERROR "CHECKSUMS not compatible with USE_MUNMAP or threads") + endif() + add_definitions("-DCHECKSUMS") + set(SRC ${SRC} checksums.c) +endif(enable_checksums) + +if (enable_werror) + if (BORLAND) + add_compile_options(/w!) + elseif (MSVC) + add_compile_options(/WX) + # Workaround "typedef ignored on left of ..." warning reported in + # imagehlp.h of e.g. Windows Kit 8.1. + add_compile_options(/wd4091) + elseif (WATCOM) + add_compile_options(/we) + else() + add_compile_options(-Werror) + if (APPLE) + # _dyld_bind_fully_image_containing_address is deprecated in OS X 10.5+ + add_compile_options(-Wno-deprecated-declarations) + endif() + endif() +endif(enable_werror) + +if (enable_single_obj_compilation OR BUILD_SHARED_LIBS) + set(SRC extra/gc.c) # override SRC + if (CMAKE_USE_PTHREADS_INIT) + add_definitions("-DGC_PTHREAD_START_STANDALONE") + set(SRC ${SRC} pthread_start.c) + endif(CMAKE_USE_PTHREADS_INIT) +elseif (BORLAND) + # Suppress "GC_push_contents_hdr() is declared but never used" warning. + add_compile_options(/w-use) +endif() + +# Add implementation of backtrace() and backtrace_symbols(). +if (MSVC) + set(SRC ${SRC} extra/msvc_dbg.c) +endif() + +# Instruct check_c_source_compiles to skip linking. +# Alternatively, we could set CMAKE_REQUIRED_LIBRARIES properly. +SET(CMAKE_REQUIRED_FLAGS "-c") + +# Instruct check_c_source_compiles and similar CMake checks not to ignore +# compiler warnings (like "implicit declaration of function"). +if (NOT BORLAND AND NOT MSVC AND NOT WATCOM) + check_c_compiler_flag(-Werror HAVE_FLAG_WERROR) + if (HAVE_FLAG_WERROR) + SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror") + endif(HAVE_FLAG_WERROR) +endif() + +if (BUILD_SHARED_LIBS) + add_definitions("-DGC_DLL") + # Pass -fvisibility=hidden option if supported. + check_c_compiler_flag(-fvisibility=hidden HAVE_FLAG_F_VISIBILITY_HIDDEN) + if (HAVE_FLAG_F_VISIBILITY_HIDDEN) + add_definitions("-DGC_VISIBILITY_HIDDEN_SET") + add_compile_options(-fvisibility=hidden) + else() + add_definitions("-DGC_NO_VISIBILITY") + endif() + check_c_compiler_flag(-Wl,--no-undefined HAVE_FLAG_WL_NO_UNDEFINED) +else() + add_definitions("-DGC_NOT_DLL") + if (WIN32) + # Do not require the clients to link with "user32" system library. + add_definitions("-DDONT_USE_USER32_DLL") + endif(WIN32) +endif() + +# Disable strict aliasing optimizations. +# It could re-enabled back by a flag passed in CFLAGS_EXTRA. +check_c_compiler_flag(-fno-strict-aliasing HAVE_FLAG_F_NO_STRICT_ALIASING) +if (HAVE_FLAG_F_NO_STRICT_ALIASING) + add_compile_options(-fno-strict-aliasing) +endif() + +# Extra user-defined flags to pass both to C and C++ compilers. +if (DEFINED CFLAGS_EXTRA) + separate_arguments(CFLAGS_EXTRA_LIST UNIX_COMMAND "${CFLAGS_EXTRA}") + add_compile_options(${CFLAGS_EXTRA_LIST}) +endif() + +# Check whether execinfo.h header file is present. +check_include_file(execinfo.h HAVE_EXECINFO_H) +if (NOT HAVE_EXECINFO_H) + add_definitions("-DGC_MISSING_EXECINFO_H") +endif() + +# Check for getcontext (uClibc can be configured without it, for example). +check_function_exists(getcontext HAVE_GETCONTEXT) +if (NOT HAVE_GETCONTEXT) + add_definitions("-DNO_GETCONTEXT") +endif() + +# Check whether dl_iterate_phdr exists (as a strong symbol). +check_function_exists(dl_iterate_phdr HAVE_DL_ITERATE_PHDR) +if (HAVE_DL_ITERATE_PHDR) + add_definitions("-DHAVE_DL_ITERATE_PHDR") +endif() + +check_symbol_exists(sigsetjmp setjmp.h HAVE_SIGSETJMP) +if (NOT HAVE_SIGSETJMP) + add_definitions("-DGC_NO_SIGSETJMP") +endif() + +# pthread_setname_np, if available, may have 1, 2 or 3 arguments. +if (CMAKE_USE_PTHREADS_INIT) + check_c_source_compiles(" +#include <pthread.h>\n +int main(void) { (void)pthread_setname_np(\"thread-name\"); return 0; }" + HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID) + if (HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID) + # Define to use 'pthread_setname_np(const char*)' function. + add_definitions("-DHAVE_PTHREAD_SETNAME_NP_WITHOUT_TID") + else() + check_c_source_compiles(" +#include <pthread.h>\n +int main(void) {\n + (void)pthread_setname_np(pthread_self(), \"thread-name-%u\", 0); return 0; }" + HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG) + if (HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG) + # Define to use 'pthread_setname_np(pthread_t, const char*, void *)'. + add_definitions("-DHAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG") + else() + check_c_source_compiles(" +#if defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) || defined(__CYGWIN__)\n +#define _GNU_SOURCE 1\n +#endif\n +#include <pthread.h>\n +int main(void) {\n + (void)pthread_setname_np(pthread_self(), \"thread-name\"); return 0; }" + HAVE_PTHREAD_SETNAME_NP_WITH_TID) + if (HAVE_PTHREAD_SETNAME_NP_WITH_TID) + # Define to use 'pthread_setname_np(pthread_t, const char*)' function. + add_definitions("-DHAVE_PTHREAD_SETNAME_NP_WITH_TID") + endif() + endif(HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG) + endif (HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID) +endif() + +# Check for dladdr (used for debugging). +check_c_source_compiles(" +#define _GNU_SOURCE 1\n +#include <dlfcn.h>\n +int main(void) { Dl_info info; (void)dladdr(\"\", &info); return 0; }" + HAVE_DLADDR) +if (HAVE_DLADDR) + # Define to use 'dladdr' function. + add_definitions("-DHAVE_DLADDR") +endif() + +add_library(gc ${SRC}) +target_link_libraries(gc PRIVATE ${THREADDLLIBS_LIST} ${ATOMIC_OPS_LIBS}) +target_include_directories(gc INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + "$<INSTALL_INTERFACE:include>") + +if (enable_cplusplus) + add_library(gccpp gc_badalc.cc gc_cpp.cc) + target_link_libraries(gccpp PRIVATE gc) + target_include_directories(gccpp INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + "$<INSTALL_INTERFACE:include>") + if (enable_throw_bad_alloc_library) + # The same as gccpp but contains only gc_badalc. + add_library(gctba gc_badalc.cc) + target_link_libraries(gctba PRIVATE gc) + target_include_directories(gctba INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + "$<INSTALL_INTERFACE:include>") + endif(enable_throw_bad_alloc_library) +endif() + +if (build_cord) + set(CORD_SRC cord/cordbscs.c cord/cordprnt.c cord/cordxtra.c) + add_library(cord ${CORD_SRC}) + target_link_libraries(cord PRIVATE gc) + target_include_directories(cord INTERFACE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" + "$<INSTALL_INTERFACE:include>") + if (BUILD_SHARED_LIBS) + set_property(TARGET cord PROPERTY VERSION ${CORD_VERSION_PROP}) + set_property(TARGET cord PROPERTY SOVERSION ${CORD_SOVERSION}) + endif() + install(TARGETS cord EXPORT BDWgcTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") +endif(build_cord) + +if (BUILD_SHARED_LIBS AND HAVE_FLAG_WL_NO_UNDEFINED) + # Declare that the libraries do not refer to external symbols. + # TODO: use add_link_options() when cmake_minimum_required > 3.13 + target_link_libraries(gc PRIVATE -Wl,--no-undefined) + if (enable_cplusplus) + target_link_libraries(gccpp PRIVATE -Wl,--no-undefined) + if (enable_throw_bad_alloc_library) + target_link_libraries(gctba PRIVATE -Wl,--no-undefined) + endif(enable_throw_bad_alloc_library) + endif(enable_cplusplus) + if (build_cord) + target_link_libraries(cord PRIVATE -Wl,--no-undefined) + endif(build_cord) +endif() + +if (BUILD_SHARED_LIBS) + set_property(TARGET gc PROPERTY VERSION ${GC_VERSION_PROP}) + set_property(TARGET gc PROPERTY SOVERSION ${GC_SOVERSION}) +endif() +install(TARGETS gc EXPORT BDWgcTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + +if (enable_cplusplus) + if (BUILD_SHARED_LIBS) + set_property(TARGET gccpp PROPERTY VERSION ${GCCPP_VERSION_PROP}) + set_property(TARGET gccpp PROPERTY SOVERSION ${GCCPP_SOVERSION}) + endif() + install(TARGETS gccpp EXPORT BDWgcTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + if (enable_throw_bad_alloc_library) + if (BUILD_SHARED_LIBS) + set_property(TARGET gctba PROPERTY VERSION ${GCCPP_VERSION_PROP}) + set_property(TARGET gctba PROPERTY SOVERSION ${GCCPP_SOVERSION}) + endif() + install(TARGETS gctba EXPORT BDWgcTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + endif(enable_throw_bad_alloc_library) +endif(enable_cplusplus) + +if (install_headers) + install(FILES include/gc.h + include/gc_backptr.h + include/gc_config_macros.h + include/gc_inline.h + include/gc_mark.h + include/gc_tiny_fl.h + include/gc_typed.h + include/gc_version.h + include/javaxfc.h + include/leak_detector.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc") + install(FILES include/extra/gc.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + if (enable_cplusplus) + install(FILES include/gc_allocator.h + include/gc_cpp.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc") + install(FILES include/extra/gc_cpp.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + endif() + if (enable_disclaim) + install(FILES include/gc_disclaim.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc") + endif() + if (enable_gcj_support) + install(FILES include/gc_gcj.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc") + endif() + if (enable_threads AND CMAKE_USE_PTHREADS_INIT) + install(FILES include/gc_pthread_redirects.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc") + endif() + if (build_cord) + install(FILES include/cord.h + include/cord_pos.h + include/ec.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gc") + endif() + + # Provide pkg-config metadata. + set(prefix "${CMAKE_INSTALL_PREFIX}") + set(exec_prefix \${prefix}) + set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}") + set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}") + string(REPLACE ";" " " THREADDLLIBS "${THREADDLLIBS_LIST}") + # ATOMIC_OPS_LIBS, PACKAGE_VERSION are defined above. + configure_file(bdw-gc.pc.in bdw-gc.pc @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/bdw-gc.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +endif(install_headers) + +if (build_tests) + if (build_cord) + add_executable(cordtest cord/tests/cordtest.c) + target_link_libraries(cordtest PRIVATE cord gc) + add_test(NAME cordtest COMMAND cordtest) + + if (WIN32 AND NOT CYGWIN) + add_executable(de cord/tests/de.c cord/tests/de_win.c + cord/tests/de_win.rc) + set_target_properties(de PROPERTIES WIN32_EXECUTABLE TRUE) + target_link_libraries(de PRIVATE cord gc gdi32) + endif() + endif(build_cord) + + # Compile some tests as C++ to test extern "C" in header files. + if (enable_cplusplus) + set_source_files_properties(tests/leak_test.c PROPERTIES LANGUAGE CXX) + if (NOT MSVC) + # WinMain-based test hangs at startup if compiled by VC as C++ code. + set_source_files_properties(tests/test.c PROPERTIES LANGUAGE CXX) + endif() + # To avoid "treating 'c' input as 'c++' when in C++ mode" Clang warning. + if (NOT (BORLAND OR MSVC OR WATCOM)) + add_compile_options(-x c++) + endif() + endif(enable_cplusplus) + + add_executable(gctest WIN32 tests/test.c) + target_link_libraries(gctest PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME gctest COMMAND gctest) + if (WATCOM) + # Suppress "conditional expression in if statement is always true/false" + # and "unreachable code" warnings in GC_MALLOC_ATOMIC_WORDS. + target_compile_options(gctest PRIVATE + /wcd=13 /wcd=201 /wcd=367 /wcd=368 /wcd=726) + endif() + + add_executable(hugetest tests/huge_test.c) + target_link_libraries(hugetest PRIVATE gc) + add_test(NAME hugetest COMMAND hugetest) + + add_executable(leaktest tests/leak_test.c) + target_link_libraries(leaktest PRIVATE gc) + add_test(NAME leaktest COMMAND leaktest) + + add_executable(middletest tests/middle.c) + target_link_libraries(middletest PRIVATE gc) + add_test(NAME middletest COMMAND middletest) + + add_executable(realloc_test tests/realloc_test.c) + target_link_libraries(realloc_test PRIVATE gc) + add_test(NAME realloc_test COMMAND realloc_test) + + add_executable(smashtest tests/smash_test.c) + target_link_libraries(smashtest PRIVATE gc) + add_test(NAME smashtest COMMAND smashtest) + + if (NOT (BUILD_SHARED_LIBS AND WIN32)) + add_library(staticrootslib_test tests/staticrootslib.c) + target_link_libraries(staticrootslib_test PRIVATE gc) + add_library(staticrootslib2_test tests/staticrootslib.c) + target_compile_options(staticrootslib2_test PRIVATE "-DSTATICROOTSLIB2") + target_link_libraries(staticrootslib2_test PRIVATE gc) + add_executable(staticrootstest tests/staticrootstest.c) + target_compile_options(staticrootstest PRIVATE "-DSTATICROOTSLIB2") + target_link_libraries(staticrootstest PRIVATE + gc staticrootslib_test staticrootslib2_test) + add_test(NAME staticrootstest COMMAND staticrootstest) + endif() + + if (enable_gc_debug) + add_executable(tracetest tests/trace_test.c) + target_link_libraries(tracetest PRIVATE gc) + add_test(NAME tracetest COMMAND tracetest) + endif() + + if (enable_threads) + add_executable(test_atomic_ops tests/test_atomic_ops.c) + target_link_libraries(test_atomic_ops PRIVATE gc) + add_test(NAME test_atomic_ops COMMAND test_atomic_ops) + + add_executable(threadleaktest tests/thread_leak_test.c) + target_link_libraries(threadleaktest PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME threadleaktest COMMAND threadleaktest) + + if (NOT WIN32) + add_executable(threadkey_test tests/threadkey_test.c) + target_link_libraries(threadkey_test PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME threadkey_test COMMAND threadkey_test) + endif() + + add_executable(subthreadcreate_test tests/subthread_create.c) + target_link_libraries(subthreadcreate_test PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME subthreadcreate_test COMMAND subthreadcreate_test) + + add_executable(initsecondarythread_test tests/initsecondarythread.c) + target_link_libraries(initsecondarythread_test + PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME initsecondarythread_test COMMAND initsecondarythread_test) + endif(enable_threads) + + if (enable_cplusplus) + add_executable(test_cpp WIN32 tests/test_cpp.cc) + target_link_libraries(test_cpp PRIVATE gc gccpp) + add_test(NAME test_cpp COMMAND test_cpp) + endif() + + if (enable_disclaim) + add_executable(disclaim_bench tests/disclaim_bench.c) + target_link_libraries(disclaim_bench PRIVATE gc) + add_test(NAME disclaim_bench COMMAND disclaim_bench) + + add_executable(disclaim_test tests/disclaim_test.c) + target_link_libraries(disclaim_test PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME disclaim_test COMMAND disclaim_test) + + add_executable(disclaim_weakmap_test tests/disclaim_weakmap_test.c) + target_link_libraries(disclaim_weakmap_test + PRIVATE gc ${THREADDLLIBS_LIST}) + add_test(NAME disclaim_weakmap_test COMMAND disclaim_weakmap_test) + endif() +endif(build_tests) + +if (enable_docs) + # Note: documentation which is not installed: README.QUICK + install(FILES AUTHORS README.md + DESTINATION "${CMAKE_INSTALL_DOCDIR}") + install(DIRECTORY doc/ DESTINATION "${CMAKE_INSTALL_DOCDIR}" + FILES_MATCHING + PATTERN "README.*" + PATTERN "*.md") + + install(FILES doc/gc.man DESTINATION "${CMAKE_INSTALL_MANDIR}/man3" + RENAME gc.3) +endif(enable_docs) + +# CMake config/targets files. +install(EXPORT BDWgcTargets FILE BDWgcTargets.cmake + NAMESPACE BDWgc:: DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/bdwgc") + +configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfig.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/bdwgc" + NO_SET_AND_CHECK_MACRO) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfigVersion.cmake" + VERSION "${PACKAGE_VERSION}" COMPATIBILITY AnyNewerVersion) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/BDWgcConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/bdwgc") + +export(EXPORT BDWgcTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/BDWgcTargets.cmake")
View file
_service:tar_scm:gc-8.0.6.tar.gz/ChangeLog -> _service:tar_scm:gc-8.2.2.tar.gz/ChangeLog
Changed
@@ -1,4 +1,435 @@ +== 8.2.2 2022-08-26 == + +* Abort if no progress with thread suspend/resume signals resending +* Add CMake option to force libatomic_ops headers usage +* Add _PROP suffix to CORD/GCCPP_VERSION variables in CMake script +* Allow not to bypass pthread_cancel hardening in pthread_start +* Allow to start marker threads in child of single-threaded client +* Avoid potential race in GC_init_real_syms after GC_allow_register_threads +* Avoid potential signal loss before sigsuspend in suspend_handler if TSan +* Define SUNOS5SIGS macro for kFreeBSD +* Distribute gc_gcj.h and some other headers in single-obj-compilation +* Do not assert that GC is initialized at DLL_THREAD_DETACH (Win32) +* Do not call SET_HDR() to remove forwarding counts if none exists in hblk +* Do not call mprotect/mmap to GC_unmap/remap (Linux) +* Do not count unmapped regions if GC_unmap is madvise-based (Linux) +* Do not define NEED_FIND_LIMIT in case of OpenBSD user threads +* Do not fail tests if pthread_create returns resource unavailable error +* Do not name GCC intrinsics as C11 ones +* Do not probe to find main data root start if dl_iterate_phdr exists +* Do not send signal to thread which is suspended manually +* Do not use usleep between signals resend if ThreadSanitizer +* Eliminate '-pedantic is not option that controls warnings' GCC-6.3 message +* Eliminate '/GS can not protect parameters' MS VC warning in msvc_dbg +* Eliminate 'R_AARCH64_ABS64 used with TLS symbol' linker warning (clang) +* Eliminate 'buffer overflow detected' FP error in realloc_test +* Eliminate 'extension used' clang warning in sparc_mach_dep.S (configure) +* Eliminate 'function/data pointer conversion in expression' MSVC warning +* Eliminate 'implicit decl of _setjmp' gcc warning if -std=c11 on Cygwin +* Eliminate 'layout of aggregates has changed in GCC 5' warning in test_cpp +* Eliminate 'new_l may be used uninitialized' gcc warning in os_dep (Cygwin) +* Eliminate 'old_gc_no is initialized but not referenced' MS VC false warning +* Eliminate 'possible loss of data' compiler warning in GC_envfile_getenv +* Eliminate 'potentially uninitialized local variable tc' warning (MSVC) +* Eliminate 'skipping config since MAX_HEAP_SECTS is unknown' cppcheck FP +* Eliminate 'unused but set variable' gcc warnings in cpptest +* Eliminate 'value exceeds maximum size' warnings in debug_malloc, huge_test +* Eliminate 'writing into region of size 0' gcc FP warning in realloc +* Eliminate ASan stack-buffer-underflow FP in GC_mark_and_push_stack (E2K) +* Eliminate code defect about incorrect size of allocated object (leaktest) +* Eliminate data race reported by TSan in GC_have_errors +* Eliminate division-by-zero FP warning in GC_ASSERT in reclaim_block +* Eliminate stringop-overflow gcc-12 warning in CORD__next +* Ensure typed objects descriptor is never located in the first word +* Fix 'GC_greatest_stack_base_below is defined but not used' warning (IA64) +* Fix 'GC_text_mapping not used' GCC warning if redirect malloc w/o threads +* Fix 'ISO C forbids conversion of function pointer to object' warning +* Fix 'undeclared getpagesize' compiler warning on AIX and OSF1 +* Fix 'undefined reference to __data_start' linker error on Linux/aarch64 +* Fix 'unresolved __imp__wsprintfA' linker error in msvc_dbg.c (MSVC) +* Fix 'unresolved symbol GetModuleHandle' error in win32_threads.c (UWP) +* Fix (workaround) stack overflow in gctest on Alpine Linux/s390x +* Fix GC_ATTR_NO_SANITIZE_THREAD definition for GCC +* Fix GC_allocate_ml incorrect cleanup in GC_deinit if pthreads (MinGW) +* Fix GC_dirty() argument in GC_malloc_explicitly_typed_ignore_off_page +* Fix GC_make_descriptor for zero length argument +* Fix GC_suspend_thread if called before thread destructor +* Fix GC_unmapped_bytes update in GC_unmap for Sony PS/3 +* Fix SIGSEGV caused by dropped stack access from child process in gctest +* Fix SUNOS5SIGS documentation to match macro definition in gcconfig.h +* Fix abort in Win32 DllMain if PARALLEL_MARK +* Fix abort when GC_repeat_read returns zero +* Fix assertion about built-in AO_test_and_set_acquire on sparc64 (gcc-12) +* Fix assertion violation in GC_allow_register_threads on Windows +* Fix assertion violation of GC_thread_key alignment if pthread-based TLS +* Fix comment in GC_init regarding GC_init_parallel call +* Fix context saving when GC_suspend_thread(self) +* Fix data race in fail_proc1 of gctest +* Fix hang in GC_free if GC_PREFER_MPROTECT_VDB (Mingw64) +* Fix hang in select() called from suspend signal handler if TSan +* Fix hang on sem_wait in GC_suspend_thread if thread was resumed recently +* Fix hb_obj_kind type in documentation (ASCII diagram) describing hblkhdr +* Fix incremental mode enabling in gctest if TEST_MANUAL_VDB +* Fix linking of tests in case of finalization is off +* Fix lock assertion violation in GC_find_limit if always multi-threaded +* Fix memory return to OS in GC_unmap +* Fix missing lock when GC_generate_random_valid_address is called +* Fix missing write() declaration if CONSOLE_LOG (Watcom) +* Fix nodist_libgc_la_SOURCES value in Makefile.am for Solaris/sparc +* Fix oldProc initialization in gc_cleanup and eliminate related warnings +* Fix parallel_initialized assertion violation in initsecondarythread (Win32) +* Fix potential race if start_mark_threads called from threads in child +* Fix propagation of out-of-memory occurred in GC_make_sequence_descriptor +* Fix pthread_setname_np and dladdr detection by CMake +* Fix race between calloc_explicitly_typed and push_complex_descriptor +* Fix typos in comments and debugging.md +* Fix undefined __stack_base__ on UWP/arm64 (llvm-mingw) +* Force GC_with_callee_saves_pushed in suspend_handler if NO_SA_SIGACTION +* Link with rt library to get clock_gettime where necessary +* Make finalizer_closure pointer read/write atomic in malloc and callback +* Move platform-specific sleep call to GC_usleep (refactoring) +* Pass -lrt linker option in CMake script on HP/UX, NetBSD +* Prevent (fix) parallel custom mark procs run in single-threaded clients +* Prevent changing of GC_markers_m1 value while collection in progress +* Refer to Makefile.direct instead of deleted Makefile file in README +* Relax assertion of hb_n_marks in reclaim_block if more than two markers +* Remove IF_IA64 macro in pthread_stop_world (refactoring) +* Remove checking of RS6000 completely +* Remove duplicate check of MSWIN_XBOX1 in os_dep.c +* Remove duplicate include gc_tiny_fl.h in gc_priv.h +* Remove non-working check of M68K in gctest +* Remove useless TSan W/A about read of mark_lock_holder for Windows +* Replace RAISE_SIGNAL macro with a static function (refactoring) +* Replace SSH cloning with HTTPS one in README +* Retry pthread_kill if EAGAIN (Linux) +* Revert "Check real-symbols are already initialized in pthread_join/detach" +* Revert "Remove nested always-false ifdef for HPUX and FREEBSD" +* Revert addition of msvc_dbg.h in include.am +* Set default build type to RelWithDebInfo (CMake) +* Start configure help messages with a lower case letter +* Support 'z' format modifier by CORD_vsprintf +* Support Elbrus 2000 (Linux/e2k) +* Support GCC MCF thread model (mcfgthreads) in configure (MinGW) +* Support GC_remove_roots on Win32 +* Support OpenBSD/riscv64 +* Support build using Makefile.direct on Linux/sparc +* Support space-separated flags in CFLAGS_EXTRA passed to CMake +* Update README.win32 about default build configuration (configure, cmake) +* Update documentation of GC_RATE and MAX_PRIOR_ATTEMPTS +* Use SIGRTMIN+6 as suspend signal if sigrt-signals on OpenBSD +* Use SIGUSR1/2 on FreeBSD/arm64 +* Use compiler TLS on NetBSD only if at least gcc-4.4 or clang-3.9 +* Workaround 'info is not assigned' cppcheck FP if assertions on (OS X) +* Workaround SIG_SUSPEND delivery to thread inside mutex_lock fail if TSan +* Workaround TSan FP about race between generic_malloc and array_mark_proc +* Workaround TSan FP in acquire_mark_lock called from fork_prepare_proc +* Workaround TSan FP warning in finalized_malloc, push_unconditionally +* Workaround TSan FP warning in fork_prepare_proc +* Workaround TSan FP warning in push_marked1/2/4, ptr_store_and_dirty +* Workaround Thread Sanitizer (TSan) FP warning in is_valid_displacement +* Workaround call stack size exceeded in gctest (Wasm) +* Workaround crash in FreeBSD rand() by avoiding its concurrent usage +* Workaround gctest hang if test compiled as C++ code by MSVC (CMake) +* Workaround msvc_dbg.c build failure on arm64 (MSVC) + + +== 8.2.0 2021-09-29 == + +* Add API for accessing incremental GC time limit with nanosecond precision +* Add API function to force start of incremental collection +* Add GC_ prefix to scan_ptr and some other static variables (refactoring) +* Add GC_get/set_disable_automatic_collection API +* Add I_HOLD_LOCK assertion to expand_hp_inner and related functions +* Add assertion on free-list argument and result of GC_new_kind +* Add assertion that GC is initialized to base incremental_protection_needs +* Add assertions that GC_page_size is initialized +* Add cordtest, staticrootstest, test_cpp, tracetest, disclaim tests (CMake) +* Add debug messages on thread suspend/resume (Win32) +* Add dummy testing of GC_incr_bytes_allocd/freed +* Add table of contents in gcdescr.md +* Add testing of GC_CALLOC/MALLOC_EXPLICITLY_TYPED (gctest) +* Adjust formatting of numbered lists in README.md to match other .md files +* Adjust highlighting of API prototypes in gcinterface.md +* Adjust macro def/usage for AVR32, CRIS, NETBSD, OPENBSD, SH4 in gcconfig.h +* Adjust printf calls in gctest check_heap_stats so that each has new-line +* Allow incremental GC on Cygwin +* Allow memory unmapping in case of MPROTECT_VDB +* Allow to disable GWW or mprotect-based VDB at build +* Allow to disable Glibc FPU exception mask and TSX workarounds (Linux) +* Allow to disable __builtin_return_address(1) usage (x86 and x64) +* Allow to specify custom value of LOG_PHT_ENTRIES +* Always abort on failure to access /proc/self/maps (Linux) +* Always define default_push_other_roots (code refactoring) +* Avoid gcc stringop-overflow warning for intended overflow in smashtest +* Avoid initial 3ms pause on world stop/start with GC_retry_signals (Linux) +* Build cord.lib by Makefile.direct, NT_MAKEFILE, OS2_MAKEFILE, WCC_MAKEFILE +* Build gc as a shared multi-threaded library by default (CMake) +* Build gccpp library by Makefile.direct, NT_MAKEFILE and WCC_MAKEFILE +* Build gctba library +* Build shared libraries by default (WCC_MAKEFILE) +* Change CLOCK_TYPE to timespec for Nintendo Switch (code refactoring) +* Change EMSCRIPTEN macro for internal use to no-underscore format +* Change log_size fields of finalizer to unsigned type (code refactoring) +* Change type of toggleref_array_size/capacity to size_t (code refactoring) +* Check leak of objects allocated by CRT malloc in gctest (MS VC) +* Check real-symbols are already initialized in pthread_join/detach +* Collapse multiple includes of windows.h (code refactoring) +* Comments reformatting in mark.c to properly delimit sentences +* Compile de test GUI app with resources (CMake) +* Compile gc.c unless building static libraries (NT_MAKEFILE, WCC_MAKEFILE) +* Compile msvc_dbg.c by CMake script (MS VC) +* Declare API function and print amount of memory obtained from OS +* Define GC_win32_free_heap API function for all Windows targets +* Define STATIC macro to static by default +* Depend number of fork_a_thread calls on NTHREADS (gctest) +* Detect dladdr() presence in CMake script +* Detect presence of execinfo.h system header in CMake script +* Detect presence of getcontext and dl_iterate_phdr in CMake script +* Detect sigsetjmp() availability in CMake script +* Disable Clang/GCC aliasing optimization in CMake script by default +* Do not build tests by default (Makefile.direct and other Makefiles) +* Do not build the tests by default (CMake) +* Do not call GC_push_conditional unless PROC_VDB +* Do not call add_to_our_memory with null pointer (refactoring) +* Do not compile pthread_*.c files in Cygwin or MSYS (CMake) +* Do not define GC_write_cs for Xbox One target +* Do not define HAVE_NO_FORK for all Unix-like systems +* Do not hard-code CMAKE_DL_LIBS value and install paths (CMake) +* Do not hard-code finalizable objects limit which triggers GC +* Do not update scratch_last_end_ptr unless used by reg dynamic libraries +* Document GC_incr_bytes_allocd/freed API function +* Eliminate '(long)size<=0 is always false' cppcheck FP +* Eliminate 'Consecutive return is unnecessary' cppcheck style warning +* Eliminate 'accessing GC_dont_gc without lock' in GC_init code defect FP +* Eliminate 'bytes_freed access w/o lock in incr_bytes_free' code defect FP +* Eliminate 'checking if unsigned i < 0' cppcheck FP in is_heap_base +* Eliminate 'hash_val value is never used' cppcheck false positive +* Eliminate 'passing tainted var maps_buf to tainted sink' code defect FP +* Eliminate 'retry_cnt is assigned value but never used' cppcheck FP +* Eliminate 'stop variable is always 0' compiler warning in print_callers +* Eliminate 'struct member os_callback is never used' cppcheck warning +* Eliminate 't->flags not atomically updated' code defect FP +* Eliminate 'tmpl might be accessed at non-zero index' cppcheck error +* Eliminate GCC warning of unsafe __builtin_return_address(1) +* Eliminate code duplication in reclaim_clear and disclaim_and_reclaim +* Eliminate double lock code defect false positive in generic_lock +* Eliminate memory leak reported in add_current_malloc_heap at exit (Win32) +* Emscripten single-threaded support (detect stack base, push registers) +* Enable CMake-based build for Borland and Watcom compilers +* Enable compilation without C runtime (Win32) +* Enable fork testing in single-thread builds (Unix-like) +* Enable mprotect-based incremental GC for Linux/arm and Linux/aarch64 +* Enable true incremental collection even if parallel marker is on +* Enable use of __builtin_unwind_init() if clang-8 or later +* Ensure ELFSIZE is defined in dyn_load.c for OpenBSD (code refactoring) +* Ensure add_to_heap_inner arguments are valid (refactoring) +* Ensure all getters and setters are run at least once by gctest (pthreads) +* Export CMake targets with namespace BDWgc +* Fix 'const obj must be initialized if not extern' error in gc_alloc_ptrs.h +* Fix ./libgc.la dependency on FreeBSD (Automake) +* Fix HOST determination in CMake script +* Fix copyright message in de_win.rc, gc_cpp.cc, ec.h and specific.h +* Fix missing OS_TYPE definition for some targets +* Fix mmap(PROT_NONE) failure if RLIMIT_AS value is low (Linux) +* Generate cordtest and de executable files in GC base folder +* Generate pkg-config metadata file (CMake) +* Get rid of some non-ELF ifdefs (code refactoring) +* Handle potential incomplete buffer read in GC_linux_main_stack_base +* Implement GET_TIME for Nintendo Switch +* Increase NTHREADS value in tests if code coverage analysis +* Install docs and man page if enable_docs (CMake) +* Install gc_gcj.h and gc_pthread_redirects.h only if appropriate +* Log abort message details even if not print_stats (unless SMALL_CONFIG) +* Mark buffer returned by get_maps as const (code refactoring) +* Move C++ GC_ATTR_EXPLICIT and GC_NOEXCEPT definition to gc_config_macros.h +* Move GC state non-pointer variables into GC_arrays (code refactoring) +* Move GC state pointer variables into GC_arrays +* Move GC_scratch_recycle_inner() to alloc.c (refactoring) +* Move GC_throw_bad_alloc definition to new C++ file +* Move QNX and Emscripten macro definitions to proper place in gcconfig.h +* Move definition of GC_n_mark_procs and GC_n_kinds from mark.c to misc.c +* New API (GC_set_markers_count) to control number of parallel markers +* New API function to clear GC exclusion table +* New API function to get size of object debug header +* New API standalone functions to acquire and release the allocator lock +* New CMake option (disable_gc_debug) to remove debugging code +* New CMake option (disable_handle_fork) to disable fork handling completely +* New macro (CONSOLE_LOG) to enable logging to console on Win32 +* New macro (GCTEST_PRINT_VERBOSE) to enable verbose logging in test.c only +* New macro (NO_MSGBOX_ON_ERROR) to avoid message box on GC abort (Win32) +* OpenBSD does not use ELF_CLASS (code refactoring) +* Pass -D GC_DLL -fvisibility=hidden if default configure build is requested +* Pass -no-undefined linker flag if building shared libraries (CMake) +* Print pid of child processes if verbose logging (gctest) +* Read environment variables from a file on WinCE (CMake script) +* Reduce stack-allocated buffer in get_nprocs from 4KB to 1.7KB +* Refine flags field comment in pthread_support.h +* Reflect result of VDB selection at runtime in incremental_protection_needs +* Reformat code of GC_push_roots +* Reformat gc.man (wrap long lines) +* Reformatting and code refactoring of CMake script +* Remove 'current users' section from overview.md +* Remove 'distributed ports', 'scalable versions' sections from overview.md +* Remove AC_MSG_RESULT for THREADDLLIBS (dgux386) +* Remove Borland-specific Makefile and gc.mak script +* Remove GC_eobjfreelist variable in typd_mlc.c (code refactoring) +* Remove GC_gcj_malloc_initialized variable (code refactoring) +* Remove Linux-specific commands for building cord/de from Makefile.direct +* Remove Win32 main_thread static variable if threads discovery is disabled +* Remove code duplication between GC_unmap and GC_unmap_gap (refactoring) +* Remove code duplication between PROTECT and UNPROTECT macros (refactoring) +* Remove commented out assignment of gc_use_mmap in configure (refactoring) +* Remove dash characters comprising prefix of some verbose logs (gctest) +* Remove dependency on user32.dll import library from static libgc (Win32) +* Remove documentation specific to particular old BDWGC releases +* Remove duplicate Linux-related macro definitions in gcconfig.h +* Remove duplicate macro definitions in gcconfig.h except for Linux +* Remove gcmt-dll generation, rename libgc-lib.a to libgc.a (CMake) +* Remove goto statement in print_callers (code refactoring) +* Remove limit on number of heap sections +* Remove new_gc_alloc.h file +* Remove redundant GC_with_callee_saves_pushed call in multi-threaded builds +* Remove redundant check of GC_free argument in register_finalizer +* Remove redundant type casts in backgraph HEIGHT_UNKNOWN/IN_PROGRESS +* Remove unused GC_prev_heap_addr (refactoring) +* Remove unused STACK_GRAN macro definitions (code refactoring) +* Remove unused sparc_sunos4_mach_dep.s file +* Remove useless empty statements after block ones (refactoring) +* Remove weakobj_free_list variable in disclaim_weakmap_test (refactoring) +* Rename READ to PROC_READ in os_dep.c (code refactoring) +* Rename cord/cord test executable to de (CMake) +* Rename ext_descr to typed_ext_descr_t (code refactoring) +* Rename gc64.dll to gc.dll and gc64_dll.lib to gc.lib in NT_MAKEFILE +* Rename gc68060.lib to gc.lib, cord/cord68060.lib to cord.lib in SMakefile +* Rename make_as_lib option to enable_static in NT_MAKEFILE and WCC_MAKEFILE +* Rename nothreads option to disable_threads in NT_MAKEFILE +* Repeat run_one_test NTHREADS times by gctest if single-threaded +* Replace "msecs" with "ms" in all comments and messages +* Replace 'stack base' with 'stack bottom' in the documentation +* Replace SN_TARGET_ORBIS to PLATFORM_* and GC_NO_* macros +* Replace _M_AMD64 macro with _M_X64 (code refactoring) +* Replace find_limit_openbsd to find_limit_with_bound (OpenBSD 5.2+) +* Replace obsolete AC_HELP_STRING with AS_HELP_STRING (refactoring) +* Replace push_one calls with push_many_regs one for Win32 thread context +* Report memory region bounds and errno on GC_unmap/remap failure +* Report presence of process fork testing (gctest) +* Report time with a nanosecond precision where available +* Retry suspend/resume signals on all platforms by default +* Run tree and typed tests in child process (gctest) +* Set GC_collecting hint for GC_collect_a_little_inner calls (pthreads) +* Set name of GC marker threads +* Set so-version for installed shared libraries (CMake) +* Simplify logged message in scratch_recycle +* Simplify loops of collect_a_little/stopped_mark invoking mark_some +* Support -fvisibility=hidden option in CMake script +* Support CFLAGS_EXTRA to pass extra user-defined compiler flags (CMake) +* Support FreeBSD/RISC-V, Linux/arc, LoongArch, OpenBSD/powerpc64 +* Support header files installation (CMake) +* Support most configure options in CMake script +* Suppress warnings in test_tinyfl() of gctest reported by Watcom C complier +* Take nanoseconds into account when updating full_gc_total_time +* Turn off C++ API by default, export it in gccpp library (CMake) +* Turn on automatic fork() handling by default on Android +* Update README.cmake regarding Unix, C++ and tests +* Update libgc.so version info to differentiate against v8.0.x +* Update the ASCII diagrams describing the tree structure for pointer lookups +* Update the documentation to match the current GC implementation +* Upgrade cmake_minimum_required(version) to 3.1 +* Use CreateThread without GC_ prefix in gctest (code refactoring) +* Use KB/MB/GB abbreviations uniformly across entire documentation +* Use USE_MMAP_ANON when USE_MMAP is configured on OpenBSD +* Use a specific Emscripten allocator for Tiny +* Use atomic primitives for Sony PlayStation Portable 2 and PS4 +* Use better precision Windows timers +* Use clock_gettime() instead of clock() on Cygwin and Linux +* Use compiler TLS on FreeBSD and NetBSD +* Use mprotect-based VDB on PowerPC and S390 (Linux) +* Use soft dirty bits on Linux (i386, powerpc, s390, x86_64) +* Workaround 'condition result<=0 is always false' cppcheck FP in get_maps +* Workaround 'push_regs configured incorrectly' error (GCC-11) +* Workaround 'same value in both branches of ternary operator' cppcheck FP +* Workaround various cppcheck false positives + + +== 8.0.8 2022-08-26 == + +* Avoid potential race in GC_init_real_syms after GC_allow_register_threads +* Define SUNOS5SIGS macro for kFreeBSD +* Distribute gc_disclaim.h in single-obj-compilation +* Do not assert that GC is initialized at DLL_THREAD_DETACH (Win32) +* Do not name GCC intrinsics as C11 ones +* Do not send signal to thread which is suspended manually +* Eliminate 'buffer overflow detected' FP error in realloc_test +* Eliminate 'extension used' clang warning in sparc_mach_dep.S (configure) +* Eliminate 'function/data pointer conversion in expression' MSVC warning +* Eliminate 'implicit decl of _setjmp' gcc warning if -std=c11 on Cygwin +* Eliminate 'new_l may be used uninitialized' gcc warning in os_dep (Cygwin) +* Eliminate 'old_gc_no is initialized but not referenced' MS VC false warning +* Eliminate 'possible loss of data' compiler warning in GC_envfile_getenv +* Eliminate 'value exceeds maximum size' warnings in debug_malloc, huge_test +* Eliminate 'writing into region of size 0' gcc FP warning in realloc +* Eliminate division-by-zero FP warning in GC_ASSERT in reclaim_block +* Eliminate stringop-overflow gcc-12 warning in CORD__next +* Ensure typed objects descriptor is never located in the first word +* Fix 'GC_greatest_stack_base_below is defined but not used' warning (IA64) +* Fix 'GC_text_mapping not used' GCC warning if redirect malloc w/o threads +* Fix 'ISO C forbids conversion of function pointer to object' warning +* Fix 'undeclared getpagesize' compiler warning on AIX and OSF1 +* Fix 'undefined reference to __data_start' linker error on Linux/aarch64 +* Fix GC_allocate_ml incorrect cleanup in GC_deinit if pthreads (MinGW) +* Fix GC_dirty() argument in GC_malloc_explicitly_typed_ignore_off_page +* Fix GC_make_descriptor for zero length argument +* Fix GC_suspend_thread if called before thread destructor +* Fix GC_unmapped_bytes update in GC_unmap for Sony PS/3 +* Fix SIGSEGV caused by dropped stack access from child process in gctest +* Fix SUNOS5SIGS documentation to match macro definition in gcconfig.h +* Fix abort in Win32 DllMain if PARALLEL_MARK +* Fix assertion about built-in AO_test_and_set_acquire on sparc64 (gcc-12) +* Fix assertion violation in GC_allow_register_threads on Windows +* Fix assertion violation of GC_thread_key alignment if pthread-based TLS +* Fix context saving when GC_suspend_thread(self) +* Fix data race in fail_proc1 of gctest +* Fix get_maps failure when GC_repeat_read returns zero +* Fix hang in GC_free if GC_PREFER_MPROTECT_VDB (Mingw64) +* Fix hang in select() called from suspend signal handler if TSan +* Fix hang on sem_wait in GC_suspend_thread if thread was resumed recently +* Fix hb_obj_kind type in documentation (ASCII diagram) describing hblkhdr +* Fix incremental mode enabling in gctest if TEST_MANUAL_VDB +* Fix lock assertion violation in GC_find_limit if always multi-threaded +* Fix missing lock when GC_generate_random_valid_address is called +* Fix nodist_libgc_la_SOURCES value in Makefile.am for Solaris/sparc +* Fix oldProc initialization in gc_cleanup and eliminate related warnings +* Fix parallel_initialized assertion violation in initsecondarythread (Win32) +* Fix potential race if start_mark_threads called from threads in child +* Fix propagation of out-of-memory occurred in GC_make_sequence_descriptor +* Fix race between calloc_explicitly_typed and push_complex_descriptor +* Fix stack overflow in gctest on Alpine Linux/s390x +* Fix typo in debugging.html +* Fix typos in comments of .c files and gc.h +* Fix undefined __stack_base__ on UWP/arm64 (llvm-mingw) +* Make finalizer_closure pointer read/write atomic in malloc and callback +* Prevent (fix) parallel custom mark procs run in single-threaded clients +* Prevent changing of GC_markers_m1 value while collection in progress +* Refer to Makefile.direct instead of deleted Makefile file in README +* Relax assertion of hb_n_marks in reclaim_block if more than two markers +* Remove checking of RS6000 completely +* Remove duplicate check of MSWIN_XBOX1 in os_dep.c +* Remove non-working check of M68K in gctest +* Remove useless TSan W/A about read of mark_lock_holder for Windows +* Replace SSH cloning with HTTPS one in README +* Revert "Remove nested always-false ifdef for HPUX and FREEBSD" +* Revert addition of msvc_dbg.h in include.am +* Support 'z' format modifier by CORD_vsprintf +* Update documentation of GC_RATE and MAX_PRIOR_ATTEMPTS +* Use SIGRTMIN+6 as suspend signal if sigrt-signals on OpenBSD +* Workaround TSan FP about race between generic_malloc and array_mark_proc +* Workaround TSan FP warning in finalized_malloc, push_unconditionally +* Workaround TSan FP warning in push_marked1/2/4, ptr_store_and_dirty +* Workaround Thread Sanitizer (TSan) FP warning in is_valid_displacement +* Workaround crash in FreeBSD rand() by avoiding its concurrent usage (tests) + + == 8.0.6 2021-09-28 == * Add loop to handle abort error like in suspend logic on Darwin @@ -208,7 +639,7 @@ * Access finalize_now atomically to avoid TSan warning without no-sanitize * Acknowledge thread restart from suspend_handler (NetBSD) * Add a sanity check that load_acquire and store_release are available -* Add AO primitives implementation to GC based on C11 atomic intrinsic +* Add AO primitives implementation to GC based on GCC atomic intrinsic * Add assertion for suspend_ack_sem in start_world * Add assertion to allocobj that live unmarked object cannot be reclaimed * Add assertions about held lock when accessing all_bottom_indices @@ -415,6 +846,25 @@ * Workaround Thread Sanitizer (TSan) false positive warnings +== 7.6.16 2022-08-26 == + +* Do not send signal to thread which is suspended manually +* Eliminate 'old_gc_no is initialized but not referenced' MS VC false warning +* Fix 'GC_greatest_stack_base_below is defined but not used' warning (IA64) +* Fix context saving when GC_suspend_thread(self) +* Fix data race in fail_proc1 of gctest +* Fix GC_suspend_thread if called before thread destructor +* Fix hang on sem_wait in GC_suspend_thread if thread was resumed recently +* Fix lock assertion violation in GC_find_limit if always multi-threaded +* Fix potential race if start_mark_threads called from threads in child +* Make finalizer_closure pointer read/write atomic in malloc and callback +* Prevent changing of GC_markers_m1 value while collection in progress +* Replace SSH cloning with HTTPS one in README +* Workaround Thread Sanitizer (TSan) FP warning in is_valid_displacement + +Also, includes 7.4.22 changes + + == 7.6.14 2021-09-28 == * Add loop to handle abort error like in suspend logic on Darwin @@ -956,6 +1406,24 @@ Also, includes 7.4.4 changes +== 7.4.22 2022-08-26 == + +* Eliminate 'new_l may be used uninitialized' gcc warning in os_dep (Cygwin) +* Eliminate 'possible loss of data' compiler warning in GC_envfile_getenv +* Fix 'undeclared getpagesize' compiler warning on AIX and OSF1 +* Fix GC_dirty() argument in GC_malloc_explicitly_typed_ignore_off_page +* Fix SIGSEGV caused by dropped stack access from child process in gctest +* Fix abort in Win32 DllMain if PARALLEL_MARK +* Fix assertion violation of GC_thread_key alignment if pthread-based TLS +* Fix comment in GC_init regarding GC_init_parallel call +* Fix stack overflow in gctest on Alpine Linux/s390x +* Revert "Remove nested always-false ifdef for HPUX and FREEBSD" +* Use SIGRTMIN+6 as suspend signal if sigrt-signals on OpenBSD +* Workaround crash in FreeBSD rand() by avoiding its concurrent usage + +Also, includes 7.2p changes. + + == 7.4.20 2021-09-28 == * Do not hold GC_fault_handler_lock when in Sleep (Windows) @@ -1482,6 +1950,30 @@ Also, includes 7.2 changes +== 7.2p 2022-08-25 == + +* Avoid potential race in GC_init_real_syms after GC_allow_register_threads +* Define SUNOS5SIGS macro for kFreeBSD +* Do not assert that GC is initialized at DLL_THREAD_DETACH (Win32) +* Ensure typed objects descriptor is never located in the first word +* Fix GC_make_descriptor for zero length argument +* Fix SUNOS5SIGS documentation to match macro definition in gcconfig.h +* Fix assertion violation in GC_allow_register_threads on Windows +* Fix get_maps failure when GC_repeat_read returns zero +* Fix hb_obj_kind type in documentation (ASCII diagram) describing hblkhdr +* Fix missing lock when GC_generate_random_valid_address is called +* Fix nodist_libgc_la_SOURCES value in Makefile.am for Solaris/sparc +* Fix oldProc initialization in gc_cleanup and eliminate related warnings +* Fix parallel_initialized assertion violation in initsecondarythread (Win32) +* Fix propagation of out-of-memory occurred in GC_make_sequence_descriptor +* Fix race between calloc_explicitly_typed and push_complex_descriptor +* Fix typos in comments of .c files, gc.h and a typo in debugging.html +* Refer to Makefile.direct instead of deleted Makefile file in README +* Remove checking of RS6000 completely +* Remove non-working check of M68K in gctest +* Revert addition of msvc_dbg.h in include.am + + == 7.2o 2021-09-28 == * Add loop to handle abort error like in suspend logic on Darwin @@ -5292,7 +5784,7 @@ possible). * alloc.c (GC_gcollect): Use GC_default_stop_func. * alloc.c (GC_collect_or_expand): Use GC_default_stop_func -(instead of GC_never_stop_func) unless it is trigged due to out of +(instead of GC_never_stop_func) unless it is triggered due to out of memory; don't increment GC_fail_count and don't output warning (before trying to collect again) in case the collection has been interrupted (by GC_default_stop_func) and the heap expansion has @@ -6925,7 +7417,7 @@ * misc.c: Declare GC_thr_init(). * allchblk.c (add_to_fl): disable assertions with USE_MUNMAP, -and refine assertions to handle huge unmergable blocks. +and refine assertions to handle huge unmergeable blocks. (GC_allochblk_nth): Add comment. * include/private/gcconfig.h: Add missing FREEBSD macro @@ -9120,7 +9612,7 @@ * Removed the tests for SGI_SOURCE in new_gc_alloc.h. This was causing that interface to fail on non-SGI platforms. * Changed the Linux stack finding code to use /proc, after changing it -to use HEURISTIC1 (thanks to David Mossberger for pointing out /proc hook). +to use HEURISTIC1 (thanks to David Mosberger for pointing out /proc hook). * Added HP/UX incremental GC support and HP/UX 11 thread support. Thread support is currently still flaky. * Added basic Linux/IA64 support.
View file
_service:tar_scm:gc-8.2.2.tar.gz/Config.cmake.in
Added
@@ -0,0 +1,5 @@ +# The BDWgc CMake configuration file. + +@PACKAGE_INIT@ +include("${CMAKE_CURRENT_LIST_DIR}/BDWgcTargets.cmake") +check_required_components(gc)
View file
_service:tar_scm:gc-8.0.6.tar.gz/Makefile.am -> _service:tar_scm:gc-8.2.2.tar.gz/Makefile.am
Changed
@@ -14,8 +14,8 @@ # Info (current:revision:age) for the Libtool versioning system. # These numbers should be updated at most once just before the release, # and, optionally, at most once during the development (after the release). -LIBGC_VER_INFO = 5:4:4 -LIBGCCPP_VER_INFO = 5:1:4 +LIBGC_VER_INFO = 6:1:5 +LIBGCCPP_VER_INFO = 6:0:5 ## FIXME: `make distcheck' in this directory will not currently work. ## This is most likely to the explicit flags passed to submakes. @@ -70,7 +70,7 @@ EXTRA_DIST += extra/gc.c libgc_la_SOURCES = \ allchblk.c alloc.c blacklst.c dbg_mlc.c \ - dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c \ + dyn_load.c finalize.c gc_dlopen.c headers.c \ mach_dep.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \ obj_map.c os_dep.c ptr_chck.c reclaim.c specific.c typd_mlc.c @@ -103,31 +103,45 @@ libgc_la_SOURCES += checksums.c endif +if ENABLE_GCJ_SUPPORT +libgc_la_SOURCES += gcj_mlc.c +endif + if ENABLE_DISCLAIM libgc_la_SOURCES += fnlz_mlc.c -pkginclude_HEADERS += include/gc_disclaim.h endif ## End of !SINGLE_GC_OBJ endif -if USE_INTERNAL_LIBATOMIC_OPS -nodist_libgc_la_SOURCES = libatomic_ops/src/atomic_ops.c +if PTHREADS +pkginclude_HEADERS += include/gc_pthread_redirects.h +endif + +if ENABLE_GCJ_SUPPORT +pkginclude_HEADERS += include/gc_gcj.h endif +if ENABLE_DISCLAIM +pkginclude_HEADERS += include/gc_disclaim.h +endif + +if USE_INTERNAL_LIBATOMIC_OPS +nodist_libgc_la_SOURCES = libatomic_ops/src/atomic_ops.c if NEED_ATOMIC_OPS_ASM -nodist_libgc_la_SOURCES = libatomic_ops/src/atomic_ops_sysdeps.S +nodist_libgc_la_SOURCES += libatomic_ops/src/atomic_ops_sysdeps.S +endif endif # Include THREADDLLIBS here to ensure that the correct versions of -# linuxthread semaphore functions get linked: +# linuxthread semaphore (and clock_gettime) functions get linked: libgc_la_LIBADD = @addobjs@ $(THREADDLLIBS) $(UNWINDLIBS) $(ATOMIC_OPS_LIBS) libgc_la_DEPENDENCIES = @addobjs@ libgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info $(LIBGC_VER_INFO) \ -no-undefined EXTRA_libgc_la_SOURCES = ia64_save_regs_in_stack.s sparc_mach_dep.S \ - sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s + sparc_netbsd_mach_dep.s if CPLUSPLUS # C++ Interface @@ -135,15 +149,23 @@ lib_LTLIBRARIES += libgccpp.la pkginclude_HEADERS += include/gc_allocator.h include/gc_cpp.h include_HEADERS += include/extra/gc_cpp.h -libgccpp_la_SOURCES = gc_cpp.cc -libgccpp_la_LIBADD = ./libgc.la +libgccpp_la_SOURCES = gc_badalc.cc gc_cpp.cc +libgccpp_la_LIBADD = libgc.la libgccpp_la_LDFLAGS = -version-info $(LIBGCCPP_VER_INFO) -no-undefined +if GC_TBA_LIBRARY +# The same as libgccpp but contains only gc_badalc.o. +lib_LTLIBRARIES += libgctba.la +libgctba_la_SOURCES = gc_badalc.cc +libgctba_la_LIBADD = libgc.la +# Set the same version as for libgccpp. +libgctba_la_LDFLAGS = -version-info $(LIBGCCPP_VER_INFO) -no-undefined +endif endif ## FIXME: If Visual C++ users use Makefile.am, this should go into ## pkginclude_HEADERS with proper AM_CONDITIONALization. Otherwise ## delete this comment. -EXTRA_DIST += gc_cpp.cpp +EXTRA_DIST += gc_badalc.cpp gc_cpp.cpp # Misc @@ -195,20 +217,17 @@ EXTRA_DIST += README.QUICK # other makefiles -# :GOTCHA: deliberately we do not include 'Makefile' -EXTRA_DIST += BCC_MAKEFILE NT_MAKEFILE \ - OS2_MAKEFILE PCR-Makefile digimars.mak \ - Makefile.direct SMakefile.amiga WCC_MAKEFILE autogen.sh \ - CMakeLists.txt tests/CMakeLists.txt +EXTRA_DIST += NT_MAKEFILE OS2_MAKEFILE PCR-Makefile digimars.mak \ + Makefile.direct SMakefile.amiga WCC_MAKEFILE autogen.sh CMakeLists.txt \ + Config.cmake.in build/s60v3/bld.inf build/s60v3/libgc.mmp # files used by makefiles other than Makefile.am # EXTRA_DIST += tools/if_mach.c tools/if_not_there.c tools/setjmp_t.c \ - tools/threadlibs.c gc.mak extra/MacOS.c extra/AmigaOS.c \ + tools/threadlibs.c extra/MacOS.c extra/AmigaOS.c \ extra/symbian/global_end.cpp extra/symbian/global_start.cpp \ extra/symbian/init_global_static_roots.cpp extra/symbian.cpp \ extra/pcr_interface.c extra/real_malloc.c \ - build/s60v3/bld.inf build/s60v3/libgc.mmp \ extra/Mac_files/datastart.c extra/Mac_files/dataend.c \ extra/Mac_files/MacOS_config.h \ include/private/msvc_dbg.h extra/msvc_dbg.c tools/callprocs.sh @@ -225,3 +244,6 @@ include doc/doc.am ## Putting these at the top causes cord to be built first, and not find ## libgc.a on HP/UX. There may be a better fix. + +# A dummy target for mono build. +test-bundle:
View file
_service:tar_scm:gc-8.0.6.tar.gz/Makefile.direct -> _service:tar_scm:gc-8.2.2.tar.gz/Makefile.direct
Changed
@@ -2,13 +2,13 @@ # to build the collector. # # Primary targets: -# gc.a - builds basic library -# c++ - adds C++ interface to library -# cords - adds cords (heavyweight strings) to library -# check - prints porting information, then builds basic version of gc.a, -# and runs some tests of collector and cords. Does not add cords or -# c++ interface to gc.a -# check-cpp - runs C++ test without adding C++ (and cords) interface to gc.a +# all - builds gc.a, gccpp.a, gctba.a and cord.a +# base_lib - builds gc.a only (basic library) +# c++ - builds gccpp.a and gctba.a only (C++ interface to library) +# cords - builds cord.a only (heavyweight strings library) +# check - same as "all" but also prints porting information, and runs some +# tests of collector and cords +# check-cpp - builds gc.a, gccpp.a and gctba.a, runs C++ only test # cord/de - builds dumb editor based on cords. ABI_FLAG= @@ -25,7 +25,7 @@ # Compiler executable name. For EMX, replace to "gcc". CXX=g++ $(ABI_FLAG) -# Needed only for "make c++", which adds the c++ interface. +# Needed only for "make c++", which builds the C++ interface. AS=as $(AS_ABI_FLAG) # The above doesn't work with gas, which doesn't run cpp. @@ -108,17 +108,17 @@ include/gc_version.h include/private/gc_hdrs.h include/private/gc_priv.h \ include/private/gcconfig.h include/private/gc_pmark.h \ include/gc_inline.h include/gc_mark.h include/gc_disclaim.h \ - tools/threadlibs.c tools/if_mach.c tools/if_not_there.c gc_cpp.cc \ - include/gc_cpp.h include/private/gc_locks.h include/new_gc_alloc.h \ - include/gc_alloc_ptrs.h include/gc_allocator.h include/javaxfc.h \ - include/gc_backptr.h include/gc_gcj.h include/private/dbg_mlc.h \ + tools/threadlibs.c tools/if_mach.c tools/if_not_there.c gc_badalc.cc \ + gc_cpp.cc include/gc_cpp.h include/private/gc_alloc_ptrs.h \ + include/gc_allocator.h include/javaxfc.h include/gc_backptr.h \ + include/gc_gcj.h include/private/gc_locks.h include/private/dbg_mlc.h \ include/private/specific.h include/leak_detector.h \ include/gc_pthread_redirects.h include/private/gc_atomic_ops.h \ include/gc_config_macros.h include/private/pthread_support.h \ include/private/pthread_stop_world.h include/private/darwin_semaphore.h \ include/private/darwin_stop_world.h include/private/thread_local_alloc.h \ ia64_save_regs_in_stack.s sparc_mach_dep.S \ - sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s $(CORD_SRCS) + sparc_netbsd_mach_dep.s $(CORD_SRCS) CORD_INCLUDE_FILES= $(srcdir)/include/gc.h $(srcdir)/include/cord.h \ $(srcdir)/include/ec.h $(srcdir)/include/cord_pos.h @@ -143,7 +143,7 @@ # not time-critical anyway. # Set SPECIALCFLAGS to -q nodirect_code on Encore. -all: base_lib gctest$(EXEEXT) +all: base_lib cords c++ atomic_ops.o: $(AO_SRC_DIR)/src/atomic_ops.c $(CC) $(CFLAGS) -c -o $@ $(AO_SRC_DIR)/src/atomic_ops.c @@ -156,9 +156,11 @@ BSD-pkg-all: bsd-libgc.a bsd-libleak.a -bsd-libgc.a: +bsd-libgc.a bsd-libgccpp.a bsd-libgctba.a: $(MAKE) -f Makefile.direct CFLAGS="$(CFLAGS)" clean c++-t mv gc.a bsd-libgc.a + mv gccpp.a bsd-libgccpp.a + mv gctba.a bsd-libgctba.a bsd-libleak.a: $(MAKE) -f Makefile.direct CFLAGS="$(LEAKFLAGS)" clean c++-nt @@ -167,12 +169,16 @@ BSD-pkg-install: BSD-pkg-all ${CP} bsd-libgc.a libgc.a ${INSTALL_DATA} libgc.a ${PREFIX}/lib + ${CP} bsd-libgccpp.a libgccpp.a + ${INSTALL_DATA} libgccpp.a ${PREFIX}/lib + ${CP} bsd-libgctba.a libgctba.a + ${INSTALL_DATA} libgctba.a ${PREFIX}/lib ${INSTALL_DATA} gc.h gc_cpp.h ${PREFIX}/include ${INSTALL_MAN} doc/gc.man ${PREFIX}/man/man3/gc.3 pcr: PCR-Makefile include/private/gc_private.h include/private/gc_hdrs.h \ -include/private/gc_locks.h include/gc.h include/private/gcconfig.h \ -mach_dep.o $(SRCS) + include/private/gc_locks.h include/gc.h include/private/gcconfig.h \ + mach_dep.o $(SRCS) $(MAKE) -f PCR-Makefile depend $(MAKE) -f PCR-Makefile @@ -209,24 +215,28 @@ # Ignore ranlib failure; that usually means it doesn't exist, and # isn't needed. -cords: $(CORD_OBJS) $(UTILS) base_lib +cords cord.a: $(CORD_OBJS) $(UTILS) rm -f dont_ar_3 ./if_mach SPARC SOLARIS touch dont_ar_3 - ./if_mach SPARC SOLARIS $(AR) rus gc.a $(CORD_OBJS) + ./if_mach SPARC SOLARIS $(AR) rus cord.a $(CORD_OBJS) ./if_mach M68K AMIGA touch dont_ar_3 - ./if_mach M68K AMIGA $(AR) -vrus gc.a $(CORD_OBJS) - ./if_not_there dont_ar_3 || $(AR) ru gc.a $(CORD_OBJS) - ./if_not_there dont_ar_3 || $(RANLIB) gc.a || cat /dev/null + ./if_mach M68K AMIGA $(AR) -vrus cord.a $(CORD_OBJS) + ./if_not_there dont_ar_3 || $(AR) ru cord.a $(CORD_OBJS) + ./if_not_there dont_ar_3 || $(RANLIB) cord.a || cat /dev/null echo > cords +gc_badalc.o: $(srcdir)/gc_badalc.cc $(srcdir)/include/gc_cpp.h \ + $(srcdir)/include/gc.h + $(CXX) -c $(CXXFLAGS) $(srcdir)/gc_badalc.cc + gc_cpp.o: $(srcdir)/gc_cpp.cc $(srcdir)/include/gc_cpp.h $(srcdir)/include/gc.h $(CXX) -c $(CXXFLAGS) $(srcdir)/gc_cpp.cc test_cpp$(EXEEXT): $(srcdir)/tests/test_cpp.cc $(srcdir)/include/gc_cpp.h \ - $(srcdir)/include/gc.h gc_cpp.o base_lib $(UTILS) + $(srcdir)/include/gc.h c++ base_lib $(UTILS) rm -f test_cpp$(EXEEXT) - ./if_mach HP_PA HPUX $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/tests/test_cpp.cc gc_cpp.o gc.a -ldld `./threadlibs` - ./if_not_there test_cpp$(EXEEXT) || $(CXX) $(CXXFLAGS) -DGC_NOT_DLL -o test_cpp$(EXEEXT) $(srcdir)/tests/test_cpp.cc gc_cpp.o gc.a `./threadlibs` + ./if_mach HP_PA HPUX $(CXX) $(CXXFLAGS) -o test_cpp $(srcdir)/tests/test_cpp.cc gc.a gccpp.a -ldld `./threadlibs` + ./if_not_there test_cpp$(EXEEXT) || $(CXX) $(CXXFLAGS) -DGC_NOT_DLL -o test_cpp$(EXEEXT) $(srcdir)/tests/test_cpp.cc gc.a gccpp.a `./threadlibs` check-cpp: test_cpp$(EXEEXT) ./test_cpp @@ -237,14 +247,18 @@ c++-nt: c++ @echo "Use ./test_cpp 1 to test the leak library" -c++: gc_cpp.o $(srcdir)/include/gc_cpp.h base_lib $(UTILS) +c++ gccpp.a gctba.a: gc_badalc.o gc_cpp.o $(UTILS) rm -f dont_ar_4 ./if_mach SPARC SOLARIS touch dont_ar_4 - ./if_mach SPARC SOLARIS $(AR) rus gc.a gc_cpp.o + ./if_mach SPARC SOLARIS $(AR) rus gccpp.a gc_badalc.o gc_cpp.o + ./if_mach SPARC SOLARIS $(AR) rus gctba.a gc_badalc.o ./if_mach M68K AMIGA touch dont_ar_4 - ./if_mach M68K AMIGA $(AR) -vrus gc.a gc_cpp.o - ./if_not_there dont_ar_4 || $(AR) ru gc.a gc_cpp.o - ./if_not_there dont_ar_4 || $(RANLIB) gc.a || cat /dev/null + ./if_mach M68K AMIGA $(AR) -vrus gccpp.a gc_badalc.o gc_cpp.o + ./if_mach M68K AMIGA $(AR) -vrus gctba.a gc_badalc.o + ./if_not_there dont_ar_4 || $(AR) ru gccpp.a gc_badalc.o gc_cpp.o + ./if_not_there dont_ar_4 || $(RANLIB) gccpp.a || cat /dev/null + ./if_not_there dont_ar_4 || $(AR) ru gctba.a gc_badalc.o + ./if_not_there dont_ar_4 || $(RANLIB) gctba.a || cat /dev/null echo > c++ dyn_load_sunos53.o: dyn_load.c @@ -292,6 +306,7 @@ $(srcdir)/ia64_save_regs_in_stack.s \ $(srcdir)/sparc_netbsd_mach_dep.s $(UTILS) rm -f mach_dep.o + ./if_mach SPARC LINUX $(CC) -c -o mach_dep2.o $(srcdir)/sparc_mach_dep.S ./if_mach SPARC SOLARIS $(CC) -c -o mach_dep2.o $(srcdir)/sparc_mach_dep.S ./if_mach SPARC OPENBSD $(CC) -c -o mach_dep2.o $(srcdir)/sparc_mach_dep.S ./if_mach SPARC NETBSD $(AS) -o mach_dep2.o $(srcdir)/sparc_netbsd_mach_dep.s @@ -331,27 +346,24 @@ mkdir cord || cat /dev/null mv cordprnt.o cord/cordprnt.o -cord/cordtest$(EXEEXT): $(srcdir)/cord/tests/cordtest.c $(CORD_OBJS) \ - base_lib $(UTILS) - rm -f cord/cordtest$(EXEEXT) - ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/tests/cordtest.c $(CORD_OBJS) gc.a -lucb - ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/cordtest $(srcdir)/cord/tests/cordtest.c $(CORD_OBJS) gc.a -ldld `./threadlibs` - ./if_mach M68K AMIGA $(CC) $(CFLAGS) -UGC_AMIGA_MAKINGLIB -o cord/cordtest $(srcdir)/cord/tests/cordtest.c $(CORD_OBJS) gc.a `./threadlibs` - ./if_not_there cord/cordtest$(EXEEXT) || $(CC) $(CFLAGS) -o cord/cordtest$(EXEEXT) $(srcdir)/cord/tests/cordtest.c $(CORD_OBJS) gc.a `./threadlibs` - -cord/de: $(srcdir)/cord/tests/de.c $(srcdir)/cord/tests/de_win.c \ - $(srcdir)/cord/tests/de_win.h cord/cordbscs.o cord/cordxtra.o base_lib \ - $(UTILS) - rm -f cord/de - ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses -ltermlib -lucb `./threadlibs` - ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses -ltermlib -ldld `./threadlibs` - ./if_mach POWERPC AIX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses - ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a - ./if_mach I386 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` - ./if_mach ALPHA LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` - ./if_mach IA64 LINUX $(CC) $(CFLAGS) -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses `./threadlibs` - ./if_mach M68K AMIGA $(CC) $(CFLAGS) -UGC_AMIGA_MAKINGLIB -o cord/de $(srcdir)/cord/tests/de.c cord/cordbscs.o cord/cordxtra.o gc.a -lcurses - ./if_not_there cord/de$(EXEEXT) || $(CC) $(CFLAGS) -o cord/de$(EXEEXT) $(srcdir)/cord/tests/de.c $(srcdir)/cord/tests/de_win.c cord/cordbscs.o cord/cordxtra.o gc.a $(CURSES) `./threadlibs` +cordtest$(EXEEXT): $(srcdir)/cord/tests/cordtest.c cords base_lib $(UTILS) + rm -f cordtest$(EXEEXT) + ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o cordtest $(srcdir)/cord/tests/cordtest.c gc.a cord.a -lucb + ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o cordtest $(srcdir)/cord/tests/cordtest.c gc.a cord.a -ldld `./threadlibs` + ./if_mach M68K AMIGA $(CC) $(CFLAGS) -UGC_AMIGA_MAKINGLIB -o cordtest $(srcdir)/cord/tests/cordtest.c gc.a cord.a `./threadlibs` + ./if_not_there cordtest$(EXEEXT) || $(CC) $(CFLAGS) -o cordtest$(EXEEXT) $(srcdir)/cord/tests/cordtest.c gc.a cord.a `./threadlibs` + +cord/de: de$(EXEEXT) + +de$(EXEEXT): $(srcdir)/cord/tests/de.c $(srcdir)/cord/tests/de_win.c \ + $(srcdir)/cord/tests/de_win.h cords base_lib $(UTILS) + rm -f de$(EXEEXT) + ./if_mach SPARC DRSNX $(CC) $(CFLAGS) -o de $(srcdir)/cord/tests/de.c gc.a cord.a -lcurses -ltermlib -lucb `./threadlibs` + ./if_mach HP_PA HPUX $(CC) $(CFLAGS) -o de $(srcdir)/cord/tests/de.c gc.a cord.a -lcurses -ltermlib -ldld `./threadlibs` + ./if_mach POWERPC AIX $(CC) $(CFLAGS) -o de $(srcdir)/cord/tests/de.c gc.a cord.a -lcurses + ./if_mach POWERPC DARWIN $(CC) $(CFLAGS) -o de $(srcdir)/cord/tests/de.c gc.a cord.a + ./if_mach M68K AMIGA $(CC) $(CFLAGS) -UGC_AMIGA_MAKINGLIB -o de $(srcdir)/cord/tests/de.c gc.a cord.a -lcurses + ./if_not_there de$(EXEEXT) || $(CC) $(CFLAGS) -o de$(EXEEXT) $(srcdir)/cord/tests/de.c $(srcdir)/cord/tests/de_win.c gc.a cord.a $(CURSES) `./threadlibs` if_mach$(EXEEXT): $(srcdir)/tools/if_mach.c \ $(srcdir)/include/private/gcconfig.h @@ -365,10 +377,9 @@ $(HOSTCC) $(HOSTCFLAGS) -o if_not_there$(EXEEXT) $(srcdir)/tools/if_not_there.c clean: - rm -f gc.a *.i *.o *.exe tests/*.o gctest gctest_dyn_link test_cpp \ + rm -f *.a *.i *.o *.exe tests/*.o gctest gctest_dyn_link test_cpp \ setjmp_test mon.out gmon.out a.out core if_not_there if_mach \ - base_lib c++ $(CORD_OBJS) cord/cordtest cord/de cords \ - dont_ar_* threadlibs + base_lib c++ $(CORD_OBJS) cordtest de cords dont_ar_* threadlibs -rm -f *~ gctest$(EXEEXT): tests/test.o base_lib $(UTILS) @@ -385,10 +396,11 @@ $(UTILS) $(CC) $(CFLAGS) -o setjmp_test$(EXEEXT) $(srcdir)/tools/setjmp_t.c -check: cord/cordtest$(EXEEXT) gctest$(EXEEXT) setjmp_test$(EXEEXT) +check: cordtest$(EXEEXT) gctest$(EXEEXT) setjmp_test$(EXEEXT) test_cpp$(EXEEXT) ./setjmp_test ./gctest - cord/cordtest + ./cordtest + ./test_cpp # A synonym to "check" (for compatibility with older GC versions). test: check
View file
_service:tar_scm:gc-8.0.6.tar.gz/Makefile.in -> _service:tar_scm:gc-8.2.2.tar.gz/Makefile.in
Changed
@@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -132,10 +132,11 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -check_PROGRAMS = cordtest$(EXEEXT) gctest$(EXEEXT) leaktest$(EXEEXT) \ - middletest$(EXEEXT) smashtest$(EXEEXT) hugetest$(EXEEXT) \ - realloc_test$(EXEEXT) staticrootstest$(EXEEXT) $(am__EXEEXT_1) \ - $(am__EXEEXT_2) $(am__EXEEXT_3) $(am__EXEEXT_4) +check_PROGRAMS = cordtest$(EXEEXT) gctest$(EXEEXT) $(am__EXEEXT_1) \ + leaktest$(EXEEXT) middletest$(EXEEXT) smashtest$(EXEEXT) \ + hugetest$(EXEEXT) realloc_test$(EXEEXT) \ + staticrootstest$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + $(am__EXEEXT_4) $(am__EXEEXT_5) @PTHREAD_START_STANDALONE_TRUE@@SINGLE_GC_OBJ_TRUE@am__append_1 = -DGC_PTHREAD_START_STANDALONE @PTHREAD_START_STANDALONE_TRUE@@SINGLE_GC_OBJ_TRUE@am__append_2 = pthread_start.c @SINGLE_GC_OBJ_FALSE@am__append_3 = extra/gc.c @@ -150,36 +151,46 @@ @SINGLE_GC_OBJ_FALSE@@THREAD_LOCAL_ALLOC_TRUE@am__append_8 = thread_local_alloc.c @MAKE_BACK_GRAPH_TRUE@@SINGLE_GC_OBJ_FALSE@am__append_9 = backgraph.c @CHECKSUMS_TRUE@@SINGLE_GC_OBJ_FALSE@am__append_10 = checksums.c -@ENABLE_DISCLAIM_TRUE@@SINGLE_GC_OBJ_FALSE@am__append_11 = fnlz_mlc.c -@ENABLE_DISCLAIM_TRUE@@SINGLE_GC_OBJ_FALSE@am__append_12 = include/gc_disclaim.h +@ENABLE_GCJ_SUPPORT_TRUE@@SINGLE_GC_OBJ_FALSE@am__append_11 = gcj_mlc.c +@ENABLE_DISCLAIM_TRUE@@SINGLE_GC_OBJ_FALSE@am__append_12 = fnlz_mlc.c +@PTHREADS_TRUE@am__append_13 = include/gc_pthread_redirects.h +@ENABLE_GCJ_SUPPORT_TRUE@am__append_14 = include/gc_gcj.h +@ENABLE_DISCLAIM_TRUE@am__append_15 = include/gc_disclaim.h +@NEED_ATOMIC_OPS_ASM_TRUE@@USE_INTERNAL_LIBATOMIC_OPS_TRUE@am__append_16 = libatomic_ops/src/atomic_ops_sysdeps.S # C++ Interface # ------------- -@CPLUSPLUS_TRUE@am__append_13 = libgccpp.la -@CPLUSPLUS_TRUE@am__append_14 = include/gc_allocator.h include/gc_cpp.h -@CPLUSPLUS_TRUE@am__append_15 = include/extra/gc_cpp.h -@ENABLE_SHARED_TRUE@am__append_16 = $(top_builddir)/libgc.la -@THREADS_TRUE@am__append_17 = $(THREADDLLIBS) -@ENABLE_SHARED_TRUE@am__append_18 = $(top_builddir)/libgc.la -@KEEP_BACK_PTRS_TRUE@am__append_19 = tracetest$(EXEEXT) -@KEEP_BACK_PTRS_TRUE@am__append_20 = tracetest -@THREADS_TRUE@am__append_21 = test_atomic_ops$(EXEEXT) \ +@CPLUSPLUS_TRUE@am__append_17 = libgccpp.la +@CPLUSPLUS_TRUE@am__append_18 = include/gc_allocator.h include/gc_cpp.h +@CPLUSPLUS_TRUE@am__append_19 = include/extra/gc_cpp.h +# The same as libgccpp but contains only gc_badalc.o. +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@am__append_20 = libgctba.la +@ENABLE_SHARED_TRUE@am__append_21 = $(top_builddir)/libgc.la +@THREADS_TRUE@am__append_22 = $(THREADDLLIBS) + +# Note: because of libtool, you'll need to point your browser to +# .libs/gctest.html, not gctest.html at topdir. +@EMSCRIPTEN_TRUE@am__append_23 = gctest.html +@ENABLE_SHARED_TRUE@am__append_24 = $(top_builddir)/libgc.la +@KEEP_BACK_PTRS_TRUE@am__append_25 = tracetest$(EXEEXT) +@KEEP_BACK_PTRS_TRUE@am__append_26 = tracetest +@THREADS_TRUE@am__append_27 = test_atomic_ops$(EXEEXT) \ @THREADS_TRUE@ threadleaktest$(EXEEXT) threadkey_test$(EXEEXT) \ @THREADS_TRUE@ subthreadcreate_test$(EXEEXT) \ @THREADS_TRUE@ initsecondarythread_test$(EXEEXT) -@THREADS_TRUE@am__append_22 = test_atomic_ops threadleaktest \ +@THREADS_TRUE@am__append_28 = test_atomic_ops threadleaktest \ @THREADS_TRUE@ threadkey_test subthreadcreate_test \ @THREADS_TRUE@ initsecondarythread_test -@CPLUSPLUS_TRUE@am__append_23 = test_cpp$(EXEEXT) -@CPLUSPLUS_TRUE@am__append_24 = test_cpp -@AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@@ENABLE_SHARED_TRUE@am__append_25 = $(top_builddir)/libgc.la -@ENABLE_DISCLAIM_TRUE@am__append_26 = disclaim_test$(EXEEXT) \ +@CPLUSPLUS_TRUE@am__append_29 = test_cpp$(EXEEXT) +@CPLUSPLUS_TRUE@am__append_30 = test_cpp +@AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@@ENABLE_SHARED_TRUE@am__append_31 = $(top_builddir)/libgc.la +@ENABLE_DISCLAIM_TRUE@am__append_32 = disclaim_test$(EXEEXT) \ @ENABLE_DISCLAIM_TRUE@ disclaim_bench$(EXEEXT) \ @ENABLE_DISCLAIM_TRUE@ disclaim_weakmap_test$(EXEEXT) -@ENABLE_DISCLAIM_TRUE@am__append_27 = disclaim_test disclaim_bench \ +@ENABLE_DISCLAIM_TRUE@am__append_33 = disclaim_test disclaim_bench \ @ENABLE_DISCLAIM_TRUE@ disclaim_weakmap_test -@ENABLE_DISCLAIM_TRUE@@THREADS_TRUE@am__append_28 = $(THREADDLLIBS) -@ENABLE_DISCLAIM_TRUE@@THREADS_TRUE@am__append_29 = $(THREADDLLIBS) +@ENABLE_DISCLAIM_TRUE@@THREADS_TRUE@am__append_34 = $(THREADDLLIBS) +@ENABLE_DISCLAIM_TRUE@@THREADS_TRUE@am__append_35 = $(THREADDLLIBS) subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gc_set_version.m4 \ @@ -198,6 +209,16 @@ CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = bdw-gc.pc CONFIG_CLEAN_VPATH_FILES = +@EMSCRIPTEN_TRUE@am__EXEEXT_1 = gctest.html$(EXEEXT) +@KEEP_BACK_PTRS_TRUE@am__EXEEXT_2 = tracetest$(EXEEXT) +@THREADS_TRUE@am__EXEEXT_3 = test_atomic_ops$(EXEEXT) \ +@THREADS_TRUE@ threadleaktest$(EXEEXT) threadkey_test$(EXEEXT) \ +@THREADS_TRUE@ subthreadcreate_test$(EXEEXT) \ +@THREADS_TRUE@ initsecondarythread_test$(EXEEXT) +@CPLUSPLUS_TRUE@am__EXEEXT_4 = test_cpp$(EXEEXT) +@ENABLE_DISCLAIM_TRUE@am__EXEEXT_5 = disclaim_test$(EXEEXT) \ +@ENABLE_DISCLAIM_TRUE@ disclaim_bench$(EXEEXT) \ +@ENABLE_DISCLAIM_TRUE@ disclaim_weakmap_test$(EXEEXT) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -229,7 +250,7 @@ "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) -libcord_la_DEPENDENCIES = $(top_builddir)/libgc.la +libcord_la_DEPENDENCIES = libgc.la am__dirstamp = $(am__leading_dot)dirstamp am_libcord_la_OBJECTS = cord/libcord_la-cordbscs.lo \ cord/libcord_la-cordprnt.lo cord/libcord_la-cordxtra.lo @@ -243,12 +264,12 @@ $(libcord_la_LDFLAGS) $(LDFLAGS) -o $@ am__DEPENDENCIES_1 = am__libgc_la_SOURCES_DIST = allchblk.c alloc.c blacklst.c dbg_mlc.c \ - dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c \ - mach_dep.c malloc.c mallocx.c mark.c mark_rts.c misc.c \ - new_hblk.c obj_map.c os_dep.c ptr_chck.c reclaim.c specific.c \ - typd_mlc.c win32_threads.c pthread_start.c pthread_support.c \ + dyn_load.c finalize.c gc_dlopen.c headers.c mach_dep.c \ + malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \ + obj_map.c os_dep.c ptr_chck.c reclaim.c specific.c typd_mlc.c \ + win32_threads.c pthread_start.c pthread_support.c \ darwin_stop_world.c pthread_stop_world.c thread_local_alloc.c \ - backgraph.c checksums.c fnlz_mlc.c extra/gc.c + backgraph.c checksums.c gcj_mlc.c fnlz_mlc.c extra/gc.c @SINGLE_GC_OBJ_FALSE@@WIN32_THREADS_TRUE@am__objects_1 = \ @SINGLE_GC_OBJ_FALSE@@WIN32_THREADS_TRUE@ win32_threads.lo @PTHREADS_TRUE@@SINGLE_GC_OBJ_FALSE@@WIN32_THREADS_FALSE@am__objects_2 = pthread_start.lo \ @@ -259,40 +280,55 @@ @MAKE_BACK_GRAPH_TRUE@@SINGLE_GC_OBJ_FALSE@am__objects_6 = \ @MAKE_BACK_GRAPH_TRUE@@SINGLE_GC_OBJ_FALSE@ backgraph.lo @CHECKSUMS_TRUE@@SINGLE_GC_OBJ_FALSE@am__objects_7 = checksums.lo -@ENABLE_DISCLAIM_TRUE@@SINGLE_GC_OBJ_FALSE@am__objects_8 = \ +@ENABLE_GCJ_SUPPORT_TRUE@@SINGLE_GC_OBJ_FALSE@am__objects_8 = \ +@ENABLE_GCJ_SUPPORT_TRUE@@SINGLE_GC_OBJ_FALSE@ gcj_mlc.lo +@ENABLE_DISCLAIM_TRUE@@SINGLE_GC_OBJ_FALSE@am__objects_9 = \ @ENABLE_DISCLAIM_TRUE@@SINGLE_GC_OBJ_FALSE@ fnlz_mlc.lo -@PTHREAD_START_STANDALONE_TRUE@@SINGLE_GC_OBJ_TRUE@am__objects_9 = pthread_start.lo +@PTHREAD_START_STANDALONE_TRUE@@SINGLE_GC_OBJ_TRUE@am__objects_10 = pthread_start.lo @SINGLE_GC_OBJ_FALSE@am_libgc_la_OBJECTS = allchblk.lo alloc.lo \ @SINGLE_GC_OBJ_FALSE@ blacklst.lo dbg_mlc.lo dyn_load.lo \ -@SINGLE_GC_OBJ_FALSE@ finalize.lo gc_dlopen.lo gcj_mlc.lo \ -@SINGLE_GC_OBJ_FALSE@ headers.lo mach_dep.lo malloc.lo \ -@SINGLE_GC_OBJ_FALSE@ mallocx.lo mark.lo mark_rts.lo misc.lo \ -@SINGLE_GC_OBJ_FALSE@ new_hblk.lo obj_map.lo os_dep.lo \ -@SINGLE_GC_OBJ_FALSE@ ptr_chck.lo reclaim.lo specific.lo \ -@SINGLE_GC_OBJ_FALSE@ typd_mlc.lo $(am__objects_1) \ -@SINGLE_GC_OBJ_FALSE@ $(am__objects_2) $(am__objects_3) \ -@SINGLE_GC_OBJ_FALSE@ $(am__objects_4) $(am__objects_5) \ -@SINGLE_GC_OBJ_FALSE@ $(am__objects_6) $(am__objects_7) \ -@SINGLE_GC_OBJ_FALSE@ $(am__objects_8) -@SINGLE_GC_OBJ_TRUE@am_libgc_la_OBJECTS = extra/gc.lo $(am__objects_9) \ -@SINGLE_GC_OBJ_TRUE@ $(am__objects_1) $(am__objects_2) \ -@SINGLE_GC_OBJ_TRUE@ $(am__objects_3) $(am__objects_4) \ -@SINGLE_GC_OBJ_TRUE@ $(am__objects_5) $(am__objects_6) \ -@SINGLE_GC_OBJ_TRUE@ $(am__objects_7) $(am__objects_8) -@NEED_ATOMIC_OPS_ASM_FALSE@@USE_INTERNAL_LIBATOMIC_OPS_TRUE@nodist_libgc_la_OBJECTS = libatomic_ops/src/atomic_ops.lo -@NEED_ATOMIC_OPS_ASM_TRUE@nodist_libgc_la_OBJECTS = libatomic_ops/src/atomic_ops_sysdeps.lo +@SINGLE_GC_OBJ_FALSE@ finalize.lo gc_dlopen.lo headers.lo \ +@SINGLE_GC_OBJ_FALSE@ mach_dep.lo malloc.lo mallocx.lo mark.lo \ +@SINGLE_GC_OBJ_FALSE@ mark_rts.lo misc.lo new_hblk.lo \ +@SINGLE_GC_OBJ_FALSE@ obj_map.lo os_dep.lo ptr_chck.lo \ +@SINGLE_GC_OBJ_FALSE@ reclaim.lo specific.lo typd_mlc.lo \ +@SINGLE_GC_OBJ_FALSE@ $(am__objects_1) $(am__objects_2) \ +@SINGLE_GC_OBJ_FALSE@ $(am__objects_3) $(am__objects_4) \ +@SINGLE_GC_OBJ_FALSE@ $(am__objects_5) $(am__objects_6) \ +@SINGLE_GC_OBJ_FALSE@ $(am__objects_7) $(am__objects_8) \ +@SINGLE_GC_OBJ_FALSE@ $(am__objects_9) +@SINGLE_GC_OBJ_TRUE@am_libgc_la_OBJECTS = extra/gc.lo \ +@SINGLE_GC_OBJ_TRUE@ $(am__objects_10) $(am__objects_1) \ +@SINGLE_GC_OBJ_TRUE@ $(am__objects_2) $(am__objects_3) \ +@SINGLE_GC_OBJ_TRUE@ $(am__objects_4) $(am__objects_5) \ +@SINGLE_GC_OBJ_TRUE@ $(am__objects_6) $(am__objects_7) \ +@SINGLE_GC_OBJ_TRUE@ $(am__objects_8) $(am__objects_9) +@NEED_ATOMIC_OPS_ASM_TRUE@@USE_INTERNAL_LIBATOMIC_OPS_TRUE@am__objects_11 = libatomic_ops/src/atomic_ops_sysdeps.lo +@USE_INTERNAL_LIBATOMIC_OPS_TRUE@nodist_libgc_la_OBJECTS = libatomic_ops/src/atomic_ops.lo \ +@USE_INTERNAL_LIBATOMIC_OPS_TRUE@ $(am__objects_11) libgc_la_OBJECTS = $(am_libgc_la_OBJECTS) $(nodist_libgc_la_OBJECTS) libgc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libgc_la_LDFLAGS) $(LDFLAGS) -o $@ -@CPLUSPLUS_TRUE@libgccpp_la_DEPENDENCIES = ./libgc.la -am__libgccpp_la_SOURCES_DIST = gc_cpp.cc -@CPLUSPLUS_TRUE@am_libgccpp_la_OBJECTS = gc_cpp.lo +@CPLUSPLUS_TRUE@libgccpp_la_DEPENDENCIES = libgc.la +am__libgccpp_la_SOURCES_DIST = gc_badalc.cc gc_cpp.cc +@CPLUSPLUS_TRUE@am_libgccpp_la_OBJECTS = gc_badalc.lo gc_cpp.lo libgccpp_la_OBJECTS = $(am_libgccpp_la_OBJECTS) libgccpp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libgccpp_la_LDFLAGS) $(LDFLAGS) -o $@ @CPLUSPLUS_TRUE@am_libgccpp_la_rpath = -rpath $(libdir) +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@libgctba_la_DEPENDENCIES = \ +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@ libgc.la +am__libgctba_la_SOURCES_DIST = gc_badalc.cc +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@am_libgctba_la_OBJECTS = \ +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@ gc_badalc.lo +libgctba_la_OBJECTS = $(am_libgctba_la_OBJECTS) +libgctba_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libgctba_la_LDFLAGS) $(LDFLAGS) -o $@ +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@am_libgctba_la_rpath = -rpath \ +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@ $(libdir) am__DEPENDENCIES_2 = $(nodist_libgc_la_OBJECTS) \ $(top_builddir)/libgc.la $(am__DEPENDENCIES_1) libstaticrootslib2_test_la_DEPENDENCIES = $(am__DEPENDENCIES_2) @@ -311,18 +347,9 @@ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libstaticrootslib_test_la_LDFLAGS) \ $(LDFLAGS) -o $@ -@KEEP_BACK_PTRS_TRUE@am__EXEEXT_1 = tracetest$(EXEEXT) -@THREADS_TRUE@am__EXEEXT_2 = test_atomic_ops$(EXEEXT) \ -@THREADS_TRUE@ threadleaktest$(EXEEXT) threadkey_test$(EXEEXT) \ -@THREADS_TRUE@ subthreadcreate_test$(EXEEXT) \ -@THREADS_TRUE@ initsecondarythread_test$(EXEEXT) -@CPLUSPLUS_TRUE@am__EXEEXT_3 = test_cpp$(EXEEXT) -@ENABLE_DISCLAIM_TRUE@am__EXEEXT_4 = disclaim_test$(EXEEXT) \ -@ENABLE_DISCLAIM_TRUE@ disclaim_bench$(EXEEXT) \ -@ENABLE_DISCLAIM_TRUE@ disclaim_weakmap_test$(EXEEXT) am_cordtest_OBJECTS = cord/tests/cordtest.$(OBJEXT) cordtest_OBJECTS = $(am_cordtest_OBJECTS) -cordtest_DEPENDENCIES = $(top_builddir)/libcord.la $(am__append_16) +cordtest_DEPENDENCIES = $(top_builddir)/libcord.la $(am__append_21) am__disclaim_bench_SOURCES_DIST = tests/disclaim_bench.c @ENABLE_DISCLAIM_TRUE@am_disclaim_bench_OBJECTS = \ @ENABLE_DISCLAIM_TRUE@ tests/disclaim_bench.$(OBJEXT) @@ -349,6 +376,15 @@ am_gctest_OBJECTS = tests/test.$(OBJEXT) gctest_OBJECTS = $(am_gctest_OBJECTS) @THREADS_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) +am__gctest_html_SOURCES_DIST = tests/test.c +am__objects_12 = tests/test.$(OBJEXT) +@EMSCRIPTEN_TRUE@am_gctest_html_OBJECTS = $(am__objects_12) +gctest_html_OBJECTS = $(am_gctest_html_OBJECTS) +am__DEPENDENCIES_5 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_4) +@EMSCRIPTEN_TRUE@gctest_html_DEPENDENCIES = $(am__DEPENDENCIES_5) +gctest_html_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(gctest_html_LDFLAGS) $(LDFLAGS) -o $@ am_hugetest_OBJECTS = tests/huge_test.$(OBJEXT) hugetest_OBJECTS = $(am_hugetest_OBJECTS) hugetest_DEPENDENCIES = $(am__DEPENDENCIES_2) @@ -377,7 +413,7 @@ staticrootstest_OBJECTS = $(am_staticrootstest_OBJECTS) staticrootstest_DEPENDENCIES = $(nodist_libgc_la_OBJECTS) \ $(am__DEPENDENCIES_1) libstaticrootslib_test.la \ - libstaticrootslib2_test.la $(am__append_18) + libstaticrootslib2_test.la $(am__append_24) staticrootstest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(staticrootstest_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ @@ -402,11 +438,12 @@ @AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(nodist_libgc_la_OBJECTS) \ @AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(am__DEPENDENCIES_1) \ @AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(am__DEPENDENCIES_1) \ -@AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(am__append_25) -@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@test_cpp_DEPENDENCIES = gc_cpp.o \ +@AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(am__append_31) +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@test_cpp_DEPENDENCIES = \ +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ gc_badalc.o gc_cpp.o \ @AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(am__DEPENDENCIES_2) \ @AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(am__DEPENDENCIES_1) \ -@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(am__append_25) +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(am__append_31) am__threadkey_test_SOURCES_DIST = tests/threadkey_test.c @THREADS_TRUE@am_threadkey_test_OBJECTS = \ @THREADS_TRUE@ tests/threadkey_test.$(OBJEXT) @@ -438,11 +475,51 @@ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/allchblk.Plo ./$(DEPDIR)/alloc.Plo \ + ./$(DEPDIR)/backgraph.Plo ./$(DEPDIR)/blacklst.Plo \ + ./$(DEPDIR)/checksums.Plo ./$(DEPDIR)/darwin_stop_world.Plo \ + ./$(DEPDIR)/dbg_mlc.Plo ./$(DEPDIR)/dyn_load.Plo \ + ./$(DEPDIR)/finalize.Plo ./$(DEPDIR)/fnlz_mlc.Plo \ + ./$(DEPDIR)/gc_badalc.Plo ./$(DEPDIR)/gc_cpp.Plo \ + ./$(DEPDIR)/gc_dlopen.Plo ./$(DEPDIR)/gcj_mlc.Plo \ + ./$(DEPDIR)/headers.Plo ./$(DEPDIR)/mach_dep.Plo \ + ./$(DEPDIR)/malloc.Plo ./$(DEPDIR)/mallocx.Plo \ + ./$(DEPDIR)/mark.Plo ./$(DEPDIR)/mark_rts.Plo \ + ./$(DEPDIR)/misc.Plo ./$(DEPDIR)/new_hblk.Plo \ + ./$(DEPDIR)/obj_map.Plo ./$(DEPDIR)/os_dep.Plo \ + ./$(DEPDIR)/pthread_start.Plo \ + ./$(DEPDIR)/pthread_stop_world.Plo \ + ./$(DEPDIR)/pthread_support.Plo ./$(DEPDIR)/ptr_chck.Plo \ + ./$(DEPDIR)/reclaim.Plo ./$(DEPDIR)/sparc_mach_dep.Plo \ + ./$(DEPDIR)/specific.Plo ./$(DEPDIR)/thread_local_alloc.Plo \ + ./$(DEPDIR)/typd_mlc.Plo ./$(DEPDIR)/win32_threads.Plo \ + cord/$(DEPDIR)/libcord_la-cordbscs.Plo \ + cord/$(DEPDIR)/libcord_la-cordprnt.Plo \ + cord/$(DEPDIR)/libcord_la-cordxtra.Plo \ + cord/tests/$(DEPDIR)/cordtest.Po extra/$(DEPDIR)/gc.Plo \ + libatomic_ops/src/$(DEPDIR)/atomic_ops.Plo \ + libatomic_ops/src/$(DEPDIR)/atomic_ops_sysdeps.Plo \ + tests/$(DEPDIR)/disclaim_bench.Po \ + tests/$(DEPDIR)/disclaim_test.Po \ + tests/$(DEPDIR)/disclaim_weakmap_test.Po \ + tests/$(DEPDIR)/huge_test.Po \ + tests/$(DEPDIR)/initsecondarythread.Po \ + tests/$(DEPDIR)/leak_test.Po \ + tests/$(DEPDIR)/libstaticrootslib2_test_la-staticrootslib.Plo \ + tests/$(DEPDIR)/middle.Po tests/$(DEPDIR)/realloc_test.Po \ + tests/$(DEPDIR)/smash_test.Po \ + tests/$(DEPDIR)/staticrootslib.Plo \ + tests/$(DEPDIR)/staticrootstest-staticrootstest.Po \ + tests/$(DEPDIR)/subthread_create.Po tests/$(DEPDIR)/test.Po \ + tests/$(DEPDIR)/test_atomic_ops.Po tests/$(DEPDIR)/test_cpp.Po \ + tests/$(DEPDIR)/thread_leak_test.Po \ + tests/$(DEPDIR)/threadkey_test.Po \ + tests/$(DEPDIR)/trace_test.Po am__mv = mv -f CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CCASFLAGS) $(CCASFLAGS) @@ -496,25 +573,27 @@ am__v_CCAS_1 = SOURCES = $(libcord_la_SOURCES) $(libgc_la_SOURCES) \ $(EXTRA_libgc_la_SOURCES) $(nodist_libgc_la_SOURCES) \ - $(libgccpp_la_SOURCES) $(libstaticrootslib2_test_la_SOURCES) \ + $(libgccpp_la_SOURCES) $(libgctba_la_SOURCES) \ + $(libstaticrootslib2_test_la_SOURCES) \ $(libstaticrootslib_test_la_SOURCES) $(cordtest_SOURCES) \ $(disclaim_bench_SOURCES) $(disclaim_test_SOURCES) \ $(disclaim_weakmap_test_SOURCES) $(gctest_SOURCES) \ - $(hugetest_SOURCES) $(initsecondarythread_test_SOURCES) \ - $(leaktest_SOURCES) $(middletest_SOURCES) \ - $(realloc_test_SOURCES) $(smashtest_SOURCES) \ - $(staticrootstest_SOURCES) $(subthreadcreate_test_SOURCES) \ - $(test_atomic_ops_SOURCES) $(test_cpp_SOURCES) \ - $(threadkey_test_SOURCES) $(threadleaktest_SOURCES) \ - $(tracetest_SOURCES) + $(gctest_html_SOURCES) $(hugetest_SOURCES) \ + $(initsecondarythread_test_SOURCES) $(leaktest_SOURCES) \ + $(middletest_SOURCES) $(realloc_test_SOURCES) \ + $(smashtest_SOURCES) $(staticrootstest_SOURCES) \ + $(subthreadcreate_test_SOURCES) $(test_atomic_ops_SOURCES) \ + $(test_cpp_SOURCES) $(threadkey_test_SOURCES) \ + $(threadleaktest_SOURCES) $(tracetest_SOURCES) DIST_SOURCES = $(libcord_la_SOURCES) $(am__libgc_la_SOURCES_DIST) \ $(EXTRA_libgc_la_SOURCES) $(am__libgccpp_la_SOURCES_DIST) \ + $(am__libgctba_la_SOURCES_DIST) \ $(libstaticrootslib2_test_la_SOURCES) \ $(libstaticrootslib_test_la_SOURCES) $(cordtest_SOURCES) \ $(am__disclaim_bench_SOURCES_DIST) \ $(am__disclaim_test_SOURCES_DIST) \ $(am__disclaim_weakmap_test_SOURCES_DIST) $(gctest_SOURCES) \ - $(hugetest_SOURCES) \ + $(am__gctest_html_SOURCES_DIST) $(hugetest_SOURCES) \ $(am__initsecondarythread_test_SOURCES_DIST) \ $(leaktest_SOURCES) $(middletest_SOURCES) \ $(realloc_test_SOURCES) $(smashtest_SOURCES) \ @@ -544,24 +623,23 @@ am__dist_doc_DATA_DIST = AUTHORS README.md doc/README.DGUX386 \ doc/README.Mac doc/README.OS2 doc/README.amiga \ doc/README.arm.cross doc/README.autoconf doc/README.cmake \ - doc/README.cords doc/README.darwin doc/README.environment \ - doc/README.ews4800 doc/README.hp doc/README.linux \ - doc/README.macros doc/README.rs6000 doc/README.sgi \ - doc/README.solaris2 doc/README.symbian doc/README.uts \ - doc/README.win32 doc/README.win64 doc/debugging.md \ - doc/finalization.md doc/gcdescr.md doc/gcinterface.md \ - doc/leak.md doc/overview.md doc/porting.md doc/scale.md \ - doc/simple_example.md doc/tree.md + doc/README.cords doc/README.darwin doc/README.emscripten \ + doc/README.environment doc/README.ews4800 doc/README.hp \ + doc/README.linux doc/README.macros doc/README.rs6000 \ + doc/README.sgi doc/README.solaris2 doc/README.symbian \ + doc/README.uts doc/README.win32 doc/README.win64 \ + doc/debugging.md doc/finalization.md doc/gcdescr.md \ + doc/gcinterface.md doc/leak.md doc/overview.md doc/porting.md \ + doc/scale.md doc/simple_example.md doc/tree.md DATA = $(dist_doc_DATA) $(pkgconfig_DATA) am__include_HEADERS_DIST = include/extra/gc_cpp.h include/extra/gc.h -am__pkginclude_HEADERS_DIST = include/gc_disclaim.h \ - include/gc_allocator.h include/gc_cpp.h include/gc.h \ - include/gc_backptr.h include/gc_config_macros.h \ - include/gc_gcj.h include/gc_inline.h include/gc_mark.h \ - include/gc_pthread_redirects.h include/gc_tiny_fl.h \ - include/gc_typed.h include/gc_version.h include/javaxfc.h \ - include/leak_detector.h include/cord.h include/cord_pos.h \ - include/ec.h +am__pkginclude_HEADERS_DIST = include/gc_pthread_redirects.h \ + include/gc_gcj.h include/gc_disclaim.h include/gc_allocator.h \ + include/gc_cpp.h include/gc.h include/gc_backptr.h \ + include/gc_config_macros.h include/gc_inline.h \ + include/gc_mark.h include/gc_tiny_fl.h include/gc_typed.h \ + include/gc_version.h include/javaxfc.h include/leak_detector.h \ + include/cord.h include/cord_pos.h include/ec.h HEADERS = $(dist_noinst_HEADERS) $(include_HEADERS) \ $(pkginclude_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ @@ -571,7 +649,8 @@ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope check recheck distdir dist dist-all distcheck + cscope check recheck distdir distdir-am dist dist-all \ + distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -589,9 +668,6 @@ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no @@ -747,6 +823,7 @@ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` +AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test @@ -773,8 +850,8 @@ $(srcdir)/bdw-gc.pc.in $(srcdir)/cord/cord.am \ $(srcdir)/doc/doc.am $(srcdir)/include/include.am \ $(srcdir)/tests/tests.am $(top_srcdir)/include/config.h.in \ - AUTHORS ChangeLog compile config.guess config.sub depcomp \ - install-sh ltmain.sh missing test-driver + AUTHORS ChangeLog README.md compile config.guess config.sub \ + depcomp install-sh ltmain.sh missing test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -813,6 +890,8 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -839,6 +918,8 @@ CFLAGS_EXTRA = @CFLAGS_EXTRA@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ @@ -854,6 +935,7 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ EXTRA_TEST_LIBS = @EXTRA_TEST_LIBS@ FGREP = @FGREP@ @@ -968,8 +1050,8 @@ # Info (current:revision:age) for the Libtool versioning system. # These numbers should be updated at most once just before the release, # and, optionally, at most once during the development (after the release). -LIBGC_VER_INFO = 5:4:4 -LIBGCCPP_VER_INFO = 5:1:4 +LIBGC_VER_INFO = 6:1:5 +LIBGCCPP_VER_INFO = 6:0:5 # We currently use the source files directly from libatomic_ops, if we # use the internal version. This is done since libatomic_ops doesn't @@ -993,51 +1075,51 @@ # # other makefiles -# :GOTCHA: deliberately we do not include 'Makefile' # files used by makefiles other than Makefile.am # -EXTRA_DIST = $(am__append_3) gc_cpp.cpp README.QUICK BCC_MAKEFILE \ +EXTRA_DIST = $(am__append_3) gc_badalc.cpp gc_cpp.cpp README.QUICK \ NT_MAKEFILE OS2_MAKEFILE PCR-Makefile digimars.mak \ Makefile.direct SMakefile.amiga WCC_MAKEFILE autogen.sh \ - CMakeLists.txt tests/CMakeLists.txt tools/if_mach.c \ - tools/if_not_there.c tools/setjmp_t.c tools/threadlibs.c \ - gc.mak extra/MacOS.c extra/AmigaOS.c \ - extra/symbian/global_end.cpp extra/symbian/global_start.cpp \ + CMakeLists.txt Config.cmake.in build/s60v3/bld.inf \ + build/s60v3/libgc.mmp tools/if_mach.c tools/if_not_there.c \ + tools/setjmp_t.c tools/threadlibs.c extra/MacOS.c \ + extra/AmigaOS.c extra/symbian/global_end.cpp \ + extra/symbian/global_start.cpp \ extra/symbian/init_global_static_roots.cpp extra/symbian.cpp \ - extra/pcr_interface.c extra/real_malloc.c build/s60v3/bld.inf \ - build/s60v3/libgc.mmp extra/Mac_files/datastart.c \ - extra/Mac_files/dataend.c extra/Mac_files/MacOS_config.h \ - include/private/msvc_dbg.h extra/msvc_dbg.c tools/callprocs.sh \ - cord/tests/de.c cord/tests/de_cmds.h cord/tests/de_win.c \ - cord/tests/de_win.h cord/tests/de_win.rc + extra/pcr_interface.c extra/real_malloc.c \ + extra/Mac_files/datastart.c extra/Mac_files/dataend.c \ + extra/Mac_files/MacOS_config.h include/private/msvc_dbg.h \ + extra/msvc_dbg.c tools/callprocs.sh cord/tests/de.c \ + cord/tests/de_cmds.h cord/tests/de_win.c cord/tests/de_win.h \ + cord/tests/de_win.rc # C Library # --------- -lib_LTLIBRARIES = libgc.la $(am__append_13) libcord.la +lib_LTLIBRARIES = libgc.la $(am__append_17) $(am__append_20) \ + libcord.la # unprefixed header -include_HEADERS = $(am__append_15) include/extra/gc.h +include_HEADERS = $(am__append_19) include/extra/gc.h # installed headers # -pkginclude_HEADERS = $(am__append_12) $(am__append_14) include/gc.h \ +pkginclude_HEADERS = $(am__append_13) $(am__append_14) \ + $(am__append_15) $(am__append_18) include/gc.h \ include/gc_backptr.h include/gc_config_macros.h \ - include/gc_gcj.h include/gc_inline.h include/gc_mark.h \ - include/gc_pthread_redirects.h include/gc_tiny_fl.h \ + include/gc_inline.h include/gc_mark.h include/gc_tiny_fl.h \ include/gc_typed.h include/gc_version.h include/javaxfc.h \ include/leak_detector.h include/cord.h include/cord_pos.h \ include/ec.h # headers which are not installed # -dist_noinst_HEADERS = include/gc_alloc_ptrs.h include/new_gc_alloc.h \ - include/private/darwin_semaphore.h \ +dist_noinst_HEADERS = include/private/darwin_semaphore.h \ include/private/darwin_stop_world.h include/private/dbg_mlc.h \ + include/private/gc_alloc_ptrs.h \ include/private/gc_atomic_ops.h include/private/gc_hdrs.h \ include/private/gc_locks.h include/private/gc_pmark.h \ include/private/gc_priv.h include/private/gcconfig.h \ - include/private/msvc_dbg.h \ include/private/pthread_stop_world.h \ include/private/pthread_support.h include/private/specific.h \ include/private/thread_local_alloc.h @@ -1046,42 +1128,47 @@ TESTS = cordtest$(EXEEXT) gctest$(EXEEXT) leaktest$(EXEEXT) \ middletest$(EXEEXT) smashtest$(EXEEXT) hugetest$(EXEEXT) \ realloc_test$(EXEEXT) staticrootstest$(EXEEXT) \ - $(am__append_19) $(am__append_21) $(am__append_23) \ - $(am__append_26) + $(am__append_25) $(am__append_27) $(am__append_29) \ + $(am__append_32) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = bdw-gc.pc @SINGLE_GC_OBJ_FALSE@libgc_la_SOURCES = allchblk.c alloc.c blacklst.c \ @SINGLE_GC_OBJ_FALSE@ dbg_mlc.c dyn_load.c finalize.c \ -@SINGLE_GC_OBJ_FALSE@ gc_dlopen.c gcj_mlc.c headers.c \ -@SINGLE_GC_OBJ_FALSE@ mach_dep.c malloc.c mallocx.c mark.c \ -@SINGLE_GC_OBJ_FALSE@ mark_rts.c misc.c new_hblk.c obj_map.c \ -@SINGLE_GC_OBJ_FALSE@ os_dep.c ptr_chck.c reclaim.c specific.c \ -@SINGLE_GC_OBJ_FALSE@ typd_mlc.c $(am__append_4) \ -@SINGLE_GC_OBJ_FALSE@ $(am__append_5) $(am__append_6) \ -@SINGLE_GC_OBJ_FALSE@ $(am__append_7) $(am__append_8) \ -@SINGLE_GC_OBJ_FALSE@ $(am__append_9) $(am__append_10) \ -@SINGLE_GC_OBJ_FALSE@ $(am__append_11) +@SINGLE_GC_OBJ_FALSE@ gc_dlopen.c headers.c mach_dep.c malloc.c \ +@SINGLE_GC_OBJ_FALSE@ mallocx.c mark.c mark_rts.c misc.c \ +@SINGLE_GC_OBJ_FALSE@ new_hblk.c obj_map.c os_dep.c ptr_chck.c \ +@SINGLE_GC_OBJ_FALSE@ reclaim.c specific.c typd_mlc.c \ +@SINGLE_GC_OBJ_FALSE@ $(am__append_4) $(am__append_5) \ +@SINGLE_GC_OBJ_FALSE@ $(am__append_6) $(am__append_7) \ +@SINGLE_GC_OBJ_FALSE@ $(am__append_8) $(am__append_9) \ +@SINGLE_GC_OBJ_FALSE@ $(am__append_10) $(am__append_11) \ +@SINGLE_GC_OBJ_FALSE@ $(am__append_12) @SINGLE_GC_OBJ_TRUE@libgc_la_SOURCES = extra/gc.c $(am__append_2) \ @SINGLE_GC_OBJ_TRUE@ $(am__append_4) $(am__append_5) \ @SINGLE_GC_OBJ_TRUE@ $(am__append_6) $(am__append_7) \ @SINGLE_GC_OBJ_TRUE@ $(am__append_8) $(am__append_9) \ -@SINGLE_GC_OBJ_TRUE@ $(am__append_10) $(am__append_11) -@NEED_ATOMIC_OPS_ASM_TRUE@nodist_libgc_la_SOURCES = libatomic_ops/src/atomic_ops_sysdeps.S -@USE_INTERNAL_LIBATOMIC_OPS_TRUE@nodist_libgc_la_SOURCES = libatomic_ops/src/atomic_ops.c +@SINGLE_GC_OBJ_TRUE@ $(am__append_10) $(am__append_11) \ +@SINGLE_GC_OBJ_TRUE@ $(am__append_12) +@USE_INTERNAL_LIBATOMIC_OPS_TRUE@nodist_libgc_la_SOURCES = libatomic_ops/src/atomic_ops.c \ +@USE_INTERNAL_LIBATOMIC_OPS_TRUE@ $(am__append_16) # Include THREADDLLIBS here to ensure that the correct versions of -# linuxthread semaphore functions get linked: +# linuxthread semaphore (and clock_gettime) functions get linked: libgc_la_LIBADD = @addobjs@ $(THREADDLLIBS) $(UNWINDLIBS) $(ATOMIC_OPS_LIBS) libgc_la_DEPENDENCIES = @addobjs@ libgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info $(LIBGC_VER_INFO) \ -no-undefined EXTRA_libgc_la_SOURCES = ia64_save_regs_in_stack.s sparc_mach_dep.S \ - sparc_netbsd_mach_dep.s sparc_sunos4_mach_dep.s + sparc_netbsd_mach_dep.s -@CPLUSPLUS_TRUE@libgccpp_la_SOURCES = gc_cpp.cc -@CPLUSPLUS_TRUE@libgccpp_la_LIBADD = ./libgc.la +@CPLUSPLUS_TRUE@libgccpp_la_SOURCES = gc_badalc.cc gc_cpp.cc +@CPLUSPLUS_TRUE@libgccpp_la_LIBADD = libgc.la @CPLUSPLUS_TRUE@libgccpp_la_LDFLAGS = -version-info $(LIBGCCPP_VER_INFO) -no-undefined +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@libgctba_la_SOURCES = gc_badalc.cc +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@libgctba_la_LIBADD = libgc.la +# Set the same version as for libgccpp. +@CPLUSPLUS_TRUE@@GC_TBA_LIBRARY_TRUE@libgctba_la_LDFLAGS = -version-info $(LIBGCCPP_VER_INFO) -no-undefined # Misc # ---- @@ -1100,8 +1187,8 @@ # Info (current:revision:age) for the Libtool versioning system. # These numbers should be updated at most once just before the release, # and, optionally, at most once during the development (after the release). -LIBCORD_VER_INFO = 5:0:4 -libcord_la_LIBADD = $(top_builddir)/libgc.la +LIBCORD_VER_INFO = 6:0:5 +libcord_la_LIBADD = libgc.la libcord_la_LDFLAGS = -version-info $(LIBCORD_VER_INFO) -no-undefined libcord_la_CPPFLAGS = $(AM_CPPFLAGS) libcord_la_SOURCES = \ @@ -1110,15 +1197,20 @@ cord/cordxtra.c cordtest_SOURCES = cord/tests/cordtest.c -cordtest_LDADD = $(top_builddir)/libcord.la $(am__append_16) +cordtest_LDADD = $(top_builddir)/libcord.la $(am__append_21) # Common libs to _LDADD for all tests. test_ldadd = $(nodist_libgc_la_OBJECTS) $(top_builddir)/libgc.la \ $(EXTRA_TEST_LIBS) gctest_SOURCES = tests/test.c -gctest_LDADD = $(test_ldadd) $(am__append_17) +gctest_LDADD = $(test_ldadd) $(am__append_22) gctest_DEPENDENCIES = $(top_builddir)/libgc.la +@EMSCRIPTEN_TRUE@gctest_html_SOURCES = $(gctest_SOURCES) +@EMSCRIPTEN_TRUE@gctest_html_LDADD = $(gctest_LDADD) +# Bug in the linker not being able to determine that _memalign and +# _memalign is needed? it's part of mmap. +@EMSCRIPTEN_TRUE@gctest_html_LDFLAGS = -s "EXPORTED_FUNCTIONS='_memalign', '_main', '_memset'" leaktest_SOURCES = tests/leak_test.c leaktest_LDADD = $(test_ldadd) middletest_SOURCES = tests/middle.c @@ -1133,7 +1225,7 @@ staticrootstest_CFLAGS = -DSTATICROOTSLIB2 staticrootstest_LDADD = $(nodist_libgc_la_OBJECTS) $(EXTRA_TEST_LIBS) \ libstaticrootslib_test.la libstaticrootslib2_test.la \ - $(am__append_18) + $(am__append_24) libstaticrootslib_test_la_SOURCES = tests/staticrootslib.c libstaticrootslib_test_la_LIBADD = $(test_ldadd) libstaticrootslib_test_la_LDFLAGS = -no-undefined -rpath /nowhere @@ -1160,18 +1252,19 @@ @AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(nodist_libgc_la_OBJECTS) \ @AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(EXTRA_TEST_LIBS) \ @AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(CXXLIBS) \ -@AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(am__append_25) -@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@test_cpp_LDADD = gc_cpp.o \ -@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(test_ldadd) $(CXXLIBS) \ -@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(am__append_25) +@AVOID_CPP_LIB_FALSE@@CPLUSPLUS_TRUE@ $(am__append_31) +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@test_cpp_LDADD = gc_badalc.o \ +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ gc_cpp.o $(test_ldadd) \ +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(CXXLIBS) \ +@AVOID_CPP_LIB_TRUE@@CPLUSPLUS_TRUE@ $(am__append_31) @ENABLE_DISCLAIM_TRUE@disclaim_test_SOURCES = tests/disclaim_test.c @ENABLE_DISCLAIM_TRUE@disclaim_test_LDADD = $(test_ldadd) \ -@ENABLE_DISCLAIM_TRUE@ $(am__append_28) +@ENABLE_DISCLAIM_TRUE@ $(am__append_34) @ENABLE_DISCLAIM_TRUE@disclaim_bench_SOURCES = tests/disclaim_bench.c @ENABLE_DISCLAIM_TRUE@disclaim_bench_LDADD = $(test_ldadd) @ENABLE_DISCLAIM_TRUE@disclaim_weakmap_test_SOURCES = tests/disclaim_weakmap_test.c @ENABLE_DISCLAIM_TRUE@disclaim_weakmap_test_LDADD = $(test_ldadd) \ -@ENABLE_DISCLAIM_TRUE@ $(am__append_29) +@ENABLE_DISCLAIM_TRUE@ $(am__append_35) # installed documentation @ENABLE_DOCS_TRUE@dist_doc_DATA = \ @@ -1186,6 +1279,7 @@ @ENABLE_DOCS_TRUE@ doc/README.cmake \ @ENABLE_DOCS_TRUE@ doc/README.cords \ @ENABLE_DOCS_TRUE@ doc/README.darwin \ +@ENABLE_DOCS_TRUE@ doc/README.emscripten \ @ENABLE_DOCS_TRUE@ doc/README.environment \ @ENABLE_DOCS_TRUE@ doc/README.ews4800 \ @ENABLE_DOCS_TRUE@ doc/README.hp \ @@ -1235,8 +1329,8 @@ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(srcdir)/include/include.am $(srcdir)/cord/cord.am $(srcdir)/tests/tests.am $(srcdir)/doc/doc.am $(am__empty): @@ -1266,6 +1360,15 @@ bdw-gc.pc: $(top_builddir)/config.status $(srcdir)/bdw-gc.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ @@ -1339,17 +1442,20 @@ libatomic_ops/src/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) libatomic_ops/src/$(DEPDIR) @: > libatomic_ops/src/$(DEPDIR)/$(am__dirstamp) +libatomic_ops/src/atomic_ops.lo: libatomic_ops/src/$(am__dirstamp) \ + libatomic_ops/src/$(DEPDIR)/$(am__dirstamp) libatomic_ops/src/atomic_ops_sysdeps.lo: \ libatomic_ops/src/$(am__dirstamp) \ libatomic_ops/src/$(DEPDIR)/$(am__dirstamp) -libatomic_ops/src/atomic_ops.lo: libatomic_ops/src/$(am__dirstamp) \ - libatomic_ops/src/$(DEPDIR)/$(am__dirstamp) libgc.la: $(libgc_la_OBJECTS) $(libgc_la_DEPENDENCIES) $(EXTRA_libgc_la_DEPENDENCIES) $(AM_V_CCLD)$(libgc_la_LINK) -rpath $(libdir) $(libgc_la_OBJECTS) $(libgc_la_LIBADD) $(LIBS) libgccpp.la: $(libgccpp_la_OBJECTS) $(libgccpp_la_DEPENDENCIES) $(EXTRA_libgccpp_la_DEPENDENCIES) $(AM_V_CXXLD)$(libgccpp_la_LINK) $(am_libgccpp_la_rpath) $(libgccpp_la_OBJECTS) $(libgccpp_la_LIBADD) $(LIBS) + +libgctba.la: $(libgctba_la_OBJECTS) $(libgctba_la_DEPENDENCIES) $(EXTRA_libgctba_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libgctba_la_LINK) $(am_libgctba_la_rpath) $(libgctba_la_OBJECTS) $(libgctba_la_LIBADD) $(LIBS) tests/$(am__dirstamp): @$(MKDIR_P) tests @: > tests/$(am__dirstamp) @@ -1366,15 +1472,6 @@ libstaticrootslib_test.la: $(libstaticrootslib_test_la_OBJECTS) $(libstaticrootslib_test_la_DEPENDENCIES) $(EXTRA_libstaticrootslib_test_la_DEPENDENCIES) $(AM_V_CCLD)$(libstaticrootslib_test_la_LINK) $(libstaticrootslib_test_la_OBJECTS) $(libstaticrootslib_test_la_LIBADD) $(LIBS) - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list cord/tests/$(am__dirstamp): @$(MKDIR_P) cord/tests @: > cord/tests/$(am__dirstamp) @@ -1411,6 +1508,10 @@ gctest$(EXEEXT): $(gctest_OBJECTS) $(gctest_DEPENDENCIES) $(EXTRA_gctest_DEPENDENCIES) @rm -f gctest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gctest_OBJECTS) $(gctest_LDADD) $(LIBS) + +gctest.html$(EXEEXT): $(gctest_html_OBJECTS) $(gctest_html_DEPENDENCIES) $(EXTRA_gctest_html_DEPENDENCIES) + @rm -f gctest.html$(EXEEXT) + $(AM_V_CCLD)$(gctest_html_LINK) $(gctest_html_OBJECTS) $(gctest_html_LDADD) $(LIBS) tests/huge_test.$(OBJEXT): tests/$(am__dirstamp) \ tests/$(DEPDIR)/$(am__dirstamp) @@ -1505,65 +1606,72 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allchblk.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backgraph.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blacklst.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checksums.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/darwin_stop_world.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbg_mlc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyn_load.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/finalize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnlz_mlc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_cpp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_dlopen.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcj_mlc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/headers.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach_dep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mallocx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mark.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mark_rts.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/new_hblk.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obj_map.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_dep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_start.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_stop_world.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_support.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptr_chck.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reclaim.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_mach_dep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specific.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_local_alloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typd_mlc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32_threads.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cord/$(DEPDIR)/libcord_la-cordbscs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cord/$(DEPDIR)/libcord_la-cordprnt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cord/$(DEPDIR)/libcord_la-cordxtra.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cord/tests/$(DEPDIR)/cordtest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@extra/$(DEPDIR)/gc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@libatomic_ops/src/$(DEPDIR)/atomic_ops.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@libatomic_ops/src/$(DEPDIR)/atomic_ops_sysdeps.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/disclaim_bench.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/disclaim_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/disclaim_weakmap_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/huge_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/initsecondarythread.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/leak_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libstaticrootslib2_test_la-staticrootslib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/middle.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/realloc_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/smash_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/staticrootslib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/staticrootstest-staticrootstest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/subthread_create.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_atomic_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_cpp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/thread_leak_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/threadkey_test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/trace_test.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allchblk.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backgraph.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blacklst.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checksums.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/darwin_stop_world.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbg_mlc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dyn_load.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/finalize.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnlz_mlc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_badalc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_cpp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gc_dlopen.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcj_mlc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/headers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach_dep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mallocx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mark.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mark_rts.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/new_hblk.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obj_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_dep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_start.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_stop_world.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pthread_support.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptr_chck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reclaim.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sparc_mach_dep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specific.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_local_alloc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/typd_mlc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32_threads.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@cord/$(DEPDIR)/libcord_la-cordbscs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@cord/$(DEPDIR)/libcord_la-cordprnt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@cord/$(DEPDIR)/libcord_la-cordxtra.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@cord/tests/$(DEPDIR)/cordtest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@extra/$(DEPDIR)/gc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libatomic_ops/src/$(DEPDIR)/atomic_ops.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libatomic_ops/src/$(DEPDIR)/atomic_ops_sysdeps.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/disclaim_bench.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/disclaim_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/disclaim_weakmap_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/huge_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/initsecondarythread.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/leak_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/libstaticrootslib2_test_la-staticrootslib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/middle.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/realloc_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/smash_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/staticrootslib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/staticrootstest-staticrootstest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/subthread_create.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_atomic_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_cpp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/thread_leak_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/threadkey_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/trace_test.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .S.o: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|^/*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -2028,7 +2136,7 @@ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ @@ -2041,7 +2149,7 @@ fi; \ $$success || exit 1 -check-TESTS: +check-TESTS: $(check_PROGRAMS) $(check_LTLIBRARIES) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @@ -2051,7 +2159,7 @@ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; -recheck: all $(check_LTLIBRARIES) $(check_PROGRAMS) +recheck: all $(check_PROGRAMS) $(check_LTLIBRARIES) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ @@ -2202,8 +2310,10 @@ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am -distdir: $(DISTFILES) +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/.^$$\\*/\\\\&/g'`; \ @@ -2268,7 +2378,7 @@ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -2283,6 +2393,10 @@ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -2294,7 +2408,7 @@ @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -2312,7 +2426,7 @@ distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -2322,9 +2436,11 @@ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -2340,7 +2456,7 @@ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ @@ -2392,10 +2508,14 @@ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_LTLIBRARIES) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS) +install-checkPROGRAMS: install-libLTLIBRARIES + +install-checkLTLIBRARIES: install-libLTLIBRARIES + installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \ @@ -2451,7 +2571,66 @@ distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) cord/$(DEPDIR) cord/tests/$(DEPDIR) extra/$(DEPDIR) libatomic_ops/src/$(DEPDIR) tests/$(DEPDIR) + -rm -f ./$(DEPDIR)/allchblk.Plo + -rm -f ./$(DEPDIR)/alloc.Plo + -rm -f ./$(DEPDIR)/backgraph.Plo + -rm -f ./$(DEPDIR)/blacklst.Plo + -rm -f ./$(DEPDIR)/checksums.Plo + -rm -f ./$(DEPDIR)/darwin_stop_world.Plo + -rm -f ./$(DEPDIR)/dbg_mlc.Plo + -rm -f ./$(DEPDIR)/dyn_load.Plo + -rm -f ./$(DEPDIR)/finalize.Plo + -rm -f ./$(DEPDIR)/fnlz_mlc.Plo + -rm -f ./$(DEPDIR)/gc_badalc.Plo + -rm -f ./$(DEPDIR)/gc_cpp.Plo + -rm -f ./$(DEPDIR)/gc_dlopen.Plo + -rm -f ./$(DEPDIR)/gcj_mlc.Plo + -rm -f ./$(DEPDIR)/headers.Plo + -rm -f ./$(DEPDIR)/mach_dep.Plo + -rm -f ./$(DEPDIR)/malloc.Plo + -rm -f ./$(DEPDIR)/mallocx.Plo + -rm -f ./$(DEPDIR)/mark.Plo + -rm -f ./$(DEPDIR)/mark_rts.Plo + -rm -f ./$(DEPDIR)/misc.Plo + -rm -f ./$(DEPDIR)/new_hblk.Plo + -rm -f ./$(DEPDIR)/obj_map.Plo + -rm -f ./$(DEPDIR)/os_dep.Plo + -rm -f ./$(DEPDIR)/pthread_start.Plo + -rm -f ./$(DEPDIR)/pthread_stop_world.Plo + -rm -f ./$(DEPDIR)/pthread_support.Plo + -rm -f ./$(DEPDIR)/ptr_chck.Plo + -rm -f ./$(DEPDIR)/reclaim.Plo + -rm -f ./$(DEPDIR)/sparc_mach_dep.Plo + -rm -f ./$(DEPDIR)/specific.Plo + -rm -f ./$(DEPDIR)/thread_local_alloc.Plo + -rm -f ./$(DEPDIR)/typd_mlc.Plo + -rm -f ./$(DEPDIR)/win32_threads.Plo + -rm -f cord/$(DEPDIR)/libcord_la-cordbscs.Plo + -rm -f cord/$(DEPDIR)/libcord_la-cordprnt.Plo + -rm -f cord/$(DEPDIR)/libcord_la-cordxtra.Plo + -rm -f cord/tests/$(DEPDIR)/cordtest.Po + -rm -f extra/$(DEPDIR)/gc.Plo + -rm -f libatomic_ops/src/$(DEPDIR)/atomic_ops.Plo + -rm -f libatomic_ops/src/$(DEPDIR)/atomic_ops_sysdeps.Plo + -rm -f tests/$(DEPDIR)/disclaim_bench.Po + -rm -f tests/$(DEPDIR)/disclaim_test.Po + -rm -f tests/$(DEPDIR)/disclaim_weakmap_test.Po + -rm -f tests/$(DEPDIR)/huge_test.Po + -rm -f tests/$(DEPDIR)/initsecondarythread.Po + -rm -f tests/$(DEPDIR)/leak_test.Po + -rm -f tests/$(DEPDIR)/libstaticrootslib2_test_la-staticrootslib.Plo + -rm -f tests/$(DEPDIR)/middle.Po + -rm -f tests/$(DEPDIR)/realloc_test.Po + -rm -f tests/$(DEPDIR)/smash_test.Po + -rm -f tests/$(DEPDIR)/staticrootslib.Plo + -rm -f tests/$(DEPDIR)/staticrootstest-staticrootstest.Po + -rm -f tests/$(DEPDIR)/subthread_create.Po + -rm -f tests/$(DEPDIR)/test.Po + -rm -f tests/$(DEPDIR)/test_atomic_ops.Po + -rm -f tests/$(DEPDIR)/test_cpp.Po + -rm -f tests/$(DEPDIR)/thread_leak_test.Po + -rm -f tests/$(DEPDIR)/threadkey_test.Po + -rm -f tests/$(DEPDIR)/trace_test.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -2500,7 +2679,66 @@ maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) cord/$(DEPDIR) cord/tests/$(DEPDIR) extra/$(DEPDIR) libatomic_ops/src/$(DEPDIR) tests/$(DEPDIR) + -rm -f ./$(DEPDIR)/allchblk.Plo + -rm -f ./$(DEPDIR)/alloc.Plo + -rm -f ./$(DEPDIR)/backgraph.Plo + -rm -f ./$(DEPDIR)/blacklst.Plo + -rm -f ./$(DEPDIR)/checksums.Plo + -rm -f ./$(DEPDIR)/darwin_stop_world.Plo + -rm -f ./$(DEPDIR)/dbg_mlc.Plo + -rm -f ./$(DEPDIR)/dyn_load.Plo + -rm -f ./$(DEPDIR)/finalize.Plo + -rm -f ./$(DEPDIR)/fnlz_mlc.Plo + -rm -f ./$(DEPDIR)/gc_badalc.Plo + -rm -f ./$(DEPDIR)/gc_cpp.Plo + -rm -f ./$(DEPDIR)/gc_dlopen.Plo + -rm -f ./$(DEPDIR)/gcj_mlc.Plo + -rm -f ./$(DEPDIR)/headers.Plo + -rm -f ./$(DEPDIR)/mach_dep.Plo + -rm -f ./$(DEPDIR)/malloc.Plo + -rm -f ./$(DEPDIR)/mallocx.Plo + -rm -f ./$(DEPDIR)/mark.Plo + -rm -f ./$(DEPDIR)/mark_rts.Plo + -rm -f ./$(DEPDIR)/misc.Plo + -rm -f ./$(DEPDIR)/new_hblk.Plo + -rm -f ./$(DEPDIR)/obj_map.Plo + -rm -f ./$(DEPDIR)/os_dep.Plo + -rm -f ./$(DEPDIR)/pthread_start.Plo + -rm -f ./$(DEPDIR)/pthread_stop_world.Plo + -rm -f ./$(DEPDIR)/pthread_support.Plo + -rm -f ./$(DEPDIR)/ptr_chck.Plo + -rm -f ./$(DEPDIR)/reclaim.Plo + -rm -f ./$(DEPDIR)/sparc_mach_dep.Plo + -rm -f ./$(DEPDIR)/specific.Plo + -rm -f ./$(DEPDIR)/thread_local_alloc.Plo + -rm -f ./$(DEPDIR)/typd_mlc.Plo + -rm -f ./$(DEPDIR)/win32_threads.Plo + -rm -f cord/$(DEPDIR)/libcord_la-cordbscs.Plo + -rm -f cord/$(DEPDIR)/libcord_la-cordprnt.Plo + -rm -f cord/$(DEPDIR)/libcord_la-cordxtra.Plo + -rm -f cord/tests/$(DEPDIR)/cordtest.Po + -rm -f extra/$(DEPDIR)/gc.Plo + -rm -f libatomic_ops/src/$(DEPDIR)/atomic_ops.Plo + -rm -f libatomic_ops/src/$(DEPDIR)/atomic_ops_sysdeps.Plo + -rm -f tests/$(DEPDIR)/disclaim_bench.Po + -rm -f tests/$(DEPDIR)/disclaim_test.Po + -rm -f tests/$(DEPDIR)/disclaim_weakmap_test.Po + -rm -f tests/$(DEPDIR)/huge_test.Po + -rm -f tests/$(DEPDIR)/initsecondarythread.Po + -rm -f tests/$(DEPDIR)/leak_test.Po + -rm -f tests/$(DEPDIR)/libstaticrootslib2_test_la-staticrootslib.Plo + -rm -f tests/$(DEPDIR)/middle.Po + -rm -f tests/$(DEPDIR)/realloc_test.Po + -rm -f tests/$(DEPDIR)/smash_test.Po + -rm -f tests/$(DEPDIR)/staticrootslib.Plo + -rm -f tests/$(DEPDIR)/staticrootstest-staticrootstest.Po + -rm -f tests/$(DEPDIR)/subthread_create.Po + -rm -f tests/$(DEPDIR)/test.Po + -rm -f tests/$(DEPDIR)/test_atomic_ops.Po + -rm -f tests/$(DEPDIR)/test_cpp.Po + -rm -f tests/$(DEPDIR)/thread_leak_test.Po + -rm -f tests/$(DEPDIR)/threadkey_test.Po + -rm -f tests/$(DEPDIR)/trace_test.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -2526,28 +2764,29 @@ .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-TESTS check-am clean \ + am--depfiles am--refresh check check-TESTS check-am clean \ clean-checkLTLIBRARIES clean-checkPROGRAMS clean-cscope \ clean-generic clean-libLTLIBRARIES clean-libtool cscope \ cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dist_docDATA install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-man3 install-pdf \ - install-pdf-am install-pkgconfigDATA install-pkgincludeHEADERS \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am \ - uninstall-dist_docDATA uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES uninstall-man uninstall-man3 \ - uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS + dist-zstd distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_docDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-man3 install-pdf install-pdf-am install-pkgconfigDATA \ + install-pkgincludeHEADERS install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ + uninstall uninstall-am uninstall-dist_docDATA \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-man uninstall-man3 uninstall-pkgconfigDATA \ + uninstall-pkgincludeHEADERS .PRECIOUS: Makefile @@ -2587,6 +2826,9 @@ test ! -f tracetest$(EXEEXT) || ./tracetest$(EXEEXT) ./cordtest$(EXEEXT) +# A dummy target for mono build. +test-bundle: + # Tell versions 3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT:
View file
_service:tar_scm:gc-8.0.6.tar.gz/NT_MAKEFILE -> _service:tar_scm:gc-8.2.2.tar.gz/NT_MAKEFILE
Changed
@@ -1,9 +1,9 @@ # Makefile for Windows NT. Assumes Microsoft compiler. # Should be invoked as "nmake -f NT_MAKEFILE <args>"; the optional arguments # are: "cpu=AMD64" - to target x64, "cpu=i386" - to target x86, -# "make_as_lib=1" - to build it as a static library, "nodebug=1" - to produce -# the release variant of the library, "nothreads=1" - to build the library and -# the tests without threads support. +# "enable_static=1" - to build it as a static library, "nodebug=1" - to produce +# the release variant of the library, "disable_threads=1" - to build the +# library and the tests without threads support. cc = cl link = link @@ -52,26 +52,25 @@ CFLAGS_DEBUG=-DGC_ASSERTIONS !ENDIF -!IFNDEF NOTHREADS -CFLAGS_MT=$(cvarsmt) -DGC_THREADS -DTHREAD_LOCAL_ALLOC -DPARALLEL_MARK -!ENDIF - -!IFDEF MAKE_AS_LIB +!IFDEF ENABLE_STATIC CFLAGS_GCDLL=-DGC_NOT_DLL -GC_LIB=gc.lib -LINK_GC=lib /out:$(GC_LIB) +CORDFLAG= !ELSE CFLAGS_GCDLL=-DGC_DLL -!IF "$(CPU)" == "AMD64" -GC_DLL=gc64.dll -GC_LIB=gc64_dll.lib +# cord.dll and its clients should not link C library statically otherwise +# FILE-related functions might not work (because own set of opened FILEs +# is maintained by each copy of the C library thus making impossible to pass +# FILE pointer from .exe code to .dll code). +cvarsmt= +!IFDEF NODEBUG +CORDFLAG=-MD !ELSE -GC_DLL=gc.dll -GC_LIB=gc_dll.lib +CORDFLAG=-MDd !ENDIF -LINK_DLL_FLAGS=kernel32.lib user32.lib /subsystem:windows /dll \ - /INCREMENTAL:NO /pdb:"gc.pdb" /out:$(GC_DLL) /implib:$(GC_LIB) -LINK_GC=$(link) $(ldebug) $(LINK_DLL_FLAGS) +!ENDIF + +!IFNDEF DISABLE_THREADS +CFLAGS_MT=$(cvarsmt) -DGC_THREADS -DTHREAD_LOCAL_ALLOC -DPARALLEL_MARK !ENDIF CFLAGS_SPECIFIC=$(CFLAGS_DEBUG) $(CFLAGS_GCDLL) $(CFLAGS_MT) @@ -91,12 +90,23 @@ AO_SRC_DIR=libatomic_ops/src AO_INCLUDE_DIR=$(AO_SRC_DIR) -OBJS= misc.obj win32_threads.obj alloc.obj reclaim.obj allchblk.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj fnlz_mlc.obj malloc.obj dyn_load.obj typd_mlc.obj ptr_chck.obj gc_cpp.obj gcj_mlc.obj mallocx.obj extra\msvc_dbg.obj thread_local_alloc.obj +!IFDEF ENABLE_STATIC +OBJS= misc.obj win32_threads.obj alloc.obj reclaim.obj allchblk.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj fnlz_mlc.obj malloc.obj dyn_load.obj typd_mlc.obj ptr_chck.obj gcj_mlc.obj mallocx.obj extra\msvc_dbg.obj thread_local_alloc.obj +!ELSE +OBJS= extra\gc.obj extra\msvc_dbg.obj +!ENDIF + +COBJS= cord\cordbscs.obj cord\cordxtra.obj cord\cordprnt.obj -all: gctest.exe cord\de.exe test_cpp.exe +all: gc.lib cord.lib gccpp.lib gctba.lib + +check: gctest.exe test_cpp.exe cordtest.exe de.exe + gctest.exe + cordtest.exe + test_cpp.exe .c.obj: - $(cc) $(cdebug) $(cflags) $(CFLAGS_SPECIFIC) -Iinclude -I$(AO_INCLUDE_DIR) $(CFLAGS_DEFAULT) -DCORD_NOT_DLL -D_CRT_SECURE_NO_DEPRECATE $*.c /Fo$*.obj /wd4100 /wd4127 /wd4701 + $(cc) $(cdebug) $(cflags) $(CFLAGS_SPECIFIC) $(CORDFLAG) -Iinclude -I$(AO_INCLUDE_DIR) $(CFLAGS_DEFAULT) -D_CRT_SECURE_NO_DEPRECATE $*.c /Fo$*.obj /wd4100 /wd4127 /wd4701 # Disable crt security warnings, since unfortunately they warn about all sorts # of safe uses of strncpy. It would be nice to leave the rest enabled. @@ -105,11 +115,39 @@ $(OBJS) tests\test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h include\private\gc_locks.h include\private\gc_pmark.h include\gc_mark.h include\gc_disclaim.h include\private\msvc_dbg.h -$(GC_LIB): $(OBJS) - $(LINK_GC) /MACHINE:$(CPU) $(OBJS) +!IFDEF ENABLE_STATIC + +gc.lib: $(OBJS) + lib /out:gc.lib /MACHINE:$(CPU) $(OBJS) + +cord.lib: $(COBJS) + lib /out:cord.lib /MACHINE:$(CPU) $(COBJS) -gctest.exe: $(GC_LIB) tests\test.obj - $(link) /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) user32.lib -out:$*.exe tests\test.obj $(GC_LIB) +gccpp.lib: gc_badalc.obj gc_cpp.obj + lib /out:gccpp.lib /MACHINE:$(CPU) gc_badalc.obj gc_cpp.obj + +# The same as gccpp.lib but contains only gc_badalc.obj. +gctba.lib: gc_badalc.obj + lib /out:gctba.lib /MACHINE:$(CPU) gc_badalc.obj + +!ELSE + +gc.lib: $(OBJS) + $(link) $(ldebug) kernel32.lib user32.lib /subsystem:windows /dll /INCREMENTAL:NO /pdb:"gc.pdb" /out:gc.dll /implib:gc.lib /MACHINE:$(CPU) $(OBJS) + +cord.lib: $(COBJS) gc.lib + $(link) $(ldebug) gc.lib /subsystem:windows /dll /INCREMENTAL:NO /pdb:"cord.pdb" /out:cord.dll /implib:cord.lib /MACHINE:$(CPU) $(COBJS) + +gccpp.lib: gc_badalc.obj gc_cpp.obj gc.lib + $(link) $(ldebug) gc.lib /subsystem:windows /dll /INCREMENTAL:NO /pdb:"gccpp.pdb" /out:gccpp.dll /implib:gccpp.lib /MACHINE:$(CPU) gc_badalc.obj gc_cpp.obj + +gctba.lib: gc_badalc.obj gc.lib + $(link) $(ldebug) gc.lib /subsystem:windows /dll /INCREMENTAL:NO /pdb:"gctba.pdb" /out:gctba.dll /implib:gctba.lib /MACHINE:$(CPU) gc_badalc.obj + +!ENDIF + +gctest.exe: gc.lib tests\test.obj + $(link) /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) user32.lib -out:$*.exe tests\test.obj gc.lib # mapsympe -n -o gctest.sym gctest.exe # This produces a GUI app that opens no window and writes to gctest.gc.log. @@ -122,8 +160,13 @@ $(rc) $(rcvars) -r -fo cord\tests\de_win.res cord\tests\de_win.rc # Cord/de is a real win32 GUI app. -cord\de.exe: cord\cordbscs.obj cord\cordxtra.obj cord\tests\de.obj cord\tests\de_win.obj cord\tests\de_win.rbj $(GC_LIB) - $(link) /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) -out:cord\de.exe cord\cordbscs.obj cord\cordxtra.obj cord\tests\de.obj cord\tests\de_win.obj cord\tests\de_win.rbj $(GC_LIB) gdi32.lib user32.lib +de.exe: cord\tests\de.obj cord\tests\de_win.obj cord\tests\de_win.rbj gc.lib cord.lib + $(link) /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) -out:de.exe cord\tests\de.obj cord\tests\de_win.obj cord\tests\de_win.rbj gc.lib cord.lib gdi32.lib user32.lib + +cordtest.exe: cord\tests\cordtest.obj gc.lib cord.lib + $(link) /subsystem:console /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) -out:cordtest.exe cord\tests\cordtest.obj gc.lib cord.lib user32.lib + +gc_badalc.obj: gc_badalc.cc include\gc_cpp.h include\gc.h gc_cpp.obj: gc_cpp.cc include\gc_cpp.h include\gc.h @@ -133,11 +176,11 @@ # This generates the C++ test executable. The executable expects # a single numeric argument, which is the number of iterations. # The output appears in test_cpp.gc.log file. -test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h $(GC_LIB) - $(link) /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) user32.lib -out:test_cpp.exe test_cpp.obj $(GC_LIB) +test_cpp.exe: test_cpp.obj include\gc_cpp.h include\gc.h gc.lib gccpp.lib + $(link) /MACHINE:$(CPU) /INCREMENTAL:NO $(ldebug) $(lflags) user32.lib -out:test_cpp.exe test_cpp.obj gc.lib gccpp.lib $(AO_SRC_DIR): tar xvfz $(AO_SRC_DIR).tar.gz clean: - del *.exe *.log *.obj *.pdb cord\*.exe cord\*.exp cord\*.lib cord\*.obj cord\*.pdb cord\tests\*.rbj cord\tests\*.res cord\tests\*.obj extra\*.obj gc*.lib gc*.dll gc*.exp test_cpp.cpp tests\*.obj 2> nul + del *.dll *.exe *.exp *.lib *.log *.obj *.pdb cordtst*.tmp cord\*.obj cord\tests\*.rbj cord\tests\*.res cord\tests\*.obj extra\*.obj test_cpp.cpp tests\*.obj 2> nul
View file
_service:tar_scm:gc-8.0.6.tar.gz/OS2_MAKEFILE -> _service:tar_scm:gc-8.2.2.tar.gz/OS2_MAKEFILE
Changed
@@ -3,7 +3,7 @@ # Adding thread support may be nontrivial, since we haven't yet figured out how to # look at another thread's registers. -# Significantly revised for GC version 4.4 by Mark Boulter (Jan 1994). +# Significantly revised by Mark Boulter (Jan 1994). OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj fnlz_mlc.obj malloc.obj typd_mlc.obj ptr_chck.obj mallocx.obj gcj_mlc.obj @@ -15,7 +15,11 @@ # Setjmp_test may yield overly optimistic results when compiled # without optimization. -all: $(OBJS) gctest.exe cord\cordtest.exe +all: gc.lib cord.lib + +check: gctest.exe cordtest.exe + gctest.exe + cordtest.exe $(OBJS) test.obj: include\private\gc_priv.h include\private\gc_hdrs.h include\gc.h include\private\gcconfig.h @@ -41,5 +45,15 @@ cord\cordprnt.obj: cord\cordprnt.c include\cord.h include\cord_pos.h include\ec.h $(CC) $(CFLAGS) /C /Focord\cordprnt cord\cordprnt.c -cord\cordtest.exe: cord\tests\cordtest.c include\cord.h include\cord_pos.h include\ec.h $(CORDOBJS) gc.lib - $(CC) $(CFLAGS) /B"/STACK:65536" /Fecord\cordtest cord\tests\cordtest.c gc.lib $(CORDOBJS) +cord.lib: $(CORDOBJS) + echo . > cord.lib + erase cord.lib + LIB cord.lib $(CORDOBJS), cord.lst + +cordtest.exe: cord\tests\cordtest.c include\cord.h include\cord_pos.h include\ec.h gc.lib cord.lib + $(CC) $(CFLAGS) /B"/STACK:65536" /Fecordtest cord\tests\cordtest.c gc.lib cord.lib + +clean: + erase gc.lib cord.lib + erase gctest.exe cordtest.exe + erase $(OBJS) $(CORDOBJS)
View file
_service:tar_scm:gc-8.0.6.tar.gz/README.QUICK -> _service:tar_scm:gc-8.2.2.tar.gz/README.QUICK
Changed
@@ -2,7 +2,7 @@ Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. Copyright (c) 1999-2001 by Hewlett-Packard. All rights reserved. -Copyright (c) 2009-2019 Ivan Maidanski +Copyright (c) 2009-2021 Ivan Maidanski THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -36,7 +36,7 @@ See doc/README.autoconf for details Under Windows 95, 98, Me, NT, or 2000: -copy the appropriate makefile to MAKEFILE, read it, and type "nmake test". +copy the appropriate makefile to MAKEFILE, read it, and type "nmake check". (Under Windows, this assumes you have Microsoft command-line tools installed, and suitably configured.) Read the machine specific README.XXX in the doc directory if one exists. @@ -52,10 +52,11 @@ package should still work.) See include/cord.h for the API. If you wish to use the collector from C++, type "make c++", or use ---enable-cplusplus with the configure script. With Makefile.direct, -these ones add further files to gc.a and to the include subdirectory. -With the alternate build process, this generates libgccpp. -See include/gc_cpp.h. +--enable-cplusplus with the configure script. With Makefile.direct, +"make c++" creates gccpp.a and gctba.a files (you should link with either +gccpp.a or gctba.a). With the alternate (preferred) build process, this +generates libgccpp.a and libgctba.a, and/or libgccpp.so and libgctba.so. +See include/gc_cpp.h and doc/gcinterface.md. TYPICAL USE: Include "gc.h" from the include subdirectory. Link against the @@ -75,10 +76,10 @@ with system malloc, since the collector usually does not scan memory allocated in this way. -Use with threads may be supported on your system, but requires the -collector to be built with thread support. See Makefile. The collector -does not guarantee to scan thread-local storage (e.g. of the kind -accessed with pthread_getspecific()). The collector does scan +Use with threads may be supported on your system, but requires the collector +to be built with thread support. See Makefile.am or Makefile.direct. +The collector does not guarantee to scan thread-local storage (e.g. of the +kind accessed with pthread_getspecific()). The collector does scan thread stacks though, so generally the best solution is to ensure that any pointers stored in thread-local storage are also stored on the thread's stack for the duration of their lifetime.
View file
_service:tar_scm:gc-8.0.6.tar.gz/README.md -> _service:tar_scm:gc-8.2.2.tar.gz/README.md
Changed
@@ -1,6 +1,6 @@ # Boehm-Demers-Weiser Garbage Collector -This is version 8.0.6 of a conservative garbage +This is version 8.2.2 of a conservative garbage collector for C and C++. @@ -55,7 +55,7 @@ by others. Notably, some of the run-time systems developed at Xerox PARC in the early 1980s conservatively scanned thread stacks to locate possible pointers (cf. Paul Rovner, "On Adding Garbage Collection and Runtime Types -to a Strongly-Typed Statically Checked, Concurrent Language" Xerox PARC +to a Strongly-Typed Statically Checked, Concurrent Language" Xerox PARC CSL 84-7). Doug McIlroy wrote a simpler fully conservative collector that was part of version 8 UNIX (tm), but appears to not have received widespread use. @@ -134,8 +134,8 @@ visible to the collector. Note that the garbage collector does not need to be informed of shared -read-only data. However if the shared library mechanism can introduce -discontiguous data areas that may contain pointers, then the collector does +read-only data. However, if the shared library mechanism can introduce +discontiguous data areas that may contain pointers then the collector does need to be informed. Signal processing for most signals may be deferred during collection, @@ -158,7 +158,7 @@ ## Installation and Portability -As distributed, the collector operates silently +The collector operates silently in the default configuration. In the event of problems, this can usually be changed by defining the `GC_PRINT_STATS` or `GC_PRINT_VERBOSE_STATS` environment variables. This will result in a few lines of descriptive output for each collection. @@ -176,9 +176,9 @@ and similar auto-generated files, thus the full procedure of autoconf-based build of `master` branch of the collector could look like: - git clone git://github.com/ivmai/bdwgc.git + git clone https://github.com/ivmai/bdwgc cd bdwgc - git clone git://github.com/ivmai/libatomic_ops.git + git clone https://github.com/ivmai/libatomic_ops ./autogen.sh ./configure make -j @@ -195,24 +195,18 @@ a somewhat superficial test of collector functionality. Failure is indicated by a core dump or a message to the effect that the collector is broken. Gctest takes about a second to two to run on reasonable 2007 vintage desktops. It may -use up to about 30MB of memory. (The multi-threaded version will use more. -64-bit versions may use more.) `make test` will also, as its last step, attempt -to build and test the "cord" string library.) +use up to about 30 MB of memory. (The multi-threaded version will use more. +64-bit versions may use more.) `make check` will also, as its last step, +attempt to build and test the "cord" string library.) Makefile.direct will generate a library gc.a which you should link against. -Typing "make cords" will add the cord library to gc.a. +Typing "make cords" will build the cord library (cord.a). The GNU style build process understands the usual targets. `make check` runs a number of tests. `make install` installs at least libgc, and libcord. Try `./configure --help` to see the configuration options. It is currently not possible to exercise all combinations of build options this way. -It is suggested that if you need to replace a piece of the collector -(e.g. GC_mark_rts.c) you simply list your version ahead of gc.a on the -ld command line, rather than replacing the one in gc.a. (This will -generate numerous warnings under some versions of AIX, but it still -works.) - All include files that need to be used by clients will be put in the include subdirectory. (Normally this is just gc.h. `make cords` adds "cord.h" and "ec.h".) @@ -220,8 +214,6 @@ The collector currently is designed to run essentially unmodified on machines that use a flat 32-bit or 64-bit address space. That includes the vast majority of Workstations and X86 (X >= 3) PCs. -(The list here was deleted because it was getting too long and constantly -out of date.) In a few cases (Amiga, OS/2, Win32, MacOS) a separate makefile or equivalent is supplied. Many of these have separate README.system @@ -234,14 +226,13 @@ of dyn_load.c. On other machines we recommend that you do one of the following: - 1) Add dynamic library support (and send us the code). - 2) Use static versions of the libraries. - 3) Arrange for dynamic libraries to use the standard malloc. - This is still dangerous if the library stores a pointer to a - garbage collected object. But nearly all standard interfaces - prohibit this, because they deal correctly with pointers - to stack allocated objects. (Strtok is an exception. Don't - use it.) + 1. Add dynamic library support (and send us the code). + 2. Use static versions of the libraries. + 3. Arrange for dynamic libraries to use the standard malloc. This is still + dangerous if the library stores a pointer to a garbage collected object. + But nearly all standard interfaces prohibit this, because they deal + correctly with pointers to stack allocated objects. (`strtok` is an + exception. Don't use it.) In all cases we assume that pointer alignment is consistent with that enforced by the standard C compilers. If you use a nonstandard compiler @@ -265,81 +256,69 @@ from nonstandard places (e.g. from dynamic library data areas on a machine on which the collector doesn't already understand them.) On some machines, it may be desirable to set `GC_stackbottom` to a good -approximation of the stack base. (This enhances code portability on -HP PA machines, since there is no good way for the collector to -compute this value.) Client code may include "gc.h", which defines -all of the following, plus many others. - - 1) `GC_malloc(nbytes)` - - Allocate an object of size nbytes. Unlike malloc, the object is - cleared before being returned to the user. `GC_malloc` will - invoke the garbage collector when it determines this to be appropriate. - GC_malloc may return 0 if it is unable to acquire sufficient - space from the operating system. This is the most probable - consequence of running out of space. Other possible consequences - are that a function call will fail due to lack of stack space, - or that the collector will fail in other ways because it cannot - maintain its internal data structures, or that a crucial system - process will fail and take down the machine. Most of these - possibilities are independent of the malloc implementation. - - 2) `GC_malloc_atomic(nbytes)` - - Allocate an object of size nbytes that is guaranteed not to contain any - pointers. The returned object is not guaranteed to be cleared. - (Can always be replaced by `GC_malloc`, but results in faster collection - times. The collector will probably run faster if large character - arrays, etc. are allocated with `GC_malloc_atomic` than if they are - statically allocated.) - - 3) `GC_realloc(object, new_size)` - - Change the size of object to be `new_size`. Returns a pointer to the - new object, which may, or may not, be the same as the pointer to - the old object. The new object is taken to be atomic if and only if the - old one was. If the new object is composite and larger than the original - object,then the newly added bytes are cleared (we hope). This is very - likely to allocate a new object, unless `MERGE_SIZES` is defined in - gc_priv.h. Even then, it is likely to recycle the old object only if the - object is grown in small additive increments (which, we claim, is - generally bad coding practice.) - - 4) `GC_free(object)` - - Explicitly deallocate an object returned by `GC_malloc` or - `GC_malloc_atomic`. Not necessary, but can be used to minimize - collections if performance is critical. Probably a performance - loss for very small objects (<= 8 bytes). - - 5) `GC_expand_hp(bytes)` - - Explicitly increase the heap size. (This is normally done automatically - if a garbage collection failed to `GC_reclaim` enough memory. Explicit - calls to `GC_expand_hp` may prevent unnecessarily frequent collections at - program startup.) - - 6) `GC_malloc_ignore_off_page(bytes)` - - Identical to `GC_malloc`, but the client promises to keep a pointer to - the somewhere within the first 256 bytes of the object while it is - live. (This pointer should normally be declared volatile to prevent - interference from compiler optimizations.) This is the recommended - way to allocate anything that is likely to be larger than 100 Kbytes - or so. (`GC_malloc` may result in failure to reclaim such objects.) - - 7) `GC_set_warn_proc(proc)` - - Can be used to redirect warnings from the collector. Such warnings - should be rare, and should not be ignored during code development. - - 8) `GC_enable_incremental()` - - Enables generational and incremental collection. Useful for large - heaps on machines that provide access to page dirty information. - Some dirty bit implementations may interfere with debugging - (by catching address faults) and place restrictions on heap arguments - to system calls (since write faults inside a system call may not be - handled well). - - 9) Several routines to allow for registration of finalization code. - User supplied finalization code may be invoked when an object becomes - unreachable. To call `(*f)(obj, x)` when obj becomes inaccessible, use - `GC_register_finalizer(obj, f, x, 0, 0);` - For more sophisticated uses, and for finalization ordering issues, - see gc.h. +approximation of the stack base (bottom). + +Client code may include "gc.h", which defines all of the following, plus many +others. + + 1. `GC_malloc(bytes)` - Allocate an object of a given size. Unlike malloc, + the object is cleared before being returned to the user. `GC_malloc` will + invoke the garbage collector when it determines this to be appropriate. + GC_malloc may return 0 if it is unable to acquire sufficient space from the + operating system. This is the most probable consequence of running out + of space. Other possible consequences are that a function call will fail + due to lack of stack space, or that the collector will fail in other ways + because it cannot maintain its internal data structures, or that a crucial + system process will fail and take down the machine. Most of these + possibilities are independent of the malloc implementation. + + 2. `GC_malloc_atomic(bytes)` - Allocate an object of a given size that + is guaranteed not to contain any pointers. The returned object is not + guaranteed to be cleared. (Can always be replaced by `GC_malloc`, but + results in faster collection times. The collector will probably run faster + if large character arrays, etc. are allocated with `GC_malloc_atomic` than + if they are statically allocated.) + + 3. `GC_realloc(object, new_bytes)` - Change the size of object to be of + a given size. Returns a pointer to the new object, which may, or may not, + be the same as the pointer to the old object. The new object is taken to + be atomic if and only if the old one was. If the new object is composite + and larger than the original object then the newly added bytes are cleared. + This is very likely to allocate a new object. + + 4. `GC_free(object)` - Explicitly deallocate an object returned by + `GC_malloc` or `GC_malloc_atomic`, or friends. Not necessary, but can be + used to minimize collections if performance is critical. Probably + a performance loss for very small objects (<= 8 bytes). + + 5. `GC_expand_hp(bytes)` - Explicitly increase the heap size. (This is + normally done automatically if a garbage collection failed to reclaim + enough memory. Explicit calls to `GC_expand_hp` may prevent unnecessarily + frequent collections at program startup.) + + 6. `GC_malloc_ignore_off_page(bytes)` - Identical to `GC_malloc`, but the + client promises to keep a pointer to the somewhere within the first 256 + bytes of the object while it is live. (This pointer should normally be + declared volatile to prevent interference from compiler optimizations.) + This is the recommended way to allocate anything that is likely to be + larger than 100 KB or so. (`GC_malloc` may result in a failure to reclaim + such objects.) + + 7. `GC_set_warn_proc(proc)` - Can be used to redirect warnings from the + collector. Such warnings should be rare, and should not be ignored during + code development. + + 8. `GC_enable_incremental()` - Enables generational and incremental + collection. Useful for large heaps on machines that provide access to page + dirty information. Some dirty bit implementations may interfere with + debugging (by catching address faults) and place restrictions on heap + arguments to system calls (since write faults inside a system call may not + be handled well). + + 9. `GC_register_finalizer(object, proc, data, 0, 0)` and friends - Allow for + registration of finalization code. User supplied finalization code + (`(*proc)(object, data)`) is invoked after object becomes unreachable. + For more sophisticated uses, and for finalization ordering issues, see gc.h. The global variable `GC_free_space_divisor` may be adjusted up from it default value of 3 to use less space and more collection time, or down for @@ -365,7 +344,7 @@ All externally visible names in the garbage collector start with `GC_`. To avoid name conflicts, client code should avoid this prefix, except when -accessing garbage collector routines or variables. +accessing garbage collector routines. There are provisions for allocation with explicit type information. This is rarely necessary. Details can be found in gc_typed.h. @@ -373,12 +352,12 @@ ## The C++ Interface to the Allocator -The Ellis-Hull C++ interface to the collector is included in -the collector distribution. If you intend to use this, type -`make c++` after the initial build of the collector is complete. -See gc_cpp.h for the definition of the interface. This interface -tries to approximate the Ellis-Detlefs C++ garbage collection -proposal without compiler changes. +The Ellis-Hull C++ interface to the collector is included in the collector +distribution. If you intend to use this, type +`./configure --enable-cplusplus; make` (or `make -f Makefile.direct c++`) +after the initial build of the collector is complete. See gc_cpp.h for the +definition of the interface. This interface tries to approximate the +Ellis-Detlefs C++ garbage collection proposal without compiler changes. Very often it will also be necessary to use gc_allocator.h and the allocator declared there to construct STL data structures. Otherwise @@ -391,26 +370,25 @@ The collector may be used to track down leaks in C programs that are intended to run with malloc/free (e.g. code with extreme real-time or portability constraints). To do so define `FIND_LEAK` in Makefile. -This will cause the collector to invoke the `report_leak` -routine defined near the top of reclaim.c whenever an inaccessible -object is found that has not been explicitly freed. Such objects will -also be automatically reclaimed. - -If all objects are allocated with `GC_DEBUG_MALLOC` (see next section), then -the default version of report_leak will report at least the source file and -line number at which the leaked object was allocated. This may sometimes be -sufficient. (On a few machines, it will also report a cryptic stack trace. -If this is not symbolic, it can sometimes be called into a symbolic stack -trace by invoking program "foo" with "tools/callprocs.sh foo". It is a short -shell script that invokes adb to expand program counter values to symbolic -addresses. It was largely supplied by Scott Schwartz.) +This will cause the collector to print a human-readable object description +whenever an inaccessible object is found that has not been explicitly freed. +Such objects will also be automatically reclaimed. + +If all objects are allocated with `GC_DEBUG_MALLOC` (see the next section) +then, by default, the human-readable object description will at least contain +the source file and the line number at which the leaked object was allocated. +This may sometimes be sufficient. (On a few machines, it will also report +a cryptic stack trace. If this is not symbolic, it can sometimes be called +into a symbolic stack trace by invoking program "foo" with +`tools/callprocs.sh foo`. It is a short shell script that invokes adb to +expand program counter values to symbolic addresses. It was largely supplied +by Scott Schwartz.) Note that the debugging facilities described in the next section can -sometimes be slightly LESS effective in leak finding mode, since in -leak finding mode, `GC_debug_free` actually results in reuse of the object. -(Otherwise the object is simply marked invalid.) Also note that the test -program is not designed to run meaningfully in `FIND_LEAK` mode. -Use "make gc.a" to build the collector. +sometimes be slightly LESS effective in leak finding mode, since in the latter +`GC_debug_free` actually results in reuse of the object. (Otherwise the +object is simply marked invalid.) Also, note that most GC tests are not +designed to run meaningfully in `FIND_LEAK` mode. ## Debugging Facilities @@ -430,8 +408,8 @@ deallocation of an object without debugging information. Out of memory errors will be reported to stderr, in addition to returning `NULL`. -`GC_debug_malloc` checking during garbage collection is enabled -with the first call to `GC_debug_malloc`. This will result in some +`GC_debug_malloc` checking during garbage collection is enabled +with the first call to this function. This will result in some slowdown during collections. If frequent heap checks are desired, this can be achieved by explicitly invoking `GC_gcollect`, e.g. from the debugger. @@ -444,18 +422,18 @@ having been overwritten. This should happen with probability at most one in 2**32. This probability is zero if `GC_debug_malloc` is never called. -`GC_debug_malloc`, `GC_malloc_atomic`, and `GC_debug_realloc` take two +`GC_debug_malloc`, `GC_debug_malloc_atomic`, and `GC_debug_realloc` take two additional trailing arguments, a string and an integer. These are not interpreted by the allocator. They are stored in the object (the string is not copied). If an error involving the object is detected, they are printed. -The macros `GC_MALLOC`, `GC_MALLOC_ATOMIC`, `GC_REALLOC`, `GC_FREE`, and -`GC_REGISTER_FINALIZER` are also provided. These require the same arguments -as the corresponding (nondebugging) routines. If gc.h is included +The macros `GC_MALLOC`, `GC_MALLOC_ATOMIC`, `GC_REALLOC`, `GC_FREE`, +`GC_REGISTER_FINALIZER` and friends are also provided. These require the same +arguments as the corresponding (nondebugging) routines. If gc.h is included with `GC_DEBUG` defined, they call the debugging versions of these functions, passing the current file name and line number as the two extra arguments, where appropriate. If gc.h is included without `GC_DEBUG` -defined, then all these macros will instead be defined to their nondebugging +defined then all these macros will instead be defined to their nondebugging equivalents. (`GC_REGISTER_FINALIZER` is necessary, since pointers to objects with debugging information are really pointers to a displacement of 16 bytes from the object beginning, and some translation is necessary @@ -481,21 +459,20 @@ or pages have been recently modified. The collector uses two sources of information: -1. Information provided by the VM system. This may be provided in - one of several forms. Under Solaris 2.X (and potentially under other - similar systems) information on dirty pages can be read from the - /proc file system. Under other systems (currently SunOS4.X) it is - possible to write-protect the heap, and catch the resulting faults. - On these systems we require that system calls writing to the heap - (other than read) be handled specially by client code. - See os_dep.c for details. + 1. Information provided by the VM system. This may be provided in one of + several forms. Under Solaris 2.X (and potentially under other similar + systems) information on dirty pages can be read from the /proc file system. + Under other systems (e.g. SunOS4.X) it is possible to write-protect + the heap, and catch the resulting faults. On these systems we require that + system calls writing to the heap (other than read) be handled specially by + client code. See `os_dep.c` for details. -2. Information supplied by the programmer. The object is considered dirty - after a call to `GC_end_stubborn_change` provided the library has been - compiled suitably. It is typically not worth using for short-lived objects. - Note that bugs caused by a missing `GC_end_stubborn_change` or - `GC_reachable_here` call are likely to be observed very infrequently and - hard to trace. + 2. Information supplied by the programmer. The object is considered dirty + after a call to `GC_end_stubborn_change` provided the library has been + compiled suitably. It is typically not worth using for short-lived objects. + Note that bugs caused by a missing `GC_end_stubborn_change` or + `GC_reachable_here` call are likely to be observed very infrequently and + hard to trace. ## Bugs @@ -514,7 +491,7 @@ They will decrease with the number of processors if parallel marking is enabled. -(On 2007 vintage machines, GC times may be on the order of 5 msecs +(On 2007 vintage machines, GC times may be on the order of 5 ms per MB of accessible memory that needs to be scanned and processed. Your mileage may vary.) The incremental/generational collection facility may help in some cases. @@ -551,7 +528,7 @@ * Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. * Copyright (c) 1999-2011 by Hewlett-Packard Development Company. - * Copyright (c) 2008-2019 Ivan Maidanski + * Copyright (c) 2008-2021 Ivan Maidanski The files pthread_stop_world.c, pthread_support.c and some others are also
View file
_service:tar_scm:gc-8.0.6.tar.gz/SMakefile.amiga -> _service:tar_scm:gc-8.2.2.tar.gz/SMakefile.amiga
Changed
@@ -49,39 +49,39 @@ #------------------LINKING---------------------------- -all: gctest setjmp_t cord/cordtest +all: gc.lib cord.lib clean: - delete *.lib gctest setjmp_t *.o *.lnk cord/*.o cord/*.lib cord/*.lnk cord/tests/*.o cord/cordtest + delete *.lib gctest setjmp_t *.o *.lnk cord/*.o cord/tests/*.o cordtest smake -test: setjmp_t gctest cord/cordtest +check: setjmp_t gctest cordtest setjmp_t gctest - cord/cordtest + cordtest -gctest: gc$(CPU).lib GCAmigaOS$(CPU).lib test.o - $(LINKER) LIB:c.o test.o TO gctest LIB gc$(CPU).lib LIB:sc.lib $(MATHLIB) +gctest: gc.lib GCAmigaOS$(CPU).lib test.o + $(LINKER) LIB:c.o test.o TO gctest LIB gc.lib LIB:sc.lib $(MATHLIB) setjmp_t: setjmp_t.o gc.h $(LINKER) LIB:c.o setjmp_t.o to setjmp_t lib LIB:sc.lib -cord/cordtest: cord/tests/cordtest.o cord/cord$(CPU).lib gc$(CPU).lib - slink LIB:c.o cord/tests/cordtest.o LIB $(MATHLIB) gc$(CPU).lib cord/cord$(CPU).lib LIB:sc.lib TO cord/cordtest +cordtest: cord/tests/cordtest.o cord.lib gc.lib + $(LINKER) LIB:c.o cord/tests/cordtest.o LIB $(MATHLIB) gc.lib cord.lib LIB:sc.lib TO cordtest #------------------LIBBING---------------------------- 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 dyn_load.o dbg_mlc.o malloc.o checksums.o typd_mlc.o ptr_chck.o mallocx.o fnlz_mlc.o -gc$(CPU).lib: $(OBJS) - $(LIBER) gc$(CPU).lib r $(OBJS) +gc.lib: $(OBJS) + $(LIBER) gc.lib r $(OBJS) COBJS = cord/cordbscs.o cord/cordprnt.o cord/cordxtra.o -cord/cord$(CPU).lib: $(COBJS) - oml cord/cord$(CPU).lib r $(COBJS) +cord.lib: $(COBJS) + $(LIBER) cord.lib r $(COBJS) #------------------COMPILING-------------------------- @@ -160,13 +160,13 @@ # cords: cord/cordbscs.o: cord/cordbscs.c - sc cord/cordbscs.c $(CSCOPT) + $(CC) cord/cordbscs.c $(CSCOPT) cord/cordprnt.o: cord/cordprnt.c - sc cord/cordprnt.c $(CSCOPT) + $(CC) cord/cordprnt.c $(CSCOPT) cord/cordxtra.o: cord/cordxtra.c - sc cord/cordxtra.c $(CSCOPT) + $(CC) cord/cordxtra.c $(CSCOPT) cord/tests/cordtest.o: cord/tests/cordtest.c - sc cord/tests/cordtest.c $(CSCOPT) + $(CC) cord/tests/cordtest.c $(CSCOPT)
View file
_service:tar_scm:gc-8.0.6.tar.gz/WCC_MAKEFILE -> _service:tar_scm:gc-8.2.2.tar.gz/WCC_MAKEFILE
Changed
@@ -6,10 +6,9 @@ #SYSTEM=DOS4GW #SYSTEM=OS2 -# The collector can be built either as dynamic or as static library. -# Select the library type you need. -#MAKE_AS_DLL=1 -MAKE_AS_LIB=1 +# The collector can be built either as dynamic (the default) or as static +# library. The latter is selected by setting ENABLE_STATIC variable. +#ENABLE_STATIC=1 # Select calling conventions. # Possible choices are r and s. @@ -54,14 +53,19 @@ !else !error undefined or unsupported target platform: $(SYSTEM) !endif -!ifdef MAKE_AS_DLL -DLLFLAG=-bd -DGC_DLL -TEST_DLLFLAG=-DGC_DLL -!else ifdef MAKE_AS_LIB + +!ifdef ENABLE_STATIC DLLFLAG= -TEST_DLLFLAG= +TEST_DLLFLAG=-DGC_NOT_DLL +CORDFLAG= !else -!error Either MAKE_AS_LIB or MAKE_AS_DLL should be defined +DLLFLAG=-bd -DGC_DLL +TEST_DLLFLAG=-DGC_DLL +# cord.dll and its clients should not link C library statically otherwise +# FILE-related functions might not work (because own set of opened FILEs +# is maintained by each copy of the C library thus making impossible to pass +# FILE pointer from, e.g., .exe code to .dll one). +CORDFLAG=-br !endif CC=wcc386 @@ -72,20 +76,54 @@ TEST_CFLAGS=-$(CPU)$(CALLING) $(OPTIM) -iinclude -zp4 -zc $(SYSFLAG) $(TEST_DLLFLAG) $(DEFS) TEST_CXXFLAGS= $(TEST_CFLAGS) -xs +COBJS= cordbscs.obj cordxtra.obj cordprnt.obj + +all: gc.lib gccpp.lib gctba.lib cord.lib + +check: gctest.exe test_cpp.exe cordtest.exe .SYMBOLIC + *gctest.exe + *test_cpp.exe + *cordtest.exe + +!ifdef ENABLE_STATIC + OBJS= alloc.obj reclaim.obj allchblk.obj misc.obj & mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj & obj_map.obj blacklst.obj finalize.obj new_hblk.obj & dbg_mlc.obj malloc.obj dyn_load.obj & typd_mlc.obj ptr_chck.obj mallocx.obj fnlz_mlc.obj gcj_mlc.obj -all: gc.lib gctest.exe test_cpp.exe +gc.lib: $(OBJS) + @%create $*.lb1 + @for %i in ($(OBJS)) do @%append $*.lb1 +'%i' + *wlib -b -c -n -p=512 $@ @$*.lb1 -!ifdef MAKE_AS_DLL +cord.lib: $(COBJS) + @%create $*.lb1 + @for %i in ($(COBJS)) do @%append $*.lb1 +'%i' + *wlib -b -c -n -p=512 $@ @$*.lb1 + +gccpp.lib: gc_badalc.obj gc_cpp.obj + @%create $*.lb1 + @%append $*.lb1 +'gc_badalc.obj' + @%append $*.lb1 +'gc_cpp.obj' + *wlib -b -c -n -p=512 $@ @$*.lb1 + +# The same as gccpp.lib but contains only gc_badalc.obj. +gctba.lib: gc_badalc.obj + @%create $*.lb1 + @%append $*.lb1 +'gc_badalc.obj' + *wlib -b -c -n -p=512 $@ @$*.lb1 + +!else -gc.lib: gc.dll gc_cpp.obj - *wlib -b -c -n -p=512 $@ +gc.dll +gc_cpp.obj +gc.obj: extra\gc.c .AUTODEPEND + $(CC) $(CFLAGS) extra\gc.c -gc.dll: $(OBJS) .AUTODEPEND +gc.lib: gc.dll + *wlib -b -c -n -p=512 $@ +gc.dll + +gc.dll: gc.obj .AUTODEPEND @%create $*.lnk !ifdef DOS4GW @%append $*.lnk sys os2v2_dll @@ -94,18 +132,69 @@ !else ifdef OS2 @%append $*.lnk sys os2v2_dll !endif + @%append $*.lnk op case @%append $*.lnk name $* - @for %i in ($(OBJS)) do @%append $*.lnk file '%i' + @%append $*.lnk file 'gc.obj' *wlink @$*.lnk -!else -gc.lib: $(OBJS) gc_cpp.obj - @%create $*.lb1 - @for %i in ($(OBJS)) do @%append $*.lb1 +'%i' - @%append $*.lb1 +'gc_cpp.obj' - *wlib -b -c -n -p=512 $@ @$*.lb1 +cord.lib: cord.dll + *wlib -b -c -n -p=512 $@ +cord.dll + +cord.dll: $(COBJS) gc.lib .AUTODEPEND + @%create $*.lnk +!ifdef DOS4GW + @%append $*.lnk sys os2v2_dll +!else ifdef MSWIN32 + @%append $*.lnk sys nt_dll +!else ifdef OS2 + @%append $*.lnk sys os2v2_dll !endif + @%append $*.lnk op case + @%append $*.lnk name $* + @for %i in ($(COBJS)) do @%append $*.lnk file '%i' + @%append $*.lnk library gc.lib + *wlink @$*.lnk +gccpp.lib: gccpp.dll + *wlib -b -c -n -p=512 $@ +gccpp.dll + +gccpp.dll: gc_badalc.obj gc_cpp.obj gc.lib .AUTODEPEND + @%create $*.lnk +!ifdef DOS4GW + @%append $*.lnk sys os2v2_dll +!else ifdef MSWIN32 + @%append $*.lnk sys nt_dll +!else ifdef OS2 + @%append $*.lnk sys os2v2_dll +!endif + @%append $*.lnk op case + @%append $*.lnk name $* + @%append $*.lnk file 'gc_badalc.obj' + @%append $*.lnk file 'gc_cpp.obj' + @%append $*.lnk library gc.lib + @%append $*.lnk library wr7$(CALLING)dll.lib + *wlink @$*.lnk + +gctba.lib: gctba.dll + *wlib -b -c -n -p=512 $@ +gctba.dll + +gctba.dll: gc_badalc.obj gc.lib .AUTODEPEND + @%create $*.lnk +!ifdef DOS4GW + @%append $*.lnk sys os2v2_dll +!else ifdef MSWIN32 + @%append $*.lnk sys nt_dll +!else ifdef OS2 + @%append $*.lnk sys os2v2_dll +!endif + @%append $*.lnk op case + @%append $*.lnk name $* + @%append $*.lnk file 'gc_badalc.obj' + @%append $*.lnk library gc.lib + @%append $*.lnk library wr7$(CALLING)dll.lib + *wlink @$*.lnk + +!endif gctest.exe: test.obj gc.lib %create $*.lnk @@ -122,7 +211,25 @@ @%append $*.lnk file test.obj @%append $*.lnk library gc.lib *wlink @$*.lnk -test_cpp.exe: test_cpp.obj gc.lib + +cordtest.exe: cordtest.obj gc.lib cord.lib + %create $*.lnk +!ifdef DOS4GW + @%append $*.lnk sys dos4g +!else ifdef MSWIN32 + @%append $*.lnk sys nt +!else ifdef OS2 + @%append $*.lnk sys os2v2 +!endif + @%append $*.lnk op case + @%append $*.lnk op stack=256K + @%append $*.lnk name $* + @%append $*.lnk file cordtest.obj + @%append $*.lnk library gc.lib + @%append $*.lnk library cord.lib + *wlink @$*.lnk + +test_cpp.exe: test_cpp.obj gc.lib gccpp.lib %create $*.lnk !ifdef DOS4GW @%append $*.lnk sys dos4g @@ -136,12 +243,25 @@ @%append $*.lnk name $* @%append $*.lnk file test_cpp.obj @%append $*.lnk library gc.lib + @%append $*.lnk library gccpp.lib *wlink @$*.lnk +cordbscs.obj: cord\cordbscs.c .AUTODEPEND + $(CC) $(CFLAGS) $(CORDFLAG) cord\cordbscs.c +cordxtra.obj: cord\cordxtra.c .AUTODEPEND + $(CC) $(CFLAGS) $(CORDFLAG) cord\cordxtra.c +cordprnt.obj: cord\cordprnt.c .AUTODEPEND + $(CC) $(CFLAGS) $(CORDFLAG) cord\cordprnt.c + +gc_badalc.obj: gc_badalc.cc .AUTODEPEND + $(CXX) $(TEST_CXXFLAGS) $*.cc gc_cpp.obj: gc_cpp.cc .AUTODEPEND $(CXX) $(TEST_CXXFLAGS) $*.cc + test.obj: tests\test.c .AUTODEPEND - $(CC) $(TEST_CFLAGS) tests\test.c + $(CC) $(TEST_CFLAGS) /wcd=13 /wcd=201 /wcd=367 /wcd=368 tests\test.c +cordtest.obj: cord\tests\cordtest.c .AUTODEPEND + $(CC) $(TEST_CFLAGS) $(CORDFLAG) cord\tests\cordtest.c test_cpp.obj: tests\test_cpp.cc .AUTODEPEND $(CXX) $(TEST_CXXFLAGS) tests\test_cpp.cc @@ -151,7 +271,7 @@ .cc.obj: .AUTODEPEND $(CXX) $(CXXFLAGS) $*.cc -clean : .SYMBOLIC +clean: .SYMBOLIC @if exist *.obj del *.obj @if exist *.map del *.map @if exist *.lnk del *.lnk
View file
_service:tar_scm:gc-8.0.6.tar.gz/aclocal.m4 -> _service:tar_scm:gc-8.2.2.tar.gz/aclocal.m4
Changed
@@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.)) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN(AM_AUTOMAKE_VERSION, -am__api_version='1.15' +am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if($1, 1.15, , +m4_if($1, 1.16.5, , AC_FATAL(Do not call $0, use AM_INIT_AUTOMAKE($1).))dnl ) @@ -51,14 +51,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN(AM_SET_CURRENT_AUTOMAKE_VERSION, -AM_AUTOMAKE_VERSION(1.15)dnl +AM_AUTOMAKE_VERSION(1.16.5)dnl m4_ifndef(AC_AUTOCONF_VERSION, m4_copy(m4_PACKAGE_VERSION, AC_AUTOCONF_VERSION))dnl _AM_AUTOCONF_VERSION(m4_defn(AC_AUTOCONF_VERSION))) # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -78,7 +78,7 @@ # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -130,7 +130,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -161,7 +161,7 @@ Usually this means the macro was only invoked conditionally.) fi)) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -352,13 +352,12 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN(_AM_OUTPUT_DEPENDENCY_COMMANDS, @@ -366,49 +365,43 @@ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE($CONFIG_FILES, + *\'*, eval set x "$CONFIG_FILES", + *, set x $CONFIG_FILES) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO("$am_mf") | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME("$file")` - AS_MKDIR_P($dirpart/$fdir) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME("$am_mf")` + am_filepart=`AS_BASENAME("$am_mf")` + AM_RUN_LOG(cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE(Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).) + fi + AS_UNSET(am_dirpart) + AS_UNSET(am_filepart) + AS_UNSET(am_mf) + AS_UNSET(am_rc) + rm -f conftest-deps.mk } )# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -417,18 +410,17 @@ # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN(AM_OUTPUT_DEPENDENCY_COMMANDS, AC_CONFIG_COMMANDS(depfiles, test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS, - AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir") -) + AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}")) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -456,6 +448,10 @@ # release and drop the old call support. AC_DEFUN(AM_INIT_AUTOMAKE, AC_PREREQ(2.65)dnl +m4_ifdef(_$0_ALREADY_INIT, + m4_fatal($0 expanded multiple times +m4_defn(_$0_ALREADY_INIT)), + m4_define(_$0_ALREADY_INIT, m4_expansion_stack))dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow(^AM_A-Z+FLAGS$)dnl @@ -492,7 +488,7 @@ _AM_SET_OPTIONS($1)dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( - m4_ifdef(AC_PACKAGE_NAME, ok):m4_ifdef(AC_PACKAGE_VERSION, ok), + m4_ifset(AC_PACKAGE_NAME, ok):m4_ifset(AC_PACKAGE_VERSION, ok), ok:ok,, m4_fatal(AC_INIT should be called with package and version arguments))dnl AC_SUBST(PACKAGE, 'AC_PACKAGE_TARNAME')dnl @@ -515,8 +511,8 @@ AC_REQUIRE(AC_PROG_MKDIR_P)dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> AC_SUBST(mkdir_p, '$(MKDIR_P)') # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -544,6 +540,20 @@ m4_define(AC_PROG_OBJCXX, m4_defn(AC_PROG_OBJCXX)_AM_DEPENDENCIES(OBJCXX)))dnl ) +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi +AC_SUBST(CTAGS) +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST(ETAGS) +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi +AC_SUBST(CSCOPE) + AC_REQUIRE(AM_SILENT_RULES)dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This @@ -583,7 +593,7 @@ Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. +that behaves properly: <https://www.gnu.org/software/coreutils/>. If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -625,7 +635,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME("$_am_arg")`/stamp-h$_am_stamp_count) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -646,7 +656,7 @@ fi AC_SUBST(install_sh)) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -668,7 +678,7 @@ # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -703,7 +713,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -711,49 +721,42 @@ # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN(AM_MAKE_INCLUDE, -am_make=${MAKE-make} -cat > confinc << 'END' +AC_MSG_CHECKING(whether ${MAKE-make} supports the include directive) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING(for style of include used by $am_make) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST(am__include) -AC_SUBST(am__quote) -AC_MSG_RESULT($_am_result) -rm -f confinc confmf -) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG(${MAKE-make} -f confmf.$s && cat confinc.out) + AS_CASE($?:`cat confinc.out 2>/dev/null`, + '0:this is the am__doit target', + AS_CASE($s, + BSD, am__include='.include' am__quote='"', + am__include='include' am__quote='')) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT(${_am_result}) +AC_SUBST(am__include)) +AC_SUBST(am__quote)) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -774,12 +777,7 @@ AC_REQUIRE(AM_AUX_DIR_EXPAND)dnl AC_REQUIRE_AUX_FILE(missing)dnl if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -792,7 +790,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -821,7 +819,7 @@ AC_DEFUN(_AM_IF_OPTION, m4_ifset(_AM_MANGLE_OPTION($1), $2, $3)) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -868,7 +866,7 @@ # For backward compatibility. AC_DEFUN_ONCE(AM_PROG_CC_C_O, AC_REQUIRE(AC_PROG_CC)) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -887,7 +885,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -968,7 +966,7 @@ rm -f conftest.file ) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1028,7 +1026,7 @@ _AM_SUBST_NOTMAKE(AM_BACKSLASH)dnl ) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1056,7 +1054,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST(INSTALL_STRIP_PROGRAM)) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1075,7 +1073,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it,
View file
_service:tar_scm:gc-8.0.6.tar.gz/allchblk.c -> _service:tar_scm:gc-8.2.2.tar.gz/allchblk.c
Changed
@@ -130,7 +130,7 @@ if (0 != h) GC_printf("Free list %u (total size %lu):\n", i, (unsigned long)GC_free_bytesi); - while (h != 0) { + while (h /* != NULL */) { /* CPPCHECK */ hdr * hhdr = HDR(h); GC_printf("\t%p size %lu %s black listed\n", @@ -389,7 +389,7 @@ GC_ASSERT(GC_free_bytesindex <= GC_large_free_bytes); hhdr -> hb_next = second; hhdr -> hb_prev = 0; - if (0 != second) { + if (second /* != NULL */) { /* CPPCHECK */ hdr * second_hdr; GET_HDR(second, second_hdr); @@ -460,8 +460,8 @@ # endif } -/* Unmap blocks that haven't been recently touched. This is the only way */ -/* way blocks are ever unmapped. */ +/* Unmap blocks that haven't been recently touched. This is the only */ +/* way blocks are ever unmapped. */ GC_INNER void GC_unmap_old(void) { int i; @@ -507,24 +507,6 @@ } } -# ifdef MPROTECT_VDB - GC_INNER GC_bool GC_has_unmapped_memory(void) - { - int i; - - for (i = 0; i <= N_HBLK_FLS; ++i) { - struct hblk * h; - hdr * hhdr; - - for (h = GC_hblkfreelisti; h != NULL; h = hhdr -> hb_next) { - hhdr = HDR(h); - if (!IS_MAPPED(hhdr)) return TRUE; - } - } - return FALSE; - } -# endif /* MPROTECT_VDB */ - /* Merge all unmapped blocks that are adjacent to other free */ /* blocks. This may involve remapping, since all blocks are either */ /* fully mapped or fully unmapped. */ @@ -587,7 +569,7 @@ GC_add_to_fl(h, hhdr); /* Start over at beginning of list */ h = GC_hblkfreelisti; - } else /* not mergable with successor */ { + } else /* not mergeable with successor */ { h = hhdr -> hb_next; } } /* while (h != 0) ... */ @@ -659,12 +641,12 @@ nhdr -> hb_next = next; nhdr -> hb_sz = total_size - h_size; nhdr -> hb_flags = 0; - if (0 != prev) { + if (prev /* != NULL */) { /* CPPCHECK */ HDR(prev) -> hb_next = n; } else { GC_hblkfreelistindex = n; } - if (0 != next) { + if (next /* != NULL */) { HDR(next) -> hb_prev = n; } GC_ASSERT(GC_free_bytesindex > h_size); @@ -701,6 +683,7 @@ int split_limit; /* Highest index of free list whose blocks we */ /* split. */ + GC_ASSERT(I_HOLD_LOCK()); GC_ASSERT((sz & (GRANULE_BYTES - 1)) == 0); blocks = OBJ_SZ_TO_BLOCKS_CHECKED(sz); if ((signed_word)(blocks * HBLKSIZE) < 0) { @@ -769,7 +752,11 @@ for (hbp = GC_hblkfreelistn;; hbp = hhdr -> hb_next) { signed_word size_avail; /* bytes available in this block */ - if (NULL == hbp) return NULL; + if (hbp /* != NULL */) { + /* CPPCHECK */ + } else { + return NULL; + } GET_HDR(hbp, hhdr); /* set hhdr value */ size_avail = (signed_word)hhdr->hb_sz; if (size_avail < size_needed) continue; @@ -779,7 +766,7 @@ /* This prevents us from disassembling a single large */ /* block to get tiny blocks. */ thishbp = hhdr -> hb_next; - if (thishbp != 0) { + if (thishbp /* != NULL */) { /* CPPCHECK */ signed_word next_size; GET_HDR(thishbp, thishdr); @@ -952,7 +939,7 @@ GET_HDR(hbp, hhdr); size = HBLKSIZE * OBJ_SZ_TO_BLOCKS(hhdr->hb_sz); - if ((signed_word)size <= 0) + if ((size & SIGNB) != 0) ABORT("Deallocating excessively large block. Too large an allocation?"); /* Probably possible if we try to allocate more than half the address */ /* space at once. If we don't catch it here, strange things happen */ @@ -983,7 +970,7 @@ GC_remove_header(next); } /* Coalesce with predecessor, if possible. */ - if (0 != prev) { + if (prev /* != NULL */) { /* CPPCHECK */ prevhdr = HDR(prev); if (IS_MAPPED(prevhdr) && (signed_word)(hhdr -> hb_sz + prevhdr -> hb_sz) > 0) {
View file
_service:tar_scm:gc-8.0.6.tar.gz/alloc.c -> _service:tar_scm:gc-8.2.2.tar.gz/alloc.c
Changed
@@ -3,7 +3,7 @@ * Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. * Copyright (c) 1998 by Silicon Graphics. All rights reserved. * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P. - * Copyright (c) 2008-2019 Ivan Maidanski + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -21,7 +21,7 @@ #include <stdio.h> #if !defined(MACOS) && !defined(MSWINCE) # include <signal.h> -# if !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) \ +# if !defined(GC_NO_TYPES) && !defined(SN_TARGET_PSP2) \ && !defined(__CC_ARM) # include <sys/types.h> # endif @@ -69,7 +69,8 @@ word GC_gc_no = 0; #ifndef NO_CLOCK - static unsigned long full_gc_total_time = 0; /* in msecs, may wrap */ + static unsigned long full_gc_total_time = 0; /* in ms, may wrap */ + static unsigned full_gc_total_ns_frac = 0; /* fraction of 1 ms */ static GC_bool measure_performance = FALSE; /* Do performance measurements if set to true (e.g., */ /* accumulation of the total time of full collections). */ @@ -87,6 +88,7 @@ #ifndef GC_DISABLE_INCREMENTAL GC_INNER GC_bool GC_incremental = FALSE; /* By default, stop the world. */ + STATIC GC_bool GC_should_start_incremental_collection = FALSE; #endif GC_API int GC_CALL GC_is_incremental_mode(void) @@ -107,12 +109,34 @@ #endif STATIC GC_bool GC_need_full_gc = FALSE; - /* Need full GC do to heap growth. */ + /* Need full GC due to heap growth. */ #ifdef THREAD_LOCAL_ALLOC GC_INNER GC_bool GC_world_stopped = FALSE; #endif +STATIC GC_bool GC_disable_automatic_collection = FALSE; + +GC_API void GC_CALL GC_set_disable_automatic_collection(int value) +{ + DCL_LOCK_STATE; + + LOCK(); + GC_disable_automatic_collection = (GC_bool)value; + UNLOCK(); +} + +GC_API int GC_CALL GC_get_disable_automatic_collection(void) +{ + int value; + DCL_LOCK_STATE; + + LOCK(); + value = (int)GC_disable_automatic_collection; + UNLOCK(); + return value; +} + STATIC word GC_used_heap_size_after_full = 0; /* GC_copyright symbol is externally visible. */ @@ -124,7 +148,7 @@ "Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. ", "Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. ", "Copyright (c) 1999-2009 by Hewlett-Packard Company. All rights reserved. ", -"Copyright (c) 2008-2019 Ivan Maidanski ", +"Copyright (c) 2008-2021 Ivan Maidanski ", "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." }; @@ -168,15 +192,44 @@ unsigned long GC_time_limit = GC_TIME_LIMIT; /* We try to keep pause times from exceeding */ /* this by much. In milliseconds. */ +#elif defined(PARALLEL_MARK) + unsigned long GC_time_limit = GC_TIME_UNLIMITED; + /* The parallel marker cannot be interrupted for */ + /* now, so the time limit is absent by default. */ #else unsigned long GC_time_limit = 50; #endif #ifndef NO_CLOCK + STATIC unsigned long GC_time_lim_nsec = 0; + /* The nanoseconds add-on to GC_time_limit */ + /* value. Not updated by GC_set_time_limit(). */ + /* Ignored if the value of GC_time_limit is */ + /* GC_TIME_UNLIMITED. */ + +# define TV_NSEC_LIMIT (1000UL * 1000) /* amount of nanoseconds in 1 ms */ + + GC_API void GC_CALL GC_set_time_limit_tv(struct GC_timeval_s tv) + { + GC_ASSERT(tv.tv_ms <= GC_TIME_UNLIMITED); + GC_ASSERT(tv.tv_nsec < TV_NSEC_LIMIT); + GC_time_limit = tv.tv_ms; + GC_time_lim_nsec = tv.tv_nsec; + } + + GC_API struct GC_timeval_s GC_CALL GC_get_time_limit_tv(void) + { + struct GC_timeval_s tv; + + tv.tv_ms = GC_time_limit; + tv.tv_nsec = GC_time_lim_nsec; + return tv; + } + STATIC CLOCK_TYPE GC_start_time = CLOCK_TYPE_INITIALIZER; /* Time at which we stopped world. */ /* used only in GC_timeout_stop_func. */ -#endif +#endif /* !NO_CLOCK */ STATIC int GC_n_attempts = 0; /* Number of attempts at finishing */ /* collection within GC_time_limit. */ @@ -210,7 +263,7 @@ { CLOCK_TYPE current_time; static unsigned count = 0; - unsigned long time_diff; + unsigned long time_diff, nsec_diff; if ((*GC_default_stop_func)()) return(1); @@ -218,11 +271,16 @@ if ((count++ & 3) != 0) return(0); GET_TIME(current_time); time_diff = MS_TIME_DIFF(current_time,GC_start_time); - if (time_diff >= GC_time_limit) { - GC_COND_LOG_PRINTF( - "Abandoning stopped marking after %lu msecs (attempt %d)\n", - time_diff, GC_n_attempts); - return(1); + nsec_diff = NS_FRAC_TIME_DIFF(current_time, GC_start_time); +# if defined(CPPCHECK) + GC_noop1((word)&nsec_diff); +# endif + if (time_diff >= GC_time_limit + && (time_diff > GC_time_limit || nsec_diff >= GC_time_lim_nsec)) { + GC_COND_LOG_PRINTF("Abandoning stopped marking after %lu ms %lu ns" + " (attempt %d)\n", + time_diff, nsec_diff, GC_n_attempts); + return 1; } return(0); } @@ -351,15 +409,40 @@ /* limits used by blacklisting. */ STATIC word GC_collect_at_heapsize = GC_WORD_MAX; +GC_API void GC_CALL GC_start_incremental_collection(void) +{ +# ifndef GC_DISABLE_INCREMENTAL + DCL_LOCK_STATE; + + if (!GC_incremental) return; + LOCK(); + GC_should_start_incremental_collection = TRUE; + ENTER_GC(); + GC_collect_a_little_inner(1); + EXIT_GC(); + UNLOCK(); +# endif +} + /* Have we allocated enough to amortize a collection? */ GC_INNER GC_bool GC_should_collect(void) { static word last_min_bytes_allocd; static word last_gc_no; + + GC_ASSERT(I_HOLD_LOCK()); if (last_gc_no != GC_gc_no) { - last_gc_no = GC_gc_no; last_min_bytes_allocd = min_bytes_allocd(); + last_gc_no = GC_gc_no; + } +# ifndef GC_DISABLE_INCREMENTAL + if (GC_should_start_incremental_collection) { + GC_should_start_incremental_collection = FALSE; + return TRUE; } +# endif + if (GC_disable_automatic_collection) return FALSE; + return(GC_adj_bytes_allocd() >= last_min_bytes_allocd || GC_heapsize >= GC_collect_at_heapsize); } @@ -503,7 +586,9 @@ /* TODO: Notify GC_EVENT_ABANDON */ return(FALSE); } + ENTER_GC(); GC_collect_a_little_inner(1); + EXIT_GC(); } } GC_notify_full_gc(); @@ -554,14 +639,23 @@ # ifndef NO_CLOCK if (start_time_valid) { CLOCK_TYPE current_time; - unsigned long time_diff; + unsigned long time_diff, ns_frac_diff; GET_TIME(current_time); time_diff = MS_TIME_DIFF(current_time, start_time); - if (measure_performance) + ns_frac_diff = NS_FRAC_TIME_DIFF(current_time, start_time); + if (measure_performance) { full_gc_total_time += time_diff; /* may wrap */ + full_gc_total_ns_frac += (unsigned)ns_frac_diff; + if (full_gc_total_ns_frac >= 1000000U) { + /* Overflow of the nanoseconds part. */ + full_gc_total_ns_frac -= 1000000U; + full_gc_total_time++; + } + } if (GC_print_stats) - GC_log_printf("Complete collection took %lu msecs\n", time_diff); + GC_log_printf("Complete collection took %lu ms %lu ns\n", + time_diff, ns_frac_diff); } # endif if (GC_on_collection_event) @@ -569,28 +663,19 @@ return(TRUE); } -/* - * Perform n units of garbage collection work. A unit is intended to touch - * roughly GC_rate pages. Every once in a while, we do more than that. - * This needs to be a fairly large number with our current incremental - * GC strategy, since otherwise we allocate too much during GC, and the - * cleanup gets expensive. - */ +/* The number of extra calls to GC_mark_some that we have made. */ +STATIC int GC_deficit = 0; + +/* The default value of GC_rate. */ #ifndef GC_RATE # define GC_RATE 10 #endif -#ifndef MAX_PRIOR_ATTEMPTS -# define MAX_PRIOR_ATTEMPTS 1 -#endif - /* Maximum number of prior attempts at world stop marking */ - /* A value of 1 means that we finish the second time, no matter */ - /* how long it takes. Doesn't count the initial root scan */ - /* for a full GC. */ - -STATIC int GC_deficit = 0;/* The number of extra calls to GC_mark_some */ - /* that we have made. */ - +/* When GC_collect_a_little_inner() performs n units of GC work, a unit */ +/* is intended to touch roughly GC_rate pages. (But, every once in */ +/* a while, we do more than that.) This needs to be a fairly large */ +/* number with our current incremental GC strategy, since otherwise we */ +/* allocate too much during GC, and the cleanup gets expensive. */ STATIC int GC_rate = GC_RATE; GC_API void GC_CALL GC_set_rate(int value) @@ -604,6 +689,14 @@ return GC_rate; } +/* The default maximum number of prior attempts at world stop marking. */ +#ifndef MAX_PRIOR_ATTEMPTS +# define MAX_PRIOR_ATTEMPTS 1 +#endif + +/* The maximum number of prior attempts at world stop marking. */ +/* A value of 1 means that we finish the second time, no matter how */ +/* long it takes. Does not count the initial root scan for a full GC. */ static int max_prior_attempts = MAX_PRIOR_ATTEMPTS; GC_API void GC_CALL GC_set_max_prior_attempts(int value) @@ -629,32 +722,42 @@ int i; int max_deficit = GC_rate * n; +# ifdef PARALLEL_MARK + if (GC_time_limit != GC_TIME_UNLIMITED) + GC_parallel_mark_disabled = TRUE; +# endif for (i = GC_deficit; i < max_deficit; i++) { - if (GC_mark_some((ptr_t)0)) { - /* Need to finish a collection */ -# ifdef SAVE_CALL_CHAIN - GC_save_callers(GC_last_stack); -# endif -# ifdef PARALLEL_MARK - if (GC_parallel) - GC_wait_for_reclaim(); -# endif - if (GC_n_attempts < max_prior_attempts - && GC_time_limit != GC_TIME_UNLIMITED) { -# ifndef NO_CLOCK + if (GC_mark_some(NULL)) + break; + } +# ifdef PARALLEL_MARK + GC_parallel_mark_disabled = FALSE; +# endif + + if (i < max_deficit) { + /* Need to finish a collection. */ +# ifdef SAVE_CALL_CHAIN + GC_save_callers(GC_last_stack); +# endif +# ifdef PARALLEL_MARK + if (GC_parallel) + GC_wait_for_reclaim(); +# endif + if (GC_n_attempts < max_prior_attempts + && GC_time_limit != GC_TIME_UNLIMITED) { +# ifndef NO_CLOCK GET_TIME(GC_start_time); -# endif - if (!GC_stopped_mark(GC_timeout_stop_func)) { - GC_n_attempts++; - break; - } +# endif + if (GC_stopped_mark(GC_timeout_stop_func)) { + GC_finish_collection(); } else { - /* TODO: If possible, GC_default_stop_func should be */ - /* used here. */ - (void)GC_stopped_mark(GC_never_stop_func); + GC_n_attempts++; } + } else { + /* TODO: If possible, GC_default_stop_func should be */ + /* used here. */ + (void)GC_stopped_mark(GC_never_stop_func); GC_finish_collection(); - break; } } if (GC_deficit > 0) { @@ -677,7 +780,9 @@ DCL_LOCK_STATE; LOCK(); + ENTER_GC(); GC_collect_a_little_inner(1); + EXIT_GC(); result = (int)GC_collection_in_progress(); UNLOCK(); if (!result && GC_debugging_started) GC_print_all_smashed(); @@ -713,7 +818,7 @@ */ STATIC GC_bool GC_stopped_mark(GC_stop_func stop_func) { - unsigned i; + int i; # ifndef NO_CLOCK CLOCK_TYPE start_time = CLOCK_TYPE_INITIALIZER; # endif @@ -766,56 +871,77 @@ GC_noop6(0,0,0,0,0,0); GC_initiate_gc(); - for (i = 0;;i++) { - if ((*stop_func)()) { - GC_COND_LOG_PRINTF("Abandoned stopped marking after" - " %u iterations\n", i); - GC_deficit = i; /* Give the mutator a chance. */ -# ifdef THREAD_LOCAL_ALLOC - GC_world_stopped = FALSE; +# ifdef PARALLEL_MARK + if (stop_func != GC_never_stop_func) + GC_parallel_mark_disabled = TRUE; +# endif + for (i = 0; !(*stop_func)(); i++) { + if (GC_mark_some(GC_approx_sp())) { +# ifdef PARALLEL_MARK + if (GC_parallel && GC_parallel_mark_disabled) { + GC_COND_LOG_PRINTF("Stopped marking done after %d iterations" + " with disabled parallel marker\n", i); + } # endif + i = -1; + break; + } + } +# ifdef PARALLEL_MARK + GC_parallel_mark_disabled = FALSE; +# endif -# ifdef THREADS - if (GC_on_collection_event) - GC_on_collection_event(GC_EVENT_PRE_START_WORLD); -# endif + if (i >= 0) { + GC_COND_LOG_PRINTF("Abandoned stopped marking after" + " %d iterations\n", i); + GC_deficit = i; /* Give the mutator a chance. */ +# ifdef THREAD_LOCAL_ALLOC + GC_world_stopped = FALSE; +# endif - START_WORLD(); +# ifdef THREADS + if (GC_on_collection_event) + GC_on_collection_event(GC_EVENT_PRE_START_WORLD); +# endif -# ifdef THREADS - if (GC_on_collection_event) - GC_on_collection_event(GC_EVENT_POST_START_WORLD); -# endif + START_WORLD(); - /* TODO: Notify GC_EVENT_MARK_ABANDON */ - return(FALSE); - } - if (GC_mark_some(GC_approx_sp())) break; +# ifdef THREADS + if (GC_on_collection_event) + GC_on_collection_event(GC_EVENT_POST_START_WORLD); +# endif + + /* TODO: Notify GC_EVENT_MARK_ABANDON */ + return FALSE; } GC_gc_no++; - GC_DBGLOG_PRINTF("GC #%lu freed %ld bytes, heap %lu KiB" - IF_USE_MUNMAP(" (+ %lu KiB unmapped)") "\n", +# ifdef USE_MUNMAP + GC_ASSERT(GC_heapsize >= GC_unmapped_bytes); +# endif + GC_ASSERT(GC_our_mem_bytes >= GC_heapsize); + GC_DBGLOG_PRINTF("GC #%lu freed %ld bytes, heap %lu KiB (" + IF_USE_MUNMAP("+ %lu KiB unmapped ") + "+ %lu KiB internal)\n", (unsigned long)GC_gc_no, (long)GC_bytes_found, TO_KiB_UL(GC_heapsize - GC_unmapped_bytes) /*, */ - COMMA_IF_USE_MUNMAP(TO_KiB_UL(GC_unmapped_bytes))); + COMMA_IF_USE_MUNMAP(TO_KiB_UL(GC_unmapped_bytes)), + TO_KiB_UL(GC_our_mem_bytes - GC_heapsize)); /* Check all debugged objects for consistency */ if (GC_debugging_started) { (*GC_check_heap)(); } - if (GC_on_collection_event) + if (GC_on_collection_event) { GC_on_collection_event(GC_EVENT_MARK_END); - +# ifdef THREADS + GC_on_collection_event(GC_EVENT_PRE_START_WORLD); +# endif + } # ifdef THREAD_LOCAL_ALLOC GC_world_stopped = FALSE; # endif -# ifdef THREADS - if (GC_on_collection_event) - GC_on_collection_event(GC_EVENT_PRE_START_WORLD); -# endif - START_WORLD(); # ifdef THREADS @@ -847,9 +973,10 @@ world_stopped_total_divisor = ++divisor; GC_ASSERT(divisor != 0); - GC_log_printf( - "World-stopped marking took %lu msecs (%u in average)\n", - time_diff, total_time / divisor); + GC_log_printf("World-stopped marking took %lu ms %lu ns" + " (%u ms in average)\n", + time_diff, NS_FRAC_TIME_DIFF(current_time, start_time), + total_time / divisor); } # endif return(TRUE); @@ -858,7 +985,7 @@ /* Set all mark bits for the free list whose first entry is q */ GC_INNER void GC_set_fl_marks(ptr_t q) { - if (q != NULL) { + if (q /* != NULL */) { /* CPPCHECK */ struct hblk *h = HBLKPTR(q); struct hblk *last_h = h; hdr *hhdr = HDR(h); @@ -984,7 +1111,13 @@ { word used = GC_composite_in_use + GC_atomic_in_use; word heap_sz = GC_heapsize - GC_unmapped_bytes; - return used >= heap_sz ? 0 : used < GC_WORD_MAX / 100 ? +# if defined(CPPCHECK) + word limit = (GC_WORD_MAX >> 1) / 50; /* to avoid a false positive */ +# else + const word limit = GC_WORD_MAX / 100; +# endif + + return used >= heap_sz ? 0 : used < limit ? (int)((used * 100) / heap_sz) : (int)(used / (heap_sz / 100)); } @@ -1125,9 +1258,12 @@ /* A convenient place to output finalization statistics. */ GC_print_finalization_stats(); # endif - GC_log_printf("Finalize plus initiate sweep took %lu + %lu msecs\n", - MS_TIME_DIFF(finalize_time,start_time), - MS_TIME_DIFF(done_time,finalize_time)); + GC_log_printf("Finalize and initiate sweep took %lu ms %lu ns" + " + %lu ms %lu ns\n", + MS_TIME_DIFF(finalize_time, start_time), + NS_FRAC_TIME_DIFF(finalize_time, start_time), + MS_TIME_DIFF(done_time, finalize_time), + NS_FRAC_TIME_DIFF(done_time, finalize_time)); } # elif !defined(SMALL_CONFIG) && !defined(GC_NO_FINALIZATION) if (GC_print_stats) @@ -1172,6 +1308,7 @@ } /* Externally callable routines to invoke full, stop-the-world collection. */ + GC_API int GC_CALL GC_try_to_collect(GC_stop_func stop_func) { GC_ASSERT(NONNULL_ARG_NOT_NULL(stop_func)); @@ -1183,7 +1320,8 @@ /* 0 is passed as stop_func to get GC_default_stop_func value */ /* while holding the allocation lock (to prevent data races). */ (void)GC_try_to_collect_general(0, FALSE); - if (GC_have_errors) GC_print_all_errors(); + if (get_have_errors()) + GC_print_all_errors(); } STATIC word GC_heapsize_at_forced_unmap = 0; @@ -1197,40 +1335,67 @@ (void)GC_try_to_collect_general(GC_never_stop_func, TRUE); } -GC_INNER word GC_n_heap_sects = 0; - /* Number of sections currently in heap. */ - -#ifdef USE_PROC_FOR_LIBRARIES - GC_INNER word GC_n_memory = 0; - /* Number of GET_MEM allocated memory sections. */ -#endif - #ifdef USE_PROC_FOR_LIBRARIES /* Add HBLKSIZE aligned, GET_MEM-generated block to GC_our_memory. */ - /* Defined to do nothing if USE_PROC_FOR_LIBRARIES not set. */ GC_INNER void GC_add_to_our_memory(ptr_t p, size_t bytes) { - if (0 == p) return; + GC_ASSERT(p != NULL); if (GC_n_memory >= MAX_HEAP_SECTS) ABORT("Too many GC-allocated memory sections: Increase MAX_HEAP_SECTS"); GC_our_memoryGC_n_memory.hs_start = p; GC_our_memoryGC_n_memory.hs_bytes = bytes; GC_n_memory++; + GC_our_mem_bytes += bytes; } #endif -/* - * Use the chunk of memory starting at p of size bytes as part of the heap. - * Assumes p is HBLKSIZE aligned, and bytes is a multiple of HBLKSIZE. - */ -GC_INNER void GC_add_to_heap(struct hblk *p, size_t bytes) +/* Use the chunk of memory starting at p of size bytes as part of the heap. */ +/* Assumes p is HBLKSIZE aligned, bytes argument is a multiple of HBLKSIZE. */ +STATIC void GC_add_to_heap(struct hblk *p, size_t bytes) { hdr * phdr; word endp; + size_t old_capacity = 0; + void *old_heap_sects = NULL; +# ifdef GC_ASSERTIONS + unsigned i; +# endif + + GC_ASSERT((word)p % HBLKSIZE == 0); + GC_ASSERT(bytes % HBLKSIZE == 0); + GC_ASSERT(bytes > 0); + GC_ASSERT(GC_all_nils != NULL); - if (GC_n_heap_sects >= MAX_HEAP_SECTS) { - ABORT("Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS"); + if (GC_n_heap_sects == GC_capacity_heap_sects) { + /* Allocate new GC_heap_sects with sufficient capacity. */ +# ifndef INITIAL_HEAP_SECTS +# define INITIAL_HEAP_SECTS 32 +# endif + size_t new_capacity = GC_n_heap_sects > 0 ? + (size_t)GC_n_heap_sects * 2 : INITIAL_HEAP_SECTS; + void *new_heap_sects = + GC_scratch_alloc(new_capacity * sizeof(struct HeapSect)); + + if (EXPECT(NULL == new_heap_sects, FALSE)) { + /* Retry with smaller yet sufficient capacity. */ + new_capacity = (size_t)GC_n_heap_sects + INITIAL_HEAP_SECTS; + new_heap_sects = + GC_scratch_alloc(new_capacity * sizeof(struct HeapSect)); + if (NULL == new_heap_sects) + ABORT("Insufficient memory for heap sections"); + } + old_capacity = GC_capacity_heap_sects; + old_heap_sects = GC_heap_sects; + /* Transfer GC_heap_sects contents to the newly allocated array. */ + if (GC_n_heap_sects > 0) + BCOPY(old_heap_sects, new_heap_sects, + GC_n_heap_sects * sizeof(struct HeapSect)); + GC_capacity_heap_sects = new_capacity; + GC_heap_sects = (struct HeapSect *)new_heap_sects; + GC_COND_LOG_PRINTF("Grew heap sections array to %lu elements\n", + (unsigned long)new_capacity); } + while ((word)p <= HBLKSIZE) { /* Can't handle memory near address zero. */ ++p; @@ -1252,6 +1417,18 @@ return; } GC_ASSERT(endp > (word)p && endp == (word)p + bytes); +# ifdef GC_ASSERTIONS + /* Ensure no intersection between sections. */ + for (i = 0; i < GC_n_heap_sects; i++) { + word hs_start = (word)GC_heap_sectsi.hs_start; + word hs_end = hs_start + GC_heap_sectsi.hs_bytes; + word p_e = (word)p + bytes; + + GC_ASSERT(!((hs_start <= (word)p && (word)p < hs_end) + || (hs_start < p_e && p_e <= hs_end) + || ((word)p < hs_start && hs_end < p_e))); + } +# endif GC_heap_sectsGC_n_heap_sects.hs_start = (ptr_t)p; GC_heap_sectsGC_n_heap_sects.hs_bytes = bytes; GC_n_heap_sects++; @@ -1280,6 +1457,18 @@ if ((word)p + bytes >= (word)GC_greatest_plausible_heap_addr) { GC_greatest_plausible_heap_addr = (void *)endp; } + + if (old_capacity > 0) { +# ifndef GWW_VDB + /* Recycling may call GC_add_to_heap() again but should not */ + /* cause resizing of GC_heap_sects. */ + GC_scratch_recycle_no_gww(old_heap_sects, + old_capacity * sizeof(struct HeapSect)); +# else + /* TODO: implement GWW-aware recycling as in alloc_mark_stack */ + GC_noop1((word)old_heap_sects); +# endif + } } #if !defined(NO_DEBUGGING) @@ -1329,6 +1518,27 @@ GC_word GC_max_retries = 0; +GC_INNER void GC_scratch_recycle_inner(void *ptr, size_t bytes) +{ + size_t page_offset; + size_t displ = 0; + size_t recycled_bytes; + + if (NULL == ptr) return; + + GC_ASSERT(bytes != 0); + GC_ASSERT(GC_page_size != 0); + /* TODO: Assert correct memory flags if GWW_VDB */ + page_offset = (word)ptr & (GC_page_size - 1); + if (page_offset != 0) + displ = GC_page_size - page_offset; + recycled_bytes = bytes > displ ? (bytes - displ) & ~(GC_page_size - 1) : 0; + GC_COND_LOG_PRINTF("Recycle %lu/%lu scratch-allocated bytes at %p\n", + (unsigned long)recycled_bytes, (unsigned long)bytes, ptr); + if (recycled_bytes > 0) + GC_add_to_heap((struct hblk *)((word)ptr + displ), recycled_bytes); +} + /* This explicitly increases the size of the heap. It is used */ /* internally, but may also be invoked from GC_expand_hp by the user. */ /* The argument is in units of HBLKSIZE (tiny values are rounded up). */ @@ -1337,9 +1547,11 @@ { size_t bytes; struct hblk * space; - word expansion_slop; /* Number of bytes by which we expect the */ - /* heap to expand soon. */ + word expansion_slop; /* Number of bytes by which we expect */ + /* the heap to expand soon. */ + GC_ASSERT(I_HOLD_LOCK()); + GC_ASSERT(GC_page_size != 0); if (n < MINHINCR) n = MINHINCR; bytes = ROUNDUP_PAGESIZE((size_t)n * HBLKSIZE); if (GC_max_heapsize != 0 @@ -1349,23 +1561,24 @@ return(FALSE); } space = GET_MEM(bytes); - GC_add_to_our_memory((ptr_t)space, bytes); - if (space == 0) { + if (EXPECT(NULL == space, FALSE)) { WARN("Failed to expand heap by %" WARN_PRIdPTR " bytes\n", (word)bytes); return(FALSE); } + GC_add_to_our_memory((ptr_t)space, bytes); GC_INFOLOG_PRINTF("Grow heap to %lu KiB after %lu bytes allocated\n", TO_KiB_UL(GC_heapsize + (word)bytes), (unsigned long)GC_bytes_allocd); + /* Adjust heap limits generously for blacklisting to work better. */ /* GC_add_to_heap performs minimal adjustment needed for */ /* correctness. */ - expansion_slop = min_bytes_allocd() + 4*MAXHINCR*HBLKSIZE; + expansion_slop = min_bytes_allocd() + 4 * MAXHINCR * HBLKSIZE; if ((GC_last_heap_addr == 0 && !((word)space & SIGNB)) || (GC_last_heap_addr != 0 && (word)GC_last_heap_addr < (word)space)) { - /* Assume the heap is growing up */ + /* Assume the heap is growing up. */ word new_limit = (word)space + (word)bytes + expansion_slop; if (new_limit > (word)space) { GC_greatest_plausible_heap_addr = @@ -1373,7 +1586,7 @@ (word)new_limit); } } else { - /* Heap is growing down */ + /* Heap is growing down. */ word new_limit = (word)space - expansion_slop; if (new_limit < (word)space) { GC_least_plausible_heap_addr = @@ -1381,22 +1594,23 @@ (word)space - expansion_slop); } } - GC_prev_heap_addr = GC_last_heap_addr; GC_last_heap_addr = (ptr_t)space; + GC_add_to_heap(space, bytes); - /* Force GC before we are likely to allocate past expansion_slop */ - GC_collect_at_heapsize = - GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE; - if (GC_collect_at_heapsize < GC_heapsize /* wrapped */) - GC_collect_at_heapsize = GC_WORD_MAX; + + /* Force GC before we are likely to allocate past expansion_slop. */ + GC_collect_at_heapsize = + GC_heapsize + expansion_slop - 2 * MAXHINCR * HBLKSIZE; + if (GC_collect_at_heapsize < GC_heapsize /* wrapped */) + GC_collect_at_heapsize = GC_WORD_MAX; if (GC_on_heap_resize) - (*GC_on_heap_resize)(GC_heapsize); + (*GC_on_heap_resize)(GC_heapsize); return(TRUE); } /* Really returns a bool, but it's externally visible, so that's clumsy. */ -/* Arguments is in bytes. Includes GC_init() call. */ +/* The argument is in bytes. Includes GC_init() call. */ GC_API int GC_CALL GC_expand_hp(size_t bytes) { int result; @@ -1410,12 +1624,30 @@ return(result); } -word GC_fo_entries = 0; /* used also in extra/MacOS.c */ - GC_INNER unsigned GC_fail_count = 0; /* How many consecutive GC/expansion failures? */ /* Reset by GC_allochblk. */ +/* The minimum value of the ratio of allocated bytes since the latest */ +/* GC to the amount of finalizers created since that GC which triggers */ +/* the collection instead heap expansion. Has no effect in the */ +/* incremental mode. */ +#if defined(GC_ALLOCD_BYTES_PER_FINALIZER) && !defined(CPPCHECK) + STATIC word GC_allocd_bytes_per_finalizer = GC_ALLOCD_BYTES_PER_FINALIZER; +#else + STATIC word GC_allocd_bytes_per_finalizer = 10000; +#endif + +GC_API void GC_CALL GC_set_allocd_bytes_per_finalizer(GC_word value) +{ + GC_allocd_bytes_per_finalizer = value; +} + +GC_API GC_word GC_CALL GC_get_allocd_bytes_per_finalizer(void) +{ + return GC_allocd_bytes_per_finalizer; +} + static word last_fo_entries = 0; static word last_bytes_finalized = 0; @@ -1431,11 +1663,14 @@ word blocks_to_get; IF_CANCEL(int cancel_state;) + GC_ASSERT(I_HOLD_LOCK()); DISABLE_CANCEL(cancel_state); if (!GC_incremental && !GC_dont_gc && ((GC_dont_expand && GC_bytes_allocd > 0) - || (GC_fo_entries > (last_fo_entries + 500) - && (last_bytes_finalized | GC_bytes_finalized) != 0) + || (GC_fo_entries > last_fo_entries + && (last_bytes_finalized | GC_bytes_finalized) != 0 + && (GC_fo_entries - last_fo_entries) + * GC_allocd_bytes_per_finalizer > GC_bytes_allocd) || GC_should_collect())) { /* Try to do a full collection using 'default' stop_func (unless */ /* nothing has been allocated since the latest collection or heap */ @@ -1531,9 +1766,15 @@ || NULL == GC_obj_kindskind.ok_reclaim_listgran); GC_continue_reclaim(gran, kind); EXIT_GC(); - if (*flh == 0) { +# if defined(CPPCHECK) + GC_noop1((word)&flh); +# endif + if (NULL == *flh) { GC_new_hblk(gran, kind); - if (*flh == 0) { +# if defined(CPPCHECK) + GC_noop1((word)&flh); +# endif + if (NULL == *flh) { ENTER_GC(); if (GC_incremental && GC_time_limit == GC_TIME_UNLIMITED && !tried_minor) {
View file
_service:tar_scm:gc-8.0.6.tar.gz/backgraph.c -> _service:tar_scm:gc-8.2.2.tar.gz/backgraph.c
Changed
@@ -63,9 +63,9 @@ signed_word height; /* Longest path through unreachable nodes to this node */ /* that we found using depth first search. */ +# define HEIGHT_UNKNOWN (-2) +# define HEIGHT_IN_PROGRESS (-1) -# define HEIGHT_UNKNOWN ((signed_word)(-2)) -# define HEIGHT_IN_PROGRESS ((signed_word)(-1)) ptr_t edgesMAX_IN; struct back_edges_struct *cont; /* Pointer to continuation structure; we use only the */ @@ -90,6 +90,7 @@ size_t bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(MAX_BACK_EDGE_STRUCTS * sizeof(back_edges)); + GC_ASSERT(GC_page_size != 0); back_edge_space = (back_edges *)GET_MEM(bytes_to_get); if (NULL == back_edge_space) ABORT("Insufficient memory for back edges"); @@ -132,6 +133,7 @@ if (n_in_progress >= in_progress_size) { ptr_t * new_in_progress_space; + GC_ASSERT(GC_page_size != 0); if (NULL == in_progress_space) { in_progress_size = ROUNDUP_PAGESIZE_IF_MMAP(INITIAL_IN_PROGRESS * sizeof(ptr_t)) @@ -146,8 +148,9 @@ BCOPY(in_progress_space, new_in_progress_space, n_in_progress * sizeof(ptr_t)); } - GC_add_to_our_memory((ptr_t)new_in_progress_space, - in_progress_size * sizeof(ptr_t)); + if (EXPECT(new_in_progress_space != NULL, TRUE)) + GC_add_to_our_memory((ptr_t)new_in_progress_space, + in_progress_size * sizeof(ptr_t)); # ifndef GWW_VDB GC_scratch_recycle_no_gww(in_progress_space, n_in_progress * sizeof(ptr_t)); @@ -240,7 +243,7 @@ if (((word)pred & FLAG_MANY) != 0) { n_edges = e -> n_edges; - } else if (((word)pred & 1) == 0) { + } else if (((word)COVERT_DATAFLOW(pred) & 1) == 0) { /* A misinterpreted freelist link. */ n_edges = 1; local = -1; @@ -532,8 +535,9 @@ void GC_print_back_graph_stats(void) { GC_ASSERT(I_HOLD_LOCK()); - GC_printf("Maximum backwards height of reachable objects at GC %lu is %lu\n", - (unsigned long) GC_gc_no, (unsigned long)GC_max_height); + GC_printf("Maximum backwards height of reachable objects" + " at GC #%lu is %lu\n", + (unsigned long)GC_gc_no, (unsigned long)GC_max_height); if (GC_max_height > GC_max_max_height) { ptr_t obj = GC_deepest_obj;
View file
_service:tar_scm:gc-8.0.6.tar.gz/build/s60v3/libgc.mmp -> _service:tar_scm:gc-8.2.2.tar.gz/build/s60v3/libgc.mmp
Changed
@@ -41,6 +41,7 @@ SOURCE dyn_load.c SOURCE finalize.c SOURCE fnlz_mlc.c +//SOURCE gc_badalc.cpp //SOURCE gc_cpp.cpp SOURCE gcj_mlc.c SOURCE headers.c
View file
_service:tar_scm:gc-8.0.6.tar.gz/checksums.c -> _service:tar_scm:gc-8.2.2.tar.gz/checksums.c
Changed
@@ -127,8 +127,8 @@ GC_bytes_in_used_blocks = 0; GC_apply_to_all_blocks(GC_add_block, (word)0); - GC_COND_LOG_PRINTF("GC_bytes_in_used_blocks = %lu," - " bytes_in_free_blocks = %lu, heapsize = %lu\n", + GC_COND_LOG_PRINTF("GC_bytes_in_used_blocks= %lu," + " bytes_in_free_blocks= %lu, heapsize= %lu\n", (unsigned long)GC_bytes_in_used_blocks, (unsigned long)bytes_in_free_blocks, (unsigned long)GC_heapsize);
View file
_service:tar_scm:gc-8.0.6.tar.gz/compile -> _service:tar_scm:gc-8.2.2.tar.gz/compile
Changed
@@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey <tromey@cygnus.com>. # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -53,7 +53,7 @@ MINGW*) file_conv=mingw ;; - CYGWIN*) + CYGWIN* | MSYS*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*) + cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) @@ -255,7 +255,8 @@ echo "compile $scriptversion" exit $? ;; - cl | */\\cl | cl.exe | */\\cl.exe ) + cl | */\\cl | cl.exe | */\\cl.exe | \ + icl | */\\icl | icl.exe | */\\icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -339,9 +340,9 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End:
View file
_service:tar_scm:gc-8.0.6.tar.gz/config.guess -> _service:tar_scm:gc-8.2.2.tar.gz/config.guess
Changed
@@ -1,8 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2014-11-04' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2021-06-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +17,7 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses/>. +# along with this program; if not, see <https://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,11 +29,19 @@ # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to <config-patches@gnu.org>. +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + me=`echo "$0" | sed -e 's,.*/,,'` usage="\ @@ -39,7 +49,7 @@ Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +60,7 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,7 +94,8 @@ exit 1 fi -trap 'exit 1' 1 2 15 +# Just in case it came from the environment. +GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires @@ -96,66 +107,90 @@ # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown - eval $set_cc_for_build - cat <<-EOF > $dummy.c + set_cc_for_build + cat <<-EOF > "$dummy.c" #include <features.h> #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include <stdarg.h> + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if "$LIBC" = unknown && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if "$LIBC" = unknown ; then + LIBC=gnu + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -167,22 +202,32 @@ # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv0-9\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -197,45 +242,80 @@ os=netbsd ;; esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv0-9/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/-_.*/\./'` + release=`echo "$UNAME_RELEASE" | sed -e 's/-_.*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; + GUESS=$machine-${os}${release}${abi-} + ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -249,163 +329,158 @@ # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in + case $ALPHA_CPU_TYPE in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^PVTX//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^PVTX//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; + GUESS=m68k-unknown-sysv4 + ;; *:AamigaOoSs:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; *:MmorphOoSs:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; + GUESS=$UNAME_MACHINE-unknown-morphos + ;; *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; + GUESS=i370-ibm-openedition + ;; *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; + GUESS=s390-ibm-zvmoe + ;; *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; + GUESS=powerpc-ibm-os400 + ;; arm:RISC*:1.012*:*|arm:riscix:1.012*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; + GUESS=arm-unknown-riscos + ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; + GUESS=hppa1.1-hitachi-hiuxmpp + ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; + GUESS=pyramid-pyramid-svr4 + ;; DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; + GUESS=sparc-icl-nx6 + ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/^.*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/^.*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/^.*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/^.*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/^.*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/^.*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" + set_cc_for_build + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if "$CC_FOR_BUILD" != 'no_compiler_found' ; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/^.*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/^.*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/^.*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/^.*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac - exit ;; + ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -415,44 +490,44 @@ # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atariste:*MiNT:*:* | atariste:*mint:*:* | atariste:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atariste:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; + GUESS=mips-dec-mach_bsd4.3 + ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include <stdio.h> /* for printf() prototype */ int main (int argc, char *argv) { @@ -461,95 +536,96 @@ #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv1); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv1); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv1); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv1); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv1); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv1); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\(0-9*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\(0-9*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; + GUESS=powerpc-motorola-powermax + ;; Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; + GUESS=powerpc-harris-powerunix + ;; m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; + GUESS=m88k-harris-cxux7 + ;; m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; + GUESS=m88k-motorola-sysv4 + ;; m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if $UNAME_PROCESSOR = mc88100 || $UNAME_PROCESSOR = mc88110 + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx || \ - ${TARGET_BINARY_INTERFACE}x = x + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then - echo m88k-dg-dgux${UNAME_RELEASE} + GUESS=m88k-dg-dgux$UNAME_RELEASE else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else - echo i586-dg-dgux${UNAME_RELEASE} + GUESS=i586-dg-dgux$UNAME_RELEASE fi - exit ;; + ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; + GUESS=m88k-dolphin-sysv3 + ;; M88*:*:R3*:*) # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; + GUESS=m88k-tektronix-sysv3 + ;; Tek430-90-9:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; + GUESS=m68k-tektronix-bsd + ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; ????????:AIX?:12.1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; + GUESS=i386-ibm-aix + ;; ia64:AIX:*:*) - if -x /usr/bin/oslevel ; then + if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include <sys/systemcfg.h> main() @@ -560,77 +636,77 @@ exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then - echo "$SYSTEM_NAME" + GUESS=$SYSTEM_NAME else - echo rs6000-ibm-aix3.2.5 + GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 + GUESS=rs6000-ibm-aix3.2.4 else - echo rs6000-ibm-aix3.2 + GUESS=rs6000-ibm-aix3.2 fi - exit ;; + ;; *:AIX:*:4567) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if -x /usr/bin/lslpp ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/0-9*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; + GUESS=rs6000-bull-bosx + ;; DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; + GUESS=m68k-bull-sysv3 + ;; 9000/34??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; + GUESS=m68k-hp-bsd + ;; hp300:4.4BSD:*:* | 9000/34??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; + GUESS=m68k-hp-bsd4.4 + ;; 9000/34678??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/^.*.0B*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/34?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/^.*.0B*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/34??) HP_ARCH=m68k ;; 9000/6780-90-9) - if -x /usr/bin/getconf ; then + if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if "${HP_ARCH}" = "" ; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include <stdlib.h> @@ -663,13 +739,13 @@ exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if ${HP_ARCH} = "hppa2.0w" + if test "$HP_ARCH" = hppa2.0w then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -680,23 +756,23 @@ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/^.*.0B*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/^.*.0B*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include <unistd.h> int main () @@ -721,38 +797,38 @@ exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?79:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?79:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; + GUESS=hppa1.0-hp-bsd + ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?79:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?79:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; + GUESS=hppa1.0-hp-osf + ;; i*86:OSF1:*:*) - if -x /usr/sbin/sysversion ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + GUESS=$UNAME_MACHINE-unknown-osf1 fi - exit ;; + ;; parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; + GUESS=hppa1.1-hp-lites + ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; + GUESS=c1-convex-bsd + ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd @@ -760,139 +836,145 @@ fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; + GUESS=c34-convex-bsd + ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; + GUESS=c38-convex-bsd + ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; + GUESS=c4-convex-bsd + ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.^.*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.^.*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; CRAY*A-Z90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\(A-Z90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.^.*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.^.*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.^.*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.^.*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.^.*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.^.*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.^.*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.^.*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.^.*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; F3001:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/-(.*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/-(.*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case $UNAME_PROCESSOR in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/-(.*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/-(.*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac - exit ;; + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/-(.*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; + GUESS=$UNAME_MACHINE-pc-cygwin + ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-msys + ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-pw32 + ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case $UNAME_MACHINE in x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; + GUESS=i586-pc-interix$UNAME_RELEASE + ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; esac ;; - 34586:Windows_95:* | 34586:Windows_98:* | 34586:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; + GUESS=$UNAME_MACHINE-pc-uwin + ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; + GUESS=x86_64-pc-cygwin + ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/^.*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/^.*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,-/.*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,-/.*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^^/*/,,' | tr 'A-Z' 'a-z'``echo ${UNAME_RELEASE}|sed -e 's/-(.*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^^/*/,,' | tr ":upper:" ":lower:"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/-(.*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -902,172 +984,226 @@ EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi - exit ;; + ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} - exit ;; + GUESS=or1k-unknown-linux-$LIBC + ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} - exit ;; + GUESS=sparc-unknown-linux-$LIBC + ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} - exit ;; + GUESS=hppa64-unknown-linux-$LIBC + ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu^a-z*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; esac - exit ;; + ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc64-unknown-linux-$LIBC + ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc-unknown-linux-$LIBC + ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc64le-unknown-linux-$LIBC + ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} - exit ;; + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI=${LIBC}x32 + fi + fi + GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; + GUESS=i386-sequent-sysv4 + ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; + GUESS=$UNAME_MACHINE-unknown-stop + ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; + GUESS=$UNAME_MACHINE-unknown-atheos + ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; + GUESS=$UNAME_MACHINE-pc-syllable + ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.01*:* | i*86:LynxOS:4.02*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi - exit ;; + ;; i*86:*:5:678*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in @@ -1075,12 +1211,12 @@ *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL elif /bin/uname -X 2>/dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1090,43 +1226,43 @@ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else - echo ${UNAME_MACHINE}-pc-sysv32 + GUESS=$UNAME_MACHINE-pc-sysv32 fi - exit ;; + ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; + GUESS=i586-pc-msdosdjgpp + ;; Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; + GUESS=i386-pc-mach3 + ;; paragon:*:*:*) - echo i860-intel-osf1 - exit ;; + GUESS=i860-intel-osf1 + ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi - exit ;; + ;; mini*:CTIX:SYS*5:*) # "miniframe" - echo m68010-convergent-sysv - exit ;; + GUESS=m68010-convergent-sysv + ;; mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; + GUESS=m68k-convergent-sysv + ;; M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; + GUESS=m68k-diab-dnix + ;; M68*:*:R3V5678*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3345??:*:4.0:3.0 | 334??A:*:4.0:3.0 | 334??,*:*:4.0:3.0 | 334??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) @@ -1134,9 +1270,9 @@ test -r /etc/.relid \ && OS_REL=.`sed -n 's/^ * ^ * \(0-90-9\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 334??:*:4.0:* | 334??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1145,248 +1281,438 @@ test -r /etc/.relid \ && OS_REL=.`sed -n 's/^ * ^ * \(0-90-9\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; + GUESS=m68k-atari-sysv4 + ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.01*:* | PowerPC:LynxOS:4.02*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; SMBES:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + GUESS=$UNAME_MACHINE-sni-sysv4 else - echo ns32k-sni-sysv + GUESS=ns32k-sni-sysv fi - exit ;; + ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit ;; + GUESS=i586-unisys-sysv4 + ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes <hewes@openmarket.com>. # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; + GUESS=hppa1.1-stratus-sysv4 + ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; + GUESS=i860-stratus-sysv4 + ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; + GUESS=$UNAME_MACHINE-stratus-vos + ;; *:VOS:*:*) # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; + GUESS=hppa1.1-stratus-vos + ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; + GUESS=mips-sony-newsos6 + ;; R34000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if -d /usr/nec ; then - echo mips-nec-sysv${UNAME_RELEASE} + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE else - echo mips-unknown-sysv${UNAME_RELEASE} + GUESS=mips-unknown-sysv$UNAME_RELEASE fi - exit ;; + ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; + GUESS=powerpc-be-beos + ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; + GUESS=powerpc-apple-beos + ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; + GUESS=i586-pc-beos + ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; + GUESS=i586-pc-haiku + ;; x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; + GUESS=x86_64-unknown-haiku + ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if "$CC_FOR_BUILD" != 'no_compiler_found' ; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; *:procnto*:*:* | *:QNX:0123456789*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; + GUESS=mips-compaq-nonstopux + ;; BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; + GUESS=bs2000-siemens-sysv + ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; + GUESS=pdp10-unknown-tops10 + ;; *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; + GUESS=pdp10-unknown-tenex + ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; + GUESS=pdp10-dec-tops20 + ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; + GUESS=pdp10-xkl-tops20 + ;; *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; + GUESS=pdp10-unknown-tops20 + ;; *:ITS:*:*) - echo pdp10-unknown-its - exit ;; + GUESS=pdp10-unknown-its + ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/-(.*//'` - exit ;; + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/-(.*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; + GUESS=i386-pc-xenix + ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; + GUESS=$UNAME_MACHINE-pc-rdos + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" <<EOF +#ifdef _SEQUENT_ +#include <sys/types.h> +#include <sys/utsname.h> +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include <signal.h> +#if defined(_SIZE_T_) || defined(SIGLOST) +#include <sys/utsname.h> +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \(0-9*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include <sys/param.h> +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <<EOF + +NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize +the system type. Please install a C compiler and try again. +EOF + ;; esac cat >&2 <<EOF -$0: unable to guess system type -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from +This script (version $timestamp), has failed to recognize the +operating system you are using. If your script is old, overwrite *all* +copies of config.guess and config.sub with the latest versions from: - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + https://git.savannah.gnu.org/cgit/config.git/plain/config.guess and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + https://git.savannah.gnu.org/cgit/config.git/plain/config.sub +EOF -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. +our_year=`echo $timestamp | sed 's,-.*,,'` +thisyear=`date +%Y` +# shellcheck disable=SC2003 +script_age=`expr "$thisyear" - "$our_year"` +if test "$script_age" -lt 3 ; then + cat >&2 <<EOF + +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp @@ -1405,16 +1731,17 @@ /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'"
View file
_service:tar_scm:gc-8.0.6.tar.gz/config.sub -> _service:tar_scm:gc-8.2.2.tar.gz/config.sub
Changed
@@ -1,8 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2014 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2014-12-03' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2021-08-14' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +17,7 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see <http://www.gnu.org/licenses/>. +# along with this program; if not, see <https://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +35,7 @@ # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -50,15 +52,21 @@ # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 OPTION CPU-MFR-OPSYS - $0 OPTION ALIAS +Usage: $0 OPTION CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -68,7 +76,7 @@ version="\ GNU config.sub ($timestamp) -Copyright 1992-2014 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -90,12 +98,12 @@ - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -111,1228 +119,1181 @@ exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\(^-*-^-*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\(^-*-^-*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\(^-*-^-*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-^-*$//'` - if $basic_machine != $1 - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <<EOF +$1 +EOF +IFS=$saved_IFS -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun234* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c123* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.4-9*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v4-9*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos +# Separate into logical components for further validation +case $1 in + *-*-*-*-*) + echo Invalid configuration \`"$1"\': more than four components >&2 + exit 1 ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun234* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c123* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint0-9*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh45000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev4-8 | alphaev56 | alphaev678 | alphapca567 \ - | alpha64 | alpha64ev4-8 | alpha64ev56 | alpha64ev678 | alpha64pca567 \ - | am33_2.0 \ - | arc | arceb \ - | arm | armble | armelb | armv2-8 | armv3-8lb | armv7arm \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.01 | hppa2.0 | hppa2.0nw | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh1234 | sh24a | sh24aeb | sh23e | sh34eb | sheb | shbe | shle | sh1234le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon3-9) - basic_machine=sparc-$basic_machine + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none + op50n) + cpu=hppa1.1 + vendor=oki ;; - m88110 | m680123460 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + op60c) + cpu=hppa1.1 + vendor=oki ;; - ms1) - basic_machine=mt-unknown + ibm*) + cpu=i370 + vendor=ibm ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + orion105) + cpu=clipper + vendor=highlevel ;; - xscaleeb) - basic_machine=armeb-unknown + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; - - xscaleel) - basic_machine=armel-unknown + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev4-8-* | alphaev56-* | alphaev678-* \ - | alpha64-* | alpha64ev4-8-* | alpha64ev56-* | alpha64ev678-* \ - | alphapca567-* | alpha64pca567-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c123* | c30-* | cjt90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f3001-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.01-* | hppa2.0-* | hppa2.0nw-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m6800123460-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh1234-* | sh24a-* | sh24aeb-* | sh23e-* | sh34eb-* | sheb-* | shbe-* \ - | shle-* | sh1234le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^^-*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^^-*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^^-*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^^-*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^^-*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + basic_os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + basic_os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 + cpu=m68k + vendor=motorola ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; hp3k90-90-9 | hp90-90-9) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k20-90-9 | hp9k310-9) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k32-90-9) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k60-90-9 | hp60-90-9) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k70-790-9 | hp70-790-9) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k780-9 | hp780-9) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8671 | hp8671 | hp9k8024 | hp8024 | hp9k8789 | hp8789 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k80-913679 | hp80-913679) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k80-90-9 | hp80-90-9) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) + cpu=mips + vendor=sgi + case $basic_os in + irix*) ;; *) - os=-irix4 + basic_os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon3-9-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^^-*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint0-9* | *MiNT | *MiNT0-9*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl + cpu=m68000 + vendor=convergent ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint0-9* | *MiNT | *MiNT0-9*) + cpu=m68k + vendor=atari + basic_os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + basic_os=nextstep2 ;; *) - os=-nextstep3 + basic_os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh45000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + basic_os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^^-*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc + cpu=m68k + vendor=tti ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^^-*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^^-*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^^-*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^^-*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^^-*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown + cpu=pn + vendor=gould ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^^-*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^^-*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^^-*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^^-*-//'` + power) + cpu=power + vendor=ibm ;; ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + cpu=i386 + vendor=ibm ;; rm4600) - basic_machine=mips-siemens + cpu=mips + vendor=siemens ;; rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm + cpu=romp + vendor=ibm ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks ;; - sde) - basic_machine=mipsisa32-sde - os=-elf + tower | tower-32) + cpu=m68k + vendor=ncr ;; - sei) - basic_machine=mips-sei - os=-seiux + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - sequent) - basic_machine=i386-sequent + w65) + cpu=w65 + vendor=wdc ;; - sh) - basic_machine=sh-hitachi - os=-hms + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf ;; - sh5el) - basic_machine=sh5le-unknown + none) + cpu=none + vendor=none ;; - sh64) - basic_machine=sh64-unknown + leon|leon3-9) + cpu=sparc + vendor=$basic_machine ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks + leon-*|leon3-9-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <<EOF +$basic_machine +EOF + IFS=$saved_IFS ;; - spur) - basic_machine=spur-unknown + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + cpu=$basic_machine + vendor=pc ;; - st2000) - basic_machine=m68k-tandem + # These rules are duplicated from below for sake of the special case above; + # i.e. things that normalized to x86 arches should also default to "pc" + pc98) + cpu=i386 + vendor=pc ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 + x64 | amd64) + cpu=x86_64 + vendor=pc ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^^-*-//'` + # Recognize the basic CPU types without company name. + *) + cpu=$basic_machine + vendor=unknown ;; - sun2) - basic_machine=m68000-sun +esac + +unset -v basic_machine + +# Decode basic machines in the full and proper CPU-Company form. +case $cpu-$vendor in + # Here we handle the default manufacturer of certain CPU types in canonical form. It is in + # some cases the only manufacturer, in others, it is the most popular. + craynv-unknown) + vendor=cray + basic_os=${basic_os:-unicosmp} ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 + c90-unknown | c90-cray) + vendor=cray + basic_os=${Basic_os:-unicos} ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 + fx80-unknown) + vendor=alliant ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 + romp-unknown) + vendor=ibm ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 + mmix-unknown) + vendor=knuth ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 + microblaze-unknown | microblazeel-unknown) + vendor=xilinx ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 + rs6000-unknown) + vendor=ibm ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 + vax-unknown) + vendor=dec ;; - sun3 | sun3-*) - basic_machine=m68k-sun + pdp11-unknown) + vendor=dec ;; - sun4) - basic_machine=sparc-sun + we32k-unknown) + vendor=att ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun + cydra-unknown) + vendor=cydrome ;; - sv1) - basic_machine=sv1-cray - os=-unicos + i370-ibm*) + vendor=ibm ;; - symmetry) - basic_machine=i386-sequent - os=-dynix + orion-unknown) + vendor=highlevel ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos + xps-unknown | xps100-unknown) + cpu=xps100 + vendor=honeywell ;; - t90) - basic_machine=t90-cray - os=-unicos + + # Here we normalize CPU types with a missing or matching vendor + dpx20-unknown | dpx20-bull) + cpu=rs6000 + vendor=bull + basic_os=${basic_os:-bosx} ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu + + # Here we normalize CPU types irrespective of the vendor + amd64-*) + cpu=x86_64 ;; - tx39) - basic_machine=mipstx39-unknown + blackfin-*) + cpu=bfin + basic_os=linux ;; - tx39el) - basic_machine=mipstx39el-unknown + c54x-*) + cpu=tic54x ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 + c55x-*) + cpu=tic55x ;; - tower | tower-32) - basic_machine=m68k-ncr + c6x-*) + cpu=tic6x ;; - tpf) - basic_machine=s390x-ibm - os=-tpf + e500v12-*) + cpu=powerpc + basic_os=${basic_os}"spe" ;; - udi29k) - basic_machine=a29k-amd - os=-udi + mips3*-*) + cpu=mips64 ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 + ms1-*) + cpu=mt ;; - v810 | necv810) - basic_machine=v810-nec - os=-none + m68knommu-*) + cpu=m68k + basic_os=linux ;; - vaxv) - basic_machine=vax-dec - os=-sysv + m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) + cpu=s12z ;; - vms) - basic_machine=vax-dec - os=-vms + openrisc-*) + cpu=or32 ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu + parisc-*) + cpu=hppa + basic_os=linux ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + cpu=i586 ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks + pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + cpu=i686 ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + cpu=i686 ;; - w65*) - basic_machine=w65-wdc - os=-none + pentium4-*) + cpu=i786 ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf + pc98-*) + cpu=i386 ;; - xbox) - basic_machine=i686-pc - os=-mingw32 + ppc-* | ppcbe-*) + cpu=powerpc ;; - xps | xps100) - basic_machine=xps100-honeywell + ppcle-* | powerpclittle-*) + cpu=powerpcle ;; - xscale-* | xscaleebl-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ppc64-*) + cpu=powerpc64 ;; - ymp) - basic_machine=ymp-cray - os=-unicos + ppc64le-* | powerpc64little-*) + cpu=powerpc64le ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim + sb1-*) + cpu=mipsisa64sb1 ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim + sb1el-*) + cpu=mipsisa64sb1el ;; - none) - basic_machine=none-none - os=-none + sh5elb-*) + cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond + spur-*) + cpu=spur ;; - op50n) - basic_machine=hppa1.1-oki + strongarm-* | thumb-*) + cpu=arm ;; - op60c) - basic_machine=hppa1.1-oki + tx39-*) + cpu=mipstx39 ;; - romp) - basic_machine=romp-ibm + tx39el-*) + cpu=mipstx39el ;; - mmix) - basic_machine=mmix-knuth + x64-*) + cpu=x86_64 ;; - rs6000) - basic_machine=rs6000-ibm + xscale-* | xscaleebl-*) + cpu=`echo "$cpu" | sed 's/^xscale/arm/'` ;; - vax) - basic_machine=vax-dec + arm64-*) + cpu=aarch64 ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown + + # Recognize the canonical CPU Types that limit and/or modify the + # company names they are paired with. + cr16-*) + basic_os=${basic_os:-elf} ;; - pdp11) - basic_machine=pdp11-dec + crisv32-* | etraxfs*-*) + cpu=crisv32 + vendor=axis ;; - we32k) - basic_machine=we32k-att + cris-* | etrax*-*) + cpu=cris + vendor=axis ;; - sh1234 | sh24a | sh24aeb | sh34eb | sh1234le | sh23ele) - basic_machine=sh-unknown + crx-*) + basic_os=${basic_os:-elf} ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun + neo-tandem) + cpu=neo + vendor=tandem ;; - cydra) - basic_machine=cydra-cydrome + nse-tandem) + cpu=nse + vendor=tandem ;; - orion) - basic_machine=orion-highlevel + nsr-tandem) + cpu=nsr + vendor=tandem ;; - orion105) - basic_machine=clipper-highlevel + nsv-tandem) + cpu=nsv + vendor=tandem ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple + nsx-tandem) + cpu=nsx + vendor=tandem ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. + tile*-*) + basic_os=${basic_os:-linux-gnu} ;; + *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev4-8 | alphaev56 | alphaev678 \ + | alpha64 | alpha64ev4-8 | alpha64ev56 | alpha64ev678 \ + | alphapca567 | alpha64pca567 \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb | arc32 | arc64 \ + | arm | armlbe | armelb | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c123* | c30 | cjt90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f3001 | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.01 | hppa2.0 | hppa2.0nw | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m6800123460 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r3 | mipsisa32r3el \ + | mipsisa32r5 | mipsisa32r5el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r3 | mipsisa64r3el \ + | mipsisa64r5 | mipsisa64r5el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh1234 | sh24a | sh24aelb | sh23e | shelb | shlbe \ + | sh1234elb | sh12345lbe | sh23ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1340,200 +1301,215 @@ # Decode manufacturer-specific aliases for certain operating systems. -if x"$os" != x"" +if test x$basic_os != x then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <<EOF +$basic_os +EOF + IFS=$saved_IFS + ;; + # Default OS when just kernel was specified + nto*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto|qnx|'` + ;; + linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|linux|gnu|'` + ;; + *) + kernel= + os=$basic_os + ;; +esac + +# Now, normalize the OS (knowing we just have one component, it's not a kernel, +# etc.) case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux + # First match some system type aliases that might get confused + # with valid system types. + # solaris* is a basic system type, with this one exception. + auroraux) + os=auroraux ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` + bluegene*) + os=cnk ;; - -solaris) - os=-solaris2 + solaris1 | solaris1.*) + os=`echo "$os" | sed -e 's|solaris1|sunos4|'` ;; - -svr4*) - os=-sysv4 + solaris) + os=solaris2 ;; - -unixware*) - os=-sysv4.2uw + unixware*) + os=sysv4.2uw ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + # es1800 is here to avoid being matched by es* (a different OS) + es1800*) + os=ose ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos34*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac + # Some version numbers need modification + chorusos*) + os=chorusos ;; - -nto-qnx*) + isc) + os=isc2.2 ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` + sco6) + os=sco5v6 ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + sco5) + os=sco3.2v5 ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + sco4) + os=sco3.2v4 ;; - -linux-dietlibc) - os=-linux-dietlibc + sco3.2.4-9*) + os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'` ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` + sco*v* | scout) + # Don't match below ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + sco*) + os=sco3.2v2 ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + psos*) + os=psos ;; - -opened*) - os=-openedition + qnx*) + os=qnx ;; - -os400*) - os=-os400 + hiux*) + os=hiuxwe2 ;; - -wince*) - os=-wince + lynx*178) + os=lynxos178 ;; - -osfrose*) - os=-osfrose + lynx*5) + os=lynxos5 ;; - -osf*) - os=-osf + lynxos*) + # don't get caught up in next wildcard ;; - -utek*) - os=-bsd + lynx*) + os=lynxos ;; - -dynix*) - os=-bsd + mac0-9*) + os=`echo "$os" | sed -e 's|mac|macos|'` ;; - -acis*) - os=-aos + opened*) + os=openedition ;; - -atheos*) - os=-atheos + os400*) + os=os400 ;; - -syllable*) - os=-syllable + sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; - -386bsd) - os=-bsd + sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; - -ctix* | -uts*) - os=-sysv + wince*) + os=wince ;; - -nova*) - os=-rtmk-nova + utek*) + os=bsd ;; - -ns2 ) - os=-nextstep2 + dynix*) + os=bsd ;; - -nsk*) - os=-nsk + acis*) + os=aos ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` + atheos*) + os=atheos ;; - -sinix*) - os=-sysv4 + syllable*) + os=syllable ;; - -tpf*) - os=-tpf + 386bsd) + os=bsd ;; - -triton*) - os=-sysv3 + ctix* | uts*) + os=sysv ;; - -oss*) - os=-sysv3 + nova*) + os=rtmk-nova ;; - -svr4) - os=-sysv4 + ns2) + os=nextstep2 ;; - -svr3) - os=-sysv3 + # Preserve the version number of sinix5. + sinix5.*) + os=`echo "$os" | sed -e 's|sinix|sysv|'` ;; - -sysvr4) - os=-sysv4 + sinix*) + os=sysv4 ;; - # This must come after -sysvr4. - -sysv*) + tpf*) + os=tpf ;; - -ose*) - os=-ose + triton*) + os=sysv3 ;; - -es1800*) - os=-ose + oss*) + os=sysv3 ;; - -xenix) - os=-xenix + svr4*) + os=sysv4 ;; - -*mint | -mint0-9* | -*MiNT | -MiNT0-9*) - os=-mint + svr3) + os=sysv3 ;; - -aros*) - os=-aros + sysvr4) + os=sysv4 ;; - -zvmoe) - os=-zvmoe + ose*) + os=ose ;; - -dicos*) - os=-dicos + *mint | mint0-9* | *MiNT | MiNT0-9*) + os=mint ;; - -nacl*) + dicos*) + os=dicos ;; - -none) + pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $cpu in + arm*) + os=eabi + ;; + *) + os=elf + ;; + esac ;; *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/^-*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1546,261 +1522,362 @@ # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; - *-be) - os=-beos + pru-*) + os=elf ;; - *-haiku) - os=-haiku + *-be) + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; - *-next ) - os=-nextstep + *-next) + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f3001-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | relibc* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos34* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v4-9* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - -os400*) + s390-* | s390x-*) vendor=ibm ;; - -ptx*) + *-ptx*) vendor=sequent ;; - -tpf*) + *-tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint0-9* | -*MiNT | -MiNT0-9*) + *-*mint | *-mint0-9* | *-*MiNT | *-MiNT0-9*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'"
View file
_service:tar_scm:gc-8.0.6.tar.gz/configure -> _service:tar_scm:gc-8.2.2.tar.gz/configure
Changed
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for gc 8.0.6. +# Generated by GNU Autoconf 2.69 for gc 8.2.2. # # Report bugs to <https://github.com/ivmai/bdwgc/issues>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='gc' PACKAGE_TARNAME='gc' -PACKAGE_VERSION='8.0.6' -PACKAGE_STRING='gc 8.0.6' +PACKAGE_VERSION='8.2.2' +PACKAGE_STRING='gc 8.2.2' PACKAGE_BUGREPORT='https://github.com/ivmai/bdwgc/issues' PACKAGE_URL='' @@ -664,11 +664,15 @@ KEEP_BACK_PTRS_TRUE MAKE_BACK_GRAPH_FALSE MAKE_BACK_GRAPH_TRUE +ENABLE_GCJ_SUPPORT_FALSE +ENABLE_GCJ_SUPPORT_TRUE addlibs addobjs CXXLIBS AM_CPPFLAGS AM_CFLAGS +GC_TBA_LIBRARY_FALSE +GC_TBA_LIBRARY_TRUE CPLUSPLUS_FALSE CPLUSPLUS_TRUE target_all @@ -691,6 +695,8 @@ THREADDLLIBS CFLAGS_EXTRA GC_CFLAGS +EMSCRIPTEN_FALSE +EMSCRIPTEN_TRUE CXXCPP CPP LT_SYS_LIBRARY_PATH @@ -733,7 +739,6 @@ AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR OBJEXT @@ -751,6 +756,9 @@ AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V +CSCOPE +ETAGS +CTAGS am__untar am__tar AMTAR @@ -824,7 +832,8 @@ PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -845,6 +854,7 @@ enable_threads_discovery enable_cplusplus with_ecos +enable_throw_bad_alloc_library with_target_subdir with_cross_host enable_gcj_support @@ -1434,7 +1444,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures gc 8.0.6 to adapt to many kinds of systems. +\`configure' configures gc 8.2.2 to adapt to many kinds of systems. Usage: $0 OPTION... VAR=VALUE... @@ -1506,7 +1516,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of gc 8.0.6:";; + short | recursive ) echo "Configuration of gc 8.2.2:";; esac cat <<\_ACEOF @@ -1536,6 +1546,8 @@ --disable-threads-discovery disable threads discovery in GC --enable-cplusplus install C++ support + --disable-throw-bad-alloc-library + do not build C++ gctba library --disable-gcj-support disable support for gcj --enable-sigrt-signals force GC to use SIGRTMIN-based signals for thread suspend/resume @@ -1567,7 +1579,7 @@ (default: yes if static libraries are disabled) --enable-gcov turn on code coverage analysis --disable-docs do not build and install documentation - --enable-handle-fork=yes|no|auto|manual + --enable-handle-fork=yes|no|auto|manual attempt to ensure a usable collector after fork() in multi-threaded programs (default: auto; manual: GC_atfork_prepare/parent/child should be called by @@ -1589,7 +1601,7 @@ configuring with a cross compiler --with-cross-host=HOST configuring with a cross compiler --with-libatomic-ops=yes|no|check|none - Use an external libatomic_ops? (default: check; + use an external libatomic_ops? (default: check; none: use compiler intrinsics or no thread support) Some influential environment variables: @@ -1675,7 +1687,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -gc configure 8.0.6 +gc configure 8.2.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2165,7 +2177,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by gc $as_me 8.0.6, which was +It was created by gc $as_me 8.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2692,7 +2704,7 @@ $as_echo "major=$GC_VERSION_MAJOR minor=$GC_VERSION_MINOR \ micro=$GC_VERSION_MICRO" >&6; } -am__api_version='1.15' +am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2868,12 +2880,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -3178,7 +3185,7 @@ # Define the identity of the package. PACKAGE='gc' - VERSION='8.0.6' + VERSION='8.2.2' cat >>confdefs.h <<_ACEOF @@ -3208,8 +3215,8 @@ # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -3228,6 +3235,20 @@ +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi + +if test -z "$ETAGS"; then + ETAGS=etags +fi + +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi + + # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile @@ -3260,7 +3281,7 @@ Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. +that behaves properly: <https://www.gnu.org/software/coreutils/>. If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3304,45 +3325,45 @@ ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -16177,8 +16198,8 @@ # Special CFLAGS to use when building gc_cflags="" -# gc_use_mmap Set to "yes" on platforms where mmap should be used instead -# of sbrk. This will define USE_MMAP. +# Set to "yes" on platforms where mmap should be used instead of sbrk. +# This will define USE_MMAP. gc_use_mmap="" # We should set -fexceptions if we are using gcc and might be used @@ -16197,13 +16218,6 @@ esac fi -case "${host}" in - *-linux*) - # FIXME: This seems to be no longer needed as configured in gcconfig.h - #gc_use_mmap=yes - ;; -esac - # target_optspace --enable-target-optspace ("yes", "no", "") case "${target_optspace}:${host}" in yes:*) @@ -16226,6 +16240,37 @@ ;; esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for emscripten" >&5 +$as_echo_n "checking for emscripten... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef __EMSCRIPTEN__ +#error "this is emscripten" +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + emscripten=no +else + emscripten=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Note -s ASYNCIFY is required to scan the stack, ASYNCIFY_STACK_SIZE is +# probably needed for gctest only. +if test "x$emscripten" = "xyes"; then : + gc_cflags="${gc_cflags} -s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000" +fi + if test x$emscripten = xyes; then + EMSCRIPTEN_TRUE= + EMSCRIPTEN_FALSE='#' +else + EMSCRIPTEN_TRUE='#' + EMSCRIPTEN_FALSE= +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $emscripten" >&5 +$as_echo "$emscripten" >&6; } GC_CFLAGS=${gc_cflags} @@ -16239,7 +16284,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for thread model used by GCC" >&5 $as_echo_n "checking for thread model used by GCC... " >&6; } THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` - if test -z "$THREADS"; then + if test -z "$THREADS" -o "x$emscripten" = "xyes"; then THREADS=no fi if test "$THREADS" = "posix"; then @@ -16263,7 +16308,7 @@ as_fn_error $? "Parallel mark requires --enable-threads=x spec" "$LINENO" 5 fi ;; - esac + esac fi @@ -16276,7 +16321,7 @@ as_fn_error $? "Thread-local allocation requires --enable-threads=x spec" "$LINENO" 5 fi ;; - esac + esac fi @@ -16360,6 +16405,8 @@ THREADDLLIBS= need_atomic_ops_asm=false +need_lib_rt=false +compile_asm=false use_parallel_mark=no use_thread_local_alloc=no # Libraries needed to support dynamic loading and/or threads. @@ -16434,8 +16481,9 @@ $as_echo "$as_me: WARNING: \"Only HP/UX 11 POSIX threads are supported.\"" >&2;} $as_echo "#define _POSIX_C_SOURCE 199506L" >>confdefs.h - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" # HPUX needs REENTRANT for the _r calls. + need_lib_rt=true ;; *-*-openbsd*) AM_CFLAGS="$AM_CFLAGS -pthread" @@ -16456,10 +16504,12 @@ $as_echo "$as_me: WARNING: \"Only on NetBSD 2.0 or later.\"" >&2;} $as_echo "#define _PTHREADS 1" >>confdefs.h - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" + need_lib_rt=true ;; *-*-solaris*) - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" + need_lib_rt=true ;; *-*-cygwin* | *-*-msys*) # Cygwin doesn't have a real libpthread, so Libtool can't link @@ -16481,7 +16531,8 @@ ;; *-*-osf*) AM_CFLAGS="$AM_CFLAGS -pthread" - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" + need_lib_rt=true ;; *) if test x$default_threadlibs != xtrue; then : @@ -16498,7 +16549,7 @@ ;; esac ;; - win32) + mcf | win32) $as_echo "#define GC_THREADS 1" >>confdefs.h use_parallel_mark=$enable_parallel_mark @@ -16520,9 +16571,6 @@ dgux386) $as_echo "#define GC_THREADS 1" >>confdefs.h - THREADS=dgux386 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $THREADDLLIBS" >&5 -$as_echo "$THREADDLLIBS" >&6; } # Use pthread GCC switch THREADDLLIBS=-pthread use_parallel_mark=$enable_parallel_mark @@ -16556,6 +16604,77 @@ ;; esac +# Check whether -lrt linker option is needed to use clock_gettime. +if test "x$need_lib_rt" != xtrue; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime without additional libraries" >&5 +$as_echo_n "checking for clock_gettime without additional libraries... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <time.h> +int +main () +{ +struct timespec t; clock_gettime(CLOCK_REALTIME, &t) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 +$as_echo_n "checking for clock_gettime in -lrt... " >&6; } +if ${ac_cv_lib_rt_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_rt_clock_gettime=yes +else + ac_cv_lib_rt_clock_gettime=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 +$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } +if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : + need_lib_rt=true +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +if test "x$need_lib_rt" = xtrue; then + THREADDLLIBS="$THREADDLLIBS -lrt" +fi + + if test x$THREADS != xnone; then THREADS_TRUE= THREADS_FALSE='#' @@ -16924,6 +17043,21 @@ fi +# Check whether --enable-throw-bad-alloc-library was given. +if test "${enable_throw_bad_alloc_library+set}" = set; then : + enableval=$enable_throw_bad_alloc_library; +fi + + if test "${enable_cplusplus}" = yes \ + -a "${enable_throw_bad_alloc_library}" != no; then + GC_TBA_LIBRARY_TRUE= + GC_TBA_LIBRARY_FALSE='#' +else + GC_TBA_LIBRARY_TRUE='#' + GC_TBA_LIBRARY_FALSE= +fi + + if test "$GCC" = yes; then if test "${enable_cplusplus}" = yes; then case "$host" in @@ -16994,7 +17128,7 @@ $as_echo "$enable_shared" >&6; } # Compile with GC_DLL defined unless building static libraries. -if test "${enable_shared}" = yes -a "${enable_static}" = no; then +if test "${enable_shared}" != no -a "${enable_static}" != yes; then $as_echo "#define GC_DLL 1" >>confdefs.h if test "$GCC" = yes; then @@ -17033,6 +17167,10 @@ case "$host" in *-*-cygwin* | *-*-mingw* | *-*-msys*) + # Do not require the clients to link with "user32" system library. + +$as_echo "#define DONT_USE_USER32_DLL 1" >>confdefs.h + # Use inline version of GC new and delete operators in test_cpp # otherwise the system ones might be used instead because of arbitrary # ordering of object files when linking. @@ -17059,30 +17197,28 @@ $as_echo "#define SOLARIS25_PROC_VDB_BUG_FIXED 1" >>confdefs.h ;; - mips-*-*) - ;; sparc-*-netbsd*) machdep="sparc_netbsd_mach_dep.lo" + compile_asm=true ;; sparc*-*-linux* | sparc*-*-openbsd* | sparc64-*-freebsd* | sparc64-*-netbsd*) machdep="sparc_mach_dep.lo" + compile_asm=true ;; sparc-sun-solaris2.3) machdep="sparc_mach_dep.lo" + compile_asm=true $as_echo "#define SUNOS53_SHARED_LIB 1" >>confdefs.h ;; sparc*-sun-solaris2*) machdep="sparc_mach_dep.lo" + compile_asm=true ;; ia64-*-*) machdep="ia64_save_regs_in_stack.lo" ;; - *-*-nacl*) - $as_echo "#define NO_EXECUTE_PERMISSION 1" >>confdefs.h - - ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $machdep" >&5 $as_echo "$machdep" >&6; } @@ -17092,6 +17228,37 @@ +# Suppress "extension used" clang warning (when compiling .S files). +if test x$compile_asm = xtrue -a "$GCC" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Wno-language-extension-token" >&5 +$as_echo_n "checking whether compiler supports -Wno-language-extension-token... " >&6; } + old_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wno-language-extension-token" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_lang_ext_token=yes +else + ac_cv_lang_ext_token=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$old_CFLAGS" + if test "$ac_cv_lang_ext_token" = yes; then : + CFLAGS="$CFLAGS -Wno-language-extension-token" +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lang_ext_token" >&5 +$as_echo "$ac_cv_lang_ext_token" >&6; } +fi + # Check whether --with-target-subdir was given. if test "${with_target_subdir+set}" = set; then : @@ -17170,6 +17337,14 @@ ;; esac fi + if test x"enable_gcj_support" != xno; then + ENABLE_GCJ_SUPPORT_TRUE= + ENABLE_GCJ_SUPPORT_FALSE='#' +else + ENABLE_GCJ_SUPPORT_TRUE='#' + ENABLE_GCJ_SUPPORT_FALSE= +fi + # Check whether --enable-sigrt-signals was given. if test "${enable_sigrt_signals+set}" = set; then : @@ -17288,6 +17463,38 @@ fi +# Check whether a compiler warning of unsafe __builtin_return_address(1) +# could be suppressed by -Wno-frame-address option. +# __builtin_return_address(1) is used by libgc for debugging purposes only. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wno-frame-address works" >&5 +$as_echo_n "checking whether -Wno-frame-address works... " >&6; } +use_wno_error_frame_address=no +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror -Wno-frame-address $CFLAGS_EXTRA" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +{ + if (!__builtin_return_address(1)) return 1; +} + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + use_wno_error_frame_address=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_wno_error_frame_address" >&5 +$as_echo "$use_wno_error_frame_address" >&6; } +if test x"$use_wno_error_frame_address" = xyes; then + CFLAGS="$CFLAGS -Wno-frame-address" +fi + # Check for dladdr (used for debugging). { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dladdr" >&5 $as_echo_n "checking for dladdr... " >&6; } @@ -17353,6 +17560,83 @@ conftest$ac_exeext conftest.$ac_ext CFLAGS="$old_CFLAGS" +# pthread_setname_np, if available, may have 1, 2 or 3 arguments. +if test "$THREADS" = posix; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setname_np" >&5 +$as_echo_n "checking for pthread_setname_np... " >&6; } + old_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $CFLAGS_EXTRA -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pthread.h> +int +main () +{ +pthread_setname_np("thread-name") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (w/o tid)" >&5 +$as_echo "yes (w/o tid)" >&6; } + +$as_echo "#define HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID 1" >>confdefs.h + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pthread.h> +int +main () +{ +pthread_setname_np(pthread_self(), "thread-name-%u", 0) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (with tid and arg)" >&5 +$as_echo "yes (with tid and arg)" >&6; } + +$as_echo "#define HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG 1" >>confdefs.h + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef __CYGWIN__ +#define _GNU_SOURCE 1 +#elif defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) +#define _GNU_SOURCE 1 +#endif +#include <pthread.h> +int +main () +{ +pthread_setname_np(pthread_self(), "thread-name") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (with tid)" >&5 +$as_echo "yes (with tid)" >&6; } + +$as_echo "#define HAVE_PTHREAD_SETNAME_NP_WITH_TID 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$old_CFLAGS" +fi + # Check for AViiON Machines running DGUX ac_is_dgux=no ac_fn_c_check_header_mongrel "$LINENO" "sys/dg_sys_info.h" "ac_cv_header_sys_dg_sys_info_h" "$ac_includes_default" @@ -17610,7 +17894,7 @@ fi if test "$enable_gcov" = "yes"; then - CFLAGS="$CFLAGS --coverage" + CFLAGS="-D NTHREADS=20 $CFLAGS --coverage" if test "${enable_shared}" = no; then # FIXME: As of g++-4.8.4/x86_64, in case of shared library build, test_cpp # linkage fails with "hidden symbol atexit is referenced by DSO" message. @@ -17898,18 +18182,10 @@ # If the option is omitted, pthread_atfork handlers are installed # by default for the targets where pthread_atfork is known to work. case "$host" in - *-*-android*) - # Android NDK does not provide pthread_atfork. - ;; *-*-darwin*) - # The incremental mode (which is off if parallel marking) conflicts - # with fork handling on Darwin. - if test x$use_parallel_mark != xno; then - $as_echo "#define HANDLE_FORK 1" >>confdefs.h - - fi + # The incremental mode conflicts with fork handling on Darwin. ;; - *-*-aix* | *-*-cygwin* | *-*-freebsd* | *-*-haiku* | \ + *-*-aix* | *-*-android* | *-*-cygwin* | *-*-freebsd* | *-*-haiku* | \ *-*-hpux11* | *-*-irix* | *-*-kfreebsd*-gnu | \ *-*-*linux* | *-*-netbsd* | *-*-openbsd* | *-*-osf* | *-*-solaris*) $as_echo "#define HANDLE_FORK 1" >>confdefs.h @@ -18070,6 +18346,10 @@ as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${EMSCRIPTEN_TRUE}" && test -z "${EMSCRIPTEN_FALSE}"; then + as_fn_error $? "conditional \"EMSCRIPTEN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${THREADS_TRUE}" && test -z "${THREADS_FALSE}"; then as_fn_error $? "conditional \"THREADS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -18102,6 +18382,14 @@ as_fn_error $? "conditional \"CPLUSPLUS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${GC_TBA_LIBRARY_TRUE}" && test -z "${GC_TBA_LIBRARY_FALSE}"; then + as_fn_error $? "conditional \"GC_TBA_LIBRARY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_GCJ_SUPPORT_TRUE}" && test -z "${ENABLE_GCJ_SUPPORT_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_GCJ_SUPPORT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MAKE_BACK_GRAPH_TRUE}" && test -z "${MAKE_BACK_GRAPH_FALSE}"; then as_fn_error $? "conditional \"MAKE_BACK_GRAPH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -18543,7 +18831,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by gc $as_me 8.0.6, which was +This file was extended by gc $as_me 8.2.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18609,7 +18897,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/\\""\`\$/\\\\&/g'`" ac_cs_version="\\ -gc config.status 8.0.6 +gc config.status 8.2.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -18728,7 +19016,7 @@ # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -19729,29 +20017,35 @@ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*^/\)//*^/^/*/*$' \| \ - X"$mf" : 'X\(//\)^/' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*^/\)//*^/^/*/*$' \| \ + X"$am_mf" : 'X\(//\)^/' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*^/\)\/\/*^/^/*\/*$/{ s//\1/ q @@ -19769,53 +20063,50 @@ q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*^/\)//*^/^/*/*$' \| \ - X"$file" : 'X\(//\)^/' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*^/\)\/\/*^/^/*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)^/.*/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\(^/^/*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\(^/^/*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)$/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; "libtool":C)
View file
_service:tar_scm:gc-8.0.6.tar.gz/configure.ac -> _service:tar_scm:gc-8.2.2.tar.gz/configure.ac
Changed
@@ -1,6 +1,6 @@ # Copyright (c) 1999-2001 by Red Hat, Inc. All rights reserved. # Copyright (c) 2005-2009 Hewlett-Packard Development Company, L.P. -# Copyright (c) 2009-2019 Ivan Maidanski +# Copyright (c) 2009-2021 Ivan Maidanski # # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED # OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -14,7 +14,7 @@ dnl Process this file with autoconf to produce configure. dnl Initialization. -AC_INIT(gc,8.0.6,https://github.com/ivmai/bdwgc/issues) +AC_INIT(gc,8.2.2,https://github.com/ivmai/bdwgc/issues) dnl Version must conform to: 0-9+.0-9+.0-9+ AC_CONFIG_SRCDIR(gcj_mlc.c) @@ -42,8 +42,8 @@ # Special CFLAGS to use when building gc_cflags="" -# gc_use_mmap Set to "yes" on platforms where mmap should be used instead -# of sbrk. This will define USE_MMAP. +# Set to "yes" on platforms where mmap should be used instead of sbrk. +# This will define USE_MMAP. gc_use_mmap="" # We should set -fexceptions if we are using gcc and might be used @@ -62,13 +62,6 @@ esac fi -case "${host}" in - *-linux*) - # FIXME: This seems to be no longer needed as configured in gcconfig.h - #gc_use_mmap=yes - ;; -esac - # target_optspace --enable-target-optspace ("yes", "no", "") case "${target_optspace}:${host}" in yes:*) @@ -91,6 +84,18 @@ ;; esac +AC_MSG_CHECKING(for emscripten) +AC_COMPILE_IFELSE(AC_LANG_SOURCE( +#ifdef __EMSCRIPTEN__ +#error "this is emscripten" +#endif +), emscripten=no, emscripten=yes) +# Note -s ASYNCIFY is required to scan the stack, ASYNCIFY_STACK_SIZE is +# probably needed for gctest only. +AS_IF(test "x$emscripten" = "xyes", + gc_cflags="${gc_cflags} -s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000") +AM_CONDITIONAL(EMSCRIPTEN, test x$emscripten = xyes) +AC_MSG_RESULT($emscripten) GC_CFLAGS=${gc_cflags} AC_SUBST(GC_CFLAGS) @@ -99,11 +104,11 @@ AC_SUBST(CFLAGS_EXTRA) AC_ARG_ENABLE(threads, - AC_HELP_STRING(--enable-threads=TYPE, choose threading package), + AS_HELP_STRING(--enable-threads=TYPE, choose threading package), THREADS=$enableval, AC_MSG_CHECKING(for thread model used by GCC) THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` - if test -z "$THREADS"; then + if test -z "$THREADS" -o "x$emscripten" = "xyes"; then THREADS=no fi if test "$THREADS" = "posix"; then @@ -117,28 +122,28 @@ AC_MSG_RESULT($THREADS) ) AC_ARG_ENABLE(parallel-mark, - AC_HELP_STRING(--disable-parallel-mark, + AS_HELP_STRING(--disable-parallel-mark, do not parallelize marking and free list construction), - case "$THREADS" in + case "$THREADS" in no | none | single) if test "${enable_parallel_mark}" != no; then AC_MSG_ERROR(Parallel mark requires --enable-threads=x spec) fi ;; - esac + esac ) AC_ARG_ENABLE(thread-local-alloc, - AS_HELP_STRING(--disable-thread-local-alloc, + AS_HELP_STRING(--disable-thread-local-alloc, turn off thread-local allocation optimization), - case "$THREADS" in + case "$THREADS" in no | none | single) if test "${enable_thread_local_alloc}" = yes; then AC_MSG_ERROR( Thread-local allocation requires --enable-threads=x spec) fi ;; - esac) + esac) AC_ARG_ENABLE(threads-discovery, AS_HELP_STRING(--disable-threads-discovery, @@ -149,7 +154,7 @@ fi AC_ARG_ENABLE(cplusplus, - AC_HELP_STRING(--enable-cplusplus, install C++ support)) + AS_HELP_STRING(--enable-cplusplus, install C++ support)) dnl Features which may be selected in the following thread-detection switch. AH_TEMPLATE(PARALLEL_MARK, Define to enable parallel marking.) @@ -186,6 +191,8 @@ THREADDLLIBS= need_atomic_ops_asm=false +need_lib_rt=false +compile_asm=false use_parallel_mark=no use_thread_local_alloc=no # Libraries needed to support dynamic loading and/or threads. @@ -216,8 +223,9 @@ *-*-hpux11*) AC_MSG_WARN("Only HP/UX 11 POSIX threads are supported.") AC_DEFINE(_POSIX_C_SOURCE,199506L) - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" # HPUX needs REENTRANT for the _r calls. + need_lib_rt=true ;; *-*-openbsd*) AM_CFLAGS="$AM_CFLAGS -pthread" @@ -236,10 +244,12 @@ *-*-netbsd*) AC_MSG_WARN("Only on NetBSD 2.0 or later.") AC_DEFINE(_PTHREADS) - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" + need_lib_rt=true ;; *-*-solaris*) - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" + need_lib_rt=true ;; *-*-cygwin* | *-*-msys*) # Cygwin doesn't have a real libpthread, so Libtool can't link @@ -260,7 +270,8 @@ ;; *-*-osf*) AM_CFLAGS="$AM_CFLAGS -pthread" - THREADDLLIBS="-lpthread -lrt" + THREADDLLIBS="-lpthread" + need_lib_rt=true ;; *) AS_IF(test x$default_threadlibs != xtrue, @@ -277,7 +288,7 @@ ;; esac ;; - win32) + mcf | win32) AC_DEFINE(GC_THREADS) use_parallel_mark=$enable_parallel_mark if test "${enable_parallel_mark}" != no \ @@ -295,8 +306,6 @@ ;; dgux386) AC_DEFINE(GC_THREADS) - THREADS=dgux386 - AC_MSG_RESULT($THREADDLLIBS) # Use pthread GCC switch THREADDLLIBS=-pthread use_parallel_mark=$enable_parallel_mark @@ -325,7 +334,22 @@ AC_MSG_ERROR($THREADS is an unknown thread package) ;; esac + +# Check whether -lrt linker option is needed to use clock_gettime. +if test "x$need_lib_rt" != xtrue; then + AC_MSG_CHECKING(for clock_gettime without additional libraries) + AC_LINK_IFELSE(AC_LANG_PROGRAM(#include <time.h>, + struct timespec t; clock_gettime(CLOCK_REALTIME, &t)), + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no) + AC_CHECK_LIB(rt, clock_gettime, need_lib_rt=true)) +fi + +if test "x$need_lib_rt" = xtrue; then + THREADDLLIBS="$THREADDLLIBS -lrt" +fi AC_SUBST(THREADDLLIBS) + AM_CONDITIONAL(THREADS, test x$THREADS != xnone) AM_CONDITIONAL(PTHREADS, test x$THREADS = xposix) AM_CONDITIONAL(DARWIN_THREADS, test x$darwin_threads = xtrue) @@ -494,6 +518,13 @@ AM_CONDITIONAL(CPLUSPLUS, test "${enable_cplusplus}" = yes) +AC_ARG_ENABLE(throw-bad-alloc-library, + AS_HELP_STRING(--disable-throw-bad-alloc-library, + do not build C++ gctba library)) +AM_CONDITIONAL(GC_TBA_LIBRARY, + test "${enable_cplusplus}" = yes \ + -a "${enable_throw_bad_alloc_library}" != no) + if test "$GCC" = yes; then if test "${enable_cplusplus}" = yes; then case "$host" in @@ -532,7 +563,7 @@ AC_MSG_RESULT($enable_shared) # Compile with GC_DLL defined unless building static libraries. -if test "${enable_shared}" = yes -a "${enable_static}" = no; then +if test "${enable_shared}" != no -a "${enable_static}" != yes; then AC_DEFINE(GC_DLL) if test "$GCC" = yes; then # Pass -fvisibility=hidden option if supported @@ -551,6 +582,9 @@ case "$host" in *-*-cygwin* | *-*-mingw* | *-*-msys*) + # Do not require the clients to link with "user32" system library. + AC_DEFINE(DONT_USE_USER32_DLL, 1, + Do not use user32.dll import library (Win32).) # Use inline version of GC new and delete operators in test_cpp # otherwise the system ones might be used instead because of arbitrary # ordering of object files when linking. @@ -575,31 +609,27 @@ AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED, 1, See the comment in gcconfig.h.) ;; - mips-*-*) - dnl AC_DEFINE(NO_EXECUTE_PERMISSION) - dnl This is now redundant, but it is also important for incremental GC - dnl performance under Irix. - ;; sparc-*-netbsd*) machdep="sparc_netbsd_mach_dep.lo" + compile_asm=true ;; sparc*-*-linux* | sparc*-*-openbsd* | sparc64-*-freebsd* | sparc64-*-netbsd*) machdep="sparc_mach_dep.lo" + compile_asm=true ;; sparc-sun-solaris2.3) machdep="sparc_mach_dep.lo" + compile_asm=true AC_DEFINE(SUNOS53_SHARED_LIB, 1, Define to work around a Solaris 5.3 bug (see dyn_load.c).) ;; sparc*-sun-solaris2*) machdep="sparc_mach_dep.lo" + compile_asm=true ;; ia64-*-*) machdep="ia64_save_regs_in_stack.lo" ;; - *-*-nacl*) - AC_DEFINE(NO_EXECUTE_PERMISSION) - ;; esac AC_MSG_RESULT($machdep) addobjs="$addobjs $machdep" @@ -608,6 +638,19 @@ AC_PROG_LIBTOOL +# Suppress "extension used" clang warning (when compiling .S files). +if test x$compile_asm = xtrue -a "$GCC" = yes; then + AC_MSG_CHECKING(whether compiler supports -Wno-language-extension-token) + old_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror -Wno-language-extension-token" + AC_COMPILE_IFELSE(AC_LANG_PROGRAM(, ), + ac_cv_lang_ext_token=yes, ac_cv_lang_ext_token=no) + CFLAGS="$old_CFLAGS" + AS_IF(test "$ac_cv_lang_ext_token" = yes, + CFLAGS="$CFLAGS -Wno-language-extension-token") + AC_MSG_RESULT($ac_cv_lang_ext_token) +fi + dnl We use these options to decide which functions to include. AC_ARG_WITH(target-subdir, --with-target-subdir=SUBDIR @@ -665,9 +708,8 @@ dnl ------------------- dnl dnl By default, make the library as general as possible. -dnl enable_gcj_support=no AC_ARG_ENABLE(gcj-support, - AC_HELP_STRING(--disable-gcj-support, disable support for gcj)) + AS_HELP_STRING(--disable-gcj-support, disable support for gcj)) if test x"$enable_gcj_support" != xno; then AC_DEFINE(GC_GCJ_SUPPORT, 1, Define to include support for gcj.) case "$host" in @@ -684,10 +726,11 @@ ;; esac fi +AM_CONDITIONAL(ENABLE_GCJ_SUPPORT, test x"enable_gcj_support" != xno) dnl Interaction with other programs that might use signals. AC_ARG_ENABLE(sigrt-signals, - AC_HELP_STRING(--enable-sigrt-signals, + AS_HELP_STRING(--enable-sigrt-signals, force GC to use SIGRTMIN-based signals for thread suspend/resume)) if test x"${enable_sigrt_signals}" = xyes; then AC_DEFINE(GC_USESIGRT_SIGNALS, 1, @@ -706,8 +749,8 @@ debugging API.) UNWINDLIBS= AC_ARG_ENABLE(gc-debug, -AC_HELP_STRING(--enable-gc-debug, - include full support for pointer backtracing etc.), + AS_HELP_STRING(--enable-gc-debug, + include full support for pointer backtracing etc.), if test "$enable_gc_debug" = "yes"; then AC_MSG_WARN("Should define GC_DEBUG and use debug alloc in clients.") AC_DEFINE(KEEP_BACK_PTRS, 1, @@ -742,6 +785,22 @@ AM_CONDITIONAL(MAKE_BACK_GRAPH, test x"$enable_gc_debug" = xyes) AM_CONDITIONAL(KEEP_BACK_PTRS, test x"$keep_back_ptrs" = xtrue) +# Check whether a compiler warning of unsafe __builtin_return_address(1) +# could be suppressed by -Wno-frame-address option. +# __builtin_return_address(1) is used by libgc for debugging purposes only. +AC_MSG_CHECKING(whether -Wno-frame-address works) +use_wno_error_frame_address=no +old_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror -Wno-frame-address $CFLAGS_EXTRA" +AC_TRY_COMPILE(, { + if (!__builtin_return_address(1)) return 1; +}, use_wno_error_frame_address=yes ) +CFLAGS="$old_CFLAGS" +AC_MSG_RESULT($use_wno_error_frame_address) +if test x"$use_wno_error_frame_address" = xyes; then + CFLAGS="$CFLAGS -Wno-frame-address" +fi + # Check for dladdr (used for debugging). AC_MSG_CHECKING(for dladdr) have_dladdr=no @@ -770,6 +829,37 @@ AC_DEFINE(GC_NO_SIGSETJMP, 1, Missing sigsetjmp function.)) CFLAGS="$old_CFLAGS" +# pthread_setname_np, if available, may have 1, 2 or 3 arguments. +AS_IF(test "$THREADS" = posix, + AC_MSG_CHECKING(for pthread_setname_np) + old_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $CFLAGS_EXTRA -Werror" + AC_TRY_COMPILE(#include <pthread.h>, + pthread_setname_np("thread-name"), + AC_MSG_RESULT(yes (w/o tid)) + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID, 1, + Define to use 'pthread_setname_np(const char*)' function.), + AC_TRY_COMPILE(#include <pthread.h>, + pthread_setname_np(pthread_self(), "thread-name-%u", 0), + AC_MSG_RESULT(yes (with tid and arg)) + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG, 1, + Define to use 'pthread_setname_np(pthread_t, const char*, void *)' + function.), + AC_TRY_COMPILE( +#ifdef __CYGWIN__ +#define _GNU_SOURCE 1 +#elif defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) +#define _GNU_SOURCE 1 +#endif +#include <pthread.h>, + pthread_setname_np(pthread_self(), "thread-name"), + AC_MSG_RESULT(yes (with tid)) + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP_WITH_TID, 1, + Define to use 'pthread_setname_np(pthread_t, const char*)' + function.), + AC_MSG_RESULT(no)))) + CFLAGS="$old_CFLAGS") + # Check for AViiON Machines running DGUX ac_is_dgux=no AC_CHECK_HEADER(sys/dg_sys_info.h, @@ -789,14 +879,14 @@ fi AC_ARG_ENABLE(java-finalization, - AC_HELP_STRING(--disable-java-finalization, + AS_HELP_STRING(--disable-java-finalization, disable support for java finalization)) if test x"$enable_java_finalization" != xno; then AC_DEFINE(JAVA_FINALIZATION, 1, See doc/README.macros.) fi AC_ARG_ENABLE(atomic-uncollectable, - AC_HELP_STRING(--disable-atomic-uncollectible, + AS_HELP_STRING(--disable-atomic-uncollectible, disable support for atomic uncollectible allocation)) if test x"$enable_atomic_uncollectible" != x"no"; then AC_DEFINE(GC_ATOMIC_UNCOLLECTABLE, 1, @@ -804,7 +894,7 @@ fi AC_ARG_ENABLE(redirect-malloc, - AC_HELP_STRING(--enable-redirect-malloc, + AS_HELP_STRING(--enable-redirect-malloc, redirect malloc and friends to GC routines)) if test "${enable_redirect_malloc}" = yes; then @@ -822,7 +912,7 @@ fi AC_ARG_ENABLE(disclaim, - AC_HELP_STRING(--disable-disclaim, + AS_HELP_STRING(--disable-disclaim, disable alternative (more efficient) finalization interface)) if test x"$enable_disclaim" != xno; then AC_DEFINE(ENABLE_DISCLAIM, 1, @@ -832,7 +922,7 @@ test x"$enable_disclaim" != xno) AC_ARG_ENABLE(large-config, - AC_HELP_STRING(--enable-large-config, + AS_HELP_STRING(--enable-large-config, optimize for large (> 100 MB) heap or root set)) if test "${enable_large_config}" = yes; then AC_DEFINE(LARGE_CONFIG, 1, @@ -856,7 +946,7 @@ AC_SUBST(UNWINDLIBS) AC_ARG_ENABLE(gc-assertions, - AC_HELP_STRING(--enable-gc-assertions, + AS_HELP_STRING(--enable-gc-assertions, collector-internal assertion checking)) if test "${enable_gc_assertions}" = yes; then AC_DEFINE(GC_ASSERTIONS, 1, @@ -869,7 +959,7 @@ gc_use_mmap=$enableval) AC_ARG_ENABLE(munmap, - AC_HELP_STRING(--enable-munmap=N, + AS_HELP_STRING(--enable-munmap=N, return page to the OS if empty for N collections (default: 6)), MUNMAP_THRESHOLD=$enableval) @@ -944,18 +1034,18 @@ AC_SUBST(WERROR_CFLAGS) AC_ARG_ENABLE(single-obj-compilation, - AC_HELP_STRING(--enable-single-obj-compilation, - compile all libgc source files into single .o - (default: yes if static libraries are disabled)), - , AS_IF(test x"$enable_static" = xno, - enable_single_obj_compilation=yes) ) + AS_HELP_STRING(--enable-single-obj-compilation, + compile all libgc source files into single .o + (default: yes if static libraries are disabled)), + , AS_IF(test x"$enable_static" = xno, + enable_single_obj_compilation=yes) ) AM_CONDITIONAL(SINGLE_GC_OBJ, test x"$enable_single_obj_compilation" = xyes) AC_ARG_ENABLE(gcov, AS_HELP_STRING(--enable-gcov, turn on code coverage analysis)) if test "$enable_gcov" = "yes"; then - CFLAGS="$CFLAGS --coverage" + CFLAGS="-D NTHREADS=20 $CFLAGS --coverage" if test "${enable_shared}" = no; then # FIXME: As of g++-4.8.4/x86_64, in case of shared library build, test_cpp # linkage fails with "hidden symbol atexit is referenced by DSO" message. @@ -967,7 +1057,7 @@ fi AC_ARG_ENABLE(docs, - AC_HELP_STRING(--disable-docs, + AS_HELP_STRING(--disable-docs, do not build and install documentation)) AM_CONDITIONAL(ENABLE_DOCS, test x$enable_docs != xno) @@ -980,7 +1070,7 @@ # found. AC_ARG_WITH(libatomic-ops, AS_HELP_STRING(--with-libatomic-ops=yes|no|check|none, - Use an external libatomic_ops? (default: check; + use an external libatomic_ops? (default: check; none: use compiler intrinsics or no thread support)), , AS_IF(test x"$THREADS" != xnone, with_libatomic_ops=check, with_libatomic_ops=none) ) @@ -1038,7 +1128,7 @@ AC_MSG_RESULT(none) AS_IF(test x"$THREADS" != xnone, AC_DEFINE(GC_BUILTIN_ATOMIC, 1, - Use C11 (GCC) atomic intrinsics instead of + Use GCC atomic intrinsics instead of libatomic_ops primitives.) ) ) AO_TRYLINK_CFLAGS="" , AC_MSG_RESULT(internal) @@ -1098,11 +1188,11 @@ AM_CONDITIONAL(THREAD_LOCAL_ALLOC, test x$use_thread_local_alloc != xno) AC_ARG_ENABLE(handle-fork, - AC_HELP_STRING(--enable-handle-fork=yes|no|auto|manual, - attempt to ensure a usable collector after fork() - in multi-threaded programs (default: auto; - manual: GC_atfork_prepare/parent/child should be - called by the client)) ) + AS_HELP_STRING(--enable-handle-fork=yes|no|auto|manual, + attempt to ensure a usable collector after fork() + in multi-threaded programs (default: auto; + manual: GC_atfork_prepare/parent/child should be + called by the client))) if test "${enable_handle_fork}" = yes; then AC_DEFINE(HANDLE_FORK, 1, Define to install pthread_atfork() handlers by default.) @@ -1113,17 +1203,10 @@ # If the option is omitted, pthread_atfork handlers are installed # by default for the targets where pthread_atfork is known to work. case "$host" in - *-*-android*) - # Android NDK does not provide pthread_atfork. - ;; *-*-darwin*) - # The incremental mode (which is off if parallel marking) conflicts - # with fork handling on Darwin. - if test x$use_parallel_mark != xno; then - AC_DEFINE(HANDLE_FORK) - fi + # The incremental mode conflicts with fork handling on Darwin. ;; - *-*-aix* | *-*-cygwin* | *-*-freebsd* | *-*-haiku* | \ + *-*-aix* | *-*-android* | *-*-cygwin* | *-*-freebsd* | *-*-haiku* | \ *-*-hpux11* | *-*-irix* | *-*-kfreebsd*-gnu | \ *-*-*linux* | *-*-netbsd* | *-*-openbsd* | *-*-osf* | *-*-solaris*) AC_DEFINE(HANDLE_FORK)
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/cord.am -> _service:tar_scm:gc-8.2.2.tar.gz/cord/cord.am
Changed
@@ -3,11 +3,11 @@ # Info (current:revision:age) for the Libtool versioning system. # These numbers should be updated at most once just before the release, # and, optionally, at most once during the development (after the release). -LIBCORD_VER_INFO = 5:0:4 +LIBCORD_VER_INFO = 6:0:5 lib_LTLIBRARIES += libcord.la -libcord_la_LIBADD = $(top_builddir)/libgc.la +libcord_la_LIBADD = libgc.la libcord_la_LDFLAGS = -version-info $(LIBCORD_VER_INFO) -no-undefined libcord_la_CPPFLAGS = $(AM_CPPFLAGS)
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/cordbscs.c -> _service:tar_scm:gc-8.2.2.tar.gz/cord/cordbscs.c
Changed
@@ -816,20 +816,20 @@ if (cur_pos < end_pos) { /* Fill cache and return. */ size_t i; - size_t limit = cur_pos + FUNCTION_BUF_SZ; + size_t limit = FUNCTION_BUF_SZ; CORD_fn fn = f -> fn; void * client_data = f -> client_data; - if (limit > end_pos) { - limit = end_pos; + if (end_pos - cur_pos < FUNCTION_BUF_SZ) { + limit = end_pos - cur_pos; } - for (i = cur_pos; i < limit; i++) { - p0.function_bufi - cur_pos = - (*fn)(i - start_pos, client_data); + for (i = 0; i < limit; i++) { + p0.function_bufi = (*fn)(i + cur_pos - start_pos, + client_data); } p0.cur_start = cur_pos; p0.cur_leaf = p0.function_buf; - p0.cur_end = limit; + p0.cur_end = cur_pos + limit; return; } }
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/cordprnt.c -> _service:tar_scm:gc-8.2.2.tar.gz/cord/cordprnt.c
Changed
@@ -10,6 +10,7 @@ * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. */ + /* An sprintf implementation that understands cords. This is probably */ /* not terribly portable. It assumes an ANSI stdarg.h. It further */ /* assumes that I can make copies of va_list variables, and read */ @@ -43,19 +44,26 @@ #define CONV_RESULT_LEN 50 /* Maximum length of any */ /* conversion with default */ /* width and prec. */ +#if defined(CPPCHECK) +# define MACRO_BLKSTMT_BEGIN { +# define MACRO_BLKSTMT_END } +#else +# define MACRO_BLKSTMT_BEGIN do { +# define MACRO_BLKSTMT_END } while (0) +#endif -#define OUT_OF_MEMORY do { \ +#define OUT_OF_MEMORY MACRO_BLKSTMT_BEGIN \ if (CORD_oom_fn != 0) (*CORD_oom_fn)(); \ fprintf(stderr, "Out of memory\n"); \ abort(); \ - } while (0) + MACRO_BLKSTMT_END static int ec_len(CORD_ec x) { return (int)(CORD_len(x0.ec_cord) + (x0.ec_bufptr - x0.ec_buf)); } -/* Possible nonumeric precision values. */ +/* Possible non-numeric precision values. */ # define NONE -1 # define VARIABLE -2 /* Copy the conversion specification from CORD_pos into the buffer buf */ @@ -66,7 +74,7 @@ /* If width or prec is *, VARIABLE is assigned. */ /* Set *left to 1 if left adjustment flag is present. */ /* Set *long_arg to 1 if long flag ('l' or 'L') is present, or to */ -/* -1 if 'h' is present. */ +/* -1 if 'h' is present, or to 2 if 'z' is present. */ static int extract_conv_spec(CORD_pos source, char *buf, int * width, int *prec, int *left, int * long_arg) { @@ -121,6 +129,10 @@ *long_arg = 1; current_number = 0; break; + case 'z': + *long_arg = 2; + current_number = 0; + break; case 'h': *long_arg = -1; current_number = 0; @@ -225,6 +237,9 @@ int * pos_ptr; pos_ptr = va_arg(args, int *); *pos_ptr = ec_len(result); + } else if (long_arg == 2) { + size_t * pos_ptr = va_arg(args, size_t *); + *pos_ptr = (size_t)(unsigned)ec_len(result); } else if (long_arg > 0) { long * pos_ptr; pos_ptr = va_arg(args, long *); @@ -326,7 +341,9 @@ case 'c': if (long_arg <= 0) { (void) va_arg(args, int); - } else /* long_arg > 0 */ { + } else if (long_arg == 2) { + (void) va_arg(args, size_t); + } else /* long_arg == 1 */ { (void) va_arg(args, long); } break;
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/cordxtra.c -> _service:tar_scm:gc-8.2.2.tar.gz/cord/cordxtra.c
Changed
@@ -573,12 +573,14 @@ return(cl -> dataMOD_LINE_SZ(i)); } -void CORD_lf_close_proc(void * obj, void * client_data CORD_ATTR_UNUSED) -{ +#ifndef GC_NO_FINALIZATION + void CORD_lf_close_proc(void * obj, void * client_data CORD_ATTR_UNUSED) + { if (fclose(((lf_state *)obj) -> lf_file) != 0) { ABORT("CORD_lf_close_proc: fclose failed"); } -} + } +#endif CORD CORD_from_file_lazy_inner(FILE * f, size_t len) { @@ -604,7 +606,9 @@ state -> lf_cachei = 0; } state -> lf_current = 0; - GC_REGISTER_FINALIZER(state, CORD_lf_close_proc, 0, 0, 0); +# ifndef GC_NO_FINALIZATION + GC_REGISTER_FINALIZER(state, CORD_lf_close_proc, 0, 0, 0); +# endif return(CORD_from_fn(CORD_lf_func, state, len)); }
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/tests/cordtest.c -> _service:tar_scm:gc-8.2.2.tar.gz/cord/tests/cordtest.c
Changed
@@ -221,8 +221,10 @@ *(CORD volatile *)&w = CORD_EMPTY; *(CORD volatile *)&z = CORD_EMPTY; GC_gcollect(); - GC_invoke_finalizers(); +# ifndef GC_NO_FINALIZATION + GC_invoke_finalizers(); /* Of course, this does not guarantee the files are closed. */ +# endif if (remove(FNAME1) != 0) { /* On some systems, e.g. OS2, this may fail if f1 is still open. */ /* But we cannot call fclose as it might lead to double close. */ @@ -270,6 +272,8 @@ # endif #endif +/* no static */ /* no const */ char *zu_format = (char*)"%zu"; + void test_printf(void) { CORD result; @@ -277,14 +281,15 @@ long l = -1; short s = (short)-1; CORD x; + int res; if (CORD_sprintf(&result, "%7.2f%ln", 3.14159F, &l) != 7) ABORT("CORD_sprintf failed 1"); - if (CORD_cmp(result, " 3.14") != 0)ABORT("CORD_sprintf goofed 1"); + if (CORD_cmp(result, " 3.14") != 0) ABORT("CORD_sprintf goofed 1"); if (l != 7) ABORT("CORD_sprintf goofed 2"); if (CORD_sprintf(&result, "%-7.2s%hn%c%s", "abcd", &s, 'x', "yz") != 10) ABORT("CORD_sprintf failed 2"); - if (CORD_cmp(result, "ab xyz") != 0)ABORT("CORD_sprintf goofed 3"); + if (CORD_cmp(result, "ab xyz") != 0) ABORT("CORD_sprintf goofed 3"); if (s != 7) ABORT("CORD_sprintf goofed 4"); x = "abcdefghij"; x = CORD_cat(x,x); @@ -299,7 +304,26 @@ (void)sprintf(result2, "->%-120.78s!\n", CORD_to_char_star(x)); # endif result2sizeof(result2) - 1 = '\0'; - if (CORD_cmp(result, result2) != 0)ABORT("CORD_sprintf goofed 5"); + if (CORD_cmp(result, result2) != 0) ABORT("CORD_sprintf goofed 5"); + +# ifdef GC_SNPRINTF + /* Check whether "%zu" specifier is supported; pass the format */ + /* string via a variable to avoid a compiler warning if not. */ + res = GC_SNPRINTF(result2, sizeof(result2), zu_format, (size_t)0); +# else + res = sprintf(result2, zu_format, (size_t)0); +# endif + result2sizeof(result2) - 1 = '\0'; + if (res == 1) /* is "%z" supported by printf? */ { + if (CORD_sprintf(&result, "%zu %zd 0x%0zx", + (size_t)123, (size_t)4567, (size_t)0x4abc) != 15) + ABORT("CORD_sprintf failed 5"); + if (CORD_cmp(result, "123 4567 0x4abc") != 0) + ABORT("CORD_sprintf goofed 5"); + } else { + (void)CORD_printf("printf lacks support of 'z' modifier\n"); + } + /* TODO: Better test CORD_vfprintf. */ (void)CORD_printf(CORD_EMPTY); (void)wrap_vfprintf(stdout, CORD_EMPTY);
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/tests/de.c -> _service:tar_scm:gc-8.2.2.tar.gz/cord/tests/de.c
Changed
@@ -75,10 +75,18 @@ #endif #include "de_cmds.h" -#define OUT_OF_MEMORY do { \ +#if defined(CPPCHECK) +# define MACRO_BLKSTMT_BEGIN { +# define MACRO_BLKSTMT_END } +#else +# define MACRO_BLKSTMT_BEGIN do { +# define MACRO_BLKSTMT_END } while (0) +#endif + +#define OUT_OF_MEMORY MACRO_BLKSTMT_BEGIN \ fprintf(stderr, "Out of memory\n"); \ exit(3); \ - } while (0) + MACRO_BLKSTMT_END /* List of line number to position mappings, in descending order. */ /* There may be holes. */ @@ -375,7 +383,7 @@ } #if defined(WIN32) -# define beep() Beep(1000 /* Hz */, 300 /* msecs */) +# define beep() Beep(1000 /* Hz */, 300 /* ms */) #elif defined(MACINTOSH) # define beep() SysBeep(1) #else
View file
_service:tar_scm:gc-8.0.6.tar.gz/cord/tests/de_win.rc -> _service:tar_scm:gc-8.2.2.tar.gz/cord/tests/de_win.rc
Changed
@@ -4,8 +4,11 @@ * 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 copy this garbage collector for any purpose, - * provided the above notices are retained on all copies. + * 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. */ #include "windows.h"
View file
_service:tar_scm:gc-8.0.6.tar.gz/darwin_stop_world.c -> _service:tar_scm:gc-8.2.2.tar.gz/darwin_stop_world.c
Changed
@@ -73,12 +73,15 @@ __asm__ __volatile__ ("mov %0, x29\n" : "=r" (sp_reg)); frame = (StackFrame *)sp_reg; # else +# if defined(CPPCHECK) + GC_noop1((word)&frame); +# endif ABORT("GC_FindTopOfStack(0) is not implemented"); # endif } # ifdef DEBUG_THREADS_EXTRA - GC_log_printf("FindTopOfStack start at sp = %p\n", (void *)frame); + GC_log_printf("FindTopOfStack start at sp= %p\n", (void *)frame); # endif while (frame->savedSP != 0) { /* if there are no more stack frames, stop */ @@ -92,7 +95,7 @@ break; /* if the next LR is bogus, stop */ } # ifdef DEBUG_THREADS_EXTRA - GC_log_printf("FindTopOfStack finish at sp = %p\n", (void *)frame); + GC_log_printf("FindTopOfStack finish at sp= %p\n", (void *)frame); # endif return (ptr_t)frame; } @@ -204,7 +207,7 @@ } while (kern_result == KERN_ABORTED); } # ifdef DEBUG_THREADS - GC_log_printf("thread_get_state returns value = %d\n", kern_result); + GC_log_printf("thread_get_state returns %d\n", kern_result); # endif if (kern_result != KERN_SUCCESS) ABORT("thread_get_state failed"); @@ -234,7 +237,7 @@ GC_push_one(state.THREAD_FLD(rdi)); GC_push_one(state.THREAD_FLD(rsi)); GC_push_one(state.THREAD_FLD(rbp)); - /* GC_push_one(state.THREAD_FLD(rsp)); */ + /* rsp is skipped. */ GC_push_one(state.THREAD_FLD(r8)); GC_push_one(state.THREAD_FLD(r9)); GC_push_one(state.THREAD_FLD(r10)); @@ -250,6 +253,7 @@ *phi = GC_FindTopOfStack(state.THREAD_FLD(r1)); # endif GC_push_one(state.THREAD_FLD(r0)); + /* r1 is skipped. */ GC_push_one(state.THREAD_FLD(r2)); GC_push_one(state.THREAD_FLD(r3)); GC_push_one(state.THREAD_FLD(r4)); @@ -337,7 +341,7 @@ *paltstack_lo = NULL; } # ifdef DEBUG_THREADS - GC_log_printf("Darwin: Stack for thread %p = %p,%p)\n", + GC_log_printf("Darwin: Stack for thread %p is %p,%p)\n", (void *)(word)thread, (void *)lo, (void *)(*phi)); # endif return lo; @@ -660,6 +664,9 @@ struct thread_basic_info info; mach_msg_type_number_t outCount = THREAD_BASIC_INFO_COUNT; +# ifdef CPPCHECK + info.run_state = 0; +# endif kern_result = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &outCount); if (kern_result != KERN_SUCCESS)
View file
_service:tar_scm:gc-8.0.6.tar.gz/dbg_mlc.c -> _service:tar_scm:gc-8.2.2.tar.gz/dbg_mlc.c
Changed
@@ -247,24 +247,23 @@ out:; } - /* Force a garbage collection and generate/print a backtrace */ - /* from a random heap address. */ - GC_INNER void GC_generate_random_backtrace_no_gc(void) - { - void * current; - current = GC_generate_random_valid_address(); - GC_printf("\n****Chosen address %p in object\n", current); - GC_print_backtrace(current); - } - GC_API void GC_CALL GC_generate_random_backtrace(void) { + void *current; + DCL_LOCK_STATE; + if (GC_try_to_collect(GC_never_stop_func) == 0) { GC_err_printf("Cannot generate a backtrace: " "garbage collection is disabled!\n"); return; } - GC_generate_random_backtrace_no_gc(); + + /* Generate/print a backtrace from a random heap address. */ + LOCK(); + current = GC_generate_random_valid_address(); + UNLOCK(); + GC_printf("\n****Chosen address %p in object\n", current); + GC_print_backtrace(current); } #endif /* KEEP_BACK_PTRS */ @@ -414,14 +413,14 @@ } if (NULL != kind_str) { - GC_err_printf("%p (%s:%d," IF_NOT_SHORTDBG_HDRS(" sz=%lu,") " %s)\n", + GC_err_printf("%p (%s:%d," IF_NOT_SHORTDBG_HDRS(" sz= %lu,") " %s)\n", (void *)((ptr_t)ohdr + sizeof(oh)), ohdr->oh_string, GET_OH_LINENUM(ohdr) /*, */ COMMA_IFNOT_SHORTDBG_HDRS((unsigned long)ohdr->oh_sz), kind_str); } else { - GC_err_printf("%p (%s:%d," IF_NOT_SHORTDBG_HDRS(" sz=%lu,") - " kind=%d descr=0x%lx)\n", + GC_err_printf("%p (%s:%d," IF_NOT_SHORTDBG_HDRS(" sz= %lu,") + " kind= %d, descr= 0x%lx)\n", (void *)((ptr_t)ohdr + sizeof(oh)), ohdr->oh_string, GET_OH_LINENUM(ohdr) /*, */ COMMA_IFNOT_SHORTDBG_HDRS((unsigned long)ohdr->oh_sz), @@ -456,11 +455,11 @@ if ((word)clobbered_addr <= (word)(&ohdr->oh_sz) || ohdr -> oh_string == 0) { GC_err_printf( - "%s %p in or near object at %p(<smashed>, appr. sz = %lu)\n", + "%s %p in or near object at %p(<smashed>, appr. sz= %lu)\n", msg, (void *)clobbered_addr, p, (unsigned long)(GC_size((ptr_t)ohdr) - DEBUG_BYTES)); } else { - GC_err_printf("%s %p in or near object at %p (%s:%d, sz=%lu)\n", + GC_err_printf("%s %p in or near object at %p (%s:%d, sz= %lu)\n", msg, (void *)clobbered_addr, p, (word)(ohdr -> oh_string) < HBLKSIZE ? "(smashed string)" : ohdr -> oh_string0 == '\0' ? "EMPTY(smashed?)" : @@ -489,9 +488,16 @@ GC_print_heap_obj = GC_debug_print_heap_obj_proc; GC_debugging_started = TRUE; GC_register_displacement_inner((word)sizeof(oh)); +# if defined(CPPCHECK) + GC_noop1(GC_debug_header_size); +# endif } -size_t GC_debug_header_size = sizeof(oh); +const size_t GC_debug_header_size = sizeof(oh); + +GC_API size_t GC_CALL GC_get_debug_header_size(void) { + return sizeof(oh); +} GC_API void GC_CALL GC_debug_register_displacement(size_t offset) { @@ -532,7 +538,13 @@ /* Note that according to malloc() specification, if size is 0 then */ /* malloc() returns either NULL, or a unique pointer value that can */ /* later be successfully passed to free(). We always do the latter. */ - result = GC_malloc(SIZET_SAT_ADD(lb, DEBUG_BYTES)); +# if defined(_FORTIFY_SOURCE) && !defined(__clang__) + /* Workaround to avoid "exceeds maximum object size" gcc warning. */ + result = GC_malloc(lb < GC_SIZE_MAX - DEBUG_BYTES ? lb + DEBUG_BYTES + : GC_SIZE_MAX >> 1); +# else + result = GC_malloc(SIZET_SAT_ADD(lb, DEBUG_BYTES)); +# endif # ifdef GC_ADD_CALLER if (s == NULL) { GC_caller_func_offset(ra, &s, &i); @@ -612,13 +624,15 @@ } #endif /* DBG_HDRS_ALL */ -GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS) -{ +#ifndef CPPCHECK + GC_API void * GC_CALL GC_debug_malloc_stubborn(size_t lb, GC_EXTRA_PARAMS) + { return GC_debug_malloc(lb, OPT_RA s, i); -} + } -GC_API void GC_CALL GC_debug_change_stubborn( + GC_API void GC_CALL GC_debug_change_stubborn( const void * p GC_ATTR_UNUSED) {} +#endif /* !CPPCHECK */ GC_API void GC_CALL GC_debug_end_stubborn_change(const void *p) { @@ -768,7 +782,7 @@ ptr_t clobbered = GC_check_annotated_obj((oh *)base); word sz = GC_size(base); if (clobbered != 0) { - GC_have_errors = TRUE; + GC_SET_HAVE_ERRORS(); /* no "release" barrier is needed */ if (((oh *)base) -> oh_sz == sz) { GC_print_smashed_obj( "GC_debug_free: found previously deallocated (?) object at", @@ -781,7 +795,7 @@ } /* Invalidate size (mark the object as deallocated) */ ((oh *)base) -> oh_sz = sz; -# endif /* SHORT_DBG_HDRS */ +# endif /* !SHORT_DBG_HDRS */ } if (GC_find_leak # ifndef SHORT_DBG_HDRS @@ -933,7 +947,7 @@ if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed; /* In case of overflow, we keep the first MAX_SMASHED-1 */ /* entries plus the last one. */ - GC_have_errors = TRUE; + GC_SET_HAVE_ERRORS(); } /* Print all objects on the list. Clear the list. */ @@ -1084,7 +1098,7 @@ void * *ocd) { GC_finalization_proc my_old_fn = OFN_UNSET; - void * my_old_cd; + void * my_old_cd = NULL; /* to avoid "might be uninitialized" warning */ ptr_t base = (ptr_t)GC_base(obj); if (NULL == base) { /* We won't collect it, hence finalizer wouldn't be run. */ @@ -1100,7 +1114,7 @@ GC_register_finalizer(base, 0, 0, &my_old_fn, &my_old_cd); } else { cd = GC_make_closure(fn, cd); - if (cd == 0) return; /* out of memory */ + if (cd == 0) return; /* out of memory; *ofn and *ocd are unchanged */ GC_register_finalizer(base, GC_debug_invoke_finalizer, cd, &my_old_fn, &my_old_cd); } @@ -1113,7 +1127,7 @@ void * *ocd) { GC_finalization_proc my_old_fn = OFN_UNSET; - void * my_old_cd; + void * my_old_cd = NULL; ptr_t base = (ptr_t)GC_base(obj); if (NULL == base) { /* We won't collect it, hence finalizer wouldn't be run. */ @@ -1142,7 +1156,7 @@ void * *ocd) { GC_finalization_proc my_old_fn = OFN_UNSET; - void * my_old_cd; + void * my_old_cd = NULL; ptr_t base = (ptr_t)GC_base(obj); if (NULL == base) { /* We won't collect it, hence finalizer wouldn't be run. */ @@ -1171,7 +1185,7 @@ void * *ocd) { GC_finalization_proc my_old_fn = OFN_UNSET; - void * my_old_cd; + void * my_old_cd = NULL; ptr_t base = (ptr_t)GC_base(obj); if (NULL == base) { /* We won't collect it, hence finalizer wouldn't be run. */
View file
_service:tar_scm:gc-8.0.6.tar.gz/depcomp -> _service:tar_scm:gc-8.2.2.tar.gz/depcomp
Changed
@@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2013-05-30.07; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -783,9 +783,9 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End:
View file
_service:tar_scm:gc-8.0.6.tar.gz/digimars.mak -> _service:tar_scm:gc-8.2.2.tar.gz/digimars.mak
Changed
@@ -22,6 +22,7 @@ fnlz_mlc.obj\ dyn_load.obj\ finalize.obj\ + gc_badalc.obj\ gc_cpp.obj\ gcj_mlc.obj\ headers.obj\ @@ -39,7 +40,13 @@ typd_mlc.obj\ win32_threads.obj -targets: gc.dll gc.lib gctest.exe test_cpp.exe +targets: gc.dll gc.lib + +check: gctest.exe test_cpp.exe + gctest.exe + test_cpp.exe + +gc.lib: gc.dll gc.dll: $(OBJS) gc.def digimars.mak $(CC) -ogc.dll $(OBJS) -L$(LFLAGS) gc.def kernel32.lib user32.lib @@ -77,6 +84,7 @@ dyn_load.obj: dyn_load.c finalize.obj: finalize.c fnlz_mlc.obj: fnlz_mlc.c +gc_badalc.obj: gc_badalc.cc gc_badalc.cpp gc_cpp.obj: gc_cpp.cc gc_cpp.cpp headers.obj: headers.c mach_dep.obj: mach_dep.c
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.Mac -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.Mac
Changed
@@ -3,7 +3,7 @@ --------------------------------------------- -Patrick Beard's Notes for building GC v4.12 with CodeWarrior Pro 2: +Patrick Beard's Notes for building GC with CodeWarrior Pro 2: ---------------------------------------------------------------------------- The current build environment for the collector is CodeWarrior Pro 2. Projects for CodeWarrior Pro 2 (and for quite a few older versions) @@ -24,15 +24,10 @@ porting instructions in pure TEXT form to avoid those problems. A manual 'makefile' if you like. - GC version: 4.12a2 Codewarrior: CWPro1 date: 18 July 1997 -The notes may or may not apply to earlier or later versions of the -GC/CWPro. Actually, they do apply to earlier versions of both except that -until recently a project could only build one target so each target was a -separate project. The notes will most likely apply to future versions too. -Possibly with minor tweaks. +The notes may or may not apply to earlier or later versions of the CWPro. This is just to record my experiences. These notes do not mean I now provide a supported port of the GC to MacOS. It works for me. If it works @@ -204,9 +199,10 @@ checksums.c dbg_mlc.c finalize.c + fnlz_mlc.c headers.c mach_dep.c - MacOS.c -- contains MacOS code + extra/MacOS.c -- contains MacOS code malloc.c mallocx.c mark.c @@ -218,9 +214,8 @@ ptr_chck.c reclaim.c typd_mlc.c - gc++.cc -- this is 'gc_cpp.cc' with less 'inline' and - -- throw std::bad_alloc when out of memory - -- gc_cpp.cc works just fine too + gc_badalc.cc + gc_cpp.cc == 2. Test that the library works with 'test.c' == @@ -291,7 +286,7 @@ Patrick Beard's instructions (may be dated): -v4.3 of the collector now runs under Symantec C++/THINK C v7.0.4, and +The collector should run under Symantec C++/THINK C v7.0.4, and Metrowerks C/C++ v4.5 both 68K and PowerPC. Project files are provided to build and test the collector under both development systems. @@ -315,7 +310,7 @@ systems are provided. For Symantec C++/THINK C, you must build the two projects gclib-1 and -gclib-2. It has to be split up because the collector has more than 32k +gclib-2. It has to be split up because the collector has more than 32 KB of static data and no library can have more than this in the Symantec environment. (Future versions will probably fix this.)
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.amiga -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.amiga
Changed
@@ -24,7 +24,7 @@ Programs using more time actually using the memory allocated (instead of just allocate and free rapidly) have the most to earn on this, but even gctest now normally runs twice - as fast and uses less memory, on my poor 8MB machine. + as fast and uses less memory, on my poor 8 MB machine. The changes have only effect when there is no more fast-mem left. But with the way GC works, it @@ -187,18 +187,16 @@ In addition to Jesper's notes, I have the following to say: -- Starting with version 4.3, gctest checks to see if the code segment is - added to the root set or not, and complains if it is. Previous versions - of this Amiga port added the code segment to the root set, so I tried to - fix that. The only problem is that, as far as I know, it is impossible to - know which segments are code segments and which are data segments (there - are indeed solutions to this problem, like scanning the program on disk - or patch the LoadSeg functions, but they are rather complicated). The - solution I have chosen (see os_dep.c) is to test whether the program - counter is in the segment we are about to add to the root set, and if it - is, to skip the segment. The problems are that this solution is rather - awkward and that it works only for one code segment. This means that if - your program has more than one code segment, all of them but one will be +- gctest checks to see if the code segment is added to the root set or not, + and complains if it is. The only problem is that, as far as I know, it is + impossible to know which segments are code segments and which are data + segments (there are indeed solutions to this problem, like scanning the + program on disk or patch the LoadSeg functions, but they are rather + complicated). The solution I have chosen (see os_dep.c) is to test whether + the program counter is in the segment we are about to add to the root set, + and if it is, to skip the segment. The problems are that this solution is + rather awkward and that it works only for one code segment. This means that + if your program has more than one code segment, all of them but one will be added to the root set. This isn't a big problem in fact, since the collector will continue to work correctly, but it may be slower. @@ -281,8 +279,6 @@ The library as it stands is compatible with the GigaMem commercial virtual memory software, and probably similar PD software. -The performance of "gctest" on an Amiga 2630 (68030 @ 25Mhz) +The performance of "gctest" on an Amiga 2630 (68030 @ 25 MHz) compares favorably with an HP9000 with similar architecture (a 325 with a 68030 I think). - ------------------------------------------------------------------------
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.arm.cross -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.arm.cross
Changed
@@ -7,21 +7,21 @@ The badge4 has a StrongArm-1110 processor and a StrongArm-1111 coprocessor. -Assume that the garbage collector distribution is unpacked into /home/arm/gc6.0, +Assume that the garbage collector distribution is unpacked into /home/arm/gc, which is visible to both the ARM machine and a linux desktop (e.g. via NFS mounting). Assume that you have a file /home/arm/config.site with contents something like the example attached below. Notice that our local ARM toolchain lives in /skiff/local. -Go to /home/arm/gc6.0 directory. Do +Go to /home/arm/gc directory. Do CONFIG_SITE=/home/arm/config.site ./configure --target=arm-linux ---prefix=/home/arm/gc6.0 +--prefix=/home/arm/gc On your desktop, do: make make install -The main garbage collector library should now be in ../gc6.0/lib/libgc.so. +The main garbage collector library should now be in ../gc/lib/libgc.so. To test the garbage collector, first do the following on your desktop make gctest @@ -30,7 +30,7 @@ cd .libs ./lt-gctest -Do not try to do "make test" (the usual way of running the test +Do not try to do "make check" (the usual way of running the test program). This does not work and seems to erase some of the important files.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.autoconf -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.autoconf
Changed
@@ -1,6 +1,5 @@ -Starting from GC v6.0, we support GNU-style builds based on automake, -autoconf and libtool. This is based almost entirely on Tom Tromey's work -with gcj. +We support GNU-style builds based on automake, autoconf and libtool. +This is based almost entirely on Tom Tromey's work with gcj. To build and install libraries use @@ -52,8 +51,9 @@ Unless --prefix is set (or --exec-prefix or one of the more obscure options), -make install will install libgc.a and libgc.so in /usr/local/bin, which -would typically require the "make install" to be run as root. +"make install" will install libgc.a and libgc.so in /usr/local/lib and +/usr/local/bin, respectively, which would typically require the "make install" +to be run as root. It is not recommended to turn off parallel marking for multiprocessors unless a poor support of the feature on the platform.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.cmake -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.cmake
Changed
@@ -2,27 +2,22 @@ CMAKE ----- -Win32 binaries (both 32- and 64-bit) can be built using CMake. CMake is an -open-source tool like automake - it generates makefiles. - -Some preliminary work has been done to make this work on other platforms, but -the support is not yet complete. - -CMake will generate: +Unix and Win32 binaries (both 32- and 64-bit) can be built using CMake. +CMake is an open-source tool like automake - it generates makefiles. +CMake v3.14.5 is able to generate: Borland Makefiles MSYS Makefiles MinGW Makefiles NMake Makefiles Unix Makefiles - . Visual Studio project files - Visual Studio 6 - Visual Studio 7 - Visual Studio 7 .NET 2003 - Visual Studio 8 2005 - Visual Studio 8 2005 Win64 - Visual Studio 9 2008 - Visual Studio 9 2008 Win64 + Visual Studio 16 2019 + Visual Studio 15 2017 + Visual Studio 14 2015 + Visual Studio 12 2013 + Visual Studio 11 2012 + Visual Studio 10 2010 + Visual Studio 9 2008 Watcom WMake @@ -33,18 +28,35 @@ . add directory containing cmake.exe to %PATH% . run cmake from the gc root directory, passing the target with -G: e.g., - > cmake -G "Visual Studio 8 2005" + > cmake -G "Visual Studio 9 2008" . use the gc.sln file generated by cmake to build gc + . specify -Denable_cplusplus=ON option to build gccpp (GC C++ support) + . specify -Dbuild_tests=ON option to the tests (and run them by "ctest -V") . you can also run cmake from a build directory to build outside of the source tree. Just specify the path to the source tree: e.g., - > mkdir build - > cd build - > cmake .. -G "Visual Studio 8 2005" + > mkdir out + > cd out + > cmake -G "Visual Studio 9 2008" .. + > cmake --build . --config Release + > ctest --build-config Release -V INPUT ----- -The main input to cmake are the CMakeLists.txt files in each directory. For +The main input to cmake is CMakeLists.txt file in the GC root directory. For help, go to cmake.org. + + +HOW TO IMPORT BDWGC +------------------- + +Another project could add bdwgc as one of its dependencies with something like +this in their CMakeLists.txt: + +find_package(BDWgc 8.2.2 REQUIRED) +add_executable(Foo foo.c) +target_link_libraries(Foo BDWgc::gc) + +Other exported libraries are: cord, gccpp, gctba.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.cords -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.cords
Changed
@@ -36,7 +36,7 @@ arguments. Note that ^R^N and ^R^P move the cursor by almost a screen. It does not understand tabs, which will show up as highlighted "I"s. Use the UNIX "expand" program first.) -To build the editor, type "make cord/de" in the gc directory. +To build the editor, type "make de" in the gc directory. Note that CORD_printf and friends use C functions with variable numbers of arguments in non-standard-conforming ways. This code is known to
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.darwin -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.darwin
Changed
@@ -11,18 +11,18 @@ == Important Usage Notes == -GC_init() MUST be called before calling any other GC functions. This +GC_INIT() MUST be called before calling any other GC functions. This is necessary to properly register segments in dynamic libraries. This call is required even if you code does not use dynamic libraries as the dyld code handles registering all data segments. When your use of the garbage collector is confined to dylibs and you -cannot call GC_init() before your libraries' static initializers have +cannot call GC_INIT() before your libraries' static initializers have run and perhaps called GC_malloc(), create an initialization routine -for each library to call GC_init(): +for each library to call GC_INIT(), e.g.: #include "gc.h" -extern "C" void my_library_init() { GC_init(); } +extern "C" void my_library_init() { GC_INIT(); } Compile this code into a my_library_init.o, and link it into your dylib. When you link the dylib, pass the -init argument with @@ -31,10 +31,10 @@ my_library_init() to be called before any static initializers, and will initialize the garbage collector properly. -Note: It doesn't hurt to call GC_init() more than once, so it's best, +Note: It doesn't hurt to call GC_INIT() more than once, so it's best, if you have an application or set of libraries that all use the garbage collector, to create an initialization routine for each of -them that calls GC_init(). Better safe than sorry. +them that calls GC_INIT(). Better safe than sorry. Thread-local GC allocation will not work with threads that are not created using the GC-provided override of pthread_create(). Threads
View file
_service:tar_scm:gc-8.2.2.tar.gz/doc/README.emscripten
Added
@@ -0,0 +1,15 @@ + +The build system (at least autotools-based) should detect and configure +emscripten correctly. + +As of now, gctest almost passes, except for the tests that involve a_get(). + +No thread support for now. No idea how to stop other threads (perhaps we need +support from JS side). + +How to build: + + # source EMSDK first + emconfigure ./configure + emmake make gctest.html + # point your browser at .libs/gctest.html
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.environment -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.environment
Changed
@@ -104,13 +104,13 @@ was turned into a runtime flag to enable last-minute work-arounds. "0" value means "do not retry signals". -GC_USE_GETWRITEWATCH=<n> - Only if MPROTECT_VDB and GWW_VDB are both defined - (Win32 only). Explicitly specify which strategy of - keeping track of dirtied pages should be used. - If n=0 then GetWriteWatch() is not used (falling back to - protecting pages and catching memory faults strategy) - else the collector tries to use GetWriteWatch-based - strategy (GWW_VDB) first if available. +GC_USE_GETWRITEWATCH=<n> - Only if MPROTECT_VDB and (GWW_VDB or SOFT_VDB) are + both defined (Win32 and Linux only). Explicitly specify + which strategy of keeping track of dirtied pages should + be used. If n=0, then fall back to protecting pages and + catching memory faults strategy), else the collector + tries to use GetWriteWatch-based strategy (GWW_VDB) or + soft-dirty bits strategy (SOFT_VDB) first if available. GC_DISABLE_INCREMENTAL - Ignore runtime requests to enable incremental GC. Useful for debugging. @@ -127,17 +127,17 @@ to be transparent, it may cause unintended system call failures. Use with caution. -GC_PAUSE_TIME_TARGET - Set the desired garbage collector pause time in msecs. - This only has an effect if incremental collection is - enabled. If a collection requires appreciably more time - than this, the client will be restarted, and the collector - will need to do additional work to compensate. The - special value "999999" indicates that pause time is - unlimited, and the incremental collector will behave - completely like a simple generational collector. If - the collector is configured for parallel marking, and - run on a multiprocessor, incremental collection should - only be used with unlimited pause time. +GC_PAUSE_TIME_TARGET - Set the desired garbage collector pause time in + milliseconds (ms). This only has an effect if incremental + collection is enabled. If a collection requires + appreciably more time than this, the client will be + restarted, and the collector will need to do additional + work to compensate. The special value "999999" indicates + that pause time is unlimited, and the incremental + collector will behave completely like a simple + generational collector. Any value, except for the given + special one, disables parallel marker (almost fully) for + now. GC_FULL_FREQUENCY - Set the desired number of partial collections between full collections. Matters only if GC_incremental is set.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.hp -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.hp
Changed
@@ -15,4 +15,4 @@ work in combination with it. The stack finding code can be confused by putenv calls before collector -initialization. Call GC_malloc or GC_init before any putenv calls. +initialization. Call GC_malloc() or GC_INIT() before any putenv() calls.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.linux -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.linux
Changed
@@ -1,7 +1,7 @@ See README.alpha for Linux on DEC AXP info. -This file applies mostly to Linux/Intel IA32. Ports to Linux on an M68K, -IA64, SPARC, MIPS, Alpha and PowerPC are integrated too. They should behave +This file applies mostly to Linux/Intel IA-32. Ports to Linux on an M68K, +IA-64, SPARC, MIPS, Alpha and PowerPC are integrated too. They should behave similarly, except that the PowerPC port lacks incremental GC support, and it is unknown to what extent the Linux threads code is functional. See below for M68K specific notes. @@ -26,11 +26,11 @@ MIT pthreads). 2) You must compile the collector with "-DGC_THREADS -D_REENTRANT" specified - in the Makefile. + in the Makefile.direct file. 3a) Every file that makes thread calls should define GC_THREADS, and then - include gc.h. Gc.h redefines some of the pthread primitives as macros - which also provide the collector with information it requires. + include gc.h. The latter redefines some of the pthread primitives as + macros which also provide the collector with information it requires. 3b) A new alternative to (3a) is to build the collector and compile GC clients with -DGC_USE_LD_WRAP, and to link the final program with @@ -60,9 +60,9 @@ collector. This probably depends on the linuxthreads version. For the time being, any collectible memory referenced by thread local storage should also be referenced from elsewhere, or be allocated as uncollectible. - (This is really a bug that should be fixed somehow. The current GC - version probably gets things right if there are not too many tls locations - and if dlopen is not used.) + (This is really a bug that should be fixed somehow. Actually, the + collector probably gets things right, on Linux at least, if there are not + too many tls locations and if dlopen is not used.) M68K LINUX:
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.macros -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.macros
Changed
@@ -87,12 +87,17 @@ dynamic libraries are used, but the collector is in a static library. Tested by gc_config_macros.h. -GC_REQUIRE_WCSDUP Force GC to export GC_wcsdup() (the Unicode version - of GC_strdup); could be useful in the leak-finding mode. +GC_MARKERS=<n> Set the desired number of marker threads. If not defined or + defined to zero, then the collector decides based on the + number of CPU cores. Only if compiled with PARALLEL_MARK. These define arguments influence the collector configuration: +GC_REQUIRE_WCSDUP Force GC to export GC_wcsdup() (the Unicode version + of GC_strdup); could be useful in the leak-finding mode. Clients should + define it before including gc.h if the function is needed. + FIND_LEAK Causes GC_find_leak to be initially set. This causes the collector to assume that all inaccessible objects should have been explicitly deallocated, and reports exceptions. Finalization and the test @@ -109,19 +114,18 @@ SUNOS5SIGS Solaris-like signal handling. This is probably misnamed, since it really doesn't guarantee much more than POSIX. Currently set only - for Solaris2.X, HPUX, and DRSNX. Should probably be set for some other - platforms. + for DRSNX, FreeBSD, HP/UX and Solaris. PCR Set if the collector is being built as part of the Xerox Portable Common Runtime. -IMPORTANT: Any of the _THREADS options must normally also be defined in - the client before including gc.h. This redefines thread primitives to - invoke the GC_ versions instead. Alternatively, linker-based symbol - interception can be used on a few platforms. - GC_THREADS Should set the appropriate one of the below macros, except GC_WIN32_PTHREADS, which must be set explicitly. Tested by gc.h. + IMPORTANT: GC_THREADS macro (or the relevant platform-specific deprecated + one) must normally also be defined by the client before including gc.h. + This redefines thread primitives to invoke the GC_ wrappers instead. + Alternatively, linker-based symbol interception can be used on a few + platforms. GC_SOLARIS_THREADS Enables support for Solaris pthreads. Must also define _REENTRANT. Deprecated, use GC_THREADS instead. @@ -159,8 +163,7 @@ See README.DGUX386. (Probably has not been tested recently.) Deprecated, use GC_THREADS instead. -GC_WIN32_THREADS Enables support for Win32 threads. That makes sense - for Makefile (and Makefile.direct) only under Cygwin or MinGW. Deprecated, +GC_WIN32_THREADS Enables support for Win32 threads. Deprecated, use GC_THREADS instead. GC_WIN32_PTHREADS Enables support for pthreads-win32 (or other @@ -187,9 +190,9 @@ GC_DISABLE_INCREMENTAL Turn off the incremental collection support. -NO_INCREMENTAL Causes the gctest program to not invoke the incremental - collector. This has no impact on the generated library, only on the test - program. (This is often useful for debugging failures unrelated to +NO_INCREMENTAL Causes the GC test programs to not invoke the incremental mode + of the collector. This has no impact on the generated library, only on the + test programs. (This is often useful for debugging failures unrelated to incremental GC.) LARGE_CONFIG Tunes the collector for unusually large heaps. @@ -215,7 +218,7 @@ execute permission is required. GC_NO_OPERATOR_NEW_ARRAY Declares that the C++ compiler does not - support the new syntax "operator new" for allocating and deleting arrays. + support the new syntax "operator new" for allocating and deleting arrays. See gc_cpp.h for details. No effect on the C part of the collector. This is defined implicitly in a few environments. Must also be defined by clients that use gc_cpp.h. @@ -262,17 +265,16 @@ (Might be useful for application debugging or in find-leak mode.) JAVA_FINALIZATION Makes it somewhat safer to finalize objects out of - order by specifying a nonstandard finalization mark procedure (see + order by specifying a nonstandard finalization mark procedure (see finalize.c). Objects reachable from finalizable objects will be marked in a separate post-pass, and hence their memory won't be reclaimed. Not recommended unless you are implementing a language that specifies - these semantics. Since 5.0, determines only the initial value + these semantics. Actually, the macro determines only the initial value of GC_java_finalization variable. FINALIZE_ON_DEMAND Causes finalizers to be run only in response - to explicit GC_invoke_finalizers() calls. - In 5.0 this became runtime adjustable, and this only determines the - initial value of GC_finalize_on_demand. + to explicit GC_invoke_finalizers() calls. Actually, the macro only + determines the initial value of GC_finalize_on_demand. GC_NO_FINALIZATION Exclude finalization support (for smaller code size). @@ -302,9 +304,7 @@ Works for Linux, FreeBSD, Cygwin, Solaris and Irix. USE_MUNMAP Causes memory to be returned to the OS under the right - circumstances. This currently disables VM-based incremental collection - (except for Win32 with GetWriteWatch() available). - Works under some Unix, Linux and Windows versions. + circumstances. Works under some Unix, Linux and Windows versions. Requires USE_MMAP except for Windows. USE_WINALLOC (Cygwin only) Use Win32 VirtualAlloc (instead of sbrk or mmap) @@ -332,9 +332,9 @@ for debugging/profiling purposes. The gc_backptr.h interface is implemented only if this is defined. -GC_ASSERTIONS Enable some internal GC assertion checking. Currently - this facility is only used in a few places. It is intended primarily - for debugging of the garbage collector itself, but could also... +GC_ASSERTIONS Enable some internal GC assertion checking. It is intended + primarily for debugging of the garbage collector itself, but could also + help to identify cases of incorrect GC usage by a client. DBG_HDRS_ALL Make sure that all objects have debug headers. Increases the reliability (from 99.9999% to 100% mod. bugs) of some of the debugging @@ -355,10 +355,10 @@ SAVE_CALL_COUNT=<n> Set the number of call frames saved with objects allocated through the debugging interface. Affects the amount of information generated in leak reports. Only matters on platforms - on which we can quickly generate call stacks, currently Linux/(X86 & SPARC) - and Solaris/SPARC and platforms that provide execinfo.h. - Default is zero. On X86, client - code should NOT be compiled with -fomit-frame-pointer. + on which we can quickly generate call stacks, currently Linux/X86, + Linux/SPARC, Solaris/SPARC, and platforms that provide execinfo.h. + Default is zero. On X86, client code should NOT be compiled with + -fomit-frame-pointer. SAVE_CALL_NARGS=<n> Set the number of functions arguments to be saved with each call frame. Default is zero. Ignored if we don't know how to @@ -372,13 +372,11 @@ that include a pointer to a type descriptor in each allocated object). USE_I686_PREFETCH Causes the collector to issue Pentium III style - prefetch instructions. No effect except on X86 Linux platforms. - Assumes a very recent gcc-compatible compiler and assembler. - (Gas prefetcht0 support was added around May 1999.) + prefetch instructions. No effect except on Linux/X86 platforms. Empirically the code appears to still run correctly on Pentium II processors, though with no performance benefit. May not run on other - X86 processors? In some cases this improves performance by - 15% or so. + X86 processors probably. In some cases this improves performance by 15% + or so. USE_3DNOW_PREFETCH Causes the collector to issue AMD 3DNow style prefetch instructions. Same restrictions as USE_I686_PREFETCH. @@ -401,8 +399,7 @@ THREAD_LOCAL_ALLOC Defines GC_malloc(), GC_malloc_atomic() and GC_gcj_malloc() to use a per-thread set of free-lists. These then allocate in a way that usually does not involve acquisition of a global lock. - Recommended for multiprocessors. Requires explicit GC_INIT() call, unless - REDIRECT_MALLOC is defined and GC_malloc is used first. + Recommended for multiprocessors. USE_COMPILER_TLS Causes thread local allocation to use the compiler-supported "__thread" thread-local variables. This is the @@ -415,11 +412,10 @@ PARALLEL_MARK Allows the marker to run in multiple threads. Recommended for multiprocessors. -GC_BUILTIN_ATOMIC Use C11 (GCC) atomic intrinsics instead of - libatomic_ops primitives. +GC_BUILTIN_ATOMIC Use GCC atomic intrinsics instead of libatomic_ops + primitives. GC_ALWAYS_MULTITHREADED Force multi-threaded mode at GC initialization. - (Turns GC_allow_register_threads into a no-op routine.) GC_ENABLE_SUSPEND_THREAD (Linux only) Turn on thread suspend/resume API support. @@ -534,13 +530,18 @@ causes the exported symbols to have 'default' visibility (ignored unless GCC v4+) and the internal ones to have 'hidden' visibility. +NO_MSGBOX_ON_ERROR (Win32 only) Do not show Windows message box with + "OK" button on a GC fatal error. Otherwise the client application is + terminated only once the user clicks "OK" button. Useful for non-GUI (or + non-interactive) applications. + DONT_USE_USER32_DLL (Win32 only) Don't use "user32" DLL import library (containing MessageBox() entry); useful for a static GC library. GC_PREFER_MPROTECT_VDB Choose MPROTECT_VDB manually in case of multiple - virtual dirty bit strategies are implemented (at present useful on Win32 and - Solaris to force MPROTECT_VDB strategy instead of the default GWW_VDB or - PROC_VDB ones). + virtual dirty bit strategies are implemented (at present useful on Win32, + Solaris and Linux to force MPROTECT_VDB strategy instead of the default + GWW_VDB, PROC_VDB or SOFT_VDB ones, respectively). GC_IGNORE_GCJ_INFO Disable GCJ-style type information (useful for debugging on WinCE). @@ -554,6 +555,9 @@ GC_ANDROID_LOG (Android only) Output error/debug information to Android log. +CONSOLE_LOG (Win32 only) Output error/debug information to stdout and + stderr. + GC_DONT_EXPAND Don't expand the heap unless explicitly requested or forced to. GC_USE_ENTIRE_HEAP Causes the non-incremental collector to use the @@ -569,6 +573,9 @@ GC_FREE_SPACE_DIVISOR=<value> Set alternate default GC_free_space_divisor value. +GC_ALLOCD_BYTES_PER_FINALIZER=<value> Set alternate default value of + GC_allocd_bytes_per_finalizer. + GC_TIME_LIMIT=<milliseconds> Set alternate default GC_time_limit value (setting this to GC_TIME_UNLIMITED will essentially disable incremental collection while leaving generational collection enabled). @@ -592,5 +599,5 @@ USE_GET_STACKBASE_FOR_MAIN (Linux only) Use pthread_attr_getstack() instead of __libc_stack_end (or instead of any hard-coded value) for getting the - primordial thread stack base (useful if the client modifies the program's + primordial thread stack bottom (useful if the client modifies the program's address space).
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.sgi -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.sgi
Changed
@@ -2,18 +2,17 @@ -DNO_EXECUTE_PERMISSION. The collector should run with all of the -32, -n32 and -64 ABIs. Remember to -define the AS macro in the Makefile to be "as -64", or "as -n32". +define the AS macro in the Makefile.direct to be "as -64", or "as -n32". If you use -DREDIRECT_MALLOC=GC_malloc with C++ code, your code should make at least one explicit call to malloc instead of new to ensure that the proper version of malloc is linked in. -Sproc threads are not supported in this version, though there may exist other -ports. +Sproc threads are not supported. Pthreads support is provided. This requires that: -1) You compile the collector with -DGC_THREADS specified in the Makefile. +1) You compile the collector with -DGC_THREADS specified in Makefile.direct. 2) You have the latest pthreads patches installed.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.solaris2 -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.solaris2
Changed
@@ -10,7 +10,7 @@ to expect that this is not safe if the client program also calls the system malloc, or especially realloc. The sbrk man page strongly suggests this is not safe: "Many library routines use malloc() internally, so use brk() -and sbrk() only when you know that malloc() definitely will not be used by +and sbrk() only when you know that malloc() definitely will not be used by any library routine." This doesn't make a lot of sense to me, since there seems to be no documentation as to which routines can transitively call malloc. Nonetheless, under Solaris2, the collector now allocates @@ -27,32 +27,30 @@ Unless --disable-threads option is given, threads support is on by default in configure. This causes the collector to be compiled with -D GC_THREADS ensuring thread safety. This assumes use of the pthread_ interface; old-style -Solaris threads are no longer supported. -Thread-local allocation is now on by default. Parallel marking is on by -default starting from GC v7.3 but it could be disabled manually -by configure --disable-parallel-mark option. +Solaris threads are no longer supported. Thread-local allocation is on by +default. Parallel marking is on by default (it could be disabled manually +by configure --disable-parallel-mark option). It is also essential that gc.h be included in files that call pthread_create, pthread_join, pthread_detach, or dlopen. gc.h macro defines these to also do -GC bookkeeping, etc. gc.h must be included with one or both of these macros -defined, otherwise these replacements are not visible. A collector built in -this way way only be used by programs that are linked with the threads library. +GC bookkeeping, etc. gc.h must be included with GC_THREADS macro defined +first, otherwise these replacements are not visible. A collector built in +this way may only be used by programs that are linked with the threads library. -Since 5.0 alpha5, dlopen disables collection temporarily, -unless USE_PROC_FOR_LIBRARIES is defined. In some unlikely cases, this -can result in unpleasant heap growth. But it seems better than the -race/deadlock issues we had before. +Unless USE_PROC_FOR_LIBRARIES is defined, dlopen disables collection +temporarily. In some unlikely cases, this can result in unpleasant heap +growth. But it seems better than the race/deadlock issues we had before. If threads are used on an X86 processor with malloc redirected to GC_malloc, it is necessary to call GC_INIT explicitly before forking the first thread. (This avoids a deadlock arising from calling GC_thr_init with the allocation lock held.) -It appears that there is a problem in using gc_cpp.h in conjunction with -Solaris threads and Sun's C++ runtime. Apparently the overloaded new operator -is invoked by some iostream initialization code before threads are correctly -initialized. As a result, call to thr_self() in garbage collector -initialization SEGV faults. Currently the only known workaround is to not +There could be an issue when using gc_cpp.h in conjunction with Solaris +threads and Sun's C++ runtime. Apparently the overloaded new operator +may be invoked by some iostream initialization code before threads are +correctly initialized. This may cause a SIGSEGV during initialization +of the garbage collector. Currently the only known workaround is to not invoke the garbage collector from a user defined global operator new, or to have it invoke the garbage-collector's allocators only after main has started. (Note that the latter requires a moderately expensive test in operator
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.symbian -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.symbian
Changed
@@ -1,10 +1,8 @@ Instructions for Symbian: -1. base version: libgc 7.1 -2. Build: use libgc.mmp -3. Limitations -3.1.No multi-threaded support - -3.2. Be careful with limitation that emulator introduces: Static roots are not +1. Build: use libgc.mmp +2. Limitations +2.1. No multi-threaded support yet +2.2. Be careful with limitation that emulator introduces: Static roots are not dynamically accessible (there are Symbian APIs for this purpose but are just stubs, returning irrelevant values). Consequently, on emulator, you can only use dlls or exe, and retrieve static
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.win32 -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.win32
Changed
@@ -1,8 +1,7 @@ -The collector has at various times been compiled under Windows 95 & later, NT, -and XP, with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, with -the GNU win32 tools, with Borland C++ Builder, with Watcom C, and -with the Digital Mars compiler. It is likely that some of these have been -broken in the meantime. Patches are appreciated. +The collector has at various times been compiled under Windows 95 and later, +NT, and XP, with the original Microsoft SDK, with Visual C++ 2.0, 4.0, and 6, +with the GNU win32 tools, with Borland C++ Builder, with Watcom C, with EMX, +and with the Digital Mars compiler (DMC). For historical reasons, the collector test program "gctest" is linked as a GUI application, @@ -11,10 +10,10 @@ cursor may appear as long as it's running. If it is started from the command line, it will usually run in the background. Wait a few minutes (a few seconds on a modern machine) before you check the output. -You should see either a failure indication or a "Collector appears to -work" message. +You should see either a failure indication or a "Collector appears to work" +message. -A toy editor (cord/de.exe) based on cords (heavyweight +A toy editor (de.exe) based on cords (heavyweight strings represented as trees) has been ported and is included. It runs fine under either win32 or win32S. It serves as an example of a true Windows application, except that it was written by a @@ -40,8 +39,9 @@ Microsoft Tools --------------- + For Microsoft development tools, type -"nmake -f NT_MAKEFILE cpu=i386 make_as_lib=1 nothreads=1 nodebug=1" +"nmake -f NT_MAKEFILE cpu=i386 disable_threads=1 enable_static=1 nodebug=1" to build the release variant of the collector as a static library without threads support. @@ -61,6 +61,7 @@ GNU Tools --------- + The collector should be buildable under Cygwin with the "./configure; make check" machinery. @@ -68,8 +69,8 @@ host) and via cross-compilation, e.g. "./configure --host=i686-pc-mingw32; make check" -To build the collector as a DLL, pass "--enable-shared --disable-static" to -configure (this will instruct make to compile with -D GC_DLL). +By default, configure instructs make to build the collector as a DLL (shared +library), adding -D GC_DLL to CFLAGS. Parallel marker is enabled by default; it could be disabled by "--disable-parallel-mark" option. @@ -78,8 +79,8 @@ Borland Tools ------------- -Rarely tested. -For Borland tools, use BCC_MAKEFILE. Note that + +For Borland tools, use `cmake -G "Borland Makefiles"`. Note that Borland's compiler defaults to 1 byte alignment in structures (-a1), whereas Visual C++ appears to default to 8 byte alignment (/Zp8). The garbage collector in its default configuration EXPECTS AT @@ -89,8 +90,6 @@ 486 or Pentium.) Note that this changes structure layouts. (As a last resort, gcconfig.h can be changed to allow 1 byte alignment. But this has significant negative performance implications.) -The Makefile is set up to assume Borland 5.5. If you have another -version, change the line near the top. Digital Mars compiler --------------------- @@ -104,7 +103,7 @@ Ivan V. Demakov's README for the Watcom port: -The collector has been compiled with Watcom C 10.6 and 11.0. +The collector has been tested with Watcom C 10.6, 11.0 and OpenWatcom 2.0. It runs under win32, win32s, and even under msdos with dos4gw dos-extender. It should also run under OS/2, though this isn't tested. Under win32 the collector can be built either as dll @@ -116,13 +115,11 @@ Incremental collection is supported (except for MSDOS and OS/2). -cord is not ported. - Before compiling you may need to edit WCC_MAKEFILE to set target platform, library type (dynamic or static), calling conventions, and optimization options. -To compile the collector and testing programs use the command: +To compile the collector use the command: wmake -f WCC_MAKEFILE All programs using gc should be compiled with 4-byte alignment. @@ -132,6 +129,9 @@ including "gc.h" (for example, with -DGC_DLL compiler option). It's important, otherwise resulting programs will not run. +The alternate way to compile the collector is to use cmake build system: + cmake -G "Watcom WMake" . + cmake --build . Special note for OpenWatcom users: the C (unlike the C++) compiler (of the latest stable release, not sure for older ones) doesn't force pointer global @@ -141,9 +141,9 @@ a feature (see an old report of same kind - http://bugzilla.openwatcom.org/show_bug.cgi?id=664), so You are warned. - Incremental Collection ---------------------- + There is some support for incremental collection. By default, the collector chooses between explicit page protection, and GetWriteWatch-based write tracking automatically, depending on the platform. @@ -165,9 +165,9 @@ Threads ------- -This version of the collector by default handles threads similarly -to other platforms. James Clark's code which tracks threads attached -to the collector DLL still exists, but requires that both +The collector by default handles threads similarly to other platforms. +James Clark's code which tracks threads attached to the collector DLL still +exists, but requires that both - the collector is built in a DLL with GC_DLL defined, and - GC_use_threads_discovery() is called before GC initialization, which in turn must happen before creating additional threads. @@ -180,26 +180,17 @@ tracking) is needed then delete "-DTHREAD_LOCAL_ALLOC" from NT_MAKEFILE manually before the build. -The alternate way (not well tested) to build the dynamic library that supports -both kinds of thread tracking is to use gc.mak instead of NT_MAKEFILE. -To build the garbage collector test with VC++ from the command line, use - -nmake /F ".\gc.mak" CFG="gctest - Win32 Release" - -This requires that the subdirectory gctest\Release exist. -The test program and DLL will reside in the Release directory. +The incremental collection is supported only if it is enabled before any +additional threads are created. -This version currently supports incremental collection only if it is -enabled before any additional threads are created. - -Since 6.3alpha2, threads are also better supported in static library builds -with Microsoft tools (e.g., NT_MAKEFILE) and with the GNU -tools. The collector must be built with GC_THREADS defined (this is the -default in NT_MAKEFILE, ./configure and CMakeLists.txt). +Threads are also supported in static library builds with Microsoft tools +(e.g., NT_MAKEFILE), as well as with the CMake and GNU tools. The collector +must be built with GC_THREADS defined (this is the default in NT_MAKEFILE, +CMakeLists.txt and configure). For the normal, non-dll-based thread tracking to work properly, threads should be created with GC_CreateThread or GC_beginthreadex, -and exit normally or call GC_endthreadex or GC_ExitThread. (For Cygwin, the +and exit normally, or call GC_endthreadex or GC_ExitThread. (For Cygwin, the standard pthread_create/exit calls could be used instead.) As in the pthread case, including gc.h will redefine CreateThread, _beginthreadex, _endthreadex, and ExitThread to call the GC_ versions instead. @@ -219,3 +210,6 @@ implementation for Windows), use Makefile.direct and explicitly set GC_WIN32_PTHREADS (or pass --enable-threads=pthreads to configure). Use -DPTW32_STATIC_LIB for the static threads library. + +The alternate (better) way to build the library is to use CMake script; +please see README.cmake for the details.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/README.win64 -> _service:tar_scm:gc-8.2.2.tar.gz/doc/README.win64
Changed
@@ -1,13 +1,13 @@ -64-bit Windows on AMD64/Intel EM64T is somewhat supported in the 7.0 -and later release. A collector can be built with Microsoft Visual C++ 2005 -or with mingw-w64 gcc. +64-bit Windows on AMD64/Intel EM64T is supported. A collector can be built +with Microsoft Visual C++ 2005 or with mingw-w64 gcc. NT_MAKEFILE has been used in this environment. Type "nmake -f NT_MAKEFILE cpu=AMD64 nodebug=1" in a Visual C++ command line window to build the release variant of the dynamic library with threads -support and the usual test programs. -To verify that the collector is at least somewhat functional, run gctest.exe. -This should create gctest.gc.log after a few seconds. +support. +To verify that the collector is at least somewhat functional, +type "nmake -f NT_MAKEFILE cpu=AMD64 check" to build and run the usual test +programs. This should create gctest.gc.log after a few seconds. Test_cpp.exe might not run correctly in case of dynamic GC linking. (It seems that we're getting wrong instances of operator new/delete in some cases.) @@ -16,9 +16,9 @@ for the 32-bit library version. A similar procedure using NT_MAKEFILE is applicable to build the static -library - just pass "make_as_lib=1" as an extra argument to nmake. +library - just pass "enable_static=1" as an extra argument to nmake. If needed, it is also possible to build the library without threads -support - this could be done by passing "nothreads=1" argument to nmake. +support - this could be done by passing "disable_threads=1" argument to nmake. Note that some warnings have been explicitly turned off in the makefile.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/debugging.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/debugging.md
Changed
@@ -43,13 +43,8 @@ The garbage collector generates warning messages of the form: - Needed to allocate blacklisted block at 0x... - - -or - - Repeated allocation of very large block ... + May lead to memory leak and poor performance when it needs to allocate a block at a location that it knows to be referenced @@ -88,7 +83,7 @@ } - 4. In the unlikely case that even relatively small object (<20KB) + 4. In the unlikely case that even relatively small object (<20 KB) allocations are triggering these warnings, then your address space contains lots of "bogus pointers", i.e. values that appear to be pointers but aren't. Usually this can be solved by using `GC_malloc_atomic` or the routines @@ -133,11 +128,11 @@ (`-DDONT_ADD_BYTE_AT_END`). The collector rounds up object sizes so the result fits well into the chunk -size (`HBLKSIZE`, normally 4K on 32 bit machines, 8K on 64 bit machines) used -by the collector. Thus it may be worth avoiding objects of size 2K + 1 (or 2K -if a byte is being added at the end.) The last two cases can often -be identified by looking at the output of a call to `GC_dump`. Among other -things, it will print the list of free heap blocks, and a very brief +size (`HBLKSIZE`, normally 4 KB on 32-bit machines, 8 KB on 64-bit ones) used +by the collector. Thus it may be worth avoiding objects of size 2K + 1 bytes +(or exactly 2 KB if a byte is being added at the end.) The last two cases can +often be identified by looking at the output of a call to `GC_dump`. Among +other things, it will print the list of free heap blocks, and a very brief description of all chunks in the heap, the object sizes they correspond to, and how many live objects were found in the chunk at the last collection. @@ -169,11 +164,12 @@ pseudo-random numbers, and the like. It is also likely to improve GC performance, perhaps drastically so if the application is paging. 2. If you allocate large objects containing only one or two pointers at the - beginning, either try the typed allocation primitives is`gc_typed.h`, + beginning, either try the typed allocation primitives in `gc_typed.h`, or separate out the pointer-free component. 3. Consider using `GC_malloc_ignore_off_page` to allocate large objects. - (See `gc.h` and above for details. Large means >100K in most environments.) - 4. If your heap size is larger than 100MB or so, build the collector with + (See `gc.h` and above for details. Large means more than 100 KB in most + environments.) + 4. If your heap size is larger than 100 MB or so, build the collector with `-DLARGE_CONFIG`. This allows the collector to keep more precise black-list information. 5. If you are using heaps close to, or larger than, a gigabyte on a 32-bit
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/doc.am -> _service:tar_scm:gc-8.2.2.tar.gz/doc/doc.am
Changed
@@ -24,6 +24,7 @@ doc/README.cmake \ doc/README.cords \ doc/README.darwin \ + doc/README.emscripten \ doc/README.environment \ doc/README.ews4800 \ doc/README.hp \
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/finalization.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/finalization.md
Changed
@@ -37,19 +37,18 @@ recently used logically open files. Any other needed files would be closed after saving their state. They would then be reopened on demand. Finalization would logically close the file, closing the real descriptor - only if it happened to be cached.) Note that most modern systems (e.g. Irix) - allow hundreds or thousands of open files, and this is typically not - an issue. + only if it happened to be cached.) Note that most modern systems allow + thousands of open files, and this is typically not an issue. * Finalization code may be run anyplace an allocation or other call to the collector takes place. In multi-threaded programs, finalizers have to obey the normal locking conventions to ensure safety. Code run directly from finalizers should not acquire locks that may be held during allocation. - This restriction can be easily circumvented by registering a finalizer which - enqueues the real action for execution in a separate thread. + This restriction can be easily circumvented by calling + `GC_set_finalize_on_demand(1)` at program start and creating a separate + thread dedicated to periodic invocation of `GC_invoke_finalizers()`. -In single-threaded code, it is also often easiest to have finalizers queue -actions, which are then explicitly run during an explicit call by the user's -program. +In single-threaded code, it is also often easiest to have finalizers queued +and, then to have them explicitly executed by `GC_invoke_finalizers()`. ## Topologically ordered finalization
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/gc.man -> _service:tar_scm:gc-8.2.2.tar.gz/doc/gc.man
Changed
@@ -1,15 +1,28 @@ -.TH BDWGC 3 "15 Aug 2018" +.TH BDWGC 3 "26 Mar 2019" .SH NAME -GC_malloc, GC_malloc_atomic, GC_free, GC_realloc, GC_enable_incremental, GC_register_finalizer, GC_malloc_ignore_off_page, GC_malloc_atomic_ignore_off_page, GC_set_warn_proc \- Garbage collecting malloc replacement +GC_malloc, GC_malloc_atomic, GC_free, GC_realloc, GC_enable_incremental, +GC_register_finalizer, GC_malloc_ignore_off_page, +GC_malloc_atomic_ignore_off_page, GC_set_warn_proc \- Garbage collecting +malloc replacement .SH SYNOPSIS #include <gc.h> .br void * GC_malloc(size_t size); .br +void * GC_malloc_atomic(size_t size); +.br void GC_free(void *ptr); .br void * GC_realloc(void *ptr, size_t size); .br +void GC_enable_incremental(void); +.br +void * GC_malloc_ignore_off_page(size_t size); +.br +void * GC_malloc_atomic_ignore_off_page(size_t size); +.br +void GC_set_warn_proc(void (*proc)(char *, GC_word)); +.br .sp cc ... -lgc .LP @@ -20,7 +33,12 @@ are plug-in replacements for standard malloc and free. However, .I GC_malloc -will attempt to reclaim inaccessible space automatically by invoking a conservative garbage collector at appropriate points. The collector traverses all data structures accessible by following pointers from the machines registers, stack(s), data, and bss segments. Inaccessible structures will be reclaimed. A machine word is considered to be a valid pointer if it is an address inside an object allocated by +will attempt to reclaim inaccessible space automatically by invoking +a conservative garbage collector at appropriate points. The collector +traverses all data structures accessible by following pointers from the +machines registers, stack(s), data, and bss segments. Inaccessible structures +will be reclaimed. A machine word is considered to be a valid pointer if +it is an address inside an object allocated by .I GC_malloc or friends. @@ -44,30 +62,49 @@ clears the newly allocated storage. .I GC_malloc_atomic -does not. Furthermore, it informs the collector that the resulting object will never contain any pointers, and should therefore not be scanned by the collector. +does not. Furthermore, it informs the collector that the resulting object +will never contain any pointers, and should therefore not be scanned by the +collector. .LP .I GC_free -can be used to deallocate objects, but its use is optional, and generally discouraged. +can be used to deallocate objects, but its use is optional, and generally +discouraged. .I GC_realloc has the standard realloc semantics. It preserves pointer-free-ness. .I GC_register_finalizer -allows for registration of functions that are invoked when an object becomes inaccessible. +allows for registration of functions that are invoked when an object becomes +inaccessible. .LP -The garbage collector tries to avoid allocating memory at locations that already appear to be referenced before allocation. (Such apparent ``pointers'' are usually large integers and the like that just happen to look like an address.) This may make it hard to allocate very large objects. An attempt to do so may generate a warning. +The garbage collector tries to avoid allocating memory at locations that +already appear to be referenced before allocation. (Such apparent +``pointers'' are usually large integers and the like that just happen to look +like an address.) This may make it hard to allocate very large objects. +An attempt to do so may generate a warning. .LP .I GC_malloc_ignore_off_page and .I GC_malloc_atomic_ignore_off_page -inform the collector that the client code will always maintain a pointer to near the beginning of the object (within the first 512 bytes), and that pointers beyond that can be ignored by the collector. This makes it much easier for the collector to place large objects. These are recommended for large object allocation. (Objects expected to be larger than about 100KBytes should be allocated this way.) -.LP -It is also possible to use the collector to find storage leaks in programs destined to be run with standard malloc/free. The collector can be compiled for thread-safe operation. Unlike standard malloc, it is safe to call malloc after a previous malloc call was interrupted by a signal, provided the original malloc call is not resumed. -.LP -The collector may, on rare occasion produce warning messages. On UNIX machines these appear on stderr. Warning messages can be filtered, redirected, or ignored with +inform the collector that the client code will always maintain a pointer to +near the beginning of the object (within the first 512 bytes), and that +pointers beyond that can be ignored by the collector. This makes it much +easier for the collector to place large objects. These are recommended for +large object allocation. (Objects expected to be > ~100 KB should be +allocated this way.) +.LP +It is also possible to use the collector to find storage leaks in programs +destined to be run with standard malloc/free. The collector can be compiled +for thread-safe operation. Unlike standard malloc, it is safe to call malloc +after a previous malloc call was interrupted by a signal, provided the +original malloc call is not resumed. +.LP +The collector may, on rare occasion, produce warning messages. On UNIX +machines these appear on stderr. Warning messages can be filtered, +redirected, or ignored with .I GC_set_warn_proc This is recommended for production code. See gc.h for details. @@ -75,21 +112,35 @@ Fully portable code should call .I GC_INIT -from the main program before making any other GC calls. -On most platforms this does nothing and the collector is initialized on first use. -On a few platforms explicit initialization is necessary. And it can never hurt. -.LP -Debugging versions of many of the above routines are provided as macros. Their names are identical to the above, but consist of all capital letters. If GC_DEBUG is defined before gc.h is included, these routines do additional checking, and allow the leak detecting version of the collector to produce slightly more useful output. Without GC_DEBUG defined, they behave exactly like the lower-case versions. +from the primordial thread of the main program before making any other +GC calls. On most platforms this does nothing and the collector is +initialized on first use. On a few platforms explicit initialization is +necessary. And it can never hurt. +.LP +Debugging versions of many of the above routines are provided as macros. +Their names are identical to the above, but consist of all capital letters. +If GC_DEBUG is defined before gc.h is included, these routines do additional +checking, and allow the leak detecting version of the collector to produce +slightly more useful output. Without GC_DEBUG defined, they behave exactly +like the lower-case versions. .LP On some machines, collection will be performed incrementally after a call to .I GC_enable_incremental. -This may temporarily write protect pages in the heap. See the README file for more information on how this interacts with system calls that write to the heap. +This may temporarily write protect pages in the heap. See the README file for +more information on how this interacts with system calls that write to the +heap. .LP -Other facilities not discussed here include limited facilities to support incremental collection on machines without appropriate VM support, provisions for providing more explicit object layout information to the garbage collector, more direct support for ``weak'' pointers, support for ``abortable'' garbage collections during idle time, etc. +Other facilities not discussed here include limited facilities to support +incremental collection on machines without appropriate VM support, provisions +for providing more explicit object layout information to the garbage +collector, more direct support for ``weak'' pointers, support for +``abortable'' garbage collections during idle time, etc. .LP .SH "SEE ALSO" -The README and gc.h files in the distribution. More detailed definitions of the functions exported by the collector are given there. (The above list is not complete.) +The README and gc.h files in the distribution. More detailed definitions of +the functions exported by the collector are given there. (The above list is +not complete.) .LP The web site at http://www.hboehm.info/gc/ (or https://github.com/ivmai/bdwgc/). .LP @@ -100,4 +151,5 @@ .LP .SH AUTHOR Hans-J. Boehm (boehm@acm.org). -Some of the code was written by others (see the AUTHORS file for the details), most notably by Alan Demers, and, recently, Ivan Maidanski. +Some of the code was written by others (see the AUTHORS file for the details), +most notably by Alan Demers, and, recently, Ivan Maidanski.
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/gcdescr.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/gcdescr.md
Changed
@@ -18,30 +18,52 @@ be apparent in the design. We assume the default finalization model, but the code affected by that is very localized. +Table of Contents + * Introduction(#introduction) + * Allocation(#allocation) + * Mark phase(#mark-phase) + * Sweep phase(#sweep-phase) + * Finalization(#finalization) + * Generational Collection and Dirty Bits(#generational-collection-and-dirty-bits) + * Black-listing(#black-listing) + * Thread support(#thread-support) + * Thread-local allocation(#thread-local-allocation) + ## Introduction The garbage collector uses a modified mark-sweep algorithm. Conceptually it operates roughly in four phases, which are performed occasionally as part of a memory allocation: - 1. _Preparation_ Each object has an associated mark bit. Clear all mark - bits, indicating that all objects are potentially unreachable. - 2. _Mark phase_ Marks all objects that can be reachable via chains - of pointers from variables. Often the collector has no real information - about the location of pointer variables in the heap, so it views all static - data areas, stacks and registers as potentially containing pointers. Any bit - patterns that represent addresses inside heap objects managed by the - collector are viewed as pointers. Unless the client program has made heap - object layout information available to the collector, any heap objects found - to be reachable from variables are again scanned similarly. - 3. _Sweep phase_ Scans the heap for inaccessible, and hence unmarked, - objects, and returns them to an appropriate free list for reuse. This is not - really a separate phase; even in non-incremental mode this operation - is usually performed on demand during an allocation that discovers an empty - free list. Thus the sweep phase is very unlikely to touch a page that would - not have been touched shortly thereafter anyway. - 4. _Finalization phase_ Unreachable objects which had been registered for - finalization are enqueued for finalization outside the collector. + 1. _Preparation phase_ + + Each object has an associated mark bit. Clear all mark + bits, indicating that all objects are potentially unreachable. + + 2. _Mark phase_ + + Marks all objects that can be reachable via chains of pointers from + variables. Often the collector has no real information about the location + of pointer variables in the heap, so it views all static data areas, + stacks and registers as potentially containing pointers. Any bit + patterns that represent addresses inside heap objects managed by the + collector are viewed as pointers. Unless the client program has made heap + object layout information available to the collector, any heap objects + found to be reachable from variables are again scanned similarly. + + 3. _Sweep phase_ + + Scans the heap for inaccessible, and hence unmarked, + objects, and returns them to an appropriate free list for reuse. This is + not really a separate phase; even in non-incremental mode this operation + is usually performed on demand during an allocation that discovers an + empty free list. Thus the sweep phase is very unlikely to touch a page + that would not have been touched shortly thereafter anyway. + + 4. _Finalization phase_ + + Unreachable objects which had been registered for + finalization are enqueued for finalization outside the collector. The remaining sections describe the memory allocation data structures, and then the last 3 collection phases in more detail. We conclude by outlining @@ -58,17 +80,16 @@ allows the garbage collector to easily ignore the collectors own data structures when it searches for root pointers. Other allocator and collector internal data structures are allocated dynamically with `GC_scratch_alloc`. -`GC_scratch_alloc` does not allow for deallocation, and is therefore used only -for permanent data structures. +The latter does not allow for deallocation, and is therefore used only for +permanent data structures. -The allocator allocates objects of different _kinds_. Different kinds are +The allocator returns objects of different _kinds_. Different _kinds_ are handled somewhat differently by certain parts of the garbage collector. Certain kinds are scanned for pointers, others are not. Some may have per-object type descriptors that determine pointer locations. Or a specific kind may correspond to one specific object layout. Two built-in kinds are -uncollectible. -In spite of that, it is very likely that most C clients of the collector -currently use at most two kinds: `NORMAL` and `PTRFREE` objects. The +uncollectible. In spite of that, it is very likely that most C clients of the +collector currently use at most two kinds: `NORMAL` and `PTRFREE` objects. The GCJ(https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcj/) runtime also makes heavy use of a kind (allocated with `GC_gcj_malloc`) that stores type information at a known offset in method tables. @@ -78,20 +99,20 @@ of the page size. Large block sizes are rounded up to the next multiple of `HBLKSIZE` and then -allocated by `GC_allochblk`. Recent versions of the collector use an -approximate best fit algorithm by keeping free lists for several large block -sizes. The actual implementation of `GC_allochblk` is significantly -complicated by black-listing issues (see below). +allocated by `GC_allochblk`. The collector use an approximate best fit +algorithm by keeping free lists for several large block sizes. The actual +implementation of `GC_allochblk` is significantly complicated by black-listing +issues (see below). Small blocks are allocated in chunks of size `HBLKSIZE`. Each chunk is dedicated to only one object size and kind. The allocator maintains separate free lists for each size and kind of object. Associated with each kind is an array of free list pointers, with entry -`freelisti` pointing to a free list of size 'i' objects. In recent versions -of the collector, index `i` is expressed in granules, which are the minimum -allocatable unit, typically 8 or 16 bytes. The free lists themselves are -linked through the first word in each object (see `obj_link` macro). +`freelisti` pointing to a free list of size 'i' objects. Index `i` is +expressed in granules, which are the minimum allocatable unit, typically 8 or +16 bytes. The free lists themselves are linked through the first word in each +object (see `obj_link` macro). Once a large block is split for use in smaller objects, it can only be used for objects of that size, unless the collector discovers a completely empty @@ -132,14 +153,13 @@ * Programs with a large root set size and little live heap memory will expand the heap to amortize the cost of scanning the roots. - * GC v5 actually collects more frequently in non-incremental mode. The large + * GC actually collects more frequently in non-incremental mode. The large block allocator usually refuses to split large heap blocks once the garbage collection threshold is reached. This often has the effect of collecting well before the heap fills up, thus reducing fragmentation and working set - size at the expense of GC time. GC v6 chooses an intermediate strategy - depending on how much large object allocation has taken place in the past. - (If the collector is configured to unmap unused pages, GC v6 uses the - strategy of GC v5.) + size at the expense of GC time. (If the collector is configured not to unmap + unused pages, GC chooses an intermediate strategy depending on how much + large object allocation has taken place in the past.) * In calculating the amount of allocation since the last collection we give partial credit for objects we expect to be explicitly deallocated. Even if all objects are explicitly managed, it is often desirable to collect @@ -182,7 +202,7 @@ a length. (For other possibilities, see `gc_mark.h`.) At the beginning of the mark phase, all root segments (as described above) are -pushed on the stack by `GC_push_roots`. (Registers and eagerly processed stack +pushed on the stack by `GC_push_roots`. (Registers and eagerly scanned stack sections are processed by pushing the referenced objects instead of the stack section itself.) If `ALL_INTERIOR_POINTERS` is not defined, then stack roots require special treatment. In this case, the normal marking code ignores @@ -200,7 +220,7 @@ In this case `GC_objects_are_marked` will simultaneously be false, so the mark state is advanced to 2. `MS_PUSH_UNCOLLECTABLE` indicating that it suffices to push uncollectible - objects, roots, and then mark everything reachable from them. `scan_ptr` + objects, roots, and then mark everything reachable from them. `GC_scan_ptr` is advanced through the heap until all uncollectible objects are pushed, and objects reachable from them are marked. At that point, the next call to `GC_mark_some` calls `GC_push_roots` to push the roots. It, then, @@ -234,9 +254,9 @@ attempt results in additional marked objects. Each mark stack entry is processed by examining all candidate pointers in the -range described by the entry. If the region has no associated type -information, then this typically requires that each 4-byte aligned quantity -(8-byte aligned with 64-bit pointers) be considered a candidate pointer. +range described by the entry. If the region has no associated type information +then this typically requires that each 4-byte aligned quantity (8-byte aligned +if 64-bit pointers) be considered a candidate pointer. We determine whether a candidate pointer is actually the address of a heap block. This is done in the following steps: @@ -249,8 +269,10 @@ * The candidate pointer is divided into two pieces; the most significant bits identify a `HBLKSIZE`-sized page in the address space, and the least significant bits specify an offset within that page. (A hardware page may - actually consist of multiple such pages. HBLKSIZE is usually the page size - divided by a small power of two.) + actually consist of multiple such pages. Normally, HBLKSIZE is usually the + page size divided by a small power of two. Alternatively, if the collector + is built with `-DLARGE_CONFIG`, such a page may consist of multiple hardware + pages.) * The page address part of the candidate pointer is looked up in a table(tree.md). Each table entry contains either 0, indicating that the page is not part of the garbage collected heap, a small integer _n_, @@ -269,8 +291,8 @@ operation in computing the object start address. * The mark bit for the target object is checked and set. If the object was previously unmarked, the object is pushed on the mark stack. The descriptor - is read from the page descriptor. (This is computed from information - `GC_obj_kinds` when the page is first allocated.) + is read from the page descriptor. (This is computed from information stored + in `GC_obj_kinds` when the page is first allocated.) At the end of the mark phase, mark bits for left-over free lists are cleared, in case a free list was accidentally marked due to a stray pointer. @@ -373,12 +395,12 @@ In incremental mode, the heap is always expanded when we encounter insufficient space for an allocation. Garbage collection is triggered whenever -we notice that more than `GC_heap_size`/2 * `GC_free_space_divisor` bytes +we notice that more than `GC_heap_size / 2 * GC_free_space_divisor` bytes of allocation have taken place. After `GC_full_freq` minor collections a major collection is started. All collections initially run uninterrupted until a predetermined amount -of time (50 msecs by default) has expired. If this allows the collection +of time (50 ms by default) has expired. If this allows the collection to complete entirely, we can avoid correcting for data structure modifications during the collection. If it does not complete, we return control to the mutator, and perform small amounts of additional GC work during those later @@ -396,6 +418,7 @@ * (`PROC_VDB`) By retrieving dirty bit information from /proc. (Currently only Sun's Solaris supports this. Though this is considerably cleaner, performance may actually be better with `mprotect` and signals.) + * (`SOFT_VDB`) By retrieving Linux soft-dirty bit information from /proc. * (`PCR_VDB`) By relying on an external dirty bit implementation, in this case the one in Xerox PCR. * Through explicit mutator cooperation. This enabled by @@ -467,34 +490,34 @@ `gc_pthread_redirects.h`), or optionally by using `ld`'s function call wrapping mechanism under Linux. -Recent versions of the collector support several facilities to enhance the -processor-scalability and thread performance of the collector. These are -discussed in more detail here(scale.md). We briefly outline the data -approach to thread-local allocation in the next section. +The collector support several facilities to enhance the processor-scalability +and thread performance of the collector. These are discussed in more detail +here(scale.md). We briefly outline the data approach to thread-local +allocation in the next section. ## Thread-local allocation -If thread-local allocation is enabled, the collector keeps separate arrays -of free lists for each thread. Thread-local allocation is currently only -supported on a few platforms. +If thread-local allocation is enabled (which is true in the default +configuration for most supported platforms), the collector keeps separate +arrays of free lists for each thread. The free list arrays associated with each thread are only used to satisfy requests for objects that are both very small, and belong to one of a small -number of well-known kinds. These currently include _normal_ and pointer-free -objects. Depending on the configuration, _gcj_ objects may also be included. +number of well-known kinds. These include _normal_, pointer-free, _gcj_ and +_disclaim_ objects. Thread-local free list entries contain either a pointer to the first element of a free list, or they contain a counter of the number of allocation granules, corresponding to objects of this size, allocated so far. Initially they contain the value one, i.e. a small counter value. -Thread-local allocation allocates directly through the global allocator, -if the object is of a size or kind not covered by the local free lists. +Thread-local allocation goes directly through the global allocator if the +object is of a size or kind not covered by the local free lists. If there is an appropriate local free list, the allocator checks whether it contains a sufficiently small counter value. If so, the counter is simply -incremented by the counter value, and the global allocator is used. In this -way, the initial few allocations of a given size bypass the local allocator. +incremented by a value, and the global allocator is used. In this way, +the initial few allocations of a given size bypass the local allocator. A thread that only allocates a handful of objects of a given size will not build up its own free list for that size. This avoids wasting space for unpopular objects sizes or kinds. @@ -515,8 +538,9 @@ On thread exit, any remaining thread-local free list entries are transferred back to the global free list. -Note that if the collector is configured for thread-local allocation, -`GC_malloc` only uses thread-local allocation (starting from GC v7). +Note that if the collector is configured for thread-local allocation (the +default for most platforms), `GC_malloc` and friends only use thread-local +allocation. For some more details see here(scale.md), and the technical report entitled "Fast Multiprocessor Memory Allocation and Garbage Collection"(http://www.hpl.hp.com/techreports/2000/HPL-2000-165.html).
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/gcinterface.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/gcinterface.md
Changed
@@ -15,7 +15,8 @@ The following describes the standard C interface to the garbage collector. It is not a complete definition of the interface. It describes only the most commonly used functionality, approximately in decreasing order of frequency -of use. The full interface is described in `gc.h` file. +of use. This somewhat duplicates the information in `gc.man` file. The full +interface is described in `gc.h` file. Clients should include `gc.h` (i.e., not `gc_config_macros.h`, `gc_pthread_redirects.h`, `gc_version.h`). In the case of multi-threaded code, @@ -27,11 +28,11 @@ Thread users should also be aware that on many platforms objects reachable only from thread-local variables may be prematurely reclaimed. Thus objects pointed to by thread-local variables should also be pointed to by a globally -visible data structure. (This is viewed as a bug, but as one that -is exceedingly hard to fix without some `libc` hooks.) +visible data area, e.g. thread's stack. (This behavior is viewed as a bug, but +as one that is exceedingly hard to fix without some `libc` hooks.) -**void * `GC_MALLOC`(size_t _nbytes_)** - Allocates and clears _nbytes_ -of storage. Requires (amortized) time proportional to _nbytes_. The resulting +`void * GC_MALLOC(size_t _bytes_)` - Allocates and clears _bytes_ +of storage. Requires (amortized) time proportional to _bytes_. The resulting object will be automatically deallocated when unreferenced. References from objects allocated with the system malloc are usually not considered by the collector. (See `GC_MALLOC_UNCOLLECTABLE`, however. Building the collector @@ -40,33 +41,33 @@ is defined before `gc.h` is included, a debugging version that checks occasionally for overwrite errors, and the like. -**void * `GC_MALLOC_ATOMIC`(size_t _nbytes_)** - Allocates _nbytes_ -of storage. Requires (amortized) time proportional to _nbytes_. The resulting +`void * GC_MALLOC_ATOMIC(size_t _bytes_)` - Allocates _bytes_ +of storage. Requires (amortized) time proportional to _bytes_. The resulting object will be automatically deallocated when unreferenced. The client promises that the resulting object will never contain any pointers. The memory is not cleared. This is the preferred way to allocate strings, floating point arrays, bitmaps, etc. More precise information about pointer locations can be communicated to the collector using the interface in `gc_typed.h`. -**void * `GC_MALLOC_UNCOLLECTABLE`(size_t _nbytes_)** - Identical +`void * GC_MALLOC_UNCOLLECTABLE(size_t _bytes_)` - Identical to `GC_MALLOC`, except that the resulting object is not automatically deallocated. Unlike the system-provided `malloc`, the collector does scan the object for pointers to garbage-collectible memory, even if the block itself does not appear to be reachable. (Objects allocated in this way are effectively treated as roots by the collector.) -**void * `GC_REALLOC`(void * _old_, size_t _new_size_)** - Allocates a new -object of the indicated size and copy (a prefix of) the old object into the +`void * GC_REALLOC(void * _old_object_, size_t _new_bytes_)` - Allocates +a new object of the indicated size and copy the old object's content into the new object. The old object is reused in place if convenient. If the original object was allocated with `GC_MALLOC_ATOMIC`, the new object is subject to the same constraints. If it was allocated as an uncollectible object, then the new object is uncollectible, and the old object (if different) is deallocated. -**void `GC_FREE`(void * _dead_)** - Explicitly deallocates an object. +`void GC_FREE(void * _object_)` - Explicitly deallocates an _object_. Typically not useful for small collectible objects. -**void * `GC_MALLOC_IGNORE_OFF_PAGE`(size_t _nbytes_)** and -**void * `GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE`(size_t _nbytes_)** - Analogous +`void * GC_MALLOC_IGNORE_OFF_PAGE(size_t _bytes_)` and +`void * GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(size_t _bytes_)` - Analogous to `GC_MALLOC` and `GC_MALLOC_ATOMIC`, respectively, except that the client guarantees that as long as the resulting object is of use, a pointer is maintained to someplace inside the first 512 bytes of the object. This @@ -75,51 +76,49 @@ This is the preferred way to allocate objects that are likely to be more than 100 KB in size. It greatly reduces the risk that such objects will be accidentally retained when they are no longer needed. Thus space usage may -be significantly reduced. +be significantly reduced. Another way is `GC_set_all_interior_pointers(0)` +called at program start (this, however, is generally not suitable for C++ code +because of multiple inheritance). -**void `GC_INIT()`** - On some platforms, it is necessary to invoke this _from +`void GC_INIT()` - On some platforms, it is necessary to invoke this _from the main executable_, _not from a dynamic library_, before the initial invocation of a GC routine. It is recommended that this be done in portable code, though we try to ensure that it expands to a no-op on as many platforms -as possible. In GC v7.0, it was required if thread-local allocation is enabled -in the collector build, and `malloc` is not redirected to `GC_malloc`. +as possible. -**void `GC_gcollect`(void)** - Explicitly forces a garbage collection. +`void GC_gcollect(void)` - Explicitly forces a garbage collection. -**void `GC_enable_incremental`(void)** - Causes the garbage collector +`void GC_enable_incremental(void)` - Causes the garbage collector to perform a small amount of work every few invocations of `GC_MALLOC` or the like, instead of performing an entire collection at once. This is likely to increase total running time. It will improve response on a platform that -either has suitable support in the garbage collector (Linux and most Unix -versions, Win32 if the collector was suitably built). On many platforms this -interacts poorly with system calls that write to the garbage collected heap. +has suitable support in the garbage collector (Linux and most Unix versions, +Win32 if the collector was suitably built). On many platforms this interacts +poorly with system calls that write to the garbage collected heap. -**void `GC_set_warn_proc`(GC_warn_proc)** - Replaces the default procedure +`void GC_set_warn_proc(GC_warn_proc)` - Replaces the default procedure used by the collector to print warnings. The collector may otherwise write to `stderr`, most commonly because `GC_malloc` was used in a situation in which `GC_malloc_ignore_off_page` would have been more appropriate. See `gc.h` for details. -**void `GC_REGISTER_FINALIZER`(...)** - Registers a function to be called when +`void GC_REGISTER_FINALIZER(...)` - Registers a function to be called when an object becomes inaccessible. This is often useful as a backup method for releasing system resources (e.g. closing files) when the object referencing them becomes inaccessible. It is not an acceptable method to perform actions that must be performed in a timely fashion. See `gc.h` for details of the interface. See also here(finalization.md) for a more detailed discussion -of the design. - -Note that an object may become inaccessible before client code is done -operating on objects referenced by its fields. Suitable synchronization -is usually required. See -here(http://portal.acm.org/citation.cfm?doid=604131.604153) -or here(http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html) for -details. +of the design. Note that an object may become inaccessible before client code +is done operating on objects referenced by its fields. Suitable +synchronization is usually required. See +here(http://portal.acm.org/citation.cfm?doid=604131.604153) or +here(http://www.hpl.hp.com/techreports/2002/HPL-2002-335.html) for details. If you are concerned with multiprocessor performance and scalability, you should consider enabling and using thread local allocation. -If your platform supports it, you should build the collector with parallel -marking support (`-DPARALLEL_MARK`); configure has it on by default. +If your platform supports it, you should also build the collector with +parallel marking support (`-DPARALLEL_MARK`); configure has it on by default. If the collector is used in an environment in which pointer location information for heap objects is easily available, this can be passed on to the @@ -134,11 +133,11 @@ Unfortunately, this thin layer appears to be very sensitive to variations in C++ implementations, particularly since it tries to replace the global `::new` operator, something that appears to not be well-standardized. Your -platform may need minor adjustments in this layer (`gc_cpp.cc`, `gc_cpp.h`, -and possibly `gc_allocator.h`). Such changes do not require understanding -of collector internals, though they may require a good understanding of your -platform. (Patches enhancing portability are welcome. But it is easy to break -one platform by fixing another.) +platform may need minor adjustments in this layer (`gc_badalc.cc`, +`gc_cpp.cc`, `gc_cpp.h`, and possibly `gc_allocator.h`). Such changes do not +require understanding of collector internals, though they may require a good +understanding of your platform. (Patches enhancing portability are welcome. +But it is easy to break one platform by fixing another.) Usage of the collector from C++ is also complicated by the fact that there are many _standard_ ways to allocate memory in C++. The default `::new` operator, @@ -182,24 +181,6 @@ These should work with any fully standard-conforming C++ compiler. -Users of the SGI extended STL(http://www.sgi.com/tech/stl) or its -derivatives (including most g++ versions) may instead be able to include -`new_gc_alloc.h` before including STL header files. This is increasingly -discouraged. - -This defines SGI-style allocators - - * `traceable_alloc` - * `single_client_traceable_alloc` - * `gc_alloc` - * `single_client_gc_alloc` - -The first two allocate uncollectible but traced memory, while the second two -allocate collectible memory. The `single_client_...` versions are not safe for -concurrent access by multiple threads, but are faster. - -See sample code here(http://www.hboehm.info/gc/gc_alloc_exC.txt). - ### Class inheritance based interface for new-based allocation Users may include `gc_cpp.h` and then cause members of classes to be allocated @@ -210,6 +191,15 @@ (and friends) to allocate traceable but uncollectible memory, making it safe to refer to collectible objects from the resulting memory. +If the user includes `gc_cpp.h` but `::new` should not be overridden then +`libgctba` (in addition to the `gc`) library should be linked with to provide +the definition of `GC_throw_bad_alloc` C++ function used by operator `new` of +class `gc`. Alternatively, the client may define `GC_NEW_ABORTS_ON_OOM` macro +before include of `gc_cpp.h` (this instructs `::new` to issue an abort instead +of throwing an exception), or may define `GC_INCLUDE_NEW` one before include +of `gc_cpp.h` (however, this might not compile or work as expected on some +platforms). + ## C interface It is also possible to use the C interface from `gc.h` directly. On platforms
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/leak.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/leak.md
Changed
@@ -16,32 +16,29 @@ exit time, a potentially useless activity that often triggers large amounts of paging. -All non-ancient versions of the garbage collector provide leak detection -support. Version 5.3 adds the following features: +The garbage collector provides leak detection support. This includes the +following features: - 1. Leak detection mode can be initiated at run-time by setting - `GC_find_leak` instead of building the collector with `FIND_LEAK` defined. - This variable should be set to a nonzero value at program startup. + 1. Leak detection mode can be initiated at run-time by `GC_set_find_leak(1)` + call at program startup instead of building the collector with `FIND_LEAK` + macro defined. 2. Leaked objects should be reported and then correctly garbage collected. - Prior versions either reported leaks or functioned as a garbage collector. - For the rest of this description we will give instructions that work with - any reasonable version of the collector. -To use the collector as a leak detector, follow the following steps: +To use the collector as a leak detector, do the following steps: - 1. Build the collector with `-DFIND_LEAK`. Otherwise use default build - options. + 1. Activate the leak detection mode as described above. 2. Change the program so that all allocation and deallocation goes through the garbage collector. - 3. Arrange to call `GC_gcollect` at appropriate points to check for leaks. - (For sufficiently long running programs, this will happen implicitly, but - probably not with sufficient frequency.) + 3. Arrange to call `GC_gcollect` (or `CHECK_LEAKS()`) at appropriate points + to check for leaks. (This happens implicitly but probably not with + a sufficient frequency for long running programs.) The second step can usually be accomplished with the `-DREDIRECT_MALLOC=GC_malloc` option when the collector is built, or by -defining `malloc`, `calloc`, `realloc` and `free` to call the corresponding +defining `malloc`, `calloc`, `realloc`, `free` (as well as `strdup`, +`strndup`, `wcsdup`, `memalign`, `posix_memalign`) to call the corresponding garbage collector functions. But this, by itself, will not yield very -informative diagnostics, since the collector does not keep track of +informative diagnostics, since the collector does not keep track of the information about how objects were allocated. The error reports will include only object addresses. @@ -56,11 +53,11 @@ generate additional bogus leak reports, since the collector itself drops some associated objects. -The same is generally true of thread support. However, as of 6.0alpha4, -correct leak reports should be generated with linuxthreads. +The same is generally true of thread support. However, the correct leak +reports should be generated with linuxthreads, at least. On a few platforms (currently Solaris/SPARC, Irix, and, with --DSAVE_CALL_CHAIN, Linux/X86), `GC_MALLOC` also causes some more information +`-DSAVE_CALL_CHAIN`, Linux/X86), `GC_MALLOC` also causes some more information about its call stack to be saved in the object. Such information is reproduced in the error reports in very non-symbolic form, but it can be very useful with the aid of a debugger. @@ -70,17 +67,17 @@ The `leak_detector.h` file is included in the "include" subdirectory of the distribution. -Assume the collector has been built with `-DFIND_LEAK`. (For newer versions -of the collector, we could instead add the statement `GC_set_find_leak(1)` as -the first statement in `main`. +Assume the collector has been built with `-DFIND_LEAK` or +`GC_set_find_leak(1)` exists as the first statement in `main`. -The program to be tested for leaks can then look like "leak_test.c" file -in the "tests" subdirectory of the distribution. +The program to be tested for leaks could look like `tests/leak_test.c` file +of the distribution. On an Intel X86 Linux system this produces on the stderr stream: - Leaked composite object at 0x806dff0 (leak_test.c:8, sz=4) + Found 1 leaked objects: + 0x806dff0 (tests/leak_test.c:19, sz=4, NORMAL) (On most unmentioned operating systems, the output is similar to this. If the @@ -91,7 +88,8 @@ On Irix it reports: - Leaked composite object at 0x10040fe0 (leak_test.c:8, sz=4) + Found 1 leaked objects: + 0x10040fe0 (tests/leak_test.c:19, sz=4, NORMAL) Caller at allocation: ##PC##= 0x10004910 @@ -99,7 +97,8 @@ and on Solaris the error report is: - Leaked composite object at 0xef621fc8 (leak_test.c:8, sz=4) + Found 1 leaked objects: + 0xef621fc8 (tests/leak_test.c:19, sz=4, NORMAL) Call chain at allocation: args: 4 (0x4), 200656 (0x30FD0) ##PC##= 0x14ADC @@ -110,27 +109,24 @@ In the latter two cases some additional information is given about how malloc was called when the leaked object was allocated. For Solaris, the first line specifies the arguments to `GC_debug_malloc` (the actual allocation routine), -The second the program counter inside main, the third the arguments to `main`, -and finally the program counter inside the caller to main (i.e. in the -C startup code). - -In the Irix case, only the address inside the caller to main is given. +The second one specifies the program counter inside `main`, the third one +specifies the arguments to `main`, and, finally, the program counter inside +the caller to `main` (i.e. in the C startup code). In the Irix case, only the +address inside the caller to `main` is given. In many cases, a debugger is needed to interpret the additional information. -On systems supporting the "adb" debugger, the `tools/callprocs.sh` script can -be used to replace program counter values with symbolic names. As of version -6.1, the collector tries to generate symbolic names for call stacks if it -knows how to do so on the platform. This is true on Linux/X86, but not on most -other platforms. +On systems supporting the `adb` debugger, the `tools/callprocs.sh` script can +be used to replace program counter values with symbolic names. The collector +tries to generate symbolic names for call stacks if it knows how to do so on +the platform. This is true on Linux/X86, but not on most other platforms. ## Simplified leak detection under Linux -Since version 6.1, it should be possible to run the collector in leak -detection mode on a program a.out under Linux/X86 as follows: +It should be possible to run the collector in the leak detection mode on +a program a.out under Linux/X86 as follows: - 1. _Ensure that a.out is a single-threaded executable, or you are using - a very recent (7.0alpha7+) collector version on Linux._ On most platforms - this does not work at all for the multi-threaded programs. + 1. If possible, ensure that a.out is a single-threaded executable. On some + platforms this does not work at all for the multi-threaded programs. 2. If possible, ensure that the `addr2line` program is installed in `/usr/bin`. (It comes with most Linux distributions.) 3. If possible, compile your program, which we'll call `a.out`, with full
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/overview.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/overview.md
Changed
@@ -4,13 +4,11 @@ # A garbage collector for C and C++ * Platforms - * Scalable multiprocessor versions * Some collector details * Further reading - * Current users - * Local Links for this collector - * Local Background Links - * Contacts and Mailing List + * Information provided on the BDWGC site + * More background information + * Contacts and new release announcements This is an updated version of the page formerly at `www.hpl.hp.com/personal/Hans_Boehm/gc/`, before that at @@ -41,6 +39,8 @@ Preview versions may contain additional features, platform support, but are likely to be less well tested. The list of changes for each version is specified on the releases(https://github.com/ivmai/bdwgc/releases) page. +The development version (snapshot) is available in the master branch of +bdwgc git(https://github.com/ivmai/bdwgc) repository on GitHub. The arguments for and against conservative garbage collection in C and C++ are briefly discussed here(http://www.hboehm.info/gc/issues.html). The @@ -50,51 +50,30 @@ The garbage collector code is copyrighted by Hans-J. Boehm(http://www.hboehm.info), Alan J. Demers, Xerox Corporation(http://www.xerox.com/), -Silicon Graphics(http://www.sgi.com/), and -Hewlett-Packard Company(http://www.hp.com/). It may be used and copied -without payment of a fee under minimal restrictions. See the README.md file -in the distribution or the license(http://www.hboehm.info/gc/license.txt) -for more details. **IT IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY -EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK**. +Silicon Graphics(http://www.sgi.com/), +Hewlett-Packard Company(http://www.hp.com/), +Ivan Maidanski(https://github.com/ivmai), and partially by some others. +It may be used and copied without payment of a fee under minimal restrictions. +See the README.md file in the distribution or the +license(http://www.hboehm.info/gc/license.txt) for more details. +**IT IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR IMPLIED. +ANY USE IS AT YOUR OWN RISK.** Empirically, this collector works with most unmodified C programs, simply -by replacing `malloc` with `GC_malloc` calls, replacing `realloc` with -`GC_realloc` calls, and removing free calls. Exceptions are discussed +by replacing `malloc` and `calloc` with `GC_malloc` calls, replacing `realloc` +with `GC_realloc` calls, and removing `free` calls. Exceptions are discussed here(http://www.hboehm.info/gc/issues.html). ## Platforms The collector is not completely portable, but the distribution includes ports to most standard PC and UNIX/Linux platforms. The collector should work -on Linux, *BSD, recent Windows versions, MacOS X, HP/UX, Solaris, Tru64, Irix -and a few other operating systems. Some ports are more polished than others. +on Linux, Android, BSD variants, OS/2, Windows (Win32 and Win64), MacOS X, +iOS, HP/UX, Solaris, Tru64, Irix, Symbian and other operating systems. Some +platforms are more polished (better supported) than others. -Irix pthreads, Linux threads, Win32 threads, Solaris threads (pthreads only), -HP/UX 11 pthreads, Tru64 pthreads, and MacOS X threads are supported in recent -versions. - -### Separately distributed ports - -For MacOS 9/Classic use, Patrick Beard's latest port is available from -`http://homepage.mac.com/pcbeard/gc/`. (Unfortunately, that's now quite dated. -I'm not in a position to test under MacOS. Although I try to incorporate -changes, it is impossible for me to update the project file.) - -Precompiled versions of the collector for NetBSD are available -here(ftp://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/devel/boehm-gc/README.html). - - -Debian Linux(http://www.debian.org/) includes prepackaged versions of the -collector. - -## Scalable multiprocessor versions - -Kenjiro Taura, Toshio Endo, and Akinori Yonezawa have made available -a parallel collector(http://ieeexplore.ieee.org/abstract/document/1592629/) -based on this one. Their collector takes advantage of multiple processors -during a collection. Starting with GC v6.0alpha1 we also do this, though with -more modest processor scalability goals. Our approach is discussed briefly -in this document(scale.md). +Irix pthreads, Linux threads, Windows threads, Solaris threads (pthreads +only), HP/UX 11 pthreads, Tru64 pthreads, and MacOS X threads are supported. ## Some Collector Details @@ -102,7 +81,7 @@ algorithm. It provides incremental and generational collection under operating systems which provide the right kind of virtual memory support. (Currently this includes SunOS45, IRIX, OSF/1, Linux, and Windows, with varying -restrictions.) It allows _finalization_(finalization.md) code to be invoked +restrictions.) It allows finalization(finalization.md) code to be invoked when an object is collected. It can take advantage of type information to locate pointers if such information is provided, but it is usually used without such information. See the README and `gc.h` files in the distribution @@ -127,16 +106,18 @@ `malloc`/`free` allocation in time. We also expect that in many cases any additional overhead will be more than -compensated for by decreased copying etc. if programs are written and tuned +compensated for by e.g. decreased copying if programs are written and tuned for garbage collection. ## Further reading **The beginnings of a frequently asked questions list for this collector are -here(http://www.hboehm.info/gc/faq.html)**. +here(http://www.hboehm.info/gc/faq.html).** + +**The following provide information on garbage collection in general:** -**The following provide information on garbage collection in general**: Paul -Wilson's garbage collection ftp archive(ftp://ftp.cs.utexas.edu/pub/garbage) +Paul Wilson's +garbage collection ftp archive(ftp://ftp.cs.utexas.edu/pub/garbage) and GC survey(ftp://ftp.cs.utexas.edu/pub/garbage/gcsurvey.ps). The Ravenbrook @@ -149,7 +130,7 @@ and his book(http://www.cs.kent.ac.uk/people/staff/rej/gcbook/gcbook.html). **The following papers describe the collector algorithms we use and the -underlying design decisions at a higher level.** +underlying design decisions at a higher level:** (Some of the lower level details can be found here(gcdescr.md).) @@ -206,7 +187,7 @@ test for the potential of unbounded heap growth. **The following papers discuss language and compiler restrictions necessary -to guaranteed safety of conservative garbage collection.** +to guaranteed safety of conservative garbage collection:** We thank John Levine and JCLT for allowing us to make the second paper available electronically, and providing PostScript for the final version. @@ -239,69 +220,11 @@ Slides for Hans Boehm's Allocation and GC Myths(http://www.hboehm.info/gc/myths.ps) talk. -## Current users - -Known current users of some variant of this collector include: - -The runtime system for GCJ(https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcj/), -the static GNU java compiler. - -W3m(http://w3m.sourceforge.net/), a text-based web browser. - -Some versions of the Xerox DocuPrint printer software. - -The Mozilla(http://www.mozilla.org/) project, as leak detector. - -The Mono(http://www.mono-project.com) project, an open source implementation -of the .NET development framework. - -The DotGNU Portable.NET project(http://www.gnu.org/projects/dotgnu/), -another open source .NET implementation. - -The Irssi IRC client(http://irssi.org/). - -The Berkeley Titanium project(http://titanium.cs.berkeley.edu/). - -The NAGWare f90 Fortran 90 compiler(http://www.nag.co.uk/nagware/NP/NP_desc.asp). - -Elwood Corporation's Eclipse Common Lisp system, C library, and translator. - -The Bigloo Scheme(http://www-sop.inria.fr/mimosa/fp/Bigloo/) and -Camloo ML compilers(https://github.com/samoht/camloo) written by Manuel -Serrano and others. - -Brent Benson's -libscheme(http://www.cs.indiana.edu/scheme-repository/libscheme-vhll/final.html). - -The MzScheme scheme implementation. - -The -University of Washington Cecil Implementation(http://www.cs.washington.edu/research/projects/cecil/www/cecil-home.html). - -The Berkeley Sather implementation(http://www1.icsi.berkeley.edu/~sather/). - -The Berkeley Harmonia Project(http://www.cs.berkeley.edu/~harmonia/harmonia/index.html). - -The -Toba(http://www.cs.arizona.edu/projects/sumatra/toba/) Java Virtual Machine -to C translator. - -The Gwydion Dylan compiler(http://www.gwydiondylan.org/). - -The -GNU Objective C runtime(http://gcc.gnu.org/onlinedocs/gcc/Objective-C.html). - -Macaulay 2(http://www.math.uiuc.edu/Macaulay2), a system to support research -in algebraic geometry and commutative algebra. - -The Vesta(http://www.vestasys.org/) configuration management system. - -Visual Prolog 6(http://www.visual-prolog.com/). - -Asymptote LaTeX-compatible vector graphics language(http://asymptote.sf.net/). - ## Information provided on the BDWGC site +Current users(https://github.com/ivmai/bdwgc/wiki/Known-clients) (the list +may be rather outdated). + A simple illustration of how to build and use the collector(simple_example.md). Description of alternate interfaces to the garbage collector(gcinterface.md).
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/porting.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/porting.md
Changed
@@ -6,8 +6,7 @@ All of the following assumes that the collector is being ported to a byte-addressable 32- or 64-bit machine. Currently all successful ports -to 64-bit machines involve LP64 targets. The code base includes some -provisions for P64 targets (notably Win64), but that has not been tested. You +to 64-bit machines involve LP64 and LLP64 targets (notably Win64). You are hereby discouraged from attempting a port to non-byte-addressable, or 8-bit, or 16-bit machines. @@ -96,7 +95,7 @@ is found. This often works on Posix-like platforms. It makes it harder to debug client programs, since startup involves generating and catching a segmentation fault, which tends to confuse users. - * `DATAEND` - Set to the end of the main data segment. Defaults to `end`, + * `DATAEND` - Set to the end of the main data segment. Defaults to `_end`, where that is declared as an array. This works in some cases, since the linker introduces a suitable symbol. * `DATASTART2`, `DATAEND2` - Some platforms have two discontiguous main data @@ -107,20 +106,21 @@ architecture has more than one stack per thread, and is not supported yet, you will need to do more work. Grep for "IA64" in the source for an example.) - * `STACKBOTTOM` - Defined to be the cool end of the stack, which is usually - the highest address in the stack. It must bound the region of the stack that - contains pointers into the GC heap. With thread support, this must be the - cold end of the main stack, which typically cannot be found in the same way - as the other thread stacks. If this is not defined and none of the following - three macros is defined, client code must explicitly set `GC_stackbottom` - to an appropriate value before calling `GC_INIT` or any other `GC_` routine. + * `STACKBOTTOM` - Defined to be the cold end of the stack, which is usually + (i.e. when the stacks grow down) the highest address in the stack. It must + bound the region of the stack that contains pointers into the GC heap. With + thread support, this must be the cold end of the main stack, which typically + cannot be found in the same way as the other thread stacks. If this is not + defined and none of the following three macros is defined, client code must + explicitly set `GC_stackbottom` to an appropriate value before calling + `GC_INIT` or any other `GC_` routine. * `LINUX_STACKBOTTOM` - May be defined instead of `STACKBOTTOM`. If defined, then the cold end of the stack will be determined, we usually read it from `/proc`. * `HEURISTIC1` - May be defined instead of `STACKBOTTOM`. `STACK_GRAN` should generally also be redefined. The cold end of the stack is determined by taking an address inside `GC_init`s frame, and rounding it up to the next - multiple of `STACK_GRAN`. This works well if the stack base is always + multiple of `STACK_GRAN`. This works well if the stack bottom is always aligned to a large power of two. (`STACK_GRAN` is predefined to 0x1000000, which is rarely optimal.) * `HEURISTIC2` - May be defined instead of `STACKBOTTOM`. The cold end @@ -128,14 +128,16 @@ incrementing it repeatedly in small steps (decrement if `STACK_GROWS_UP`), and reading the value at each location. We remember the value when the first Segmentation violation or Bus error is signaled, round that to the nearest - plausible page boundary, and use that as the stack base. + plausible page boundary, and use that as the stack bottom. * `DYNAMIC_LOADING` - Should be defined if `dyn_load.c` has been updated for this platform and tracing of dynamic library roots is supported. - * `MPROTECT_VDB`, `PROC_VDB` - May be defined if the corresponding - _virtual dirty bit_ implementation in `os_dep.c` is usable on this platform. - This allows incremental/generational garbage collection. `MPROTECT_VDB` - identifies modified pages by write protecting the heap and catching faults. - `PROC_VDB` uses the /proc primitives to read dirty bits. + * `GWW_VDB`, `MPROTECT_VDB`, `PROC_VDB`, `SOFT_VDB` - May be defined if the + corresponding _virtual dirty bit_ implementation in `os_dep.c` is usable on + this platform. This allows incremental/generational garbage collection. + (`GWW_VDB` uses the Win32 `GetWriteWatch` function to read dirty bits, + `MPROTECT_VDB` identifies modified pages by write protecting the heap and + catching faults. `PROC_VDB` and `SOFT_VDB` use the /proc pseudo-files to + read dirty bits.) * `PREFETCH`, `GC_PREFETCH_FOR_WRITE` - The collector uses `PREFETCH(x)` to preload the cache with the data at _x_ address. This defaults to a no-op. * `CLEAR_DOUBLE` - If `CLEAR_DOUBLE` is defined, then `CLEAR_DOUBLE(x)` @@ -153,7 +155,7 @@ this can be done portably, but on some platforms it may require assembly code, or just tweaking of conditional compilation tests. -For GC v7, if your platform supports `getcontext`, then defining the macro +If your platform supports `getcontext` then defining the macro `UNIX_LIKE` for your OS in `gcconfig.h` (if it is not defined there yet) is likely to solve the problem. Otherwise, if you are using gcc, `_builtin_unwind_init` will be used, and should work fine. If that is not @@ -161,10 +163,8 @@ if your `setjmp` implementation saves all possibly pointer-valued registers into the buffer, as opposed to trying to unwind the stack at `longjmp` time. The `setjmp_test` test tries to determine this, but often does not get it -right. - -In GC v6.x versions of the collector, tracing of registers was more commonly -handled with assembly code. In GC v7, this is generally to be avoided. +right. Registers tracing handled with an assembly code is generally to be +avoided. Most commonly `os_dep.c` will not require attention, but see below. @@ -198,7 +198,7 @@ be automatically defined by `gc_config_macros.h` in the right cases. It should also result in a definition of `GC_PTHREADS`, as for the existing cases. - 2. For GC v7, ensuring that the `atomic_ops` package at least minimally + 2. Ensuring that the `atomic_ops` package at least minimally supports the platform. If incremental GC is needed, or if pthread locks do not perform adequately as the allocation lock, you will probably need to ensure that a sufficient `atomic_ops` port exists for the platform @@ -211,7 +211,7 @@ workarounds are common. Non-preemptive threads packages will probably require further work. Similarly thread-local allocation and parallel marking requires further work in `pthread_support.c`, and may require better - `atomic_ops` support. + `atomic_ops` support for the designed platform. ## Dynamic library support
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/scale.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/scale.md
Changed
@@ -1,12 +1,14 @@ # Garbage collector scalability -In its default configuration, the Boehm-Demers-Weiser garbage collector is not -thread-safe. It can be made thread-safe for a number of environments -by building the collector with `-DGC_THREADS` compilation flag. This has -primarily two effects: +If Makefile.direct is used, in its default configuration the +Boehm-Demers-Weiser garbage collector is not thread-safe. Generally, it can be +made thread-safe by building the collector with `-DGC_THREADS` compilation +flag. This has primarily the following effects: 1. It causes the garbage collector to stop all other threads when it needs - to see a consistent memory state. + to see a consistent memory state. It intercepts thread creation and + termination events to maintain a list of client threads to be stopped when + needed. 2. It causes the collector to acquire a lock around essentially all allocation and garbage collection activity. Since a single lock is used for all allocation-related activity, only one thread can be allocating @@ -16,36 +18,35 @@ On most platforms, the allocator/collector lock is implemented as a spin lock with exponential back-off. Longer wait times are implemented by yielding and/or sleeping. If a collection is in progress, the pure spinning stage -is skipped. This has the advantage that uncontested and thus most uniprocessor -lock acquisitions are very cheap. It has the disadvantage that the application -may sleep for small periods of time even when there is work to be done. And +is skipped. This has the uncontested advantage that most uniprocessor lock +acquisitions are very cheap. It has the disadvantage that the application may +sleep for small periods of time even when there is work to be done. And threads may be unnecessarily woken up for short periods. Nonetheless, this scheme empirically outperforms native queue-based mutual exclusion implementations in most cases, sometimes drastically so. ## Options for enhanced scalability -Version 6.0 of the collector adds two facilities to enhance collector -scalability on multiprocessors. As of 6.0alpha1, these are supported only -under Linux on X86 and IA64 processors, though ports to other otherwise -supported Pthreads platforms should be straightforward. They are intended -to be used together. +The collector uses two facilities to enhance collector scalability on +multiprocessors. They are intended to be used together. (The following refers +to Makefile.direct again.) * Building the collector with `-DPARALLEL_MARK` allows the collector to run the mark phase in parallel in multiple threads, and thus on multiple - processors. The mark phase typically consumes the large majority of the - collection time. Thus this largely parallelizes the garbage collector - itself, though not the allocation process. Currently the marking + processors (or processor cores). The mark phase typically consumes the large + majority of the collection time. Thus, this largely parallelizes the garbage + collector itself, though not the allocation process. Currently the marking is performed by the thread that triggered the collection, together with - _N_ - 1 dedicated threads, where _N_ is the number of processors detected - by the collector. The dedicated threads are created once at initialization - time (and optionally recreated in child processes after forking). - A second effect of this flag is to switch to a more concurrent - implementation of `GC_malloc_many`, so that free lists can be built, and - memory can be cleared, by more than one thread concurrently. + _N_ - 1 dedicated threads, where _N_ is the number of processors (cores) + detected by the collector. The dedicated marker threads are created when the + client calls `GC_start_mark_threads()` or when the client starts the first + non-main thread after the GC initialization (or after fork operation in + a child process). Another effect of this flag is to switch to a more + concurrent implementation of `GC_malloc_many`, so that free lists can be + built and memory can be cleared by more than one thread concurrently. * Building the collector with `-DTHREAD_LOCAL_ALLOC` adds support for - thread-local allocation. This causes `GC_malloc`, `GC_malloc_atomic`, and - `GC_gcj_malloc` to be redefined to perform thread-local allocation. + thread-local allocation. This causes `GC_malloc` (actually `GC_malloc_kind`) + and `GC_gcj_malloc` to be redefined to perform thread-local allocation. Memory returned from thread-local allocators is completely interchangeable with that returned by the standard allocators. It may be used by other @@ -58,7 +59,7 @@ spin-then-sleep lock to be replaced by a spin-then-queue based implementation. This _reduces performance_ for the standard allocation functions, though it usually improves performance when thread-local allocation is used heavily, -and thus the number of short-duration lock acquisitions is greatly reduced. +and, thus, the number of short-duration lock acquisitions is greatly reduced. ## The Parallel Marking Algorithm @@ -86,18 +87,19 @@ The sequential marking code is reused to process local mark stacks. Hence the amount of additional code required for parallel marking is minimal. -It should be possible to use generational collection in the presence of the -parallel collector, by calling `GC_enable_incremental`. This does not result -in fully incremental collection, since parallel mark phases cannot currently -be interrupted, and doing so may be too expensive. +It should be possible to use incremental/generational collection in the +presence of the parallel collector by calling `GC_enable_incremental`, but +the current implementation does not allow interruption of the parallel marker, +so the latter is mostly avoided if the client sets the collection time limit. Gcj-style mark descriptors do not currently mix with the combination of local allocation and incremental collection. They should work correctly with one or the other, but not both. The number of marker threads is set on startup to the number of available -processors (or to the value of the `GC_NPROCS` environment variable). If only -a single processor is detected, parallel marking is disabled. +processor cores (or to the value of either `GC_MARKERS` or `GC_NPROCS` +environment variable, if provided). If only a single processor is detected, +parallel marking is disabled. Note that setting `GC_NPROCS` to 1 also causes some lock acquisitions inside the collector to immediately yield the processor instead of busy waiting @@ -112,15 +114,15 @@ modified to run multiple concurrent client threads in the same address space. Each client thread does the same work as the original benchmark, but they share a heap. This benchmark involves very little work outside of memory -allocation. This was run with GC 6.0alpha3 on a dual processor Pentium III/500 -machine under Linux 2.2.12. +allocation. This was run with an ancient GC (released in 2000) on a dual +processor Pentium III/500 machine under Linux 2.2.12. Running with a thread-unsafe collector, the benchmark ran in 9 seconds. With the simple thread-safe collector, built with `-DGC_THREADS`, the execution time increased to 10.3 seconds, or 23.5 elapsed seconds with two clients. (The times for the `malloc`/`free` version with glibc `malloc` are 10.51 (standard library, pthreads not linked), 20.90 (one thread, pthreads linked), and 24.55 -seconds respectively. The benchmark favors a garbage collector, since most +seconds, respectively. The benchmark favors a garbage collector, since most objects are small.) The following table gives execution times for the collector built with @@ -164,7 +166,7 @@ kind of hardware even with such a small number of processors, since the memory system is a major constraint for the garbage collector, the processors usually share a single memory bus, and thus the aggregate memory bandwidth does not -increase in proportion to the number of processors. +increase in proportion to the number of processors (cores). These results are likely to be very sensitive to both hardware and OS issues. Preliminary experiments with an older Pentium Pro machine running an older
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/simple_example.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/simple_example.md
Changed
@@ -137,8 +137,8 @@ Additional debug checks can be performed by defining `GC_DEBUG` before including `gc.h`. Additional options are available if the collector is also -built with `--enable-gc-debug` (`--enable-full-debug` in some older versions) -and all allocations are performed with `GC_DEBUG` defined. +built with `--enable-gc-debug` and all allocations are performed with +`GC_DEBUG` defined. ### What if I can't rewrite/recompile my program?
View file
_service:tar_scm:gc-8.0.6.tar.gz/doc/tree.md -> _service:tar_scm:gc-8.2.2.tar.gz/doc/tree.md
Changed
@@ -77,99 +77,101 @@ ## A picture -The following is an _ASCII_ diagram of the data structure used by GC_base (as -of GC v3.7, Apr 21, 1994). This was contributed by Dave Barrett. - - - 63 LOG_TOP_SZ11 LOG_BOTTOM_SZ10 LOG_HBLKSIZE13 - +------------------+----------------+------------------+------------------+ - p:| | TL_HASH(hi) | | HBLKDISPL(p) | - +------------------+----------------+------------------+------------------+ - \-----------------------HBLKPTR(p)-------------------/ - \------------hi-------------------/ - \______ ________/ \________ _______/ \________ _______/ - V V V - | | | - GC_top_index | | | - --- +--------------+ | | | - ^ | | | | | - | | | | | | - TOP +--------------+<--+ | | - _SZ +-<| | * | | - (items)| +--------------+ if 0 < bi< HBLKSIZE | | - | | | | then large object | | - | | | | starts at the bi'th | | - v | | | HBLK before p. | i | - --- | +--------------+ | (word- | - v | aligned) | - bi= |GET_BI(p){->hash_link}->key==hi | | - v | | - | (bottom_index) \ scratch_alloc'd | | - | ( struct bi ) / by get_index() | | - --- +->+--------------+ | | - ^ | | | | - ^ | | | | - BOTTOM | | ha=GET_HDR_ADDR(p) | | - _SZ(items)+--------------+<----------------------+ +-------+ - | +--<| index | | - | | +--------------+ GC_obj_map: v - | | | | from / +-+-+-----+-+-+-+-+ --- - v | | | GC_add < 0| | | | | | | | ^ - --- | +--------------+ _map_entry \ +-+-+-----+-+-+-+-+ | - | | asc_link | +-+-+-----+-+-+-+-+ MAXOBJSZ - | +--------------+ +-->| | | j | | | | | +1 - | | key | | +-+-+-----+-+-+-+-+ | - | +--------------+ | +-+-+-----+-+-+-+-+ | - | | hash_link | | | | | | | | | | v - | +--------------+ | +-+-+-----+-+-+-+-+ --- - | | |<--MAX_OFFSET--->| - | | (bytes) - HDR(p)| GC_find_header(p) | |<--MAP_ENTRIES-->| - | \ from | =HBLKSIZE/WORDSZ - | (hdr) (struct hblkhdr) / alloc_hdr() | (1024 on Alpha) - +-->+----------------------+ | (8/16 bits each) - GET_HDR(p)| word hb_sz (words) | | - +----------------------+ | - | struct hblk *hb_next | | - +----------------------+ | - |mark_proc hb_mark_proc| | - +----------------------+ | - | char * hb_map |>-------------+ - +----------------------+ - | ushort hb_obj_kind | - +----------------------+ - | hb_last_reclaimed | - --- +----------------------+ - ^ | | - MARK_BITS| hb_marks | * if hdr is free, hb_sz is the size of - _SZ(words)| | a heap chunk (struct hblk) of at least - v | | MININCR*HBLKSIZE bytes (below), - --- +----------------------+ otherwise, size of each object in chunk. +The following is an _ASCII_ diagram of the data structure used by GC_base. This was +contributed originally by Dave Barrett. + + + 63 LOG_TOP_SZ11 LOG_BOTTOM_SZ10 LOG_HBLKSIZE13 + +------------------+----------------+------------------+------------------+ + p:| | TL_HASH(hi) | | HBLKDISPL(p) | + +------------------+----------------+------------------+------------------+ + \-----------------------HBLKPTR(p)-------------------/ + \------------hi-------------------/ + \______ ________/ \________ _______/ \________ _______/ + V V V + | | | + GC_top_index | | | + --- +--------------+ | | | + ^ | | | | | + | | | | | | + TOP_SZ +--------------+<--+ | | + (items)+-<| | * | | + | | +--------------+ if 0 < bi< HBLKSIZE | | + | | | | then large object | | + | | | | starts at the bi'th | | + v | | | hblk before p. | i | + --- | +--------------+ | (word- | + v | aligned) | + bi= |GET_BI(p){->hash_link}->key==hi | | + v | | + | (bottom_index) \ scratch_alloc'd | | + | ( struct bi ) / by get_index() | | + --- +->+--------------+ | | + ^ | | | | + | | | | | + BOTTOM_SZ | | ha=GET_HDR_ADDR(p) | | + (items) +--------------+<----------------------+ +-------+ + | +--<| index | | + | | +--------------+ GC_obj_map: v + | | | | from / +-+-+-----+-+-+-+-+ --- + v | | | GC_add_map_entry <0| | | | | | | | ^ + --- | +--------------+ \ +-+-+-----+-+-+-+-+ | + | | asc_link | +-+-+-----+-+-+-+-+ MAXOBJGRANULES + | +--------------+ +-->| | | j | | | | | +1 + | | key | | +-+-+-----+-+-+-+-+ | + | +--------------+ | +-+-+-----+-+-+-+-+ | + | | hash_link | | | | | | | | | | v + | +--------------+ | +-+-+-----+-+-+-+-+ --- + | | |<----MAP_LEN---->| + | | =HBLKSIZE/GRANULE_BYTES + HDR(p)| GC_find_header(p) | (1024 on Alpha) + | \ from | (8/16 bits each) + | (hdr) (struct hblkhdr) / alloc_hdr() | + +--->+----------------------+ | + GET_HDR(p)| word hb_sz (words) | | + +----------------------+ | + | struct hblk *hb_next | | + +----------------------+ | + | word hb_descr | | + +----------------------+ | + | char * hb_map |>------------+ + +----------------------+ + | uchar hb_obj_kind | + +----------------------+ + | uchar hb_flags | + +----------------------+ + | hb_last_reclaimed | + --- +----------------------+ + ^ | | + MARK_BITS_SZ| hb_marks | * if hdr is free, hb_sz is the size of + (words) | | a heap chunk (struct hblk) of at least + v | | MININCR*HBLKSIZE bytes (below), + --- +----------------------+ otherwise, size of each object in chunk. Dynamic data structures above are interleaved throughout the heap in blocks of size `MININCR * HBLKSIZE` bytes as done by `gc_scratch_alloc` which cannot -be freed; free lists are used (e.g. `alloc_hdr`). `HBLK`'s below are +be freed; free lists are used (e.g. `alloc_hdr`). `hblk`'s below are collected. - (struct hblk) HDR_BYTES - --- +----------------------+ < HBLKSIZE --- (bytes) - ^ +-----hb_body----------+ (and WORDSZ) ^ --- --- - | | | aligned | ^ ^ - | | | | hb_sz | - | | | | (words) | - | | Object 0 | | | | - | | | i |(word- v | - | + - - - - - - - - - - -+ --- (bytes)|aligned) --- | - | | | ^ | ^ | - | | | j (words) | | | - n * | Object 1 | v v hb_sz BODY_SZ - HBLKSIZE | |--------------- | (words) - (bytes) | | v MAX_OFFSET - | + - - - - - - - - - - -+ --- (bytes) - | | | !ALL_INTERIOR_POINTERS ^ | - | | | sets j only for hb_sz | - | | Object N | valid object offsets. | | - v | | All objects WORDSZ v v - --- +----------------------+ aligned. --- --- + (struct hblk) + --- +----------------------+ < HBLKSIZE --- + ^ +-----hb_body----------+ (and WORDSZ) ^ --- --- + | | | aligned | ^ ^ + | | | | hb_sz | + | | | | (words) | + | | Object 0 | | | | + | | | i |(word- v | + | + - - - - - - - - - - -+ --- (bytes)|aligned) --- | + | | | ^ | ^ | + | | | j (words) | | | + n * | Object 1 | v v hb_sz HBLKSIZE/BYTES_PER_WORD + HBLKSIZE | |--------------- | (words) + (bytes) | | v | + | + - - - - - - - - - - -+ --- | + | | | !ALL_INTERIOR_POINTERS ^ | + | | | sets j only for hb_sz | + | | Object N | valid object offsets. | | + v | | All objects WORDSZ- v v + --- +----------------------+ aligned. --- ---
View file
_service:tar_scm:gc-8.0.6.tar.gz/dyn_load.c -> _service:tar_scm:gc-8.2.2.tar.gz/dyn_load.c
Changed
@@ -1,6 +1,7 @@ /* * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1997 by Silicon Graphics. All rights reserved. + * Copyright (c) 2009-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -26,7 +27,7 @@ * But then not much of anything is safe in the presence of dlclose. */ -#if !defined(MACOS) && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) \ +#if !defined(MACOS) && !defined(GC_NO_TYPES) && !defined(SN_TARGET_PSP2) \ && !defined(_WIN32_WCE) && !defined(__CC_ARM) # include <sys/types.h> #endif @@ -58,10 +59,10 @@ && !defined(CYGWIN32) && !defined(MSWIN32) && !defined(MSWINCE) \ && !(defined(ALPHA) && defined(OSF1)) \ && !(defined(FREEBSD) && defined(__ELF__)) \ - && !((defined(LINUX) || defined(NACL)) && defined(__ELF__)) \ + && !(defined(LINUX) && defined(__ELF__)) \ && !(defined(NETBSD) && defined(__ELF__)) \ - && !defined(HAIKU) && !defined(HURD) \ && !(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) \ + && !defined(HAIKU) && !defined(HURD) && !defined(NACL) \ && !defined(CPPCHECK) # error We only know how to find data segments of dynamic libraries for above. # error Additional SVR4 variants might not be too hard to add. @@ -88,10 +89,9 @@ # endif #endif /* OPENBSD */ -#if defined(SCO_ELF) || defined(DGUX) || defined(HURD) \ +#if defined(SCO_ELF) || defined(DGUX) || defined(HURD) || defined(NACL) \ || (defined(__ELF__) && (defined(LINUX) || defined(FREEBSD) \ - || defined(NACL) || defined(NETBSD) \ - || defined(OPENBSD))) + || defined(NETBSD) || defined(OPENBSD))) # include <stddef.h> # if !defined(OPENBSD) && !defined(HOST_ANDROID) /* OpenBSD does not have elf.h file; link.h below is sufficient. */ @@ -150,8 +150,10 @@ # elif defined(NETBSD) || defined(OPENBSD) # if ELFSIZE == 32 # define ElfW(type) Elf32_##type -# else +# elif ELFSIZE == 64 # define ElfW(type) Elf64_##type +# else +# error Missing ELFSIZE define # endif # else # if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32 @@ -259,10 +261,9 @@ # endif /* !USE_PROC ... */ # endif /* SOLARISDL */ -#if defined(SCO_ELF) || defined(DGUX) || defined(HURD) \ +#if defined(SCO_ELF) || defined(DGUX) || defined(HURD) || defined(NACL) \ || (defined(__ELF__) && (defined(LINUX) || defined(FREEBSD) \ - || defined(NACL) || defined(NETBSD) \ - || defined(OPENBSD))) + || defined(NETBSD) || defined(OPENBSD))) #ifdef USE_PROC_FOR_LIBRARIES @@ -305,10 +306,9 @@ } } -STATIC void GC_register_map_entries(char *maps) +STATIC void GC_register_map_entries(const char *maps) { - char *prot; - char *buf_ptr = maps; + const char *prot; ptr_t start, end; unsigned int maj_dev; ptr_t least_ha, greatest_ha; @@ -321,10 +321,9 @@ + GC_our_memoryGC_n_memory-1.hs_bytes; for (;;) { - buf_ptr = GC_parse_map_entry(buf_ptr, &start, &end, &prot, - &maj_dev, 0); - if (NULL == buf_ptr) - break; + maps = GC_parse_map_entry(maps, &start, &end, &prot, &maj_dev, 0); + if (NULL == maps) break; + if (prot1 == 'w') { /* This is a writable mapping. Add it to */ /* the root set unless it is already otherwise */ @@ -399,11 +398,7 @@ GC_INNER void GC_register_dynamic_libraries(void) { - char *maps = GC_get_maps(); - - if (NULL == maps) - ABORT("Failed to read /proc for library registration"); - GC_register_map_entries(maps); + GC_register_map_entries(GC_get_maps()); } /* We now take care of the main data segment ourselves: */ @@ -841,7 +836,7 @@ } if (ioctl(fd, PIOCNMAP, &needed_sz) < 0) { ABORT_ARG2("/proc PIOCNMAP ioctl failed", - ": fd = %d, errno = %d", fd, errno); + ": fd= %d, errno= %d", fd, errno); } if (needed_sz >= current_sz) { GC_scratch_recycle_no_gww(addr_map, @@ -857,7 +852,7 @@ ABORT_ARG3("/proc PIOCMAP ioctl failed", ": errcode= %d, needed_sz= %d, addr_map= %p", errno, needed_sz, (void *)addr_map); - }; + } if (GC_n_heap_sects > 0) { heap_end = GC_heap_sectsGC_n_heap_sects-1.hs_start + GC_heap_sectsGC_n_heap_sects-1.hs_bytes; @@ -919,6 +914,8 @@ } /* Don't keep cached descriptor, for now. Some kernels don't like us */ /* to keep a /proc file descriptor around during kill -9. */ + /* Otherwise, it should also require FD_CLOEXEC and proper handling */ + /* at fork (i.e. close because of the pid change). */ if (close(fd) < 0) ABORT("Couldn't close /proc file"); fd = -1; } @@ -927,11 +924,6 @@ # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> # include <stdlib.h> /* We traverse the entire address space and register all segments */ @@ -985,11 +977,12 @@ # ifdef DEBUG_VIRTUALQUERY void GC_dump_meminfo(MEMORY_BASIC_INFORMATION *buf) { - GC_printf("BaseAddress = 0x%lx, AllocationBase = 0x%lx," - " RegionSize = 0x%lx(%lu)\n", buf -> BaseAddress, - buf -> AllocationBase, buf -> RegionSize, buf -> RegionSize); - GC_printf("\tAllocationProtect = 0x%lx, State = 0x%lx, Protect = 0x%lx, " - "Type = 0x%lx\n", buf -> AllocationProtect, buf -> State, + GC_printf("BaseAddress= 0x%lx, AllocationBase= 0x%lx," + " RegionSize= 0x%lx(%lu)\n", + buf -> BaseAddress, buf -> AllocationBase, + buf -> RegionSize, buf -> RegionSize); + GC_printf("\tAllocationProtect= 0x%lx, State= 0x%lx, Protect= 0x%lx, " + "Type= 0x%lx\n", buf -> AllocationProtect, buf -> State, buf -> Protect, buf -> Type); } # endif /* DEBUG_VIRTUALQUERY */ @@ -1118,10 +1111,10 @@ # ifdef DL_VERBOSE GC_log_printf("---Module---\n"); - GC_log_printf("Module ID\t = %16ld\n", moduleinfo.lmi_modid); - GC_log_printf("Count of regions = %16d\n", moduleinfo.lmi_nregion); - GC_log_printf("flags for module = %16lx\n", moduleinfo.lmi_flags); - GC_log_printf("module pathname\t = \"%s\"\n", moduleinfo.lmi_name); + GC_log_printf("Module ID: %ld\n", moduleinfo.lmi_modid); + GC_log_printf("Count of regions: %d\n", moduleinfo.lmi_nregion); + GC_log_printf("Flags for module: %016lx\n", moduleinfo.lmi_flags); + GC_log_printf("Module pathname: \"%s\"\n", moduleinfo.lmi_name); # endif /* For each region in this module */ @@ -1138,14 +1131,12 @@ # ifdef DL_VERBOSE GC_log_printf("--- Region ---\n"); - GC_log_printf("Region number\t = %16ld\n", - regioninfo.lri_region_no); - GC_log_printf("Protection flags = %016x\n", regioninfo.lri_prot); - GC_log_printf("Virtual address\t = %16p\n", regioninfo.lri_vaddr); - GC_log_printf("Mapped address\t = %16p\n", - regioninfo.lri_mapaddr); - GC_log_printf("Region size\t = %16ld\n", regioninfo.lri_size); - GC_log_printf("Region name\t = \"%s\"\n", regioninfo.lri_name); + GC_log_printf("Region number: %ld\n", regioninfo.lri_region_no); + GC_log_printf("Protection flags: %016x\n", regioninfo.lri_prot); + GC_log_printf("Virtual address: %p\n", regioninfo.lri_vaddr); + GC_log_printf("Mapped address: %p\n", regioninfo.lri_mapaddr); + GC_log_printf("Region size: %ld\n", regioninfo.lri_size); + GC_log_printf("Region name: \"%s\"\n", regioninfo.lri_name); # endif /* register region as a garbage collection root */ @@ -1197,15 +1188,14 @@ # ifdef DL_VERBOSE GC_log_printf("---Shared library---\n"); - GC_log_printf("\tfilename\t= \"%s\"\n", shl_desc->filename); - GC_log_printf("\tindex\t\t= %d\n", index); - GC_log_printf("\thandle\t\t= %08x\n", - (unsigned long) shl_desc->handle); - GC_log_printf("\ttext seg.start\t= %08x\n", shl_desc->tstart); - GC_log_printf("\ttext seg.end\t= %08x\n", shl_desc->tend); - GC_log_printf("\tdata seg.start\t= %08x\n", shl_desc->dstart); - GC_log_printf("\tdata seg.end\t= %08x\n", shl_desc->dend); - GC_log_printf("\tref.count\t= %lu\n", shl_desc->ref_count); + GC_log_printf("filename= \"%s\"\n", shl_desc->filename); + GC_log_printf("index= %d\n", index); + GC_log_printf("handle= %08x\n", (unsigned long) shl_desc->handle); + GC_log_printf("text seg.start= %08x\n", shl_desc->tstart); + GC_log_printf("text seg.end= %08x\n", shl_desc->tend); + GC_log_printf("data seg.start= %08x\n", shl_desc->dstart); + GC_log_printf("data seg.end= %08x\n", shl_desc->dend); + GC_log_printf("ref.count= %lu\n", shl_desc->ref_count); # endif /* register shared library's data segment as a garbage collection root */
View file
_service:tar_scm:gc-8.0.6.tar.gz/extra/AmigaOS.c -> _service:tar_scm:gc-8.2.2.tar.gz/extra/AmigaOS.c
Changed
@@ -425,6 +425,9 @@ #endif } +# if defined(CPPCHECK) + if (GC_amiga_dontalloc) /* variable is actually used by AllocFunction */ +# endif GC_amiga_dontalloc=FALSE; return ret;
View file
_service:tar_scm:gc-8.0.6.tar.gz/extra/MacOS.c -> _service:tar_scm:gc-8.2.2.tar.gz/extra/MacOS.c
Changed
@@ -45,7 +45,9 @@ } fprintf(stderr, "Couldn't load the jump table."); exit(-1); - return 0; +# if !defined(CPPCHECK) + return 0; /* to avoid compiler complain about missing return */ +# endif } #ifdef USE_TEMPORARY_MEMORY @@ -95,8 +97,6 @@ return tempPtr; } -extern word GC_fo_entries; - static void perform_final_collection(void) { unsigned i; @@ -126,7 +126,7 @@ long totalMemoryUsed = 0; # endif TemporaryMemoryHandle tempMemBlock = theTemporaryMemory; - while (tempMemBlock != NULL) { + while (tempMemBlock /* != NULL */) { TemporaryMemoryHandle nextBlock = (**tempMemBlock).nextBlock; # if !defined(SHARED_LIBRARY_BUILD) totalMemoryUsed += GetHandleSize((Handle)tempMemBlock); @@ -161,7 +161,9 @@ } fprintf(stderr, "Couldn't load the jump table."); exit(-1); +# if !defined(CPPCHECK) return 0; +# endif } #endif /* __option(far_data) */
View file
_service:tar_scm:gc-8.0.6.tar.gz/extra/gc.c -> _service:tar_scm:gc-8.2.2.tar.gz/extra/gc.c
Changed
@@ -67,8 +67,12 @@ #include "../darwin_stop_world.c" #include "../dyn_load.c" #include "../gc_dlopen.c" -#include "../mach_dep.c" -#include "../pthread_stop_world.c" +#if !defined(PLATFORM_MACH_DEP) +# include "../mach_dep.c" +#endif +#if !defined(PLATFORM_STOP_WORLD) +# include "../pthread_stop_world.c" +#endif #include "../pthread_support.c" #include "../specific.c" #include "../win32_threads.c"
View file
_service:tar_scm:gc-8.0.6.tar.gz/extra/msvc_dbg.c -> _service:tar_scm:gc-8.2.2.tar.gz/extra/msvc_dbg.c
Changed
@@ -20,14 +20,18 @@ THE SOFTWARE. */ -#if !defined(_M_AMD64) && defined(_MSC_VER) +#if !defined(_M_ARM) && !defined(_M_ARM64) \ + && !defined(_M_X64) && defined(_MSC_VER) -/* X86_64 is currently missing some machine-dependent code below. */ +/* TODO: arm64, x86_64 currently miss some machine-dependent code below. */ +/* See also GC_HAVE_BUILTIN_BACKTRACE in gc_config_macros.h. */ #define GC_BUILD #include "private/msvc_dbg.h" #include "gc.h" +#include <stdio.h> + #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN 1 #endif @@ -41,6 +45,10 @@ #pragma comment(lib, "dbghelp.lib") #pragma optimize("gy", off) +/* Disable a warning that /GS can not protect parameters and local */ +/* variables from local buffer overrun because optimizations are off. */ +#pragma warning(disable:4748) + typedef GC_word word; #define GC_ULONG_PTR word @@ -75,7 +83,7 @@ { MEMORY_BASIC_INFORMATION memoryInfo; ULONG_ADDR dwAddrBase = SymGetModuleBase(hProcess, dwAddress); - if (dwAddrBase) { + if (dwAddrBase != 0) { return dwAddrBase; } if (VirtualQueryEx(hProcess, (void*)(GC_ULONG_PTR)dwAddress, &memoryInfo, @@ -90,12 +98,11 @@ /* article Q189780. */ GetCurrentDirectoryA(sizeof(curDir), curDir); GetModuleFileNameA(NULL, exePath, sizeof(exePath)); -#if defined(_MSC_VER) && _MSC_VER == 1200 - /* use strcat for VC6 */ - strcat(exePath, "\\.."); -#else +#if _MSC_VER > 1200 strcat_s(exePath, sizeof(exePath), "\\.."); -#endif /* _MSC_VER >= 1200 */ +#else /* VC6 or earlier */ + strcat(exePath, "\\.."); +#endif SetCurrentDirectoryA(exePath); #ifdef _DEBUG GetCurrentDirectoryA(sizeof(exePath), exePath); @@ -308,11 +315,13 @@ return 0; } +#define GC_SNPRINTF _snprintf + size_t GetDescriptionFromAddress(void* address, const char* format, char* buffer, size_t size) { - char*const begin = buffer; - char*const end = buffer + size; + char* const begin = buffer; + char* const end = buffer + size; size_t line_number = 0; (void)format; @@ -323,9 +332,10 @@ size = (GC_ULONG_PTR)end < (GC_ULONG_PTR)buffer ? 0 : end - buffer; if (line_number) { - char str128; + char str20; - wsprintf(str, "(%d) : ", (int)line_number); + (void)GC_SNPRINTF(str, sizeof(str), "(%d) : ", (int)line_number); + strsizeof(str) - 1 = '\0'; if (size) { strncpy(buffer, str, size)size - 1 = 0; } @@ -393,4 +403,4 @@ extern int GC_quiet; /* ANSI C does not allow translation units to be empty. */ -#endif /* _M_AMD64 */ +#endif
View file
_service:tar_scm:gc-8.0.6.tar.gz/finalize.c -> _service:tar_scm:gc-8.2.2.tar.gz/finalize.c
Changed
@@ -3,7 +3,8 @@ * Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. * Copyright (C) 2007 Free Software Foundation, Inc - + * Copyright (c) 2008-2020 Ivan Maidanski + * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. * @@ -44,18 +45,6 @@ word dl_hidden_obj; /* Pointer to object base */ }; -struct dl_hashtbl_s { - struct disappearing_link **head; - signed_word log_size; - word entries; -}; - -STATIC struct dl_hashtbl_s GC_dl_hashtbl = { - /* head */ NULL, /* log_size */ -1, /* entries */ 0 }; -#ifndef GC_LONG_REFS_NOT_NEEDED - STATIC struct dl_hashtbl_s GC_ll_hashtbl = { NULL, -1, 0 }; -#endif - struct finalizable_object { struct hash_chain_entry prolog; # define fo_hidden_base prolog.hidden_key @@ -70,14 +59,6 @@ finalization_mark_proc fo_mark_proc; /* Mark-through procedure */ }; -static signed_word log_fo_table_size = -1; - -STATIC struct fnlz_roots_s { - struct finalizable_object **fo_head; - /* List of objects that should be finalized now: */ - struct finalizable_object *finalize_now; -} GC_fnlz_roots = { NULL, NULL }; - #ifdef AO_HAVE_store /* Update finalize_now atomically as GC_should_invoke_finalizers does */ /* not acquire the allocation lock. */ @@ -97,6 +78,7 @@ # endif GC_PUSH_ALL_SYM(GC_dl_hashtbl.head); GC_PUSH_ALL_SYM(GC_fnlz_roots); + /* GC_toggleref_arr is pushed specially by GC_mark_togglerefs. */ } /* Threshold of log_size to initiate full collection before growing */ @@ -110,13 +92,13 @@ /* *table is a pointer to an array of hash headers. If we succeed, we */ /* update both *table and *log_size_ptr. Lock is held. */ STATIC void GC_grow_table(struct hash_chain_entry ***table, - signed_word *log_size_ptr, word *entries_ptr) + unsigned *log_size_ptr, word *entries_ptr) { word i; struct hash_chain_entry *p; - signed_word log_old_size = *log_size_ptr; - signed_word log_new_size = log_old_size + 1; - word old_size = log_old_size == -1 ? 0 : (word)1 << log_old_size; + unsigned log_old_size = *log_size_ptr; + unsigned log_new_size = log_old_size + 1; + word old_size = *table == NULL ? 0 : (word)1 << log_old_size; word new_size = (word)1 << log_new_size; /* FIXME: Power of 2 size often gets rounded up to one more page. */ struct hash_chain_entry **new_table; @@ -188,15 +170,13 @@ if (EXPECT(GC_find_leak, FALSE)) return GC_UNIMPLEMENTED; LOCK(); GC_ASSERT(obj != NULL && GC_base_C(obj) == obj); - if (dl_hashtbl -> log_size == -1 - || dl_hashtbl -> entries > ((word)1 << dl_hashtbl -> log_size)) { + if (EXPECT(NULL == dl_hashtbl -> head, FALSE) + || EXPECT(dl_hashtbl -> entries + > ((word)1 << dl_hashtbl -> log_size), FALSE)) { GC_grow_table((struct hash_chain_entry ***)&dl_hashtbl -> head, &dl_hashtbl -> log_size, &dl_hashtbl -> entries); -# ifdef LINT2 - if (dl_hashtbl->log_size < 0) ABORT("log_size is negative"); -# endif GC_COND_LOG_PRINTF("Grew %s table to %u entries\n", tbl_log_name, - 1 << (unsigned)dl_hashtbl -> log_size); + 1U << dl_hashtbl -> log_size); } index = HASH2(link, dl_hashtbl -> log_size); for (curr_dl = dl_hashtbl -> headindex; curr_dl != 0; @@ -270,10 +250,9 @@ size_t index; GC_ASSERT(I_HOLD_LOCK()); - if (dl_hashtbl->log_size == -1) - return NULL; /* prevent integer shift by a negative amount */ + if (EXPECT(NULL == dl_hashtbl -> head, FALSE)) return NULL; - index = HASH2(link, dl_hashtbl->log_size); + index = HASH2(link, dl_hashtbl -> log_size); for (curr_dl = dl_hashtbl -> headindex; curr_dl; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) { @@ -310,21 +289,14 @@ /* Toggle-ref support. */ #ifndef GC_TOGGLE_REFS_NOT_NEEDED - typedef union { - /* Lowest bit is used to distinguish between choices. */ - void *strong_ref; - GC_hidden_pointer weak_ref; - } GCToggleRef; + typedef union toggle_ref_u GCToggleRef; STATIC GC_toggleref_func GC_toggleref_callback = 0; - STATIC GCToggleRef *GC_toggleref_arr = NULL; - STATIC int GC_toggleref_array_size = 0; - STATIC int GC_toggleref_array_capacity = 0; GC_INNER void GC_process_togglerefs(void) { - int i; - int new_size = 0; + size_t i; + size_t new_size = 0; GC_bool needs_barrier = FALSE; GC_ASSERT(I_HOLD_LOCK()); @@ -380,11 +352,10 @@ STATIC void GC_mark_togglerefs(void) { - int i; + size_t i; if (NULL == GC_toggleref_arr) return; - /* TODO: Hide GC_toggleref_arr to avoid its marking from roots. */ GC_set_mark_bit(GC_toggleref_arr); for (i = 0; i < GC_toggleref_array_size; ++i) { void *obj = GC_toggleref_arri.strong_ref; @@ -396,7 +367,7 @@ STATIC void GC_clear_togglerefs(void) { - int i; + size_t i; for (i = 0; i < GC_toggleref_array_size; ++i) { if ((GC_toggleref_arri.weak_ref & 1) != 0) { if (!GC_is_marked(GC_REVEAL_POINTER(GC_toggleref_arri.weak_ref))) { @@ -428,9 +399,8 @@ return fn; } - static GC_bool ensure_toggleref_capacity(int capacity_inc) + static GC_bool ensure_toggleref_capacity(size_t capacity_inc) { - GC_ASSERT(capacity_inc >= 0); GC_ASSERT(I_HOLD_LOCK()); if (NULL == GC_toggleref_arr) { GC_toggleref_array_capacity = 32; /* initial capacity */ @@ -440,14 +410,15 @@ if (NULL == GC_toggleref_arr) return FALSE; } - if ((unsigned)GC_toggleref_array_size + (unsigned)capacity_inc - >= (unsigned)GC_toggleref_array_capacity) { + if (GC_toggleref_array_size + capacity_inc + >= GC_toggleref_array_capacity) { GCToggleRef *new_array; - while ((unsigned)GC_toggleref_array_capacity - < (unsigned)GC_toggleref_array_size + (unsigned)capacity_inc) { + while (GC_toggleref_array_capacity + < GC_toggleref_array_size + capacity_inc) { GC_toggleref_array_capacity *= 2; - if (GC_toggleref_array_capacity < 0) /* overflow */ - return FALSE; + if ((GC_toggleref_array_capacity + & ((size_t)1 << (sizeof(size_t) * 8 - 1))) != 0) + return FALSE; /* overflow */ } new_array = (GCToggleRef *)GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE( @@ -541,31 +512,26 @@ struct dl_hashtbl_s *dl_hashtbl, void **link, void **new_link) { - struct disappearing_link *curr_dl, *prev_dl, *new_dl; + struct disappearing_link *curr_dl, *new_dl; + struct disappearing_link *prev_dl = NULL; size_t curr_index, new_index; - word curr_hidden_link; - word new_hidden_link; + word curr_hidden_link, new_hidden_link; GC_ASSERT(I_HOLD_LOCK()); - if (dl_hashtbl->log_size == -1) - return GC_NOT_FOUND; /* prevent integer shift by a negative amount */ + if (EXPECT(NULL == dl_hashtbl -> head, FALSE)) return GC_NOT_FOUND; /* Find current link. */ curr_index = HASH2(link, dl_hashtbl -> log_size); curr_hidden_link = GC_HIDE_POINTER(link); - prev_dl = NULL; for (curr_dl = dl_hashtbl -> headcurr_index; curr_dl; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == curr_hidden_link) break; prev_dl = curr_dl; } - - if (NULL == curr_dl) { + if (EXPECT(NULL == curr_dl, FALSE)) { return GC_NOT_FOUND; - } - - if (link == new_link) { + } else if (link == new_link) { return GC_SUCCESS; /* Nothing to do. */ } @@ -700,24 +666,24 @@ hdr *hhdr = NULL; /* initialized to prevent warning. */ DCL_LOCK_STATE; - if (EXPECT(GC_find_leak, FALSE)) return; + if (EXPECT(GC_find_leak, FALSE)) { + /* No-op. *ocd and *ofn remain unchanged. */ + return; + } LOCK(); - if (log_fo_table_size == -1 - || GC_fo_entries > ((word)1 << log_fo_table_size)) { + if (EXPECT(NULL == GC_fnlz_roots.fo_head, FALSE) + || EXPECT(GC_fo_entries > ((word)1 << GC_log_fo_table_size), FALSE)) { GC_grow_table((struct hash_chain_entry ***)&GC_fnlz_roots.fo_head, - &log_fo_table_size, &GC_fo_entries); -# ifdef LINT2 - if (log_fo_table_size < 0) ABORT("log_size is negative"); -# endif + &GC_log_fo_table_size, &GC_fo_entries); GC_COND_LOG_PRINTF("Grew fo table to %u entries\n", - 1 << (unsigned)log_fo_table_size); + 1U << GC_log_fo_table_size); } /* in the THREADS case we hold allocation lock. */ for (;;) { struct finalizable_object *prev_fo = NULL; GC_oom_func oom_fn; - index = HASH2(obj, log_fo_table_size); + index = HASH2(obj, GC_log_fo_table_size); curr_fo = GC_fnlz_roots.fo_headindex; while (curr_fo != 0) { GC_ASSERT(GC_size(curr_fo) >= sizeof(struct finalizable_object)); @@ -760,10 +726,8 @@ GC_dirty(GC_fnlz_roots.fo_head + index); UNLOCK(); # ifndef DBG_HDRS_ALL - if (EXPECT(new_fo != 0, FALSE)) { /* Free unused new_fo returned by GC_oom_fn() */ GC_free((void *)new_fo); - } # endif return; } @@ -801,7 +765,7 @@ new_fo = (struct finalizable_object *) (*oom_fn)(sizeof(struct finalizable_object)); if (0 == new_fo) { - /* No enough memory. *ocd and *ofn remains unchanged. */ + /* No enough memory. *ocd and *ofn remain unchanged. */ return; } /* It's not likely we'll make it here, but ... */ @@ -866,10 +830,11 @@ STATIC void GC_dump_finalization_links( const struct dl_hashtbl_s *dl_hashtbl) { - size_t dl_size = dl_hashtbl->log_size == -1 ? 0 : - (size_t)1 << dl_hashtbl->log_size; + size_t dl_size = (size_t)1 << dl_hashtbl -> log_size; size_t i; + if (NULL == dl_hashtbl -> head) return; /* empty table */ + for (i = 0; i < dl_size; i++) { struct disappearing_link *curr_dl; @@ -887,9 +852,9 @@ GC_API void GC_CALL GC_dump_finalization(void) { struct finalizable_object * curr_fo; - size_t fo_size = log_fo_table_size == -1 ? 0 : - (size_t)1 << log_fo_table_size; size_t i; + size_t fo_size = GC_fnlz_roots.fo_head == NULL ? 0 : + (size_t)1 << GC_log_fo_table_size; GC_printf("Disappearing (short) links:\n"); GC_dump_finalization_links(&GC_dl_hashtbl); @@ -949,11 +914,12 @@ GC_bool is_remove_dangling) { size_t i; - size_t dl_size = dl_hashtbl->log_size == -1 ? 0 - : (size_t)1 << dl_hashtbl->log_size; + size_t dl_size = (size_t)1 << dl_hashtbl -> log_size; GC_bool needs_barrier = FALSE; GC_ASSERT(I_HOLD_LOCK()); + if (NULL == dl_hashtbl -> head) return; /* empty table */ + for (i = 0; i < dl_size; i++) { struct disappearing_link *curr_dl, *next_dl; struct disappearing_link *prev_dl = NULL; @@ -1001,8 +967,8 @@ struct finalizable_object * curr_fo, * prev_fo, * next_fo; ptr_t real_ptr; size_t i; - size_t fo_size = log_fo_table_size == -1 ? 0 : - (size_t)1 << log_fo_table_size; + size_t fo_size = GC_fnlz_roots.fo_head == NULL ? 0 : + (size_t)1 << GC_log_fo_table_size; GC_bool needs_barrier = FALSE; GC_ASSERT(I_HOLD_LOCK()); @@ -1105,10 +1071,7 @@ other finalizable objects */ if (need_unreachable_finalization) { curr_fo = GC_fnlz_roots.finalize_now; -# if defined(GC_ASSERTIONS) || defined(LINT2) - if (curr_fo != NULL && log_fo_table_size < 0) - ABORT("log_size is negative"); -# endif + GC_ASSERT(NULL == curr_fo || GC_fnlz_roots.fo_head != NULL); prev_fo = NULL; while (curr_fo != NULL) { next_fo = fo_next(curr_fo); @@ -1128,7 +1091,7 @@ GC_bytes_finalized -= curr_fo->fo_object_size + sizeof(struct finalizable_object); - i = HASH2(real_ptr, log_fo_table_size); + i = HASH2(real_ptr, GC_log_fo_table_size); fo_set_next(curr_fo, GC_fnlz_roots.fo_headi); GC_dirty(curr_fo); GC_fo_entries++; @@ -1173,11 +1136,11 @@ STATIC void GC_enqueue_all_finalizers(void) { struct finalizable_object * next_fo; - int i; - int fo_size; + size_t i; + size_t fo_size = GC_fnlz_roots.fo_head == NULL ? 0 : + (size_t)1 << GC_log_fo_table_size; GC_ASSERT(I_HOLD_LOCK()); - fo_size = log_fo_table_size == -1 ? 0 : 1 << log_fo_table_size; GC_bytes_finalized = 0; for (i = 0; i < fo_size; i++) { struct finalizable_object * curr_fo = GC_fnlz_roots.fo_headi; @@ -1338,8 +1301,11 @@ /* which may cause occasional mysterious results. */ /* We need to release the GC lock, since GC_print_callers */ /* acquires it. It probably shouldn't. */ + void *current = GC_generate_random_valid_address(); + UNLOCK(); - GC_generate_random_backtrace_no_gc(); + GC_printf("\n****Chosen address %p in object\n", current); + GC_print_backtrace(current); LOCK(); } last_back_trace_gc_no = GC_gc_no; @@ -1372,8 +1338,8 @@ /* These variables require synchronization to avoid data races. */ if (last_finalizer_notification != GC_gc_no) { - last_finalizer_notification = GC_gc_no; notifier_fn = GC_finalizer_notifier; + last_finalizer_notification = GC_gc_no; } UNLOCK(); if (notifier_fn != 0)
View file
_service:tar_scm:gc-8.0.6.tar.gz/fnlz_mlc.c -> _service:tar_scm:gc-8.2.2.tar.gz/fnlz_mlc.c
Changed
@@ -20,8 +20,6 @@ #include "gc_inline.h" /* for GC_malloc_kind */ #include "private/dbg_mlc.h" /* for oh type */ -STATIC int GC_finalized_kind = 0; - #if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) /* The first bit is already used for a debug purpose. */ # define FINALIZER_CLOSURE_FLAG 0x2 @@ -31,7 +29,11 @@ STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj) { - word fc_word = *(word *)obj; +# ifdef AO_HAVE_load + word fc_word = (word)AO_load((volatile AO_t *)obj); +# else + word fc_word = *(word *)obj; +# endif if ((fc_word & FINALIZER_CLOSURE_FLAG) != 0) { /* The disclaim function may be passed fragments from the */ @@ -96,19 +98,22 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb, const struct GC_finalizer_closure *fclos) { - word *op; + void *op; GC_ASSERT(GC_finalized_kind != 0); GC_ASSERT(NONNULL_ARG_NOT_NULL(fclos)); GC_ASSERT(((word)fclos & FINALIZER_CLOSURE_FLAG) == 0); - op = (word *)GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)), - GC_finalized_kind); + op = GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)), GC_finalized_kind); if (EXPECT(NULL == op, FALSE)) return NULL; - *op = (word)fclos | FINALIZER_CLOSURE_FLAG; +# ifdef AO_HAVE_store + AO_store((volatile AO_t *)op, (AO_t)fclos | FINALIZER_CLOSURE_FLAG); +# else + *(word *)op = (word)fclos | FINALIZER_CLOSURE_FLAG; +# endif GC_dirty(op); REACHABLE_AFTER_DIRTY(fclos); - return op + 1; + return (word *)op + 1; } #endif /* ENABLE_DISCLAIM */
View file
_service:tar_scm:gc-8.2.2.tar.gz/gc_badalc.cc
Added
@@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2020 Ivan Maidanski + * + * 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 file provides the implementation of GC_throw_bad_alloc() which +// is invoked by GC operator "new" in case of an out-of-memory event. + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifndef GC_BUILD +# define GC_BUILD +#endif + +#define GC_DONT_INCL_WINDOWS_H +#include "gc.h" + +#include <new> // for bad_alloc, precedes include of gc_cpp.h + +#if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) +# define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() +#else +# define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc() +#endif + +GC_API void GC_CALL GC_throw_bad_alloc() { + GC_ALLOCATOR_THROW_OR_ABORT(); +}
View file
_service:tar_scm:gc-8.2.2.tar.gz/gc_badalc.cpp
Added
@@ -0,0 +1,2 @@ +// Visual C++ seems to prefer a .cpp extension to .cc one. +#include "gc_badalc.cc"
View file
_service:tar_scm:gc-8.0.6.tar.gz/gc_cpp.cc -> _service:tar_scm:gc-8.2.2.tar.gz/gc_cpp.cc
Changed
@@ -4,8 +4,11 @@ * 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 copy this code for any purpose, - * provided the above notices are retained on all copies. + * 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. */ /************************************************************************* @@ -32,20 +35,17 @@ #include <new> // for bad_alloc, precedes include of gc_cpp.h -#include "gc_cpp.h" // for GC_OPERATOR_NEW_ARRAY, GC_NOEXCEPT +#include "gc_cpp.h" // for GC_OPERATOR_NEW_ARRAY + +#if !(defined(_MSC_VER) || defined(__DMC__)) || defined(GC_NO_INLINE_STD_NEW) #if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) # define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() #else +// Use bad_alloc() directly instead of GC_throw_bad_alloc() call. # define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc() #endif -GC_API void GC_CALL GC_throw_bad_alloc() { - GC_ALLOCATOR_THROW_OR_ABORT(); -} - -#if !(defined(_MSC_VER) || defined(__DMC__)) || defined(GC_NO_INLINE_STD_NEW) - # if !defined(GC_NEW_DELETE_THROW_NOT_NEEDED) \ && !defined(GC_NEW_DELETE_NEED_THROW) && GC_GNUC_PREREQ(4, 2) \ && (__cplusplus < 201103L || defined(__clang__))
View file
_service:tar_scm:gc-8.0.6.tar.gz/gc_dlopen.c -> _service:tar_scm:gc-8.2.2.tar.gz/gc_dlopen.c
Changed
@@ -46,7 +46,9 @@ DCL_LOCK_STATE; LOCK(); while (GC_incremental && GC_collection_in_progress()) { + ENTER_GC(); GC_collect_a_little_inner(1000); + EXIT_GC(); } ++GC_dont_gc; UNLOCK();
View file
_service:tar_scm:gc-8.0.6.tar.gz/gcj_mlc.c -> _service:tar_scm:gc-8.2.2.tar.gz/gcj_mlc.c
Changed
@@ -39,21 +39,12 @@ #include "gc_gcj.h" #include "private/dbg_mlc.h" -#ifdef GC_ASSERTIONS - GC_INNER /* variable is also used in thread_local_alloc.c */ -#else - STATIC -#endif -GC_bool GC_gcj_malloc_initialized = FALSE; - int GC_gcj_kind = 0; /* Object kind for objects with descriptors */ /* in "vtable". */ int GC_gcj_debug_kind = 0; /* The kind of objects that is always marked */ /* with a mark proc call. */ -GC_INNER ptr_t * GC_gcjobjfreelist = NULL; - STATIC struct GC_ms_entry * GC_gcj_fake_mark_proc(word * addr GC_ATTR_UNUSED, struct GC_ms_entry *mark_stack_ptr, struct GC_ms_entry * mark_stack_limit GC_ATTR_UNUSED, @@ -77,11 +68,11 @@ GC_init(); /* In case it's not already done. */ LOCK(); - if (GC_gcj_malloc_initialized) { + if (GC_gcjobjfreelist != NULL) { + /* Already initialized. */ UNLOCK(); return; } - GC_gcj_malloc_initialized = TRUE; # ifdef GC_IGNORE_GCJ_INFO /* This is useful for debugging on platforms with missing getenv(). */ # define ignore_gcj_info TRUE @@ -96,30 +87,27 @@ if ((unsigned)mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index"); /* Set up object kind gcj-style indirect descriptor. */ - GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner(); - if (ignore_gcj_info) { + GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner(); + if (ignore_gcj_info) { /* Use a simple length-based descriptor, thus forcing a fully */ /* conservative scan. */ GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist, /* 0 | */ GC_DS_LENGTH, TRUE, TRUE); - } else { + GC_gcj_debug_kind = GC_gcj_kind; + } else { GC_gcj_kind = GC_new_kind_inner( (void **)GC_gcjobjfreelist, (((word)(-(signed_word)MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS)) | GC_DS_PER_OBJECT), FALSE, TRUE); - } - /* Set up object kind for objects that require mark proc call. */ - if (ignore_gcj_info) { - GC_gcj_debug_kind = GC_gcj_kind; - } else { + /* Set up object kind for objects that require mark proc call. */ GC_gcj_debug_kind = GC_new_kind_inner(GC_new_free_list_inner(), GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */), FALSE, TRUE); - } + } UNLOCK(); # undef ignore_gcj_info }
View file
_service:tar_scm:gc-8.0.6.tar.gz/headers.c -> _service:tar_scm:gc-8.2.2.tar.gz/headers.c
Changed
@@ -24,14 +24,6 @@ * level tree. */ -STATIC bottom_index * GC_all_bottom_indices = 0; - /* Pointer to the first (lowest address) */ - /* bottom_index. Assumes the lock is held. */ - -STATIC bottom_index * GC_all_bottom_indices_end = 0; - /* Pointer to the last (highest address) */ - /* bottom_index. Assumes the lock is held. */ - /* Non-macro version of header location routine */ GC_INNER hdr * GC_find_header(ptr_t h) { @@ -110,14 +102,9 @@ /* Routines to dynamically allocate collector data structures that will */ /* never be freed. */ -static ptr_t scratch_free_ptr = 0; - -/* GC_scratch_last_end_ptr is end point of last obtained scratch area. */ -/* GC_scratch_end_ptr is end point of current scratch area. */ - GC_INNER ptr_t GC_scratch_alloc(size_t bytes) { - ptr_t result = scratch_free_ptr; + ptr_t result = GC_scratch_free_ptr; size_t bytes_to_get; bytes = ROUNDUP_GRANULE_SIZE(bytes); @@ -125,19 +112,23 @@ GC_ASSERT((word)GC_scratch_end_ptr >= (word)result); if (bytes <= (word)GC_scratch_end_ptr - (word)result) { /* Unallocated space of scratch buffer has enough size. */ - scratch_free_ptr = result + bytes; + GC_scratch_free_ptr = result + bytes; return result; } + GC_ASSERT(GC_page_size != 0); if (bytes >= MINHINCR * HBLKSIZE) { bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes); result = (ptr_t)GET_MEM(bytes_to_get); - GC_add_to_our_memory(result, bytes_to_get); - /* No update of scratch free area pointer; get memory directly. */ if (result != NULL) { + GC_add_to_our_memory(result, bytes_to_get); + /* No update of scratch free area pointer; */ + /* get memory directly. */ +# ifdef USE_SCRATCH_LAST_END_PTR /* Update end point of last obtained area (needed only */ /* by GC_register_dynamic_libraries for some targets). */ GC_scratch_last_end_ptr = result + bytes; +# endif } return result; } @@ -145,44 +136,49 @@ bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(MINHINCR * HBLKSIZE); /* round up for safety */ result = (ptr_t)GET_MEM(bytes_to_get); - GC_add_to_our_memory(result, bytes_to_get); - if (NULL == result) { + if (EXPECT(NULL == result, FALSE)) { WARN("Out of memory - trying to allocate requested amount" " (%" WARN_PRIdPTR " bytes)...\n", (word)bytes); bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes); result = (ptr_t)GET_MEM(bytes_to_get); - GC_add_to_our_memory(result, bytes_to_get); - if (result != NULL) + if (result != NULL) { + GC_add_to_our_memory(result, bytes_to_get); +# ifdef USE_SCRATCH_LAST_END_PTR GC_scratch_last_end_ptr = result + bytes; +# endif + } return result; } + + GC_add_to_our_memory(result, bytes_to_get); + /* TODO: some amount of unallocated space may remain unused forever */ /* Update scratch area pointers and retry. */ - scratch_free_ptr = result; - GC_scratch_end_ptr = scratch_free_ptr + bytes_to_get; - GC_scratch_last_end_ptr = GC_scratch_end_ptr; + GC_scratch_free_ptr = result; + GC_scratch_end_ptr = GC_scratch_free_ptr + bytes_to_get; +# ifdef USE_SCRATCH_LAST_END_PTR + GC_scratch_last_end_ptr = GC_scratch_end_ptr; +# endif } } -static hdr * hdr_free_list = 0; - /* Return an uninitialized header */ static hdr * alloc_hdr(void) { hdr * result; - if (NULL == hdr_free_list) { + if (NULL == GC_hdr_free_list) { result = (hdr *)GC_scratch_alloc(sizeof(hdr)); } else { - result = hdr_free_list; - hdr_free_list = (hdr *) (result -> hb_next); + result = GC_hdr_free_list; + GC_hdr_free_list = (hdr *) result -> hb_next; } return(result); } GC_INLINE void free_hdr(hdr * hhdr) { - hhdr -> hb_next = (struct hblk *) hdr_free_list; - hdr_free_list = hhdr; + hhdr -> hb_next = (struct hblk *) GC_hdr_free_list; + GC_hdr_free_list = hhdr; } #ifdef COUNT_HDR_CACHE_HITS @@ -195,6 +191,7 @@ { unsigned i; + GC_ASSERT(NULL == GC_all_nils); GC_all_nils = (bottom_index *)GC_scratch_alloc(sizeof(bottom_index)); if (GC_all_nils == NULL) { GC_err_printf("Insufficient memory for GC_all_nils\n"); @@ -313,6 +310,15 @@ { struct hblk * hbp; + if (sz <= HBLKSIZE) return; + if (HDR(h+1) == 0) { +# ifdef GC_ASSERTIONS + for (hbp = h+2; (word)hbp < (word)h + sz; hbp++) + GC_ASSERT(HDR(hbp) == 0); +# endif + return; + } + for (hbp = h+1; (word)hbp < (word)h + sz; hbp += 1) { SET_HDR(hbp, 0); }
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/config.h.in -> _service:tar_scm:gc-8.2.2.tar.gz/include/config.h.in
Changed
@@ -17,6 +17,9 @@ /* Define to force debug headers on all objects. */ #undef DBG_HDRS_ALL +/* Do not use user32.dll import library (Win32). */ +#undef DONT_USE_USER32_DLL + /* Define to enable eCos target support. */ #undef ECOS @@ -32,7 +35,7 @@ /* Define to enable atomic uncollectible allocation. */ #undef GC_ATOMIC_UNCOLLECTABLE -/* Use C11 (GCC) atomic intrinsics instead of libatomic_ops primitives. */ +/* Use GCC atomic intrinsics instead of libatomic_ops primitives. */ #undef GC_BUILTIN_ATOMIC /* Define to build dynamic libraries with only API symbols exposed. */ @@ -110,6 +113,16 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Define to use 'pthread_setname_np(const char*)' function. */ +#undef HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID + +/* Define to use 'pthread_setname_np(pthread_t, const char*)' function. */ +#undef HAVE_PTHREAD_SETNAME_NP_WITH_TID + +/* Define to use 'pthread_setname_np(pthread_t, const char*, void *)' + function. */ +#undef HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/cord.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/cord.h
Changed
@@ -26,7 +26,7 @@ * - A text editor that converts the input file to a cord, and then * performs editing operations by producing a new cord representing * the file after each character change (and keeping the old ones in an - * edit history) + * edit history). * * For optimal performance, cords should be built by * concatenating short sections. @@ -44,14 +44,15 @@ * CORD_cat(cord1,cord2) - concatenation of two cords; * CORD_substr(cord, start, len) - substring (or subcord); * CORD_pos i; CORD_FOR(i, cord) { ... CORD_pos_fetch(i) ... } - - * examine each character in a cord. CORD_pos_fetch(i) is the char. - * CORD_fetch(int i) - Retrieve i'th character (slowly). - * CORD_cmp(cord1, cord2) - compare two cords. - * CORD_from_file(FILE * f) - turn a read-only file into a cord. - * CORD_to_char_star(cord) - convert to C string. - * (Non-NULL C constant strings are cords.) - * CORD_printf (etc.) - cord version of printf. Use %r for cords. + * examine each character in a cord (CORD_pos_fetch(i) is the char); + * CORD_fetch(int i) - Retrieve i'th character (slowly); + * CORD_cmp(cord1, cord2) - compare two cords; + * CORD_from_file(FILE * f) - turn a read-only file into a cord; + * CORD_to_char_star(cord) - convert to C string + * (non-NULL C constant strings are cords); + * CORD_printf (etc.) - cord version of printf (use %r for cords). */ + #ifndef CORD_H #define CORD_H @@ -97,7 +98,7 @@ typedef const char * CORD; -/* An empty cord is always represented as nil */ +/* An empty cord is always represented as nil. */ #define CORD_EMPTY 0 /* Is a nonempty cord represented as a C string? */ @@ -114,10 +115,10 @@ /* not be altered by the caller. */ CORD_API CORD CORD_cat_char_star(CORD x, const char * y, size_t leny); -/* Compute the length of a cord */ +/* Compute the length of a cord. */ CORD_API size_t CORD_len(CORD x); -/* Cords may be represented by functions defining the ith character */ +/* Cords may be represented by functions defining the ith character. */ typedef char (* CORD_fn)(size_t i, void * client_data); /* Turn a functional description into a cord. */ @@ -152,8 +153,8 @@ #define CORD_NO_FN ((CORD_batched_iter_fn)0) /* Apply f1 to each character in the cord, in ascending order, */ -/* starting at position i. If */ -/* f2 is not CORD_NO_FN, then multiple calls to f1 may be replaced by */ +/* starting at position i. If f2 is not CORD_NO_FN, then */ +/* multiple calls to f1 may be replaced by */ /* a single call to f2. The parameter f2 is provided only to allow */ /* some optimization by the client. This terminates when the right */ /* end of this string is reached, or when f1 or f2 return != 0. In the */ @@ -162,15 +163,15 @@ CORD_API int CORD_iter5(CORD x, size_t i, CORD_iter_fn f1, CORD_batched_iter_fn f2, void * client_data); -/* A simpler version that starts at 0, and without f2: */ +/* A simpler version that starts at 0, and without f2. */ CORD_API int CORD_iter(CORD x, CORD_iter_fn f1, void * client_data); #define CORD_iter(x, f1, cd) CORD_iter5(x, 0, f1, CORD_NO_FN, cd) -/* Similar to CORD_iter5, but end-to-beginning. No provisions for */ +/* Similar to CORD_iter5, but end-to-beginning. No provisions for */ /* CORD_batched_iter_fn. */ CORD_API int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data); -/* A simpler version that starts at the end: */ +/* A simpler version that starts at the end. */ CORD_API int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data); #ifdef __cplusplus @@ -184,9 +185,9 @@ /* positions are big (order of a few 100 bytes), so allocate them with */ /* caution. */ /* Things in cord_pos.h should be treated as opaque, except as */ -/* described below. Also note that */ -/* CORD_pos_fetch, CORD_next and CORD_prev have both macro and function */ -/* definitions. The former may evaluate their argument more than once. */ +/* described below. Also, note that CORD_pos_fetch, CORD_next and */ +/* CORD_prev have both macro and function definitions. The former */ +/* may evaluate their argument more than once. */ #include "cord_pos.h" #ifdef __cplusplus @@ -245,10 +246,10 @@ /* Concatenate n cords. */ CORD_API CORD CORD_catn(int n, /* CORD */ ...); -/* Return the character in CORD_substr(x, i, 1) */ +/* Return the character in CORD_substr(x, i, 1). */ CORD_API char CORD_fetch(CORD x, size_t i); -/* Return < 0, 0, or > 0, depending on whether x < y, x = y, x > y */ +/* Return < 0, 0, or > 0, depending on whether x < y, x = y, x > y. */ CORD_API int CORD_cmp(CORD x, CORD y); /* A generalization that takes both starting positions for the */ @@ -276,13 +277,13 @@ /* We must have exclusive access to the descriptor f, i.e. we may */ /* read it at any time, and expect the file pointer to be */ /* where we left it. Normally this should be invoked as */ -/* CORD_from_file(fopen(...)) */ +/* CORD_from_file(fopen(...)). */ /* CORD_from_file arranges to close the file descriptor when it is no */ /* longer needed (e.g. when the result becomes inaccessible). */ /* The file f must be such that ftell reflects the actual character */ /* position in the file, i.e. the number of characters that can be */ -/* or were read with fread. On UNIX systems this is always true. On */ -/* MS Windows systems, f must be opened in binary mode. */ +/* or were read with fread. On UNIX systems this is always true. */ +/* On MS Windows systems, f must be opened in binary mode. */ CORD_API CORD CORD_from_file(FILE * f); /* Equivalent to the above, except that the entire file will be read */ @@ -290,8 +291,8 @@ /* The binary mode restriction from above does not apply. */ CORD_API CORD CORD_from_file_eager(FILE * f); -/* Equivalent to the above, except that the file will be read on demand.*/ -/* The binary mode restriction applies. */ +/* Equivalent to the above, except that the file will be read on */ +/* demand. The binary mode restriction applies. */ CORD_API CORD CORD_from_file_lazy(FILE * f); /* Turn a cord into a C string. The result shares no structure with */ @@ -306,8 +307,8 @@ /* the argument and is thus not modifiable. */ CORD_API const char * CORD_to_const_char_star(CORD x); -/* Write a cord to a file, starting at the current position. No */ -/* trailing NULs are newlines are added. */ +/* Write a cord to a file, starting at the current position. */ +/* No trailing NULs are newlines are added. */ /* Returns EOF if a write error occurs, 1 otherwise. */ CORD_API int CORD_put(CORD x, FILE * f); @@ -316,11 +317,11 @@ /* A vague analog of strchr. Returns the position (an integer, not */ /* a pointer) of the first occurrence of (char) c inside x at position */ -/* i or later. The value i must be < CORD_len(x). */ +/* i or later. The value i must be < CORD_len(x). */ CORD_API size_t CORD_chr(CORD x, size_t i, int c); /* A vague analog of strrchr. Returns index of the last occurrence */ -/* of (char) c inside x at position i or earlier. The value i */ +/* of (char) c inside x at position i or earlier. The value i */ /* must be < CORD_len(x). */ CORD_API size_t CORD_rchr(CORD x, size_t i, int c); @@ -337,8 +338,8 @@ /* (Note that %c, %C, and %S were already taken.) */ /* 2. The format string is represented as a CORD. */ /* 3. CORD_sprintf and CORD_vsprintf assign the result through the 1st */ -/* argument. Unlike their ANSI C versions, there is no need to guess */ -/* the correct buffer size. */ +/* argument. Unlike their ANSI C versions, there is no need to */ +/* guess the correct buffer size. */ /* 4. Most of the conversions are implement through the native */ /* vsprintf. Hence they are usually no faster, and */ /* idiosyncrasies of the native printf are preserved. However, */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/cord_pos.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/cord_pos.h
Changed
@@ -47,8 +47,8 @@ /* Always points to a valid string */ /* containing the current character */ /* unless cur_end is 0. */ - size_t cur_start; /* Start position of cur_leaf */ - size_t cur_end; /* Ending position of cur_leaf */ + size_t cur_start; /* Start position of cur_leaf. */ + size_t cur_end; /* Ending position of cur_leaf; */ /* 0 if cur_leaf is invalid. */ struct CORD_pe pathMAX_DEPTH + 1; /* pathpath_len is the leaf corresponding to cur_pos */ @@ -110,16 +110,16 @@ #define CORD_pos_valid(p) ((p)0.path_len != CORD_POS_INVALID) /* Some grubby stuff for performance-critical friends: */ -#define CORD_pos_chars_left(p) ((long)((p)0.cur_end) - (long)((p)0.cur_pos)) +#define CORD_pos_chars_left(p) ((long)((p)0.cur_end)-(long)((p)0.cur_pos)) /* Number of characters in cache. <= 0 ==> none */ #define CORD_pos_advance(p,n) ((p)0.cur_pos += (n) - 1, CORD_next(p)) - /* Advance position by n characters */ - /* 0 < n < CORD_pos_chars_left(p) */ + /* Advance position by n characters; */ + /* 0 < n < CORD_pos_chars_left(p). */ #define CORD_pos_cur_char_addr(p) \ (p)0.cur_leaf + ((p)0.cur_pos - (p)0.cur_start) - /* address of current character in cache. */ + /* Address of the current character in cache. */ #ifdef __cplusplus } /* extern "C" */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/ec.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/ec.h
Changed
@@ -1,5 +1,18 @@ -# ifndef EC_H -# define EC_H +/* + * Copyright (c) 1993-1994 by Xerox Corporation. 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. + */ + +#ifndef EC_H +#define EC_H # ifndef CORD_H # include "cord.h" @@ -73,4 +86,4 @@ } /* extern "C" */ #endif -# endif /* EC_H */ +#endif /* EC_H */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc.h
Changed
@@ -5,7 +5,7 @@ * Copyright 1999 by Hewlett-Packard Company. All rights reserved. * Copyright (C) 2007 Free Software Foundation, Inc * Copyright (c) 2000-2011 by Hewlett-Packard Development Company. - * Copyright (c) 2009-2018 Ivan Maidanski + * Copyright (c) 2009-2020 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -87,24 +87,28 @@ /* avoid data races on multiprocessors. */ #ifdef GC_THREADS + /* GC is parallelized for performance on multiprocessors. Set to */ + /* a non-zero value when client calls GC_start_mark_threads() */ + /* directly or starts the first non-main thread, provided the */ + /* collector is built with PARALLEL_MARK defined, and either */ + /* GC_MARKERS (or GC_NPROCS) environment variable is set to a value */ + /* bigger than 1, or multiple cores (processors) are available, or */ + /* the client calls GC_set_markers_count() before GC initialization. */ + /* After setting, GC_parallel value is equal to the number of marker */ + /* threads minus one (i.e. the number of existing parallel marker */ + /* threads excluding the initiating one). */ GC_API GC_ATTR_DEPRECATED int GC_parallel; - /* GC is parallelized for performance on */ - /* multiprocessors. Set to a non-zero value */ - /* only implicitly if collector is built with */ - /* PARALLEL_MARK defined, and if either */ - /* GC_MARKERS (or GC_NPROCS) environment */ - /* variable is set to > 1, or multiple cores */ - /* (processors) are available. */ - /* If GC_parallel is on (non-zero), incremental */ - /* collection is only partially functional, */ - /* and may not be desirable. The getter does */ - /* not use or need synchronization (i.e. */ - /* acquiring the GC lock). Starting from */ - /* GC v7.3, GC_parallel value is equal to the */ - /* number of marker threads minus one (i.e. */ - /* number of existing parallel marker threads */ - /* excluding the initiating one). */ + + /* Return value of GC_parallel. Does not acquire the GC lock. */ GC_API int GC_CALL GC_get_parallel(void); + + /* Set the number of marker threads (including the initiating one) */ + /* to the desired value at start-up. Zero value means the collector */ + /* is to decide. If the correct non-zero value is passed, then later */ + /* GC_parallel will be set to the value minus one. Has no effect if */ + /* called after GC initialization. Does not itself cause creation of */ + /* the marker threads. Does not use any synchronization. */ + GC_API void GC_CALL GC_set_markers_count(unsigned); #endif @@ -242,8 +246,8 @@ # ifndef GC_DONT_GC GC_ATTR_DEPRECATED # endif - int GC_dont_gc; /* != 0 ==> Don't collect. In versions 6.2a1+, */ - /* this overrides explicit GC_gcollect() calls. */ + int GC_dont_gc; /* != 0 ==> Do not collect. This overrides */ + /* explicit GC_gcollect() calls as well. */ /* Used as a counter, so that nested enabling */ /* and disabling work correctly. Should */ /* normally be updated with GC_enable() and */ @@ -261,8 +265,7 @@ GC_API GC_ATTR_DEPRECATED int GC_use_entire_heap; /* Causes the non-incremental collector to use the */ - /* entire heap before collecting. This was the only */ - /* option for GC versions < 5.0. This sometimes */ + /* entire heap before collecting. This sometimes */ /* results in more large block fragmentation, since */ /* very large blocks will tend to get broken up */ /* during each GC cycle. It is likely to result in a */ @@ -329,8 +332,8 @@ /* GC_call_with_alloc_lock() is required to */ /* avoid data races (if the value is modified */ /* after the GC is put to multi-threaded mode). */ - /* In version 7.1 (and before), the setter */ - /* returned the old value. */ + /* In GC v7.1 (and before), the setter returned */ + /* the old value. */ GC_API void GC_CALL GC_set_free_space_divisor(GC_word); GC_API GC_word GC_CALL GC_get_free_space_divisor(void); @@ -347,7 +350,7 @@ GC_API GC_ATTR_DEPRECATED char *GC_stackbottom; - /* Cool end of user stack. */ + /* The cold end (bottom) of user stack. */ /* May be set in the client prior to */ /* calling any GC_ routines. This */ /* avoids some overhead, and */ @@ -378,9 +381,12 @@ GC_API GC_ATTR_DEPRECATED unsigned long GC_time_limit; /* If incremental collection is enabled, */ - /* We try to terminate collections */ - /* after this many milliseconds. Not a */ - /* hard time bound. Setting this to */ + /* we try to terminate collections */ + /* after this many milliseconds (plus */ + /* the amount of nanoseconds as given in */ + /* the latest GC_set_time_limit_tv call, */ + /* if any). Not a hard time bound. */ + /* Setting this variable to */ /* GC_TIME_UNLIMITED will essentially */ /* disable incremental collection while */ /* leaving generational collection */ @@ -393,11 +399,46 @@ /* GC_call_with_alloc_lock() is required to */ /* avoid data races (if the value is modified */ /* after the GC is put to multi-threaded mode). */ + /* The setter does not update the value of the */ + /* nanosecond part of the time limit (it is */ + /* zero unless ever set by GC_set_time_limit_tv */ + /* call). */ GC_API void GC_CALL GC_set_time_limit(unsigned long); GC_API unsigned long GC_CALL GC_get_time_limit(void); +/* A portable type definition of time with a nanosecond precision. */ +struct GC_timeval_s { + unsigned long tv_ms; /* time in milliseconds */ + unsigned long tv_nsec;/* nanoseconds fraction (<1000000) */ +}; + /* Public procedures */ +/* Set/get the time limit of the incremental collections. This is */ +/* similar to GC_set_time_limit and GC_get_time_limit but the time is */ +/* provided with the nanosecond precision. The value of tv_nsec part */ +/* should be less than a million. If the value of tv_ms part is */ +/* GC_TIME_UNLIMITED then tv_nsec is ignored. Initially, the value of */ +/* tv_nsec part of the time limit is zero. The functions do not use */ +/* any synchronization. Defined only if the library has been compiled */ +/* without NO_CLOCK. */ +GC_API void GC_CALL GC_set_time_limit_tv(struct GC_timeval_s); +GC_API struct GC_timeval_s GC_CALL GC_get_time_limit_tv(void); + +/* Set/get the minimum value of the ratio of allocated bytes since GC */ +/* to the amount of finalizers created since that GC (value > */ +/* GC_bytes_allocd / (GC_fo_entries - last_fo_entries)) which triggers */ +/* the collection instead heap expansion. The value has no effect in */ +/* the GC incremental mode. The default value is 10000 unless */ +/* GC_ALLOCD_BYTES_PER_FINALIZER macro with a custom value is defined */ +/* to build libgc. The default value might be not the right choice for */ +/* clients where e.g. most objects have a finalizer. Zero value */ +/* effectively disables taking amount of finalizers in the decision */ +/* whether to collect or not. The functions do not use any */ +/* synchronization. */ +GC_API void GC_CALL GC_set_allocd_bytes_per_finalizer(GC_word); +GC_API GC_word GC_CALL GC_get_allocd_bytes_per_finalizer(void); + /* Tell the collector to start various performance measurements. */ /* Only the total time taken by full collections is calculated, as */ /* of now. And, currently, there is no way to stop the measurements. */ @@ -444,6 +485,12 @@ GC_API void GC_CALL GC_set_max_prior_attempts(int); GC_API int GC_CALL GC_get_max_prior_attempts(void); +/* Control whether to disable algorithm deciding if a collection should */ +/* be started when we allocated enough to amortize GC. Both the setter */ +/* and the getter acquire the GC lock (to avoid data races). */ +GC_API void GC_CALL GC_set_disable_automatic_collection(int); +GC_API int GC_CALL GC_get_disable_automatic_collection(void); + /* Overrides the default handle-fork mode. Non-zero value means GC */ /* should install proper pthread_atfork handlers. Has effect only if */ /* called before GC_INIT. Clients should invoke GC_set_handle_fork */ @@ -452,8 +499,8 @@ /* activities are not fully POSIX-compliant.) GC_set_handle_fork */ /* instructs GC_init to setup GC fork handlers using pthread_atfork, */ /* the latter might fail (or, even, absent on some targets) causing */ -/* abort at GC initialization. Starting from 7.3alpha3, problems with */ -/* missing (or failed) pthread_atfork() could be avoided by invocation */ +/* abort at GC initialization. Issues with missing (or failed) */ +/* pthread_atfork() could be avoided by invocation */ /* of GC_set_handle_fork(-1) at application start-up and surrounding */ /* each fork() with the relevant GC_atfork_prepare/parent/child calls. */ GC_API void GC_CALL GC_set_handle_fork(int); @@ -463,7 +510,7 @@ /* before fork(); GC_atfork_parent should be invoked just after fork in */ /* the branch that corresponds to parent process (i.e., fork result is */ /* non-zero); GC_atfork_child is to be called immediately in the child */ -/* branch (i.e., fork result is 0). Note that GC_atfork_child() call */ +/* branch (i.e., fork result is 0). Note that GC_atfork_child() call */ /* should, of course, precede GC_start_mark_threads call (if any). */ GC_API void GC_CALL GC_atfork_prepare(void); GC_API void GC_CALL GC_atfork_parent(void); @@ -599,17 +646,20 @@ GC_API void GC_CALL GC_exclude_static_roots(void * /* low_address */, void * /* high_address_plus_1 */); +/* Clear the number of entries in the exclusion table. Wizards only. */ +GC_API void GC_CALL GC_clear_exclusion_table(void); + /* Clear the set of root segments. Wizards only. */ GC_API void GC_CALL GC_clear_roots(void); /* Add a root segment. Wizards only. */ +/* May merge adjacent or overlapping segments if appropriate. */ /* Both segment start and end are not needed to be pointer-aligned. */ /* low_address must not be greater than high_address_plus_1. */ GC_API void GC_CALL GC_add_roots(void * /* low_address */, void * /* high_address_plus_1 */); -/* Remove a root segment. Wizards only. */ -/* May be unimplemented on some platforms. */ +/* Remove root segments located fully in the region. Wizards only. */ GC_API void GC_CALL GC_remove_roots(void * /* low_address */, void * /* high_address_plus_1 */); @@ -659,8 +709,8 @@ GC_ATTR_NONNULL(1); /* Set and get the default stop_func. The default stop_func is used by */ -/* GC_gcollect() and by implicitly trigged collections (except for the */ -/* case when handling out of memory). Must not be 0. */ +/* GC_gcollect() and by implicitly triggered collections (except for */ +/* the case when handling out of memory). Must not be 0. */ /* Both the setter and getter acquire the GC lock to avoid data races. */ GC_API void GC_CALL GC_set_stop_func(GC_stop_func /* stop_func */) GC_ATTR_NONNULL(1); @@ -677,7 +727,7 @@ /* This getter remains lock-free (unsynchronized) for compatibility */ /* reason since some existing clients call it from a GC callback */ /* holding the allocator lock. (This API function and the following */ -/* four ones below were made thread-safe in GC v7.2alpha1 and */ +/* four ones below were made thread-safe in GC v7.2alpha1 and */ /* reverted back in v7.2alpha7 for the reason described.) */ GC_API size_t GC_CALL GC_get_heap_size(void); @@ -706,13 +756,15 @@ /* getter (see GC_get_heap_size comment regarding thread-safety). */ GC_API size_t GC_CALL GC_get_total_bytes(void); +/* Return the total number of bytes obtained from OS. Includes the */ +/* unmapped memory. Never decreases. It is an unsynchronized getter. */ +GC_API size_t GC_CALL GC_get_obtained_from_os_bytes(void); + /* Return the heap usage information. This is a thread-safe (atomic) */ /* alternative for the five above getters. (This function acquires */ /* the allocator lock thus preventing data racing and returning the */ /* consistent result.) Passing NULL pointer is allowed for any */ /* argument. Returned (filled in) values are of word type. */ -/* (This API function was introduced in GC v7.2alpha7 at the same time */ -/* when GC_get_heap_size and the friends were made lock-free again.) */ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word * /* pheap_size */, GC_word * /* pfree_bytes */, GC_word * /* punmapped_bytes */, @@ -758,6 +810,8 @@ GC_word expl_freed_bytes_since_gc; /* Number of bytes freed explicitly since the recent GC. */ /* Same as returned by GC_get_expl_freed_bytes_since_gc(). */ + GC_word obtained_from_os_bytes; + /* Total amount of memory obtained from OS, in bytes. */ }; /* Atomically get GC statistics (various global counters). Clients */ @@ -820,12 +874,11 @@ /* dirty bits are available or most heap objects are pointer-free */ /* (atomic) or immutable. Don't use in leak finding mode. Ignored if */ /* GC_dont_gc is non-zero. Only the generational piece of this is */ -/* functional if GC_parallel is non-zero or if GC_time_limit is */ -/* GC_TIME_UNLIMITED. Causes thread-local variant of GC_gcj_malloc() */ -/* to revert to locked allocation. Must be called before any such */ -/* GC_gcj_malloc() calls. For best performance, should be called as */ -/* early as possible. On some platforms, calling it later may have */ -/* adverse effects. */ +/* functional if GC_time_limit is set to GC_TIME_UNLIMITED. Causes */ +/* thread-local variant of GC_gcj_malloc() to revert to locked */ +/* allocation. Must be called before any such GC_gcj_malloc() calls. */ +/* For best performance, should be called as early as possible. */ +/* On some platforms, calling it later may have adverse effects. */ /* Safe to call before GC_INIT(). Includes a GC_init() call. */ GC_API void GC_CALL GC_enable_incremental(void); @@ -833,17 +886,26 @@ /* Does not acquire the lock. */ GC_API int GC_CALL GC_is_incremental_mode(void); -/* Does incremental mode write-protect pages? Returns zero or */ -/* more of the following, or'ed together: */ #define GC_PROTECTS_POINTER_HEAP 1 /* May protect non-atomic objects. */ #define GC_PROTECTS_PTRFREE_HEAP 2 #define GC_PROTECTS_STATIC_DATA 4 /* Currently never. */ #define GC_PROTECTS_STACK 8 /* Probably impractical. */ #define GC_PROTECTS_NONE 0 -/* The collector is assumed to be initialized before this call. */ + +/* Does incremental mode write-protect pages? Returns zero or */ +/* more of the above GC_PROTECTS_*, or'ed together. */ +/* The collector is assumed to be initialized before this call. */ +/* The result is not affected by GC_set_manual_vdb_allowed(). */ +/* Call of GC_enable_incremental() may change the result to */ +/* GC_PROTECTS_NONE if some implementation is chosen at runtime */ +/* not needing to write-protect the pages. */ GC_API int GC_CALL GC_incremental_protection_needs(void); +/* Force start of incremental collection. Acquires the GC lock. */ +/* No-op unless GC incremental mode is on. */ +GC_API void GC_CALL GC_start_incremental_collection(void); + /* Perform some garbage collection work, if appropriate. */ /* Return 0 if there is no more work to be done (including the */ /* case when garbage collection is not appropriate). */ @@ -865,7 +927,7 @@ /* it reduces the chance of the allocator not finding space for such */ /* an array, since it will try hard to avoid introducing such a false */ /* reference.) On a SunOS 4.X or MS Windows system this is recommended */ -/* for arrays likely to be larger than 100K or so. For other systems, */ +/* for arrays likely to be larger than 100 KB or so. For other systems,*/ /* or if the collector is not configured to recognize all interior */ /* pointers, the threshold is normally much higher. */ GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL @@ -914,11 +976,7 @@ GC_API void * GC_CALL GC_debug_realloc(void * /* old_object */, size_t /* new_size_in_bytes */, GC_EXTRA_PARAMS) /* 'realloc' attr */ GC_ATTR_ALLOC_SIZE(2); -GC_API -#if !defined(CPPCHECK) - GC_ATTR_DEPRECATED -#endif -void GC_CALL GC_debug_change_stubborn(const void *); +GC_API GC_ATTR_DEPRECATED void GC_CALL GC_debug_change_stubborn(const void *); GC_API void GC_CALL GC_debug_end_stubborn_change(const void *) GC_ATTR_NONNULL(1); @@ -1324,8 +1382,13 @@ /* The function is sometimes called keep_alive in other */ /* settings. */ #if defined(__GNUC__) && !defined(__INTEL_COMPILER) -# define GC_reachable_here(ptr) \ - __asm__ __volatile__(" " : : "X"(ptr) : "memory") +# if defined(__e2k__) +# define GC_reachable_here(ptr) \ + __asm__ __volatile__ (" " : : "r"(ptr) : "memory") +# else +# define GC_reachable_here(ptr) \ + __asm__ __volatile__ (" " : : "X"(ptr) : "memory") +# endif #else GC_API void GC_CALL GC_noop1(GC_word); # ifdef LINT2 @@ -1339,7 +1402,7 @@ /* GC_set_warn_proc can be used to redirect or filter warning messages. */ /* p may not be a NULL pointer. msg is printf format string (arg must */ /* match the format). Both the setter and the getter acquire the GC */ -/* lock (to avoid data races). In version 7.1 (and before), the setter */ +/* lock (to avoid data races). In GC v7.1 (and before), the setter */ /* returned the old warn_proc value. */ typedef void (GC_CALLBACK * GC_warn_proc)(char * /* msg */, GC_word /* arg */); @@ -1391,6 +1454,18 @@ # define REVEAL_POINTER(p) GC_REVEAL_POINTER(p) #endif +/* The routines to acquire/release the allocator lock. */ +/* The lock is not reentrant. GC_alloc_unlock() should not be called */ +/* unless the lock is acquired by the current thread. */ +#ifdef GC_THREADS + GC_API void GC_CALL GC_alloc_lock(void); + GC_API void GC_CALL GC_alloc_unlock(void); +#else + /* No need for real locking if the client is single-threaded. */ +# define GC_alloc_lock() (void)0 +# define GC_alloc_unlock() (void)0 +#endif /* !GC_THREADS */ + typedef void * (GC_CALLBACK * GC_fn_type)(void * /* client_data */); GC_API void * GC_CALL GC_call_with_alloc_lock(GC_fn_type /* fn */, void * /* client_data */) GC_ATTR_NONNULL(1); @@ -1402,15 +1477,16 @@ /* is to always make redundant registration safe. In the short run, */ /* this is being implemented a platform at a time. */ /* The interface is complicated by the fact that we probably will not */ -/* ever be able to automatically determine the stack base for thread */ +/* ever be able to automatically determine the stack bottom for thread */ /* stacks on all platforms. */ -/* Structure representing the base of a thread stack. On most */ -/* platforms this contains just a single address. */ +/* Structure representing the bottom (cold end) of a thread stack. */ +/* On most platforms this contains just a single address. */ struct GC_stack_base { - void * mem_base; /* Base of memory stack. */ -# if defined(__ia64) || defined(__ia64__) || defined(_M_IA64) - void * reg_base; /* Base of separate register stack. */ + void * mem_base; /* the bottom of the general-purpose stack */ +# if defined(__e2k__) \ + || defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + void * reg_base; /* the bottom of the register stack */ # endif }; @@ -1419,7 +1495,7 @@ /* Call a function with a stack base structure corresponding to */ /* somewhere in the GC_call_with_stack_base frame. This often can */ -/* be used to provide a sufficiently accurate stack base. And we */ +/* be used to provide a sufficiently accurate stack bottom. And we */ /* implement it everywhere. */ GC_API void * GC_CALL GC_call_with_stack_base(GC_stack_base_func /* fn */, void * /* arg */) GC_ATTR_NONNULL(1); @@ -1432,6 +1508,12 @@ #define GC_NOT_FOUND 4 /* Requested link not found (returned */ /* by GC_move_disappearing_link). */ +/* Start the parallel marker threads, if available. Useful, e.g., */ +/* after POSIX fork in a child process (provided not followed by exec) */ +/* or in single-threaded clients (provided it is OK for the client to */ +/* perform marking in parallel). Acquires the GC lock to avoid a race. */ +GC_API void GC_CALL GC_start_mark_threads(void); + #if defined(GC_DARWIN_THREADS) || defined(GC_WIN32_THREADS) /* Use implicit thread registration and processing (via Win32 DllMain */ /* or Darwin task_threads). Deprecated. Must be called before */ @@ -1459,10 +1541,6 @@ /* systems. Return -1 otherwise. */ GC_API int GC_CALL GC_get_thr_restart_signal(void); - /* Restart marker threads after POSIX fork in child. Meaningless in */ - /* other situations. Should not be called if fork followed by exec. */ - GC_API void GC_CALL GC_start_mark_threads(void); - /* Explicitly enable GC_register_my_thread() invocation. */ /* Done implicitly if a GC thread-creation function is called (or */ /* implicit thread registration is activated, or the collector is */ @@ -1470,9 +1548,10 @@ /* must be called from the main (or any previously registered) thread */ /* between the collector initialization and the first explicit */ /* registering of a thread (it should be called as late as possible). */ + /* Includes a GC_start_mark_threads() call. */ GC_API void GC_CALL GC_allow_register_threads(void); - /* Register the current thread, with the indicated stack base, as */ + /* Register the current thread, with the indicated stack bottom, as */ /* a new thread whose stack(s) should be traced by the GC. If it */ /* is not implicitly called by the GC, this must be called before a */ /* thread can allocate garbage collected memory, or assign pointers */ @@ -1552,11 +1631,11 @@ /* initialized and the current thread is registered. fn may toggle */ /* the collector thread's state temporarily to "inactive" one by using */ /* GC_do_blocking. GC_call_with_gc_active() often can be used to */ -/* provide a sufficiently accurate stack base. */ +/* provide a sufficiently accurate stack bottom. */ GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type /* fn */, void * /* client_data */) GC_ATTR_NONNULL(1); -/* Attempt to fill in the GC_stack_base structure with the stack base */ +/* Attempt to fill in the GC_stack_base structure with the stack bottom */ /* for this thread. This appears to be required to implement anything */ /* like the JNI AttachCurrentThread in an environment in which new */ /* threads are not automatically registered with the collector. */ @@ -1566,6 +1645,30 @@ GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *) GC_ATTR_NONNULL(1); +/* Fill in the GC_stack_base structure with the cold end (bottom) of */ +/* the stack of the current thread (or coroutine). */ +/* Unlike GC_get_stack_base, it retrieves the value stored in the */ +/* collector (which is initially set by the collector upon the thread */ +/* is started or registered manually but it could be later updated by */ +/* client using GC_set_stackbottom). Returns the GC-internal non-NULL */ +/* handle of the thread which could be passed to GC_set_stackbottom */ +/* later. It is assumed that the collector is already initialized and */ +/* the thread is registered. Acquires the GC lock to avoid data races. */ +GC_API void * GC_CALL GC_get_my_stackbottom(struct GC_stack_base *) + GC_ATTR_NONNULL(1); + +/* Set the cool end of the user (coroutine) stack of the specified */ +/* thread. The GC thread handle is either the one returned by */ +/* GC_get_my_stackbottom or NULL (the latter designates the current */ +/* thread). The caller should hold the GC lock (e.g. using */ +/* GC_call_with_alloc_lock). Also, the function could be used for */ +/* setting GC_stackbottom value (the bottom of the primordial thread) */ +/* before the collector is initialized (the GC lock is not needed to be */ +/* acquired in this case). */ +GC_API void GC_CALL GC_set_stackbottom(void * /* gc_thread_handle */, + const struct GC_stack_base *) + GC_ATTR_NONNULL(2); + /* The following routines are primarily intended for use with a */ /* preprocessor which inserts calls to check C pointer arithmetic. */ /* They indicate failure by invoking the corresponding _print_proc. */ @@ -1942,6 +2045,14 @@ # define GC_INIT_CONF_MAX_RETRIES /* empty */ #endif +#if defined(GC_ALLOCD_BYTES_PER_FINALIZER) && !defined(CPPCHECK) + /* Set GC_allocd_bytes_per_finalizer to the desired value at start-up. */ +# define GC_INIT_CONF_ALLOCD_BYTES_PER_FINALIZER \ + GC_set_allocd_bytes_per_finalizer(GC_ALLOCD_BYTES_PER_FINALIZER) +#else +# define GC_INIT_CONF_ALLOCD_BYTES_PER_FINALIZER /* empty */ +#endif + #if defined(GC_FREE_SPACE_DIVISOR) && !defined(CPPCHECK) /* Set GC_free_space_divisor to the desired value at start-up */ # define GC_INIT_CONF_FREE_SPACE_DIVISOR \ @@ -1958,12 +2069,20 @@ #endif #if defined(GC_TIME_LIMIT) && !defined(CPPCHECK) - /* Set GC_time_limit to the desired value at start-up */ + /* Set GC_time_limit (in ms) to the desired value at start-up. */ # define GC_INIT_CONF_TIME_LIMIT GC_set_time_limit(GC_TIME_LIMIT) #else # define GC_INIT_CONF_TIME_LIMIT /* empty */ #endif +#if defined(GC_MARKERS) && defined(GC_THREADS) && !defined(CPPCHECK) + /* Set the number of marker threads (including the initiating */ + /* one) to the desired value at start-up. */ +# define GC_INIT_CONF_MARKERS GC_set_markers_count(GC_MARKERS) +#else +# define GC_INIT_CONF_MARKERS /* empty */ +#endif + #if defined(GC_SIG_SUSPEND) && defined(GC_THREADS) && !defined(CPPCHECK) # define GC_INIT_CONF_SUSPEND_SIGNAL GC_set_suspend_signal(GC_SIG_SUSPEND) #else @@ -2011,9 +2130,11 @@ #define GC_INIT() { GC_INIT_CONF_DONT_EXPAND; /* pre-init */ \ GC_INIT_CONF_FORCE_UNMAP_ON_GCOLLECT; \ GC_INIT_CONF_MAX_RETRIES; \ + GC_INIT_CONF_ALLOCD_BYTES_PER_FINALIZER; \ GC_INIT_CONF_FREE_SPACE_DIVISOR; \ GC_INIT_CONF_FULL_FREQ; \ GC_INIT_CONF_TIME_LIMIT; \ + GC_INIT_CONF_MARKERS; \ GC_INIT_CONF_SUSPEND_SIGNAL; \ GC_INIT_CONF_THR_RESTART_SIGNAL; \ GC_INIT_CONF_MAXIMUM_HEAP_SIZE; \ @@ -2022,8 +2143,8 @@ GC_INIT_CONF_IGNORE_WARN; \ GC_INIT_CONF_INITIAL_HEAP_SIZE; } -/* win32S may not free all resources on process exit. */ -/* This explicitly deallocates the heap. */ +/* win32S may not free all resources on process exit. */ +/* This explicitly deallocates the heap. Defined only for Windows. */ GC_API void GC_CALL GC_win32_free_heap(void); #if defined(__SYMBIAN32__)
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_allocator.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc_allocator.h
Changed
@@ -43,36 +43,11 @@ #include "gc.h" #include <new> // for placement new and bad_alloc -#ifndef GC_ATTR_EXPLICIT -# if __cplusplus >= 201103L && !defined(__clang__) || _MSVC_LANG >= 201103L \ - || defined(CPPCHECK) -# define GC_ATTR_EXPLICIT explicit -# else -# define GC_ATTR_EXPLICIT /* empty */ -# endif -#endif - #if !defined(GC_NO_MEMBER_TEMPLATES) && defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC++ 6.0 do not support member templates. # define GC_NO_MEMBER_TEMPLATES #endif -#ifndef GC_NOEXCEPT -# if defined(__DMC__) || (defined(__BORLANDC__) \ - && (defined(_RWSTD_NO_EXCEPTIONS) || defined(_RWSTD_NO_EX_SPEC))) \ - || (defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) \ - || (defined(__WATCOMC__) && !defined(_CPPUNWIND)) -# define GC_NOEXCEPT /* empty */ -# ifndef GC_NEW_ABORTS_ON_OOM -# define GC_NEW_ABORTS_ON_OOM -# endif -# elif __cplusplus >= 201103L || _MSVC_LANG >= 201103L -# define GC_NOEXCEPT noexcept -# else -# define GC_NOEXCEPT throw() -# endif -#endif // !GC_NOEXCEPT - #if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) # define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() #else
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_config_macros.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc_config_macros.h
Changed
@@ -4,6 +4,7 @@ * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. * All rights reserved. + * Copyright (c) 2008-2020 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -90,8 +91,8 @@ # define GC_HPUX_THREADS # elif defined(__HAIKU__) # define GC_HAIKU_THREADS -# elif defined(__DragonFly__) || defined(__FreeBSD_kernel__) \ - || (defined(__FreeBSD__) && !defined(SN_TARGET_ORBIS)) +# elif (defined(__DragonFly__) || defined(__FreeBSD_kernel__) \ + || defined(__FreeBSD__)) && !defined(GC_NO_FREEBSD) # define GC_FREEBSD_THREADS # elif defined(__NetBSD__) # define GC_NETBSD_THREADS @@ -285,6 +286,14 @@ # endif #endif +#ifndef GC_ATTR_CONST +# if GC_GNUC_PREREQ(4, 0) +# define GC_ATTR_CONST __attribute__((__const__)) +# else +# define GC_ATTR_CONST /* empty */ +# endif +#endif + #ifndef GC_ATTR_DEPRECATED # ifdef GC_BUILD # undef GC_ATTR_DEPRECATED @@ -319,6 +328,7 @@ #endif /* GLIBC */ #if defined(_MSC_VER) && _MSC_VER >= 1200 /* version 12.0+ (MSVC 6.0+) */ \ + && !defined(_M_ARM) && !defined(_M_ARM64) \ && !defined(_AMD64_) && !defined(_M_X64) && !defined(_WIN32_WCE) \ && !defined(GC_HAVE_NO_BUILTIN_BACKTRACE) \ && !defined(GC_HAVE_BUILTIN_BACKTRACE) @@ -351,10 +361,13 @@ /* how to generate call stacks. */ # define GC_RETURN_ADDR (GC_word)__builtin_return_address(0) # if GC_GNUC_PREREQ(4, 0) && (defined(__i386__) || defined(__amd64__) \ - || defined(__x86_64__) /* and probably others... */) + || defined(__x86_64__) /* and probably others... */) \ + && !defined(GC_NO_RETURN_ADDR_PARENT) # define GC_HAVE_RETURN_ADDR_PARENT # define GC_RETURN_ADDR_PARENT \ (GC_word)__builtin_extract_return_addr(__builtin_return_address(1)) + /* Note: a compiler might complain that calling */ + /* __builtin_return_address with a nonzero argument is unsafe. */ # endif # else /* Just pass 0 for gcc compatibility. */ @@ -413,4 +426,33 @@ #endif /* GC_PTHREADS */ +#ifdef __cplusplus + +#ifndef GC_ATTR_EXPLICIT +# if __cplusplus >= 201103L && !defined(__clang__) || _MSVC_LANG >= 201103L \ + || defined(CPPCHECK) +# define GC_ATTR_EXPLICIT explicit +# else +# define GC_ATTR_EXPLICIT /* empty */ +# endif +#endif + +#ifndef GC_NOEXCEPT +# if defined(__DMC__) || (defined(__BORLANDC__) \ + && (defined(_RWSTD_NO_EXCEPTIONS) || defined(_RWSTD_NO_EX_SPEC))) \ + || (defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) \ + || (defined(__WATCOMC__) && !defined(_CPPUNWIND)) +# define GC_NOEXCEPT /* empty */ +# ifndef GC_NEW_ABORTS_ON_OOM +# define GC_NEW_ABORTS_ON_OOM +# endif +# elif __cplusplus >= 201103L || _MSVC_LANG >= 201103L +# define GC_NOEXCEPT noexcept +# else +# define GC_NOEXCEPT throw() +# endif +#endif + +#endif /* __cplusplus */ + #endif
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_cpp.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc_cpp.h
Changed
@@ -135,7 +135,7 @@ 5. GC name conflicts: Many other systems seem to use the identifier "GC" as an abbreviation -for "Graphics Context". Since version 5.0, GC placement has been replaced +for "Graphics Context". Thus, GC placement has been replaced by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. ****************************************************************************/ @@ -173,22 +173,6 @@ # define GC_PLACEMENT_DELETE #endif -#ifndef GC_NOEXCEPT -# if defined(__DMC__) || (defined(__BORLANDC__) \ - && (defined(_RWSTD_NO_EXCEPTIONS) || defined(_RWSTD_NO_EX_SPEC))) \ - || (defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) \ - || (defined(__WATCOMC__) && !defined(_CPPUNWIND)) -# define GC_NOEXCEPT /* empty */ -# ifndef GC_NEW_ABORTS_ON_OOM -# define GC_NEW_ABORTS_ON_OOM -# endif -# elif __cplusplus >= 201103L || _MSVC_LANG >= 201103L -# define GC_NOEXCEPT noexcept -# else -# define GC_NOEXCEPT throw() -# endif -#endif // !GC_NOEXCEPT - #if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) # define GC_OP_NEW_OOM_CHECK(obj) \ do { if (!(obj)) GC_abort_on_oom(); } while (0) @@ -504,9 +488,11 @@ inline gc_cleanup::~gc_cleanup() { - void* base = GC_base(this); - if (0 == base) return; // Non-heap object. - GC_register_finalizer_ignore_self(base, 0, 0, 0, 0); +# ifndef GC_NO_FINALIZATION + void* base = GC_base(this); + if (0 == base) return; // Non-heap object. + GC_register_finalizer_ignore_self(base, 0, 0, 0, 0); +# endif } inline void GC_CALLBACK gc_cleanup::cleanup(void* obj, void* displ) @@ -516,19 +502,23 @@ inline gc_cleanup::gc_cleanup() { - GC_finalization_proc oldProc; - void* oldData; - void* this_ptr = (void*)this; - void* base = GC_base(this_ptr); - if (base != 0) { - // Don't call the debug version, since this is a real base address. - GC_register_finalizer_ignore_self(base, (GC_finalization_proc) cleanup, - (void*)((char*)this_ptr - (char*)base), - &oldProc, &oldData); - if (oldProc != 0) { - GC_register_finalizer_ignore_self(base, oldProc, oldData, 0, 0); +# ifndef GC_NO_FINALIZATION + GC_finalization_proc oldProc = 0; + void* oldData = NULL; // to avoid "might be uninitialized" compiler warning + void* this_ptr = (void*)this; + void* base = GC_base(this_ptr); + if (base != 0) { + // Don't call the debug version, since this is a real base address. + GC_register_finalizer_ignore_self(base, (GC_finalization_proc) cleanup, + (void*)((char*)this_ptr-(char*)base), + &oldProc, &oldData); + if (oldProc != 0) { + GC_register_finalizer_ignore_self(base, oldProc, oldData, 0, 0); + } } - } +# elif defined(CPPCHECK) + (void)cleanup; +# endif } #ifdef GC_NAMESPACE @@ -543,9 +533,14 @@ switch (gcp) { case GC_NS_QUALIFY(UseGC): obj = GC_MALLOC(size); - if (cleanup != 0 && obj != 0) { - GC_REGISTER_FINALIZER_IGNORE_SELF(obj, cleanup, clientData, 0, 0); - } +# ifndef GC_NO_FINALIZATION + if (cleanup != 0 && obj != 0) { + GC_REGISTER_FINALIZER_IGNORE_SELF(obj, cleanup, clientData, 0, 0); + } +# else + (void)cleanup; + (void)clientData; +# endif break; case GC_NS_QUALIFY(PointerFreeGC): obj = GC_MALLOC_ATOMIC(size);
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_inline.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc_inline.h
Changed
@@ -95,7 +95,7 @@ /* The ultimately general inline allocation macro. Allocate an object */ /* of size granules, putting the resulting pointer in result. Tiny_fl */ /* is a "tiny" free list array, which will be used first, if the size */ -/* is appropriate. If granules is too large, we allocate with */ +/* is appropriate. If granules argument is too large, we allocate with */ /* default_expr instead. If we need to refill the free list, we use */ /* GC_generic_malloc_many with the indicated kind. */ /* Tiny_fl should be an array of GC_TINY_FREELISTS void * pointers. */ @@ -108,8 +108,8 @@ /* size that are used to satisfy size 0 allocation requests. */ /* We rely on much of this hopefully getting optimized away in the */ /* num_direct = 0 case. */ -/* Particularly if granules is constant, this should generate a small */ -/* amount of code. */ +/* Particularly, if granules argument is constant, this should generate */ +/* a small amount of code. */ # define GC_FAST_MALLOC_GRANS(result,granules,tiny_fl,num_direct, \ kind,default_expr,init) \ do { \ @@ -167,10 +167,9 @@ /* Allocate n words (NOT BYTES). X is made to point to the result. */ /* This should really only be used if GC_all_interior_pointers is */ /* not set, or DONT_ADD_BYTE_AT_END is set. See above. */ -/* The semantics changed in version 7.0; we no longer lock, and */ -/* the caller is responsible for supplying a cleared tiny_fl */ -/* free list array. For single-threaded applications, this may be */ -/* a global array. */ +/* Does not acquire lock. The caller is responsible for supplying */ +/* a cleared tiny_fl free list array. For single-threaded */ +/* applications, this may be a global array. */ # define GC_MALLOC_WORDS_KIND(result,n,tiny_fl,kind,init) \ do { \ size_t granules = GC_WORDS_TO_WHOLE_GRANULES(n); \
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_mark.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc_mark.h
Changed
@@ -33,6 +33,14 @@ extern "C" { #endif +#define GC_PROC_BYTES 100 + +#if defined(GC_BUILD) || defined(NOT_GCBUILD) + struct GC_ms_entry; +#else + struct GC_ms_entry { void *opaque; }; +#endif + /* A client supplied mark procedure. Returns new mark stack pointer. */ /* Primary effect should be to push new entries on the mark stack. */ /* Mark stack pointer values are passed and returned explicitly. */ @@ -54,14 +62,10 @@ /* residing on a free list. Such objects are cleared, except for a */ /* free list link field in the first word. Thus mark procedures may */ /* not count on the presence of a type descriptor, and must handle this */ -/* case correctly somehow. */ -#define GC_PROC_BYTES 100 - -#ifdef GC_BUILD - struct GC_ms_entry; -#else - struct GC_ms_entry { void *opaque; }; -#endif +/* case correctly somehow. Also, a mark procedure should be prepared */ +/* to be executed concurrently from the marker threads (the later ones */ +/* are created only if the client has called GC_start_mark_threads() */ +/* or started a user thread previously). */ typedef struct GC_ms_entry * (*GC_mark_proc)(GC_word * /* addr */, struct GC_ms_entry * /* mark_stack_ptr */, struct GC_ms_entry * /* mark_stack_limit */, @@ -152,12 +156,23 @@ (GC_word)(obj) <= (GC_word)GC_greatest_plausible_heap_addr ? \ GC_mark_and_push(obj, msp, lim, src) : (msp)) -GC_API size_t GC_debug_header_size; - /* The size of the header added to objects allocated through */ - /* the GC_debug routines. */ - /* Defined as a variable so that client mark procedures don't */ - /* need to be recompiled for collector version changes. */ -#define GC_USR_PTR_FROM_BASE(p) ((void *)((char *)(p) + GC_debug_header_size)) +/* The size of the header added to objects allocated through the */ +/* GC_debug routines. Defined as a function so that client mark */ +/* procedures do not need to be recompiled for the collector library */ +/* version changes. */ +GC_API GC_ATTR_CONST size_t GC_CALL GC_get_debug_header_size(void); +#define GC_USR_PTR_FROM_BASE(p) \ + ((void *)((char *)(p) + GC_get_debug_header_size())) + +/* The same but defined as a variable. Exists only for the backward */ +/* compatibility. Some compilers do not accept "const" together with */ +/* deprecated or dllimport attributes, so the symbol is exported as */ +/* a non-constant one. */ +GC_API GC_ATTR_DEPRECATED +# ifdef GC_BUILD + const +# endif + size_t GC_debug_header_size; /* And some routines to support creation of new "kinds", e.g. with */ /* custom mark procedures, by language runtimes. */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/gc_version.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/gc_version.h
Changed
@@ -29,8 +29,8 @@ /* Eventually this one may become unnecessary. For now we need */ /* it to keep the old-style build process working. */ #define GC_TMP_VERSION_MAJOR 8 -#define GC_TMP_VERSION_MINOR 0 -#define GC_TMP_VERSION_MICRO 6 /* 8.0.6 */ +#define GC_TMP_VERSION_MINOR 2 +#define GC_TMP_VERSION_MICRO 2 /* 8.2.2 */ #ifdef GC_VERSION_MAJOR # if GC_TMP_VERSION_MAJOR != GC_VERSION_MAJOR \
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/include.am -> _service:tar_scm:gc-8.2.2.tar.gz/include/include.am
Changed
@@ -16,10 +16,8 @@ include/gc.h \ include/gc_backptr.h \ include/gc_config_macros.h \ - include/gc_gcj.h \ include/gc_inline.h \ include/gc_mark.h \ - include/gc_pthread_redirects.h \ include/gc_tiny_fl.h \ include/gc_typed.h \ include/gc_version.h \ @@ -29,18 +27,16 @@ # headers which are not installed # dist_noinst_HEADERS += \ - include/gc_alloc_ptrs.h \ - include/new_gc_alloc.h \ include/private/darwin_semaphore.h \ include/private/darwin_stop_world.h \ include/private/dbg_mlc.h \ + include/private/gc_alloc_ptrs.h \ include/private/gc_atomic_ops.h \ include/private/gc_hdrs.h \ include/private/gc_locks.h \ include/private/gc_pmark.h \ include/private/gc_priv.h \ include/private/gcconfig.h \ - include/private/msvc_dbg.h \ include/private/pthread_stop_world.h \ include/private/pthread_support.h \ include/private/specific.h \
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/leak_detector.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/leak_detector.h
Changed
@@ -16,7 +16,7 @@ #define GC_LEAK_DETECTOR_H /* Include leak_detector.h (e.g., via GCC --include directive) */ -/* to turn BoehmGC into a Leak Detector. */ +/* to turn libgc into a leak detector. */ #ifndef GC_DEBUG # define GC_DEBUG
View file
_service:tar_scm:gc-8.2.2.tar.gz/include/private/gc_alloc_ptrs.h
Added
@@ -0,0 +1,60 @@ +/* + * Copyright (c) 1996-1998 by Silicon Graphics. All rights reserved. + * Copyright (c) 2018-2021 Ivan Maidanski + * + * 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 file is kept for a binary compatibility purpose only. */ + +#ifndef GC_ALLOC_PTRS_H +#define GC_ALLOC_PTRS_H + +#include "gc.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef GC_API_PRIV +# define GC_API_PRIV GC_API +#endif + +/* Some compilers do not accept "const" together with the dllimport */ +/* attribute, so the symbols below are exported as non-constant ones. */ +#ifndef GC_APIVAR_CONST +# if defined(GC_BUILD) || !defined(GC_DLL) +# define GC_APIVAR_CONST const +# else +# define GC_APIVAR_CONST /* empty */ +# endif +#endif + +GC_API_PRIV void ** GC_APIVAR_CONST GC_objfreelist_ptr; +GC_API_PRIV void ** GC_APIVAR_CONST GC_aobjfreelist_ptr; +GC_API_PRIV void ** GC_APIVAR_CONST GC_uobjfreelist_ptr; + +#ifdef GC_ATOMIC_UNCOLLECTABLE + GC_API_PRIV void ** GC_APIVAR_CONST GC_auobjfreelist_ptr; +#endif + +/* Manually update the number of bytes allocated during the current */ +/* collection cycle and the number of explicitly deallocated bytes of */ +/* memory since the last collection, respectively. Both functions are */ +/* unsynchronized, GC_call_with_alloc_lock() should be used to avoid */ +/* data races. */ +GC_API_PRIV void GC_CALL GC_incr_bytes_allocd(size_t /* bytes */); +GC_API_PRIV void GC_CALL GC_incr_bytes_freed(size_t /* bytes */); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* GC_ALLOC_PTRS_H */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/gc_atomic_ops.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/gc_atomic_ops.h
Changed
@@ -12,7 +12,7 @@ */ /* This is a private GC header which provides an implementation of */ -/* libatomic_ops subset primitives sufficient for GC assuming that C11 */ +/* libatomic_ops subset primitives sufficient for GC assuming that GCC */ /* atomic intrinsics are available (and have correct implementation). */ /* This is enabled by defining GC_BUILTIN_ATOMIC macro. Otherwise, */ /* libatomic_ops library is used to define the primitives. */ @@ -45,7 +45,8 @@ # define AO_TS_SET (AO_TS_t)1 /* true */ # endif # define AO_CLEAR(p) __atomic_clear(p, __ATOMIC_RELEASE) -# define AO_test_and_set_acquire(p) __atomic_test_and_set(p, __ATOMIC_ACQUIRE) +# define AO_test_and_set_acquire(p) \ + (__atomic_test_and_set(p, __ATOMIC_ACQUIRE) ? AO_TS_SET : AO_TS_CLEAR) # define AO_HAVE_test_and_set_acquire # define AO_compiler_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/gc_locks.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/gc_locks.h
Changed
@@ -53,21 +53,17 @@ # endif # if (!defined(AO_HAVE_test_and_set_acquire) || defined(GC_RTEMS_PTHREADS) \ - || defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \ + || defined(SN_TARGET_PS3) \ || defined(GC_WIN32_THREADS) || defined(BASE_ATOMIC_OPS_EMULATED) \ || defined(LINT2)) && defined(GC_PTHREADS) # define USE_PTHREAD_LOCKS # undef USE_SPIN_LOCK +# if defined(LINT2) && !defined(NO_PTHREAD_TRYLOCK) +# define NO_PTHREAD_TRYLOCK +# endif # endif # if defined(GC_WIN32_THREADS) && !defined(USE_PTHREAD_LOCKS) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE - EXTERN_C_END -# include <windows.h> - EXTERN_C_BEGIN # define NO_THREAD (DWORD)(-1) GC_EXTERN CRITICAL_SECTION GC_allocate_ml; # ifdef GC_ASSERTIONS
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/gc_pmark.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/gc_pmark.h
Changed
@@ -74,8 +74,6 @@ /* Number of mark stack entries to discard on overflow. */ #define GC_MARK_STACK_DISCARDS (INITIAL_MARK_STACK_SIZE/8) -GC_EXTERN size_t GC_mark_stack_size; - #ifdef PARALLEL_MARK /* * Allow multiple threads to participate in the marking process. @@ -344,13 +342,13 @@ /* beginning of object. If so, it is valid, and we are fine. */ GC_ASSERT(gran_displ <= HBLK_OBJS(hhdr -> hb_sz)); # endif /* MARK_BIT_PER_OBJ */ - TRACE(source, GC_log_printf("GC #%u: passed validity tests\n", - (unsigned)GC_gc_no)); + TRACE(source, GC_log_printf("GC #%lu: passed validity tests\n", + (unsigned long)GC_gc_no)); SET_MARK_BIT_EXIT_IF_SET(hhdr, gran_displ); /* contains "break" */ - TRACE(source, GC_log_printf("GC #%u: previously unmarked\n", - (unsigned)GC_gc_no)); - TRACE_TARGET(base, GC_log_printf("GC #%u: marking %p from %p instead\n", - (unsigned)GC_gc_no, (void *)base, + TRACE(source, GC_log_printf("GC #%lu: previously unmarked\n", + (unsigned long)GC_gc_no)); + TRACE_TARGET(base, GC_log_printf("GC #%lu: marking %p from %p instead\n", + (unsigned long)GC_gc_no, (void *)base, (void *)source)); INCR_MARKS(hhdr); GC_STORE_BACK_PTR(source, base); @@ -442,13 +440,7 @@ } \ } while (0) -GC_EXTERN GC_bool GC_mark_stack_too_small; - /* We need a larger mark stack. May be */ - /* set by client supplied mark routines.*/ - -typedef int mark_state_t; /* Current state of marking, as follows:*/ - /* Used to remember where we are during */ - /* concurrent marking. */ + /* Current state of marking, as follows.*/ /* We say something is dirty if it was */ /* written since the last time we */ @@ -469,24 +461,24 @@ /* being pushed. "I" holds, except */ /* that grungy roots may point to */ /* unmarked objects, as may marked */ - /* grungy objects above scan_ptr. */ + /* grungy objects above GC_scan_ptr. */ #define MS_PUSH_UNCOLLECTABLE 2 /* "I" holds, except that marked */ - /* uncollectible objects above scan_ptr */ - /* may point to unmarked objects. */ - /* Roots may point to unmarked objects */ + /* uncollectible objects above */ + /* GC_scan_ptr may point to unmarked */ + /* objects. Roots may point to */ + /* unmarked objects. */ #define MS_ROOTS_PUSHED 3 /* "I" holds, mark stack may be nonempty. */ #define MS_PARTIALLY_INVALID 4 /* "I" may not hold, e.g. because of */ - /* the mark stack overflow. However */ - /* marked heap objects below scan_ptr */ - /* point to marked or stacked objects. */ + /* the mark stack overflow. However, */ + /* marked heap objects below */ + /* GC_scan_ptr point to marked or */ + /* stacked objects. */ #define MS_INVALID 5 /* "I" may not hold. */ -GC_EXTERN mark_state_t GC_mark_state; - EXTERN_C_END #endif /* GC_PMARK_H */
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/gc_priv.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/gc_priv.h
Changed
@@ -3,7 +3,7 @@ * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P. - * + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -22,13 +22,12 @@ # include "config.h" #endif -#ifndef GC_BUILD +#if !defined(GC_BUILD) && !defined(NOT_GCBUILD) # define GC_BUILD #endif #if (defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) \ - || (defined(__CYGWIN__) && !defined(USE_MMAP))) \ - && !defined(_GNU_SOURCE) + || defined(__CYGWIN__)) && !defined(_GNU_SOURCE) /* Can't test LINUX, since this must be defined before other includes. */ # define _GNU_SOURCE 1 #endif @@ -167,6 +166,16 @@ # define REGISTER register #endif +#if defined(CPPCHECK) +# define MACRO_BLKSTMT_BEGIN { +# define MACRO_BLKSTMT_END } +# define LOCAL_VAR_INIT_OK =0 /* to avoid "uninit var" false positive */ +#else +# define MACRO_BLKSTMT_BEGIN do { +# define MACRO_BLKSTMT_END } while (0) +# define LOCAL_VAR_INIT_OK /* empty */ +#endif + #if defined(M68K) && defined(__GNUC__) /* By default, __alignof__(word) is 2 on m68k. Use this attribute to */ /* have proper word alignment (i.e. 4-byte on a 32-bit arch). */ @@ -205,7 +214,10 @@ # elif GC_CLANG_PREREQ(3, 8) # define GC_ATTR_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread"))) # else -# define GC_ATTR_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) + /* It seems that no_sanitize_thread attribute has no effect if the */ + /* function is inlined (as of gcc 11.1.0, at least). */ +# define GC_ATTR_NO_SANITIZE_THREAD \ + GC_ATTR_NOINLINE __attribute__((no_sanitize_thread)) # endif #endif /* !GC_ATTR_NO_SANITIZE_THREAD */ @@ -259,14 +271,22 @@ # define GC_API_PRIV GC_API #endif -#if defined(THREADS) && !defined(NN_PLATFORM_CTR) \ - && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) +#if defined(THREADS) && !defined(NN_PLATFORM_CTR) # include "gc_atomic_ops.h" # ifndef AO_HAVE_compiler_barrier # define AO_HAVE_compiler_barrier 1 # endif #endif +#if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# define NOSERVICE +# include <windows.h> +# include <winbase.h> +#endif + #include "gc_locks.h" #define GC_WORD_MAX (~(word)0) @@ -323,7 +343,7 @@ /* by integers, etc. Under SunOS 4.X with a */ /* statically linked libc, we empirically */ /* observed that it would be difficult to */ - /* allocate individual objects larger than 100K. */ + /* allocate individual objects > 100 KB. */ /* Even if only smaller objects are allocated, */ /* more swap space is likely to be needed. */ /* Fortunately, much of this will never be */ @@ -446,23 +466,43 @@ x = rusage.ru_utime; \ } while (0) # define MS_TIME_DIFF(a,b) ((unsigned long)((long)(a.tv_sec-b.tv_sec) * 1000 \ - + (long)(a.tv_usec-b.tv_usec) / 1000)) + + (long)(a.tv_usec - b.tv_usec) / 1000 \ + - (a.tv_usec < b.tv_usec \ + && (long)(a.tv_usec - b.tv_usec) % 1000 != 0 ? 1 : 0))) /* "a" time is expected to be not earlier than */ /* "b" one; the result has unsigned long type. */ -#elif defined(MSWIN32) || defined(MSWINCE) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> -# include <winbase.h> -# define CLOCK_TYPE DWORD -# ifdef MSWINRT_FLAVOR -# define GET_TIME(x) (void)(x = (DWORD)GetTickCount64()) +# define NS_FRAC_TIME_DIFF(a, b) ((unsigned long) \ + ((a.tv_usec < b.tv_usec \ + && (long)(a.tv_usec - b.tv_usec) % 1000 != 0 ? 1000L : 0) \ + + (long)(a.tv_usec - b.tv_usec) % 1000) * 1000) + /* The total time difference could be computed as */ + /* MS_TIME_DIFF(a,b)*1000000+NS_FRAC_TIME_DIFF(a,b).*/ + +#elif defined(MSWIN32) || defined(MSWINCE) || defined(WINXP_USE_PERF_COUNTER) +# if defined(MSWINRT_FLAVOR) || defined(WINXP_USE_PERF_COUNTER) +# define CLOCK_TYPE ULONGLONG +# define GET_TIME(x) \ + do { \ + LARGE_INTEGER freq, tc; \ + if (!QueryPerformanceFrequency(&freq)) \ + ABORT("QueryPerformanceFrequency requires WinXP+"); \ + /* Note: two standalone if statements are needed to */ \ + /* avoid MS VC false warning about potentially */ \ + /* uninitialized tc variable. */ \ + if (!QueryPerformanceCounter(&tc)) \ + ABORT("QueryPerformanceCounter failed"); \ + x = (CLOCK_TYPE)((double)tc.QuadPart/freq.QuadPart * 1e9); \ + } while (0) + /* TODO: Call QueryPerformanceFrequency once at GC init. */ +# define MS_TIME_DIFF(a, b) ((unsigned long)(((a) - (b)) / 1000000UL)) +# define NS_FRAC_TIME_DIFF(a, b) ((unsigned long)(((a) - (b)) % 1000000UL)) # else +# define CLOCK_TYPE DWORD # define GET_TIME(x) (void)(x = GetTickCount()) -# endif -# define MS_TIME_DIFF(a,b) ((unsigned long)((a)-(b))) +# define MS_TIME_DIFF(a, b) ((unsigned long)((a) - (b))) +# define NS_FRAC_TIME_DIFF(a, b) 0UL +# endif /* !WINXP_USE_PERF_COUNTER */ + #elif defined(NN_PLATFORM_CTR) # define CLOCK_TYPE long long EXTERN_C_BEGIN @@ -471,7 +511,36 @@ EXTERN_C_END # define GET_TIME(x) (void)(x = n3ds_get_system_tick()) # define MS_TIME_DIFF(a,b) ((unsigned long)n3ds_convert_tick_to_ms((a)-(b))) -#else /* !BSD_TIME && !NN_PLATFORM_CTR && !MSWIN32 && !MSWINCE */ +# define NS_FRAC_TIME_DIFF(a, b) 0UL /* TODO: implement it */ + +#elif defined(NINTENDO_SWITCH) \ + || (((defined(LINUX) && defined(__USE_POSIX199309)) \ + || defined(CYGWIN32)) && defined(_POSIX_TIMERS)) +# include <time.h> +# define HAVE_CLOCK_GETTIME 1 +# define CLOCK_TYPE struct timespec +# define CLOCK_TYPE_INITIALIZER { 0, 0 } +# if defined(_POSIX_MONOTONIC_CLOCK) && !defined(NINTENDO_SWITCH) +# define GET_TIME(x) \ + do { \ + if (clock_gettime(CLOCK_MONOTONIC, &x) == -1) \ + ABORT("clock_gettime failed"); \ + } while (0) +# else +# define GET_TIME(x) \ + do { \ + if (clock_gettime(CLOCK_REALTIME, &x) == -1) \ + ABORT("clock_gettime failed"); \ + } while (0) +# endif +# define MS_TIME_DIFF(a, b) \ + /* a.tv_nsec - b.tv_nsec is in range -1e9 to 1e9 exclusively */ \ + ((unsigned long)((a).tv_nsec + (1000000L*1000 - (b).tv_nsec)) / 1000000UL \ + + ((unsigned long)((a).tv_sec - (b).tv_sec) * 1000UL) - 1000UL) +# define NS_FRAC_TIME_DIFF(a, b) \ + ((unsigned long)((a).tv_nsec + (1000000L*1000 - (b).tv_nsec)) % 1000000UL) + +#else /* !BSD_TIME && !LINUX && !NN_PLATFORM_CTR && !MSWIN32 */ # include <time.h> # if defined(FREEBSD) && !defined(CLOCKS_PER_SEC) # include <machine/limits.h> @@ -496,6 +565,13 @@ : ((unsigned long)((a) - (b)) * 1000) / (unsigned long)CLOCKS_PER_SEC) /* Avoid using double type since some targets (like ARM) might */ /* require -lm option for double-to-long conversion. */ +# define NS_FRAC_TIME_DIFF(a, b) (CLOCKS_PER_SEC <= 1000 ? 0UL \ + : (unsigned long)(CLOCKS_PER_SEC <= (clock_t)1000000UL \ + ? (((a) - (b)) * ((clock_t)1000000UL / CLOCKS_PER_SEC) % 1000) * 1000 \ + : (CLOCKS_PER_SEC <= (clock_t)1000000UL * 1000 \ + ? ((a) - (b)) * ((clock_t)1000000UL * 1000 / CLOCKS_PER_SEC) \ + : (((a) - (b)) * (clock_t)1000000UL * 1000) / CLOCKS_PER_SEC) \ + % (clock_t)1000000UL)) #endif /* !BSD_TIME && !MSWIN32 */ # ifndef CLOCK_TYPE_INITIALIZER /* This is used to initialize CLOCK_TYPE variables (to some value) */ @@ -610,21 +686,21 @@ /* literals. C_msg should not contain format specifiers. Arguments */ /* should match their format specifiers. */ #define ABORT_ARG1(C_msg, C_fmt, arg1) \ - do { \ - GC_INFOLOG_PRINTF(C_msg /* + */ C_fmt "\n", arg1); \ + MACRO_BLKSTMT_BEGIN \ + GC_ERRINFO_PRINTF(C_msg /* + */ C_fmt "\n", arg1); \ ABORT(C_msg); \ - } while (0) + MACRO_BLKSTMT_END #define ABORT_ARG2(C_msg, C_fmt, arg1, arg2) \ - do { \ - GC_INFOLOG_PRINTF(C_msg /* + */ C_fmt "\n", arg1, arg2); \ + MACRO_BLKSTMT_BEGIN \ + GC_ERRINFO_PRINTF(C_msg /* + */ C_fmt "\n", arg1, arg2); \ ABORT(C_msg); \ - } while (0) + MACRO_BLKSTMT_END #define ABORT_ARG3(C_msg, C_fmt, arg1, arg2, arg3) \ - do { \ - GC_INFOLOG_PRINTF(C_msg /* + */ C_fmt "\n", \ + MACRO_BLKSTMT_BEGIN \ + GC_ERRINFO_PRINTF(C_msg /* + */ C_fmt "\n", \ arg1, arg2, arg3); \ ABORT(C_msg); \ - } while (0) + MACRO_BLKSTMT_END /* Same as ABORT but does not have 'no-return' attribute. */ /* ABORT on a dummy condition (which is always true). */ @@ -762,8 +838,6 @@ # endif #endif /* DARWIN */ -#include "../gc_tiny_fl.h" - #include <setjmp.h> #if __STDC_VERSION__ >= 201112L @@ -845,16 +919,16 @@ /* Heap block size, bytes. Should be power of 2. */ /* Incremental GC with MPROTECT_VDB currently requires the */ /* page size to be a multiple of HBLKSIZE. Since most modern */ -/* architectures support variable page sizes down to 4K, and */ -/* X86 is generally 4K, we now default to 4K, except for */ -/* Alpha: Seems to be used with 8K pages. */ +/* architectures support variable page sizes down to 4 KB, and */ +/* X86 is generally 4 KB, we now default to 4 KB, except for */ +/* Alpha: Seems to be used with 8 KB pages. */ /* SMALL_CONFIG: Want less block-level fragmentation. */ #ifndef HBLKSIZE # if defined(LARGE_CONFIG) || !defined(SMALL_CONFIG) # ifdef ALPHA # define CPP_LOG_HBLKSIZE 13 -# elif defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PSP2) -# define CPP_LOG_HBLKSIZE 16 /* page size is set to 64K */ +# elif defined(SN_TARGET_PSP2) +# define CPP_LOG_HBLKSIZE 16 /* page size is set to 64 KB */ # else # define CPP_LOG_HBLKSIZE 12 # endif @@ -940,31 +1014,34 @@ * Used by black-listing code, and perhaps by dirty bit maintenance code. */ +#ifndef LOG_PHT_ENTRIES # ifdef LARGE_CONFIG # if CPP_WORDSZ == 32 # define LOG_PHT_ENTRIES 20 /* Collisions likely at 1M blocks, */ - /* which is >= 4GB. Each table takes */ - /* 128KB, some of which may never be */ + /* which is >= 4 GB. Each table takes */ + /* 128 KB, some of which may never be */ /* touched. */ # else # define LOG_PHT_ENTRIES 21 /* Collisions likely at 2M blocks, */ - /* which is >= 8GB. Each table takes */ - /* 256KB, some of which may never be */ + /* which is >= 8 GB. Each table takes */ + /* 256 KB, some of which may never be */ /* touched. */ # endif # elif !defined(SMALL_CONFIG) # define LOG_PHT_ENTRIES 18 /* Collisions are likely if heap grows */ - /* to more than 256K hblks >= 1GB. */ - /* Each hash table occupies 32K bytes. */ + /* to more than 256K hblks >= 1 GB. */ + /* Each hash table occupies 32 KB. */ /* Even for somewhat smaller heaps, */ /* say half that, collisions may be an */ /* issue because we blacklist */ /* addresses outside the heap. */ # else # define LOG_PHT_ENTRIES 15 /* Collisions are likely if heap grows */ - /* to more than 32K hblks = 128MB. */ - /* Each hash table occupies 4K bytes. */ + /* to more than 32K hblks (128 MB). */ + /* Each hash table occupies 4 KB. */ # endif +#endif /* !LOG_PHT_ENTRIES */ + # define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES) # define PHT_SIZE (PHT_ENTRIES >> LOGWL) typedef word page_hash_tablePHT_SIZE; @@ -1198,7 +1275,9 @@ # define RT_SIZE (1 << LOG_RT_SIZE) /* Power of 2, may be != MAX_ROOT_SETS */ #endif -#ifndef MAX_HEAP_SECTS +#if (!defined(MAX_HEAP_SECTS) || defined(CPPCHECK)) \ + && (defined(CYGWIN32) || defined(MSWIN32) || defined(MSWINCE) \ + || defined(USE_PROC_FOR_LIBRARIES)) # ifdef LARGE_CONFIG # if CPP_WORDSZ > 32 # define MAX_HEAP_SECTS 81920 @@ -1209,12 +1288,12 @@ # if defined(PARALLEL_MARK) && (defined(MSWIN32) || defined(CYGWIN32)) # define MAX_HEAP_SECTS 384 # else -# define MAX_HEAP_SECTS 128 /* Roughly 256MB (128*2048*1K) */ +# define MAX_HEAP_SECTS 128 /* Roughly 256 MB (128*2048*1024) */ # endif # elif CPP_WORDSZ > 32 -# define MAX_HEAP_SECTS 1024 /* Roughly 8GB */ +# define MAX_HEAP_SECTS 1024 /* Roughly 8 GB */ # else -# define MAX_HEAP_SECTS 512 /* Roughly 4GB */ +# define MAX_HEAP_SECTS 512 /* Roughly 4 GB */ # endif #endif /* !MAX_HEAP_SECTS */ @@ -1225,6 +1304,44 @@ /* as described in gc_mark.h. */ } mse; +typedef int mark_state_t; /* Current state of marking. */ + /* Used to remember where we are during */ + /* concurrent marking. */ + +struct disappearing_link; +struct finalizable_object; + +struct dl_hashtbl_s { + struct disappearing_link **head; + word entries; + unsigned log_size; +}; + +struct fnlz_roots_s { + struct finalizable_object **fo_head; + /* List of objects that should be finalized now: */ + struct finalizable_object *finalize_now; +}; + +union toggle_ref_u { + /* The lowest bit is used to distinguish between choices. */ + void *strong_ref; + GC_hidden_pointer weak_ref; +}; + +/* Extended descriptors. GC_typed_mark_proc understands these. */ +/* These are used for simple objects that are larger than what */ +/* can be described by a BITMAP_BITS sized bitmap. */ +typedef struct { + word ed_bitmap; /* lsb corresponds to first word. */ + GC_bool ed_continued; /* next entry is continuation. */ +} typed_ext_descr_t; + +struct HeapSect { + ptr_t hs_start; + size_t hs_bytes; +}; + /* Lists of all heap blocks and free lists */ /* as well as other random data structures */ /* that should not be scanned by the */ @@ -1248,7 +1365,6 @@ word _heapsize; /* Heap size in bytes (value never goes down). */ word _requested_heapsize; /* Heap size due to explicit expansion. */ ptr_t _last_heap_addr; - ptr_t _prev_heap_addr; word _large_free_bytes; /* Total bytes contained in blocks on large object free */ /* list. */ @@ -1264,6 +1380,8 @@ word _bytes_allocd_before_gc; /* Number of bytes allocated before this */ /* collection cycle. */ +# define GC_our_mem_bytes GC_arrays._our_mem_bytes + word _our_mem_bytes; # ifndef SEPARATE_GLOBALS # define GC_bytes_allocd GC_arrays._bytes_allocd word _bytes_allocd; @@ -1285,10 +1403,24 @@ /* Bytes of memory explicitly deallocated while */ /* finalizers were running. Used to approximate memory */ /* explicitly deallocated by finalizers. */ + bottom_index *_all_bottom_indices; + /* Pointer to the first (lowest address) bottom_index; */ + /* assumes the lock is held. */ + bottom_index *_all_bottom_indices_end; + /* Pointer to the last (highest address) bottom_index; */ + /* assumes the lock is held. */ + ptr_t _scratch_free_ptr; + hdr *_hdr_free_list; ptr_t _scratch_end_ptr; - ptr_t _scratch_last_end_ptr; - /* Used by headers.c, and can easily appear to point to */ - /* heap. Also used by GC_register_dynamic_libraries(). */ + /* GC_scratch_end_ptr is end point of the current scratch area. */ +# if defined(IRIX5) || (defined(USE_PROC_FOR_LIBRARIES) && !defined(LINUX)) +# define USE_SCRATCH_LAST_END_PTR +# define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr + ptr_t _scratch_last_end_ptr; + /* GC_scratch_last_end_ptr is the end point of the last */ + /* obtained scratch area. */ + /* Used by GC_register_dynamic_libraries(). */ +# endif mse *_mark_stack; /* Limits of stack for GC_mark routine. All ranges */ /* between GC_mark_stack (incl.) and GC_mark_stack_top */ @@ -1316,10 +1448,99 @@ # define GC_unmapped_bytes 0 # endif bottom_index * _all_nils; +# define GC_scan_ptr GC_arrays._scan_ptr + struct hblk * _scan_ptr; +# ifdef PARALLEL_MARK +# define GC_main_local_mark_stack GC_arrays._main_local_mark_stack + mse *_main_local_mark_stack; +# define GC_first_nonempty GC_arrays._first_nonempty + volatile AO_t _first_nonempty; + /* Lowest entry on mark stack that may be */ + /* nonempty. Updated only by initiating thread. */ +# endif +# define GC_mark_stack_size GC_arrays._mark_stack_size + size_t _mark_stack_size; +# define GC_mark_state GC_arrays._mark_state + mark_state_t _mark_state; /* Initialized to MS_NONE (0). */ +# define GC_mark_stack_too_small GC_arrays._mark_stack_too_small + GC_bool _mark_stack_too_small; + /* We need a larger mark stack. May be set by */ + /* client supplied mark routines. */ +# define GC_objects_are_marked GC_arrays._objects_are_marked + GC_bool _objects_are_marked; + /* Are there collectible marked objects in the heap? */ # ifdef ENABLE_TRACE # define GC_trace_addr GC_arrays._trace_addr ptr_t _trace_addr; # endif +# define GC_capacity_heap_sects GC_arrays._capacity_heap_sects + size_t _capacity_heap_sects; +# define GC_n_heap_sects GC_arrays._n_heap_sects + word _n_heap_sects; /* Number of separately added heap sections. */ +# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) +# define GC_n_heap_bases GC_arrays._n_heap_bases + word _n_heap_bases; /* See GC_heap_bases. */ +# endif +# ifdef USE_PROC_FOR_LIBRARIES +# define GC_n_memory GC_arrays._n_memory + word _n_memory; /* Number of GET_MEM allocated memory sections. */ +# endif +# ifdef GC_GCJ_SUPPORT +# define GC_gcjobjfreelist GC_arrays._gcjobjfreelist + ptr_t *_gcjobjfreelist; +# endif +# define GC_fo_entries GC_arrays._fo_entries + word _fo_entries; +# ifndef GC_NO_FINALIZATION +# define GC_dl_hashtbl GC_arrays._dl_hashtbl +# define GC_fnlz_roots GC_arrays._fnlz_roots +# define GC_log_fo_table_size GC_arrays._log_fo_table_size +# ifndef GC_LONG_REFS_NOT_NEEDED +# define GC_ll_hashtbl GC_arrays._ll_hashtbl + struct dl_hashtbl_s _ll_hashtbl; +# endif + struct dl_hashtbl_s _dl_hashtbl; + struct fnlz_roots_s _fnlz_roots; + unsigned _log_fo_table_size; +# ifndef GC_TOGGLE_REFS_NOT_NEEDED +# define GC_toggleref_arr GC_arrays._toggleref_arr +# define GC_toggleref_array_size GC_arrays._toggleref_array_size +# define GC_toggleref_array_capacity GC_arrays._toggleref_array_capacity + union toggle_ref_u *_toggleref_arr; + size_t _toggleref_array_size; + size_t _toggleref_array_capacity; +# endif +# endif +# ifdef TRACE_BUF +# define GC_trace_buf_ptr GC_arrays._trace_buf_ptr + int _trace_buf_ptr; +# endif +# ifdef ENABLE_DISCLAIM +# define GC_finalized_kind GC_arrays._finalized_kind + int _finalized_kind; +# endif +# define n_root_sets GC_arrays._n_root_sets +# define GC_excl_table_entries GC_arrays._excl_table_entries + int _n_root_sets; /* GC_static_roots0..n_root_sets) contains the */ + /* valid root sets. */ + size_t _excl_table_entries; /* Number of entries in use. */ +# ifdef THREADS +# define GC_roots_were_cleared GC_arrays._roots_were_cleared + GC_bool _roots_were_cleared; +# endif +# define GC_explicit_typing_initialized GC_arrays._explicit_typing_initialized +# define GC_ed_size GC_arrays._ed_size +# define GC_avail_descr GC_arrays._avail_descr +# define GC_ext_descriptors GC_arrays._ext_descriptors +# ifdef AO_HAVE_load_acquire + volatile AO_t _explicit_typing_initialized; +# else + GC_bool _explicit_typing_initialized; +# endif + size_t _ed_size; /* Current size of above arrays. */ + size_t _avail_descr; /* Next available slot. */ + typed_ext_descr_t *_ext_descriptors; /* Points to array of extended */ + /* descriptors. */ GC_mark_proc _mark_procsMAX_MARK_PROCS; /* Table of user-defined mark procedures. There is */ /* a small number of these, which can be referenced */ @@ -1388,15 +1609,13 @@ volatile page_hash_table _dirty_pages; /* Pages dirtied since last GC_read_dirty. */ # endif -# if (defined(CHECKSUMS) && defined(GWW_VDB)) || defined(PROC_VDB) +# if (defined(CHECKSUMS) && (defined(GWW_VDB) || defined(SOFT_VDB))) \ + || defined(PROC_VDB) # define GC_written_pages GC_arrays._written_pages page_hash_table _written_pages; /* Pages ever dirtied */ # endif # define GC_heap_sects GC_arrays._heap_sects - struct HeapSect { - ptr_t hs_start; - size_t hs_bytes; - } _heap_sectsMAX_HEAP_SECTS; /* Heap segments potentially */ + struct HeapSect *_heap_sects; /* Heap segments potentially */ /* client objects. */ # if defined(USE_PROC_FOR_LIBRARIES) # define GC_our_memory GC_arrays._our_memory @@ -1442,10 +1661,12 @@ #define GC_mark_procs GC_arrays._mark_procs #define GC_max_large_allocd_bytes GC_arrays._max_large_allocd_bytes #define GC_modws_valid_offsets GC_arrays._modws_valid_offsets -#define GC_prev_heap_addr GC_arrays._prev_heap_addr #define GC_requested_heapsize GC_arrays._requested_heapsize +#define GC_all_bottom_indices GC_arrays._all_bottom_indices +#define GC_all_bottom_indices_end GC_arrays._all_bottom_indices_end +#define GC_scratch_free_ptr GC_arrays._scratch_free_ptr +#define GC_hdr_free_list GC_arrays._hdr_free_list #define GC_scratch_end_ptr GC_arrays._scratch_end_ptr -#define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr #define GC_size_map GC_arrays._size_map #define GC_static_roots GC_arrays._static_roots #define GC_top_index GC_arrays._top_index @@ -1528,14 +1749,6 @@ GC_EXTERN unsigned GC_n_kinds; -GC_EXTERN word GC_n_heap_sects; /* Number of separately added heap */ - /* sections. */ - -#ifdef USE_PROC_FOR_LIBRARIES - GC_EXTERN word GC_n_memory; /* Number of GET_MEM allocated memory */ - /* sections. */ -#endif - GC_EXTERN size_t GC_page_size; /* Round up allocation size to a multiple of a page size. */ @@ -1551,13 +1764,6 @@ #endif #if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE - EXTERN_C_END -# include <windows.h> - EXTERN_C_BEGIN GC_EXTERN SYSTEM_INFO GC_sysinfo; GC_INNER GC_bool GC_is_heap_base(void *p); #endif @@ -1609,7 +1815,7 @@ /* NULL if no such "frame" active. */ #endif /* !THREADS */ -#ifdef IA64 +#if defined(E2K) || defined(IA64) /* Similar to GC_push_all_stack_sections() but for IA-64 registers store. */ GC_INNER void GC_push_all_register_sections(ptr_t bs_lo, ptr_t bs_hi, int eager, struct GC_traced_stack_sect_s *traced_stack_sect); @@ -1721,6 +1927,16 @@ /* As GC_push_all but consider */ /* interior pointers as valid. */ +#ifdef NO_VDB_FOR_STATIC_ROOTS +# define GC_push_conditional_static(b, t, all) \ + ((void)(all), GC_push_all(b, t)) +#else + /* Same as GC_push_conditional (does either of GC_push_all or */ + /* GC_push_selected depending on the third argument) but the caller */ + /* guarantees the region belongs to the registered static roots. */ + GC_INNER void GC_push_conditional_static(void *b, void *t, GC_bool all); +#endif + #if defined(WRAP_MARK_SOME) && defined(PARALLEL_MARK) /* GC_mark_local does not handle memory protection faults yet. So, */ /* the static data regions are scanned immediately by GC_push_roots. */ @@ -1757,16 +1973,109 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *), volatile ptr_t arg); -#if defined(SPARC) || defined(IA64) +#if defined(E2K) || defined(IA64) || defined(SPARC) /* Cause all stacked registers to be saved in memory. Return a */ /* pointer to the top of the corresponding memory stack. */ ptr_t GC_save_regs_in_stack(void); #endif - /* Push register contents onto mark stack. */ -#if defined(MSWIN32) || defined(MSWINCE) - void __cdecl GC_push_one(word p); +#ifdef E2K + /* Copy the full procedure stack to the provided buffer (with the */ + /* given capacity). Returns either the required buffer size if it */ + /* is bigger than capacity, otherwise the amount of copied bytes. */ + /* May be called from a signal handler. */ + GC_INNER size_t GC_get_procedure_stack(ptr_t, size_t); + +# if defined(CPPCHECK) +# define PS_ALLOCA_BUF(sz) NULL +# define ALLOCA_SAFE_LIMIT 0 +# else +# define PS_ALLOCA_BUF(sz) alloca(sz) /* cannot return NULL */ +# ifndef ALLOCA_SAFE_LIMIT +# define ALLOCA_SAFE_LIMIT (HBLKSIZE*256) +# endif +# endif /* !CPPCHECK */ + + /* Copy procedure (register) stack to a stack-allocated or */ + /* memory-mapped buffer. Usable from a signal handler. */ + /* FREE_PROCEDURE_STACK_LOCAL() must be called with the same */ + /* *pbuf and *psz values before the caller function returns */ + /* (thus, the buffer is valid only within the function). */ +# define GET_PROCEDURE_STACK_LOCAL(pbuf, psz) \ + do { \ + size_t capacity = 0; \ + GC_ASSERT(GC_page_size != 0); \ + for (*(pbuf) = NULL; ; capacity = *(psz)) { \ + *(psz) = GC_get_procedure_stack(*(pbuf), capacity); \ + if (*(psz) <= capacity) break; \ + if (*(psz) > ALLOCA_SAFE_LIMIT \ + || EXPECT(capacity != 0, FALSE)) { \ + /* Deallocate old buffer if any. */ \ + if (EXPECT(capacity > ALLOCA_SAFE_LIMIT, FALSE)) \ + GC_unmap_procedure_stack_buf(*(pbuf),capacity); \ + *(psz) = ROUNDUP_PAGESIZE(*(psz)); \ + *(pbuf) = GC_mmap_procedure_stack_buf(*(psz)); \ + } else { \ + /* Allocate buffer on the stack if not large. */ \ + *(pbuf) = PS_ALLOCA_BUF(*(psz)); \ + } \ + } \ + if (capacity > ALLOCA_SAFE_LIMIT \ + && EXPECT(((capacity - *(psz)) \ + & ~(GC_page_size-1)) != 0, FALSE)) { \ + /* Ensure sz value passed to munmap() later */ \ + /* matches that passed to mmap() above. */ \ + *(psz) = capacity - (GC_page_size - 1); \ + } \ + } while (0) + + /* Indicate that the buffer with copied procedure stack is not needed. */ +# define FREE_PROCEDURE_STACK_LOCAL(buf, sz) \ + (void)((sz) > ALLOCA_SAFE_LIMIT \ + ? (GC_unmap_procedure_stack_buf(buf, sz), 0) : 0) + + GC_INNER ptr_t GC_mmap_procedure_stack_buf(size_t); + GC_INNER void GC_unmap_procedure_stack_buf(ptr_t, size_t); + +# ifdef THREADS + /* Allocate a buffer in the GC heap (as an atomic object) and copy */ + /* procedure stack there. Assumes the GC allocation lock is held. */ + /* May trigger a collection (thus, cannot be used in GC_push_roots */ + /* or in a signal handler). The buffer should be freed with */ + /* GC_INTERNAL_FREE later when not needed (or, alternatively, it */ + /* could be just garbage-collected). */ + /* Similar to GET_PROCEDURE_STACK_LOCAL in other aspects. */ + GC_INNER size_t GC_alloc_and_get_procedure_stack(ptr_t *pbuf); +# endif + + /* Load value and get tag of the target memory. */ +# if defined(__ptr64__) +# define LOAD_TAGGED_VALUE(v, tag, p) \ + do { \ + word val; \ + __asm__ __volatile__ ( \ + "ldd, sm %adr, 0x0, %val\n\t" \ + "gettagd %val, %tag\n" \ + : val "=r" (val), \ + tag "=r" (tag) \ + : adr "r" (p)); \ + v = val; \ + } while (0) +# elif !defined(CPPCHECK) +# error Unsupported -march for e2k target +# endif + +# define LOAD_WORD_OR_CONTINUE(v, p) \ + { \ + int tag LOCAL_VAR_INIT_OK; \ + LOAD_TAGGED_VALUE(v, tag, p); \ + if (tag != 0) continue; \ + } #else +# define LOAD_WORD_OR_CONTINUE(v, p) (void)(v = *(word *)(p)) +#endif /* !E2K */ + +#if defined(AMIGA) || defined(MACOS) || defined(GC_DARWIN_THREADS) void GC_push_one(word p); /* If p points to an object, mark it */ /* and push contents on the mark stack */ @@ -1776,6 +2085,11 @@ /* stack. */ #endif +#ifdef GC_WIN32_THREADS + /* Same as GC_push_one but for a sequence of registers. */ + GC_INNER void GC_push_many_regs(const word *regs, unsigned count); +#endif + #if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) GC_INNER void GC_mark_and_push_stack(ptr_t p, ptr_t source); /* Ditto, omits plausibility test */ @@ -1917,8 +2231,8 @@ GC_INNER ptr_t GC_alloc_large(size_t lb, int k, unsigned flags); /* Allocate a large block of size lb bytes. */ - /* The block is not cleared. */ - /* Flags is 0 or IGNORE_OFF_PAGE. */ + /* The block is not cleared. flags argument */ + /* should be 0 or IGNORE_OFF_PAGE. */ /* Calls GC_allchblk to do the actual */ /* allocation, but also triggers GC and/or */ /* heap expansion as appropriate. */ @@ -1929,7 +2243,7 @@ /* Deallocate a heap block and mark it */ /* as invalid. */ -/* Misc GC: */ +/* Miscellaneous GC routines. */ GC_INNER GC_bool GC_expand_hp_inner(word n); GC_INNER void GC_start_reclaim(GC_bool abort_if_found); /* Restore unmarked objects to free */ @@ -2046,15 +2360,12 @@ /* Remove forwarding counts for h. */ GC_INNER hdr * GC_find_header(ptr_t h); -GC_INNER void GC_add_to_heap(struct hblk *p, size_t bytes); - /* Add a HBLKSIZE aligned chunk to the heap. */ - #ifdef USE_PROC_FOR_LIBRARIES GC_INNER void GC_add_to_our_memory(ptr_t p, size_t bytes); /* Add a chunk to GC_our_memory. */ - /* If p == 0, do nothing. */ #else -# define GC_add_to_our_memory(p, bytes) +# define GC_add_to_our_memory(p, bytes) \ + (GC_our_mem_bytes += (bytes), (void)(p)) #endif GC_INNER void GC_print_all_errors(void); @@ -2086,10 +2397,20 @@ GC_INNER GC_bool GC_check_leaked(ptr_t base); /* from dbg_mlc.c */ #endif -GC_EXTERN GC_bool GC_have_errors; /* We saw a smashed or leaked object. */ - /* Call error printing routine */ - /* occasionally. It is OK to read it */ - /* without acquiring the lock. */ +#ifdef AO_HAVE_store + GC_EXTERN volatile AO_t GC_have_errors; +# define GC_SET_HAVE_ERRORS() AO_store(&GC_have_errors, (AO_t)TRUE) +# define get_have_errors() ((GC_bool)AO_load(&GC_have_errors)) + /* The barriers are not needed. */ +#else + GC_EXTERN GC_bool GC_have_errors; +# define GC_SET_HAVE_ERRORS() (void)(GC_have_errors = TRUE) +# define get_have_errors() GC_have_errors +#endif /* We saw a smashed or leaked object. */ + /* Call error printing routine */ + /* occasionally. It is OK to read it */ + /* without acquiring the lock. */ + /* If set to true, it is never cleared. */ #define VERBOSE 2 #if !defined(NO_CLOCK) || !defined(SMALL_CONFIG) @@ -2104,7 +2425,6 @@ #ifdef KEEP_BACK_PTRS GC_EXTERN long GC_backtraces; - GC_INNER void GC_generate_random_backtrace_no_gc(void); #endif #ifdef LINT2 @@ -2214,8 +2534,13 @@ /* pointer-free system call buffers in the heap are */ /* not protected. */ +# if !defined(NO_VDB_FOR_STATIC_ROOTS) && !defined(PROC_VDB) + GC_INNER GC_bool GC_is_vdb_for_static_roots(void); + /* Is VDB working for static roots? */ +# endif + # ifdef CAN_HANDLE_FORK -# if defined(PROC_VDB) +# if defined(PROC_VDB) || defined(SOFT_VDB) GC_INNER void GC_dirty_update_child(void); /* Update pid-specific resources (like /proc file */ /* descriptors) needed by the dirty bits implementation */ @@ -2251,8 +2576,6 @@ void GC_print_heap_sects(void); void GC_print_static_roots(void); -extern word GC_fo_entries; /* should be visible in extra/MacOS.c */ - #ifdef KEEP_BACK_PTRS GC_INNER void GC_store_back_pointer(ptr_t source, ptr_t dest); GC_INNER void GC_marked_for_finalization(ptr_t dest); @@ -2284,7 +2607,7 @@ GC_API_PRIV void GC_printf(const char * format, ...) GC_ATTR_FORMAT_PRINTF(1, 2); /* A version of printf that doesn't allocate, */ - /* 1K total output length. */ + /* 1 KB total output length. */ /* (We use sprintf. Hopefully that doesn't */ /* allocate for long arguments.) */ GC_API_PRIV void GC_err_printf(const char * format, ...) @@ -2313,6 +2636,12 @@ GC_ATTR_FORMAT_PRINTF(1, 2); #endif /* GC_ANDROID_LOG */ +#if defined(SMALL_CONFIG) || defined(GC_ANDROID_LOG) +# define GC_ERRINFO_PRINTF GC_INFOLOG_PRINTF +#else +# define GC_ERRINFO_PRINTF GC_log_printf +#endif + /* Convenient macros for GC_verbose_log_printf invocation. */ #define GC_COND_LOG_PRINTF \ if (EXPECT(!GC_print_stats, TRUE)) {} else GC_log_printf @@ -2358,15 +2687,15 @@ #endif #ifdef THREADS -# if defined(MSWIN32) || defined(MSWINCE) || defined(MSWIN_XBOX1) +# if (defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE) GC_EXTERN CRITICAL_SECTION GC_write_cs; /* defined in misc.c */ -# endif -# if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE)) - GC_EXTERN GC_bool GC_write_disabled; +# ifdef GC_ASSERTIONS + GC_EXTERN GC_bool GC_write_disabled; /* defined in win32_threads.c; */ /* protected by GC_write_cs. */ -# endif +# endif +# endif /* MSWIN32 || MSWINCE */ # if defined(GC_DISABLE_INCREMENTAL) || defined(HAVE_LOCKFREE_AO_OR) # define GC_acquire_dirty_lock() (void)0 # define GC_release_dirty_lock() (void)0 @@ -2395,24 +2724,16 @@ GC_INNER void GC_mark_thread_local_free_lists(void); #endif -#ifdef GC_GCJ_SUPPORT -# ifdef GC_ASSERTIONS - GC_EXTERN GC_bool GC_gcj_malloc_initialized; /* defined in gcj_mlc.c */ -# endif - GC_EXTERN ptr_t * GC_gcjobjfreelist; +#if defined(GLIBC_2_19_TSX_BUG) && defined(THREADS) + /* Parse string like <major>.<minor><tail> and return major value. */ + GC_INNER int GC_parse_version(int *pminor, const char *pverstr); #endif -#ifdef MPROTECT_VDB -# ifdef GWW_VDB +#if defined(MPROTECT_VDB) && defined(GWW_VDB) GC_INNER GC_bool GC_gww_dirty_init(void); /* Returns TRUE if GetWriteWatch is available. */ /* May be called repeatedly. */ -# endif -# ifdef USE_MUNMAP - GC_INNER GC_bool GC_mprotect_dirty_init(void); - GC_INNER GC_bool GC_has_unmapped_memory(void); -# endif -#endif /* MPROTECT_VDB */ +#endif #if defined(CHECKSUMS) || defined(PROC_VDB) GC_INNER GC_bool GC_page_was_ever_dirty(struct hblk * h); @@ -2480,14 +2801,17 @@ #endif /* GC_WIN32_THREADS */ #ifdef THREADS - GC_INNER void GC_reset_finalizer_nested(void); - GC_INNER unsigned char *GC_check_finalizer_nested(void); +# ifndef GC_NO_FINALIZATION + GC_INNER void GC_reset_finalizer_nested(void); + GC_INNER unsigned char *GC_check_finalizer_nested(void); +# endif GC_INNER void GC_do_blocking_inner(ptr_t data, void * context); GC_INNER void GC_push_all_stacks(void); # ifdef USE_PROC_FOR_LIBRARIES GC_INNER GC_bool GC_segment_is_thread_stack(ptr_t lo, ptr_t hi); # endif -# ifdef IA64 +# if (defined(HAVE_PTHREAD_ATTR_GET_NP) || defined(HAVE_PTHREAD_GETATTR_NP)) \ + && defined(IA64) GC_INNER ptr_t GC_greatest_stack_base_below(ptr_t bound); # endif #endif /* THREADS */ @@ -2515,15 +2839,17 @@ #ifdef NEED_PROC_MAPS # if defined(DYNAMIC_LOADING) && defined(USE_PROC_FOR_LIBRARIES) - GC_INNER char *GC_parse_map_entry(char *buf_ptr, ptr_t *start, ptr_t *end, - char **prot, unsigned int *maj_dev, - char **mapping_name); + GC_INNER const char *GC_parse_map_entry(const char *maps_ptr, + ptr_t *start, ptr_t *end, + const char **prot, + unsigned *maj_dev, + const char **mapping_name); # endif # if defined(IA64) || defined(INCLUDE_LINUX_THREAD_DESCR) GC_INNER GC_bool GC_enclosing_mapping(ptr_t addr, ptr_t *startp, ptr_t *endp); # endif - GC_INNER char *GC_get_maps(void); /* from os_dep.c */ + GC_INNER const char *GC_get_maps(void); #endif /* NEED_PROC_MAPS */ #ifdef GC_ASSERTIONS @@ -2591,6 +2917,9 @@ /* Number of mark threads we would like to have */ /* excluding the initiating thread. */ + GC_EXTERN GC_bool GC_parallel_mark_disabled; + /* A flag to temporarily avoid parallel marking.*/ + /* The mark lock and condition variable. If the GC lock is also */ /* acquired, the GC lock must be acquired first. The mark lock is */ /* used to both protect some variables used by the parallel */ @@ -2631,8 +2960,16 @@ /* unfortunately, there is no standard mechanism. (There is one */ /* in Linux glibc, but it's not exported.) Thus we continue to use */ /* the same hard-coded signals we've always used. */ -# if (defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)) \ - && !defined(GC_USESIGRT_SIGNALS) +# ifdef THREAD_SANITIZER + /* Unfortunately, use of an asynchronous signal to suspend threads */ + /* leads to the situation when the signal is not delivered (is */ + /* stored to pending_signals in TSan runtime actually) while the */ + /* destination thread is blocked in pthread_mutex_lock. Thus, we */ + /* use some synchronous one instead (which is again unlikely to be */ + /* used by clients directly). */ +# define SIG_SUSPEND SIGSYS +# elif (defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)) \ + && !defined(GC_USESIGRT_SIGNALS) # 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. */ @@ -2641,7 +2978,14 @@ /* Linuxthreads itself uses SIGUSR1 and SIGUSR2. */ # define SIG_SUSPEND SIGPWR # endif -# elif defined(GC_OPENBSD_THREADS) +# elif defined(GC_FREEBSD_THREADS) && defined(__GLIBC__) \ + && !defined(GC_USESIGRT_SIGNALS) +# define SIG_SUSPEND (32+6) +# elif (defined(GC_FREEBSD_THREADS) || defined(HURD) || defined(RTEMS)) \ + && !defined(GC_USESIGRT_SIGNALS) +# define SIG_SUSPEND SIGUSR1 + /* SIGTSTP and SIGCONT could be used alternatively on FreeBSD. */ +# elif defined(GC_OPENBSD_THREADS) && !defined(GC_USESIGRT_SIGNALS) # ifndef GC_OPENBSD_UTHREADS # define SIG_SUSPEND SIGXFSZ # endif @@ -2701,9 +3045,10 @@ # define DATASTART_IS_FUNC #endif /* DATASTART_USES_BSDGETDATASTART */ -#if (defined(NETBSD) || defined(OPENBSD)) && defined(__ELF__) \ +#if ((defined(NETBSD) && defined(__ELF__)) \ + || (defined(OPENBSD) && !defined(GC_OPENBSD_UTHREADS))) \ && !defined(NEED_FIND_LIMIT) - /* Used by GC_init_netbsd_elf() in os_dep.c. */ + /* Used by GC_init_netbsd_elf or GC_register_data_segments in os_dep.c. */ # define NEED_FIND_LIMIT #endif
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/gcconfig.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/gcconfig.h
Changed
@@ -3,6 +3,7 @@ * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 2000-2004 Hewlett-Packard Development Company, L.P. + * Copyright (c) 2009-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -109,19 +110,6 @@ # define LINUX # endif -/* And one for QNX: */ -# if defined(__QNX__) -# define I386 -# define OS_TYPE "QNX" -# define SA_RESTART 0 -# define HEURISTIC1 - extern char etext; - extern int _end; -# define DATASTART ((ptr_t)(etext)) -# define DATAEND ((ptr_t)(_end)) -# define mach_type_known -# endif - /* And one for NetBSD: */ # if defined(__NetBSD__) # define NETBSD @@ -135,7 +123,7 @@ /* And one for FreeBSD: */ # if (defined(__FreeBSD__) || defined(__DragonFly__) \ || defined(__FreeBSD_kernel__)) && !defined(FREEBSD) \ - && !defined(SN_TARGET_ORBIS) /* Orbis compiler defines __FreeBSD__ */ + && !defined(GC_NO_FREEBSD) /* Orbis compiler defines __FreeBSD__ */ # define FREEBSD # endif @@ -161,7 +149,7 @@ # define AARCH64 # if !defined(LINUX) && !defined(DARWIN) && !defined(FREEBSD) \ && !defined(NETBSD) && !defined(NN_BUILD_TARGET_PLATFORM_NX) \ - && !defined(OPENBSD) + && !defined(OPENBSD) && !defined(_WIN32) # define NOSYS # define mach_type_known # endif @@ -173,7 +161,7 @@ # elif !defined(LINUX) && !defined(NETBSD) && !defined(FREEBSD) \ && !defined(OPENBSD) && !defined(DARWIN) && !defined(_WIN32) \ && !defined(__CEGCC__) && !defined(NN_PLATFORM_CTR) \ - && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) \ + && !defined(GC_NO_NOSYS) && !defined(SN_TARGET_PSP2) \ && !defined(SYMBIAN) # define NOSYS # define mach_type_known @@ -234,7 +222,7 @@ # endif # define mach_type_known # endif -# if defined(__NetBSD__) && defined(__vax__) +# if defined(NETBSD) && defined(__vax__) # define VAX # define mach_type_known # endif @@ -251,11 +239,15 @@ # define IRIX5 /* or IRIX 6.X */ # endif # endif /* !LINUX */ -# if defined(__NetBSD__) && defined(__MIPSEL__) +# if defined(NETBSD) && defined(__MIPSEL__) # undef ULTRIX # endif # define mach_type_known # endif +# if defined(__QNX__) +# define I386 +# define mach_type_known +# endif # if defined(__NIOS2__) || defined(__NIOS2) || defined(__nios2__) # define NIOS2 /* Altera NIOS2 */ # define mach_type_known @@ -267,7 +259,7 @@ # if defined(DGUX) && (defined(i386) || defined(__i386__)) # define I386 # ifndef _USING_DGUX -# define _USING_DGUX +# define _USING_DGUX # endif # define mach_type_known # endif @@ -303,8 +295,7 @@ # define SOLARIS # define mach_type_known # elif defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \ - && !defined(__OpenBSD__) && !defined(__NetBSD__) \ - && !defined(__FreeBSD__) && !defined(__DragonFly__) + && !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD) # define SPARC # define DRSNX # define mach_type_known @@ -314,7 +305,7 @@ # define AIX # define mach_type_known # endif -# if defined(__NetBSD__) && defined(__sparc__) +# if defined(NETBSD) && defined(__sparc__) # define SPARC # define mach_type_known # endif @@ -372,6 +363,10 @@ # define IA64 # define mach_type_known # endif +# if defined(LINUX) && defined(__e2k__) +# define E2K +# define mach_type_known +# endif # if defined(LINUX) && defined(__aarch64__) # define AARCH64 # define mach_type_known @@ -386,6 +381,10 @@ # endif # define mach_type_known # endif +# if defined(LINUX) && defined(__loongarch__) +# define LOONGARCH +# define mach_type_known +# endif # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__) \ || defined(powerpc64) || defined(__powerpc64__)) # define POWERPC @@ -438,9 +437,8 @@ # define MACOS # define mach_type_known # endif -# if defined(__OpenBSD__) && defined(__powerpc__) +# if defined(OPENBSD) && defined(__powerpc__) # define POWERPC -# define OPENBSD # define mach_type_known # endif # if defined(DARWIN) @@ -476,16 +474,15 @@ # define NEXT # define mach_type_known # endif -# if defined(__OpenBSD__) && (defined(i386) || defined(__i386__)) +# if defined(OPENBSD) && (defined(i386) || defined(__i386__)) # define I386 -# define OPENBSD # define mach_type_known # endif -# if defined(__NetBSD__) && (defined(i386) || defined(__i386__)) +# if defined(NETBSD) && (defined(i386) || defined(__i386__)) # define I386 # define mach_type_known # endif -# if defined(__NetBSD__) && defined(__x86_64__) +# if defined(NETBSD) && defined(__x86_64__) # define X86_64 # define mach_type_known # endif @@ -493,8 +490,7 @@ # define I386 # define mach_type_known # endif -# if (defined(FREEBSD) || defined(SN_TARGET_ORBIS)) \ - && (defined(__amd64__) || defined(__x86_64__)) +# if defined(FREEBSD) && (defined(__amd64__) || defined(__x86_64__)) # define X86_64 # define mach_type_known # endif @@ -663,6 +659,10 @@ # define NONSTOP # define mach_type_known # endif +# if defined(__arc__) && defined(LINUX) +# define ARC +# define mach_type_known +# endif # if defined(__hexagon__) && defined(LINUX) # define HEXAGON # define mach_type_known @@ -675,7 +675,8 @@ # endif # define mach_type_known # endif -# if defined(__riscv) && defined(LINUX) +# if defined(__riscv) && (defined(FREEBSD) || defined(LINUX) \ + || defined(OPENBSD)) # define RISCV # define mach_type_known # endif @@ -698,6 +699,7 @@ # endif # if defined(__EMSCRIPTEN__) +# define EMSCRIPTEN # define I386 # define mach_type_known # endif @@ -728,9 +730,11 @@ /* HP_PA ==> HP9000/700 & /800 */ /* HP/UX, LINUX */ /* SPARC ==> SPARC v7/v8/v9 */ - /* (SOLARIS, LINUX, DRSNX variants) */ + /* (SOLARIS, LINUX, DRSNX variants) */ /* ALPHA ==> DEC Alpha */ /* (OSF1 and LINUX variants) */ + /* LOONGARCH ==> Loongson LoongArch */ + /* (LINUX 32- and 64-bit variants) */ /* M88K ==> Motorola 88XX0 */ /* (CX_UX and DGUX) */ /* S370 ==> 370-like machine */ @@ -739,7 +743,10 @@ /* running LINUX */ /* AARCH64 ==> ARM AArch64 */ /* (LP64 and ILP32 variants) */ + /* E2K ==> Elbrus 2000 */ + /* running LINUX */ /* ARM32 ==> Intel StrongARM */ + /* (many variants) */ /* IA64 ==> Intel IPF */ /* (e.g. Itanium) */ /* (LINUX and HPUX) */ @@ -751,9 +758,14 @@ /* LINUX, NETBSD, AIX, NOSYS */ /* variants) */ /* Handles 32 and 64-bit variants. */ + /* ARC ==> Synopsys ARC */ + /* AVR32 ==> Atmel RISC 32-bit */ /* CRIS ==> Axis Etrax */ /* M32R ==> Renesas M32R */ + /* NIOS2 ==> Altera NIOS2 */ /* HEXAGON ==> Qualcomm Hexagon */ + /* OR1K ==> OpenRISC/or1k */ + /* RISCV ==> RISC-V 32/64-bit */ /* TILEPRO ==> Tilera TILEPro */ /* TILEGX ==> Tilera TILE-Gx */ @@ -791,7 +803,7 @@ * cause failures on alpha*-*-* with -msmall-data or -fpic or mips-*-* * without any special options. * - * STACKBOTTOM is the cool end of the stack, which is usually the + * STACKBOTTOM is the cold end of the stack, which is usually the * highest address in the stack. * Under PCR or OS/2, we have other ways of finding thread stacks. * For each machine, the following should: @@ -801,8 +813,8 @@ * LINUX_STACKBOTTOM * HEURISTIC1 * HEURISTIC2 - * If STACKBOTTOM is defined, then its value will be used directly as the - * stack base. If LINUX_STACKBOTTOM is defined, then it will be determined + * If STACKBOTTOM is defined, then its value will be used directly (as the + * stack bottom). If LINUX_STACKBOTTOM is defined, then it will be determined * with a method appropriate for most Linux systems. Currently we look * first for __libc_stack_end (currently only if USE_LIBC_PRIVATES is * defined), and if that fails read it from /proc. (If USE_LIBC_PRIVATES @@ -857,9 +869,10 @@ * * Each architecture may also define the style of virtual dirty bit * implementation to be used: - * MPROTECT_VDB: Write protect the heap and catch faults. * GWW_VDB: Use win32 GetWriteWatch primitive. + * MPROTECT_VDB: Write protect the heap and catch faults. * PROC_VDB: Use the SVR4 /proc primitives to read dirty bits. + * SOFT_VDB: Use the Linux /proc primitives to track dirty bits. * * The first and second one may be combined, in which case a runtime * selection will be made, based on GetWriteWatch availability. @@ -883,16 +896,213 @@ /* If available, we can use __builtin_unwind_init() to push the */ /* relevant registers onto the stack. */ # if GC_GNUC_PREREQ(2, 8) \ + && !GC_GNUC_PREREQ(11, 0) /* broken at least in 11.2.0 on cygwin64 */ \ && !defined(__INTEL_COMPILER) && !defined(__PATHCC__) \ && !defined(__FUJITSU) /* for FX10 system */ \ && !(defined(POWERPC) && defined(DARWIN)) /* for MacOS X 10.3.9 */ \ - && !defined(RTEMS) \ + && !defined(E2K) && !defined(RTEMS) \ && !defined(__ARMCC_VERSION) /* does not exist in armcc gnu emu */ \ && (!defined(__clang__) \ - || (GC_CLANG_PREREQ(8, 0) && defined(HOST_ANDROID))) + || GC_CLANG_PREREQ(8, 0) /* was no-op in clang-3 at least */) # define HAVE_BUILTIN_UNWIND_INIT # endif +/* The common OS-specific definitions (should be applicable to */ +/* all (or most, at least) supported architectures). */ + +# ifdef CYGWIN32 +# define OS_TYPE "CYGWIN32" +# define RETRY_GET_THREAD_CONTEXT +# ifdef USE_WINALLOC +# define GWW_VDB +# elif defined(USE_MMAP) +# define USE_MMAP_ANON +# endif +# endif /* CYGWIN32 */ + +# ifdef DARWIN +# define OS_TYPE "DARWIN" +# define DYNAMIC_LOADING + /* TODO: see get_end(3), get_etext() and get_end() should not be used. */ + /* These aren't used when dyld support is enabled (it is by default). */ +# define DATASTART ((ptr_t)get_etext()) +# define DATAEND ((ptr_t)get_end()) +# define USE_MMAP_ANON + EXTERN_C_END +# include <unistd.h> + EXTERN_C_BEGIN +# define GETPAGESIZE() (unsigned)getpagesize() + /* There seems to be some issues with trylock hanging on darwin. */ + /* TODO: This should be looked into some more. */ +# define NO_PTHREAD_TRYLOCK +# endif /* DARWIN */ + +# ifdef FREEBSD +# define OS_TYPE "FREEBSD" +# define FREEBSD_STACKBOTTOM +# ifdef __ELF__ +# define DYNAMIC_LOADING +# endif +# if !defined(ALPHA) && !defined(SPARC) + extern char etext; +# define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) +# define DATASTART_USES_BSDGETDATASTART +# ifndef GC_FREEBSD_THREADS +# define MPROTECT_VDB +# endif +# endif +# endif /* FREEBSD */ + +# ifdef HAIKU +# define OS_TYPE "HAIKU" +# define DYNAMIC_LOADING +# define MPROTECT_VDB + EXTERN_C_END +# include <OS.h> + EXTERN_C_BEGIN +# define GETPAGESIZE() (unsigned)B_PAGE_SIZE +# endif /* HAIKU */ + +# ifdef HPUX +# define OS_TYPE "HPUX" + extern int __data_start; +# define DATASTART ((ptr_t)(__data_start)) +# ifdef USE_MMAP +# define USE_MMAP_ANON +# endif +# define DYNAMIC_LOADING + EXTERN_C_END +# include <unistd.h> + EXTERN_C_BEGIN +# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE) +# endif /* HPUX */ + +# ifdef LINUX +# define OS_TYPE "LINUX" + EXTERN_C_END +# include <features.h> /* for __GLIBC__ */ + EXTERN_C_BEGIN +# if defined(FORCE_MPROTECT_BEFORE_MADVISE) \ + || defined(PREFER_MMAP_PROT_NONE) +# define COUNT_UNMAPPED_REGIONS +# endif +# define RETRY_TKILL_ON_EAGAIN +# if !defined(MIPS) && !defined(POWERPC) +# define LINUX_STACKBOTTOM +# endif +# if defined(__ELF__) && !defined(IA64) +# define DYNAMIC_LOADING +# endif +# if defined(__ELF__) && !defined(ARC) && !defined(RISCV) \ + && !defined(S390) && !defined(TILEGX) && !defined(TILEPRO) + extern int _end; +# define DATAEND ((ptr_t)(_end)) +# endif +# endif /* LINUX */ + +# ifdef MACOS +# define OS_TYPE "MACOS" +# ifndef __LOWMEM__ + EXTERN_C_END +# include <LowMem.h> + EXTERN_C_BEGIN +# endif + /* See os_dep.c for details of global data segments. */ +# define STACKBOTTOM ((ptr_t)LMGetCurStackBase()) +# define DATAEND /* not needed */ +# endif /* MACOS */ + +# ifdef MSWIN32 +# define OS_TYPE "MSWIN32" + /* STACKBOTTOM and DATASTART are handled specially in os_dep.c. */ +# define DATAEND /* not needed */ +# define GWW_VDB +# endif + +# ifdef MSWINCE +# define OS_TYPE "MSWINCE" +# define DATAEND /* not needed */ +# endif + +# ifdef NETBSD +# define OS_TYPE "NETBSD" +# define HEURISTIC2 +# ifdef __ELF__ + extern ptr_t GC_data_start; +# define DATASTART GC_data_start +# define DYNAMIC_LOADING +# elif !defined(MIPS) /* TODO: probably do not exclude it */ + extern char etext; +# define DATASTART ((ptr_t)(etext)) +# endif +# endif /* NETBSD */ + +# ifdef NEXT +# define OS_TYPE "NEXT" +# define DATASTART ((ptr_t)get_etext()) +# define DATASTART_IS_FUNC +# define DATAEND /* not needed */ +# endif + +# ifdef OPENBSD +# define OS_TYPE "OPENBSD" +# if !defined(M68K) /* TODO: probably do not exclude it */ +# ifndef GC_OPENBSD_THREADS +# define HEURISTIC2 +# endif + extern int __data_start; +# define DATASTART ((ptr_t)__data_start) + extern int _end; +# define DATAEND ((ptr_t)(&_end)) +# define DYNAMIC_LOADING +# endif +# endif /* OPENBSD */ + +# ifdef SOLARIS +# define OS_TYPE "SOLARIS" + extern int _etext, _end; + ptr_t GC_SysVGetDataStart(size_t, ptr_t); +# define DATASTART_IS_FUNC +# define DATAEND ((ptr_t)(_end)) +# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) +# define USE_MMAP 1 + /* 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 +# else +# define HEAP_START DATAEND +# endif +# ifndef GC_THREADS +# define MPROTECT_VDB +# endif +# define DYNAMIC_LOADING + /* Define STACKBOTTOM as (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. */ + /* HEURISTIC1 reportedly no longer works under Solaris 2.7. */ + /* HEURISTIC2 probably works, but this appears to be preferable.*/ + /* Apparently USRSTACK is defined to be USERLIMIT, but in some */ + /* installations that's undefined. We work around this with a */ + /* gross hack: */ + EXTERN_C_END +# include <sys/vmparam.h> +# include <unistd.h> + EXTERN_C_BEGIN +# ifdef USERLIMIT + /* This should work everywhere, but doesn't. */ +# define STACKBOTTOM ((ptr_t)USRSTACK) +# else +# define HEURISTIC2 +# endif +# endif /* SOLARIS */ + +# define STACK_GRAN 0x1000000 + # ifdef SYMBIAN # define MACH_TYPE "SYMBIAN" # define OS_TYPE "SYMBIAN" @@ -902,28 +1112,10 @@ # define DATAEND (ptr_t)ALIGNMENT # endif -# ifdef __EMSCRIPTEN__ -# define OS_TYPE "EMSCRIPTEN" -# define CPP_WORDSZ 32 -# define ALIGNMENT 4 -# define DATASTART (ptr_t)ALIGNMENT -# define DATAEND (ptr_t)ALIGNMENT - /* Since JavaScript/asm.js/WebAssembly is not able to access the */ - /* function call stack or the local data stack, it is not possible */ - /* for GC to perform its stack walking operation to find roots on */ - /* the stack. To work around that, the clients generally only do */ - /* BDWGC steps when the stack is empty so it is known that there */ - /* are no objects that would be found on the stack, and BDWGC is */ - /* compiled with stack walking disabled. */ -# define STACK_NOT_SCANNED -# endif - -# define STACK_GRAN 0x1000000 # ifdef M68K # define MACH_TYPE "M68K" # define ALIGNMENT 2 # ifdef OPENBSD -# define OS_TYPE "OPENBSD" # define HEURISTIC2 # ifdef __ELF__ extern ptr_t GC_data_start; @@ -935,29 +1127,13 @@ # endif # endif # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 -# ifdef __ELF__ - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define DYNAMIC_LOADING -# else - extern char etext; -# define DATASTART ((ptr_t)(etext)) -# endif + /* Nothing specific. */ # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS # if !defined(REDIRECT_MALLOC) # define MPROTECT_VDB # endif # ifdef __ELF__ -# define DYNAMIC_LOADING - EXTERN_C_END -# include <features.h> - EXTERN_C_BEGIN # if defined(__GLIBC__) && __GLIBC__ >= 2 # define SEARCH_FOR_DATA_START # else /* !GLIBC2 */ @@ -972,8 +1148,6 @@ /* contain large read-only data tables */ /* that we'd rather not scan. */ # endif /* !GLIBC2 */ - extern int _end; -# define DATAEND ((ptr_t)(_end)) # else extern int etext; # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff)) @@ -987,39 +1161,17 @@ # define GETPAGESIZE() 4096 # endif # ifdef MACOS -# ifndef __LOWMEM__ - EXTERN_C_END -# include <LowMem.h> - EXTERN_C_BEGIN -# endif -# define OS_TYPE "MACOS" - /* see os_dep.c for details of global data segments. */ -# define STACKBOTTOM ((ptr_t)LMGetCurStackBase()) -# define DATAEND /* not needed */ # define GETPAGESIZE() 4096 # endif # ifdef NEXT -# define OS_TYPE "NEXT" -# define DATASTART ((ptr_t)get_etext()) -# define DATASTART_IS_FUNC -# define STACKBOTTOM ((ptr_t)0x4000000) -# define DATAEND /* not needed */ +# define STACKBOTTOM ((ptr_t)0x4000000) # endif # endif -# if defined(POWERPC) +# ifdef POWERPC # define MACH_TYPE "POWERPC" # ifdef MACOS # define ALIGNMENT 2 /* Still necessary? Could it be 4? */ -# ifndef __LOWMEM__ - EXTERN_C_END -# include <LowMem.h> - EXTERN_C_BEGIN -# endif -# define OS_TYPE "MACOS" - /* see os_dep.c for details of global data segments. */ -# define STACKBOTTOM ((ptr_t)LMGetCurStackBase()) -# define DATAEND /* not needed */ # endif # ifdef LINUX # if defined(__powerpc64__) @@ -1031,7 +1183,6 @@ # else # define ALIGNMENT 4 # endif -# define OS_TYPE "LINUX" /* HEURISTIC1 has been reliably reported to fail for a 32-bit */ /* executable on a 64 bit kernel. */ # if defined(__bg__) @@ -1042,15 +1193,15 @@ # else # define LINUX_STACKBOTTOM # endif -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING # define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(_end)) +# if !defined(REDIRECT_MALLOC) +# define MPROTECT_VDB +# endif +# ifndef SOFT_VDB +# define SOFT_VDB +# endif # endif # ifdef DARWIN -# define OS_TYPE "DARWIN" -# define DYNAMIC_LOADING # if defined(__ppc64__) # define ALIGNMENT 8 # define CPP_WORDSZ 64 @@ -1063,16 +1214,7 @@ # define ALIGNMENT 4 # define STACKBOTTOM ((ptr_t)0xc0000000) # endif - /* XXX: see get_end(3), get_etext() and get_end() should not be used. */ - /* These aren't used when dyld support is enabled (it is by default). */ -# define DATASTART ((ptr_t)get_etext()) -# define DATAEND ((ptr_t)get_end()) -# define USE_MMAP_ANON # define MPROTECT_VDB - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)getpagesize() # if defined(USE_PPC_PREFETCH) && defined(__GNUC__) /* The performance impact of prefetches is untested */ # define PREFETCH(x) \ @@ -1080,21 +1222,14 @@ # define GC_PREFETCH_FOR_WRITE(x) \ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x))) # endif - /* There seems to be some issues with trylock hanging on darwin. */ - /* This should be looked into some more. */ -# define NO_PTHREAD_TRYLOCK # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# define ALIGNMENT 4 -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 +# if defined(__powerpc64__) +# define ALIGNMENT 8 +# define CPP_WORDSZ 64 +# else +# define ALIGNMENT 4 # endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING # endif # ifdef FREEBSD # if defined(__powerpc64__) @@ -1106,29 +1241,12 @@ # else # define ALIGNMENT 4 # endif -# define OS_TYPE "FREEBSD" -# 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 GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) -# define DATASTART_USES_BSDGETDATASTART # endif # ifdef NETBSD # define ALIGNMENT 4 -# define OS_TYPE "NETBSD" -# define HEURISTIC2 - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define DYNAMIC_LOADING # endif # ifdef SN_TARGET_PS3 +# define OS_TYPE "SN_TARGET_PS3" # define NO_GETENV # define CPP_WORDSZ 32 # define ALIGNMENT 4 @@ -1171,10 +1289,9 @@ # define DYNAMIC_LOADING /* For really old versions of AIX, this may have to be removed. */ # endif - # ifdef NOSYS -# define ALIGNMENT 4 # define OS_TYPE "NOSYS" +# define ALIGNMENT 4 extern void __end, __dso_handle; # define DATASTART ((ptr_t)__dso_handle) /* OK, that's ugly. */ # define DATAEND ((ptr_t)(__end)) @@ -1231,45 +1348,11 @@ /* Don't define USE_ASM_PUSH_REGS. We do use an asm helper, but */ /* not to push the registers on the mark stack. */ # ifdef SOLARIS -# define OS_TYPE "SOLARIS" - extern int _etext; - extern int _end; - ptr_t GC_SysVGetDataStart(size_t, ptr_t); # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext) -# define DATASTART_IS_FUNC -# define DATAEND ((ptr_t)(_end)) -# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) -# define USE_MMAP 1 - /* 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 -# else -# define HEAP_START DATAEND -# endif # define PROC_VDB - /* HEURISTIC1 reportedly no longer works under 2.7. */ - /* HEURISTIC2 probably works, but this appears to be preferable.*/ - /* Apparently USRSTACK is defined to be USERLIMIT, but in some */ - /* installations that's undefined. We work around this with a */ - /* gross hack: */ - EXTERN_C_END -# include <sys/vmparam.h> -# include <unistd.h> - EXTERN_C_BEGIN -# ifdef USERLIMIT - /* This should work everywhere, but doesn't. */ -# define STACKBOTTOM ((ptr_t)USRSTACK) -# else -# define HEURISTIC2 -# endif # define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE) - /* getpagesize() appeared to be missing from at least one */ - /* Solaris 5.4 installation. Weird. */ -# define DYNAMIC_LOADING + /* getpagesize() appeared to be missing from at least */ + /* one Solaris 5.4 installation. Weird. */ # endif # ifdef DRSNX # define OS_TYPE "DRSNX" @@ -1282,17 +1365,11 @@ # define DYNAMIC_LOADING # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# ifdef __ELF__ -# define DYNAMIC_LOADING -# elif !defined(CPPCHECK) +# if !defined(__ELF__) && !defined(CPPCHECK) # error Linux SPARC a.out not supported # endif -# define COUNT_UNMAPPED_REGIONS - extern int _end; - extern int _etext; -# define DATAEND ((ptr_t)(_end)) # define SVR4 + extern int _etext; ptr_t GC_SysVGetDataStart(size_t, ptr_t); # ifdef __arch64__ # define DATASTART GC_SysVGetDataStart(0x100000, (ptr_t)_etext) @@ -1300,39 +1377,14 @@ # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)_etext) # endif # define DATASTART_IS_FUNC -# define LINUX_STACKBOTTOM # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + /* Nothing specific. */ # endif # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 -# ifdef __ELF__ - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define DYNAMIC_LOADING -# else - extern char etext; -# define DATASTART ((ptr_t)(etext)) -# endif + /* Nothing specific. */ # endif # ifdef FREEBSD -# define OS_TYPE "FREEBSD" -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 -# define FREEBSD_STACKBOTTOM -# ifdef __ELF__ -# define DYNAMIC_LOADING -# endif extern char etext; extern char edata; # if !defined(CPPCHECK) @@ -1366,62 +1418,33 @@ # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff)) # define STACKBOTTOM ((ptr_t)0x3ffff000) # endif +# ifdef EMSCRIPTEN +# define OS_TYPE "EMSCRIPTEN" +# define DATASTART (ptr_t)ALIGNMENT +# define DATAEND (ptr_t)ALIGNMENT +# define USE_MMAP_ANON /* avoid /dev/zero, not supported */ +# define STACK_GROWS_DOWN +# endif +# if defined(__QNX__) +# define OS_TYPE "QNX" +# define SA_RESTART 0 +# define HEURISTIC1 + extern char etext; + extern int _end; +# define DATASTART ((ptr_t)etext) +# define DATAEND ((ptr_t)_end) +# endif # ifdef HAIKU -# define OS_TYPE "HAIKU" - EXTERN_C_END -# include <OS.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)B_PAGE_SIZE extern int etext; # define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff)) -# define DYNAMIC_LOADING -# define MPROTECT_VDB # endif # ifdef SOLARIS -# define OS_TYPE "SOLARIS" - extern int _etext, _end; - ptr_t GC_SysVGetDataStart(size_t, ptr_t); # define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext) -# define DATASTART_IS_FUNC -# define DATAEND ((ptr_t)(_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.*/ - /* Apparently USRSTACK is defined to be USERLIMIT, but in some */ - /* installations that's undefined. We work around this with a */ - /* gross hack: */ - EXTERN_C_END -# include <sys/vmparam.h> - EXTERN_C_BEGIN -# ifdef USERLIMIT - /* This should work everywhere, but doesn't. */ -# define STACKBOTTOM ((ptr_t)USRSTACK) -# else -# define HEURISTIC2 -# endif -/* 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. */ + /* 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 -# ifndef GC_THREADS -# define MPROTECT_VDB -# endif -# define DYNAMIC_LOADING -# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) -# define USE_MMAP 1 - /* 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 -# else -# define HEAP_START DATAEND -# endif # endif # ifdef SCO # define OS_TYPE "SCO" @@ -1459,24 +1482,18 @@ # define HEAP_START (ptr_t)0x40000000 # endif /* DGUX */ # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS # if !defined(REDIRECT_MALLOC) # define MPROTECT_VDB # else - /* We seem to get random errors in incremental mode, */ - /* possibly because Linux threads is itself a malloc client */ - /* and can't deal with the signals. */ + /* We seem to get random errors in the incremental mode, */ + /* possibly because the Linux threads implementation */ + /* itself is a malloc client and cannot deal with the */ + /* signals. fread() uses malloc too. */ # endif # define HEAP_START (ptr_t)0x1000 /* This encourages mmap to give us low addresses, */ - /* thus allowing the heap to grow to ~3GB */ + /* thus allowing the heap to grow to ~3 GB. */ # ifdef __ELF__ -# define DYNAMIC_LOADING - EXTERN_C_END -# include <features.h> - EXTERN_C_BEGIN # if defined(__GLIBC__) && __GLIBC__ >= 2 \ || defined(HOST_ANDROID) || defined(HOST_TIZEN) # define SEARCH_FOR_DATA_START @@ -1492,8 +1509,6 @@ /* contain large read-only data tables */ /* that we'd rather not scan. */ # endif - extern int _end; -# define DATAEND ((ptr_t)(_end)) # if !defined(GC_NO_SIGSETJMP) && (defined(HOST_TIZEN) \ || (defined(HOST_ANDROID) \ && !(GC_GNUC_PREREQ(4, 8) || GC_CLANG_PREREQ(3, 2) \ @@ -1529,25 +1544,27 @@ # define GC_PREFETCH_FOR_WRITE(x) \ __asm__ __volatile__ ("prefetchw %0" : : "m"(*(char *)(x))) # endif -# if defined(__GLIBC__) && !defined(__UCLIBC__) +# if defined(__GLIBC__) && !defined(__UCLIBC__) \ + && !defined(GLIBC_TSX_BUG_FIXED) /* Workaround lock elision implementation for some glibc. */ # define GLIBC_2_19_TSX_BUG EXTERN_C_END # include <gnu/libc-version.h> /* for gnu_get_libc_version() */ EXTERN_C_BEGIN # endif +# ifndef SOFT_VDB +# define SOFT_VDB +# endif # endif # ifdef CYGWIN32 -# define OS_TYPE "CYGWIN32" # define WOW64_THREAD_CONTEXT_WORKAROUND -# define RETRY_GET_THREAD_CONTEXT # define DATASTART ((ptr_t)GC_DATASTART) /* From gc.h */ # define DATAEND ((ptr_t)GC_DATAEND) -# undef STACK_GRAN -# define STACK_GRAN 0x10000 -# ifdef USE_MMAP -# define NEED_FIND_LIMIT -# define USE_MMAP_ANON +# ifndef USE_WINALLOC +# /* MPROTECT_VDB does not work, it leads to a spurious exit. */ +# ifdef USE_MMAP +# define NEED_FIND_LIMIT +# endif # endif # endif # ifdef INTERIX @@ -1570,18 +1587,12 @@ # define DATAEND /* not needed */ # endif # ifdef MSWIN32 -# define OS_TYPE "MSWIN32" # define WOW64_THREAD_CONTEXT_WORKAROUND # define RETRY_GET_THREAD_CONTEXT - /* STACKBOTTOM and DATASTART are handled specially in */ - /* os_dep.c. */ # define MPROTECT_VDB -# define GWW_VDB -# define DATAEND /* not needed */ # endif # ifdef MSWINCE -# define OS_TYPE "MSWINCE" -# define DATAEND /* not needed */ + /* Nothing specific. */ # endif # ifdef DJGPP # define OS_TYPE "DJGPP" @@ -1597,62 +1608,31 @@ /* This may not be right. */ # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + /* Nothing specific. */ # endif # ifdef FREEBSD -# define OS_TYPE "FREEBSD" -# ifndef GC_FREEBSD_THREADS -# define MPROTECT_VDB -# endif # ifdef __GLIBC__ -# define SIG_SUSPEND (32+6) -# define SIG_THR_RESTART (32+5) extern int _end; # define DATAEND ((ptr_t)(_end)) -# else -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 - /* SIGTSTP and SIGCONT could be used alternatively. */ # endif -# define FREEBSD_STACKBOTTOM -# ifdef __ELF__ -# define DYNAMIC_LOADING -# endif - extern char etext; -# define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) -# define DATASTART_USES_BSDGETDATASTART # endif # ifdef NETBSD -# define OS_TYPE "NETBSD" -# ifdef __ELF__ -# define DYNAMIC_LOADING -# endif + /* Nothing specific. */ # endif # ifdef THREE86BSD # define OS_TYPE "THREE86BSD" +# define HEURISTIC2 + extern char etext; +# define DATASTART ((ptr_t)(etext)) # endif # ifdef BSDI # define OS_TYPE "BSDI" -# endif -# if defined(NETBSD) || defined(THREE86BSD) || defined(BSDI) # define HEURISTIC2 extern char etext; # define DATASTART ((ptr_t)(etext)) # endif # ifdef NEXT -# define OS_TYPE "NEXT" -# define DATASTART ((ptr_t)get_etext()) -# define DATASTART_IS_FUNC # define STACKBOTTOM ((ptr_t)0xc0000000) -# define DATAEND /* not needed */ # endif # ifdef RTEMS # define OS_TYPE "RTEMS" @@ -1664,8 +1644,6 @@ # define InitStackBottom rtems_get_stack_bottom() # define DATASTART ((ptr_t)etext) # define STACKBOTTOM ((ptr_t)InitStackBottom) -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 # endif # ifdef DOS4GW # define OS_TYPE "DOS4GW" @@ -1686,8 +1664,6 @@ # define OS_TYPE "HURD" # define STACK_GROWS_DOWN # define HEURISTIC2 -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 # define SEARCH_FOR_DATA_START extern int _end; # define DATAEND ((ptr_t)(_end)) @@ -1696,23 +1672,9 @@ # define USE_MMAP_ANON # endif # ifdef DARWIN -# define OS_TYPE "DARWIN" # define DARWIN_DONT_PARSE_STACK 1 -# define DYNAMIC_LOADING - /* XXX: see get_end(3), get_etext() and get_end() should not be used. */ - /* These aren't used when dyld support is enabled (it is by default). */ -# define DATASTART ((ptr_t)get_etext()) -# define DATAEND ((ptr_t)get_end()) # define STACKBOTTOM ((ptr_t)0xc0000000) -# define USE_MMAP_ANON # define MPROTECT_VDB - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)getpagesize() - /* There seems to be some issues with trylock hanging on darwin. */ - /* This should be looked into some more. */ -# define NO_PTHREAD_TRYLOCK # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE) /* iPhone/iPad simulator */ # define NO_DYLD_BIND_FULLY_IMAGE @@ -1732,17 +1694,23 @@ # define STACKBOTTOM ((ptr_t)0xfffff000) /* for Encore */ # endif +# ifdef LOONGARCH +# define MACH_TYPE "LoongArch" +# ifdef LINUX +# pragma weak __data_start + extern int __data_start; +# define DATASTART ((ptr_t)(__data_start)) +# define CPP_WORDSZ _LOONGARCH_SZPTR +# define ALIGNMENT (_LOONGARCH_SZPTR/8) +# endif +# endif /* LOONGARCH */ + # ifdef MIPS # define MACH_TYPE "MIPS" # ifdef LINUX -# define OS_TYPE "LINUX" -# define DYNAMIC_LOADING -# define COUNT_UNMAPPED_REGIONS - extern int _end; # pragma weak __data_start extern int __data_start; # define DATASTART ((ptr_t)(__data_start)) -# define DATAEND ((ptr_t)(_end)) # ifdef _MIPS_SZPTR # define CPP_WORDSZ _MIPS_SZPTR # define ALIGNMENT (_MIPS_SZPTR/8) @@ -1759,6 +1727,7 @@ # endif # endif /* Linux */ # ifdef EWS4800 +# define OS_TYPE "EWS4800" # define HEURISTIC2 # if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64) extern int _fdata, _end; @@ -1782,17 +1751,17 @@ # define DATAEND2 ((ptr_t)(end)) # define ALIGNMENT 4 # endif -# define OS_TYPE "EWS4800" # endif # ifdef ULTRIX +# define OS_TYPE "ULTRIX" # define HEURISTIC2 # define DATASTART ((ptr_t)0x10000000) /* Could probably be slightly higher since */ /* startup code allocates lots of stuff. */ -# define OS_TYPE "ULTRIX" # define ALIGNMENT 4 # endif # ifdef IRIX5 +# define OS_TYPE "IRIX5" # define HEURISTIC2 extern int _fdata; # define DATASTART ((ptr_t)(_fdata)) @@ -1806,7 +1775,6 @@ /* In either case it is used to identify */ /* heap sections so they're not */ /* considered as roots. */ -# define OS_TYPE "IRIX5" /*# define MPROTECT_VDB DOB: this should work, but there is evidence */ /* of recent breakage. */ # ifdef _MIPS_SZPTR @@ -1818,56 +1786,25 @@ # define DYNAMIC_LOADING # endif # ifdef MSWINCE -# define OS_TYPE "MSWINCE" # define ALIGNMENT 4 -# define DATAEND /* not needed */ # endif -# if defined(NETBSD) -# define OS_TYPE "NETBSD" +# ifdef NETBSD # define ALIGNMENT 4 -# define HEURISTIC2 -# ifdef __ELF__ - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define NEED_FIND_LIMIT -# define DYNAMIC_LOADING -# else +# ifndef __ELF__ # define DATASTART ((ptr_t)0x10000000) # define STACKBOTTOM ((ptr_t)0x7ffff000) -# endif /* _ELF_ */ +# endif # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" # define CPP_WORDSZ 64 /* all OpenBSD/mips platforms are 64-bit */ # define ALIGNMENT 8 -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING # endif # ifdef FREEBSD -# define OS_TYPE "FREEBSD" # define ALIGNMENT 4 -# 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 GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) -# define DATASTART_USES_BSDGETDATASTART -# endif /* FreeBSD */ -# if defined(NONSTOP) -# define CPP_WORDSZ 32 +# endif +# ifdef NONSTOP # define OS_TYPE "NONSTOP" +# define CPP_WORDSZ 32 # define ALIGNMENT 4 # define DATASTART ((ptr_t)0x08000000) extern char **environ; @@ -1877,42 +1814,30 @@ # endif # ifdef NIOS2 -# define CPP_WORDSZ 32 -# define MACH_TYPE "NIOS2" -# ifdef LINUX -# define OS_TYPE "LINUX" -# define DYNAMIC_LOADING -# define COUNT_UNMAPPED_REGIONS - extern int _end; - extern int __data_start; -# define DATASTART ((ptr_t)(__data_start)) -# define DATAEND ((ptr_t)(_end)) -# define ALIGNMENT 4 -# ifndef HBLKSIZE -# define HBLKSIZE 4096 -# endif -# define LINUX_STACKBOTTOM -# endif /* Linux */ -# endif +# define CPP_WORDSZ 32 +# define MACH_TYPE "NIOS2" +# ifdef LINUX + extern int __data_start; +# define DATASTART ((ptr_t)(__data_start)) +# define ALIGNMENT 4 +# ifndef HBLKSIZE +# define HBLKSIZE 4096 +# endif +# endif +# endif /* NIOS2 */ # ifdef OR1K # define CPP_WORDSZ 32 # define MACH_TYPE "OR1K" # ifdef LINUX -# define OS_TYPE "LINUX" -# define DYNAMIC_LOADING -# define COUNT_UNMAPPED_REGIONS - extern int _end; extern int __data_start; # define DATASTART ((ptr_t)(__data_start)) -# define DATAEND ((ptr_t)(_end)) # define ALIGNMENT 4 # ifndef HBLKSIZE # define HBLKSIZE 4096 # endif -# define LINUX_STACKBOTTOM -# endif /* Linux */ -# endif +# endif +# endif /* OR1K */ # ifdef HP_PA # define MACH_TYPE "HP_PA" @@ -1923,17 +1848,10 @@ # define CPP_WORDSZ 32 # define ALIGNMENT 4 # endif -# if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) \ - && !defined(OPENBSD) && !defined(LINUX) /* For now. */ -# define MPROTECT_VDB -# endif # define STACK_GROWS_UP # ifdef HPUX -# define OS_TYPE "HPUX" - extern int __data_start; -# define DATASTART ((ptr_t)(__data_start)) -# ifdef USE_MMAP -# define USE_MMAP_ANON +# ifndef GC_THREADS +# define MPROTECT_VDB # endif # ifdef USE_HPUX_FIXED_STACKBOTTOM /* The following appears to work for 7xx systems running HP/UX */ @@ -1960,11 +1878,6 @@ # define HPUX_MAIN_STACKBOTTOM # define NEED_FIND_LIMIT # endif -# define DYNAMIC_LOADING - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)sysconf(_SC_PAGE_SIZE) # ifndef __GNUC__ # define PREFETCH(x) do { \ register long addr = (long)(x); \ @@ -1973,25 +1886,11 @@ # endif # endif /* HPUX */ # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING # define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# endif /* LINUX */ -# ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING -# endif +# endif +# ifdef OPENBSD + /* Nothing specific. */ +# endif # endif /* HP_PA */ # ifdef ALPHA @@ -1999,37 +1898,15 @@ # define ALIGNMENT 8 # define CPP_WORDSZ 64 # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 - extern ptr_t GC_data_start; -# define DATASTART GC_data_start # define ELFCLASS32 32 # define ELFCLASS64 64 # define ELF_CLASS ELFCLASS64 -# define DYNAMIC_LOADING # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# define ELF_CLASS ELFCLASS64 -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + /* Nothing specific. */ # endif # ifdef FREEBSD -# define OS_TYPE "FREEBSD" -/* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */ -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 - /* SIGTSTP and SIGCONT could be used alternatively. */ -# define FREEBSD_STACKBOTTOM -# ifdef __ELF__ -# define DYNAMIC_LOADING -# endif + /* MPROTECT_VDB is not yet supported at all on FreeBSD/alpha. */ /* Handle unmapped hole alpha*-*-freebsd45* puts between etext and edata. */ extern char etext; extern char edata; @@ -2051,6 +1928,9 @@ extern int _end; # define DATAEND ((ptr_t)(&_end)) extern char ** environ; + EXTERN_C_END +# include <unistd.h> + EXTERN_C_BEGIN /* round up from the value of environ to the nearest page boundary */ /* Probably breaks if putenv is called before collector */ /* initialization. */ @@ -2069,24 +1949,20 @@ # define DYNAMIC_LOADING # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS # ifdef __ELF__ # define SEARCH_FOR_DATA_START -# define DYNAMIC_LOADING # else -# define DATASTART ((ptr_t)0x140000000) +# define DATASTART ((ptr_t)0x140000000) + extern int _end; +# define DATAEND ((ptr_t)(_end)) # endif - extern int _end; -# define DATAEND ((ptr_t)(_end)) # if !defined(REDIRECT_MALLOC) # define MPROTECT_VDB /* Has only been superficially tested. May not */ /* work on all versions. */ # endif # endif -# endif +# endif /* ALPHA */ # ifdef IA64 # define MACH_TYPE "IA64" @@ -2103,23 +1979,10 @@ /* Requires 16 byte alignment for malloc */ # define ALIGNMENT 8 # endif -# define OS_TYPE "HPUX" - extern int __data_start; -# define DATASTART ((ptr_t)(__data_start)) -# ifdef USE_MMAP -# define USE_MMAP_ANON -# endif - /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2 */ - /* to this. Note that the GC must be initialized before the */ - /* first putenv call. */ + /* Note that the GC must be initialized before the 1st putenv call. */ extern char ** environ; # define STACKBOTTOM ((ptr_t)environ) # define HPUX_STACKBOTTOM -# define DYNAMIC_LOADING - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)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 */ @@ -2133,16 +1996,13 @@ # ifdef LINUX # define CPP_WORDSZ 64 # define ALIGNMENT 8 -# define OS_TYPE "LINUX" /* The following works on NUE and older kernels: */ -/* # define STACKBOTTOM ((ptr_t) 0xa000000000000000l) */ - /* This does not work on NUE: */ -# define LINUX_STACKBOTTOM + /* define STACKBOTTOM ((ptr_t)0xa000000000000000l) */ + /* TODO: LINUX_STACKBOTTOM does not work on NUE. */ /* We also need the base address of the register stack */ /* backing store. */ extern ptr_t GC_register_stackbottom; # define BACKING_STORE_BASE GC_register_stackbottom -# define COUNT_UNMAPPED_REGIONS # define SEARCH_FOR_DATA_START # ifdef __GNUC__ # define DYNAMIC_LOADING @@ -2155,8 +2015,6 @@ # define MPROTECT_VDB /* Requires Linux 2.3.47 or later. */ # endif - extern int _end; -# define DATAEND ((ptr_t)(_end)) # ifdef __GNUC__ # ifndef __INTEL_COMPILER # define PREFETCH(x) \ @@ -2177,10 +2035,6 @@ # endif # ifdef MSWIN32 /* FIXME: This is a very partial guess. There is no port, yet. */ -# define OS_TYPE "MSWIN32" - /* STACKBOTTOM and DATASTART are handled specially in */ - /* os_dep.c. */ -# define DATAEND /* not needed */ # if defined(_WIN64) # define CPP_WORDSZ 64 # else @@ -2190,22 +2044,35 @@ # endif # endif +# ifdef E2K +# define MACH_TYPE "E2K" +# define CPP_WORDSZ 64 +# define ALIGNMENT 8 +# ifndef HBLKSIZE +# define HBLKSIZE 4096 +# endif +# ifdef LINUX + extern int __dso_handle; +# define DATASTART ((ptr_t)__dso_handle) +# endif +# endif /* E2K */ + # ifdef M88K # define MACH_TYPE "M88K" # define ALIGNMENT 4 +# define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */ extern int etext; # ifdef CX_UX # define OS_TYPE "CX_UX" # define DATASTART ((ptr_t)((((word)(etext) + 0x3fffff) & ~0x3fffff) \ + 0x10000)) # endif -# ifdef DGUX +# ifdef DGUX # define OS_TYPE "DGUX" ptr_t GC_SysVGetDataStart(size_t, ptr_t); # define DATASTART GC_SysVGetDataStart(0x10000, (ptr_t)etext) # define DATASTART_IS_FUNC # endif -# define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */ # endif # ifdef S370 @@ -2229,28 +2096,30 @@ # ifdef S390 # define MACH_TYPE "S390" # ifndef __s390x__ -# define ALIGNMENT 4 -# define CPP_WORDSZ 32 +# define ALIGNMENT 4 +# define CPP_WORDSZ 32 # else -# define ALIGNMENT 8 -# define CPP_WORDSZ 64 -# ifndef HBLKSIZE -# define HBLKSIZE 4096 -# endif +# define ALIGNMENT 8 +# define CPP_WORDSZ 64 +# ifndef HBLKSIZE +# define HBLKSIZE 4096 +# endif # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING extern int __data_start __attribute__((__weak__)); # define DATASTART ((ptr_t)(__data_start)) extern int _end __attribute__((__weak__)); # define DATAEND ((ptr_t)(_end)) # define CACHE_LINE_SIZE 256 # define GETPAGESIZE() 4096 +# if !defined(REDIRECT_MALLOC) +# define MPROTECT_VDB +# endif +# ifndef SOFT_VDB +# define SOFT_VDB +# endif # endif -# endif +# endif /* S390 */ # ifdef AARCH64 # define MACH_TYPE "AARCH64" @@ -2265,76 +2134,38 @@ # define HBLKSIZE 4096 # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING +# if !defined(REDIRECT_MALLOC) +# define MPROTECT_VDB +# endif # if defined(HOST_ANDROID) # define SEARCH_FOR_DATA_START # else - extern int __data_start; + extern int __data_start __attribute__((__weak__)); # define DATASTART ((ptr_t)__data_start) # endif - extern int _end; -# define DATAEND ((ptr_t)(&_end)) # endif # ifdef DARWIN /* iOS */ -# define OS_TYPE "DARWIN" # define DARWIN_DONT_PARSE_STACK 1 -# define DYNAMIC_LOADING -# define DATASTART ((ptr_t)get_etext()) -# define DATAEND ((ptr_t)get_end()) # define STACKBOTTOM ((ptr_t)0x16fdfffff) -# define USE_MMAP_ANON /* MPROTECT_VDB causes use of non-public API like exc_server, */ /* this could be a reason for blocking the client application in */ /* the store. */ - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)getpagesize() - /* FIXME: There seems to be some issues with trylock hanging on */ - /* darwin. This should be looked into some more. */ -# define NO_PTHREAD_TRYLOCK # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE) # define NO_DYLD_BIND_FULLY_IMAGE # endif # endif # ifdef FREEBSD -# define OS_TYPE "FREEBSD" -# ifndef GC_FREEBSD_THREADS -# define MPROTECT_VDB -# endif -# define FREEBSD_STACKBOTTOM -# ifdef __ELF__ -# define DYNAMIC_LOADING -# endif - extern char etext; -# define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) -# define DATASTART_USES_BSDGETDATASTART + /* Nothing specific. */ # endif # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 - extern ptr_t GC_data_start; -# define DATASTART GC_data_start # define ELF_CLASS ELFCLASS64 -# define DYNAMIC_LOADING # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# define ELF_CLASS ELFCLASS64 -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + /* Nothing specific. */ # endif # ifdef NINTENDO_SWITCH +# define OS_TYPE "NINTENDO_SWITCH" extern int __bss_end; # define NO_HANDLE_FORK 1 # define DATASTART (ptr_t)ALIGNMENT /* cannot be null */ @@ -2343,13 +2174,10 @@ # define STACKBOTTOM ((ptr_t)switch_get_stack_bottom()) # endif # ifdef MSWIN32 /* UWP */ -# define OS_TYPE "MSWIN32" - /* TODO: Enable GWW_VDB and/or MPROTECT_VDB */ -# ifndef DATAEND -# define DATAEND /* not needed */ -# endif + /* TODO: Enable MPROTECT_VDB */ # endif # ifdef NOSYS +# define OS_TYPE "NOSYS" /* __data_start is usually defined in the target linker script. */ extern int __data_start; # define DATASTART ((ptr_t)__data_start) @@ -2367,34 +2195,18 @@ # define CPP_WORDSZ 32 # define ALIGNMENT 4 # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 -# ifdef __ELF__ - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define DYNAMIC_LOADING -# else - extern char etext; -# define DATASTART ((ptr_t)(etext)) -# endif + /* Nothing specific. */ # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# undef STACK_GRAN -# define STACK_GRAN 0x10000000 -# ifdef __ELF__ -# define DYNAMIC_LOADING - EXTERN_C_END -# include <features.h> - EXTERN_C_BEGIN -# if defined(__GLIBC__) && __GLIBC__ >= 2 \ +# if !defined(REDIRECT_MALLOC) +# define MPROTECT_VDB +# endif +# if defined(__GLIBC__) && __GLIBC__ >= 2 \ || defined(HOST_ANDROID) || defined(HOST_TIZEN) -# define SEARCH_FOR_DATA_START -# else - extern char **__environ; -# define DATASTART ((ptr_t)(&__environ)) +# define SEARCH_FOR_DATA_START +# else + extern char **__environ; +# define DATASTART ((ptr_t)(&__environ)) /* hideous kludge: __environ is the first */ /* word in crt0.o, and delimits the start */ /* of the data segment, no matter which */ @@ -2403,67 +2215,28 @@ /* would include .rodata, which may */ /* contain large read-only data tables */ /* that we'd rather not scan. */ -# endif - extern int _end; -# define DATAEND ((ptr_t)(_end)) -# else - extern int etext; -# define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff)) # endif # endif # ifdef MSWINCE -# define OS_TYPE "MSWINCE" -# define DATAEND /* not needed */ + /* Nothing specific. */ # endif # ifdef FREEBSD - /* FreeBSD/arm */ -# define OS_TYPE "FREEBSD" -# 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 GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) -# define DATASTART_USES_BSDGETDATASTART + /* Nothing specific. */ # endif # ifdef DARWIN /* iOS */ -# define OS_TYPE "DARWIN" # define DARWIN_DONT_PARSE_STACK 1 -# define DYNAMIC_LOADING -# define DATASTART ((ptr_t)get_etext()) -# define DATAEND ((ptr_t)get_end()) # define STACKBOTTOM ((ptr_t)0x30000000) -# define USE_MMAP_ANON /* MPROTECT_VDB causes use of non-public API. */ - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)getpagesize() - /* FIXME: There seems to be some issues with trylock hanging on */ - /* darwin. This should be looked into some more. */ -# define NO_PTHREAD_TRYLOCK # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE) # define NO_DYLD_BIND_FULLY_IMAGE # endif # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + /* Nothing specific. */ # endif # ifdef SN_TARGET_PSP2 +# define OS_TYPE "SN_TARGET_PSP2" # define NO_HANDLE_FORK 1 # define DATASTART (ptr_t)ALIGNMENT # define DATAEND (ptr_t)ALIGNMENT @@ -2471,6 +2244,7 @@ # define STACKBOTTOM ((ptr_t)psp2_get_stack_bottom()) # endif # ifdef NN_PLATFORM_CTR +# define OS_TYPE "NN_PLATFORM_CTR" extern unsigned char Image$$ZI$$ZI$$Base; # define DATASTART (ptr_t)(Image$$ZI$$ZI$$Base) extern unsigned char Image$$ZI$$ZI$$Limit; @@ -2479,13 +2253,10 @@ # define STACKBOTTOM ((ptr_t)n3ds_get_stack_bottom()) # endif # ifdef MSWIN32 /* UWP */ -# define OS_TYPE "MSWIN32" - /* TODO: Enable GWW_VDB and/or MPROTECT_VDB */ -# ifndef DATAEND -# define DATAEND /* not needed */ -# endif + /* TODO: Enable MPROTECT_VDB */ # endif # ifdef NOSYS +# define OS_TYPE "NOSYS" /* __data_start is usually defined in the target linker script. */ extern int __data_start; # define DATASTART ((ptr_t)(__data_start)) @@ -2499,87 +2270,53 @@ # define MACH_TYPE "CRIS" # define CPP_WORDSZ 32 # define ALIGNMENT 1 -# define OS_TYPE "LINUX" -# define DYNAMIC_LOADING -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(_end)) -# endif +# ifdef LINUX +# define SEARCH_FOR_DATA_START +# endif +# endif /* CRIS */ # if defined(SH) && !defined(SH4) # define MACH_TYPE "SH" # define ALIGNMENT 4 -# ifdef MSWINCE -# define OS_TYPE "MSWINCE" -# define DATAEND /* not needed */ -# endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING # define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(_end)) # endif # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define DYNAMIC_LOADING + /* Nothing specific. */ # endif # ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; -# define DATASTART ((ptr_t)__data_start) - extern int _end; -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + /* Nothing specific. */ +# endif +# ifdef MSWINCE + /* Nothing specific. */ # endif # endif # ifdef SH4 # define MACH_TYPE "SH4" -# define OS_TYPE "MSWINCE" # define ALIGNMENT 4 -# define DATAEND /* not needed */ +# ifdef MSWINCE + /* Nothing specific. */ +# endif # endif # ifdef AVR32 # define MACH_TYPE "AVR32" # define CPP_WORDSZ 32 # define ALIGNMENT 4 -# define OS_TYPE "LINUX" -# define DYNAMIC_LOADING -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(_end)) -# endif +# ifdef LINUX +# define SEARCH_FOR_DATA_START +# endif +# endif /* AVR32 */ # ifdef M32R # define CPP_WORDSZ 32 # define MACH_TYPE "M32R" # define ALIGNMENT 4 # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# undef STACK_GRAN -# define STACK_GRAN 0x10000000 -# define DYNAMIC_LOADING # define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(_end)) # endif -# endif +# endif /* M32R */ # ifdef X86_64 # define MACH_TYPE "X86_64" @@ -2596,192 +2333,102 @@ # ifndef CACHE_LINE_SIZE # define CACHE_LINE_SIZE 64 # endif -# ifdef SN_TARGET_ORBIS +# ifdef PLATFORM_GETMEM +# define OS_TYPE "PLATFORM_GETMEM" # define DATASTART (ptr_t)ALIGNMENT # define DATAEND (ptr_t)ALIGNMENT - void *ps4_get_stack_bottom(void); -# define STACKBOTTOM ((ptr_t)ps4_get_stack_bottom()) -# endif -# ifdef OPENBSD -# define OS_TYPE "OPENBSD" -# define ELF_CLASS ELFCLASS64 -# ifndef GC_OPENBSD_THREADS -# define HEURISTIC2 -# endif - extern int __data_start; - extern int _end; -# define DATASTART ((ptr_t)__data_start) -# define DATAEND ((ptr_t)(&_end)) -# define DYNAMIC_LOADING + EXTERN_C_END +# include <pthread.h> + EXTERN_C_BEGIN + void *platform_get_stack_bottom(void); +# define STACKBOTTOM ((ptr_t)platform_get_stack_bottom()) # endif # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM # if !defined(REDIRECT_MALLOC) # define MPROTECT_VDB # else - /* We seem to get random errors in incremental mode, */ - /* possibly because Linux threads is itself a malloc client */ - /* and can't deal with the signals. */ -# endif -# define COUNT_UNMAPPED_REGIONS -# ifdef __ELF__ -# define DYNAMIC_LOADING - EXTERN_C_END -# include <features.h> - EXTERN_C_BEGIN -# define SEARCH_FOR_DATA_START - extern int _end; -# define DATAEND ((ptr_t)(_end)) -# else - extern int etext; -# define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff)) + /* We seem to get random errors in the incremental mode, */ + /* possibly because the Linux threads implementation */ + /* itself is a malloc client and cannot deal with the */ + /* signals. fread() uses malloc too. */ # endif +# define SEARCH_FOR_DATA_START # if defined(__GLIBC__) && !defined(__UCLIBC__) /* A workaround for GCF (Google Cloud Function) which does */ /* not support mmap() for "/dev/zero". Should not cause any */ /* harm to other targets. */ # define USE_MMAP_ANON +# endif +# if defined(__GLIBC__) && !defined(__UCLIBC__) \ + && !defined(GETCONTEXT_FPU_BUG_FIXED) /* At present, there's a bug in GLibc getcontext() on */ /* Linux/x64 (it clears FPU exception mask). We define this */ /* macro to workaround it. */ /* TODO: This seems to be fixed in GLibc v2.14. */ # define GETCONTEXT_FPU_EXCMASK_BUG +# endif +# if defined(__GLIBC__) && !defined(__UCLIBC__) \ + && !defined(GLIBC_TSX_BUG_FIXED) /* Workaround lock elision implementation for some glibc. */ # define GLIBC_2_19_TSX_BUG EXTERN_C_END # include <gnu/libc-version.h> /* for gnu_get_libc_version() */ EXTERN_C_BEGIN # endif +# ifndef SOFT_VDB +# define SOFT_VDB +# endif # endif # ifdef DARWIN -# define OS_TYPE "DARWIN" # define DARWIN_DONT_PARSE_STACK 1 -# define DYNAMIC_LOADING - /* XXX: see get_end(3), get_etext() and get_end() should not be used. */ - /* These aren't used when dyld support is enabled (it is by default) */ -# define DATASTART ((ptr_t)get_etext()) -# define DATAEND ((ptr_t)get_end()) # define STACKBOTTOM ((ptr_t)0x7fff5fc00000) -# define USE_MMAP_ANON # define MPROTECT_VDB - EXTERN_C_END -# include <unistd.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)getpagesize() - /* There seems to be some issues with trylock hanging on darwin. */ - /* This should be looked into some more. */ -# define NO_PTHREAD_TRYLOCK # if TARGET_OS_IPHONE && !defined(NO_DYLD_BIND_FULLY_IMAGE) /* iPhone/iPad simulator */ # define NO_DYLD_BIND_FULLY_IMAGE # endif # endif # ifdef FREEBSD -# define OS_TYPE "FREEBSD" -# ifndef GC_FREEBSD_THREADS -# define MPROTECT_VDB -# endif # ifdef __GLIBC__ -# define SIG_SUSPEND (32+6) -# define SIG_THR_RESTART (32+5) extern int _end; # define DATAEND ((ptr_t)(_end)) -# else -# define SIG_SUSPEND SIGUSR1 -# define SIG_THR_RESTART SIGUSR2 - /* SIGTSTP and SIGCONT could be used alternatively. */ # endif -# define FREEBSD_STACKBOTTOM # if defined(__DragonFly__) /* DragonFly BSD still has vm.max_proc_mmap, according to */ /* its mmap(2) man page. */ # define COUNT_UNMAPPED_REGIONS # endif -# ifdef __ELF__ -# define DYNAMIC_LOADING -# endif - extern char etext; -# define DATASTART GC_FreeBSDGetDataStart(0x1000, (ptr_t)etext) -# define DATASTART_USES_BSDGETDATASTART # endif # ifdef NETBSD -# define OS_TYPE "NETBSD" -# define HEURISTIC2 -# ifdef __ELF__ - extern ptr_t GC_data_start; -# define DATASTART GC_data_start -# define DYNAMIC_LOADING -# else -# define SEARCH_FOR_DATA_START -# endif + /* Nothing specific. */ +# endif +# ifdef OPENBSD + /* Nothing specific. */ # endif # ifdef HAIKU -# define OS_TYPE "HAIKU" - EXTERN_C_END -# include <OS.h> - EXTERN_C_BEGIN -# define GETPAGESIZE() (unsigned)B_PAGE_SIZE # define HEURISTIC2 # define SEARCH_FOR_DATA_START -# define DYNAMIC_LOADING -# define MPROTECT_VDB # endif # ifdef SOLARIS -# define OS_TYPE "SOLARIS" -# define ELF_CLASS ELFCLASS64 - extern int _etext, _end; - ptr_t GC_SysVGetDataStart(size_t, ptr_t); -# define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext) -# define DATASTART_IS_FUNC -# define DATAEND ((ptr_t)(_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.*/ - /* Apparently USRSTACK is defined to be USERLIMIT, but in some */ - /* installations that's undefined. We work around this with a */ - /* gross hack: */ - EXTERN_C_END -# include <sys/vmparam.h> - EXTERN_C_BEGIN -# ifdef USERLIMIT - /* This should work everywhere, but doesn't. */ -# define STACKBOTTOM ((ptr_t)USRSTACK) -# else -# define HEURISTIC2 -# endif -/* 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 -# ifndef GC_THREADS -# define MPROTECT_VDB -# endif -# define DYNAMIC_LOADING -# if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) -# define USE_MMAP 1 - /* 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 -# else -# define HEAP_START DATAEND -# endif +# define ELF_CLASS ELFCLASS64 +# define DATASTART GC_SysVGetDataStart(0x1000, (ptr_t)_etext) +# ifdef SOLARIS25_PROC_VDB_BUG_FIXED +# define PROC_VDB +# endif # endif # ifdef CYGWIN32 -# define OS_TYPE "CYGWIN32" -# define RETRY_GET_THREAD_CONTEXT -# ifdef USE_MMAP -# define USE_MMAP_ANON +# ifndef USE_WINALLOC +# if defined(THREAD_LOCAL_ALLOC) + /* TODO: For an unknown reason, thread-local allocations */ + /* lead to spurious process exit after the fault handler is */ + /* once invoked. */ +# else +# define MPROTECT_VDB # endif +# endif # endif # ifdef MSWIN_XBOX1 +# define OS_TYPE "MSWIN_XBOX1" # define NO_GETENV # define DATASTART (ptr_t)ALIGNMENT # define DATAEND (ptr_t)ALIGNMENT @@ -2801,53 +2448,42 @@ # define MAP_FAILED ((void *)-1) # endif # ifdef MSWIN32 -# define OS_TYPE "MSWIN32" # define RETRY_GET_THREAD_CONTEXT - /* STACKBOTTOM and DATASTART are handled specially in */ - /* os_dep.c. */ # if !defined(__GNUC__) || defined(__INTEL_COMPILER) \ - || GC_GNUC_PREREQ(4, 7) - /* Older GCC has not supported SetUnhandledExceptionFilter */ - /* properly on x64 (e.g. SEH unwinding information missed). */ + || (GC_GNUC_PREREQ(4, 7) && !defined(__MINGW64__)) + /* Older GCC and Mingw-w64 (both GCC and Clang) do not */ + /* support SetUnhandledExceptionFilter() properly on x64. */ # define MPROTECT_VDB # endif -# define GWW_VDB -# ifndef DATAEND -# define DATAEND /* not needed */ -# endif # endif # endif /* X86_64 */ +# ifdef ARC +# define CPP_WORDSZ 32 +# define MACH_TYPE "ARC" +# define ALIGNMENT 4 +# define CACHE_LINE_SIZE 64 +# ifdef LINUX + extern int __data_start __attribute__((__weak__)); +# define DATASTART ((ptr_t)__data_start) +# endif +# endif /* ARC */ + # ifdef HEXAGON # define CPP_WORDSZ 32 # define MACH_TYPE "HEXAGON" # define ALIGNMENT 4 # ifdef LINUX -# define OS_TYPE "LINUX" -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS +# if !defined(REDIRECT_MALLOC) # define MPROTECT_VDB -# ifdef __ELF__ -# if !defined(REDIRECT_MALLOC) -# define MPROTECT_VDB -# endif - EXTERN_C_END -# include <features.h> - EXTERN_C_BEGIN -# if defined(__GLIBC__) && __GLIBC__ >= 2 -# define SEARCH_FOR_DATA_START -# else -# error Unknown Hexagon libc configuration -# endif - extern int _end; -# define DATAEND ((ptr_t)(_end)) -# elif !defined(CPPCHECK) -# error Bad Hexagon Linux configuration -# endif -# else -# error Unknown Hexagon OS configuration +# endif +# if defined(__GLIBC__) +# define SEARCH_FOR_DATA_START +# elif !defined(CPPCHECK) +# error Unknown Hexagon libc configuration +# endif # endif -# endif +# endif /* HEXAGON */ # ifdef TILEPRO # define CPP_WORDSZ 32 @@ -2856,14 +2492,10 @@ # define PREFETCH(x) __insn_prefetch(x) # define CACHE_LINE_SIZE 64 # ifdef LINUX -# define OS_TYPE "LINUX" extern int __data_start; # define DATASTART ((ptr_t)__data_start) -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING # endif -# endif +# endif /* TILEPRO */ # ifdef TILEGX # define CPP_WORDSZ (__SIZEOF_POINTER__ * 8) @@ -2875,26 +2507,24 @@ # define PREFETCH(x) __insn_prefetch_l1(x) # define CACHE_LINE_SIZE 64 # ifdef LINUX -# define OS_TYPE "LINUX" extern int __data_start; # define DATASTART ((ptr_t)__data_start) -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING # endif -# endif +# endif /* TILEGX */ # ifdef RISCV # define MACH_TYPE "RISC-V" # define CPP_WORDSZ __riscv_xlen /* 32 or 64 */ # define ALIGNMENT (CPP_WORDSZ/8) +# ifdef FREEBSD + /* Nothing specific. */ +# endif # ifdef LINUX -# define OS_TYPE "LINUX" extern int __data_start __attribute__((__weak__)); # define DATASTART ((ptr_t)__data_start) -# define LINUX_STACKBOTTOM -# define COUNT_UNMAPPED_REGIONS -# define DYNAMIC_LOADING +# endif +# ifdef OPENBSD + /* Nothing specific. */ # endif # endif /* RISCV */ @@ -2910,7 +2540,7 @@ #if defined(LINUX_STACKBOTTOM) && defined(NO_PROC_STAT) \ && !defined(USE_LIBC_PRIVATES) /* This combination will fail, since we have no way to get */ - /* the stack base. Use HEURISTIC2 instead. */ + /* the stack bottom. Use HEURISTIC2 instead. */ # undef LINUX_STACKBOTTOM # define HEURISTIC2 /* This may still fail on some architectures like IA64. */ @@ -2919,7 +2549,7 @@ #if defined(USE_MMAP_ANON) && !defined(USE_MMAP) # define USE_MMAP 1 -#elif defined(LINUX) && defined(USE_MMAP) +#elif (defined(LINUX) || defined(OPENBSD)) && defined(USE_MMAP) /* The kernel may do a somewhat better job merging mappings etc. */ /* with anonymous mappings. */ # define USE_MMAP_ANON @@ -2990,7 +2620,7 @@ #endif #ifndef GETPAGESIZE -# if defined(SOLARIS) || defined(IRIX5) || defined(LINUX) \ +# if defined(AIX) || defined(IRIX5) || defined(LINUX) || defined(SOLARIS) \ || defined(NETBSD) || defined(FREEBSD) || defined(HPUX) EXTERN_C_END # include <unistd.h> @@ -3013,6 +2643,11 @@ # define SVR4 #endif +#if defined(MPROTECT_VDB) && defined(__GLIBC__) \ + && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)) +# error glibc too old? +#endif + #if defined(SOLARIS) || defined(DRSNX) /* OS has SOLARIS style semi-undocumented interface */ /* to dynamic loader. */ @@ -3026,7 +2661,7 @@ #endif #if defined(FREEBSD) && (defined(__DragonFly__) || __FreeBSD__ >= 4 \ - || (__FreeBSD_kernel__ >= 4)) + || __FreeBSD_kernel__ >= 4 || defined(__GLIBC__)) # define SUNOS5SIGS #endif @@ -3130,7 +2765,7 @@ /* The platform does not have a virtual paging system, so it does not */ /* have a large virtual address space that a standard x64 platform has. */ #if defined(USE_MUNMAP) && !defined(MUNMAP_THRESHOLD) \ - && (defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \ + && (defined(SN_TARGET_PS3) \ || defined(SN_TARGET_PSP2) || defined(MSWIN_XBOX1)) # define MUNMAP_THRESHOLD 2 #endif @@ -3154,8 +2789,31 @@ # undef MPROTECT_VDB # undef PCR_VDB # undef PROC_VDB +# undef SOFT_VDB #endif +#ifdef NO_GWW_VDB +# undef GWW_VDB +#endif + +#ifdef NO_MPROTECT_VDB +# undef MPROTECT_VDB +#endif + +#ifdef NO_SOFT_VDB +# undef SOFT_VDB +#endif + +#if defined(SOFT_VDB) && defined(SOFT_VDB_LINUX_VER_STATIC_CHECK) + EXTERN_C_END +# include <linux/version.h> /* for LINUX_VERSION_CODE */ + EXTERN_C_BEGIN +# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) + /* Not reliable in kernels prior to v3.18. */ +# undef SOFT_VDB +# endif +#endif /* SOFT_VDB */ + #ifdef GC_DISABLE_INCREMENTAL # undef CHECKSUMS #endif @@ -3171,17 +2829,8 @@ # undef MPROTECT_VDB #endif -#if defined(USE_MUNMAP) && defined(GWW_VDB) -# undef MPROTECT_VDB /* TODO: Cannot deal with address space holes. */ - /* Else if MPROTECT_VDB is available but not GWW_VDB then decide */ - /* whether to disable memory unmapping or mprotect-based virtual */ - /* dirty bits at runtime when GC_enable_incremental is called. */ -#endif - -/* PARALLEL_MARK does not cause undef MPROTECT_VDB any longer. */ - #if defined(USE_PROC_FOR_LIBRARIES) && defined(GC_LINUX_THREADS) - /* Incremental GC is incompatible with /proc roots. */ + /* Incremental GC based on mprotect is incompatible with /proc roots. */ # undef MPROTECT_VDB #endif @@ -3189,12 +2838,14 @@ /* Choose MPROTECT_VDB manually (if multiple strategies available). */ # undef PCR_VDB # undef PROC_VDB - /* #undef GWW_VDB - handled in os_dep.c */ + /* GWW_VDB, SOFT_VDB are handled in os_dep.c. */ #endif #ifdef PROC_VDB - /* Multi-VDB mode is not implemented. */ + /* Mutually exclusive VDB implementations (for now). */ # undef MPROTECT_VDB + /* For a test purpose only. */ +# undef SOFT_VDB #endif #if defined(MPROTECT_VDB) && !defined(MSWIN32) && !defined(MSWINCE) @@ -3216,11 +2867,17 @@ #endif #if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) \ - && !defined(GWW_VDB) && !defined(DEFAULT_VDB) \ + && !defined(GWW_VDB) && !defined(SOFT_VDB) && !defined(DEFAULT_VDB) \ && !defined(GC_DISABLE_INCREMENTAL) # define DEFAULT_VDB #endif +#if !defined(PROC_VDB) && !defined(SOFT_VDB) \ + && !defined(NO_VDB_FOR_STATIC_ROOTS) + /* Cannot determine whether a static root page is dirty? */ +# define NO_VDB_FOR_STATIC_ROOTS +#endif + #if ((defined(UNIX_LIKE) && (defined(DARWIN) || defined(HAIKU) \ || defined(HURD) || defined(OPENBSD) \ || defined(ARM32) \ @@ -3253,8 +2910,8 @@ #endif #ifndef STATIC -# ifndef NO_DEBUGGING -# define STATIC /* ignore to aid profiling and possibly debugging */ +# ifdef GC_ASSERTIONS +# define STATIC /* ignore to aid debugging (or profiling) */ # else # define STATIC static # endif @@ -3327,7 +2984,7 @@ #if defined(PCR) || defined(GC_WIN32_THREADS) || defined(GC_PTHREADS) \ || ((defined(NN_PLATFORM_CTR) || defined(NINTENDO_SWITCH) \ - || defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \ + || defined(SN_TARGET_PS3) \ || defined(SN_TARGET_PSP2)) && defined(GC_THREADS)) # define THREADS #endif @@ -3336,10 +2993,14 @@ # error Invalid config: PARALLEL_MARK requires GC_THREADS #endif +#if defined(GWW_VDB) && !defined(USE_WINALLOC) && !defined(CPPCHECK) +# error Invalid config: GWW_VDB requires USE_WINALLOC +#endif + #if (((defined(MSWIN32) || defined(MSWINCE)) && !defined(__GNUC__)) \ || (defined(MSWIN32) && defined(I386)) /* for Win98 */ \ || (defined(USE_PROC_FOR_LIBRARIES) && defined(THREADS))) \ - && !defined(NO_WRAP_MARK_SOME) + && !defined(NO_CRT) && !defined(NO_WRAP_MARK_SOME) /* Under rare conditions, we may end up marking from nonexistent */ /* memory. Hence we need to be prepared to recover by running */ /* GC_mark_some with a suitable handler in place. */ @@ -3416,15 +3077,14 @@ #endif #if defined(CAN_HANDLE_FORK) && !defined(CAN_CALL_ATFORK) \ - && !defined(HURD) && !defined(SN_TARGET_ORBIS) && !defined(HOST_TIZEN) \ - && (!defined(HOST_ANDROID) || __ANDROID_API__ >= 21) + && !defined(GC_NO_CAN_CALL_ATFORK) && !defined(HOST_TIZEN) \ + && !defined(HURD) && (!defined(HOST_ANDROID) || __ANDROID_API__ >= 21) /* Have working pthread_atfork(). */ # define CAN_CALL_ATFORK #endif #if !defined(CAN_HANDLE_FORK) && !defined(HAVE_NO_FORK) \ - && (defined(MSWIN32) || defined(MSWINCE) || defined(DOS4GW) \ - || defined(OS2) || defined(SYMBIAN) /* and probably others ... */) + && !(defined(CYGWIN32) || defined(SOLARIS) || defined(UNIX_LIKE)) # define HAVE_NO_FORK #endif @@ -3443,6 +3103,14 @@ # define NO_GETENV_WIN32 #endif +#if !defined(MSGBOX_ON_ERROR) && !defined(NO_MSGBOX_ON_ERROR) \ + && !defined(SMALL_CONFIG) && defined(MSWIN32) \ + && !defined(MSWINRT_FLAVOR) && !defined(MSWIN_XBOX1) + /* Show Windows message box with "OK" button on a GC fatal error. */ + /* Client application is terminated once the user clicks the button. */ +# define MSGBOX_ON_ERROR +#endif + #ifndef STRTOULL # if defined(_WIN64) && !defined(__GNUC__) # define STRTOULL _strtoui64 @@ -3645,9 +3313,9 @@ SIZET_SAT_ADD(bytes, \ GC_page_size)) \ + GC_page_size-1) -# elif defined(SN_TARGET_ORBIS) - void *ps4_get_mem(size_t bytes); -# define GET_MEM(bytes) (struct hblk*)ps4_get_mem(bytes) +# elif defined(PLATFORM_GETMEM) + void *platform_get_mem(size_t bytes); +# define GET_MEM(bytes) (struct hblk*)platform_get_mem(bytes) # elif defined(SN_TARGET_PS3) void *ps3_get_mem(size_t bytes); # define GET_MEM(bytes) (struct hblk*)ps3_get_mem(bytes) @@ -3660,6 +3328,9 @@ # elif defined(HAIKU) ptr_t GC_haiku_get_mem(size_t bytes); # define GET_MEM(bytes) (struct hblk*)GC_haiku_get_mem(bytes) +# elif defined(EMSCRIPTEN_TINY) + void *emmalloc_memalign(size_t alignment, size_t size); +# define GET_MEM(bytes) (struct hblk*)emmalloc_memalign(GC_page_size, bytes) # else ptr_t GC_unix_get_mem(size_t bytes); # define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/pthread_stop_world.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/pthread_stop_world.h
Changed
@@ -22,10 +22,18 @@ struct thread_stop_info { # if !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ - && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) volatile AO_t last_stop_count; /* The value of GC_stop_count when the thread */ /* last successfully handled a suspend signal. */ +# ifdef GC_ENABLE_SUSPEND_THREAD + volatile AO_t ext_suspend_cnt; + /* An odd value means thread was suspended */ + /* externally. Incremented on every call of */ + /* GC_suspend_thread() and GC_resume_thread(). */ + /* Updated with the GC lock held, but could be */ + /* read from a signal handler. */ +# endif # endif ptr_t stack_ptr; /* Valid only when stopped. */ @@ -44,9 +52,8 @@ # define NACL_GC_REG_STORAGE_SIZE 20 # endif ptr_t reg_storageNACL_GC_REG_STORAGE_SIZE; -# elif defined(SN_TARGET_ORBIS) -# define ORBIS_GC_REG_STORAGE_SIZE 27 - word registersORBIS_GC_REG_STORAGE_SIZE; /* used externally */ +# elif defined(PLATFORM_HAVE_GC_REG_STORAGE_SIZE) + word registersPLATFORM_GC_REG_STORAGE_SIZE; /* used externally */ # endif };
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/pthread_support.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/pthread_support.h
Changed
@@ -66,12 +66,7 @@ /* Extra bookkeeping information the stopping code uses */ struct thread_stop_info stop_info; -# if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_DARWIN_THREADS) \ - && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) - volatile AO_t suspended_ext; /* Thread was suspended externally. */ -# endif - - unsigned char flags; + unsigned char flags; /* Protected by GC lock. */ # define FINISHED 1 /* Thread has exited. */ # define DETACHED 2 /* Thread is treated as detached. */ /* Thread may really be detached, or */ @@ -93,12 +88,14 @@ /* not need to be sent a signal to stop */ /* it. */ - unsigned short finalizer_skipped; - unsigned char finalizer_nested; +# ifndef GC_NO_FINALIZATION + unsigned short finalizer_skipped; + unsigned char finalizer_nested; /* Used by GC_check_finalizer_nested() */ /* to minimize the level of recursion */ /* when a client finalizer allocates */ /* memory (initially both are 0). */ +# endif ptr_t stack_end; /* Cold end of the stack (except for */ /* main thread). */ @@ -113,8 +110,8 @@ /* valid only if the thread is blocked; */ /* non-NULL value means already set. */ # endif -# ifdef IA64 - ptr_t backing_store_end; +# if defined(E2K) || defined(IA64) + ptr_t backing_store_end; /* Note: may reference data in GC heap */ ptr_t backing_store_ptr; # endif @@ -168,6 +165,15 @@ GC_INNER void GC_unblock_gc_signals(void); #endif +#if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_DARWIN_THREADS) \ + && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) + GC_INNER void GC_suspend_self_inner(GC_thread me, word suspend_cnt); + + GC_INNER void GC_suspend_self_blocked(ptr_t thread_me, void *context); + /* Wrapper over GC_suspend_self_inner. */ +#endif + #ifdef GC_PTHREAD_START_STANDALONE # define GC_INNER_PTHRSTART /* empty */ #else
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/specific.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/specific.h
Changed
@@ -1,4 +1,17 @@ /* + * Copyright (c) 2000 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 is a reimplementation of a subset of the pthread_getspecific/setspecific * interface. This appears to outperform the standard linuxthreads one * by a significant margin. @@ -67,7 +80,7 @@ /* only as a backup. */ /* Return the "quick thread id". Default version. Assumes page size, */ -/* or at least thread stack separation, is at least 4K. */ +/* or at least thread stack separation, is at least 4 KB. */ /* Must be defined so that it never returns 0. (Page 0 can't really be */ /* part of any stack, since that would make 0 a valid stack pointer.) */ #define quick_thread_id() (((word)GC_approx_sp()) >> 12)
View file
_service:tar_scm:gc-8.0.6.tar.gz/include/private/thread_local_alloc.h -> _service:tar_scm:gc-8.2.2.tar.gz/include/private/thread_local_alloc.h
Changed
@@ -54,9 +54,11 @@ # endif /* !GNU */ # elif (defined(LINUX) && !defined(ARM32) && !defined(AVR32) \ && GC_GNUC_PREREQ(3, 3) \ - && !(defined(__clang__) && defined(HOST_ANDROID))) \ - || (defined(FREEBSD) && defined(__GLIBC__) /* kFreeBSD */ \ - && GC_GNUC_PREREQ(4, 4)) \ + && !(defined(__clang__) && (defined(HOST_ANDROID) \ + || (defined(AARCH64) && !GC_CLANG_PREREQ(8, 0))))) \ + || ((defined(NETBSD) && __NetBSD_Version__ >= 600000000 /* 6.0 */ \ + || defined(FREEBSD)) \ + && (GC_GNUC_PREREQ(4, 4) || GC_CLANG_PREREQ(3, 9))) \ || (defined(HOST_ANDROID) && defined(ARM32) \ && (GC_GNUC_PREREQ(4, 6) || GC_CLANG_PREREQ_FULL(3, 8, 256229))) # define USE_COMPILER_TLS @@ -133,13 +135,6 @@ # define GC_remove_specific_after_fork(key, t) (void)0 typedef void * GC_key_t; #elif defined(USE_WIN32_SPECIFIC) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE - EXTERN_C_END -# include <windows.h> - EXTERN_C_BEGIN # define GC_getspecific TlsGetValue # define GC_setspecific(key, v) !TlsSetValue(key, v) /* We assume 0 == success, msft does the opposite. */
View file
_service:tar_scm:gc-8.0.6.tar.gz/install-sh -> _service:tar_scm:gc-8.2.2.tar.gz/install-sh
Changed
@@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2013-12-25.23; # UTC +scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -69,6 +69,11 @@ # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -99,18 +104,28 @@ --version display version info and exit. -c (ignored) - -C install only if different (preserve the last data modification time) + -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do @@ -137,8 +152,13 @@ -o) chowncmd="$chownprog $2" shift;; + -p) cpprog="$cpprog -p";; + -s) stripcmd=$stripprog;; + -S) backupsuffix="$2" + shift;; + -t) is_target_a_directory=always dst_arg=$2 @@ -255,6 +275,10 @@ dstdir=$dst test -d "$dstdir" dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command @@ -271,15 +295,18 @@ fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else dstdir=`dirname "$dst"` @@ -288,27 +315,16 @@ fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *23672367) mkdir_umask=$umask;; - .*00202 | .0202 | .02) mkdir_umask=22;; - - *0-7) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then @@ -318,43 +334,49 @@ fi posix_mkdir=false - case $umask in - *1235670-70-7) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; esac if @@ -365,7 +387,7 @@ then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. @@ -394,7 +416,7 @@ prefixes= else if $posix_mkdir; then - (umask=$mkdir_umask && + (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 @@ -427,14 +449,25 @@ else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -460,6 +493,13 @@ then rm -f "$dsttmp" else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || @@ -474,9 +514,9 @@ # file should still install successfully. { test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || + $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 @@ -493,9 +533,9 @@ done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End:
View file
_service:tar_scm:gc-8.0.6.tar.gz/mach_dep.c -> _service:tar_scm:gc-8.2.2.tar.gz/mach_dep.c
Changed
@@ -14,7 +14,7 @@ #include "private/gc_priv.h" -#if !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) +#if !defined(PLATFORM_MACH_DEP) && !defined(SN_TARGET_PSP2) #include <stdio.h> @@ -26,6 +26,89 @@ # endif #endif +#ifdef E2K +# include <errno.h> +# include <asm/e2k_syswork.h> +# include <sys/mman.h> +# include <sys/syscall.h> + + GC_INNER size_t GC_get_procedure_stack(ptr_t buf, size_t buf_sz) { + word new_sz; + + GC_ASSERT(0 == buf_sz || buf != NULL); + for (;;) { + word stack_ofs; + + new_sz = 0; + if (syscall(__NR_access_hw_stacks, E2K_GET_PROCEDURE_STACK_SIZE, + NULL, NULL, 0, &new_sz) == -1) { + if (errno != EAGAIN) + ABORT_ARG1("Cannot get size of procedure stack", + ": errno= %d", errno); + continue; + } + GC_ASSERT(new_sz > 0 && new_sz % sizeof(word) == 0); + if (new_sz > buf_sz) + break; + /* Immediately read the stack right after checking its size. */ + stack_ofs = 0; + if (syscall(__NR_access_hw_stacks, E2K_READ_PROCEDURE_STACK_EX, + &stack_ofs, buf, new_sz, NULL) != -1) + break; + if (errno != EAGAIN) + ABORT_ARG2("Cannot read procedure stack", + ": new_sz= %lu, errno= %d", (unsigned long)new_sz, errno); + } + return (size_t)new_sz; + } + + ptr_t GC_save_regs_in_stack(void) { + __asm__ __volatile__ ("flushr"); + return NULL; + } + + GC_INNER ptr_t GC_mmap_procedure_stack_buf(size_t aligned_sz) + { + void *buf = mmap(NULL, aligned_sz, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, 0 /* fd */, 0 /* offset */); + if (MAP_FAILED == buf) + ABORT_ARG2("Could not map memory for procedure stack", + ": requested %lu bytes, errno= %d", + (unsigned long)aligned_sz, errno); + return (ptr_t)buf; + } + + GC_INNER void GC_unmap_procedure_stack_buf(ptr_t buf, size_t sz) + { + if (munmap(buf, ROUNDUP_PAGESIZE(sz)) == -1) + ABORT_ARG1("munmap failed (for procedure stack space)", + ": errno= %d", errno); + } + +# ifdef THREADS + GC_INNER size_t GC_alloc_and_get_procedure_stack(ptr_t *pbuf) + { + /* TODO: support saving from non-zero ofs in stack */ + ptr_t buf = NULL; + size_t new_sz, buf_sz; + + GC_ASSERT(I_HOLD_LOCK()); + for (buf_sz = 0; ; buf_sz = new_sz) { + new_sz = GC_get_procedure_stack(buf, buf_sz); + if (new_sz <= buf_sz) break; + + if (EXPECT(buf != NULL, FALSE)) + GC_INTERNAL_FREE(buf); + buf = (ptr_t)GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE(new_sz, PTRFREE); + if (NULL == buf) + ABORT("Could not allocate memory for procedure stack"); + } + *pbuf = buf; + return new_sz; + } +# endif /* THREADS */ +#endif /* E2K */ + #if defined(MACOS) && defined(__MWERKS__) #if defined(POWERPC) @@ -232,6 +315,8 @@ # if defined(HAVE_PUSH_REGS) GC_push_regs(); +# elif defined(EMSCRIPTEN) + /* No-op, "registers" are pushed in GC_push_other_roots(). */ # else # if defined(UNIX_LIKE) && !defined(NO_GETCONTEXT) /* Older versions of Darwin seem to lack getcontext(). */ @@ -284,11 +369,14 @@ ABORT("feenableexcept failed"); # endif # endif /* GETCONTEXT_FPU_EXCMASK_BUG */ -# if defined(SPARC) || defined(IA64) +# if defined(E2K) || defined(IA64) || defined(SPARC) /* On a register window machine, we need to save register */ /* contents on the stack for this to work. This may already be */ /* subsumed by the getcontext() call. */ - GC_save_regs_ret_val = GC_save_regs_in_stack(); +# if defined(IA64) || defined(SPARC) + GC_save_regs_ret_val = +# endif + GC_save_regs_in_stack(); # endif if (NULL == context) /* getcontext failed */ # endif /* !NO_GETCONTEXT */ @@ -298,6 +386,9 @@ /* force callee-save registers and register windows onto */ /* the stack. */ __builtin_unwind_init(); +# elif defined(NO_CRT) && defined(MSWIN32) + CONTEXT ctx; + RtlCaptureContext(&ctx); # else /* Generic code */ /* The idea is due to Parag Patel at HP. */ @@ -334,4 +425,4 @@ GC_noop1(COVERT_DATAFLOW(&dummy)); } -#endif /* !SN_TARGET_ORBIS && !SN_TARGET_PSP2 */ +#endif /* !PLATFORM_MACH_DEP && !SN_TARGET_PSP2 */
View file
_service:tar_scm:gc-8.0.6.tar.gz/malloc.c -> _service:tar_scm:gc-8.2.2.tar.gz/malloc.c
Changed
@@ -31,10 +31,9 @@ return(TRUE); } -/* Allocate a large block of size lb bytes. */ -/* The block is not cleared. */ -/* Flags is 0 or IGNORE_OFF_PAGE. */ -/* EXTRA_BYTES were already added to lb. */ +/* Allocate a large block of size lb bytes. The block is not cleared. */ +/* flags argument should be 0 or IGNORE_OFF_PAGE. EXTRA_BYTES value */ +/* was already added to lb. */ GC_INNER ptr_t GC_alloc_large(size_t lb, int k, unsigned flags) { struct hblk * h; @@ -52,8 +51,11 @@ LOCK(); } /* Do our share of marking work */ - if (GC_incremental && !GC_dont_gc) + if (GC_incremental && !GC_dont_gc) { + ENTER_GC(); GC_collect_a_little_inner((int)n_blocks); + EXIT_GC(); + } h = GC_allochblk(lb, k, flags); # ifdef USE_MUNMAP if (0 == h) { @@ -242,7 +244,7 @@ DCL_LOCK_STATE; GC_ASSERT(k < MAXOBJKINDS); - if (EXPECT(GC_have_errors, FALSE)) + if (EXPECT(get_have_errors(), FALSE)) GC_print_all_errors(); GC_INVOKE_FINALIZERS(); GC_DBG_COLLECT_AT_MALLOC(lb); @@ -381,14 +383,11 @@ } GC_ASSERT(0 == op || GC_is_marked(op)); } else { - hdr * hhdr; - - op = GC_generic_malloc(lb, k); - if (NULL == op) - return NULL; + op = GC_generic_malloc(lb, k); + if (op /* != NULL */) { /* CPPCHECK */ + hdr * hhdr = HDR(op); GC_ASSERT(((word)op & (HBLKSIZE - 1)) == 0); /* large block */ - hhdr = HDR(op); /* We don't need the lock here, since we have an undisguised */ /* pointer. We do need to hold the lock while we adjust */ /* mark bits. */ @@ -401,6 +400,7 @@ # endif hhdr -> hb_n_marks = 1; UNLOCK(); + } } return op; } @@ -564,8 +564,13 @@ struct obj_kind * ok; DCL_LOCK_STATE; - if (p == 0) return; + if (p /* != NULL */) { + /* CPPCHECK */ + } else { /* Required by ANSI. It's not my fault ... */ + return; + } + # ifdef LOG_ALLOCS GC_log_printf("GC_free(%p) after GC #%lu\n", p, (unsigned long)GC_gc_no);
View file
_service:tar_scm:gc-8.0.6.tar.gz/mallocx.c -> _service:tar_scm:gc-8.2.2.tar.gz/mallocx.c
Changed
@@ -3,6 +3,7 @@ * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 2009-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -27,20 +28,14 @@ #include <stdio.h> #include <string.h> -#ifdef MSWINCE -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> -#else +#ifndef MSWINCE # include <errno.h> #endif /* Some externally visible but unadvertised variables to allow access to */ /* free lists from inlined allocators without including gc_priv.h */ /* or introducing dependencies on internal data structure layouts. */ -#include "gc_alloc_ptrs.h" +#include "private/gc_alloc_ptrs.h" void ** const GC_objfreelist_ptr = GC_objfreelist; void ** const GC_aobjfreelist_ptr = GC_aobjfreelist; void ** const GC_uobjfreelist_ptr = GC_uobjfreelist; @@ -84,6 +79,12 @@ struct hblk * h; hdr * hhdr; void * result; +# if defined(_FORTIFY_SOURCE) && defined(__GNUC__) && !defined(__clang__) + volatile /* Use cleared_p instead of p as a workaround to avoid */ + /* passing alloc_size(lb) attribute associated with p */ + /* to memset (including memset call inside GC_free). */ +# endif + word cleared_p = (word)p; size_t sz; /* Current size in bytes */ size_t orig_sz; /* Original sz in bytes */ int obj_kind; @@ -151,7 +152,7 @@ if (orig_sz > lb) { /* Clear unneeded part of object to avoid bogus pointer */ /* tracing. */ - BZERO(((ptr_t)p) + lb, orig_sz - lb); + BZERO((ptr_t)cleared_p + lb, orig_sz - lb); } return(p); } @@ -164,7 +165,7 @@ /* But this gives the client warning of imminent disaster. */ BCOPY(p, result, sz); # ifndef IGNORE_FREE - GC_free(p); + GC_free((ptr_t)cleared_p); # endif } return result; @@ -210,7 +211,7 @@ lb_rounded = GRANULES_TO_BYTES(lg); n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded); init = GC_obj_kindsk.ok_init; - if (EXPECT(GC_have_errors, FALSE)) + if (EXPECT(get_have_errors(), FALSE)) GC_print_all_errors(); GC_INVOKE_FINALIZERS(); GC_DBG_COLLECT_AT_MALLOC(lb); @@ -255,13 +256,13 @@ /* Increment GC_bytes_allocd from code that doesn't have direct access */ /* to GC_arrays. */ -GC_API void GC_CALL GC_incr_bytes_allocd(size_t n) +void GC_CALL GC_incr_bytes_allocd(size_t n) { GC_bytes_allocd += n; } /* The same for GC_bytes_freed. */ -GC_API void GC_CALL GC_incr_bytes_freed(size_t n) +void GC_CALL GC_incr_bytes_freed(size_t n) { GC_bytes_freed += n; } @@ -330,7 +331,7 @@ GC_ASSERT(k < MAXOBJKINDS); lw = BYTES_TO_WORDS(lb); lg = BYTES_TO_GRANULES(lb); - if (EXPECT(GC_have_errors, FALSE)) + if (EXPECT(get_have_errors(), FALSE)) GC_print_all_errors(); GC_INVOKE_FINALIZERS(); GC_DBG_COLLECT_AT_MALLOC(lb); @@ -443,7 +444,7 @@ /* Next try to allocate a new block worth of objects of this size. */ { struct hblk *h = GC_allochblk(lb, k, 0); - if (h != 0) { + if (h /* != NULL */) { /* CPPCHECK */ if (IS_UNCOLLECTABLE(k)) GC_set_hdr_marks(HDR(h)); GC_bytes_allocd += HBLKSIZE - HBLKSIZE % lb; # ifdef PARALLEL_MARK @@ -612,15 +613,17 @@ } #endif /* GC_REQUIRE_WCSDUP */ -GC_API void * GC_CALL GC_malloc_stubborn(size_t lb) -{ - return GC_malloc(lb); -} +#ifndef CPPCHECK + GC_API void * GC_CALL GC_malloc_stubborn(size_t lb) + { + return GC_malloc(lb); + } -GC_API void GC_CALL GC_change_stubborn(const void *p GC_ATTR_UNUSED) -{ - /* Empty. */ -} + GC_API void GC_CALL GC_change_stubborn(const void *p GC_ATTR_UNUSED) + { + /* Empty. */ + } +#endif /* !CPPCHECK */ GC_API void GC_CALL GC_end_stubborn_change(const void *p) {
View file
_service:tar_scm:gc-8.0.6.tar.gz/mark.c -> _service:tar_scm:gc-8.2.2.tar.gz/mark.c
Changed
@@ -2,6 +2,7 @@ * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. * Copyright (c) 2000 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -56,10 +57,6 @@ GC_noop_sink = x; } -/* mark_proc GC_mark_procsMAX_MARK_PROCS = {0} -- declared in gc_priv.h */ - -GC_INNER unsigned GC_n_mark_procs = GC_RESERVED_MARK_PROCS; - /* Initialize GC_obj_kinds properly and standard free lists properly. */ /* This must be done statically since they may be accessed before */ /* GC_init is called. */ @@ -84,8 +81,6 @@ # endif }; -GC_INNER unsigned GC_n_kinds = GC_N_KINDS_INITIAL_VALUE; - # ifndef INITIAL_MARK_STACK_SIZE # define INITIAL_MARK_STACK_SIZE (1*HBLKSIZE) /* INITIAL_MARK_STACK_SIZE * sizeof(mse) should be a */ @@ -103,25 +98,10 @@ /* Used for logging only. */ #endif -GC_INNER size_t GC_mark_stack_size = 0; - #ifdef PARALLEL_MARK - STATIC volatile AO_t GC_first_nonempty = 0; - /* Lowest entry on mark stack */ - /* that may be nonempty. */ - /* Updated only by initiating */ - /* thread. */ + GC_INNER GC_bool GC_parallel_mark_disabled = FALSE; #endif -GC_INNER mark_state_t GC_mark_state = MS_NONE; - -GC_INNER GC_bool GC_mark_stack_too_small = FALSE; - -static struct hblk * scan_ptr; - -STATIC GC_bool GC_objects_are_marked = FALSE; - /* Are there collectible marked objects in the heap? */ - /* Is a collection in progress? Note that this can return true in the */ /* non-incremental case, if a collection has been abandoned and the */ /* mark state is now MS_INVALID. */ @@ -130,7 +110,7 @@ return(GC_mark_state != MS_NONE); } -/* clear all mark bits in the header */ +/* Clear all mark bits in the header. */ GC_INNER void GC_clear_hdr_marks(hdr *hhdr) { size_t last_bit; @@ -171,9 +151,7 @@ # endif } -/* - * Clear all mark bits associated with block h. - */ +/* Clear all mark bits associated with block h. */ static void clear_marks_for_block(struct hblk *h, word dummy GC_ATTR_UNUSED) { hdr * hhdr = HDR(h); @@ -185,7 +163,7 @@ GC_clear_hdr_marks(hhdr); } -/* Slow but general routines for setting/clearing/asking about mark bits */ +/* Slow but general routines for setting/clearing/asking about mark bits. */ GC_API void GC_CALL GC_set_mark_bit(const void *p) { struct hblk *h = HBLKPTR(p); @@ -231,17 +209,15 @@ return (int)mark_bit_from_hdr(hhdr, bit_no); /* 0 or 1 */ } -/* - * Clear mark bits in all allocated heap blocks. This invalidates - * the marker invariant, and sets GC_mark_state to reflect this. - * (This implicitly starts marking to reestablish the invariant.) - */ +/* Clear mark bits in all allocated heap blocks. This invalidates the */ +/* marker invariant, and sets GC_mark_state to reflect this. (This */ +/* implicitly starts marking to reestablish the invariant.) */ GC_INNER void GC_clear_marks(void) { GC_apply_to_all_blocks(clear_marks_for_block, (word)0); GC_objects_are_marked = FALSE; GC_mark_state = MS_INVALID; - scan_ptr = 0; + GC_scan_ptr = NULL; } /* Initiate a garbage collection. Initiates a full collection if the */ @@ -253,28 +229,23 @@ if (GC_incremental) { # ifdef CHECKSUMS GC_read_dirty(FALSE); + GC_check_dirty(); # else GC_read_dirty(GC_mark_state == MS_INVALID); # endif } -# endif -# ifdef CHECKSUMS - if (GC_incremental) GC_check_dirty(); -# endif -# if !defined(GC_DISABLE_INCREMENTAL) GC_n_rescuing_pages = 0; # endif if (GC_mark_state == MS_NONE) { GC_mark_state = MS_PUSH_RESCUERS; } else if (GC_mark_state != MS_INVALID) { ABORT("Unexpected state"); - } /* else this is really a full collection, and mark */ - /* bits are invalid. */ - scan_ptr = 0; + } /* Else this is really a full collection, and mark bits are invalid. */ + GC_scan_ptr = NULL; } #ifdef PARALLEL_MARK - STATIC void GC_do_parallel_mark(void); /* initiate parallel marking. */ + STATIC void GC_do_parallel_mark(void); /* Initiate parallel marking. */ #endif /* PARALLEL_MARK */ #ifdef GC_DISABLE_INCREMENTAL @@ -324,8 +295,8 @@ MARK_FROM_MARK_STACK(); break; } else { - scan_ptr = GC_push_next_marked_dirty(scan_ptr); - if (scan_ptr == 0) { + GC_scan_ptr = GC_push_next_marked_dirty(GC_scan_ptr); + if (NULL == GC_scan_ptr) { # if !defined(GC_DISABLE_INCREMENTAL) GC_COND_LOG_PRINTF("Marked from %lu dirty pages\n", (unsigned long)GC_n_rescuing_pages); @@ -350,8 +321,8 @@ MARK_FROM_MARK_STACK(); break; } else { - scan_ptr = GC_push_next_marked_uncollectable(scan_ptr); - if (scan_ptr == 0) { + GC_scan_ptr = GC_push_next_marked_uncollectable(GC_scan_ptr); + if (NULL == GC_scan_ptr) { GC_push_roots(TRUE, cold_gc_frame); GC_objects_are_marked = TRUE; if (GC_mark_state != MS_INVALID) { @@ -363,15 +334,13 @@ case MS_ROOTS_PUSHED: # ifdef PARALLEL_MARK - /* In the incremental GC case, this currently doesn't */ - /* quite do the right thing, since it runs to */ - /* completion. On the other hand, starting a */ - /* parallel marker is expensive, so perhaps it is */ - /* the right thing? */ /* Eventually, incremental marking should run */ /* asynchronously in multiple threads, without grabbing */ /* the allocation lock. */ - if (GC_parallel) { + /* For now, parallel marker is disabled if there is */ + /* a chance that marking could be interrupted by */ + /* a client-supplied time limit or custom stop function. */ + if (GC_parallel && !GC_parallel_mark_disabled) { GC_do_parallel_mark(); GC_ASSERT((word)GC_mark_stack_top < (word)GC_first_nonempty); GC_mark_stack_top = GC_mark_stack - 1; @@ -406,7 +375,7 @@ MARK_FROM_MARK_STACK(); break; } - if (scan_ptr == 0 && GC_mark_state == MS_INVALID) { + if (NULL == GC_scan_ptr && GC_mark_state == MS_INVALID) { /* About to start a heap scan for marked objects. */ /* Mark stack is empty. OK to reallocate. */ if (GC_mark_stack_too_small) { @@ -414,8 +383,8 @@ } GC_mark_state = MS_PARTIALLY_INVALID; } - scan_ptr = GC_push_next_marked(scan_ptr); - if (scan_ptr == 0 && GC_mark_state == MS_PARTIALLY_INVALID) { + GC_scan_ptr = GC_push_next_marked(GC_scan_ptr); + if (NULL == GC_scan_ptr && GC_mark_state == MS_PARTIALLY_INVALID) { GC_push_roots(TRUE, cold_gc_frame); GC_objects_are_marked = TRUE; if (GC_mark_state != MS_INVALID) { @@ -519,7 +488,7 @@ # if GC_GNUC_PREREQ(4, 7) || GC_CLANG_PREREQ(3, 3) # pragma GCC diagnostic push /* Suppress "taking the address of label is non-standard" warning. */ -# if defined(__clang__) || GC_GNUC_PREREQ(6, 4) +# if defined(__clang__) || GC_GNUC_PREREQ(6, 0) # pragma GCC diagnostic ignored "-Wpedantic" # else /* GCC before ~4.8 does not accept "-Wpedantic" quietly. */ @@ -543,7 +512,7 @@ goto handle_thr_start; # endif rm_handler: - /* Uninstall the exception handler */ + /* Uninstall the exception handler. */ __asm__ __volatile__ ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev)); return ret_val; @@ -581,9 +550,9 @@ /* Warn about it at most once per collection. */ if (warned_gc_no != GC_gc_no) { - warned_gc_no = GC_gc_no; WARN("Caught ACCESS_VIOLATION in marker;" " memory mapping disappeared\n", 0); + warned_gc_no = GC_gc_no; } } # if (defined(MSWIN32) || defined(MSWINCE)) && defined(GC_WIN32_THREADS) \ @@ -598,8 +567,7 @@ STOP_WORLD(); # endif GC_invalidate_mark_state(); - scan_ptr = 0; - + GC_scan_ptr = NULL; ret_val = FALSE; goto rm_handler; /* Back to platform-specific code. */ } @@ -623,7 +591,7 @@ # else GC_mark_stack_too_small = TRUE; # endif - GC_COND_LOG_PRINTF("Mark stack overflow; current size = %lu entries\n", + GC_COND_LOG_PRINTF("Mark stack overflow; current size: %lu entries\n", (unsigned long)GC_mark_stack_size); return(msp - GC_MARK_STACK_DISCARDS); } @@ -646,7 +614,7 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, mse *mark_stack_limit) { - signed_word credit = HBLKSIZE; /* Remaining credit for marking work */ + signed_word credit = HBLKSIZE; /* Remaining credit for marking work. */ ptr_t current_p; /* Pointer to current candidate ptr. */ word current; /* Candidate pointer. */ ptr_t limit = 0; /* (Incl) limit of current candidate range. */ @@ -659,7 +627,7 @@ GC_objects_are_marked = TRUE; INIT_HDR_CACHE; -# ifdef OS2 /* Use untweaked version to circumvent compiler problem */ +# ifdef OS2 /* Use untweaked version to circumvent compiler problem. */ while ((word)mark_stack_top >= (word)mark_stack && credit >= 0) # else while (((((word)mark_stack_top - (word)mark_stack) | (word)credit) @@ -669,8 +637,8 @@ current_p = mark_stack_top -> mse_start; descr = mark_stack_top -> mse_descr.w; retry: - /* current_p and descr describe the current object. */ - /* *mark_stack_top is vacant. */ + /* current_p and descr describe the current object. */ + /* (*mark_stack_top) is vacant. */ /* The following is 0 only for small objects described by a simple */ /* length descriptor. For many applications this is the common */ /* case, so we try to detect it quickly. */ @@ -696,15 +664,15 @@ mark_stack_top -> mse_start = current_p; mark_stack_top -> mse_descr.w = new_size + sizeof(word); - /* makes sure we handle */ + /* Makes sure we handle */ /* misaligned pointers. */ mark_stack_top++; # ifdef ENABLE_TRACE if ((word)GC_trace_addr >= (word)current_p && (word)GC_trace_addr < (word)(current_p + descr)) { - GC_log_printf("GC #%u: large section; start %p, len %lu," + GC_log_printf("GC #%lu: large section; start %p, len %lu," " splitting (parallel) at %p\n", - (unsigned)GC_gc_no, (void *)current_p, + (unsigned long)GC_gc_no, (void *)current_p, (unsigned long)descr, (void *)(current_p + new_size)); } @@ -721,9 +689,9 @@ # ifdef ENABLE_TRACE if ((word)GC_trace_addr >= (word)current_p && (word)GC_trace_addr < (word)(current_p + descr)) { - GC_log_printf("GC #%u: large section; start %p, len %lu," + GC_log_printf("GC #%lu: large section; start %p, len %lu," " splitting at %p\n", - (unsigned)GC_gc_no, (void *)current_p, + (unsigned long)GC_gc_no, (void *)current_p, (unsigned long)descr, (void *)limit); } # endif @@ -737,32 +705,29 @@ if ((word)GC_trace_addr >= (word)current_p && (word)GC_trace_addr < (word)(current_p + WORDS_TO_BYTES(WORDSZ-2))) { - GC_log_printf("GC #%u: tracing from %p bitmap descr %lu\n", - (unsigned)GC_gc_no, (void *)current_p, + GC_log_printf("GC #%lu: tracing from %p bitmap descr %lu\n", + (unsigned long)GC_gc_no, (void *)current_p, (unsigned long)descr); } # endif /* ENABLE_TRACE */ descr &= ~GC_DS_TAGS; credit -= WORDS_TO_BYTES(WORDSZ/2); /* guess */ - while (descr != 0) { - if ((descr & SIGNB) != 0) { - current = *(word *)current_p; - FIXUP_POINTER(current); - if (current >= (word)least_ha && current < (word)greatest_ha) { + for (; descr != 0; descr <<= 1, current_p += sizeof(word)) { + if ((descr & SIGNB) == 0) continue; + LOAD_WORD_OR_CONTINUE(current, current_p); + FIXUP_POINTER(current); + if (current >= (word)least_ha && current < (word)greatest_ha) { PREFETCH((ptr_t)current); # ifdef ENABLE_TRACE if (GC_trace_addr == current_p) { - GC_log_printf("GC #%u: considering(3) %p -> %p\n", - (unsigned)GC_gc_no, (void *)current_p, + GC_log_printf("GC #%lu: considering(3) %p -> %p\n", + (unsigned long)GC_gc_no, (void *)current_p, (void *)current); } # endif /* ENABLE_TRACE */ PUSH_CONTENTS((ptr_t)current, mark_stack_top, mark_stack_limit, current_p); - } } - descr <<= 1; - current_p += sizeof(word); } continue; case GC_DS_PROC: @@ -771,8 +736,8 @@ if ((word)GC_trace_addr >= (word)current_p && GC_base(current_p) != 0 && GC_base(current_p) == GC_base(GC_trace_addr)) { - GC_log_printf("GC #%u: tracing from %p, proc descr %lu\n", - (unsigned)GC_gc_no, (void *)current_p, + GC_log_printf("GC #%lu: tracing from %p, proc descr %lu\n", + (unsigned long)GC_gc_no, (void *)current_p, (unsigned long)descr); } # endif /* ENABLE_TRACE */ @@ -805,13 +770,14 @@ } if (0 == descr) { /* Can happen either because we generated a 0 descriptor */ - /* or we saw a pointer to a free object. */ + /* or we saw a pointer to a free object. */ mark_stack_top--; continue; } goto retry; } - } else /* Small object with length descriptor */ { + } else { + /* Small object with length descriptor. */ mark_stack_top--; # ifndef SMALL_CONFIG if (descr < sizeof(word)) @@ -820,8 +786,8 @@ # ifdef ENABLE_TRACE if ((word)GC_trace_addr >= (word)current_p && (word)GC_trace_addr < (word)(current_p + descr)) { - GC_log_printf("GC #%u: small object; start %p, len %lu\n", - (unsigned)GC_gc_no, (void *)current_p, + GC_log_printf("GC #%lu: small object; start %p, len %lu\n", + (unsigned long)GC_gc_no, (void *)current_p, (unsigned long)descr); } # endif @@ -834,7 +800,7 @@ { # define PREF_DIST 4 -# ifndef SMALL_CONFIG +# if !defined(SMALL_CONFIG) && !defined(E2K) word deferred; /* Try to prefetch the next pointer to be examined ASAP. */ @@ -867,11 +833,11 @@ } # endif - while ((word)current_p <= (word)limit) { + for (; (word)current_p <= (word)limit; current_p += ALIGNMENT) { /* Empirically, unrolling this loop doesn't help a lot. */ /* Since PUSH_CONTENTS expands to a lot of code, */ /* we don't. */ - current = *(word *)current_p; + LOAD_WORD_OR_CONTINUE(current, current_p); FIXUP_POINTER(current); PREFETCH(current_p + PREF_DIST*CACHE_LINE_SIZE); if (current >= (word)least_ha && current < (word)greatest_ha) { @@ -880,25 +846,24 @@ PREFETCH((ptr_t)current); # ifdef ENABLE_TRACE if (GC_trace_addr == current_p) { - GC_log_printf("GC #%u: considering(1) %p -> %p\n", - (unsigned)GC_gc_no, (void *)current_p, + GC_log_printf("GC #%lu: considering(1) %p -> %p\n", + (unsigned long)GC_gc_no, (void *)current_p, (void *)current); } # endif /* ENABLE_TRACE */ PUSH_CONTENTS((ptr_t)current, mark_stack_top, mark_stack_limit, current_p); } - current_p += ALIGNMENT; } -# ifndef SMALL_CONFIG +# if !defined(SMALL_CONFIG) && !defined(E2K) /* We still need to mark the entry we previously prefetched. */ /* We already know that it passes the preliminary pointer */ /* validity test. */ # ifdef ENABLE_TRACE if (GC_trace_addr == current_p) { - GC_log_printf("GC #%u: considering(2) %p -> %p\n", - (unsigned)GC_gc_no, (void *)current_p, + GC_log_printf("GC #%lu: considering(2) %p -> %p\n", + (unsigned long)GC_gc_no, (void *)current_p, (void *)deferred); } # endif /* ENABLE_TRACE */ @@ -913,11 +878,11 @@ #ifdef PARALLEL_MARK -STATIC GC_bool GC_help_wanted = FALSE; /* Protected by mark lock */ +STATIC GC_bool GC_help_wanted = FALSE; /* Protected by mark lock. */ STATIC unsigned GC_helper_count = 0; /* Number of running helpers. */ - /* Protected by mark lock */ + /* Protected by mark lock. */ STATIC unsigned GC_active_count = 0; /* Number of active helpers. */ - /* Protected by mark lock */ + /* Protected by mark lock. */ /* May increase and decrease */ /* within each mark cycle. But */ /* once it returns to 0, it */ @@ -925,8 +890,6 @@ GC_INNER word GC_mark_no = 0; -static mse *main_local_mark_stack; - #ifdef LINT2 # define LOCAL_MARK_STACK_SIZE (HBLKSIZE / 8) #else @@ -942,22 +905,25 @@ { signed_word count; + GC_ASSERT(I_HOLD_LOCK()); if (GC_markers_m1 == 0) return; /* Allocate the local mark stack for the thread that holds GC lock. */ # ifndef CAN_HANDLE_FORK - GC_ASSERT(NULL == main_local_mark_stack); + GC_ASSERT(NULL == GC_main_local_mark_stack); # else - if (NULL == main_local_mark_stack) + if (NULL == GC_main_local_mark_stack) # endif { size_t bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(LOCAL_MARK_STACK_SIZE * sizeof(mse)); - main_local_mark_stack = (mse *)GET_MEM(bytes_to_get); - if (NULL == main_local_mark_stack) + + GC_ASSERT(GC_page_size != 0); + GC_main_local_mark_stack = (mse *)GET_MEM(bytes_to_get); + if (NULL == GC_main_local_mark_stack) ABORT("Insufficient memory for main local_mark_stack"); - GC_add_to_our_memory((ptr_t)main_local_mark_stack, bytes_to_get); + GC_add_to_our_memory((ptr_t)GC_main_local_mark_stack, bytes_to_get); } /* Reuse marker lock and builders count to synchronize */ @@ -975,7 +941,7 @@ /* Steal mark stack entries starting at mse low into mark stack local */ /* until we either steal mse high, or we have max entries. */ /* Return a pointer to the top of the local mark stack. */ -/* *next is replaced by a pointer to the next unscanned mark stack */ +/* (*next) is replaced by a pointer to the next unscanned mark stack */ /* entry. */ STATIC mse * GC_steal_mark_stack(mse * low, mse * high, mse * local, unsigned max, mse **next) @@ -1154,7 +1120,7 @@ if (0 == n_on_stack) { GC_active_count--; GC_ASSERT(GC_active_count <= GC_helper_count); - /* Other markers may redeposit objects */ + /* Other markers may redeposit objects */ /* on the stack. */ if (0 == GC_active_count) GC_notify_all_marker(); while (GC_active_count > 0 @@ -1181,7 +1147,7 @@ if (need_to_notify) GC_notify_all_marker(); return; } - /* else there's something on the stack again, or */ + /* Else there's something on the stack again, or */ /* another helper may push something. */ GC_active_count++; GC_ASSERT(GC_active_count > 0); @@ -1226,13 +1192,13 @@ GC_help_wanted = TRUE; GC_notify_all_marker(); /* Wake up potential helpers. */ - GC_mark_local(main_local_mark_stack, 0); + GC_mark_local(GC_main_local_mark_stack, 0); GC_help_wanted = FALSE; /* Done; clean up. */ while (GC_helper_count > 0) { GC_wait_marker(); } - /* GC_helper_count cannot be incremented while GC_help_wanted == FALSE */ + /* GC_helper_count cannot be incremented while not GC_help_wanted. */ GC_VERBOSE_LOG_PRINTF("Finished marking for mark phase number %lu\n", (unsigned long)GC_mark_no); GC_mark_no++; @@ -1270,27 +1236,6 @@ #endif /* PARALLEL_MARK */ -GC_INNER void GC_scratch_recycle_inner(void *ptr, size_t bytes) -{ - if (ptr != NULL) { - size_t page_offset = (word)ptr & (GC_page_size - 1); - size_t displ = 0; - size_t recycled_bytes; - - GC_ASSERT(bytes != 0); - GC_ASSERT(GC_page_size != 0); - /* TODO: Assert correct memory flags if GWW_VDB */ - if (page_offset != 0) - displ = GC_page_size - page_offset; - recycled_bytes = bytes > displ ? (bytes - displ) & ~(GC_page_size-1) : 0; - GC_COND_LOG_PRINTF("Recycle %lu/%lu scratch-allocated bytes at %p\n", - (unsigned long)recycled_bytes, (unsigned long)bytes, - ptr); - if (recycled_bytes > 0) - GC_add_to_heap((struct hblk *)((word)ptr + displ), recycled_bytes); - } -} - /* Allocate or reallocate space for mark stack of size n entries. */ /* May silently fail. */ static void alloc_mark_stack(size_t n) @@ -1312,7 +1257,7 @@ if (GC_mark_stack != NULL) { if (new_stack != 0) { if (recycle_old) { - /* Recycle old space */ + /* Recycle old space. */ GC_scratch_recycle_inner(GC_mark_stack, GC_mark_stack_size * sizeof(struct GC_ms_entry)); } @@ -1408,7 +1353,7 @@ if ((*dirty_fn)(h)) { if ((word)(GC_mark_stack_top - GC_mark_stack) > 3 * GC_mark_stack_size / 4) { - /* Danger of mark stack overflow */ + /* Danger of mark stack overflow. */ GC_push_all(h, top); return; } else { @@ -1439,6 +1384,37 @@ } } } + +# ifndef NO_VDB_FOR_STATIC_ROOTS +# ifndef PROC_VDB + /* Same as GC_page_was_dirty but h is allowed to point to some */ + /* page in the registered static roots only. Not used if */ + /* manual VDB is on. */ + STATIC GC_bool GC_static_page_was_dirty(struct hblk *h) + { + return get_pht_entry_from_index(GC_grungy_pages, PHT_HASH(h)); + } +# endif + + GC_INNER void GC_push_conditional_static(void *bottom, void *top, + GC_bool all) + { +# ifdef PROC_VDB + /* Just redirect to the generic routine because PROC_VDB */ + /* implementation gets the dirty bits map for the whole */ + /* process memory. */ + GC_push_conditional(bottom, top, all); +# else + if (all || !GC_is_vdb_for_static_roots()) { + GC_push_all(bottom, top); + } else { + GC_push_selected((ptr_t)bottom, (ptr_t)top, + GC_static_page_was_dirty); + } +# endif + } +# endif /* !NO_VDB_FOR_STATIC_ROOTS */ + #else GC_API void GC_CALL GC_push_conditional(void *bottom, void *top, int all GC_ATTR_UNUSED) @@ -1447,14 +1423,21 @@ } #endif /* GC_DISABLE_INCREMENTAL */ -#if defined(MSWIN32) || defined(MSWINCE) - void __cdecl GC_push_one(word p) -#else +#if defined(AMIGA) || defined(MACOS) || defined(GC_DARWIN_THREADS) void GC_push_one(word p) -#endif -{ + { GC_PUSH_ONE_STACK(p, MARKED_FROM_REGISTER); -} + } +#endif + +#ifdef GC_WIN32_THREADS + GC_INNER void GC_push_many_regs(const word *regs, unsigned count) + { + unsigned i; + for (i = 0; i < count; i++) + GC_PUSH_ONE_STACK(regsi, MARKED_FROM_REGISTER); + } +#endif GC_API struct GC_ms_entry * GC_CALL GC_mark_and_push(void *obj, mse *mark_stack_ptr, @@ -1483,10 +1466,12 @@ /* test, but we do not definitely know whether it is valid. */ /* Mark bits are NOT atomically updated. Thus this must be the */ /* only thread setting them. */ +GC_ATTR_NO_SANITIZE_ADDR +GC_INNER void # if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) - GC_INNER void GC_mark_and_push_stack(ptr_t p, ptr_t source) + GC_mark_and_push_stack(ptr_t p, ptr_t source) # else - GC_INNER void GC_mark_and_push_stack(ptr_t p) + GC_mark_and_push_stack(ptr_t p) # define source ((ptr_t)0) # endif { @@ -1495,12 +1480,13 @@ PREFETCH(p); GET_HDR(p, hhdr); - if (EXPECT(IS_FORWARDING_ADDR_OR_NIL(hhdr), FALSE) - && (NULL == hhdr + if (EXPECT(IS_FORWARDING_ADDR_OR_NIL(hhdr), FALSE)) { + if (NULL == hhdr || (r = (ptr_t)GC_base(p)) == NULL - || (hhdr = HDR(r)) == NULL)) { + || (hhdr = HDR(r)) == NULL) { GC_ADD_TO_BLACK_LIST_STACK(p, source); return; + } } if (EXPECT(HBLK_IS_FREE(hhdr), FALSE)) { GC_ADD_TO_BLACK_LIST_NORMAL(p, source); @@ -1535,8 +1521,6 @@ word arg2; } GC_trace_bufTRACE_ENTRIES = { { NULL, 0, 0, 0, 0 } }; -int GC_trace_buf_ptr = 0; - void GC_add_trace_entry(char *kind, word arg1, word arg2) { GC_trace_bufGC_trace_buf_ptr.kind = kind; @@ -1579,11 +1563,8 @@ #endif /* TRACE_BUF */ -/* - * A version of GC_push_all that treats all interior pointers as valid - * and scans the entire region immediately, in case the contents - * change. - */ +/* A version of GC_push_all that treats all interior pointers as valid */ +/* and scans the entire region immediately, in case the contents change.*/ GC_ATTR_NO_SANITIZE_ADDR GC_ATTR_NO_SANITIZE_MEMORY GC_ATTR_NO_SANITIZE_THREAD GC_API void GC_CALL GC_push_all_eager(void *bottom, void *top) { @@ -1597,13 +1578,14 @@ # define GC_least_plausible_heap_addr least_ha if (top == 0) return; - /* check all pointers in range and push if they appear */ - /* to be valid. */ + + /* Check all pointers in range and push if they appear to be valid. */ lim = t - 1 /* longword */; for (p = b; (word)p <= (word)lim; p = (word *)(((ptr_t)p) + ALIGNMENT)) { - REGISTER word q = *p; + REGISTER word q; + LOAD_WORD_OR_CONTINUE(q, p); GC_PUSH_ONE_STACK(q, p); } # undef GC_greatest_plausible_heap_addr @@ -1695,6 +1677,7 @@ #ifdef USE_PUSH_MARKED_ACCELERATORS /* Push all objects reachable from marked objects in the given block */ /* containing objects of size 1 granule. */ +GC_ATTR_NO_SANITIZE_THREAD STATIC void GC_push_marked1(struct hblk *h, hdr *hhdr) { word * mark_word_addr = &(hhdr->hb_marks0); @@ -1719,7 +1702,7 @@ p = (word *)(h->hb_body); plim = (word *)(((word)h) + HBLKSIZE); - /* go through all words in block */ + /* Go through all words in block. */ while ((word)p < (word)plim) { word mark_word = *mark_word_addr++; word *q = p; @@ -1748,6 +1731,7 @@ /* Push all objects reachable from marked objects in the given block */ /* of size 2 (granules) objects. */ +GC_ATTR_NO_SANITIZE_THREAD STATIC void GC_push_marked2(struct hblk *h, hdr *hhdr) { word * mark_word_addr = &(hhdr->hb_marks0); @@ -1769,7 +1753,7 @@ p = (word *)(h->hb_body); plim = (word *)(((word)h) + HBLKSIZE); - /* go through all words in block */ + /* Go through all words in block. */ while ((word)p < (word)plim) { word mark_word = *mark_word_addr++; word *q = p; @@ -1799,6 +1783,7 @@ /* of size 4 (granules) objects. */ /* There is a risk of mark stack overflow here. But we handle that. */ /* And only unmarked objects get pushed, so it's not very likely. */ +GC_ATTR_NO_SANITIZE_THREAD STATIC void GC_push_marked4(struct hblk *h, hdr *hhdr) { word * mark_word_addr = &(hhdr->hb_marks0); @@ -1820,7 +1805,7 @@ p = (word *)(h->hb_body); plim = (word *)(((word)h) + HBLKSIZE); - /* go through all words in block */ + /* Go through all words in block. */ while ((word)p < (word)plim) { word mark_word = *mark_word_addr++; word *q = p; @@ -1852,7 +1837,7 @@ #endif /* USE_PUSH_MARKED_ACCELERATORS */ -/* Push all objects reachable from marked objects in the given block */ +/* Push all objects reachable from marked objects in the given block. */ STATIC void GC_push_marked(struct hblk *h, hdr *hhdr) { word sz = hhdr -> hb_sz; @@ -1912,12 +1897,12 @@ /* Unconditionally mark from all objects which have not been reclaimed. */ /* This is useful in order to retain pointers which are reachable from */ /* the disclaim notifiers. */ -/* */ /* To determine whether an object has been reclaimed, we require that */ /* any live object has a non-zero as one of the two lowest bits of the */ /* first word. On the other hand, a reclaimed object is a members of */ /* free-lists, and thus contains a word-aligned next-pointer as the */ /* first word. */ + GC_ATTR_NO_SANITIZE_THREAD STATIC void GC_push_unconditionally(struct hblk *h, hdr *hhdr) { word sz = hhdr -> hb_sz; @@ -1987,7 +1972,7 @@ } #ifndef GC_DISABLE_INCREMENTAL - /* Identical to above, but mark only from dirty pages */ + /* Identical to above, but mark only from dirty pages. */ STATIC struct hblk * GC_push_next_marked_dirty(struct hblk *h) { hdr * hhdr = HDR(h);
View file
_service:tar_scm:gc-8.0.6.tar.gz/mark_rts.c -> _service:tar_scm:gc-8.2.2.tar.gz/mark_rts.c
Changed
@@ -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) 2009-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -36,9 +37,6 @@ int GC_no_dls = 0; /* Register dynamic library data segments. */ -static int n_root_sets = 0; - /* GC_static_roots0..n_root_sets) contains the valid root sets. */ - #if !defined(NO_DEBUGGING) || defined(GC_ASSERTIONS) /* Should return the same value as GC_root_size. */ GC_INNER word GC_compute_root_size(void) @@ -66,7 +64,7 @@ (void *)GC_static_rootsi.r_end, GC_static_rootsi.r_tmp ? " (temporary)" : ""); } - GC_printf("GC_root_size: %lu\n", (unsigned long)GC_root_size); + GC_printf("GC_root_size= %lu\n", (unsigned long)GC_root_size); if ((size = GC_compute_root_size()) != GC_root_size) GC_err_printf("GC_root_size incorrect!! Should be: %lu\n", @@ -271,15 +269,15 @@ n_root_sets++; } -static GC_bool roots_were_cleared = FALSE; - GC_API void GC_CALL GC_clear_roots(void) { DCL_LOCK_STATE; if (!EXPECT(GC_is_initialized, TRUE)) GC_init(); LOCK(); - roots_were_cleared = TRUE; +# ifdef THREADS + GC_roots_were_cleared = TRUE; +# endif n_root_sets = 0; GC_root_size = 0; # if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) @@ -341,11 +339,10 @@ } #endif -#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) - STATIC void GC_remove_roots_inner(ptr_t b, ptr_t e); +STATIC void GC_remove_roots_inner(ptr_t b, ptr_t e); - GC_API void GC_CALL GC_remove_roots(void *b, void *e) - { +GC_API void GC_CALL GC_remove_roots(void *b, void *e) +{ DCL_LOCK_STATE; /* Quick check whether has nothing to do */ @@ -356,27 +353,29 @@ LOCK(); GC_remove_roots_inner((ptr_t)b, (ptr_t)e); UNLOCK(); - } +} - /* Should only be called when the lock is held */ - STATIC void GC_remove_roots_inner(ptr_t b, ptr_t e) - { +/* Should only be called when the lock is held */ +STATIC void GC_remove_roots_inner(ptr_t b, ptr_t e) +{ int i; - GC_bool rebuild = FALSE; +# if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) + int old_n_roots = n_root_sets; +# endif for (i = 0; i < n_root_sets; ) { if ((word)GC_static_rootsi.r_start >= (word)b && (word)GC_static_rootsi.r_end <= (word)e) { GC_remove_root_at_pos(i); - rebuild = TRUE; } else { i++; } } - if (rebuild) +# if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) + if (n_root_sets < old_n_roots) GC_rebuild_root_index(); - } -#endif /* !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) */ +# endif +} #ifdef USE_PROC_FOR_LIBRARIES /* Exchange the elements of the roots table. Requires rebuild of */ @@ -502,8 +501,11 @@ GC_INNER ptr_t GC_approx_sp(void) { volatile word sp; -# if defined(S390) && !defined(CPPCHECK) && (__clang_major__ < 8) - /* Workaround a crash in SystemZTargetLowering of libLLVM-3.8. */ +# if ((defined(E2K) && defined(__clang__)) \ + || (defined(S390) && (__clang_major__ < 8))) && !defined(CPPCHECK) + /* Workaround some bugs in clang: */ + /* "undefined reference to llvm.frameaddress" error (clang-9/e2k); */ + /* a crash in SystemZTargetLowering of libLLVM-3.8 (S390). */ sp = (word)&sp; # elif defined(CPPCHECK) || (__GNUC__ >= 4 /* GC_GNUC_PREREQ(4, 0) */ \ && !defined(STACK_NOT_SCANNED)) @@ -532,7 +534,10 @@ -- address order. */ -STATIC size_t GC_excl_table_entries = 0;/* Number of entries in use. */ +GC_API void GC_CALL GC_clear_exclusion_table(void) +{ + GC_excl_table_entries = 0; +} /* Return the first exclusion range that includes an address >= start_addr */ /* Assumes the exclusion table contains at least one entry (namely the */ @@ -540,8 +545,10 @@ STATIC struct exclusion * GC_next_exclusion(ptr_t start_addr) { size_t low = 0; - size_t high = GC_excl_table_entries - 1; + size_t high; + GC_ASSERT(GC_excl_table_entries > 0); + high = GC_excl_table_entries - 1; while (high > low) { size_t mid = (low + high) >> 1; @@ -617,18 +624,14 @@ # define GC_PUSH_CONDITIONAL(b, t, all) \ (GC_parallel \ ? GC_push_conditional_eager(b, t, all) \ - : GC_push_conditional(b, t, all)) -#elif defined(GC_DISABLE_INCREMENTAL) -# define GC_PUSH_CONDITIONAL(b, t, all) GC_push_all(b, t) + : GC_push_conditional_static(b, t, all)) #else -# define GC_PUSH_CONDITIONAL(b, t, all) GC_push_conditional(b, t, all) - /* Do either of GC_push_all or GC_push_selected */ - /* depending on the third arg. */ +# define GC_PUSH_CONDITIONAL(b, t, all) GC_push_conditional_static(b, t, all) #endif /* Invoke push_conditional on ranges that are not excluded. */ STATIC void GC_push_conditional_with_exclusions(ptr_t bottom, ptr_t top, - GC_bool all GC_ATTR_UNUSED) + GC_bool all) { while ((word)bottom < (word)top) { struct exclusion *next = GC_next_exclusion(bottom); @@ -645,12 +648,15 @@ } } -#ifdef IA64 +#if defined(E2K) || defined(IA64) /* Similar to GC_push_all_stack_sections() but for IA-64 registers store. */ GC_INNER void GC_push_all_register_sections(ptr_t bs_lo, ptr_t bs_hi, int eager, struct GC_traced_stack_sect_s *traced_stack_sect) { - while (traced_stack_sect != NULL) { +# ifdef E2K + (void)traced_stack_sect; /* TODO: Not implemented yet */ +# else + while (traced_stack_sect != NULL) { ptr_t frame_bs_lo = traced_stack_sect -> backing_store_end; GC_ASSERT((word)frame_bs_lo <= (word)bs_hi); if (eager) { @@ -660,7 +666,8 @@ } bs_hi = traced_stack_sect -> saved_backing_store_ptr; traced_stack_sect = traced_stack_sect -> prev; - } + } +# endif GC_ASSERT((word)bs_lo <= (word)bs_hi); if (eager) { GC_push_all_eager(bs_lo, bs_hi); @@ -668,7 +675,7 @@ GC_push_all_stack(bs_lo, bs_hi); } } -#endif /* IA64 */ +#endif /* E2K || IA64 */ #ifdef THREADS @@ -776,27 +783,19 @@ #endif /* !THREADS */ - /* Push enough of the current stack eagerly to */ - /* ensure that callee-save registers saved in */ - /* GC frames are scanned. */ - /* In the non-threads case, schedule entire */ - /* stack for scanning. */ - /* The second argument is a pointer to the */ - /* (possibly null) thread context, for */ - /* (currently hypothetical) more precise */ - /* stack scanning. */ -/* - * In the absence of threads, push the stack contents. - * In the presence of threads, push enough of the current stack - * to ensure that callee-save registers saved in collector frames have been - * seen. - * TODO: Merge it with per-thread stuff. - */ +/* Push enough of the current stack eagerly to ensure that callee-save */ +/* registers saved in GC frames are scanned. In the non-threads case, */ +/* schedule entire stack for scanning. The 2nd argument is a pointer */ +/* to the (possibly null) thread context, for (currently hypothetical) */ +/* more precise stack scanning. In the presence of threads, push */ +/* enough of the current stack to ensure that callee-save registers */ +/* saved in collector frames have been seen. */ +/* TODO: Merge it with per-thread stuff. */ STATIC void GC_push_current_stack(ptr_t cold_gc_frame, void * context GC_ATTR_UNUSED) { # if defined(THREADS) - if (0 == cold_gc_frame) return; + /* cold_gc_frame is non-NULL. */ # ifdef STACK_GROWS_DOWN GC_push_all_eager(GC_approx_sp(), cold_gc_frame); /* For IA64, the register stack backing store is handled */ @@ -808,12 +807,12 @@ GC_push_all_stack_part_eager_sections(GC_approx_sp(), GC_stackbottom, cold_gc_frame, GC_traced_stack_sect); # ifdef IA64 - /* We also need to push the register stack backing store. */ - /* This should really be done in the same way as the */ - /* regular stack. For now we fudge it a bit. */ - /* Note that the backing store grows up, so we can't use */ - /* GC_push_all_stack_partially_eager. */ - { + /* We also need to push the register stack backing store. */ + /* This should really be done in the same way as the */ + /* regular stack. For now we fudge it a bit. */ + /* Note that the backing store grows up, so we can't use */ + /* GC_push_all_stack_partially_eager. */ + { ptr_t bsp = GC_save_regs_ret_val; ptr_t cold_gc_bs_pointer = bsp - 2048; if (GC_all_interior_pointers @@ -834,34 +833,26 @@ } /* All values should be sufficiently aligned that we */ /* don't have to worry about the boundary. */ - } + } +# elif defined(E2K) + /* We also need to push procedure stack store. */ + /* Procedure stack grows up. */ + { + ptr_t bs_lo; + size_t stack_size; + + GET_PROCEDURE_STACK_LOCAL(&bs_lo, &stack_size); + GC_push_all_register_sections(bs_lo, bs_lo + stack_size, + TRUE /* eager */, + GC_traced_stack_sect); + FREE_PROCEDURE_STACK_LOCAL(bs_lo, stack_size); + } # endif # endif /* !THREADS */ } GC_INNER void (*GC_push_typed_structures)(void) = 0; - /* Push GC internal roots. These are normally */ - /* included in the static data segment, and */ - /* Thus implicitly pushed. But we must do this */ - /* explicitly if normal root processing is */ - /* disabled. */ -/* - * Push GC internal roots. Only called if there is some reason to believe - * these would not otherwise get registered. - */ -STATIC void GC_push_gc_structures(void) -{ -# ifndef GC_NO_FINALIZATION - GC_push_finalizer_structures(); -# endif -# if defined(THREADS) - GC_push_thread_structures(); -# endif - if( GC_push_typed_structures ) - GC_push_typed_structures(); -} - GC_INNER void GC_cond_register_dynamic_libraries(void) { # if (defined(DYNAMIC_LOADING) && !defined(MSWIN_XBOX1)) \ @@ -876,85 +867,91 @@ STATIC void GC_push_regs_and_stack(ptr_t cold_gc_frame) { +# ifdef THREADS + if (NULL == cold_gc_frame) + return; /* GC_push_all_stacks should push registers and stack */ +# endif GC_with_callee_saves_pushed(GC_push_current_stack, cold_gc_frame); } -/* - * Call the mark routines (GC_push_one for a single pointer, - * GC_push_conditional on groups of pointers) on every top level - * accessible pointer. - * If all is FALSE, arrange to push only possibly altered values. - * Cold_gc_frame is an address inside a GC frame that - * remains valid until all marking is complete. - * A zero value indicates that it's OK to miss some - * register values. - */ +/* Call the mark routines (GC_push_one for a single pointer, */ +/* GC_push_conditional on groups of pointers) on every top level */ +/* accessible pointer. If all is false, arrange to push only possibly */ +/* altered values. Cold_gc_frame is an address inside a GC frame that */ +/* remains valid until all marking is complete; a NULL value indicates */ +/* that it is OK to miss some register values. Called with the */ +/* allocation lock held. */ GC_INNER void GC_push_roots(GC_bool all, ptr_t cold_gc_frame GC_ATTR_UNUSED) { int i; unsigned kind; - /* - * Next push static data. This must happen early on, since it's - * not robust against mark stack overflow. - */ - /* Re-register dynamic libraries, in case one got added. */ - /* There is some argument for doing this as late as possible, */ - /* especially on win32, where it can change asynchronously. */ - /* In those cases, we do it here. But on other platforms, it's */ - /* not safe with the world stopped, so we do it earlier. */ -# if !defined(REGISTER_LIBRARIES_EARLY) - GC_cond_register_dynamic_libraries(); -# endif - - /* Mark everything in static data areas */ - for (i = 0; i < n_root_sets; i++) { - GC_push_conditional_with_exclusions( + /* Next push static data. This must happen early on, since it is */ + /* not robust against mark stack overflow. */ + /* Re-register dynamic libraries, in case one got added. */ + /* There is some argument for doing this as late as possible, */ + /* especially on win32, where it can change asynchronously. */ + /* In those cases, we do it here. But on other platforms, it's */ + /* not safe with the world stopped, so we do it earlier. */ +# if !defined(REGISTER_LIBRARIES_EARLY) + GC_cond_register_dynamic_libraries(); +# endif + + /* Mark everything in static data areas. */ + for (i = 0; i < n_root_sets; i++) { + GC_push_conditional_with_exclusions( GC_static_rootsi.r_start, GC_static_rootsi.r_end, all); - } - - /* Mark all free list header blocks, if those were allocated from */ - /* the garbage collected heap. This makes sure they don't */ - /* disappear if we are not marking from static data. It also */ - /* saves us the trouble of scanning them, and possibly that of */ - /* marking the freelists. */ - for (kind = 0; kind < GC_n_kinds; kind++) { - void *base = GC_base(GC_obj_kindskind.ok_freelist); - if (0 != base) { - GC_set_mark_bit(base); - } - } - - /* Mark from GC internal roots if those might otherwise have */ - /* been excluded. */ - if (GC_no_dls || roots_were_cleared) { - GC_push_gc_structures(); - } - - /* Mark thread local free lists, even if their mark */ - /* descriptor excludes the link field. */ - /* If the world is not stopped, this is unsafe. It is */ - /* also unnecessary, since we will do this again with the */ - /* world stopped. */ -# if defined(THREAD_LOCAL_ALLOC) - if (GC_world_stopped) GC_mark_thread_local_free_lists(); -# endif - - /* - * Now traverse stacks, and mark from register contents. - * These must be done last, since they can legitimately overflow - * the mark stack. - * This is usually done by saving the current context on the - * stack, and then just tracing from the stack. - */ -# ifndef STACK_NOT_SCANNED - GC_push_regs_and_stack(cold_gc_frame); -# endif - - if (GC_push_other_roots != 0) (*GC_push_other_roots)(); + } + + /* Mark all free list header blocks, if those were allocated from */ + /* the garbage collected heap. This makes sure they don't */ + /* disappear if we are not marking from static data. It also */ + /* saves us the trouble of scanning them, and possibly that of */ + /* marking the freelists. */ + for (kind = 0; kind < GC_n_kinds; kind++) { + void *base = GC_base(GC_obj_kindskind.ok_freelist); + if (base != NULL) { + GC_set_mark_bit(base); + } + } + + /* Mark from GC internal roots if those might otherwise have */ + /* been excluded. */ +# ifndef GC_NO_FINALIZATION + GC_push_finalizer_structures(); +# endif +# ifdef THREADS + if (GC_no_dls || GC_roots_were_cleared) + GC_push_thread_structures(); +# endif + if (GC_push_typed_structures) + GC_push_typed_structures(); + + /* Mark thread local free lists, even if their mark */ + /* descriptor excludes the link field. */ + /* If the world is not stopped, this is unsafe. It is */ + /* also unnecessary, since we will do this again with the */ + /* world stopped. */ +# if defined(THREAD_LOCAL_ALLOC) + if (GC_world_stopped) + GC_mark_thread_local_free_lists(); +# endif + + /* Now traverse stacks, and mark from register contents. */ + /* These must be done last, since they can legitimately */ + /* overflow the mark stack. This is usually done by saving */ + /* the current context on the stack, and then just tracing */ + /* from the stack. */ +# ifndef STACK_NOT_SCANNED + GC_push_regs_and_stack(cold_gc_frame); +# endif + + if (GC_push_other_roots != 0) { /* 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. */ + (*GC_push_other_roots)(); + } }
View file
_service:tar_scm:gc-8.0.6.tar.gz/misc.c -> _service:tar_scm:gc-8.2.2.tar.gz/misc.c
Changed
@@ -2,6 +2,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. + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -27,21 +28,17 @@ # include <sys/syscall.h> #endif -#if defined(MSWIN32) || defined(MSWINCE) \ - || (defined(CYGWIN32) && defined(GC_READ_ENV_FILE)) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> -#endif - -#if defined(UNIX_LIKE) || defined(CYGWIN32) || defined(SYMBIAN) +#if defined(UNIX_LIKE) || defined(CYGWIN32) || defined(SYMBIAN) \ + || (defined(CONSOLE_LOG) && defined(MSWIN32)) # include <fcntl.h> # include <sys/types.h> # include <sys/stat.h> #endif +#if defined(CONSOLE_LOG) && defined(MSWIN32) && !defined(__GNUC__) +# include <io.h> +#endif + #ifdef NONSTOP # include <floss.h> #endif @@ -52,7 +49,7 @@ GC_INNER PCR_Th_ML GC_allocate_ml; # elif defined(SN_TARGET_PSP2) GC_INNER WapiMutex GC_allocate_ml_PSP2 = { 0, NULL }; -# elif defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) +# elif defined(GC_DEFN_ALLOCATE_ML) || defined(SN_TARGET_PS3) # include <pthread.h> GC_INNER pthread_mutex_t GC_allocate_ml; # endif @@ -78,6 +75,10 @@ GC_FAR struct _GC_arrays GC_arrays /* = { 0 } */; +GC_INNER unsigned GC_n_mark_procs = GC_RESERVED_MARK_PROCS; + +GC_INNER unsigned GC_n_kinds = GC_N_KINDS_INITIAL_VALUE; + GC_INNER GC_bool GC_debugging_started = FALSE; /* defined here so we don't have to load dbg_mlc.o */ @@ -189,8 +190,6 @@ # endif #elif !defined(HAVE_NO_FORK) - - /* Same as above but with GC_CALL calling conventions. */ GC_API void GC_CALL GC_atfork_prepare(void) { # ifdef THREADS @@ -314,7 +313,11 @@ } /* Make sure the recursive call is not a tail call, and the bzero */ /* call is not recognized as dead code. */ - GC_noop1(COVERT_DATAFLOW(dummy)); +# if defined(CPPCHECK) + GC_noop1(dummy0); +# else + GC_noop1(COVERT_DATAFLOW(dummy)); +# endif return(arg); } # endif /* !ASM_CLEAR_CODE */ @@ -479,6 +482,11 @@ return (size_t)(GC_heapsize - GC_unmapped_bytes); } +GC_API size_t GC_CALL GC_get_obtained_from_os_bytes(void) +{ + return (size_t)GC_our_mem_bytes; +} + GC_API size_t GC_CALL GC_get_free_bytes(void) { /* ignore the memory space returned to OS */ @@ -553,6 +561,7 @@ (word)GC_bytes_found : 0; pstats->reclaimed_bytes_before_gc = GC_reclaimed_bytes_before_gc; pstats->expl_freed_bytes_since_gc = GC_bytes_freed; /* since gc-7.7 */ + pstats->obtained_from_os_bytes = GC_our_mem_bytes; /* since gc-8.2 */ } # include <string.h> /* for memset() */ @@ -661,6 +670,8 @@ unsigned len; DWORD nBytesRead; TCHAR path_MAX_PATH + 0x10; /* buffer for path + ext */ + size_t bytes_to_get; + len = (unsigned)GetModuleFileName(NULL /* hModule */, path, _MAX_PATH + 1); /* If GetModuleFileName() has failed then len is 0. */ @@ -681,11 +692,14 @@ } /* At this execution point, GC_setpagesize() and GC_init_win32() */ /* must already be called (for GET_MEM() to work correctly). */ - content = (char *)GET_MEM(ROUNDUP_PAGESIZE_IF_MMAP((size_t)len + 1)); + GC_ASSERT(GC_page_size != 0); + bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP((size_t)len + 1); + content = (char *)GET_MEM(bytes_to_get); if (content == NULL) { CloseHandle(hFile); return; /* allocation failure */ } + GC_add_to_our_memory(content, bytes_to_get); ofs = 0; nBytesRead = (DWORD)-1L; /* Last ReadFile() call should clear nBytesRead on success. */ @@ -695,8 +709,10 @@ break; } CloseHandle(hFile); - if (ofs != len || nBytesRead != 0) + if (ofs != len || nBytesRead != 0) { + /* TODO: recycle content */ return; /* read operation is failed - ignoring the file content */ + } contentofs = '\0'; while (ofs-- > 0) { if (contentofs == '\r' || contentofs == '\n') @@ -714,7 +730,8 @@ { char *p; char *end_of_content; - unsigned namelen; + size_t namelen; + # ifndef NO_GETENV p = getenv(name); /* try the standard getenv() first */ if (p != NULL) @@ -745,8 +762,8 @@ return GC_is_initialized; } -#if (defined(MSWIN32) || defined(MSWINCE) || defined(MSWIN_XBOX1)) \ - && defined(THREADS) +#if defined(GC_WIN32_THREADS) \ + && ((defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE)) GC_INNER CRITICAL_SECTION GC_write_cs; #endif @@ -805,19 +822,20 @@ #if !defined(OS2) && !defined(MACOS) && !defined(GC_ANDROID_LOG) \ && !defined(NN_PLATFORM_CTR) && !defined(NINTENDO_SWITCH) \ - && !defined(MSWIN32) && !defined(MSWINCE) + && (!defined(MSWIN32) || defined(CONSOLE_LOG)) && !defined(MSWINCE) STATIC int GC_stdout = GC_DEFAULT_STDOUT_FD; STATIC int GC_stderr = GC_DEFAULT_STDERR_FD; STATIC int GC_log = GC_DEFAULT_STDERR_FD; - GC_API void GC_CALL GC_set_log_fd(int fd) - { - GC_log = fd; - } +# ifndef MSWIN32 + GC_API void GC_CALL GC_set_log_fd(int fd) + { + GC_log = fd; + } +# endif #endif -#if defined(MSWIN32) && !defined(MSWINRT_FLAVOR) && !defined(MSWIN_XBOX1) \ - && !defined(SMALL_CONFIG) +#ifdef MSGBOX_ON_ERROR STATIC void GC_win32_MessageBoxA(const char *msg, const char *caption, unsigned flags) { @@ -836,7 +854,7 @@ } # endif } -#endif /* MSWIN32 */ +#endif /* MSGBOX_ON_ERROR */ #if defined(THREADS) && defined(UNIX_LIKE) && !defined(NO_GETCONTEXT) static void callee_saves_pushed_dummy_fn(ptr_t data GC_ATTR_UNUSED, @@ -970,8 +988,9 @@ /* else */ InitializeCriticalSection(&GC_allocate_ml); } # endif -# endif /* GC_WIN32_THREADS */ -# if (defined(MSWIN32) || defined(MSWINCE)) && defined(THREADS) +# endif /* GC_WIN32_THREADS && !GC_PTHREADS */ +# if defined(GC_WIN32_THREADS) \ + && ((defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE)) InitializeCriticalSection(&GC_write_cs); # endif GC_setpagesize(); @@ -995,6 +1014,7 @@ # endif # endif # if ((defined(UNIX_LIKE) && !defined(GC_ANDROID_LOG)) \ + || (defined(CONSOLE_LOG) && defined(MSWIN32)) \ || defined(CYGWIN32) || defined(SYMBIAN)) && !defined(SMALL_CONFIG) { char * file_name = TRUSTED_STRING(GETENV("GC_LOG_FILE")); @@ -1005,7 +1025,11 @@ if (0 != file_name) # endif { - int log_d = open(file_name, O_CREAT | O_WRONLY | O_APPEND, 0644); +# if defined(_MSC_VER) + int log_d = _open(file_name, O_CREAT | O_WRONLY | O_APPEND); +# else + int log_d = open(file_name, O_CREAT | O_WRONLY | O_APPEND, 0644); +# endif if (log_d < 0) { GC_err_printf("Failed to open %s as log file\n", file_name); } else { @@ -1056,7 +1080,11 @@ GC_all_interior_pointers = 1; } if (0 != GETENV("GC_DONT_GC")) { - GC_dont_gc = 1; +# ifdef LINT2 + GC_disable(); +# else + GC_dont_gc = 1; +# endif } if (0 != GETENV("GC_PRINT_BACK_HEIGHT")) { GC_print_back_height = TRUE; @@ -1186,12 +1214,6 @@ /* entirety as part of the root set. This will grow them to */ /* maximum size, and is generally not desirable. */ # endif -# if defined(SEARCH_FOR_DATA_START) - GC_init_linux_data_start(); -# endif -# if defined(NETBSD) && defined(__ELF__) - GC_init_netbsd_elf(); -# endif # if !defined(THREADS) || defined(GC_PTHREADS) \ || defined(NN_PLATFORM_CTR) || defined(NINTENDO_SWITCH) \ || defined(GC_WIN32_THREADS) || defined(GC_SOLARIS_THREADS) @@ -1227,6 +1249,22 @@ # ifndef THREADS GC_ASSERT(!((word)GC_stackbottom HOTTER_THAN (word)GC_approx_sp())); # endif + GC_init_headers(); +# if defined(GC_ASSERTIONS) && defined(GC_ALWAYS_MULTITHREADED) \ + && (defined(SEARCH_FOR_DATA_START) || defined(NETBSD)) + LOCK(); /* just to set GC_lock_holder */ +# endif +# ifdef SEARCH_FOR_DATA_START + /* For MPROTECT_VDB, the temporary fault handler should be */ + /* installed first, before the write fault one in GC_dirty_init. */ + if (GC_REGISTER_MAIN_STATIC_DATA()) GC_init_linux_data_start(); +# elif defined(NETBSD) && defined(__ELF__) + if (GC_REGISTER_MAIN_STATIC_DATA()) GC_init_netbsd_elf(); +# endif +# if defined(GC_ASSERTIONS) && defined(GC_ALWAYS_MULTITHREADED) \ + && (defined(SEARCH_FOR_DATA_START) || defined(NETBSD)) + UNLOCK(); +# endif # ifndef GC_DISABLE_INCREMENTAL if (GC_incremental || 0 != GETENV("GC_ENABLE_INCREMENTAL")) { # if defined(BASE_ATOMIC_OPS_EMULATED) || defined(CHECKSUMS) \ @@ -1251,7 +1289,7 @@ /* Add initial guess of root sets. Do this first, since sbrk(0) */ /* might be used. */ if (GC_REGISTER_MAIN_STATIC_DATA()) GC_register_data_segments(); - GC_init_headers(); + GC_bl_init(); GC_mark_init(); { @@ -1305,16 +1343,13 @@ # endif GC_is_initialized = TRUE; # if defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) - GC_thr_init(); -# ifdef PARALLEL_MARK - /* Actually start helper threads. */ -# if defined(GC_ASSERTIONS) && defined(GC_ALWAYS_MULTITHREADED) - UNLOCK(); -# endif - GC_start_mark_threads_inner(); -# if defined(GC_ASSERTIONS) && defined(GC_ALWAYS_MULTITHREADED) - LOCK(); -# endif +# if defined(LINT2) \ + && !(defined(GC_ASSERTIONS) && defined(GC_ALWAYS_MULTITHREADED)) + LOCK(); + GC_thr_init(); + UNLOCK(); +# else + GC_thr_init(); # endif # endif COND_DUMP; @@ -1343,9 +1378,8 @@ # if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC) \ || (defined(GC_ALWAYS_MULTITHREADED) && defined(GC_WIN32_THREADS) \ && !defined(GC_NO_THREADS_DISCOVERY)) - /* Make sure marker threads are started and thread local */ - /* allocation is initialized, in case we didn't get */ - /* called from GC_init_parallel. */ + /* Make sure thread local allocation is initialized, in */ + /* case we did not get called from GC_init_parallel(). */ GC_init_parallel(); # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ @@ -1411,37 +1445,40 @@ GC_init(); } -#if defined(THREADS) - GC_API void GC_CALL GC_start_mark_threads(void) - { -# if defined(PARALLEL_MARK) && defined(CAN_HANDLE_FORK) \ - && !defined(THREAD_SANITIZER) - /* TSan does not support threads creation in the child process. */ +GC_API void GC_CALL GC_start_mark_threads(void) +{ +# ifdef PARALLEL_MARK IF_CANCEL(int cancel_state;) + DCL_LOCK_STATE; DISABLE_CANCEL(cancel_state); + LOCK(); GC_start_mark_threads_inner(); + UNLOCK(); RESTORE_CANCEL(cancel_state); # else /* No action since parallel markers are disabled (or no POSIX fork). */ GC_ASSERT(I_DONT_HOLD_LOCK()); # endif - } -#endif +} GC_API void GC_CALL GC_deinit(void) { if (GC_is_initialized) { /* Prevent duplicate resource close. */ GC_is_initialized = FALSE; -# if defined(THREADS) && (defined(MSWIN32) || defined(MSWINCE)) - DeleteCriticalSection(&GC_write_cs); - DeleteCriticalSection(&GC_allocate_ml); +# if defined(GC_WIN32_THREADS) && (defined(MSWIN32) || defined(MSWINCE)) +# if !defined(CONSOLE_LOG) || defined(MSWINCE) + DeleteCriticalSection(&GC_write_cs); +# endif +# ifndef GC_PTHREADS + DeleteCriticalSection(&GC_allocate_ml); +# endif # endif } } -#if defined(MSWIN32) || defined(MSWINCE) +#if (defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE) # if defined(_MSC_VER) && defined(_DEBUG) && !defined(MSWINCE) # include <crtdbg.h> @@ -1551,7 +1588,11 @@ # else TCHAR *logPath; - BOOL appendToFile = FALSE; +# if defined(NO_GETENV_WIN32) && defined(CPPCHECK) +# define appendToFile FALSE +# else + BOOL appendToFile = FALSE; +# endif # if !defined(NO_GETENV_WIN32) || !defined(OLD_WIN32_LOG_FILE) TCHAR pathBuf_MAX_PATH + 0x10; /* buffer for path + ext */ @@ -1596,6 +1637,7 @@ /* Seek to file end (ignoring any error) */ } # endif +# undef appendToFile # endif return hFile; } @@ -1634,7 +1676,7 @@ # endif } res = WriteFile(GC_log, buf, (DWORD)len, &written, NULL); -# if defined(_MSC_VER) && defined(_DEBUG) +# if defined(_MSC_VER) && defined(_DEBUG) && !defined(NO_CRT) # ifdef MSWINCE /* There is no CrtDbgReport() in WinCE */ { @@ -1699,28 +1741,29 @@ # define WRITE(level, buf, unused_len) \ __android_log_write(level, GC_ANDROID_LOG_TAG, buf) -# elif defined(NN_PLATFORM_CTR) - int n3ds_log_write(const char* text, int length); -# define WRITE(level, buf, len) n3ds_log_write(buf, len) -# elif defined(NINTENDO_SWITCH) - int switch_log_write(const char* text, int length); -# define WRITE(level, buf, len) switch_log_write(buf, len) +#elif defined(NN_PLATFORM_CTR) + int n3ds_log_write(const char* text, int length); +# define WRITE(level, buf, len) n3ds_log_write(buf, len) + +#elif defined(NINTENDO_SWITCH) + int switch_log_write(const char* text, int length); +# define WRITE(level, buf, len) switch_log_write(buf, len) #else -# if !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) -# if !defined(AMIGA) && !defined(MSWIN_XBOX1) \ +# if !defined(GC_NO_TYPES) && !defined(SN_TARGET_PSP2) +# if !defined(AMIGA) && !defined(MSWIN32) && !defined(MSWIN_XBOX1) \ && !defined(__CC_ARM) # include <unistd.h> # endif # if !defined(ECOS) && !defined(NOSYS) # include <errno.h> # endif -# endif /* !SN_TARGET_ORBIS && !SN_TARGET_PSP2 */ +# endif /* !GC_NO_TYPES && !SN_TARGET_PSP2 */ STATIC int GC_write(int fd, const char *buf, size_t len) { -# if defined(ECOS) || defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PSP2) \ +# if defined(ECOS) || defined(PLATFORM_WRITE) || defined(SN_TARGET_PSP2) \ || defined(NOSYS) # ifdef ECOS /* FIXME: This seems to be defined nowhere at present. */ @@ -1738,6 +1781,9 @@ # ifdef GC_SOLARIS_THREADS int result = syscall(SYS_write, fd, buf + bytes_written, len - bytes_written); +# elif defined(_MSC_VER) + int result = _write(fd, buf + bytes_written, + (unsigned)(len - bytes_written)); # else int result = write(fd, buf + bytes_written, len - bytes_written); # endif @@ -1756,7 +1802,7 @@ } # define WRITE(f, buf, len) GC_write(f, buf, len) -#endif /* !MSWIN32 && !OS2 && !MACOS && !GC_ANDROID_LOG */ +#endif /* !MSWINCE && !OS2 && !MACOS && !GC_ANDROID_LOG */ #define BUFSZ 1024 @@ -1801,7 +1847,7 @@ /* Ignore errors silently. */ # else if (WRITE(GC_stdout, buf, strlen(buf)) < 0 -# if defined(CYGWIN32) +# if defined(CYGWIN32) || (defined(CONSOLE_LOG) && defined(MSWIN32)) && GC_stdout != GC_DEFAULT_STDOUT_FD # endif ) { @@ -1828,7 +1874,7 @@ (void)WRITE(GC_log, buf, strlen(buf)); # else if (WRITE(GC_log, buf, strlen(buf)) < 0 -# if defined(CYGWIN32) +# if defined(CYGWIN32) || (defined(CONSOLE_LOG) && defined(MSWIN32)) && GC_log != GC_DEFAULT_STDERR_FD # endif ) { @@ -1929,7 +1975,7 @@ # endif if (msg != NULL) { -# if defined(MSWIN32) && !defined(MSWINRT_FLAVOR) && !defined(MSWIN_XBOX1) +# ifdef MSGBOX_ON_ERROR GC_win32_MessageBoxA(msg, "Fatal error in GC", MB_ICONERROR | MB_OK); /* Also duplicate msg to GC log file. */ # endif @@ -1938,8 +1984,8 @@ /* Avoid calling GC_err_printf() here, as GC_on_abort() could be */ /* called from it. Note 1: this is not an atomic output. */ /* Note 2: possible write errors are ignored. */ -# if defined(THREADS) && defined(GC_ASSERTIONS) \ - && (defined(MSWIN32) || defined(MSWINCE)) +# if defined(GC_WIN32_THREADS) && defined(GC_ASSERTIONS) \ + && ((defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE)) if (!GC_write_disabled) # endif { @@ -2036,6 +2082,7 @@ { unsigned result = GC_n_kinds; + GC_ASSERT(NONNULL_ARG_NOT_NULL(fl)); GC_ASSERT(adjust == FALSE || adjust == TRUE); /* If an object is not needed to be cleared (when moved to the */ /* free list) then its descriptor should be zero to denote */ @@ -2044,6 +2091,7 @@ GC_ASSERT(clear == TRUE || (descr == 0 && adjust == FALSE && clear == FALSE)); if (result < MAXOBJKINDS) { + GC_ASSERT(result > 0); GC_n_kinds++; GC_obj_kindsresult.ok_freelist = fl; GC_obj_kindsresult.ok_reclaim_list = 0; @@ -2119,6 +2167,8 @@ base.reg_base = (void *)GC_save_regs_in_stack(); /* Unnecessarily flushes register stack, */ /* but that probably doesn't hurt. */ +# elif defined(E2K) + base.reg_base = NULL; /* not used by GC currently */ # endif result = fn(&base, arg); /* Strongly discourage the compiler from treating the above */ @@ -2144,7 +2194,7 @@ struct GC_traced_stack_sect_s stacksect; GC_ASSERT(GC_is_initialized); - /* Adjust our stack base value (this could happen if */ + /* Adjust our stack bottom pointer (this could happen if */ /* GC_get_main_stack_base() is unimplemented or broken for */ /* the platform). */ if ((word)GC_stackbottom HOTTER_THAN (word)(&stacksect)) @@ -2198,9 +2248,11 @@ GC_blocked_sp = GC_save_regs_in_stack(); # else GC_blocked_sp = (ptr_t) &d; /* save approx. sp */ -# endif -# ifdef IA64 - GC_blocked_register_sp = GC_save_regs_in_stack(); +# ifdef IA64 + GC_blocked_register_sp = GC_save_regs_in_stack(); +# elif defined(E2K) + (void)GC_save_regs_in_stack(); +# endif # endif d -> client_data = (d -> fn)(d -> client_data); @@ -2216,6 +2268,32 @@ GC_blocked_sp = NULL; } + GC_API void GC_CALL GC_set_stackbottom(void *gc_thread_handle, + const struct GC_stack_base *sb) + { + GC_ASSERT(sb -> mem_base != NULL); + GC_ASSERT(NULL == gc_thread_handle || &GC_stackbottom == gc_thread_handle); + GC_ASSERT(NULL == GC_blocked_sp + && NULL == GC_traced_stack_sect); /* for now */ + (void)gc_thread_handle; + + GC_stackbottom = (char *)sb->mem_base; +# ifdef IA64 + GC_register_stackbottom = (ptr_t)sb->reg_base; +# endif + } + + GC_API void * GC_CALL GC_get_my_stackbottom(struct GC_stack_base *sb) + { + GC_ASSERT(GC_is_initialized); + sb -> mem_base = GC_stackbottom; +# ifdef IA64 + sb -> reg_base = GC_register_stackbottom; +# elif defined(E2K) + sb -> reg_base = NULL; +# endif + return &GC_stackbottom; /* gc_thread_handle */ + } #endif /* !THREADS */ GC_API void * GC_CALL GC_do_blocking(GC_fn_type fn, void * client_data) @@ -2252,7 +2330,7 @@ } # ifndef NO_CLOCK /* Note that the time is wrapped in ~49 days if sizeof(long)==4. */ - GC_printf("Time since GC init: %lu msecs\n", + GC_printf("Time since GC init: %lu ms\n", MS_TIME_DIFF(current_time, GC_init_time)); # endif @@ -2298,10 +2376,21 @@ #ifdef THREADS GC_API int GC_CALL GC_get_parallel(void) { - /* GC_parallel is initialized at start-up. */ return GC_parallel; } + GC_API void GC_CALL GC_alloc_lock(void) + { + DCL_LOCK_STATE; + LOCK(); + } + + GC_API void GC_CALL GC_alloc_unlock(void) + { + /* no DCL_LOCK_STATE */ + UNLOCK(); + } + GC_INNER GC_on_thread_event_proc GC_on_thread_event = 0; GC_API void GC_CALL GC_set_on_thread_event(GC_on_thread_event_proc fn)
View file
_service:tar_scm:gc-8.0.6.tar.gz/missing -> _service:tar_scm:gc-8.2.2.tar.gz/missing
Changed
@@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2013-10-28.13; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ exit $st fi -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software program_details () { @@ -207,9 +207,9 @@ exit $st # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End:
View file
_service:tar_scm:gc-8.0.6.tar.gz/new_hblk.c -> _service:tar_scm:gc-8.2.2.tar.gz/new_hblk.c
Changed
@@ -42,7 +42,7 @@ p1 = 0; p2 = (word)p; p3 = 0; - }; + } return((ptr_t)(p-2)); } @@ -62,7 +62,7 @@ p0 = (word)(p-4); p1 = 0; CLEAR_DOUBLE(p+2); - }; + } return((ptr_t)(p-4)); } @@ -78,7 +78,7 @@ for (; (word)p < (word)lim; p += 4) { p0 = (word)(p-2); p2 = (word)p; - }; + } return((ptr_t)(p-2)); } @@ -95,7 +95,7 @@ GC_PREFETCH_FOR_WRITE((ptr_t)(p + 64)); p0 = (word)(p-4); p4 = (word)p; - }; + } return((ptr_t)(p-4)); } #endif /* !SMALL_CONFIG */ @@ -174,6 +174,7 @@ GC_bool clear = GC_obj_kindskind.ok_init; GC_STATIC_ASSERT((sizeof (struct hblk)) == HBLKSIZE); + GC_ASSERT(I_HOLD_LOCK()); if (GC_debugging_started) clear = TRUE;
View file
_service:tar_scm:gc-8.0.6.tar.gz/obj_map.c -> _service:tar_scm:gc-8.2.2.tar.gz/obj_map.c
Changed
@@ -35,6 +35,7 @@ GC_INNER void GC_register_displacement_inner(size_t offset) { + GC_ASSERT(I_HOLD_LOCK()); if (offset >= VALID_OFFSET_SZ) { ABORT("Bad argument to GC_register_displacement"); } @@ -46,8 +47,7 @@ #ifdef MARK_BIT_PER_GRANULE /* Add a heap block map for objects of size granules to obj_map. */ - /* Return FALSE on failure. */ - /* A size of 0 granules is used for large objects. */ + /* A size of 0 is used for large objects. Return FALSE on failure. */ GC_INNER GC_bool GC_add_map_entry(size_t granules) { unsigned displ;
View file
_service:tar_scm:gc-8.0.6.tar.gz/os_dep.c -> _service:tar_scm:gc-8.2.2.tar.gz/os_dep.c
Changed
@@ -3,6 +3,7 @@ * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -50,16 +51,6 @@ # undef GC_AMIGA_DEF #endif -#if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> - /* It's not clear this is completely kosher under Cygwin. But it */ - /* allows us to get a working GC_get_stack_base. */ -#endif - #ifdef MACOS # include <Processes.h> #endif @@ -76,6 +67,10 @@ # include <sys/types.h> # include <sys/mman.h> # include <sys/stat.h> +#endif + +#if defined(ADD_HEAP_GUARD_PAGES) || defined(LINUX_STACKBOTTOM) \ + || defined(MMAP_SUPPORTED) || defined(NEED_PROC_MAPS) # include <errno.h> #endif @@ -109,34 +104,42 @@ #define IGNORE_PAGES_EXECUTABLE 1 /* Undefined on GC_pages_executable real use. */ -#ifdef NEED_PROC_MAPS -/* We need to parse /proc/self/maps, either to find dynamic libraries, */ -/* and/or to find the register backing store base (IA64). Do it once */ -/* here. */ +#if ((defined(LINUX_STACKBOTTOM) || defined(NEED_PROC_MAPS) \ + || defined(PROC_VDB) || defined(SOFT_VDB)) && !defined(PROC_READ)) \ + || defined(CPPCHECK) +# define PROC_READ read + /* Should probably call the real read, if read is wrapped. */ +#endif -/* Repeatedly perform a read call until the buffer is filled or */ -/* we encounter EOF. */ -STATIC ssize_t GC_repeat_read(int fd, char *buf, size_t count) -{ -# define READ read +#if defined(LINUX_STACKBOTTOM) || defined(NEED_PROC_MAPS) + /* Repeatedly perform a read call until the buffer is filled */ + /* up, or we encounter EOF or an error. */ + STATIC ssize_t GC_repeat_read(int fd, char *buf, size_t count) + { size_t num_read = 0; ASSERT_CANCEL_DISABLED(); while (num_read < count) { - ssize_t result = READ(fd, buf + num_read, count - num_read); + ssize_t result = PROC_READ(fd, buf + num_read, count - num_read); if (result < 0) return result; if (result == 0) break; num_read += result; } -# undef READ return num_read; -} + } +#endif /* LINUX_STACKBOTTOM || NEED_PROC_MAPS */ + +#ifdef NEED_PROC_MAPS +/* We need to parse /proc/self/maps, either to find dynamic libraries, */ +/* and/or to find the register backing store base (IA64). Do it once */ +/* here. */ #ifdef THREADS /* Determine the length of a file by incrementally reading it into a */ /* buffer. This would be silly to use it on a file supporting lseek, */ /* but Linux /proc files usually do not. */ + /* As of Linux 4.15.0, lseek(SEEK_END) fails for /proc/self/maps. */ STATIC size_t GC_get_file_len(int f) { size_t total = 0; @@ -145,7 +148,7 @@ char bufGET_FILE_LEN_BUF_SZ; do { - result = read(f, buf, GET_FILE_LEN_BUF_SZ); + result = PROC_READ(f, buf, sizeof(buf)); if (result == -1) return 0; total += result; } while (result > 0); @@ -164,10 +167,8 @@ #endif /* THREADS */ /* Copy the contents of /proc/self/maps to a buffer in our address */ -/* space. Return the address of the buffer, or zero on failure. */ -/* This code could be simplified if we could determine its size ahead */ -/* of time. */ -GC_INNER char * GC_get_maps(void) +/* space. Return the address of the buffer. */ +GC_INNER const char * GC_get_maps(void) { ssize_t result; static char *maps_buf = NULL; @@ -185,19 +186,19 @@ /* threads that we already think of as dead release their */ /* stacks. And there is no easy way to read the entire */ /* file atomically. This is arguably a misfeature of the */ - /* /proc/.../maps interface. */ + /* /proc/self/maps interface. */ /* Since we expect the file can grow asynchronously in rare */ /* cases, it should suffice to first determine */ - /* the size (using lseek or read), and then to reread the */ - /* file. If the size is inconsistent we have to retry. */ + /* the size (using read), and then to reread the file. */ + /* If the size is inconsistent we have to retry. */ /* This only matters with threads enabled, and if we use */ /* this to locate roots (not the default). */ # ifdef THREADS /* Determine the initial size of /proc/self/maps. */ - /* Note that lseek doesn't work, at least as of 2.6.15. */ maps_size = GC_get_maps_len(); - if (0 == maps_size) return 0; + if (0 == maps_size) + ABORT("Cannot determine length of /proc/self/maps"); # else maps_size = 4000; /* Guess */ # endif @@ -209,35 +210,47 @@ int f; while (maps_size >= maps_buf_sz) { - GC_scratch_recycle_no_gww(maps_buf, maps_buf_sz); +# ifdef LINT2 + /* Workaround passing tainted maps_buf to a tainted sink. */ + GC_noop1((word)maps_buf); +# else + GC_scratch_recycle_no_gww(maps_buf, maps_buf_sz); +# endif /* Grow only by powers of 2, since we leak "too small" buffers.*/ while (maps_size >= maps_buf_sz) maps_buf_sz *= 2; maps_buf = GC_scratch_alloc(maps_buf_sz); + if (NULL == maps_buf) + ABORT_ARG1("Insufficient space for /proc/self/maps buffer", + ", %lu bytes requested", (unsigned long)maps_buf_sz); # ifdef THREADS /* Recompute initial length, since we allocated. */ /* This can only happen a few times per program */ /* execution. */ maps_size = GC_get_maps_len(); - if (0 == maps_size) return 0; + if (0 == maps_size) + ABORT("Cannot determine length of /proc/self/maps"); # endif - if (maps_buf == 0) return 0; } GC_ASSERT(maps_buf_sz >= maps_size + 1); f = open("/proc/self/maps", O_RDONLY); - if (-1 == f) return 0; + if (-1 == f) + ABORT_ARG1("Cannot open /proc/self/maps", + ": errno= %d", errno); # ifdef THREADS old_maps_size = maps_size; # endif maps_size = 0; do { result = GC_repeat_read(f, maps_buf, maps_buf_sz-1); - if (result <= 0) - break; + if (result < 0) { + ABORT_ARG1("Failed to read /proc/self/maps", + ": errno= %d", errno); + } maps_size += result; } while ((size_t)result == maps_buf_sz-1); close(f); - if (result <= 0) - return 0; + if (0 == maps_size) + ABORT("Empty /proc/self/maps"); # ifdef THREADS if (maps_size > old_maps_size) { /* This might be caused by e.g. thread creation. */ @@ -268,40 +281,41 @@ * anywhere, which is safer anyway. */ -/* Assign various fields of the first line in buf_ptr to (*start), */ +/* Assign various fields of the first line in maps_ptr to (*start), */ /* (*end), (*prot), (*maj_dev) and (*mapping_name). mapping_name may */ /* be NULL. (*prot) and (*mapping_name) are assigned pointers into the */ /* original buffer. */ #if (defined(DYNAMIC_LOADING) && defined(USE_PROC_FOR_LIBRARIES)) \ || defined(IA64) || defined(INCLUDE_LINUX_THREAD_DESCR) \ - || defined(REDIRECT_MALLOC) - GC_INNER char *GC_parse_map_entry(char *buf_ptr, ptr_t *start, ptr_t *end, - char **prot, unsigned int *maj_dev, - char **mapping_name) + || (defined(REDIRECT_MALLOC) && defined(GC_LINUX_THREADS)) + GC_INNER const char *GC_parse_map_entry(const char *maps_ptr, + ptr_t *start, ptr_t *end, + const char **prot, unsigned *maj_dev, + const char **mapping_name) { - unsigned char *start_start, *end_start, *maj_dev_start; - unsigned char *p; /* unsigned for isspace, isxdigit */ + const unsigned char *start_start, *end_start, *maj_dev_start; + const unsigned char *p; /* unsigned for isspace, isxdigit */ - if (buf_ptr == NULL || *buf_ptr == '\0') { + if (maps_ptr == NULL || *maps_ptr == '\0') { return NULL; } - p = (unsigned char *)buf_ptr; + p = (const unsigned char *)maps_ptr; while (isspace(*p)) ++p; start_start = p; GC_ASSERT(isxdigit(*start_start)); - *start = (ptr_t)strtoul((char *)start_start, (char **)&p, 16); + *start = (ptr_t)strtoul((const char *)start_start, (char **)&p, 16); GC_ASSERT(*p=='-'); ++p; end_start = p; GC_ASSERT(isxdigit(*end_start)); - *end = (ptr_t)strtoul((char *)end_start, (char **)&p, 16); + *end = (ptr_t)strtoul((const char *)end_start, (char **)&p, 16); GC_ASSERT(isspace(*p)); while (isspace(*p)) ++p; GC_ASSERT(*p == 'r' || *p == '-'); - *prot = (char *)p; + *prot = (const char *)p; /* Skip past protection field to offset field */ while (!isspace(*p)) ++p; while (isspace(*p)) p++; @@ -311,16 +325,14 @@ while (isspace(*p)) p++; maj_dev_start = p; GC_ASSERT(isxdigit(*maj_dev_start)); - *maj_dev = strtoul((char *)maj_dev_start, NULL, 16); + *maj_dev = strtoul((const char *)maj_dev_start, NULL, 16); - if (mapping_name == 0) { - while (*p && *p++ != '\n'); - } else { + if (mapping_name != NULL) { while (*p && *p != '\n' && *p != '/' && *p != '') p++; - *mapping_name = (char *)p; - while (*p && *p++ != '\n'); + *mapping_name = (const char *)p; } - return (char *)p; + while (*p && *p++ != '\n'); + return (const char *)p; } #endif /* REDIRECT_MALLOC || DYNAMIC_LOADING || IA64 || ... */ @@ -332,51 +344,46 @@ GC_INNER GC_bool GC_enclosing_mapping(ptr_t addr, ptr_t *startp, ptr_t *endp) { - char *prot; + const char *prot; ptr_t my_start, my_end; unsigned int maj_dev; - char *maps = GC_get_maps(); - char *buf_ptr = maps; + const char *maps_ptr = GC_get_maps(); - if (0 == maps) return(FALSE); for (;;) { - buf_ptr = GC_parse_map_entry(buf_ptr, &my_start, &my_end, - &prot, &maj_dev, 0); + maps_ptr = GC_parse_map_entry(maps_ptr, &my_start, &my_end, + &prot, &maj_dev, 0); + if (NULL == maps_ptr) break; - if (buf_ptr == NULL) return FALSE; - if (prot1 == 'w' && maj_dev == 0) { - if ((word)my_end > (word)addr && (word)my_start <= (word)addr) { + if (prot1 == 'w' && maj_dev == 0 + && (word)my_end > (word)addr && (word)my_start <= (word)addr) { *startp = my_start; *endp = my_end; return TRUE; - } } } return FALSE; } #endif /* IA64 || INCLUDE_LINUX_THREAD_DESCR */ -#if defined(REDIRECT_MALLOC) +#if defined(REDIRECT_MALLOC) && defined(GC_LINUX_THREADS) /* Find the text(code) mapping for the library whose name, after */ /* stripping the directory part, starts with nm. */ GC_INNER GC_bool GC_text_mapping(char *nm, ptr_t *startp, ptr_t *endp) { size_t nm_len = strlen(nm); - char *prot; - char *map_path; + const char *prot, *map_path; ptr_t my_start, my_end; unsigned int maj_dev; - char *maps = GC_get_maps(); - char *buf_ptr = maps; + const char *maps_ptr = GC_get_maps(); - if (0 == maps) return(FALSE); for (;;) { - buf_ptr = GC_parse_map_entry(buf_ptr, &my_start, &my_end, - &prot, &maj_dev, &map_path); + maps_ptr = GC_parse_map_entry(maps_ptr, &my_start, &my_end, + &prot, &maj_dev, &map_path); + if (NULL == maps_ptr) break; - if (buf_ptr == NULL) return FALSE; if (prot0 == 'r' && prot1 == '-' && prot2 == 'x') { - char *p = map_path; + const char *p = map_path; + /* Set p to point just past last slash, if any. */ while (*p != '\0' && *p != '\n' && *p != ' ' && *p != '\t') ++p; while (*p != '/' && (word)p >= (word)map_path) --p; @@ -520,23 +527,22 @@ static struct sigaction old_segv_act; STATIC JMP_BUF GC_jmp_buf_openbsd; -# ifdef THREADS + STATIC void GC_fault_handler_openbsd(int sig GC_ATTR_UNUSED) + { + LONGJMP(GC_jmp_buf_openbsd, 1); + } + +# ifdef GC_OPENBSD_UTHREADS # include <sys/syscall.h> EXTERN_C_BEGIN extern sigset_t __syscall(quad_t, ...); EXTERN_C_END -# endif /* Don't use GC_find_limit() because siglongjmp() outside of the */ /* signal handler by-passes our userland pthreads lib, leaving */ /* SIGSEGV and SIGPROF masked. Instead, use this custom one that */ /* works-around the issues. */ - STATIC void GC_fault_handler_openbsd(int sig GC_ATTR_UNUSED) - { - LONGJMP(GC_jmp_buf_openbsd, 1); - } - /* Return the first non-addressable location > p or bound. */ /* Requires the allocation lock. */ STATIC ptr_t GC_find_limit_openbsd(ptr_t p, ptr_t bound) @@ -579,13 +585,15 @@ sigaction(SIGSEGV, &old_segv_act, 0); return(result); } +# endif /* GC_OPENBSD_UTHREADS */ + + static volatile int firstpass; /* Return first addressable location > p or bound. */ /* Requires the allocation lock. */ STATIC ptr_t GC_skip_hole_openbsd(ptr_t p, ptr_t bound) { static volatile ptr_t result; - static volatile int firstpass; struct sigaction act; word pgsz = (word)sysconf(_SC_PAGESIZE); @@ -716,7 +724,7 @@ GC_INNER void GC_setpagesize(void) { GetSystemInfo(&GC_sysinfo); -# if defined(CYGWIN32) && defined(USE_MUNMAP) +# if defined(CYGWIN32) && (defined(MPROTECT_VDB) || defined(USE_MUNMAP)) /* Allocations made with mmap() are aligned to the allocation */ /* granularity, which (at least on 64-bit Windows OS) is not the */ /* same as the page size. Probably a separate variable could */ @@ -819,7 +827,8 @@ #else /* !MSWIN32 */ GC_INNER void GC_setpagesize(void) { -# if defined(MPROTECT_VDB) || defined(PROC_VDB) || defined(USE_MMAP) +# if defined(MPROTECT_VDB) || defined(PROC_VDB) || defined(SOFT_VDB) \ + || defined(USE_MMAP) GC_page_size = (size_t)GETPAGESIZE(); # if !defined(CPPCHECK) if (0 == GC_page_size) @@ -875,7 +884,7 @@ || defined(HAIKU) || defined(HURD) || defined(FREEBSD) \ || defined(NETBSD) static struct sigaction old_segv_act; -# if defined(_sigargs) /* !Irix6.x */ \ +# if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) \ || defined(HURD) || defined(NETBSD) || defined(FREEBSD) static struct sigaction old_bus_act; # endif @@ -890,7 +899,7 @@ { # if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \ || defined(HAIKU) || defined(HURD) || defined(FREEBSD) \ - || defined(NETBSD) + || defined(NETBSD) || defined(OPENBSD) struct sigaction act; act.sa_handler = h; @@ -912,7 +921,8 @@ # else (void) sigaction(SIGSEGV, &act, &old_segv_act); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HURD) || defined(NETBSD) || defined(FREEBSD) + || defined(HPUX) || defined(HURD) || defined(NETBSD) \ + || defined(FREEBSD) /* Under Irix 5.x or HP/UX, we may get SIGBUS. */ /* Pthreads doesn't exist under Irix 5.x, so we */ /* don't have to worry in the threads case. */ @@ -955,10 +965,11 @@ { # if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \ || defined(HAIKU) || defined(HURD) || defined(FREEBSD) \ - || defined(NETBSD) + || defined(NETBSD) || defined(OPENBSD) (void) sigaction(SIGSEGV, &old_segv_act, 0); # if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \ - || defined(HURD) || defined(NETBSD) + || defined(HPUX) || defined(HURD) || defined(NETBSD) \ + || defined(FREEBSD) (void) sigaction(SIGBUS, &old_bus_act, 0); # endif # else @@ -1108,9 +1119,7 @@ result = backing_store_base_from_proc(); if (0 == result) { result = (ptr_t)GC_find_limit(GC_save_regs_in_stack(), FALSE); - /* Now seems to work better than constant displacement */ - /* heuristic used in 6.X versions. The latter seems to */ - /* fail for 2.6 kernels. */ + /* This works better than a constant displacement heuristic. */ } return result; } @@ -1118,19 +1127,14 @@ STATIC ptr_t GC_linux_main_stack_base(void) { - /* We read the stack base value from /proc/self/stat. We do this */ + /* We read the stack bottom value from /proc/self/stat. We do this */ /* using direct I/O system calls in order to avoid calling malloc */ /* in case REDIRECT_MALLOC is defined. */ -# ifndef STAT_READ - /* Also defined in pthread_support.c. */ # define STAT_BUF_SIZE 4096 -# define STAT_READ read -# endif - /* Should probably call the real read, if read is wrapped. */ char stat_bufSTAT_BUF_SIZE; int f; word result; - int i, buf_offset = 0, len; + ssize_t i, buf_offset = 0, len; /* First try the easy way. This should work for glibc 2.2 */ /* This fails in a prelinked ("prelink" command) executable */ @@ -1156,10 +1160,14 @@ # endif } # endif + f = open("/proc/self/stat", O_RDONLY); - if (f < 0) - ABORT("Couldn't read /proc/self/stat"); - len = STAT_READ(f, stat_buf, STAT_BUF_SIZE); + if (-1 == f) + ABORT_ARG1("Could not open /proc/self/stat", ": errno= %d", errno); + len = GC_repeat_read(f, stat_buf, sizeof(stat_buf)); + if (len < 0) + ABORT_ARG1("Failed to read /proc/self/stat", + ": errno= %d", errno); close(f); /* Skip the required number of fields. This number is hopefully */ @@ -1185,7 +1193,8 @@ result = (word)STRTOULL(&stat_bufbuf_offset, NULL, 10); if (result < 0x100000 || (result & (sizeof(word) - 1)) != 0) - ABORT("Absurd stack bottom value"); + ABORT_ARG1("Absurd stack bottom value", + ": 0x%lx", (unsigned long)result); return (ptr_t)result; } #endif /* LINUX_STACKBOTTOM */ @@ -1225,6 +1234,23 @@ return (ptr_t)GC_get_main_symbian_stack_base(); } # define GET_MAIN_STACKBASE_SPECIAL +#elif defined(EMSCRIPTEN) +# include <emscripten.h> + + static void* emscripten_stack_base; + + static void scan_stack_cb(void *begin, void *end) + { + (void)begin; + emscripten_stack_base = end; + } + + ptr_t GC_get_main_stack_base(void) + { + emscripten_scan_stack(scan_stack_cb); + return (ptr_t)emscripten_stack_base; + } +# define GET_MAIN_STACKBASE_SPECIAL #elif !defined(AMIGA) && !defined(HAIKU) && !defined(OS2) \ && !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) \ && !defined(GC_OPENBSD_THREADS) \ @@ -1279,8 +1305,8 @@ # ifdef STACKBOTTOM result = STACKBOTTOM; # else -# define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1) # ifdef HEURISTIC1 +# define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1) # ifdef STACK_GROWS_DOWN result = (ptr_t)(((word)GC_approx_sp() + STACKBOTTOM_ALIGNMENT_M1) & ~STACKBOTTOM_ALIGNMENT_M1); @@ -1324,7 +1350,9 @@ result = (ptr_t)(signed_word)(-sizeof(ptr_t)); # endif # endif - GC_ASSERT((word)GC_approx_sp() HOTTER_THAN (word)result); +# if !defined(CPPCHECK) + GC_ASSERT((word)GC_approx_sp() HOTTER_THAN (word)result); +# endif return(result); } # define GET_MAIN_STACKBASE_SPECIAL @@ -1390,6 +1418,8 @@ RESTORE_CANCEL(cancel_state); } UNLOCK(); +# elif defined(E2K) + b -> reg_base = NULL; # endif return GC_SUCCESS; } @@ -1466,8 +1496,8 @@ if (!stackbase_main_self && thr_main() != 0) { - /* Cache the stack base value for the primordial thread (this */ - /* is done during GC_init, so there is no race). */ + /* Cache the stack bottom pointer for the primordial thread */ + /* (this is done during GC_init, so there is no race). */ stackbase_main_ss_sp = s.ss_sp; stackbase_main_self = self; } @@ -1489,7 +1519,7 @@ #ifndef HAVE_GET_STACK_BASE # ifdef NEED_FIND_LIMIT - /* Retrieve stack base. */ + /* Retrieve the stack bottom. */ /* Using the GC_find_limit version is risky. */ /* On IA64, for example, there is no guard page between the */ /* stack of one thread and the register backing store of the */ @@ -1505,12 +1535,14 @@ DISABLE_CANCEL(cancel_state); /* May be unnecessary? */ # ifdef STACK_GROWS_DOWN b -> mem_base = GC_find_limit(GC_approx_sp(), TRUE); -# ifdef IA64 - b -> reg_base = GC_find_limit(GC_save_regs_in_stack(), FALSE); -# endif # else b -> mem_base = GC_find_limit(GC_approx_sp(), FALSE); # endif +# ifdef IA64 + b -> reg_base = GC_find_limit(GC_save_regs_in_stack(), FALSE); +# elif defined(E2K) + b -> reg_base = NULL; +# endif RESTORE_CANCEL(cancel_state); UNLOCK(); return GC_SUCCESS; @@ -1680,7 +1712,7 @@ # ifdef MSWINRT_FLAVOR { MEMORY_BASIC_INFORMATION memInfo; - SIZE_T result = VirtualQuery(GetProcAddress, + SIZE_T result = VirtualQuery((void*)(word)GetProcAddress, &memInfo, sizeof(memInfo)); if (result != sizeof(memInfo)) ABORT("Weird VirtualQuery result"); @@ -1694,9 +1726,11 @@ /* Also check whether VirtualAlloc accepts MEM_WRITE_WATCH, */ /* as some versions of kernel32.dll have one but not the */ /* other, making the feature completely broken. */ - void * page = VirtualAlloc(NULL, GC_page_size, - MEM_WRITE_WATCH | MEM_RESERVE, - PAGE_READWRITE); + void * page; + + GC_ASSERT(GC_page_size != 0); + page = VirtualAlloc(NULL, GC_page_size, MEM_WRITE_WATCH | MEM_RESERVE, + PAGE_READWRITE); if (page != NULL) { PVOID pages16; GC_ULONG_PTR count = 16; @@ -1719,13 +1753,6 @@ GetWriteWatch_func = 0; } } -# ifndef SMALL_CONFIG - if (!GetWriteWatch_func) { - GC_COND_LOG_PRINTF("Did not find a usable GetWriteWatch()\n"); - } else { - GC_COND_LOG_PRINTF("Using GetWriteWatch()\n"); - } -# endif done = TRUE; } @@ -1780,11 +1807,10 @@ STATIC ptr_t GC_least_described_address(ptr_t start) { MEMORY_BASIC_INFORMATION buf; - LPVOID limit; - ptr_t p; + LPVOID limit = GC_sysinfo.lpMinimumApplicationAddress; + ptr_t p = (ptr_t)((word)start & ~(GC_page_size - 1)); - limit = GC_sysinfo.lpMinimumApplicationAddress; - p = (ptr_t)((word)start & ~(GC_page_size - 1)); + GC_ASSERT(GC_page_size != 0); for (;;) { size_t result; LPVOID q = (LPVOID)(p - GC_page_size); @@ -1798,7 +1824,7 @@ } # endif /* MSWIN32 */ -# ifndef REDIRECT_MALLOC +# if defined(USE_WINALLOC) && !defined(REDIRECT_MALLOC) /* We maintain a linked list of AllocationBase values that we know */ /* correspond to malloc heap sections. Currently this is only called */ /* during a GC. But there is some hope that for long running */ @@ -1810,7 +1836,6 @@ STATIC size_t GC_max_root_size = 100000; /* Appr. largest root size. */ -# ifdef USE_WINALLOC /* In the long run, a better data structure would also be nice ... */ STATIC struct GC_malloc_heap_list { void * allocation_base; @@ -1847,6 +1872,9 @@ void *candidate; if (NULL == new_l) return; + new_l -> allocation_base = NULL; + /* to suppress maybe-uninitialized gcc warning */ + candidate = GC_get_allocation_base(new_l); if (GC_is_malloc_heap_base(candidate)) { /* Try a little harder to find malloc heap. */ @@ -1873,24 +1901,35 @@ new_l -> next = GC_malloc_heap_l; GC_malloc_heap_l = new_l; } -# endif /* USE_WINALLOC */ -# endif /* !REDIRECT_MALLOC */ + /* Free all the linked list nodes. Could be invoked at process exit */ + /* to avoid memory leak complains of a dynamic code analysis tool. */ + STATIC void GC_free_malloc_heap_list(void) + { + struct GC_malloc_heap_list *q = GC_malloc_heap_l; - STATIC word GC_n_heap_bases = 0; /* See GC_heap_bases. */ + GC_malloc_heap_l = NULL; + while (q != NULL) { + struct GC_malloc_heap_list *next = q -> next; + free(q); + q = next; + } + } +# endif /* USE_WINALLOC && !REDIRECT_MALLOC */ /* Is p the start of either the malloc heap, or of one of our */ /* heap sections? */ GC_INNER GC_bool GC_is_heap_base(void *p) { - unsigned i; -# ifndef REDIRECT_MALLOC - if (GC_root_size > GC_max_root_size) GC_max_root_size = GC_root_size; -# ifdef USE_WINALLOC - if (GC_is_malloc_heap_base(p)) return TRUE; -# endif + int i; + +# if defined(USE_WINALLOC) && !defined(REDIRECT_MALLOC) + if (GC_root_size > GC_max_root_size) + GC_max_root_size = GC_root_size; + if (GC_is_malloc_heap_base(p)) + return TRUE; # endif - for (i = 0; i < GC_n_heap_bases; i++) { + for (i = 0; i < (int)GC_n_heap_bases; i++) { if (GC_heap_basesi == p) return TRUE; } return FALSE; @@ -2034,7 +2073,11 @@ ABORT_ARG2("Wrong DATASTART/END pair", ": %p .. %p", (void *)region_start, (void *)DATAEND); for (;;) { - ptr_t region_end = GC_find_limit_openbsd(region_start, DATAEND); +# ifdef GC_OPENBSD_UTHREADS + ptr_t region_end = GC_find_limit_openbsd(region_start, DATAEND); +# else + ptr_t region_end = GC_find_limit_with_bound(region_start, TRUE, DATAEND); +# endif GC_add_roots_inner(region_start, region_end, FALSE); if ((word)region_end >= (word)DATAEND) @@ -2193,6 +2236,7 @@ } # endif + GC_ASSERT(GC_page_size != 0); if (bytes & (GC_page_size - 1)) ABORT("Bad GET_MEM arg"); result = mmap(last_addr, bytes, (PROT_READ | PROT_WRITE) | (GC_pages_executable ? PROT_EXEC : 0), @@ -2246,6 +2290,7 @@ ptr_t cur_brk = (ptr_t)sbrk(0); SBRK_ARG_T lsbs = (word)cur_brk & (GC_page_size-1); + GC_ASSERT(GC_page_size != 0); if ((SBRK_ARG_T)bytes < 0) { result = 0; /* too big */ goto out; @@ -2338,6 +2383,7 @@ ptr_t result = 0; /* initialized to prevent warning. */ word i; + GC_ASSERT(GC_page_size != 0); bytes = ROUNDUP_PAGESIZE(bytes); /* Try to find reserved, uncommitted pages */ @@ -2364,8 +2410,8 @@ GC_pages_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); - /* If I read the documentation correctly, this can */ - /* only happen if HBLKSIZE > 64k or not a power of 2. */ + /* If I read the documentation correctly, this can */ + /* only happen if HBLKSIZE > 64 KB or not a power of 2. */ if (GC_n_heap_bases >= MAX_HEAP_SECTS) ABORT("Too many heap sections"); if (result == NULL) return NULL; GC_heap_basesGC_n_heap_bases = result; @@ -2387,7 +2433,7 @@ return(result); } -#elif (defined(USE_WINALLOC) && !defined(MSWIN_XBOX1)) || defined(CYGWIN32) +#elif defined(USE_WINALLOC) /* && !MSWIN_XBOX1 */ || defined(CYGWIN32) # ifdef USE_GLOBAL_ALLOC # define GLOBAL_ALLOC_TEST 1 @@ -2400,7 +2446,7 @@ DWORD GC_mem_top_down = MEM_TOP_DOWN; /* Use GC_USE_MEM_TOP_DOWN for better 64-bit */ /* testing. Otherwise all addresses tend to */ - /* end up in first 4GB, hiding bugs. */ + /* end up in first 4 GB, hiding bugs. */ # else # define GC_mem_top_down 0 # endif /* !GC_USE_MEM_TOP_DOWN */ @@ -2461,39 +2507,49 @@ # endif /* USE_WINALLOC */ if (HBLKDISPL(result) != 0) ABORT("Bad VirtualAlloc result"); /* If I read the documentation correctly, this can */ - /* only happen if HBLKSIZE > 64k or not a power of 2. */ + /* only happen if HBLKSIZE > 64 KB or not a power of 2. */ if (GC_n_heap_bases >= MAX_HEAP_SECTS) ABORT("Too many heap sections"); if (0 != result) GC_heap_basesGC_n_heap_bases++ = result; return(result); } +#endif /* USE_WINALLOC || CYGWIN32 */ +#if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) \ + || defined(MSWIN_XBOX1) GC_API void GC_CALL GC_win32_free_heap(void) { -# ifndef MSWINRT_FLAVOR +# if defined(USE_WINALLOC) && !defined(REDIRECT_MALLOC) \ + && !defined(MSWIN_XBOX1) + GC_free_malloc_heap_list(); +# endif +# if (defined(USE_WINALLOC) && !defined(MSWIN_XBOX1) \ + && !defined(MSWINCE)) || defined(CYGWIN32) +# ifndef MSWINRT_FLAVOR +# ifndef CYGWIN32 + if (GLOBAL_ALLOC_TEST) +# endif + { + while (GC_n_heap_bases-- > 0) { +# ifdef CYGWIN32 + /* FIXME: Is it OK to use non-GC free() here? */ +# else + GlobalFree(GC_heap_basesGC_n_heap_bases); +# endif + GC_heap_basesGC_n_heap_bases = 0; + } + return; + } +# endif /* !MSWINRT_FLAVOR */ # ifndef CYGWIN32 - if (GLOBAL_ALLOC_TEST) -# endif - { - while (GC_n_heap_bases-- > 0) { -# ifdef CYGWIN32 - /* FIXME: Is it OK to use non-GC free() here? */ -# else - GlobalFree(GC_heap_basesGC_n_heap_bases); -# endif + /* Avoiding VirtualAlloc leak. */ + while (GC_n_heap_bases > 0) { + VirtualFree(GC_heap_bases--GC_n_heap_bases, 0, MEM_RELEASE); GC_heap_basesGC_n_heap_bases = 0; } - return; - } -# endif -# ifndef CYGWIN32 - /* Avoiding VirtualAlloc leak. */ - while (GC_n_heap_bases > 0) { - VirtualFree(GC_heap_bases--GC_n_heap_bases, 0, MEM_RELEASE); - GC_heap_basesGC_n_heap_bases = 0; - } -# endif +# endif +# endif /* USE_WINALLOC || CYGWIN32 */ } -#endif /* USE_WINALLOC || CYGWIN32 */ +#endif /* Windows */ #ifdef AMIGA # define GC_AMIGA_AM @@ -2514,6 +2570,13 @@ } #endif /* HAIKU */ +#if (defined(USE_MUNMAP) || defined(MPROTECT_VDB)) && !defined(USE_WINALLOC) +# define ABORT_ON_REMAP_FAIL(C_msg_prefix, start_addr, len) \ + ABORT_ARG3(C_msg_prefix " failed", \ + " at %p (length %lu), errno= %d", \ + (void *)(start_addr), (unsigned long)(len), errno) +#endif + #ifdef USE_MUNMAP /* For now, this only works on Win32/WinCE and some Unix-like */ @@ -2540,6 +2603,7 @@ ptr_t result = (ptr_t)(((word)start + GC_page_size - 1) & ~(GC_page_size - 1)); + GC_ASSERT(GC_page_size != 0); if ((word)(result + GC_page_size) > (word)(start + bytes)) return 0; return result; } @@ -2555,13 +2619,11 @@ /* We assume that GC_remap is called on exactly the same range */ /* as a previous call to GC_unmap. It is safe to consistently */ /* round the endpoints in both places. */ -GC_INNER void GC_unmap(ptr_t start, size_t bytes) -{ - ptr_t start_addr = GC_unmap_start(start, bytes); - ptr_t end_addr = GC_unmap_end(start, bytes); - word len = end_addr - start_addr; +static void block_unmap_inner(ptr_t start_addr, size_t len) +{ if (0 == start_addr) return; + # ifdef USE_WINALLOC while (len != 0) { MEMORY_BASIC_INFORMATION mem_info; @@ -2577,39 +2639,65 @@ start_addr += free_len; len -= free_len; } -# elif defined(SN_TARGET_PS3) - ps3_free_mem(start_addr, len); # else /* We immediately remap it to prevent an intervening mmap from */ /* accidentally grabbing the same address space. */ - { -# if defined(AIX) || defined(CYGWIN32) || defined(HAIKU) \ - || defined(HPUX) + if (len != 0) { +# ifdef SN_TARGET_PS3 + ps3_free_mem(start_addr, len); +# elif defined(AIX) || defined(CYGWIN32) || defined(HAIKU) \ + || (defined(LINUX) && !defined(PREFER_MMAP_PROT_NONE)) \ + || defined(HPUX) /* On AIX, mmap(PROT_NONE) fails with ENOMEM unless the */ /* environment variable XPG_SUS_ENV is set to ON. */ /* On Cygwin, calling mmap() with the new protection flags on */ /* an existing memory map with MAP_FIXED is broken. */ /* However, calling mprotect() on the given address range */ /* with PROT_NONE seems to work fine. */ - if (mprotect(start_addr, len, PROT_NONE)) - ABORT("mprotect(PROT_NONE) failed"); + /* On Linux, low RLIMIT_AS value may lead to mmap failure. */ +# if defined(LINUX) && !defined(FORCE_MPROTECT_BEFORE_MADVISE) + /* On Linux, at least, madvise() should be sufficient. */ +# else + if (mprotect(start_addr, len, PROT_NONE)) + ABORT_ON_REMAP_FAIL("unmap: mprotect", start_addr, len); +# endif +# if !defined(CYGWIN32) + /* On Linux (and some other platforms probably), */ + /* mprotect(PROT_NONE) is just disabling access to */ + /* the pages but not returning them to OS. */ + if (madvise(start_addr, len, MADV_DONTNEED) == -1) + ABORT_ON_REMAP_FAIL("unmap: madvise", start_addr, len); +# endif +# elif defined(EMSCRIPTEN) + /* Nothing to do, mmap(PROT_NONE) is not supported and */ + /* mprotect() is just a no-op. */ # else void * result = mmap(start_addr, len, PROT_NONE, MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON, zero_fd, 0/* offset */); + if (EXPECT(MAP_FAILED == result, FALSE)) + ABORT_ON_REMAP_FAIL("unmap: mmap", start_addr, len); if (result != (void *)start_addr) - ABORT("mmap(PROT_NONE) failed"); + ABORT("unmap: mmap() result differs from start_addr"); # if defined(CPPCHECK) || defined(LINT2) /* Explicitly store the resource handle to a global variable. */ GC_noop1((word)result); # endif -# endif /* !CYGWIN32 */ +# endif + GC_unmapped_bytes += len; } - GC_unmapped_bytes += len; # endif } +GC_INNER void GC_unmap(ptr_t start, size_t bytes) +{ + ptr_t start_addr = GC_unmap_start(start, bytes); + ptr_t end_addr = GC_unmap_end(start, bytes); + + block_unmap_inner(start_addr, (size_t)(end_addr - start_addr)); +} + GC_INNER void GC_remap(ptr_t start, size_t bytes) { ptr_t start_addr = GC_unmap_start(start, bytes); @@ -2647,10 +2735,14 @@ start_addr += alloc_len; len -= alloc_len; } +# undef IGNORE_PAGES_EXECUTABLE # else /* It was already remapped with PROT_NONE. */ { -# if defined(NACL) || defined(NETBSD) +# if !defined(SN_TARGET_PS3) && !defined(FORCE_MPROTECT_BEFORE_MADVISE) \ + && defined(LINUX) && !defined(PREFER_MMAP_PROT_NONE) + /* Nothing to unprotect as madvise() is just a hint. */ +# elif defined(NACL) || defined(NETBSD) /* NaCl does not expose mprotect, but mmap should work fine. */ /* In case of NetBSD, mprotect fails (unlike mmap) even */ /* without PROT_EXEC if PaX MPROTECT feature is enabled. */ @@ -2658,21 +2750,21 @@ | (GC_pages_executable ? PROT_EXEC : 0), MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON, zero_fd, 0 /* offset */); + if (EXPECT(MAP_FAILED == result, FALSE)) + ABORT_ON_REMAP_FAIL("remap: mmap", start_addr, len); if (result != (void *)start_addr) - ABORT("mmap as mprotect failed"); + ABORT("remap: mmap() result differs from start_addr"); # if defined(CPPCHECK) || defined(LINT2) GC_noop1((word)result); # endif +# undef IGNORE_PAGES_EXECUTABLE # else if (mprotect(start_addr, len, (PROT_READ | PROT_WRITE) - | (GC_pages_executable ? PROT_EXEC : 0)) != 0) { - ABORT_ARG3("mprotect remapping failed", - " at %p (length %lu), errcode= %d", - (void *)start_addr, (unsigned long)len, errno); - } + | (GC_pages_executable ? PROT_EXEC : 0))) + ABORT_ON_REMAP_FAIL("remap: mprotect", start_addr, len); +# undef IGNORE_PAGES_EXECUTABLE # endif /* !NACL */ } -# undef IGNORE_PAGES_EXECUTABLE GC_unmapped_bytes -= len; # endif } @@ -2689,49 +2781,11 @@ ptr_t start2_addr = GC_unmap_start(start2, bytes2); ptr_t start_addr = end1_addr; ptr_t end_addr = start2_addr; - size_t len; GC_ASSERT(start1 + bytes1 == start2); if (0 == start1_addr) start_addr = GC_unmap_start(start1, bytes1 + bytes2); if (0 == start2_addr) end_addr = GC_unmap_end(start1, bytes1 + bytes2); - if (0 == start_addr) return; - len = end_addr - start_addr; -# ifdef USE_WINALLOC - while (len != 0) { - MEMORY_BASIC_INFORMATION mem_info; - word free_len; - - if (VirtualQuery(start_addr, &mem_info, sizeof(mem_info)) - != sizeof(mem_info)) - ABORT("Weird VirtualQuery result"); - free_len = (len < mem_info.RegionSize) ? len : mem_info.RegionSize; - if (!VirtualFree(start_addr, free_len, MEM_DECOMMIT)) - ABORT("VirtualFree failed"); - GC_unmapped_bytes += free_len; - start_addr += free_len; - len -= free_len; - } -# else - if (len != 0) { - /* Immediately remap as above. */ -# if defined(AIX) || defined(CYGWIN32) || defined(HAIKU) \ - || defined(HPUX) - if (mprotect(start_addr, len, PROT_NONE)) - ABORT("mprotect(PROT_NONE) failed"); -# else - void * result = mmap(start_addr, len, PROT_NONE, - MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON, - zero_fd, 0/* offset */); - - if (result != (void *)start_addr) - ABORT("mmap(PROT_NONE) failed"); -# if defined(CPPCHECK) || defined(LINT2) - GC_noop1((word)result); -# endif -# endif /* !CYGWIN32 */ - GC_unmapped_bytes += len; - } -# endif + block_unmap_inner(start_addr, (size_t)(end_addr - start_addr)); } #endif /* USE_MUNMAP */ @@ -2740,7 +2794,24 @@ /* environment, this is also responsible for marking from */ /* thread stacks. */ #ifndef THREADS - GC_push_other_roots_proc GC_push_other_roots = 0; + +# ifdef EMSCRIPTEN + static void scan_regs_cb(void *begin, void *end) + { + GC_push_all_stack((ptr_t)begin, (ptr_t)end); + } + + STATIC void GC_CALLBACK GC_default_push_other_roots(void) + { + /* This needs "-s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000" */ + /* but hopefully the latter is only required for gctest. */ + emscripten_scan_registers(scan_regs_cb); + } + +# else +# define GC_default_push_other_roots 0 +# endif + #else /* THREADS */ # ifdef PCR @@ -2783,17 +2854,7 @@ } } -# endif /* PCR */ - -# if defined(NN_PLATFORM_CTR) || defined(NINTENDO_SWITCH) \ - || defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) - STATIC void GC_CALLBACK GC_default_push_other_roots(void) - { - GC_push_all_stacks(); - } -# endif - -# ifdef SN_TARGET_PS3 +# elif defined(SN_TARGET_PS3) STATIC void GC_CALLBACK GC_default_push_other_roots(void) { ABORT("GC_default_push_other_roots is not implemented"); @@ -2803,11 +2864,18 @@ { ABORT("GC_push_thread_structures is not implemented"); } -# endif /* SN_TARGET_PS3 */ - GC_push_other_roots_proc GC_push_other_roots = GC_default_push_other_roots; +# else /* GC_PTHREADS, or GC_WIN32_THREADS, etc. */ + STATIC void GC_CALLBACK GC_default_push_other_roots(void) + { + GC_push_all_stacks(); + } +# endif + #endif /* THREADS */ +GC_push_other_roots_proc GC_push_other_roots = GC_default_push_other_roots; + GC_API void GC_CALL GC_set_push_other_roots(GC_push_other_roots_proc fn) { GC_push_other_roots = fn; @@ -2818,6 +2886,31 @@ return GC_push_other_roots; } +#if defined(SOFT_VDB) && !defined(NO_SOFT_VDB_LINUX_VER_RUNTIME_CHECK) \ + || (defined(GLIBC_2_19_TSX_BUG) && defined(THREADS)) + GC_INNER int GC_parse_version(int *pminor, const char *pverstr) { + char *endp; + unsigned long value = strtoul(pverstr, &endp, 10); + int major = (int)value; + + if (major < 0 || (char *)pverstr == endp || (unsigned)major != value) { + /* Parse error. */ + return -1; + } + if (*endp != '.') { + /* No minor part. */ + *pminor = -1; + } else { + value = strtoul(endp + 1, &endp, 10); + *pminor = (int)value; + if (*pminor < 0 || (unsigned)(*pminor) != value) { + return -1; + } + } + return major; + } +#endif + /* * Routines for accessing dirty bits on virtual pages. * There are six ways to maintain this information: @@ -2845,6 +2938,16 @@ * too slow to be entirely satisfactory. Requires reading * dirty bits for entire address space. Implementations tend * to assume that the client is a (slow) debugger. + * SOFT_VDB: Use the /proc facility for reading soft-dirty PTEs. + * Works on Linux 3.18+ if the kernel is properly configured. + * The proposed implementation iterates over GC_heap_sects and + * GC_static_roots examining the soft-dirty bit of the words + * in /proc/self/pagemap corresponding to the pages of the + * sections; finally all soft-dirty bits of the process are + * cleared (by writing some special value to + * /proc/self/clear_refs file). In case the soft-dirty bit is + * not supported by the kernel, MPROTECT_VDB may be defined as + * a fallback strategy. * MPROTECT_VDB:Protect pages and then catch the faults to keep track of * dirtied pages. The implementation (and implementability) * is highly system dependent. This usually fails when system @@ -2858,14 +2961,15 @@ * MPROTECT_VDB may be defined as a fallback strategy. */ -#if (defined(CHECKSUMS) && defined(GWW_VDB)) || defined(PROC_VDB) +#if (defined(CHECKSUMS) && (defined(GWW_VDB) || defined(SOFT_VDB))) \ + || defined(PROC_VDB) /* Add all pages in pht2 to pht1. */ STATIC void GC_or_pages(page_hash_table pht1, page_hash_table pht2) { unsigned i; for (i = 0; i < PHT_SIZE; i++) pht1i |= pht2i; } -#endif /* CHECKSUMS && GWW_VDB || PROC_VDB */ +#endif /* CHECKSUMS && (GWW_VDB || SOFT_VDB) || PROC_VDB */ #ifdef GWW_VDB @@ -2959,9 +3063,13 @@ GC_or_pages(GC_written_pages, GC_grungy_pages); # endif } + +#elif defined(SOFT_VDB) + static int clear_refs_fd = -1; +# define GC_GWW_AVAILABLE() (clear_refs_fd != -1) #else # define GC_GWW_AVAILABLE() FALSE -#endif /* !GWW_VDB */ +#endif /* !GWW_VDB && !SOFT_VDB */ #ifdef DEFAULT_VDB /* All of the following assume the allocation lock is held. */ @@ -3021,16 +3129,13 @@ decrease the likelihood of some of the problems described below. */ # include <mach/vm_map.h> STATIC mach_port_t GC_task_self = 0; -# define PROTECT(addr,len) \ +# define PROTECT_INNER(addr, len, allow_write, C_msg_prefix) \ if (vm_protect(GC_task_self, (vm_address_t)(addr), (vm_size_t)(len), \ FALSE, VM_PROT_READ \ + | ((allow_write) ? VM_PROT_WRITE : 0) \ | (GC_pages_executable ? VM_PROT_EXECUTE : 0)) \ - == KERN_SUCCESS) {} else ABORT("vm_protect(PROTECT) failed") -# define UNPROTECT(addr,len) \ - if (vm_protect(GC_task_self, (vm_address_t)(addr), (vm_size_t)(len), \ - FALSE, (VM_PROT_READ | VM_PROT_WRITE) \ - | (GC_pages_executable ? VM_PROT_EXECUTE : 0)) \ - == KERN_SUCCESS) {} else ABORT("vm_protect(UNPROTECT) failed") + == KERN_SUCCESS) {} else ABORT(C_msg_prefix \ + "vm_protect() failed") # elif !defined(USE_WINALLOC) # include <sys/mman.h> @@ -3039,19 +3144,15 @@ # include <sys/syscall.h> # endif -# define PROTECT(addr, len) \ +# define PROTECT_INNER(addr, len, allow_write, C_msg_prefix) \ if (mprotect((caddr_t)(addr), (size_t)(len), \ - PROT_READ \ + PROT_READ | ((allow_write) ? PROT_WRITE : 0) \ | (GC_pages_executable ? PROT_EXEC : 0)) >= 0) { \ - } else ABORT("mprotect failed") -# define UNPROTECT(addr, len) \ - if (mprotect((caddr_t)(addr), (size_t)(len), \ - (PROT_READ | PROT_WRITE) \ - | (GC_pages_executable ? PROT_EXEC : 0)) >= 0) { \ - } else ABORT(GC_pages_executable ? \ - "un-mprotect executable page failed" \ - " (probably disabled by OS)" : \ - "un-mprotect failed") + } else if (GC_pages_executable) { \ + ABORT_ON_REMAP_FAIL(C_msg_prefix \ + "mprotect vdb executable pages", \ + addr, len); \ + } else ABORT_ON_REMAP_FAIL(C_msg_prefix "mprotect vdb", addr, len) # undef IGNORE_PAGES_EXECUTABLE # else /* USE_WINALLOC */ @@ -3060,21 +3161,21 @@ # endif static DWORD protect_junk; -# define PROTECT(addr, len) \ - if (VirtualProtect((addr), (len), \ - GC_pages_executable ? PAGE_EXECUTE_READ : \ +# define PROTECT_INNER(addr, len, allow_write, C_msg_prefix) \ + if (VirtualProtect(addr, len, \ + GC_pages_executable ? \ + ((allow_write) ? PAGE_EXECUTE_READWRITE : \ + PAGE_EXECUTE_READ) : \ + (allow_write) ? PAGE_READWRITE : \ PAGE_READONLY, \ &protect_junk)) { \ - } else ABORT_ARG1("VirtualProtect failed", \ + } else ABORT_ARG1(C_msg_prefix "VirtualProtect failed", \ ": errcode= 0x%X", (unsigned)GetLastError()) -# define UNPROTECT(addr, len) \ - if (VirtualProtect((addr), (len), \ - GC_pages_executable ? PAGE_EXECUTE_READWRITE : \ - PAGE_READWRITE, \ - &protect_junk)) { \ - } else ABORT("un-VirtualProtect failed") # endif /* USE_WINALLOC */ +# define PROTECT(addr, len) PROTECT_INNER(addr, len, FALSE, "") +# define UNPROTECT(addr, len) PROTECT_INNER(addr, len, TRUE, "un-") + # if defined(MSWIN32) typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_HNDLR_PTR; # undef SIG_DFL @@ -3090,12 +3191,6 @@ typedef void (* PLAIN_HNDLR_PTR)(int); # endif -# if defined(__GLIBC__) -# if __GLIBC__ < 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ < 2 -# error glibc too old? -# endif -# endif - #ifndef DARWIN STATIC SIG_HNDLR_PTR GC_old_segv_handler = 0; /* Also old MSWIN32 ACCESS_VIOLATION filter */ @@ -3201,6 +3296,7 @@ GC_bool in_allocd_block; size_t i; + GC_ASSERT(GC_page_size != 0); # ifdef CHECKSUMS GC_record_fault(h); # endif @@ -3305,35 +3401,12 @@ SetUnhandledExceptionFilter(GC_write_fault_handler); } # endif -#endif /* !DARWIN */ -#ifdef USE_MUNMAP - /* MPROTECT_VDB cannot deal with address space holes (for now), */ - /* so if the collector is configured with both MPROTECT_VDB and */ - /* USE_MUNMAP then, as a work around, select only one of them */ - /* during GC_init or GC_enable_incremental. */ - GC_INNER GC_bool GC_dirty_init(void) - { - if (GC_unmap_threshold != 0) { - if (GETENV("GC_UNMAP_THRESHOLD") != NULL - || GETENV("GC_FORCE_UNMAP_ON_GCOLLECT") != NULL - || GC_has_unmapped_memory()) { - WARN("Can't maintain mprotect-based dirty bits" - " in case of unmapping\n", 0); - return FALSE; - } - GC_unmap_threshold = 0; /* in favor of incremental collection */ - WARN("Memory unmapping is disabled as incompatible" - " with MPROTECT_VDB\n", 0); - } - return GC_mprotect_dirty_init(); - } -#else -# define GC_mprotect_dirty_init GC_dirty_init -#endif /* !USE_MUNMAP */ +# ifdef SOFT_VDB + static GC_bool soft_dirty_init(void); +# endif -#if !defined(DARWIN) - GC_INNER GC_bool GC_mprotect_dirty_init(void) + GC_INNER GC_bool GC_dirty_init(void) { # if !defined(MSWIN32) && !defined(MSWINCE) struct sigaction act, oldact; @@ -3353,7 +3426,29 @@ if (GC_page_size % HBLKSIZE != 0) { ABORT("Page size not multiple of HBLKSIZE"); } -# if !defined(MSWIN32) && !defined(MSWINCE) +# ifdef GWW_VDB + if (GC_gww_dirty_init()) { + GC_COND_LOG_PRINTF("Using GetWriteWatch()\n"); + return TRUE; + } +# elif defined(SOFT_VDB) + if (soft_dirty_init()) { + GC_COND_LOG_PRINTF("Using soft-dirty bit feature\n"); + return TRUE; + } +# endif +# ifdef MSWIN32 + GC_old_segv_handler = SetUnhandledExceptionFilter( + GC_write_fault_handler); + if (GC_old_segv_handler != NULL) { + GC_COND_LOG_PRINTF("Replaced other UnhandledExceptionFilter\n"); + } else { + GC_old_segv_handler = SIG_DFL; + } +# elif defined(MSWINCE) + /* MPROTECT_VDB is unsupported for WinCE at present. */ + /* FIXME: implement it (if possible). */ +# else /* act.sa_restorer is deprecated and should not be initialized. */ # if defined(GC_IRIX_THREADS) sigaction(SIGSEGV, 0, &oldact); @@ -3379,7 +3474,7 @@ GC_VERBOSE_LOG_PRINTF("Replaced other SIGSEGV handler\n"); } # if defined(HPUX) || defined(LINUX) || defined(HURD) \ - || (defined(FREEBSD) && (defined(__GLIBC__) || defined(SUNOS5SIGS))) + || (defined(FREEBSD) && defined(SUNOS5SIGS)) sigaction(SIGBUS, &act, &oldact); if ((oldact.sa_flags & SA_SIGINFO) != 0) { GC_old_bus_handler = oldact.sa_sigaction; @@ -3401,21 +3496,6 @@ } # endif /* HPUX || LINUX || HURD || (FREEBSD && SUNOS5SIGS) */ # endif /* ! MS windows */ -# if defined(GWW_VDB) - if (GC_gww_dirty_init()) - return TRUE; -# endif -# if defined(MSWIN32) - GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler); - if (GC_old_segv_handler != NULL) { - GC_COND_LOG_PRINTF("Replaced other UnhandledExceptionFilter\n"); - } else { - GC_old_segv_handler = SIG_DFL; - } -# elif defined(MSWINCE) - /* MPROTECT_VDB is unsupported for WinCE at present. */ - /* FIXME: implement it (if possible). */ -# endif # if defined(CPPCHECK) && defined(ADDRESS_SANITIZER) GC_noop1((word)&__asan_default_options); # endif @@ -3426,7 +3506,11 @@ GC_API int GC_CALL GC_incremental_protection_needs(void) { GC_ASSERT(GC_is_initialized); - +# if defined(GWW_VDB) || defined(SOFT_VDB) + /* Only if the incremental mode is already switched on. */ + if (GC_GWW_AVAILABLE()) + return GC_PROTECTS_NONE; +# endif if (GC_page_size == HBLKSIZE) { return GC_PROTECTS_POINTER_HEAP; } else { @@ -3444,6 +3528,7 @@ GC_bool protect_all = (0 != (GC_incremental_protection_needs() & GC_PROTECTS_PTRFREE_HEAP)); + GC_ASSERT(GC_page_size != 0); for (i = 0; i < GC_n_heap_sects; i++) { ptr_t start = GC_heap_sectsi.hs_start; size_t len = GC_heap_sectsi.hs_bytes; @@ -3511,6 +3596,10 @@ /* to the write-protected heap with a system call. */ #endif /* MPROTECT_VDB */ +#if !defined(THREADS) && (defined(PROC_VDB) || defined(SOFT_VDB)) + static pid_t saved_proc_pid; /* pid used to compose /proc file names */ +#endif + #ifdef PROC_VDB /* This implementation assumes a Solaris 2.X like /proc */ /* pseudo-file-system from which we can read page modified bits. This */ @@ -3545,10 +3634,6 @@ # include <sys/procfs.h> # endif -# ifndef THREADS - static pid_t saved_proc_pid; /* pid used to compose /proc file name */ -# endif - # define INITIAL_BUF_SZ 16384 STATIC size_t GC_proc_buf_size = INITIAL_BUF_SZ; STATIC char *GC_proc_buf = NULL; @@ -3604,7 +3689,6 @@ GC_INLINE void GC_proc_read_dirty(GC_bool output_unneeded) { -# define READ read int nmaps; char * bufp = GC_proc_buf; int i; @@ -3627,12 +3711,12 @@ # endif BZERO(GC_grungy_pages, sizeof(GC_grungy_pages)); - if (READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) { + if (PROC_READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) { /* Retry with larger buffer. */ size_t new_size = 2 * GC_proc_buf_size; char *new_buf; - WARN("/proc read failed: GC_proc_buf_size = %" WARN_PRIdPTR "\n", + WARN("/proc read failed: GC_proc_buf_size= %" WARN_PRIdPTR "\n", (signed_word)GC_proc_buf_size); new_buf = GC_scratch_alloc(new_size); if (new_buf != 0) { @@ -3640,7 +3724,7 @@ GC_proc_buf = bufp = new_buf; GC_proc_buf_size = new_size; } - if (READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) { + if (PROC_READ(GC_proc_fd, bufp, GC_proc_buf_size) <= 0) { WARN("Insufficient space for /proc read\n", 0); /* Punt: */ if (!output_unneeded) @@ -3702,11 +3786,327 @@ /* Update GC_written_pages (even if output_unneeded). */ GC_or_pages(GC_written_pages, GC_grungy_pages); -# undef READ } #endif /* PROC_VDB */ +#ifdef SOFT_VDB +# ifndef VDB_BUF_SZ +# define VDB_BUF_SZ 16384 +# endif + + static int open_proc_fd(pid_t pid, const char *proc_filename, int mode) + { + int f; + char buf40; + + (void)snprintf(buf, sizeof(buf), "/proc/%ld/%s", (long)pid, + proc_filename); + bufsizeof(buf) - 1 = '\0'; + f = open(buf, mode); + if (-1 == f) { + WARN("/proc/self/%s open failed; cannot enable GC incremental mode\n", + proc_filename); + } else if (fcntl(f, F_SETFD, FD_CLOEXEC) == -1) { + WARN("Could not set FD_CLOEXEC for /proc\n", 0); + } + return f; + } + +# include <stdint.h> /* for uint64_t */ + + typedef uint64_t pagemap_elem_t; + + static pagemap_elem_t *soft_vdb_buf; + static int pagemap_fd; + + static GC_bool soft_dirty_open_files(void) + { + pid_t pid = getpid(); + + clear_refs_fd = open_proc_fd(pid, "clear_refs", O_WRONLY); + if (-1 == clear_refs_fd) + return FALSE; + pagemap_fd = open_proc_fd(pid, "pagemap", O_RDONLY); + if (-1 == pagemap_fd) { + close(clear_refs_fd); + clear_refs_fd = -1; + return FALSE; + } +# ifndef THREADS + saved_proc_pid = pid; /* updated on success only */ +# endif + return TRUE; + } + +# ifdef CAN_HANDLE_FORK + GC_INNER void GC_dirty_update_child(void) + { + if (-1 == clear_refs_fd) + return; /* GC incremental mode is off */ + + close(clear_refs_fd); + close(pagemap_fd); + if (!soft_dirty_open_files()) + GC_incremental = FALSE; + } +# endif /* CAN_HANDLE_FORK */ + + /* The bit 55 of the 64-bit qword of pagemap file is the soft-dirty one. */ +# define PM_SOFTDIRTY_MASK ((pagemap_elem_t)1 << 55) + + static GC_bool detect_soft_dirty_supported(ptr_t vaddr) + { + off_t fpos; + pagemap_elem_t buf1; + + *vaddr = 1; /* make it dirty */ + + /* Read the relevant PTE from the pagemap file. */ + GC_ASSERT(GC_page_size != 0); + fpos = (off_t)((word)vaddr / GC_page_size * sizeof(pagemap_elem_t)); + if (lseek(pagemap_fd, fpos, SEEK_SET) == (off_t)(-1)) + return FALSE; + if (PROC_READ(pagemap_fd, buf, sizeof(buf)) != (int)sizeof(buf)) + return FALSE; + + /* Is the soft-dirty bit set? */ + return (buf0 & PM_SOFTDIRTY_MASK) != 0; + } + +# ifndef NO_SOFT_VDB_LINUX_VER_RUNTIME_CHECK +# include <sys/utsname.h> +# include <string.h> /* for strcmp() */ + + /* Ensure the linux (kernel) major/minor version is as given or higher. */ + static GC_bool ensure_min_linux_ver(int major, int minor) { + struct utsname info; + int actual_major; + int actual_minor = -1; + + if (uname(&info) == -1) { + return FALSE; /* uname() failed, should not happen actually. */ + } + if (strcmp(info.sysname, "Linux")) { + WARN("Cannot ensure Linux version as running on other OS: %s\n", + info.sysname); + return FALSE; + } + actual_major = GC_parse_version(&actual_minor, info.release); + return actual_major > major + || (actual_major == major && actual_minor >= minor); + } +# endif + +# ifdef MPROTECT_VDB + static GC_bool soft_dirty_init(void) +# else + GC_INNER GC_bool GC_dirty_init(void) +# endif + { + GC_ASSERT(NULL == soft_vdb_buf); +# ifdef MPROTECT_VDB + char * str = GETENV("GC_USE_GETWRITEWATCH"); +# ifdef GC_PREFER_MPROTECT_VDB + if (str == NULL || (*str == '0' && *(str + 1) == '\0')) + return FALSE; /* the environment variable is unset or set to "0" */ +# else + if (str != NULL && *str == '0' && *(str + 1) == '\0') + return FALSE; /* the environment variable is set "0" */ +# endif +# endif +# ifndef NO_SOFT_VDB_LINUX_VER_RUNTIME_CHECK + if (!ensure_min_linux_ver(3, 18)) { + GC_COND_LOG_PRINTF( + "Running on old kernel lacking correct soft-dirty bit support\n"); + return FALSE; + } +# endif + if (!soft_dirty_open_files()) + return FALSE; + soft_vdb_buf = (pagemap_elem_t *)GC_scratch_alloc(VDB_BUF_SZ); + if (NULL == soft_vdb_buf) + ABORT("Insufficient space for /proc pagemap buffer"); + if (!detect_soft_dirty_supported((ptr_t)soft_vdb_buf)) { + GC_COND_LOG_PRINTF("Soft-dirty bit is not supported by kernel\n"); + /* Release the resources. */ + GC_scratch_recycle_no_gww(soft_vdb_buf, VDB_BUF_SZ); + soft_vdb_buf = NULL; + close(clear_refs_fd); + clear_refs_fd = -1; + close(pagemap_fd); + return FALSE; + } + return TRUE; + } + + static off_t pagemap_buf_fpos; /* valid only if pagemap_buf_len > 0 */ + static size_t pagemap_buf_len; + + /* Read bytes from /proc/self/pagemap at given file position. */ + /* len - the maximum number of bytes to read; (*pres) - amount of */ + /* bytes actually read, always bigger than 0 but never exceeds len; */ + /* next_fpos_hint - the file position of the next bytes block to read */ + /* ahead if possible (0 means no information provided). */ + static const pagemap_elem_t *pagemap_buffered_read(size_t *pres, + off_t fpos, size_t len, + off_t next_fpos_hint) + { + ssize_t res; + size_t ofs; + + GC_ASSERT(len > 0); + if (pagemap_buf_fpos <= fpos + && fpos < pagemap_buf_fpos + (off_t)pagemap_buf_len) { + /* The requested data is already in the buffer. */ + ofs = (size_t)(fpos - pagemap_buf_fpos); + res = (ssize_t)(pagemap_buf_fpos + pagemap_buf_len - fpos); + } else { + off_t aligned_pos = fpos & ~(GC_page_size < VDB_BUF_SZ + ? GC_page_size-1 : VDB_BUF_SZ-1); + + for (;;) { + size_t count; + + if ((0 == pagemap_buf_len + || pagemap_buf_fpos + (off_t)pagemap_buf_len != aligned_pos) + && lseek(pagemap_fd, aligned_pos, SEEK_SET) == (off_t)(-1)) + ABORT_ARG2("Failed to lseek /proc/self/pagemap", + ": offset= %lu, errno= %d", (unsigned long)fpos, errno); + + /* How much to read at once? */ + ofs = (size_t)(fpos - aligned_pos); + GC_ASSERT(ofs < VDB_BUF_SZ); + if (next_fpos_hint > aligned_pos + && next_fpos_hint - aligned_pos < VDB_BUF_SZ) { + count = VDB_BUF_SZ; + } else { + count = len + ofs; + if (count > VDB_BUF_SZ) + count = VDB_BUF_SZ; + } + + GC_ASSERT(count % sizeof(pagemap_elem_t) == 0); + res = PROC_READ(pagemap_fd, soft_vdb_buf, count); + if (res > (ssize_t)ofs) + break; + if (res <= 0) + ABORT_ARG1("Failed to read /proc/self/pagemap", + ": errno= %d", res < 0 ? errno : 0); + /* Retry (once) w/o page-alignment. */ + aligned_pos = fpos; + } + + /* Save the buffer (file window) position and size. */ + pagemap_buf_fpos = aligned_pos; + pagemap_buf_len = (size_t)res; + res -= (ssize_t)ofs; + } + + GC_ASSERT(ofs % sizeof(pagemap_elem_t) == 0); + *pres = (size_t)res < len ? (size_t)res : len; + return &soft_vdb_bufofs / sizeof(pagemap_elem_t); + } + + static void soft_set_grungy_pages(ptr_t vaddr /* start */, ptr_t limit, + ptr_t next_start_hint) + { + GC_ASSERT(GC_page_size != 0); + while ((word)vaddr < (word)limit) { + size_t res; + word limit_buf; + const pagemap_elem_t *bufp = pagemap_buffered_read(&res, + (off_t)((word)vaddr / GC_page_size * sizeof(pagemap_elem_t)), + (size_t)((((word)limit - (word)vaddr + GC_page_size-1) + / GC_page_size) * sizeof(pagemap_elem_t)), + (off_t)((word)next_start_hint / GC_page_size + * sizeof(pagemap_elem_t))); + + if (res % sizeof(pagemap_elem_t) != 0) { + /* Punt: */ + memset(GC_grungy_pages, 0xff, sizeof(page_hash_table)); + WARN("Incomplete read of pagemap, not multiple of entry size\n", 0); + break; + } + + limit_buf = ((word)vaddr & ~(GC_page_size-1)) + + (res / sizeof(pagemap_elem_t)) * GC_page_size; + for (; (word)vaddr < limit_buf; vaddr += GC_page_size, bufp++) + if ((*bufp & PM_SOFTDIRTY_MASK) != 0) { + struct hblk * h; + ptr_t next_vaddr = vaddr + GC_page_size; + + /* If the bit is set, the respective PTE was written to */ + /* since clearing the soft-dirty bits. */ +# ifdef DEBUG_DIRTY_BITS + GC_log_printf("dirty page at: %p\n", (void *)vaddr); +# endif + for (h = (struct hblk *)vaddr; (word)h < (word)next_vaddr; h++) { + word index = PHT_HASH(h); + set_pht_entry_from_index(GC_grungy_pages, index); + } + } + /* Read the next portion of pagemap file if incomplete. */ + } + } + + GC_INLINE void GC_soft_read_dirty(GC_bool output_unneeded) + { + ssize_t res; + +# ifndef THREADS + /* Similar as for GC_proc_read_dirty. */ + if (getpid() != saved_proc_pid + && (-1 == clear_refs_fd /* no need to retry */ + || (close(clear_refs_fd), close(pagemap_fd), + !soft_dirty_open_files()))) { + /* Failed to reopen the files. */ + if (!output_unneeded) { + /* Punt: */ + memset(GC_grungy_pages, 0xff, sizeof(page_hash_table)); +# ifdef CHECKSUMS + memset(GC_written_pages, 0xff, sizeof(page_hash_table)); +# endif + } + return; + } +# endif + + if (!output_unneeded) { + word i; + + BZERO(GC_grungy_pages, sizeof(GC_grungy_pages)); + pagemap_buf_len = 0; /* invalidate soft_vdb_buf */ + + for (i = 0; i != GC_n_heap_sects; ++i) { + ptr_t vaddr = GC_heap_sectsi.hs_start; + + soft_set_grungy_pages(vaddr, vaddr + GC_heap_sectsi.hs_bytes, + i < GC_n_heap_sects-1 ? + GC_heap_sectsi+1.hs_start : NULL); + } +# ifdef CHECKSUMS + GC_or_pages(GC_written_pages, GC_grungy_pages); +# endif + +# ifndef NO_VDB_FOR_STATIC_ROOTS + for (i = 0; (int)i < n_root_sets; ++i) { + soft_set_grungy_pages(GC_static_rootsi.r_start, + GC_static_rootsi.r_end, + (int)i < n_root_sets-1 ? + GC_static_rootsi+1.r_start : NULL); + } +# endif + } + + /* Clear soft-dirty bits from the task's PTEs. */ + res = write(clear_refs_fd, "4\n", 2); + if (res != 2) + ABORT_ARG1("Failed to write to /proc/self/clear_refs", + ": errno= %d", res < 0 ? errno : 0); + } +#endif /* SOFT_VDB */ + #ifdef PCR_VDB # include "vd/PCR_VD.h" @@ -3778,6 +4178,8 @@ GC_gww_read_dirty(output_unneeded); # elif defined(PROC_VDB) GC_proc_read_dirty(output_unneeded); +# elif defined(SOFT_VDB) + GC_soft_read_dirty(output_unneeded); # elif defined(PCR_VDB) /* lazily enable dirty bits on newly added heap sects */ { @@ -3796,6 +4198,20 @@ # endif } +# if !defined(NO_VDB_FOR_STATIC_ROOTS) && !defined(PROC_VDB) + GC_INNER GC_bool GC_is_vdb_for_static_roots(void) + { + if (GC_manual_vdb) return FALSE; +# if defined(MPROTECT_VDB) + /* Currently used only in conjunction with SOFT_VDB. */ + return GC_GWW_AVAILABLE(); +# else + GC_ASSERT(GC_incremental); + return TRUE; +# endif + } +# endif + /* Is the HBLKSIZE sized page at h marked dirty in the local buffer? */ /* If the actual page size is different, this returns TRUE if any */ /* of the pages overlapping h are dirty. This routine may err on the */ @@ -3831,7 +4247,7 @@ /* Could any valid GC heap pointer ever have been written to this page? */ GC_INNER GC_bool GC_page_was_ever_dirty(struct hblk *h) { -# if defined(GWW_VDB) || defined(PROC_VDB) +# if defined(GWW_VDB) || defined(PROC_VDB) || defined(SOFT_VDB) word index; # ifdef MPROTECT_VDB @@ -3876,6 +4292,7 @@ if (!GC_auto_incremental || GC_GWW_AVAILABLE()) return; + GC_ASSERT(GC_page_size != 0); h_trunc = (struct hblk *)((word)h & ~(GC_page_size-1)); h_end = (struct hblk *)(((word)(h + nblocks) + GC_page_size - 1) & ~(GC_page_size - 1)); @@ -4129,6 +4546,9 @@ msg.data0 = 0; # endif +# if defined(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID) + (void)pthread_setname_np("GC-mprotect"); +# endif # if defined(THREADS) && !defined(GC_NO_THREADS_DISCOVERY) GC_darwin_register_mach_handler_thread(mach_thread_self()); # endif @@ -4221,7 +4641,7 @@ } #endif /* BROKEN_EXCEPTION_HANDLING */ -GC_INNER GC_bool GC_mprotect_dirty_init(void) +GC_INNER GC_bool GC_dirty_init(void) { kern_return_t r; mach_port_t me; @@ -4311,6 +4731,9 @@ } } # endif /* BROKEN_EXCEPTION_HANDLING */ +# if defined(CPPCHECK) + GC_noop1((word)GC_ports.os_callback0); +# endif return TRUE; } @@ -4497,6 +4920,7 @@ GC_sigbus_count = 0; # endif + GC_ASSERT(GC_page_size != 0); if (GC_mprotect_state == GC_MP_NORMAL) { /* common case */ struct hblk * h = (struct hblk*)((word)addr & ~(GC_page_size-1)); size_t i; @@ -4532,6 +4956,7 @@ #ifndef HAVE_INCREMENTAL_PROTECTION_NEEDS GC_API int GC_CALL GC_incremental_protection_needs(void) { + GC_ASSERT(GC_is_initialized); return GC_PROTECTS_NONE; } #endif /* !HAVE_INCREMENTAL_PROTECTION_NEEDS */ @@ -4740,7 +5165,6 @@ { int i; static int reentry_count = 0; - GC_bool stop = FALSE; DCL_LOCK_STATE; /* FIXME: This should probably use a different lock, so that we */ @@ -4754,8 +5178,13 @@ # else GC_err_printf("\tCall chain at allocation:\n"); # endif - for (i = 0; i < NFRAMES && !stop; i++) { - if (infoi.ci_pc == 0) break; + for (i = 0; i < NFRAMES; i++) { +# if defined(LINUX) && !defined(SMALL_CONFIG) + GC_bool stop = FALSE; +# endif + + if (0 == infoi.ci_pc) + break; # if NARGS > 0 { int j; @@ -4795,7 +5224,7 @@ } # if defined(LINUX) && !defined(SMALL_CONFIG) /* Try for a line number. */ - { + do { FILE *pipe; # define EXE_SZ 100 static char exe_nameEXE_SZ; @@ -4809,16 +5238,18 @@ char preload_bufPRELOAD_SZ; static GC_bool found_exe_name = FALSE; static GC_bool will_fail = FALSE; - int ret_code; + /* Try to get it via a hairy and expensive scheme. */ /* First we get the name of the executable: */ - if (will_fail) goto out; + if (will_fail) + break; if (!found_exe_name) { - ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ); + int ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ); + if (ret_code < 0 || ret_code >= EXE_SZ || exe_name0 != '/') { will_fail = TRUE; /* Don't try again. */ - goto out; + break; } exe_nameret_code = '\0'; found_exe_name = TRUE; @@ -4835,7 +5266,7 @@ size_t old_len = strlen(old_preload); if (old_len >= PRELOAD_SZ) { will_fail = TRUE; - goto out; + break; } BCOPY(old_preload, preload_buf, old_len + 1); unsetenv ("LD_PRELOAD"); @@ -4845,21 +5276,22 @@ && 0 != setenv ("LD_PRELOAD", preload_buf, 0)) { WARN("Failed to reset LD_PRELOAD\n", 0); } - if (pipe == NULL - || (result_len = fread(result_buf, 1, - RESULT_SZ - 1, pipe)) == 0) { - if (pipe != NULL) pclose(pipe); + if (NULL == pipe) { + will_fail = TRUE; + break; + } + result_len = fread(result_buf, 1, RESULT_SZ - 1, pipe); + (void)pclose(pipe); + if (0 == result_len) { will_fail = TRUE; - goto out; + break; } if (result_bufresult_len - 1 == '\n') --result_len; result_bufresult_len = 0; if (result_buf0 == '?' || (result_bufresult_len-2 == ':' - && result_bufresult_len-1 == '0')) { - pclose(pipe); - goto out; - } + && result_bufresult_len-1 == '0')) + break; /* Get rid of embedded newline, if any. Test for "main" */ { char * nl = strchr(result_buf, '\n'); @@ -4868,8 +5300,10 @@ *nl = ':'; } if (strncmp(result_buf, "main", - nl != NULL ? (size_t)(nl - result_buf) - : result_len) == 0) { + nl != NULL + ? (size_t)((word)nl /* a cppcheck workaround */ + - COVERT_DATAFLOW(result_buf)) + : result_len) == 0) { stop = TRUE; } } @@ -4880,10 +5314,12 @@ " 0x%lx", (unsigned long)infoi.ci_pc); result_bufsizeof(result_buf) - 1 = '\0'; } +# if defined(CPPCHECK) + GC_noop1((unsigned char)name0); + /* name computed previously is discarded */ +# endif name = result_buf; - pclose(pipe); - out:; - } + } while (0); # endif /* LINUX */ GC_err_printf("\t\t%s\n", name); # if defined(GC_HAVE_BUILTIN_BACKTRACE) \ @@ -4892,6 +5328,10 @@ free(sym_name); /* May call GC_debug_free; that's OK */ # endif } +# if defined(LINUX) && !defined(SMALL_CONFIG) + if (stop) + break; +# endif } LOCK(); --reentry_count; @@ -4905,11 +5345,10 @@ /* addresses in FIND_LEAK output. */ void GC_print_address_map(void) { - char *maps; + const char *maps = GC_get_maps(); GC_err_printf("---------- Begin address map ----------\n"); - maps = GC_get_maps(); - GC_err_puts(maps != NULL ? maps : "Failed to get map!\n"); + GC_err_puts(maps); GC_err_printf("---------- End address map ----------\n"); } #endif /* LINUX && ELF */
View file
_service:tar_scm:gc-8.0.6.tar.gz/pthread_start.c -> _service:tar_scm:gc-8.2.2.tar.gz/pthread_start.c
Changed
@@ -22,7 +22,7 @@ /* case at the top of the file. FIXME: it's still unclear whether this */ /* will actually cause the exit handler to be invoked last when */ /* thread_exit is called (and if -fexceptions is used). */ -#if defined(__GNUC__) && defined(__linux__) +#if !defined(DONT_UNDEF_EXCEPTIONS) && defined(__GNUC__) && defined(__linux__) /* We undefine __EXCEPTIONS to avoid using GCC __cleanup__ attribute. */ /* The current NPTL implementation of pthread_cleanup_push uses */ /* __cleanup__ attribute when __EXCEPTIONS is defined (-fexceptions). */
View file
_service:tar_scm:gc-8.0.6.tar.gz/pthread_stop_world.c -> _service:tar_scm:gc-8.2.2.tar.gz/pthread_stop_world.c
Changed
@@ -4,6 +4,7 @@ * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. * All rights reserved. + * Copyright (c) 2008-2020 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -18,13 +19,44 @@ #include "private/pthread_support.h" #if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) && \ - !defined(GC_DARWIN_THREADS) && !defined(SN_TARGET_ORBIS) \ + !defined(GC_DARWIN_THREADS) && !defined(PLATFORM_STOP_WORLD) \ && !defined(SN_TARGET_PSP2) #ifdef NACL - # include <unistd.h> # include <sys/time.h> +#elif defined(GC_OPENBSD_UTHREADS) +# include <pthread_np.h> +#else +# include <signal.h> +# include <semaphore.h> +# include <errno.h> +# include <time.h> /* for nanosleep() */ +# include <unistd.h> +#endif /* !GC_OPENBSD_UTHREADS && !NACL */ + +#ifndef GC_OPENBSD_UTHREADS + GC_INLINE void GC_usleep(unsigned us) + { +# if defined(LINT2) || defined(THREAD_SANITIZER) + /* Workaround "waiting while holding a lock" static analyzer warning. */ + /* Workaround a rare hang in usleep() trying to acquire TSan Lock. */ + while (us-- > 0) + sched_yield(); /* pretending it takes 1us */ +# elif defined(CPPCHECK) /* || _POSIX_C_SOURCE >= 199309L */ + struct timespec ts; + + ts.tv_sec = 0; + ts.tv_nsec = us * 1000; + /* This requires _POSIX_TIMERS feature. */ + (void)nanosleep(&ts, NULL); +# else + usleep(us); +# endif + } +#endif /* !GC_OPENBSD_UTHREADS */ + +#ifdef NACL STATIC int GC_nacl_num_gc_threads = 0; STATIC __thread int GC_nacl_thread_idx = -1; @@ -36,17 +68,7 @@ volatile int GC_nacl_thread_parkedMAX_NACL_GC_THREADS; int GC_nacl_thread_usedMAX_NACL_GC_THREADS; -#elif defined(GC_OPENBSD_UTHREADS) - -# include <pthread_np.h> - -#else /* !GC_OPENBSD_UTHREADS && !NACL */ - -#include <signal.h> -#include <semaphore.h> -#include <errno.h> -#include <time.h> /* for nanosleep() */ -#include <unistd.h> +#elif !defined(GC_OPENBSD_UTHREADS) #if (!defined(AO_HAVE_load_acquire) || !defined(AO_HAVE_store_release)) \ && !defined(CPPCHECK) @@ -57,10 +79,6 @@ /* It's safe to call original pthread_sigmask() here. */ #undef pthread_sigmask -#ifdef GC_ENABLE_SUSPEND_THREAD - static void *GC_CALLBACK suspend_self_inner(void *client_data); -#endif - #ifdef DEBUG_THREADS # ifndef NSIG # if defined(MAXSIG) @@ -127,8 +145,9 @@ /* before they are expected to stop (unless */ /* they have stopped voluntarily). */ -#if defined(GC_OSF1_THREADS) || defined(THREAD_SANITIZER) \ - || defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) +#ifndef NO_RETRY_SIGNALS + /* Any platform could lose signals, so let's be conservative and */ + /* always enable signals retry logic. */ STATIC GC_bool GC_retry_signals = TRUE; #else STATIC GC_bool GC_retry_signals = FALSE; @@ -153,6 +172,10 @@ # else # define SIG_THR_RESTART SIGRTMIN + 5 # endif +# elif defined(GC_FREEBSD_THREADS) && defined(__GLIBC__) +# define SIG_THR_RESTART (32+5) +# elif defined(GC_FREEBSD_THREADS) || defined(HURD) || defined(RTEMS) +# define SIG_THR_RESTART SIGUSR2 # else # define SIG_THR_RESTART SIGXCPU # endif @@ -229,17 +252,13 @@ ABORT("Bad signal in suspend_handler"); } -# if defined(IA64) || defined(HP_PA) || defined(M68K) +# if defined(E2K) || defined(HP_PA) || defined(IA64) || defined(M68K) \ + || defined(NO_SA_SIGACTION) GC_with_callee_saves_pushed(GC_suspend_handler_inner, NULL); # else - /* We believe that in all other cases the full context is already */ + /* We believe that in this case the full context is already */ /* in the signal handler frame. */ - { -# ifdef NO_SA_SIGACTION - void *context = 0; -# endif GC_suspend_handler_inner(NULL, context); - } # endif errno = old_errno; } @@ -292,7 +311,8 @@ /* avoid the related TSan warning. */ # ifdef SPARC ao_store_async((volatile AO_t *)&me->stop_info.stack_ptr, - (AO_t)GC_save_regs_in_stack()); + (AO_t)GC_save_regs_in_stack()); + /* TODO: regs saving already done by GC_with_callee_saves_pushed */ # else # ifdef IA64 me -> backing_store_ptr = GC_save_regs_in_stack(); @@ -307,7 +327,14 @@ { pthread_t self = pthread_self(); GC_thread me; +# ifdef E2K + ptr_t bs_lo; + size_t stack_size; +# endif IF_CANCEL(int cancel_state;) +# ifdef GC_ENABLE_SUSPEND_THREAD + word suspend_cnt; +# endif AO_t my_stop_count = ao_load_acquire_async(&GC_stop_count); /* After the barrier, this thread should see */ /* the actual content of GC_threads. */ @@ -329,20 +356,14 @@ me = GC_lookup_thread_async(self); # ifdef GC_ENABLE_SUSPEND_THREAD - if (ao_load_async(&me->suspended_ext)) { - GC_store_stack_ptr(me); - sem_post(&GC_suspend_ack_sem); - suspend_self_inner(me); -# ifdef DEBUG_THREADS - GC_log_printf("Continuing %p on GC_resume_thread\n", (void *)self); -# endif - RESTORE_CANCEL(cancel_state); - return; - } + suspend_cnt = (word)ao_load_async(&(me -> stop_info.ext_suspend_cnt)); # endif - if (((word)me->stop_info.last_stop_count & ~(word)THREAD_RESTARTED) - == (word)my_stop_count) { + == (word)my_stop_count +# ifdef GC_ENABLE_SUSPEND_THREAD + && (suspend_cnt & 1) == 0 +# endif + ) { /* Duplicate signal. OK if we are retrying. */ if (!GC_retry_signals) { WARN("Duplicate suspend signal in thread %p\n", self); @@ -351,21 +372,13 @@ return; } GC_store_stack_ptr(me); - -# ifdef THREAD_SANITIZER - /* TSan disables signals around signal handlers. Without */ - /* a pthread_sigmask call, sigsuspend may block forever. */ - { - sigset_t set; - sigemptyset(&set); - GC_ASSERT(GC_sig_suspend != SIGNAL_UNSET); - GC_ASSERT(GC_sig_thr_restart != SIGNAL_UNSET); - sigaddset(&set, GC_sig_suspend); - sigaddset(&set, GC_sig_thr_restart); - if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) != 0) - ABORT("pthread_sigmask failed in suspend handler"); - } +# ifdef E2K + GC_ASSERT(NULL == me -> backing_store_end); + GET_PROCEDURE_STACK_LOCAL(&bs_lo, &stack_size); + me -> backing_store_end = bs_lo; + me -> backing_store_ptr = bs_lo + stack_size; # endif + /* Tell the thread that wants to stop the world that this */ /* thread has been stopped. Note that sem_post() is */ /* the only async-signal-safe primitive in LinuxThreads. */ @@ -383,13 +396,26 @@ /* really safe to proceed. Under normal circumstances, */ /* this code should not be executed. */ do { - sigsuspend (&suspend_handler_mask); - } while (ao_load_acquire_async(&GC_world_is_stopped) - && ao_load_async(&GC_stop_count) == my_stop_count); + sigsuspend(&suspend_handler_mask); + /* Iterate while not restarting the world or thread is suspended. */ + } while ((ao_load_acquire_async(&GC_world_is_stopped) + && ao_load_async(&GC_stop_count) == my_stop_count) +# ifdef GC_ENABLE_SUSPEND_THREAD + || ((suspend_cnt & 1) != 0 + && (word)ao_load_async(&(me -> stop_info.ext_suspend_cnt)) + == suspend_cnt) +# endif + ); # ifdef DEBUG_THREADS GC_log_printf("Continuing %p\n", (void *)self); # endif +# ifdef E2K + GC_ASSERT(me -> backing_store_end == bs_lo); + FREE_PROCEDURE_STACK_LOCAL(bs_lo, stack_size); + me -> backing_store_ptr = NULL; + me -> backing_store_end = NULL; +# endif # ifndef GC_NETBSD_THREADS_WORKAROUND if (GC_retry_signals) # endif @@ -430,14 +456,19 @@ # endif } +# define WAIT_UNIT 3000 /* us */ + static int resend_lost_signals(int n_live_threads, int (*suspend_restart_all)(void)) { -# define WAIT_UNIT 3000 -# define RETRY_INTERVAL 100000 +# define RETRY_INTERVAL 100000 /* us */ +# define RESEND_SIGNALS_LIMIT 150 if (n_live_threads > 0) { unsigned long wait_usecs = 0; /* Total wait since retry. */ + int retry = 0; + int prev_sent = 0; + for (;;) { int ack_count; @@ -447,37 +478,60 @@ if (wait_usecs > RETRY_INTERVAL) { int newly_sent = suspend_restart_all(); - GC_COND_LOG_PRINTF("Resent %d signals after timeout\n", newly_sent); + if (newly_sent != prev_sent) { + retry = 0; /* restart the counter */ + } else if (++retry >= RESEND_SIGNALS_LIMIT) /* no progress */ + ABORT_ARG1("Signals delivery fails constantly", + " at GC #%lu", (unsigned long)GC_gc_no); + + GC_COND_LOG_PRINTF("Resent %d signals after timeout, retry: %d\n", + newly_sent, retry); sem_getvalue(&GC_suspend_ack_sem, &ack_count); if (newly_sent < n_live_threads - ack_count) { WARN("Lost some threads while stopping or starting world?!\n", 0); n_live_threads = ack_count + newly_sent; } + prev_sent = newly_sent; wait_usecs = 0; } - -# ifdef LINT2 - /* Workaround "waiting while holding a lock" warning. */ -# undef WAIT_UNIT -# define WAIT_UNIT 1 - sched_yield(); -# elif defined(CPPCHECK) /* || _POSIX_C_SOURCE >= 199309L */ - { - struct timespec ts; - - ts.tv_sec = 0; - ts.tv_nsec = WAIT_UNIT * 1000; - (void)nanosleep(&ts, NULL); - } -# else - usleep(WAIT_UNIT); -# endif + GC_usleep(WAIT_UNIT); wait_usecs += WAIT_UNIT; } } return n_live_threads; } +#ifdef HAVE_CLOCK_GETTIME +# define TS_NSEC_ADD(ts, ns) \ + (ts.tv_nsec += (ns), \ + (void)(ts.tv_nsec >= 1000000L*1000 ? \ + (ts.tv_nsec -= 1000000L*1000, ts.tv_sec++, 0) : 0)) +#endif + +static void resend_lost_signals_retry(int n_live_threads, + int (*suspend_restart_all)(void)) +{ +# if defined(HAVE_CLOCK_GETTIME) && !defined(DONT_TIMEDWAIT_ACK_SEM) +# define TIMEOUT_BEFORE_RESEND 10000 /* us */ + int i; + struct timespec ts; + + if (n_live_threads > 0 && clock_gettime(CLOCK_REALTIME, &ts) == 0) { + TS_NSEC_ADD(ts, TIMEOUT_BEFORE_RESEND * 1000); + /* First, try to wait for the semaphore with some timeout. */ + /* On failure, fallback to WAIT_UNIT pause and resend of the signal. */ + for (i = 0; i < n_live_threads; i++) { + if (0 != sem_timedwait(&GC_suspend_ack_sem, &ts)) + break; /* Wait timed out or any other error. */ + } + /* Update the count of threads to wait the ack from. */ + n_live_threads -= i; + } +# endif + n_live_threads = resend_lost_signals(n_live_threads, suspend_restart_all); + suspend_restart_barrier(n_live_threads); +} + STATIC void GC_restart_handler(int sig) { # if defined(DEBUG_THREADS) @@ -504,26 +558,43 @@ EXTERN_C_BEGIN extern int tkill(pid_t tid, int sig); /* from sys/linux-unistd.h */ EXTERN_C_END +# define THREAD_SYSTEM_ID(t) (t)->kernel_id +# else +# define THREAD_SYSTEM_ID(t) (t)->id +# endif + +# ifndef RETRY_TKILL_EAGAIN_LIMIT +# define RETRY_TKILL_EAGAIN_LIMIT 16 +# endif + + static int raise_signal(GC_thread p, int sig) + { + int res; +# ifdef RETRY_TKILL_ON_EAGAIN + int retry; - static int android_thread_kill(pid_t tid, int sig) + for (retry = 0; ; retry++) +# endif { - int ret; - int old_errno = errno; +# ifdef USE_TKILL_ON_ANDROID + int old_errno = errno; - ret = tkill(tid, sig); - if (ret < 0) { - ret = errno; + res = tkill(THREAD_SYSTEM_ID(p), sig); + if (res < 0) { + res = errno; errno = old_errno; - } - return ret; + } +# else + res = pthread_kill(THREAD_SYSTEM_ID(p), sig); +# endif +# ifdef RETRY_TKILL_ON_EAGAIN + if (res != EAGAIN || retry >= RETRY_TKILL_EAGAIN_LIMIT) break; + /* A temporal overflow of the real-time signal queue. */ + GC_usleep(WAIT_UNIT); +# endif } - -# define THREAD_SYSTEM_ID(t) (t)->kernel_id -# define RAISE_SIGNAL(t, sig) android_thread_kill(THREAD_SYSTEM_ID(t), sig) -# else -# define THREAD_SYSTEM_ID(t) (t)->id -# define RAISE_SIGNAL(t, sig) pthread_kill(THREAD_SYSTEM_ID(t), sig) -# endif /* !USE_TKILL_ON_ANDROID */ + return res; + } # ifdef GC_ENABLE_SUSPEND_THREAD # include <sys/time.h> @@ -541,40 +612,53 @@ (void)select(0, 0, 0, 0, &tv); } - static void *GC_CALLBACK suspend_self_inner(void *client_data) { - GC_thread me = (GC_thread)client_data; + GC_INNER void GC_suspend_self_inner(GC_thread me, word suspend_cnt) { + IF_CANCEL(int cancel_state;) - while (ao_load_acquire_async(&me->suspended_ext)) { - /* TODO: Use sigsuspend() instead. */ + GC_ASSERT((suspend_cnt & 1) != 0); + DISABLE_CANCEL(cancel_state); +# ifdef DEBUG_THREADS + GC_log_printf("Suspend self: %p\n", (void *)(me -> id)); +# endif + while ((word)ao_load_acquire_async(&(me -> stop_info.ext_suspend_cnt)) + == suspend_cnt) { + /* TODO: Use sigsuspend() even for self-suspended threads. */ GC_brief_async_signal_safe_sleep(); } - return NULL; +# ifdef DEBUG_THREADS + GC_log_printf("Resume self: %p\n", (void *)(me -> id)); +# endif + RESTORE_CANCEL(cancel_state); } GC_API void GC_CALL GC_suspend_thread(GC_SUSPEND_THREAD_ID thread) { GC_thread t; + word suspend_cnt; IF_CANCEL(int cancel_state;) DCL_LOCK_STATE; LOCK(); t = GC_lookup_thread((pthread_t)thread); - if (t == NULL || t -> suspended_ext) { + if (NULL == t) { UNLOCK(); return; } - - /* Set the flag making the change visible to the signal handler. */ - AO_store_release(&t->suspended_ext, TRUE); - - if (THREAD_EQUAL((pthread_t)thread, pthread_self())) { + suspend_cnt = (word)(t -> stop_info.ext_suspend_cnt); + if ((suspend_cnt & 1) != 0) /* already suspended? */ { + GC_ASSERT(!THREAD_EQUAL((pthread_t)thread, pthread_self())); UNLOCK(); - /* It is safe as "t" cannot become invalid here (no race with */ - /* GC_unregister_my_thread). */ - (void)GC_do_blocking(suspend_self_inner, t); return; } - if ((t -> flags & FINISHED) != 0) { - /* Terminated but not joined yet. */ + if ((t -> flags & FINISHED) != 0 || t -> thread_blocked) { + t -> stop_info.ext_suspend_cnt = (AO_t)(suspend_cnt | 1); /* suspend */ + /* Terminated but not joined yet, or in do-blocking state. */ + UNLOCK(); + return; + } + + if (THREAD_EQUAL((pthread_t)thread, pthread_self())) { + t -> stop_info.ext_suspend_cnt = (AO_t)(suspend_cnt | 1); + GC_with_callee_saves_pushed(GC_suspend_self_blocked, (ptr_t)t); UNLOCK(); return; } @@ -601,8 +685,12 @@ /* be trying to acquire this lock too, and the suspend handler */ /* execution is deferred until the write fault handler completes. */ + /* Set the flag making the change visible to the signal handler. */ + AO_store_release(&(t -> stop_info.ext_suspend_cnt), + (AO_t)(suspend_cnt | 1)); + /* TODO: Support GC_retry_signals (not needed for TSan) */ - switch (RAISE_SIGNAL(t, GC_sig_suspend)) { + switch (raise_signal(t, GC_sig_suspend)) { /* ESRCH cannot happen as terminated threads are handled above. */ case 0: break; @@ -613,10 +701,7 @@ /* Wait for the thread to complete threads table lookup and */ /* stack_ptr assignment. */ GC_ASSERT(GC_thr_initialized); - while (sem_wait(&GC_suspend_ack_sem) != 0) { - if (errno != EINTR) - ABORT("sem_wait for handler failed (suspend_self)"); - } + suspend_restart_barrier(1); if (GC_manual_vdb) GC_release_dirty_lock(); RESTORE_CANCEL(cancel_state); @@ -629,8 +714,33 @@ LOCK(); t = GC_lookup_thread((pthread_t)thread); - if (t != NULL) - AO_store(&t->suspended_ext, FALSE); + if (t != NULL) { + word suspend_cnt = (word)(t -> stop_info.ext_suspend_cnt); + + if ((suspend_cnt & 1) != 0) /* is suspended? */ { + /* Mark the thread as not suspended - it will be resumed shortly. */ + AO_store(&(t -> stop_info.ext_suspend_cnt), (AO_t)(suspend_cnt + 1)); + + if ((t -> flags & FINISHED) == 0 && !(t -> thread_blocked)) { + int result = raise_signal(t, GC_sig_thr_restart); + + /* TODO: Support signal resending on GC_retry_signals */ + if (result != 0) + ABORT_ARG1("pthread_kill failed in GC_resume_thread", + ": errcode= %d", result); +# ifndef GC_NETBSD_THREADS_WORKAROUND + if (GC_retry_signals) +# endif + { + IF_CANCEL(int cancel_state;) + + DISABLE_CANCEL(cancel_state); + suspend_restart_barrier(1); + RESTORE_CANCEL(cancel_state); + } + } + } + } UNLOCK(); } @@ -641,7 +751,7 @@ LOCK(); t = GC_lookup_thread((pthread_t)thread); - if (t != NULL && t -> suspended_ext) + if (t != NULL && (t -> stop_info.ext_suspend_cnt & 1) != 0) is_suspended = (int)TRUE; UNLOCK(); return is_suspended; @@ -654,11 +764,6 @@ # undef ao_store_release_async #endif /* !GC_OPENBSD_UTHREADS && !NACL */ -#ifdef IA64 -# define IF_IA64(x) x -#else -# define IF_IA64(x) -#endif /* We hold allocation lock. Should do exactly the right thing if the */ /* world is stopped. Should not fail if it isn't. */ GC_INNER void GC_push_all_stacks(void) @@ -668,11 +773,16 @@ int i; GC_thread p; ptr_t lo, hi; - /* On IA64, we also need to scan the register backing store. */ - IF_IA64(ptr_t bs_lo; ptr_t bs_hi;) +# if defined(E2K) || defined(IA64) + /* We also need to scan the register backing store. */ + ptr_t bs_lo, bs_hi; +# endif struct GC_traced_stack_sect_s *traced_stack_sect; pthread_t self = pthread_self(); word total_size = 0; +# ifdef E2K + GC_bool is_stopped = (GC_bool)GC_world_is_stopped; +# endif if (!EXPECT(GC_thr_initialized, TRUE)) GC_thr_init(); @@ -687,15 +797,30 @@ if (THREAD_EQUAL(p -> id, self)) { GC_ASSERT(!p->thread_blocked); # ifdef SPARC - lo = (ptr_t)GC_save_regs_in_stack(); + lo = GC_save_regs_in_stack(); # else - lo = GC_approx_sp(); + lo = GC_approx_sp(); +# ifdef IA64 + bs_hi = GC_save_regs_in_stack(); +# elif defined(E2K) + GC_ASSERT(NULL == p -> backing_store_end); + (void)GC_save_regs_in_stack(); + { + size_t stack_size; + GET_PROCEDURE_STACK_LOCAL(&bs_lo, &stack_size); + bs_hi = bs_lo + stack_size; + } +# endif # endif found_me = TRUE; - IF_IA64(bs_hi = (ptr_t)GC_save_regs_in_stack();) } else { lo = (ptr_t)AO_load((volatile AO_t *)&p->stop_info.stack_ptr); - IF_IA64(bs_hi = p -> backing_store_ptr;) +# ifdef IA64 + bs_hi = p -> backing_store_ptr; +# elif defined(E2K) + bs_lo = p -> backing_store_end; + bs_hi = p -> backing_store_ptr; +# endif if (traced_stack_sect != NULL && traced_stack_sect->saved_stack_ptr == lo) { /* If the thread has never been stopped since the recent */ @@ -706,14 +831,18 @@ } if ((p -> flags & MAIN_THREAD) == 0) { hi = p -> stack_end; - IF_IA64(bs_lo = p -> backing_store_end); +# ifdef IA64 + bs_lo = p -> backing_store_end; +# endif } else { /* The original stack. */ hi = GC_stackbottom; - IF_IA64(bs_lo = BACKING_STORE_BASE;) +# ifdef IA64 + bs_lo = BACKING_STORE_BASE; +# endif } # ifdef DEBUG_THREADS - GC_log_printf("Stack for thread %p = %p,%p)\n", + GC_log_printf("Stack for thread %p is %p,%p)\n", (void *)p->id, (void *)lo, (void *)hi); # endif if (0 == lo) ABORT("GC_push_all_stacks: sp not set!"); @@ -735,11 +864,20 @@ (ptr_t)(p -> stop_info.reg_storage + NACL_GC_REG_STORAGE_SIZE)); total_size += NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t); # endif -# ifdef IA64 +# ifdef E2K + if (!is_stopped && !p->thread_blocked +# ifdef GC_ENABLE_SUSPEND_THREAD + && (p -> stop_info.ext_suspend_cnt & 1) == 0 +# endif + && !THREAD_EQUAL(p -> id, self)) + continue; /* procedure stack buffer has already been freed */ +# endif +# if defined(E2K) || defined(IA64) # ifdef DEBUG_THREADS - GC_log_printf("Reg stack for thread %p = %p,%p)\n", + GC_log_printf("Reg stack for thread %p is %p,%p)\n", (void *)p->id, (void *)bs_lo, (void *)bs_hi); # endif + GC_ASSERT(bs_lo != NULL && bs_hi != NULL); /* FIXME: This (if p->id==self) may add an unbounded number of */ /* entries, and hence overflow the mark stack, which is bad. */ GC_push_all_register_sections(bs_lo, bs_hi, @@ -747,6 +885,10 @@ traced_stack_sect); total_size += bs_hi - bs_lo; /* bs_lo <= bs_hi */ # endif +# ifdef E2K + if (THREAD_EQUAL(p -> id, self)) + FREE_PROCEDURE_STACK_LOCAL(bs_lo, (size_t)(bs_hi - bs_lo)); +# endif } } GC_VERBOSE_LOG_PRINTF("Pushed %d thread stacks\n", (int)nthreads); @@ -783,7 +925,7 @@ if (p -> thread_blocked) /* Will wait */ continue; # ifndef GC_OPENBSD_UTHREADS # ifdef GC_ENABLE_SUSPEND_THREAD - if (p -> suspended_ext) continue; + if ((p -> stop_info.ext_suspend_cnt & 1) != 0) continue; # endif if (AO_load(&p->stop_info.last_stop_count) == GC_stop_count) continue; /* matters only if GC_retry_signals */ @@ -814,7 +956,7 @@ /* is performed in GC_stop_world because */ /* GC_release_dirty_lock cannot be called before */ /* acknowledging the thread is really suspended. */ - result = RAISE_SIGNAL(p, GC_sig_suspend); + result = raise_signal(p, GC_sig_suspend); switch(result) { case ESRCH: /* Not really there anymore. Possible? */ @@ -836,14 +978,13 @@ } # else /* NACL */ -# ifndef NACL_PARK_WAIT_NANOSECONDS -# define NACL_PARK_WAIT_NANOSECONDS (100 * 1000) +# ifndef NACL_PARK_WAIT_USEC +# define NACL_PARK_WAIT_USEC 100 /* us */ # endif -# define NANOS_PER_SECOND (1000UL * 1000 * 1000) unsigned long num_sleeps = 0; # ifdef DEBUG_THREADS - GC_log_printf("pthread_stop_world: num_threads=%d\n", + GC_log_printf("pthread_stop_world: number of threads: %d\n", GC_nacl_num_gc_threads - 1); # endif GC_nacl_thread_parker = pthread_self(); @@ -851,9 +992,8 @@ if (GC_manual_vdb) GC_acquire_dirty_lock(); - while (1) { + for (;;) { int num_threads_parked = 0; - struct timespec ts; int num_used = 0; /* Check the 'parked' flag for each thread the GC knows about. */ @@ -871,15 +1011,12 @@ /* -1 for the current thread. */ if (num_threads_parked >= GC_nacl_num_gc_threads - 1) break; - ts.tv_sec = 0; - ts.tv_nsec = NACL_PARK_WAIT_NANOSECONDS; # ifdef DEBUG_THREADS GC_log_printf("Sleep waiting for %d threads to park...\n", GC_nacl_num_gc_threads - num_threads_parked - 1); # endif - /* This requires _POSIX_TIMERS feature. */ - nanosleep(&ts, 0); - if (++num_sleeps > NANOS_PER_SECOND / NACL_PARK_WAIT_NANOSECONDS) { + GC_usleep(NACL_PARK_WAIT_USEC); + if (++num_sleeps > (1000 * 1000) / NACL_PARK_WAIT_USEC) { WARN("GC appears stalled waiting for %" WARN_PRIdPTR " threads to park...\n", GC_nacl_num_gc_threads - num_threads_parked - 1); @@ -930,9 +1067,11 @@ } AO_store_release(&GC_world_is_stopped, TRUE); n_live_threads = GC_suspend_all(); - if (GC_retry_signals) - n_live_threads = resend_lost_signals(n_live_threads, GC_suspend_all); - suspend_restart_barrier(n_live_threads); + if (GC_retry_signals) { + resend_lost_signals_retry(n_live_threads, GC_suspend_all); + } else { + suspend_restart_barrier(n_live_threads); + } if (GC_manual_vdb) GC_release_dirty_lock(); /* cannot be done in GC_suspend_all */ # endif @@ -1121,7 +1260,7 @@ if (p -> thread_blocked) continue; # ifndef GC_OPENBSD_UTHREADS # ifdef GC_ENABLE_SUSPEND_THREAD - if (p -> suspended_ext) continue; + if ((p -> stop_info.ext_suspend_cnt & 1) != 0) continue; # endif if (GC_retry_signals && AO_load(&p->stop_info.last_stop_count) @@ -1138,7 +1277,7 @@ if (GC_on_thread_event) GC_on_thread_event(GC_EVENT_THREAD_UNSUSPENDED, (void *)p->id); # else - result = RAISE_SIGNAL(p, GC_sig_thr_restart); + result = raise_signal(p, GC_sig_thr_restart); switch(result) { case ESRCH: /* Not really there anymore. Possible? */ @@ -1179,17 +1318,17 @@ /* the list of functions which synchronize memory). */ # endif n_live_threads = GC_restart_all(); -# ifndef GC_OPENBSD_UTHREADS - if (GC_retry_signals) - n_live_threads = resend_lost_signals(n_live_threads, GC_restart_all); +# ifdef GC_OPENBSD_UTHREADS + (void)n_live_threads; +# else + if (GC_retry_signals) { + resend_lost_signals_retry(n_live_threads, GC_restart_all); + } /* else */ # ifdef GC_NETBSD_THREADS_WORKAROUND - suspend_restart_barrier(n_live_threads); -# else - if (GC_retry_signals) + else { suspend_restart_barrier(n_live_threads); + } # endif -# else - (void)n_live_threads; # endif # ifdef DEBUG_THREADS GC_log_printf("World started\n");
View file
_service:tar_scm:gc-8.0.6.tar.gz/pthread_support.c -> _service:tar_scm:gc-8.2.2.tar.gz/pthread_support.c
Changed
@@ -3,6 +3,7 @@ * Copyright (c) 1996 by Silicon Graphics. All rights reserved. * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2005 by Hewlett-Packard Company. All rights reserved. + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -309,12 +310,12 @@ #endif /* THREAD_LOCAL_ALLOC */ -#ifdef PARALLEL_MARK - # ifndef MAX_MARKERS # define MAX_MARKERS 16 # endif +#ifdef PARALLEL_MARK + static ptr_t marker_spMAX_MARKERS - 1 = {0}; #ifdef IA64 static ptr_t marker_bspMAX_MARKERS - 1 = {0}; @@ -335,6 +336,40 @@ } #endif /* GC_DARWIN_THREADS */ +#ifdef HAVE_PTHREAD_SETNAME_NP_WITH_TID_AND_ARG /* NetBSD */ + static void set_marker_thread_name(unsigned id) + { + int err = pthread_setname_np(pthread_self(), "GC-marker-%zu", + (void*)(size_t)id); + if (err != 0) + WARN("pthread_setname_np failed, errno= %" WARN_PRIdPTR "\n", err); + } +#elif defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) \ + || defined(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID) + static void set_marker_thread_name(unsigned id) + { + char name_buf16; /* pthread_setname_np may fail for longer names */ + int len = sizeof("GC-marker-") - 1; + + /* Compose the name manually as snprintf may be unavailable or */ + /* "%u directive output may be truncated" warning may occur. */ + BCOPY("GC-marker-", name_buf, len); + if (id >= 10) + name_buflen++ = (char)('0' + (id / 10) % 10); + name_buflen = (char)('0' + id % 10); + name_buflen + 1 = '\0'; + +# ifdef HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID /* iOS, OS X */ + (void)pthread_setname_np(name_buf); +# else /* Linux, Solaris, etc. */ + if (pthread_setname_np(pthread_self(), name_buf) != 0) + WARN("pthread_setname_np failed\n", 0); +# endif + } +#else +# define set_marker_thread_name(id) (void)(id) +#endif + STATIC void * GC_mark_thread(void * id) { word my_mark_no = 0; @@ -344,6 +379,7 @@ DISABLE_CANCEL(cancel_state); /* Mark threads are not cancellable; they */ /* should be invisible to client. */ + set_marker_thread_name((unsigned)(word)id); marker_sp(word)id = GC_approx_sp(); # ifdef IA64 marker_bsp(word)id = GC_save_regs_in_stack(); @@ -379,15 +415,31 @@ STATIC pthread_t GC_mark_threadsMAX_MARKERS; +#ifdef GLIBC_2_1_MUTEX_HACK + /* 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 */ + /* pthread_cond_wait to die. Remove for glibc2.2. */ + /* According to the man page, we should use */ + /* PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, but that isn't actually */ + /* defined. */ + static pthread_mutex_t mark_mutex = + {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}}; +#else + static pthread_mutex_t mark_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +static int available_markers_m1 = 0; + #ifdef CAN_HANDLE_FORK - static int available_markers_m1 = 0; static pthread_cond_t mark_cv; /* initialized by GC_start_mark_threads_inner */ #else -# define available_markers_m1 GC_markers_m1 static pthread_cond_t mark_cv = PTHREAD_COND_INITIALIZER; #endif +STATIC void GC_wait_for_gc_completion(GC_bool wait_for_all); + GC_INNER void GC_start_mark_threads_inner(void) { int i; @@ -396,12 +448,13 @@ sigset_t set, oldset; # endif - GC_ASSERT(I_DONT_HOLD_LOCK()); - if (available_markers_m1 <= 0) return; + GC_ASSERT(I_HOLD_LOCK()); + ASSERT_CANCEL_DISABLED(); + if (available_markers_m1 <= 0 || GC_parallel) return; /* Skip if parallel markers disabled or already started. */ -# ifdef CAN_HANDLE_FORK - if (GC_parallel) return; + GC_wait_for_gc_completion(TRUE); +# ifdef CAN_HANDLE_FORK /* Initialize mark_cv (for the first time), or cleanup its value */ /* after forking in the child process. All the marker threads in */ /* the parent process were blocked on this variable at fork, so */ @@ -453,21 +506,20 @@ if (REAL_FUNC(pthread_sigmask)(SIG_BLOCK, &set, &oldset) < 0) { WARN("pthread_sigmask set failed, no markers started," - " errno = %" WARN_PRIdPTR "\n", errno); + " errno= %" WARN_PRIdPTR "\n", errno); GC_markers_m1 = 0; (void)pthread_attr_destroy(&attr); return; } # endif /* !NO_MARKER_SPECIAL_SIGMASK */ -# ifdef CAN_HANDLE_FORK - /* To have proper GC_parallel value in GC_help_marker. */ - GC_markers_m1 = available_markers_m1; -# endif + /* To have proper GC_parallel value in GC_help_marker. */ + GC_markers_m1 = available_markers_m1; + for (i = 0; i < available_markers_m1; ++i) { if (0 != REAL_FUNC(pthread_create)(GC_mark_threads + i, &attr, GC_mark_thread, (void *)(word)i)) { - WARN("Marker thread creation failed, errno = %" WARN_PRIdPTR "\n", + WARN("Marker thread creation failed, errno= %" WARN_PRIdPTR "\n", errno); /* Don't try to create other marker threads. */ GC_markers_m1 = i; @@ -478,7 +530,7 @@ # ifndef NO_MARKER_SPECIAL_SIGMASK /* Restore previous signal mask. */ if (REAL_FUNC(pthread_sigmask)(SIG_SETMASK, &oldset, NULL) < 0) { - WARN("pthread_sigmask restore failed, errno = %" WARN_PRIdPTR "\n", + WARN("pthread_sigmask restore failed, errno= %" WARN_PRIdPTR "\n", errno); } # endif @@ -494,11 +546,19 @@ GC_INNER volatile GC_thread GC_threadsTHREAD_TABLE_SZ = {0}; +/* It may not be safe to allocate when we register the first thread. */ +/* As "next" and "status" fields are unused, no need to push this */ +/* (but "backing_store_end" field should be pushed on E2K). */ +static struct GC_Thread_Rep first_thread; + void GC_push_thread_structures(void) { GC_ASSERT(I_HOLD_LOCK()); GC_PUSH_ALL_SYM(GC_threads); -# if defined(THREAD_LOCAL_ALLOC) +# ifdef E2K + GC_PUSH_ALL_SYM(first_thread.backing_store_end); +# endif +# if defined(THREAD_LOCAL_ALLOC) && defined(USE_CUSTOM_SPECIFIC) GC_PUSH_ALL_SYM(GC_thread_key); # endif } @@ -521,10 +581,6 @@ } #endif /* DEBUG_THREADS */ -/* It may not be safe to allocate when we register the first thread. */ -/* As "next" and "status" fields are unused, no need to push this. */ -static struct GC_Thread_Rep first_thread; - /* Add a thread to GC_threads. We assume it wasn't already there. */ /* Caller holds allocation lock. */ STATIC GC_thread GC_new_thread(pthread_t id) @@ -580,7 +636,7 @@ GC_thread prev = NULL; # ifdef DEBUG_THREADS - GC_log_printf("Deleting thread %p, n_threads = %d\n", + GC_log_printf("Deleting thread %p, n_threads= %d\n", (void *)id, GC_count_threads()); # endif @@ -638,7 +694,7 @@ GC_INTERNAL_FREE(p); # ifdef DEBUG_THREADS - GC_log_printf("Deleted thread %p, n_threads = %d\n", + GC_log_printf("Deleted thread %p, n_threads= %d\n", (void *)id, GC_count_threads()); # endif } @@ -657,32 +713,37 @@ return(p); } -/* Called by GC_finalize() (in case of an allocation failure observed). */ -GC_INNER void GC_reset_finalizer_nested(void) -{ - GC_thread me = GC_lookup_thread(pthread_self()); - me->finalizer_nested = 0; -} +#ifndef GC_NO_FINALIZATION + /* Called by GC_finalize() (in case of an allocation failure observed). */ + GC_INNER void GC_reset_finalizer_nested(void) + { + GC_thread me = GC_lookup_thread(pthread_self()); -/* Checks and updates the thread-local level of finalizers recursion. */ -/* Returns NULL if GC_invoke_finalizers() should not be called by the */ -/* collector (to minimize the risk of a deep finalizers recursion), */ -/* otherwise returns a pointer to the thread-local finalizer_nested. */ -/* Called by GC_notify_or_invoke_finalizers() only (the lock is held). */ -GC_INNER unsigned char *GC_check_finalizer_nested(void) -{ - GC_thread me = GC_lookup_thread(pthread_self()); - unsigned nesting_level = me->finalizer_nested; - if (nesting_level) { - /* We are inside another GC_invoke_finalizers(). */ - /* Skip some implicitly-called GC_invoke_finalizers() */ - /* depending on the nesting (recursion) level. */ - if (++me->finalizer_skipped < (1U << nesting_level)) return NULL; - me->finalizer_skipped = 0; + me->finalizer_nested = 0; } - me->finalizer_nested = (unsigned char)(nesting_level + 1); - return &me->finalizer_nested; -} + + /* Checks and updates the thread-local level of finalizers recursion. */ + /* Returns NULL if GC_invoke_finalizers() should not be called by the */ + /* collector (to minimize the risk of a deep finalizers recursion), */ + /* otherwise returns a pointer to the thread-local finalizer_nested. */ + /* Called by GC_notify_or_invoke_finalizers() only (the GC lock is */ + /* held). */ + GC_INNER unsigned char *GC_check_finalizer_nested(void) + { + GC_thread me = GC_lookup_thread(pthread_self()); + unsigned nesting_level = me->finalizer_nested; + + if (nesting_level) { + /* We are inside another GC_invoke_finalizers(). */ + /* Skip some implicitly-called GC_invoke_finalizers() */ + /* depending on the nesting (recursion) level. */ + if (++me->finalizer_skipped < (1U << nesting_level)) return NULL; + me->finalizer_skipped = 0; + } + me->finalizer_nested = (unsigned char)(nesting_level + 1); + return &me->finalizer_nested; + } +#endif /* !GC_NO_FINALIZATION */ #if defined(GC_ASSERTIONS) && defined(THREAD_LOCAL_ALLOC) /* This is called from thread-local GC_malloc(). */ @@ -856,7 +917,8 @@ } #endif /* USE_PROC_FOR_LIBRARIES */ -#ifdef IA64 +#if (defined(HAVE_PTHREAD_ATTR_GET_NP) || defined(HAVE_PTHREAD_GETATTR_NP)) \ + && defined(IA64) /* Find the largest stack_base smaller than bound. May be used */ /* to find the boundary between a register stack and adjacent */ /* immediately preceding memory stack. */ @@ -887,8 +949,6 @@ #endif /* IA64 */ #ifndef STAT_READ - /* Also defined in os_dep.c. */ -# define STAT_BUF_SIZE 4096 # define STAT_READ read /* If read is wrapped, this may need to be redefined to call */ /* the real one. */ @@ -920,16 +980,27 @@ /* Should be "return sysconf(_SC_NPROCESSORS_ONLN);" but that */ /* appears to be buggy in many cases. */ /* We look for lines "cpu<n>" in /proc/stat. */ - char stat_bufSTAT_BUF_SIZE; +# define PROC_STAT_BUF_SZ ((1 + MAX_MARKERS) * 100) /* should be enough */ + /* No need to read the entire /proc/stat to get maximum cpu<N> as */ + /* - the requested lines are located at the beginning of the file; */ + /* - the lines with cpu<N> where N > MAX_MARKERS are not needed. */ + char stat_bufPROC_STAT_BUF_SZ+1; int f; int result, i, len; f = open("/proc/stat", O_RDONLY); if (f < 0) { - WARN("Couldn't read /proc/stat\n", 0); + WARN("Could not open /proc/stat\n", 0); return 1; /* assume an uniprocessor */ } - len = STAT_READ(f, stat_buf, STAT_BUF_SIZE); + len = STAT_READ(f, stat_buf, sizeof(stat_buf)-1); + /* Unlikely that we need to retry because of an incomplete read here. */ + if (len < 0) { + WARN("Failed to read /proc/stat, errno= %" WARN_PRIdPTR "\n", errno); + close(f); + return 1; + } + stat_buflen = '\0'; /* to avoid potential buffer overrun by atoi() */ close(f); result = 1; @@ -937,7 +1008,7 @@ /* entry in /proc/stat. We identify those as */ /* uniprocessors. */ - for (i = 0; i < len - 100; ++i) { + for (i = 0; i < len - 4; ++i) { if (stat_bufi == '\n' && stat_bufi+1 == 'c' && stat_bufi+2 == 'p' && stat_bufi+3 == 'u') { int cpu_no = atoi(&stat_bufi + 4); @@ -1017,6 +1088,20 @@ } #endif /* ARM32 && GC_LINUX_THREADS && !NACL */ +#if defined(CAN_HANDLE_FORK) && defined(THREAD_SANITIZER) +# include "private/gc_pmark.h" /* for MS_NONE */ + + /* Workaround for TSan which does not notice that the GC lock */ + /* is acquired in fork_prepare_proc(). */ + GC_ATTR_NO_SANITIZE_THREAD + static GC_bool collection_in_progress(void) + { + return GC_mark_state != MS_NONE; + } +#else +# define collection_in_progress() GC_collection_in_progress() +#endif + /* We hold the GC lock. Wait until an in-progress GC has finished. */ /* Repeatedly RELEASES GC LOCK in order to wait. */ /* If wait_for_all is true, then we exit with the GC lock held and no */ @@ -1031,12 +1116,12 @@ GC_ASSERT(I_HOLD_LOCK()); # endif ASSERT_CANCEL_DISABLED(); - if (GC_incremental && GC_collection_in_progress()) { + if (GC_incremental && collection_in_progress()) { word old_gc_no = GC_gc_no; /* Make sure that no part of our stack is still on the mark stack, */ /* since it's about to be unmapped. */ - while (GC_incremental && GC_collection_in_progress() + while (GC_incremental && collection_in_progress() && (wait_for_all || old_gc_no == GC_gc_no)) { ENTER_GC(); GC_in_thread_creation = TRUE; @@ -1062,6 +1147,18 @@ IF_CANCEL(static int fork_cancel_state;) /* protected by allocation lock. */ +# ifdef PARALLEL_MARK +# ifdef THREAD_SANITIZER +# if defined(GC_ASSERTIONS) && defined(CAN_CALL_ATFORK) + STATIC void GC_generic_lock(pthread_mutex_t *); +# endif + GC_ATTR_NO_SANITIZE_THREAD + static void wait_for_reclaim_atfork(void); +# else +# define wait_for_reclaim_atfork() GC_wait_for_reclaim() +# endif +# endif /* PARALLEL_MARK */ + /* Called before a fork() */ #if defined(GC_ASSERTIONS) && defined(CAN_CALL_ATFORK) /* GC_lock_holder is updated safely (no data race actually). */ @@ -1081,12 +1178,20 @@ /* Following waits may include cancellation points. */ # if defined(PARALLEL_MARK) if (GC_parallel) - GC_wait_for_reclaim(); + wait_for_reclaim_atfork(); # endif GC_wait_for_gc_completion(TRUE); # if defined(PARALLEL_MARK) - if (GC_parallel) - GC_acquire_mark_lock(); + if (GC_parallel) { +# if defined(THREAD_SANITIZER) && defined(GC_ASSERTIONS) \ + && defined(CAN_CALL_ATFORK) + /* Prevent TSan false positive about the data race */ + /* when updating GC_mark_lock_holder. */ + GC_generic_lock(&mark_mutex); +# else + GC_acquire_mark_lock(); +# endif + } # endif GC_acquire_dirty_lock(); } @@ -1099,8 +1204,15 @@ { GC_release_dirty_lock(); # if defined(PARALLEL_MARK) - if (GC_parallel) - GC_release_mark_lock(); + if (GC_parallel) { +# if defined(THREAD_SANITIZER) && defined(GC_ASSERTIONS) \ + && defined(CAN_CALL_ATFORK) + /* To match that in fork_prepare_proc. */ + (void)pthread_mutex_unlock(&mark_mutex); +# else + GC_release_mark_lock(); +# endif + } # endif RESTORE_CANCEL(fork_cancel_state); UNLOCK(); @@ -1113,17 +1225,25 @@ static void fork_child_proc(void) { GC_release_dirty_lock(); -# if defined(PARALLEL_MARK) - if (GC_parallel) - GC_release_mark_lock(); -# endif - /* Clean up the thread table, so that just our thread is left. */ - GC_remove_all_threads_but_me(); # ifdef PARALLEL_MARK - /* Turn off parallel marking in the child, since we are probably */ - /* just going to exec, and we would have to restart mark threads. */ + if (GC_parallel) { +# if defined(THREAD_SANITIZER) && defined(GC_ASSERTIONS) \ + && defined(CAN_CALL_ATFORK) + (void)pthread_mutex_unlock(&mark_mutex); +# else + GC_release_mark_lock(); +# endif + /* Turn off parallel marking in the child, since we are probably */ + /* just going to exec, and we would have to restart mark threads. */ GC_parallel = FALSE; + } +# ifdef THREAD_SANITIZER + /* TSan does not support threads creation in the child process. */ + available_markers_m1 = 0; +# endif # endif + /* Clean up the thread table, so that just our thread is left. */ + GC_remove_all_threads_but_me(); # ifndef GC_DISABLE_INCREMENTAL GC_dirty_update_child(); # endif @@ -1184,7 +1304,18 @@ #ifdef PARALLEL_MARK static void setup_mark_lock(void); -#endif + + static unsigned required_markers_cnt = 0; + /* The default value (0) means the number of */ + /* markers should be selected automatically. */ +#endif /* PARALLEL_MARK */ + +GC_API void GC_CALL GC_set_markers_count(unsigned markers GC_ATTR_UNUSED) +{ +# ifdef PARALLEL_MARK + required_markers_cnt = markers < MAX_MARKERS ? markers : MAX_MARKERS; +# endif +} GC_INNER void GC_thr_init(void) { @@ -1270,7 +1401,7 @@ # ifdef PARALLEL_MARK { char * markers_string = GETENV("GC_MARKERS"); - int markers; + int markers = required_markers_cnt; if (markers_string != NULL) { markers = atoi(markers_string); @@ -1279,7 +1410,10 @@ "; using maximum threads\n", (signed_word)markers); markers = MAX_MARKERS; } - } else { + } else if (0 == markers) { + /* Unless the client sets the desired number of */ + /* parallel markers, it is determined based on the */ + /* number of CPU cores. */ markers = GC_nprocs; # if defined(GC_MIN_MARKERS) && !defined(CPPCHECK) /* This is primarily for targets without getenv(). */ @@ -1293,11 +1427,11 @@ } # endif } - GC_COND_LOG_PRINTF("Number of processors = %d\n", GC_nprocs); + GC_COND_LOG_PRINTF("Number of processors: %d\n", GC_nprocs); # if defined(BASE_ATOMIC_OPS_EMULATED) && !defined(GC_DARWIN_THREADS) \ && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ - && !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2) + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) /* Ensure the process is running on just one CPU core. */ /* This is needed because the AO primitives emulated with */ /* locks cannot be used inside signal handlers. */ @@ -1338,8 +1472,6 @@ GC_COND_LOG_PRINTF( "Single marker thread, turning off parallel marking\n"); } else { - /* Disable true incremental collection, but generational is OK. */ - GC_time_limit = GC_TIME_UNLIMITED; setup_mark_lock(); } # endif @@ -1388,24 +1520,17 @@ } #endif /* !GC_NO_PTHREAD_SIGMASK */ -/* Wrapper for functions that are likely to block for an appreciable */ -/* length of time. */ - -GC_INNER void GC_do_blocking_inner(ptr_t data, void * context GC_ATTR_UNUSED) +static GC_bool do_blocking_enter(GC_thread me) { - struct blocking_data * d = (struct blocking_data *) data; - pthread_t self = pthread_self(); - GC_thread me; # if defined(SPARC) || defined(IA64) ptr_t stack_ptr = GC_save_regs_in_stack(); + /* TODO: regs saving already done by GC_with_callee_saves_pushed */ +# elif defined(E2K) + size_t stack_size; # endif -# if defined(GC_DARWIN_THREADS) && !defined(DARWIN_DONT_PARSE_STACK) - GC_bool topOfStackUnset = FALSE; -# endif - DCL_LOCK_STATE; + GC_bool topOfStackUnset = FALSE; - LOCK(); - me = GC_lookup_thread(self); + GC_ASSERT(I_HOLD_LOCK()); GC_ASSERT(!(me -> thread_blocked)); # ifdef SPARC me -> stop_info.stack_ptr = stack_ptr; @@ -1422,18 +1547,173 @@ # endif # ifdef IA64 me -> backing_store_ptr = stack_ptr; +# elif defined(E2K) + GC_ASSERT(NULL == me -> backing_store_end); + stack_size = GC_alloc_and_get_procedure_stack(&me->backing_store_end); + me->backing_store_ptr = me->backing_store_end + stack_size; # endif me -> thread_blocked = (unsigned char)TRUE; /* Save context here if we want to support precise stack marking */ - UNLOCK(); - d -> client_data = (d -> fn)(d -> client_data); - LOCK(); /* This will block if the world is stopped. */ + return topOfStackUnset; +} + +static void do_blocking_leave(GC_thread me, GC_bool topOfStackUnset) +{ + GC_ASSERT(I_HOLD_LOCK()); +# if defined(CPPCHECK) + GC_noop1((word)&me->thread_blocked); +# endif me -> thread_blocked = FALSE; +# ifdef E2K + GC_ASSERT(me -> backing_store_end != NULL); + /* Note that me->backing_store_end value here may differ from */ + /* the one stored in this function previously. */ + GC_INTERNAL_FREE(me -> backing_store_end); + me -> backing_store_ptr = NULL; + me -> backing_store_end = NULL; +# endif # if defined(GC_DARWIN_THREADS) && !defined(DARWIN_DONT_PARSE_STACK) if (topOfStackUnset) me -> topOfStack = NULL; /* make topOfStack unset again */ +# else + (void)topOfStackUnset; # endif +} + +/* Wrapper for functions that are likely to block for an appreciable */ +/* length of time. */ +GC_INNER void GC_do_blocking_inner(ptr_t data, void * context GC_ATTR_UNUSED) +{ + struct blocking_data *d = (struct blocking_data *)data; + GC_thread me; + GC_bool topOfStackUnset; + DCL_LOCK_STATE; + + LOCK(); + me = GC_lookup_thread(pthread_self()); + topOfStackUnset = do_blocking_enter(me); + UNLOCK(); + + d -> client_data = (d -> fn)(d -> client_data); + + LOCK(); /* This will block if the world is stopped. */ +# ifdef LINT2 + { +# ifdef GC_ASSERTIONS + GC_thread saved_me = me; +# endif + + /* The pointer to the GC thread descriptor should not be */ + /* changed while the thread is registered but a static */ + /* analysis tool might complain that this pointer value */ + /* (obtained in the first locked section) is unreliable in */ + /* the second locked section. */ + me = GC_lookup_thread(pthread_self()); + GC_ASSERT(me == saved_me); + } +# endif +# if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_DARWIN_THREADS) \ + && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) + /* Note: this code cannot be moved into do_blocking_leave() */ + /* otherwise there could be a static analysis tool warning */ + /* (false positive) about unlock without a matching lock. */ + while (EXPECT((me -> stop_info.ext_suspend_cnt & 1) != 0, FALSE)) { + word suspend_cnt = (word)(me -> stop_info.ext_suspend_cnt); + /* read suspend counter (number) before unlocking */ + + UNLOCK(); + GC_suspend_self_inner(me, suspend_cnt); + LOCK(); + } +# endif + do_blocking_leave(me, topOfStackUnset); + UNLOCK(); +} + +#if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_DARWIN_THREADS) \ + && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) + /* Similar to GC_do_blocking_inner() but assuming the GC lock is held */ + /* and fn is GC_suspend_self_inner. */ + GC_INNER void GC_suspend_self_blocked(ptr_t thread_me, + void * context GC_ATTR_UNUSED) + { + GC_thread me = (GC_thread)thread_me; + GC_bool topOfStackUnset; + DCL_LOCK_STATE; + + GC_ASSERT(I_HOLD_LOCK()); + topOfStackUnset = do_blocking_enter(me); + while ((me -> stop_info.ext_suspend_cnt & 1) != 0) { + word suspend_cnt = (word)(me -> stop_info.ext_suspend_cnt); + + UNLOCK(); + GC_suspend_self_inner(me, suspend_cnt); + LOCK(); + } + do_blocking_leave(me, topOfStackUnset); + } +#endif + +GC_API void GC_CALL GC_set_stackbottom(void *gc_thread_handle, + const struct GC_stack_base *sb) +{ + GC_thread t = (GC_thread)gc_thread_handle; + + GC_ASSERT(sb -> mem_base != NULL); + if (!EXPECT(GC_is_initialized, TRUE)) { + GC_ASSERT(NULL == t); + } else { + GC_ASSERT(I_HOLD_LOCK()); + if (NULL == t) /* current thread? */ + t = GC_lookup_thread(pthread_self()); + GC_ASSERT((t -> flags & FINISHED) == 0); + GC_ASSERT(!(t -> thread_blocked) + && NULL == t -> traced_stack_sect); /* for now */ + + if ((t -> flags & MAIN_THREAD) == 0) { + t -> stack_end = (ptr_t)sb->mem_base; +# ifdef IA64 + t -> backing_store_end = (ptr_t)sb->reg_base; +# endif + return; + } + /* Otherwise alter the stack bottom of the primordial thread. */ + } + + GC_stackbottom = (char*)sb->mem_base; +# ifdef IA64 + GC_register_stackbottom = (ptr_t)sb->reg_base; +# endif +} + +GC_API void * GC_CALL GC_get_my_stackbottom(struct GC_stack_base *sb) +{ + pthread_t self = pthread_self(); + GC_thread me; + DCL_LOCK_STATE; + + LOCK(); + me = GC_lookup_thread(self); + /* The thread is assumed to be registered. */ + if ((me -> flags & MAIN_THREAD) == 0) { + sb -> mem_base = me -> stack_end; +# ifdef IA64 + sb -> reg_base = me -> backing_store_end; +# elif defined(E2K) + sb -> reg_base = NULL; +# endif + } else { + sb -> mem_base = GC_stackbottom; +# ifdef IA64 + sb -> reg_base = GC_register_stackbottom; +# elif defined(E2K) + sb -> reg_base = NULL; +# endif + } UNLOCK(); + return (void *)me; /* gc_thread_handle */ } /* GC_call_with_gc_active() has the opposite to GC_do_blocking() */ @@ -1446,12 +1726,15 @@ struct GC_traced_stack_sect_s stacksect; pthread_t self = pthread_self(); GC_thread me; +# ifdef E2K + size_t stack_size; +# endif DCL_LOCK_STATE; LOCK(); /* This will block if the world is stopped. */ me = GC_lookup_thread(self); - /* Adjust our stack base value (this could happen unless */ + /* Adjust our stack bottom value (this could happen unless */ /* GC_get_stack_base() was used which returned GC_SUCCESS). */ if ((me -> flags & MAIN_THREAD) == 0) { GC_ASSERT(me -> stack_end != NULL); @@ -1472,6 +1755,17 @@ return client_data; /* result */ } +# if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_DARWIN_THREADS) \ + && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) + while (EXPECT((me -> stop_info.ext_suspend_cnt & 1) != 0, FALSE)) { + word suspend_cnt = (word)(me -> stop_info.ext_suspend_cnt); + UNLOCK(); + GC_suspend_self_inner(me, suspend_cnt); + LOCK(); + } +# endif + /* Setup new "stack section". */ stacksect.saved_stack_ptr = me -> stop_info.stack_ptr; # ifdef IA64 @@ -1480,6 +1774,11 @@ /* Unnecessarily flushes register stack, */ /* but that probably doesn't hurt. */ stacksect.saved_backing_store_ptr = me -> backing_store_ptr; +# elif defined(E2K) + GC_ASSERT(me -> backing_store_end != NULL); + GC_INTERNAL_FREE(me -> backing_store_end); + me -> backing_store_ptr = NULL; + me -> backing_store_end = NULL; # endif stacksect.prev = me -> traced_stack_sect; me -> thread_blocked = FALSE; @@ -1491,10 +1790,20 @@ GC_ASSERT(me -> traced_stack_sect == &stacksect); /* Restore original "stack section". */ +# if defined(CPPCHECK) + GC_noop1((word)me->traced_stack_sect); +# endif +# ifdef E2K + (void)GC_save_regs_in_stack(); +# endif LOCK(); me -> traced_stack_sect = stacksect.prev; # ifdef IA64 me -> backing_store_ptr = stacksect.saved_backing_store_ptr; +# elif defined(E2K) + GC_ASSERT(NULL == me -> backing_store_end); + stack_size = GC_alloc_and_get_procedure_stack(&me->backing_store_end); + me->backing_store_ptr = me->backing_store_end + stack_size; # endif me -> thread_blocked = (unsigned char)TRUE; me -> stop_info.stack_ptr = stacksect.saved_stack_ptr; @@ -1505,9 +1814,10 @@ STATIC void GC_unregister_my_thread_inner(GC_thread me) { + GC_ASSERT(I_HOLD_LOCK()); # ifdef DEBUG_THREADS GC_log_printf( - "Unregistering thread %p, gc_thread = %p, n_threads = %d\n", + "Unregistering thread %p, gc_thread= %p, n_threads= %d\n", (void *)me->id, (void *)me, GC_count_threads()); # endif GC_ASSERT(!(me -> flags & FINISHED)); @@ -1548,7 +1858,7 @@ me = GC_lookup_thread(self); # ifdef DEBUG_THREADS GC_log_printf( - "Called GC_unregister_my_thread on %p, gc_thread = %p\n", + "Called GC_unregister_my_thread on %p, gc_thread= %p\n", (void *)self, (void *)me); # endif GC_ASSERT(THREAD_EQUAL(me->id, self)); @@ -1569,7 +1879,7 @@ DCL_LOCK_STATE; # ifdef DEBUG_THREADS - GC_log_printf("Called GC_thread_exit_proc on %p, gc_thread = %p\n", + GC_log_printf("Called GC_thread_exit_proc on %p, gc_thread= %p\n", (void *)((GC_thread)arg)->id, arg); # endif LOCK(); @@ -1589,7 +1899,7 @@ INIT_REAL_SYMS(); LOCK(); - t = GC_lookup_thread(thread); + t = (GC_thread)COVERT_DATAFLOW(GC_lookup_thread(thread)); /* This is guaranteed to be the intended one, since the thread id */ /* can't have been recycled by pthreads. */ UNLOCK(); @@ -1625,7 +1935,7 @@ INIT_REAL_SYMS(); LOCK(); - t = GC_lookup_thread(thread); + t = (GC_thread)COVERT_DATAFLOW(GC_lookup_thread(thread)); UNLOCK(); result = REAL_FUNC(pthread_detach)(thread); if (result == 0) { @@ -1738,9 +2048,17 @@ GC_API void GC_CALL GC_allow_register_threads(void) { +# ifdef GC_ASSERTIONS + DCL_LOCK_STATE; + /* Check GC is initialized and the current thread is registered. */ + LOCK(); /* just to match that in win32_threads.c */ GC_ASSERT(GC_lookup_thread(pthread_self()) != 0); - set_need_to_lock(); + UNLOCK(); +# endif + INIT_REAL_SYMS(); /* to initialize symbols while single-threaded */ + GC_start_mark_threads(); + set_need_to_lock(); } GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb) @@ -1756,6 +2074,9 @@ me = GC_lookup_thread(self); if (0 == me) { me = GC_register_my_thread_inner(sb, self); +# if defined(CPPCHECK) + GC_noop1(me->flags); +# endif me -> flags |= DETACHED; /* Treat as detached, since we do not need to worry about */ /* pointer results. */ @@ -1782,6 +2103,13 @@ # if defined(THREAD_LOCAL_ALLOC) GC_init_thread_local(&(me->tlfs)); # endif +# if defined(GC_ENABLE_SUSPEND_THREAD) && !defined(GC_DARWIN_THREADS) \ + && !defined(GC_OPENBSD_UTHREADS) && !defined(NACL) \ + && !defined(PLATFORM_STOP_WORLD) && !defined(SN_TARGET_PSP2) + if ((me -> stop_info.ext_suspend_cnt & 1) != 0) { + GC_with_callee_saves_pushed(GC_suspend_self_blocked, (ptr_t)me); + } +# endif UNLOCK(); return GC_SUCCESS; } else { @@ -1812,7 +2140,7 @@ DCL_LOCK_STATE; # ifdef DEBUG_THREADS - GC_log_printf("Starting thread %p, pid = %ld, sp = %p\n", + GC_log_printf("Starting thread %p, pid= %ld, sp= %p\n", (void *)self, (long)getpid(), (void *)&arg); # endif LOCK(); @@ -1824,7 +2152,7 @@ UNLOCK(); *pstart = si -> start_routine; # ifdef DEBUG_THREADS - GC_log_printf("start_routine = %p\n", (void *)(signed_word)(*pstart)); + GC_log_printf("start_routine= %p\n", (void *)(signed_word)(*pstart)); # endif *pstart_arg = si -> arg; sem_post(&(si -> registered)); /* Last action on si. */ @@ -1925,6 +2253,10 @@ GC_log_printf("About to start new thread from thread %p\n", (void *)pthread_self()); # endif +# ifdef PARALLEL_MARK + if (EXPECT(!GC_parallel && available_markers_m1 > 0, FALSE)) + GC_start_mark_threads(); +# endif set_need_to_lock(); result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, &si); @@ -2116,7 +2448,7 @@ # define SLEEP_THRESHOLD 12 /* Under Linux very short sleeps tend to wait until */ /* the current time quantum expires. On old Linux */ - /* kernels nanosleep (<= 2 msecs) just spins. */ + /* kernels nanosleep (<= 2 ms) just spins. */ /* (Under 2.4, this happens only for real-time */ /* processes.) We want to minimize both behaviors */ /* here. */ @@ -2126,7 +2458,7 @@ struct timespec ts; if (i > 24) i = 24; - /* Don't wait for more than about 15 msecs, */ + /* Don't wait for more than about 15 ms, */ /* even under extreme contention. */ ts.tv_sec = 0; ts.tv_nsec = 1 << i; @@ -2172,53 +2504,14 @@ # define UNSET_MARK_LOCK_HOLDER (void)0 # endif /* !GC_ASSERTIONS */ -#ifdef GLIBC_2_1_MUTEX_HACK - /* 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 */ - /* pthread_cond_wait to die. Remove for glibc2.2. */ - /* According to the man page, we should use */ - /* PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, but that isn't actually */ - /* defined. */ - static pthread_mutex_t mark_mutex = - {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}}; -#else - static pthread_mutex_t mark_mutex = PTHREAD_MUTEX_INITIALIZER; -#endif - static pthread_cond_t builder_cv = PTHREAD_COND_INITIALIZER; -#ifdef GLIBC_2_19_TSX_BUG - /* Parse string like <major>.<minor><tail> and return major value. */ - static int parse_version(int *pminor, const char *pverstr) { - char *endp; - unsigned long value = strtoul(pverstr, &endp, 10); - int major = (int)value; - - if (major < 0 || (char *)pverstr == endp || (unsigned)major != value) { - /* Parse error */ - return -1; - } - if (*endp != '.') { - /* No minor part. */ - *pminor = -1; - } else { - value = strtoul(endp + 1, &endp, 10); - *pminor = (int)value; - if (*pminor < 0 || (unsigned)(*pminor) != value) { - return -1; - } - } - return major; - } -#endif /* GLIBC_2_19_TSX_BUG */ - static void setup_mark_lock(void) { # ifdef GLIBC_2_19_TSX_BUG pthread_mutexattr_t mattr; int glibc_minor = -1; - int glibc_major = parse_version(&glibc_minor, gnu_get_libc_version()); + int glibc_major = GC_parse_version(&glibc_minor, gnu_get_libc_version()); if (glibc_major > 2 || (glibc_major == 2 && glibc_minor >= 19)) { /* TODO: disable this workaround for glibc with fixed TSX */ @@ -2279,6 +2572,20 @@ GC_release_mark_lock(); } +# if defined(CAN_HANDLE_FORK) && defined(THREAD_SANITIZER) + /* Identical to GC_wait_for_reclaim() but with the no_sanitize */ + /* attribute as a workaround for TSan which does not notice that */ + /* the GC lock is acquired in fork_prepare_proc(). */ + GC_ATTR_NO_SANITIZE_THREAD + static void wait_for_reclaim_atfork(void) + { + GC_acquire_mark_lock(); + while (GC_fl_builder_count > 0) + GC_wait_builder(); + GC_release_mark_lock(); + } +# endif /* CAN_HANDLE_FORK && THREAD_SANITIZER */ + GC_INNER void GC_notify_all_builder(void) { GC_ASSERT(GC_mark_lock_holder == NUMERIC_THREAD_ID(pthread_self()));
View file
_service:tar_scm:gc-8.0.6.tar.gz/ptr_chck.c -> _service:tar_scm:gc-8.2.2.tar.gz/ptr_chck.c
Changed
@@ -123,6 +123,7 @@ word sz; if (!EXPECT(GC_is_initialized, TRUE)) GC_init(); + if (NULL == p) return NULL; hhdr = HDR((word)p); if (hhdr == 0) return(p); h = HBLKPTR(p);
View file
_service:tar_scm:gc-8.0.6.tar.gz/reclaim.c -> _service:tar_scm:gc-8.2.2.tar.gz/reclaim.c
Changed
@@ -3,6 +3,7 @@ * Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved. * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved. * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P. + * Copyright (c) 2009-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -44,7 +45,11 @@ STATIC ptr_t GC_leakedMAX_LEAKED = { NULL }; STATIC unsigned GC_n_leaked = 0; -GC_INNER GC_bool GC_have_errors = FALSE; +#ifdef AO_HAVE_store + GC_INNER volatile AO_t GC_have_errors = 0; +#else + GC_INNER GC_bool GC_have_errors = FALSE; +#endif #if !defined(EAGER_SWEEP) && defined(ENABLE_DISCLAIM) STATIC void GC_reclaim_unconditionally_marked(void); @@ -52,12 +57,12 @@ GC_INLINE void GC_add_leaked(ptr_t leaked) { -# ifndef SHORT_DBG_HDRS - if (GC_findleak_delay_free && !GC_check_leaked(leaked)) - return; -# endif +# ifndef SHORT_DBG_HDRS + if (GC_findleak_delay_free && !GC_check_leaked(leaked)) + return; +# endif - GC_have_errors = TRUE; + GC_SET_HAVE_ERRORS(); if (GC_n_leaked < MAX_LEAKED) { GC_leakedGC_n_leaked++ = leaked; /* Make sure it's not reclaimed this cycle */ @@ -80,7 +85,7 @@ UNLOCK(); return; } - have_errors = GC_have_errors; + have_errors = get_have_errors(); printing_errors = TRUE; n_leaked = GC_n_leaked; if (n_leaked > 0) { @@ -143,6 +148,30 @@ /* TODO: This should perhaps again be specialized for USE_MARK_BYTES */ /* and USE_MARK_BITS cases. */ +GC_INLINE word *GC_clear_block(word *p, word sz, signed_word *count) +{ + word *q = (word *)((ptr_t)p + sz); + + /* Clear object, advance p to next object in the process. */ +# ifdef USE_MARK_BYTES + GC_ASSERT((sz & 1) == 0); + GC_ASSERT(((word)p & (2 * sizeof(word) - 1)) == 0); + p1 = 0; + p += 2; + while ((word)p < (word)q) { + CLEAR_DOUBLE(p); + p += 2; + } +# else + p++; /* Skip link field */ + while ((word)p < (word)q) { + *p++ = 0; + } +# endif + *count += sz; + return p; +} + /* * Restore unmarked small objects in h of size sz to the object * free list. Returns the new list. @@ -152,8 +181,7 @@ ptr_t list, signed_word *count) { word bit_no = 0; - word *p, *q, *plim; - signed_word n_bytes_found = 0; + ptr_t p, plim; GC_ASSERT(hhdr == GC_find_header((ptr_t)hbp)); # ifndef THREADS @@ -162,40 +190,23 @@ /* Skip the assertion because of a potential race with GC_realloc. */ # endif GC_ASSERT((sz & (BYTES_PER_WORD-1)) == 0); - p = (word *)(hbp->hb_body); - plim = (word *)(hbp->hb_body + HBLKSIZE - sz); + p = hbp->hb_body; + plim = p + HBLKSIZE - sz; /* go through all words in block */ while ((word)p <= (word)plim) { if (mark_bit_from_hdr(hhdr, bit_no)) { - p = (word *)((ptr_t)p + sz); + p += sz; } else { - n_bytes_found += sz; - /* object is available - put on list */ - obj_link(p) = list; - list = ((ptr_t)p); - /* Clear object, advance p to next object in the process */ - q = (word *)((ptr_t)p + sz); -# ifdef USE_MARK_BYTES - GC_ASSERT(!(sz & 1) - && !((word)p & (2 * sizeof(word) - 1))); - p1 = 0; - p += 2; - while ((word)p < (word)q) { - CLEAR_DOUBLE(p); - p += 2; - } -# else - p++; /* Skip link field */ - while ((word)p < (word)q) { - *p++ = 0; - } -# endif + /* Object is available - put it on list. */ + obj_link(p) = list; + list = p; + + p = (ptr_t)GC_clear_block((word *)p, sz, count); } bit_no += MARK_BIT_OFFSET(sz); } - *count += n_bytes_found; - return(list); + return list; } /* The same thing, but don't clear objects: */ @@ -234,52 +245,29 @@ ptr_t list, signed_word *count) { word bit_no = 0; - word *p, *q, *plim; - signed_word n_bytes_found = 0; + ptr_t p, plim; struct obj_kind *ok = &GC_obj_kindshhdr->hb_obj_kind; int (GC_CALLBACK *disclaim)(void *) = ok->ok_disclaim_proc; # ifndef THREADS GC_ASSERT(sz == hhdr -> hb_sz); # endif - p = (word *)(hbp -> hb_body); - plim = (word *)((ptr_t)p + HBLKSIZE - sz); + p = hbp->hb_body; + plim = p + HBLKSIZE - sz; - while ((word)p <= (word)plim) { - int marked = mark_bit_from_hdr(hhdr, bit_no); - if (!marked && (*disclaim)(p)) { + for (; (word)p <= (word)plim; bit_no += MARK_BIT_OFFSET(sz)) { + if (mark_bit_from_hdr(hhdr, bit_no)) { + p += sz; + } else if ((*disclaim)(p)) { set_mark_bit_from_hdr(hhdr, bit_no); hhdr -> hb_n_marks++; - marked = 1; - } - if (marked) - p = (word *)((ptr_t)p + sz); - else { - n_bytes_found += sz; - /* object is available - put on list */ - obj_link(p) = list; - list = ((ptr_t)p); - /* Clear object, advance p to next object in the process */ - q = (word *)((ptr_t)p + sz); -# ifdef USE_MARK_BYTES - GC_ASSERT((sz & 1) == 0); - GC_ASSERT(((word)p & (2 * sizeof(word) - 1)) == 0); - p1 = 0; - p += 2; - while ((word)p < (word)q) { - CLEAR_DOUBLE(p); - p += 2; - } -# else - p++; /* Skip link field */ - while ((word)p < (word)q) { - *p++ = 0; - } -# endif + p += sz; + } else { + obj_link(p) = list; + list = p; + p = (ptr_t)GC_clear_block((word *)p, sz, count); } - bit_no += MARK_BIT_OFFSET(sz); } - *count += n_bytes_found; return list; } #endif /* ENABLE_DISCLAIM */ @@ -426,6 +414,9 @@ } # endif blocks = OBJ_SZ_TO_BLOCKS(sz); +# if defined(CPPCHECK) + GC_noop1((word)&blocks); +# endif if (blocks > 1) { GC_large_allocd_bytes -= blocks * HBLKSIZE; } @@ -448,10 +439,11 @@ /* Count can be low or one too high because we sometimes */ /* have to ignore decrements. Objects can also potentially */ /* be repeatedly marked by each marker. */ - /* Here we assume two markers, but this is extremely */ + /* Here we assume 3 markers at most, but this is extremely */ /* unlikely to fail spuriously with more. And if it does, it */ /* should be looked at. */ - GC_ASSERT(hhdr -> hb_n_marks <= 2 * (HBLKSIZE/sz + 1) + 16); + GC_ASSERT(sz != 0 && (GC_markers_m1 > 1 ? 3 : GC_markers_m1 + 1) + * (HBLKSIZE/sz + 1) + 16 >= hhdr->hb_n_marks); # else GC_ASSERT(sz * hhdr -> hb_n_marks <= HBLKSIZE); # endif @@ -710,9 +702,10 @@ struct hblk ** rlh = ok -> ok_reclaim_list; void **flh = &(ok -> ok_freelistsz); - if (rlh == 0) return; /* No blocks of this kind. */ - rlh += sz; - while ((hbp = *rlh) != 0) { + if (NULL == rlh) + return; /* No blocks of this kind. */ + + for (rlh += sz; (hbp = *rlh) != NULL; ) { hhdr = HDR(hbp); *rlh = hhdr -> hb_next; GC_reclaim_small_nonempty_block(hbp, hhdr -> hb_sz, FALSE); @@ -751,8 +744,7 @@ rlp = ok -> ok_reclaim_list; if (rlp == 0) continue; for (sz = 1; sz <= MAXOBJGRANULES; sz++) { - rlh = rlp + sz; - while ((hbp = *rlh) != 0) { + for (rlh = rlp + sz; (hbp = *rlh) != NULL; ) { if (stop_func != (GC_stop_func)0 && (*stop_func)()) { return(FALSE); } @@ -773,8 +765,10 @@ CLOCK_TYPE done_time; GET_TIME(done_time); - GC_verbose_log_printf("Disposing of reclaim lists took %lu msecs\n", - MS_TIME_DIFF(done_time,start_time)); + GC_verbose_log_printf( + "Disposing of reclaim lists took %lu ms %lu ns\n", + MS_TIME_DIFF(done_time, start_time), + NS_FRAC_TIME_DIFF(done_time, start_time)); } # endif return(TRUE);
View file
_service:tar_scm:gc-8.0.6.tar.gz/specific.c -> _service:tar_scm:gc-8.2.2.tar.gz/specific.c
Changed
@@ -51,7 +51,7 @@ GC_INNER int GC_setspecific(tsd * key, void * value) { pthread_t self = pthread_self(); - int hash_val = HASH(self); + unsigned hash_val = HASH(self); volatile tse * entry; GC_ASSERT(I_HOLD_LOCK()); @@ -138,8 +138,7 @@ tse * volatile * cache_ptr) { pthread_t self = pthread_self(); - unsigned hash_val = HASH(self); - tse *entry = key->hashhash_val.p; + tse *entry = key->hashHASH(self).p; GC_ASSERT(qtid != INVALID_QTID); while (entry != NULL && !THREAD_EQUAL(entry->thread, self)) {
View file
_service:tar_scm:gc-8.0.6.tar.gz/test-driver -> _service:tar_scm:gc-8.2.2.tar.gz/test-driver
Changed
@@ -1,9 +1,9 @@ #! /bin/sh # test-driver - basic testsuite driver script. -scriptversion=2013-07-13.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -42,11 +42,13 @@ { cat <<END Usage: - test-driver --test-name=NAME --log-file=PATH --trs-file=PATH - --expect-failure={yes|no} --color-tests={yes|no} - --enable-hard-errors={yes|no} -- + test-driver --test-name NAME --log-file PATH --trs-file PATH + --expect-failure {yes|no} --color-tests {yes|no} + --enable-hard-errors {yes|no} -- TEST-SCRIPT TEST-SCRIPT-ARGUMENTS + The '--test-name', '--log-file' and '--trs-file' options are mandatory. +See the GNU Automake documentation for information. END } @@ -103,8 +105,11 @@ trap "st=141; $do_exit" 13 trap "st=143; $do_exit" 15 -# Test script is run here. -"$@" >$log_file 2>&1 +# Test script is run here. We create the file first, then append to it, +# to ameliorate tests themselves also writing to the log file. Our tests +# don't, but others can (automake bug#35762). +: >"$log_file" +"$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then @@ -126,7 +131,7 @@ # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). -echo "$res $test_name (exit status: $estatus)" >>$log_file +echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" @@ -140,9 +145,9 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End:
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/disclaim_bench.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/disclaim_bench.c
Changed
@@ -22,8 +22,7 @@ #include "gc_disclaim.h" -/* Include gc_priv.h is done after including GC public headers, so */ -/* that GC_BUILD has no effect on the public prototypes. */ +#define NOT_GCBUILD #include "private/gc_priv.h" /* for CLOCK_TYPE, COVERT_DATAFLOW, GC_random */ #ifdef LINT2 @@ -62,12 +61,14 @@ { testobj_t obj; switch (model) { +# ifndef GC_NO_FINALIZATION case 0: obj = GC_NEW(struct testobj_s); if (obj != NULL) GC_REGISTER_FINALIZER_NO_ORDER(obj, testobj_finalize, &free_count, NULL, NULL); break; +# endif case 1: obj = (testobj_t)GC_finalized_malloc(sizeof(struct testobj_s), &fclos); @@ -116,9 +117,12 @@ model_min = model_max = (int)COVERT_DATAFLOW(atoi(argv1)); if (model_min < 0 || model_max > 2) exit(2); - } - else { + } else { +# ifndef GC_NO_FINALIZATION model_min = 0; +# else + model_min = 1; +# endif model_max = 2; } if (GC_get_find_leak())
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/disclaim_test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/disclaim_test.c
Changed
@@ -28,21 +28,26 @@ #undef GC_NO_THREAD_REDIRECTS #include "gc_disclaim.h" -#ifdef LINT2 - /* Avoid include gc_priv.h. */ -# ifndef GC_API_PRIV -# define GC_API_PRIV GC_API -# endif -# ifdef __cplusplus - extern "C" { -# endif - GC_API_PRIV long GC_random(void); -# ifdef __cplusplus - } /* extern "C" */ -# endif +#if defined(GC_PTHREADS) || defined(LINT2) +# define NOT_GCBUILD +# include "private/gc_priv.h" + + GC_ATTR_NO_SANITIZE_THREAD + static int GC_rand(void) /* nearly identical to GC_random */ + { + static unsigned seed; /* concurrent update does not hurt the test */ + + seed = (seed * 1103515245U + 12345) & (~0U >> 1); + return (int)seed; + } + + /* Redefine the standard rand() with a trivial (yet sufficient for */ + /* the test purpose) implementation to avoid crashes inside rand() */ + /* on some targets (e.g. FreeBSD 13.0) when used concurrently. */ + /* The standard specifies rand() as not a thread-safe API function. */ # undef rand -# define rand() (int)GC_random() -#endif /* LINT2 */ +# define rand() GC_rand() +#endif /* GC_PTHREADS || LINT2 */ #define my_assert(e) \ if (!(e)) { \ @@ -114,7 +119,7 @@ my_assert(cd == (void *)PTR_HASH(p)); /* Check that obj and its car and cdr are not trashed. */ # ifdef DEBUG_DISCLAIM_DESTRUCT - printf("Destruct %p = (%p, %p)\n", + printf("Destruct %p: (car= %p, cdr= %p)\n", (void *)p, (void *)p->car, (void *)p->cdr); # endif my_assert(GC_base(obj)); @@ -159,7 +164,7 @@ GC_ptr_store_and_dirty(&p->cdr, cdr); GC_reachable_here(car); # ifdef DEBUG_DISCLAIM_DESTRUCT - printf("Construct %p = (%p, %p)\n", + printf("Construct %p: (car= %p, cdr= %p)\n", (void *)p, (void *)p->car, (void *)p->cdr); # endif return p; @@ -184,6 +189,7 @@ # ifndef NTHREADS # define NTHREADS 6 # endif +# include <errno.h> /* for EAGAIN */ # include <pthread.h> #else # undef NTHREADS @@ -229,7 +235,7 @@ { # if NTHREADS > 1 pthread_t thNTHREADS; - int i; + int i, n; # endif GC_set_all_interior_pointers(0); /* for a stricter test */ @@ -251,15 +257,17 @@ for (i = 0; i < NTHREADS; ++i) { int err = pthread_create(&thi, NULL, test, NULL); if (err) { - fprintf(stderr, "Failed to create thread # %d: %s\n", i, + fprintf(stderr, "Failed to create thread #%d: %s\n", i, strerror(err)); + if (i > 1 && EAGAIN == err) break; exit(1); } } - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { int err = pthread_join(thi, NULL); if (err) { - fprintf(stderr, "Failed to join thread # %d: %s\n", i, + fprintf(stderr, "Failed to join thread #%d: %s\n", i, strerror(err)); exit(69); }
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/disclaim_weakmap_test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/disclaim_weakmap_test.c
Changed
@@ -24,13 +24,31 @@ #endif #include "gc_disclaim.h" /* includes gc.h */ -#include "gc_mark.h" + +#if defined(GC_PTHREADS) || defined(LINT2) +# define NOT_GCBUILD +# include "private/gc_priv.h" + + GC_ATTR_NO_SANITIZE_THREAD + static int GC_rand(void) /* same as in disclaim_test.c */ + { + static unsigned seed; /* concurrent update does not hurt the test */ + + seed = (seed * 1103515245U + 12345) & (~0U >> 1); + return (int)seed; + } + +# undef rand +# define rand() GC_rand() +#endif /* GC_PTHREADS || LINT2 */ + +#include "gc_mark.h" /* should not precede include gc_priv.h */ #ifdef GC_PTHREADS # ifndef NTHREADS # define NTHREADS 8 # endif -# include <errno.h> +# include <errno.h> /* for EAGAIN, EBUSY */ # include <pthread.h> # include "private/gc_atomic_ops.h" /* for AO_t and AO_fetch_and_add1 */ #else @@ -39,22 +57,6 @@ # define AO_t GC_word #endif -#ifdef LINT2 - /* Avoid include gc_priv.h. */ -# ifndef GC_API_PRIV -# define GC_API_PRIV GC_API -# endif -# ifdef __cplusplus - extern "C" { -# endif - GC_API_PRIV long GC_random(void); -# ifdef __cplusplus - } /* extern "C" */ -# endif -# undef rand -# define rand() (int)GC_random() -#endif /* LINT2 */ - #define POP_SIZE 200 #define MUTATE_CNT (5000000 / NTHREADS) #define GROW_LIMIT (MUTATE_CNT / 10) @@ -166,7 +168,7 @@ return NULL; } -void *weakmap_add(struct weakmap *wm, void *obj) +void *weakmap_add(struct weakmap *wm, void *obj, size_t obj_size) { struct weakmap_link *link, *new_link, **first; GC_word *new_base; @@ -175,6 +177,7 @@ size_t key_size = wm->key_size; /* Lock and look for an existing entry. */ + my_assert(key_size <= obj_size); h = memhash(obj, key_size); first = &wm->linksh % wm->capacity; weakmap_lock(wm, h); @@ -197,7 +200,7 @@ weakmap_unlock(wm, h); AO_fetch_and_add1(&stat_found); # ifdef DEBUG_DISCLAIM_WEAKMAP - printf("Found %p, hash=%p\n", old_obj, (void *)(GC_word)h); + printf("Found %p, hash= %p\n", old_obj, (void *)(GC_word)h); # endif return old_obj; } @@ -223,7 +226,7 @@ weakmap_unlock(wm, h); AO_fetch_and_add1(&stat_added); # ifdef DEBUG_DISCLAIM_WEAKMAP - printf("Added %p, hash=%p\n", new_obj, (void *)(GC_word)h); + printf("Added %p, hash= %p\n", new_obj, (void *)(GC_word)h); # endif return new_obj; } @@ -252,7 +255,7 @@ if (weakmap_trylock(wm, h) != 0) { AO_fetch_and_add1(&stat_skip_locked); # ifdef DEBUG_DISCLAIM_WEAKMAP - printf("Skipping locked %p, hash=%p\n", obj, (void *)(GC_word)h); + printf("Skipping locked %p, hash= %p\n", obj, (void *)(GC_word)h); # endif return 1; } @@ -260,7 +263,7 @@ weakmap_unlock(wm, h); AO_fetch_and_add1(&stat_skip_marked); # ifdef DEBUG_DISCLAIM_WEAKMAP - printf("Skipping marked %p, hash=%p\n", obj, (void *)(GC_word)h); + printf("Skipping marked %p, hash= %p\n", obj, (void *)(GC_word)h); # endif return 1; } @@ -268,7 +271,7 @@ /* Remove obj from wm. */ AO_fetch_and_add1(&stat_removed); # ifdef DEBUG_DISCLAIM_WEAKMAP - printf("Removing %p, hash=%p\n", obj, (void *)(GC_word)h); + printf("Removing %p, hash= %p\n", obj, (void *)(GC_word)h); # endif *(GC_word *)obj_base |= INVALIDATE_FLAG; for (link = &wm->linksh % wm->capacity;; link = &(*link)->next) { @@ -353,7 +356,7 @@ tmpl.cdr = cdr; memcpy(tmpl.magic, pair_magic, PAIR_MAGIC_SIZE); tmpl.checksum = 782 + (car? car->checksum : 0) + (cdr? cdr->checksum : 0); - return (struct pair *)weakmap_add(pair_hcset, &tmpl); + return (struct pair *)weakmap_add(pair_hcset, &tmpl, sizeof(tmpl)); } void pair_check_rec(struct pair *p, int line) @@ -370,7 +373,7 @@ if (p->cdr != NULL) checksum += p->cdr->checksum; if (p->checksum != checksum) { - fprintf(stderr, "Checksum failure for %p = (%p, %p) at %d\n", + fprintf(stderr, "Checksum failure for %p: (car= %p, cdr= %p) at %d\n", (void *)p, (void *)p->car, (void *)p->cdr, line); exit(70); } @@ -417,9 +420,8 @@ int main(void) { unsigned weakobj_kind; - void **weakobj_free_list; # ifdef GC_PTHREADS - int i; + int i, n; pthread_t thNTHREADS; # endif @@ -434,10 +436,7 @@ # endif if (GC_get_find_leak()) printf("This test program is not designed for leak detection mode\n"); - - weakobj_free_list = GC_new_free_list(); - CHECK_OOM(weakobj_free_list); - weakobj_kind = GC_new_kind(weakobj_free_list, /* 0 | */ GC_DS_LENGTH, + weakobj_kind = GC_new_kind(GC_new_free_list(), /* 0 | */ GC_DS_LENGTH, 1 /* adjust */, 1 /* clear */); GC_register_disclaim_proc(weakobj_kind, weakmap_disclaim, 1 /* mark_unconditionally */); @@ -450,10 +449,12 @@ if (err != 0) { fprintf(stderr, "Failed to create thread #%d: %s\n", i, strerror(err)); + if (i > 1 && EAGAIN == err) break; exit(1); } } - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { int err = pthread_join(thi, NULL); if (err != 0) { fprintf(stderr, "Failed to join thread #%d: %s\n", i, strerror(err));
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/huge_test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/huge_test.c
Changed
@@ -48,10 +48,12 @@ int main(void) { - GC_INIT(); + GC_INIT(); - CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX - 1024), "SWORD_MAX-1024"); - CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX), "SWORD_MAX"); + CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX - 1024), "SWORD_MAX-1024"); + CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX), "SWORD_MAX"); + /* Skip other checks to avoid "exceeds maximum object size" gcc warning. */ +# if !defined(_FORTIFY_SOURCE) CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1), "SWORD_MAX+1"); CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1024), "SWORD_MAX+1024"); @@ -60,5 +62,6 @@ CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 8), "WORD_MAX-8"); CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 4), "WORD_MAX-4"); CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX), "WORD_MAX"); - return 0; +# endif + return 0; }
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/initsecondarythread.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/initsecondarythread.c
Changed
@@ -89,21 +89,23 @@ printf("This test program is not designed for leak detection mode\n"); # ifdef GC_PTHREADS if ((code = pthread_create (&t, NULL, thread, NULL)) != 0) { - fprintf(stderr, "Thread creation failed %d\n", code); + fprintf(stderr, "Thread creation failed, errno= %d\n", code); return 1; } if ((code = pthread_join (t, NULL)) != 0) { - fprintf(stderr, "Thread join failed %d\n", code); + fprintf(stderr, "Thread join failed, errno= %d\n", code); return 1; } # else t = CreateThread(NULL, 0, thread, 0, 0, &thread_id); if (t == NULL) { - fprintf(stderr, "Thread creation failed %d\n", (int)GetLastError()); + fprintf(stderr, "Thread creation failed, errcode= %d\n", + (int)GetLastError()); return 1; } if (WaitForSingleObject(t, INFINITE) != WAIT_OBJECT_0) { - fprintf(stderr, "Thread join failed %d\n", (int)GetLastError()); + fprintf(stderr, "Thread join failed, errcode= %d\n", + (int)GetLastError()); CloseHandle(t); return 1; }
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/leak_test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/leak_test.c
Changed
@@ -1,7 +1,7 @@ #include "leak_detector.h" int main(void) { - int *p10; + char *p10; int i; GC_set_find_leak(1); /* for new collect versions not compiled */ /* with -DFIND_LEAK. */ @@ -9,14 +9,14 @@ GC_INIT(); /* Needed if thread-local allocation is enabled. */ /* FIXME: This is not ideal. */ for (i = 0; i < 10; ++i) { - pi = (int*)malloc(sizeof(int)+i); + pi = (char*)malloc(sizeof(int)+i); } CHECK_LEAKS(); for (i = 1; i < 10; ++i) { free(pi); } for (i = 0; i < 9; ++i) { - pi = (int*)malloc(sizeof(int)+i); + pi = (char*)malloc(sizeof(int)+i); } CHECK_LEAKS(); CHECK_LEAKS();
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/middle.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/middle.c
Changed
@@ -18,6 +18,10 @@ (void)GC_malloc_atomic(4096); (void)GC_malloc(4096); } + + /* Test delayed start of marker threads, if they are enabled. */ + GC_start_mark_threads(); + for (i = 0; i < 20000; ++i) { (void)GC_malloc_atomic(2048); (void)GC_malloc(2048);
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/subthread_create.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/subthread_create.c
Changed
@@ -18,6 +18,7 @@ #ifdef AO_HAVE_fetch_and_add1 #ifdef GC_PTHREADS +# include <errno.h> /* for EAGAIN */ # include <pthread.h> #else # ifndef WIN32_LEAN_AND_MEAN @@ -35,9 +36,11 @@ #include <string.h> #ifndef NTHREADS -# define NTHREADS 31 /* number of initial threads */ +# define NTHREADS 5 #endif +#define NTHREADS_INNER (NTHREADS * 6) /* number of threads to create */ + #ifndef MAX_SUBTHREAD_DEPTH # define MAX_ALIVE_THREAD_COUNT 55 # define MAX_SUBTHREAD_DEPTH 7 @@ -72,15 +75,17 @@ err = pthread_create(&th, NULL, entry, (void *)my_depth); if (err != 0) { - fprintf(stderr, "Thread #%d creation failed: %s\n", thread_num, - strerror(err)); + fprintf(stderr, "Thread #%d creation failed, error: %s\n", + thread_num, strerror(err)); + if (err != EAGAIN) exit(2); - } - err = pthread_detach(th); - if (err != 0) { - fprintf(stderr, "Thread #%d detach failed: %s\n", thread_num, - strerror(err)); + } else { + err = pthread_detach(th); + if (err != 0) { + fprintf(stderr, "Thread #%d detach failed, error: %s\n", + thread_num, strerror(err)); exit(2); + } } # else HANDLE th; @@ -88,8 +93,8 @@ th = CreateThread(NULL, 0, entry, (LPVOID)my_depth, 0, &thread_id); if (th == NULL) { - fprintf(stderr, "Thread #%d creation failed: %d\n", thread_num, - (int)GetLastError()); + fprintf(stderr, "Thread #%d creation failed, errcode= %d\n", + thread_num, (int)GetLastError()); exit(2); } CloseHandle(th); @@ -103,39 +108,42 @@ int main(void) { #if NTHREADS > 0 - int i; + int i, n; # ifdef GC_PTHREADS int err; - pthread_t thNTHREADS; + pthread_t thNTHREADS_INNER; # else - HANDLE thNTHREADS; + HANDLE thNTHREADS_INNER; # endif GC_INIT(); - for (i = 0; i < NTHREADS; ++i) { + for (i = 0; i < NTHREADS_INNER; ++i) { # ifdef GC_PTHREADS err = pthread_create(&thi, NULL, entry, 0); if (err) { - fprintf(stderr, "Thread creation failed: %s\n", strerror(err)); + fprintf(stderr, "Thread creation failed, error: %s\n", + strerror(err)); + if (i > 0 && EAGAIN == err) break; exit(1); } # else DWORD thread_id; thi = CreateThread(NULL, 0, entry, 0, 0, &thread_id); if (thi == NULL) { - fprintf(stderr, "Thread creation failed: %d\n", + fprintf(stderr, "Thread creation failed, errcode= %d\n", (int)GetLastError()); exit(1); } # endif } - - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { # ifdef GC_PTHREADS void *res; err = pthread_join(thi, &res); if (err) { - fprintf(stderr, "Failed to join thread: %s\n", strerror(err)); + fprintf(stderr, "Failed to join thread, error: %s\n", + strerror(err)); # if defined(__HAIKU__) /* The error is just ignored (and the test is ended) to */ /* workaround some bug in Haiku pthread_join. */ @@ -146,7 +154,7 @@ } # else if (WaitForSingleObject(thi, INFINITE) != WAIT_OBJECT_0) { - fprintf(stderr, "Failed to join thread: %d\n", + fprintf(stderr, "Failed to join thread, errcode= %d\n", (int)GetLastError()); CloseHandle(thi); exit(1);
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/test.c
Changed
@@ -2,6 +2,7 @@ * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. * Copyright (c) 1996 by Silicon Graphics. All rights reserved. + * Copyright (c) 2009-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -36,11 +37,14 @@ #if defined(CPPCHECK) && defined(GC_PTHREADS) && !defined(_GNU_SOURCE) # define _GNU_SOURCE 1 #endif -#undef GC_NO_THREAD_REDIRECTS +#ifdef GC_NO_THREADS_DISCOVERY +# undef GC_NO_THREAD_REDIRECTS +#endif #include "gc.h" #ifndef NTHREADS /* Number of additional threads to fork. */ -# define NTHREADS 5 /* excludes main thread, which also runs a test. */ +# define NTHREADS 5 /* Excludes main thread, which also runs a test. */ + /* In the single-threaded case, the number of times to rerun it. */ /* Not respected by PCR test. */ #endif @@ -57,22 +61,19 @@ # include <assert.h> /* Not normally used, but handy for debugging. */ # endif +#if defined(GC_NO_FINALIZATION) && !defined(NO_TYPED_TEST) +# define NO_TYPED_TEST +#endif + #ifndef NO_TYPED_TEST # include "gc_typed.h" #endif +#define NOT_GCBUILD #include "private/gc_priv.h" /* For output, locking, */ /* some statistics and gcconfig.h. */ -#if defined(MSWIN32) || defined(MSWINCE) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> -#endif /* MSWIN32 || MSWINCE */ - -#ifdef GC_PRINT_VERBOSE_STATS +#if defined(GC_PRINT_VERBOSE_STATS) || defined(GCTEST_PRINT_VERBOSE) # define print_stats VERBOSE # define INIT_PRINT_STATS /* empty */ #else @@ -100,15 +101,13 @@ # if defined(GC_PTHREADS) && !defined(GC_WIN32_PTHREADS) # include <pthread.h> -# else -# define NO_TEST_HANDLE_FORK # endif -# if (!defined(THREADS) || !defined(HANDLE_FORK) \ - || (defined(DARWIN) && defined(MPROTECT_VDB) \ - && !defined(NO_INCREMENTAL) && !defined(MAKE_BACK_GRAPH))) \ - && !defined(NO_TEST_HANDLE_FORK) && !defined(TEST_HANDLE_FORK) \ - && !defined(TEST_FORK_WITHOUT_ATFORK) +# if ((defined(DARWIN) && defined(MPROTECT_VDB) \ + && !defined(MAKE_BACK_GRAPH) && !defined(TEST_HANDLE_FORK)) \ + || (defined(THREADS) && !defined(CAN_HANDLE_FORK)) \ + || defined(HAVE_NO_FORK) || defined(USE_WINALLOC)) \ + && !defined(NO_TEST_HANDLE_FORK) # define NO_TEST_HANDLE_FORK # endif @@ -663,18 +662,18 @@ { DWORD thread_id; HANDLE h; - h = GC_CreateThread((SECURITY_ATTRIBUTES *)NULL, (word)0, - tiny_reverse_test, NULL, (DWORD)0, &thread_id); + h = CreateThread((SECURITY_ATTRIBUTES *)NULL, (word)0, + tiny_reverse_test, NULL, (DWORD)0, &thread_id); /* Explicitly specify types of the */ /* arguments to test the prototype. */ if (h == (HANDLE)NULL) { - GC_printf("Small thread creation failed %d\n", - (int)GetLastError()); + GC_printf("Small thread creation failed, errcode= %d\n", + (int)GetLastError()); FAIL; } if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) { - GC_printf("Small thread wait failed %d\n", - (int)GetLastError()); + GC_printf("Small thread wait failed, errcode= %d\n", + (int)GetLastError()); FAIL; } } @@ -728,17 +727,23 @@ return GC_call_with_gc_active(reverse_test_inner, (void*)(word)1); } +# ifndef BIG # if defined(MACOS) \ || (defined(UNIX_LIKE) && defined(NO_GETCONTEXT)) /* e.g. musl */ - /* Assume 128K stacks at least. */ -# define BIG 1000 + /* Assume 128 KB stacks at least. */ +# if defined(__s390x__) +# define BIG 600 +# else +# define BIG 1000 +# endif # elif defined(PCR) - /* PCR default stack is 100K. Stack frames are up to 120 bytes. */ + /* PCR default stack is 100 KB. Stack frames are up to 120 bytes. */ # define BIG 700 # elif defined(MSWINCE) || defined(RTEMS) - /* WinCE only allows 64K stacks */ + /* WinCE only allows 64 KB stacks. */ # define BIG 500 -# elif defined(OSF1) +# elif defined(EMSCRIPTEN) || defined(OSF1) + /* Wasm reports "Maximum call stack size exceeded" error otherwise. */ /* OSF has limited stack space by default, and large frames. */ # define BIG 200 # elif defined(__MACH__) && defined(__ppc64__) @@ -746,6 +751,7 @@ # else # define BIG 4500 # endif +# endif a_set(ints(1, 49)); b = ints(1, 50); @@ -792,14 +798,20 @@ GC_FREE((void *)e); check_ints(b,1,50); +# ifndef EMSCRIPTEN check_ints(a_get(),1,49); +# else + /* FIXME: gctest fails unless check_ints(a_get(), ...) are skipped. */ +# endif for (i = 0; i < 50; i++) { check_ints(b,1,50); b = reverse(reverse(b)); } check_ints(b,1,50); +# ifndef EMSCRIPTEN check_ints(a_get(),1,49); - for (i = 0; i < 60; i++) { +# endif + for (i = 0; i < 10 * (NTHREADS+1); i++) { # if (defined(GC_PTHREADS) || defined(GC_WIN32_THREADS)) \ && (NTHREADS > 0) if (i % 10 == 0) fork_a_thread(); @@ -816,7 +828,9 @@ AO_fetch_and_add1(&realloc_count); # endif } +# ifndef EMSCRIPTEN check_ints(a_get(),1,49); +# endif check_ints(b,1,50); /* Restore c and d values. */ @@ -855,7 +869,10 @@ struct treenode * rchild; } tn; -int finalizable_count = 0; +#ifndef GC_NO_FINALIZATION + int finalizable_count = 0; +#endif + int finalized_count = 0; int dropped_something = 0; @@ -921,14 +938,16 @@ if (AO_fetch_and_add1(&extra_count) % 119 == 0) { # ifndef GC_NO_FINALIZATION int my_index; - void *new_link; -# endif + void **new_link = GC_NEW(void *); + CHECK_OUT_OF_MEMORY(new_link); + AO_fetch_and_add1(&collectable_count); +# endif { FINALIZER_LOCK(); /* Losing a count here causes erroneous report of failure. */ - finalizable_count++; # ifndef GC_NO_FINALIZATION + finalizable_count++; my_index = live_indicators_count++; # endif FINALIZER_UNLOCK(); @@ -953,18 +972,23 @@ GC_printf("GC_move_disappearing_link(link,link) failed\n"); FAIL; } - new_link = (void *)live_indicatorsmy_index; + *new_link = (void *)live_indicatorsmy_index; if (GC_move_disappearing_link((void **)(&(live_indicatorsmy_index)), - &new_link) != GC_SUCCESS) { + new_link) != GC_SUCCESS) { GC_printf("GC_move_disappearing_link(new_link) failed\n"); FAIL; } - if (GC_unregister_disappearing_link(&new_link) == 0) { + /* Note: if other thread is performing fork at this moment, */ + /* then the stack of the current thread is dropped (together */ + /* with new_link variable) in the child process, and */ + /* GC_dl_hashtbl entry with the link equal to new_link will be */ + /* removed when a collection occurs (as expected). */ + if (GC_unregister_disappearing_link(new_link) == 0) { GC_printf("GC_unregister_disappearing_link failed\n"); FAIL; } if (GC_move_disappearing_link((void **)(&(live_indicatorsmy_index)), - &new_link) != GC_NOT_FOUND) { + new_link) != GC_NOT_FOUND) { GC_printf("GC_move_disappearing_link(new_link) failed 2\n"); FAIL; } @@ -983,18 +1007,18 @@ GC_printf("GC_move_long_link(link,link) failed\n"); FAIL; } - new_link = live_long_refsmy_index; + *new_link = live_long_refsmy_index; if (GC_move_long_link(&live_long_refsmy_index, - &new_link) != GC_SUCCESS) { + new_link) != GC_SUCCESS) { GC_printf("GC_move_long_link(new_link) failed\n"); FAIL; } - if (GC_unregister_long_link(&new_link) == 0) { + if (GC_unregister_long_link(new_link) == 0) { GC_printf("GC_unregister_long_link failed\n"); FAIL; } if (GC_move_long_link(&live_long_refsmy_index, - &new_link) != GC_NOT_FOUND) { + new_link) != GC_NOT_FOUND) { GC_printf("GC_move_long_link(new_link) failed 2\n"); FAIL; } @@ -1180,7 +1204,7 @@ GC_descr d2; GC_descr d3 = GC_make_descriptor(bm_large, 32); GC_descr d4 = GC_make_descriptor(bm_huge, 320); - GC_word * x = (GC_word *)GC_malloc_explicitly_typed( + GC_word * x = (GC_word *)GC_MALLOC_EXPLICITLY_TYPED( 320 * sizeof(GC_word) + 123, d4); int i; @@ -1198,7 +1222,7 @@ d2 = GC_make_descriptor(bm2, 2); old = 0; for (i = 0; i < 4000; i++) { - newP = (GC_word *)GC_malloc_explicitly_typed(4 * sizeof(GC_word), d1); + newP = (GC_word *)GC_MALLOC_EXPLICITLY_TYPED(4 * sizeof(GC_word), d1); CHECK_OUT_OF_MEMORY(newP); AO_fetch_and_add1(&collectable_count); if (newP0 != 0 || newP1 != 0) { @@ -1209,19 +1233,19 @@ GC_PTR_STORE_AND_DIRTY(newP + 1, old); old = newP; AO_fetch_and_add1(&collectable_count); - newP = (GC_word *)GC_malloc_explicitly_typed(4 * sizeof(GC_word), d2); + newP = (GC_word *)GC_MALLOC_EXPLICITLY_TYPED(4 * sizeof(GC_word), d2); CHECK_OUT_OF_MEMORY(newP); newP0 = 17; GC_PTR_STORE_AND_DIRTY(newP + 1, old); old = newP; AO_fetch_and_add1(&collectable_count); - newP = (GC_word*)GC_malloc_explicitly_typed(33 * sizeof(GC_word), d3); + newP = (GC_word*)GC_MALLOC_EXPLICITLY_TYPED(33 * sizeof(GC_word), d3); CHECK_OUT_OF_MEMORY(newP); newP0 = 17; GC_PTR_STORE_AND_DIRTY(newP + 1, old); old = newP; AO_fetch_and_add1(&collectable_count); - newP = (GC_word *)GC_calloc_explicitly_typed(4, 2 * sizeof(GC_word), + newP = (GC_word *)GC_CALLOC_EXPLICITLY_TYPED(4, 2 * sizeof(GC_word), d1); CHECK_OUT_OF_MEMORY(newP); newP0 = 17; @@ -1229,10 +1253,10 @@ old = newP; AO_fetch_and_add1(&collectable_count); if (i & 0xff) { - newP = (GC_word *)GC_calloc_explicitly_typed(7, 3 * sizeof(GC_word), + newP = (GC_word *)GC_CALLOC_EXPLICITLY_TYPED(7, 3 * sizeof(GC_word), d2); } else { - newP = (GC_word *)GC_calloc_explicitly_typed(1001, + newP = (GC_word *)GC_CALLOC_EXPLICITLY_TYPED(1001, 3 * sizeof(GC_word), d2); if (newP != NULL && (newP0 != 0 || newP1 != 0)) { @@ -1262,11 +1286,11 @@ #ifdef DBG_HDRS_ALL # define set_print_procs() (void)(A.dummy = 17) #else - int fail_count = 0; + volatile AO_t fail_count = 0; void GC_CALLBACK fail_proc1(void *x GC_ATTR_UNUSED) { - fail_count++; + AO_fetch_and_add1(&fail_count); } void set_print_procs(void) @@ -1280,7 +1304,7 @@ # ifdef THREADS # define TEST_FAIL_COUNT(n) 1 # else -# define TEST_FAIL_COUNT(n) (fail_count >= (n)) +# define TEST_FAIL_COUNT(n) (fail_count >= (AO_t)(n)) # endif #endif /* !DBG_HDRS_ALL */ @@ -1303,10 +1327,29 @@ } } +#include "private/gc_alloc_ptrs.h" + void * GC_CALLBACK inc_int_counter(void *pcounter) { - ++(*(int *)pcounter); - return NULL; + ++(*(int *)pcounter); + + /* Dummy checking of API functions while GC lock is held. */ + GC_incr_bytes_allocd(0); + GC_incr_bytes_freed(0); + + return NULL; +} + +struct thr_hndl_sb_s { + void *gc_thread_handle; + struct GC_stack_base sb; +}; + +void * GC_CALLBACK set_stackbottom(void *cd) +{ + GC_set_stackbottom(((struct thr_hndl_sb_s *)cd)->gc_thread_handle, + &((struct thr_hndl_sb_s *)cd)->sb); + return NULL; } #ifndef MIN_WORDS @@ -1329,6 +1372,7 @@ pid_t pid; int wstatus; # endif + struct thr_hndl_sb_s thr_hndl_sb; GC_FREE(0); # ifdef THREADS @@ -1373,7 +1417,7 @@ GC_printf("GC_is_heap_ptr(&local_var) produced incorrect result\n"); FAIL; } - if (GC_is_heap_ptr(&fail_count) || GC_is_heap_ptr(NULL)) { + if (GC_is_heap_ptr((void *)&fail_count) || GC_is_heap_ptr(NULL)) { GC_printf("GC_is_heap_ptr(&global_var) produced incorrect result\n"); FAIL; } @@ -1407,16 +1451,15 @@ GC_printf("GC_PTR_STORE failed: %p != %p\n", (void *)(*z), (void *)x); FAIL; } - if (!TEST_FAIL_COUNT(1)) { -# if!(defined(POWERPC) || defined(IA64)) || defined(M68K) +# if !defined(IA64) && !defined(POWERPC) + if (!TEST_FAIL_COUNT(1)) { /* On POWERPCs function pointers point to a descriptor in the */ /* data segment, so there should have been no failures. */ - /* The same applies to IA64. Something similar seems to */ - /* be going on with NetBSD/M68K. */ + /* The same applies to IA64. */ GC_printf("GC_is_visible produced wrong failure indication\n"); FAIL; -# endif - } + } +# endif if (GC_is_valid_displacement(y) != y || GC_is_valid_displacement(x) != x || GC_is_valid_displacement(x + 3) != x + 3) { @@ -1434,7 +1477,7 @@ } } # ifndef ALL_INTERIOR_POINTERS -# if defined(RS6000) || defined(POWERPC) +# if defined(POWERPC) if (!TEST_FAIL_COUNT(1)) # else if (!TEST_FAIL_COUNT(GC_get_all_interior_pointers() ? 1 : 2)) @@ -1473,6 +1516,7 @@ GC_FREE(GC_MALLOC_IGNORE_OFF_PAGE(2)); } } + thr_hndl_sb.gc_thread_handle = GC_get_my_stackbottom(&thr_hndl_sb.sb); # ifdef GC_GCJ_SUPPORT GC_REGISTER_DISPLACEMENT(sizeof(struct fake_vtable *)); GC_init_gcj_malloc(0, (void *)(GC_word)fake_gcj_mark_proc); @@ -1505,35 +1549,54 @@ FAIL; } if (print_stats) - GC_log_printf("Forked child process\n"); + GC_log_printf("Forked child process, pid= %ld\n", (long)pid); if (waitpid(pid, &wstatus, 0) == -1) { GC_printf("Wait for child process failed\n"); FAIL; } if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) { - GC_printf("Child process failed, status= 0x%x\n", wstatus); + GC_printf("Child process failed, pid= %ld, status= 0x%x\n", + (long)pid, wstatus); FAIL; } } else { + pid_t child_pid = getpid(); + GC_atfork_child(); if (print_stats) - GC_log_printf("Started a child process\n"); -# ifdef THREADS -# ifdef PARALLEL_MARK - GC_gcollect(); /* no parallel markers */ -# endif - GC_start_mark_threads(); + GC_log_printf("Started a child process, pid= %ld\n", + (long)child_pid); +# ifdef PARALLEL_MARK + GC_gcollect(); /* no parallel markers */ # endif + GC_start_mark_threads(); GC_gcollect(); # ifdef THREADS + /* Skip "Premature finalization" check in the */ + /* child process because there could be a chance */ + /* that some other thread of the parent was */ + /* executing mktree at the moment of fork. */ + dropped_something = 1; +# endif + tree_test(); +# if !defined(DBG_HDRS_ALL) && !defined(NO_TYPED_TEST) + typed_test(); +# endif +# ifdef THREADS + if (print_stats) + GC_log_printf("Starting tiny reverse test, pid= %ld\n", + (long)child_pid); tiny_reverse_test(0); GC_gcollect(); # endif if (print_stats) - GC_log_printf("Finished a child process\n"); + GC_log_printf("Finished a child process, pid= %ld\n", + (long)child_pid); exit(0); } # endif + (void)GC_call_with_alloc_lock(set_stackbottom, &thr_hndl_sb); + /* Repeated list reversal test. */ # ifndef NO_CLOCK GET_TIME(start_time); @@ -1543,7 +1606,7 @@ if (print_stats) { GET_TIME(reverse_time); time_diff = MS_TIME_DIFF(reverse_time, start_time); - GC_log_printf("-------------Finished reverse_test at time %u (%p)\n", + GC_log_printf("Finished reverse_test at time %u (%p)\n", (unsigned) time_diff, (void *)&start_time); } # endif @@ -1555,7 +1618,7 @@ GET_TIME(typed_time); time_diff = MS_TIME_DIFF(typed_time, start_time); - GC_log_printf("-------------Finished typed_test at time %u (%p)\n", + GC_log_printf("Finished typed_test at time %u (%p)\n", (unsigned) time_diff, (void *)&start_time); } # endif @@ -1571,7 +1634,7 @@ GET_TIME(tree_time); time_diff = MS_TIME_DIFF(tree_time, start_time); - GC_log_printf("-------------Finished tree_test at time %u (%p)\n", + GC_log_printf("Finished tree_test at time %u (%p)\n", (unsigned) time_diff, (void *)&start_time); } # endif @@ -1581,9 +1644,8 @@ if (print_stats) { GET_TIME(reverse_time); time_diff = MS_TIME_DIFF(reverse_time, start_time); - GC_log_printf( - "-------------Finished second reverse_test at time %u (%p)\n", - (unsigned)time_diff, (void *)&start_time); + GC_log_printf("Finished second reverse_test at time %u (%p)\n", + (unsigned)time_diff, (void *)&start_time); } # endif /* GC_allocate_ml and GC_need_to_lock are no longer exported, and */ @@ -1622,12 +1684,6 @@ (*(unsigned *)pcounter)++; } -void * GC_CALLBACK reachable_objs_count_enumerator(void *pcounter) -{ - GC_enumerate_reachable_objects_inner(reachable_objs_counter, pcounter); - return NULL; -} - #define NUMBER_ROUND_UP(v, bound) ((((v) + (bound) - 1) / (bound)) * (bound)) void check_heap_stats(void) @@ -1658,7 +1714,7 @@ # endif # else # if CPP_WORDSZ == 64 - max_heap_sz = 25000000; + max_heap_sz = 26000000; # else max_heap_sz = 16000000; # endif @@ -1707,16 +1763,18 @@ FAIL; } } - (void)GC_call_with_alloc_lock(reachable_objs_count_enumerator, - &obj_count); + GC_alloc_lock(); + GC_enumerate_reachable_objects_inner(reachable_objs_counter, &obj_count); + GC_alloc_unlock(); GC_printf("Completed %u tests\n", n_tests); GC_printf("Allocated %d collectable objects\n", (int)collectable_count); GC_printf("Allocated %d uncollectable objects\n", (int)uncollectable_count); GC_printf("Allocated %d atomic objects\n", (int)atomic_count); GC_printf("Reallocated %d objects\n", (int)realloc_count); - GC_printf("Finalized %d/%d objects - ", - finalized_count, finalizable_count); +# ifndef NO_TEST_HANDLE_FORK + GC_printf("Garbage collection after fork is tested too\n"); +# endif # ifndef GC_NO_FINALIZATION if (!GC_get_find_leak()) { int still_live = 0; @@ -1726,16 +1784,20 @@ # ifdef FINALIZE_ON_DEMAND if (finalized_count != late_finalize_count) { - GC_printf("Demand finalization error\n"); - FAIL; + GC_printf("Finalized %d/%d objects - demand finalization error\n", + finalized_count, finalizable_count); + FAIL; } # endif if (finalized_count > finalizable_count || finalized_count < finalizable_count/2) { - GC_printf("finalization is probably broken\n"); + GC_printf("Finalized %d/%d objects - " + "finalization is probably broken\n", + finalized_count, finalizable_count); FAIL; } else { - GC_printf("finalization is probably ok\n"); + GC_printf("Finalized %d/%d objects - finalization is probably OK\n", + finalized_count, finalizable_count); } for (i = 0; i < MAX_FINALIZED; i++) { if (live_indicatorsi != 0) { @@ -1788,6 +1850,14 @@ (unsigned long)max_heap_sz); FAIL; } +# ifdef USE_MUNMAP + GC_printf("Obtained %lu bytes from OS (of which %lu bytes unmapped)\n", + (unsigned long)GC_get_obtained_from_os_bytes(), + (unsigned long)GC_get_unmapped_bytes()); +# else + GC_printf("Obtained %lu bytes from OS\n", + (unsigned long)GC_get_obtained_from_os_bytes()); +# endif GC_printf("Final number of reachable objects is %u\n", obj_count); # ifndef GC_GET_HEAP_USAGE_NOT_NEEDED @@ -1807,14 +1877,18 @@ # ifdef THREADS GC_unregister_my_thread(); /* just to check it works (for main) */ # endif - GC_printf("Completed %u collections", (unsigned)GC_get_gc_no()); -# ifndef NO_CLOCK - GC_printf(" in %lu msecs", GC_get_full_gc_total_time()); -# endif -# ifdef PARALLEL_MARK - GC_printf(" (using %d marker threads)", GC_get_parallel() + 1); +# ifdef NO_CLOCK + GC_printf("Completed %u collections\n", (unsigned)GC_get_gc_no()); +# elif !defined(PARALLEL_MARK) + GC_printf("Completed %u collections in %lu ms\n", + (unsigned)GC_get_gc_no(), GC_get_full_gc_total_time()); +# else + GC_printf("Completed %u collections in %lu ms" + " (using %d marker threads)\n", + (unsigned)GC_get_gc_no(), GC_get_full_gc_total_time(), + GC_get_parallel() + 1); # endif - GC_printf("\n" "Collector appears to work\n"); + GC_printf("Collector appears to work\n"); } #if defined(MACOS) @@ -1839,6 +1913,36 @@ /*FAIL;*/ } +void enable_incremental_mode(void) +{ +# if (defined(TEST_DEFAULT_VDB) || defined(TEST_MANUAL_VDB) \ + || !defined(DEFAULT_VDB)) && !defined(GC_DISABLE_INCREMENTAL) +# if !defined(MAKE_BACK_GRAPH) && !defined(NO_INCREMENTAL) \ + && !defined(REDIRECT_MALLOC) && !defined(USE_PROC_FOR_LIBRARIES) + GC_enable_incremental(); +# endif + if (GC_is_incremental_mode()) { +# ifndef SMALL_CONFIG + if (GC_get_manual_vdb_allowed()) { + GC_printf("Switched to incremental mode (manual VDB)\n"); + } else +# endif + /* else */ { + GC_printf("Switched to incremental mode\n"); + if (GC_incremental_protection_needs() == GC_PROTECTS_NONE) { +# if defined(PROC_VDB) || defined(SOFT_VDB) + GC_printf("Reading dirty bits from /proc\n"); +# elif defined(GWW_VDB) + GC_printf("Using GetWriteWatch-based implementation\n"); +# endif + } else { + GC_printf("Emulating dirty bits with mprotect/signals\n"); + } + } + } +# endif +} + #if defined(CPPCHECK) # include "javaxfc.h" /* for GC_finalize_all */ # define UNTESTED(sym) GC_noop1((word)&sym) @@ -1852,6 +1956,32 @@ #if !defined(PCR) && !defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) +#if defined(CPPCHECK) && defined(_MSC_VER) && !defined(_M_ARM) \ + && !defined(_M_ARM64) && !defined(_M_X64) +# include "private/msvc_dbg.h" +#endif + +#if defined(_DEBUG) && (_MSC_VER >= 1900) /* VS 2015+ */ +# ifndef _CRTDBG_MAP_ALLOC +# define _CRTDBG_MAP_ALLOC +# endif +# include <crtdbg.h> + /* Ensure that there is no system-malloc-allocated objects at normal */ + /* exit (i.e. no such memory leaked). */ +# define CRTMEM_CHECK_INIT() \ + (void)_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF) +# define CRTMEM_DUMP_LEAKS() \ + do { \ + if (_CrtDumpMemoryLeaks()) { \ + GC_printf("System-malloc-allocated memory leaked\n"); \ + FAIL; \ + } \ + } while (0) +#else +# define CRTMEM_CHECK_INIT() (void)0 +# define CRTMEM_DUMP_LEAKS() (void)0 +#endif /* !_MSC_VER */ + #if ((defined(MSWIN32) && !defined(__MINGW32__)) || defined(MSWINCE)) \ && !defined(NO_WINMAIN_ENTRY) int APIENTRY WinMain(HINSTANCE instance GC_ATTR_UNUSED, @@ -1872,6 +2002,7 @@ int main(void) #endif { + CRTMEM_CHECK_INIT(); # if defined(CPPCHECK) && !defined(NO_WINMAIN_ENTRY) \ && ((defined(MSWIN32) && !defined(__MINGW32__)) || defined(MSWINCE)) GC_noop1((GC_word)&WinMain); @@ -1879,6 +2010,7 @@ GC_noop1((GC_word)&Init); # endif n_tests = 0; + GC_clear_exclusion_table(); /* no-op as called before GC init */ # if defined(MACOS) /* Make sure we have lots and lots of stack space. */ SetMinimumStack(cMinStackSpace); @@ -1887,35 +2019,17 @@ # endif GC_COND_INIT(); GC_set_warn_proc(warn_proc); -# if !defined(GC_DISABLE_INCREMENTAL) \ - && (defined(TEST_DEFAULT_VDB) || !defined(DEFAULT_VDB)) -# if !defined(MAKE_BACK_GRAPH) && !defined(NO_INCREMENTAL) \ - && !(defined(MPROTECT_VDB) && defined(USE_MUNMAP)) - GC_enable_incremental(); -# endif - if (GC_is_incremental_mode()) { -# ifndef SMALL_CONFIG - if (GC_get_manual_vdb_allowed()) { - GC_printf("Switched to incremental mode (manual VDB)\n"); - } else -# endif - /* else */ { - GC_printf("Switched to incremental mode\n"); -# ifdef PROC_VDB - GC_printf("Reading dirty bits from /proc\n"); -# elif defined(GWW_VDB) - GC_printf("Using GetWriteWatch-based implementation\n"); -# ifdef MPROTECT_VDB - GC_printf("Or emulating dirty bits with mprotect/signals\n"); -# endif -# elif defined(MPROTECT_VDB) - GC_printf("Emulating dirty bits with mprotect/signals\n"); -# endif /* MPROTECT_VDB && !GWW_VDB */ - } - } -# endif + enable_incremental_mode(); set_print_procs(); + GC_start_incremental_collection(); run_one_test(); +# if NTHREADS > 0 + { + int i; + for (i = 0; i < NTHREADS; i++) + run_one_test(); + } +# endif run_single_threaded_test(); check_heap_stats(); # ifndef MSWINCE @@ -1943,68 +2057,24 @@ # if defined(MACOS) && defined(USE_TEMPORARY_MEMORY) UNTESTED(GC_MacTemporaryNewPtr); # endif -# if !defined(_M_AMD64) && defined(_MSC_VER) +# if !defined(_M_ARM) && !defined(_M_ARM64) \ + && !defined(_M_X64) && defined(_MSC_VER) UNTESTED(GetFileLineFromStack); UNTESTED(GetModuleNameFromStack); UNTESTED(GetSymbolNameFromStack); # endif UNTESTED(GC_abort_on_oom); - UNTESTED(GC_get_bytes_since_gc); - UNTESTED(GC_get_dont_expand); - UNTESTED(GC_get_dont_precollect); - UNTESTED(GC_get_finalize_on_demand); - UNTESTED(GC_get_finalizer_notifier); - UNTESTED(GC_get_force_unmap_on_gcollect); - UNTESTED(GC_get_free_bytes); - UNTESTED(GC_get_free_space_divisor); - UNTESTED(GC_get_full_freq); - UNTESTED(GC_get_java_finalization); - UNTESTED(GC_get_max_retries); - UNTESTED(GC_get_no_dls); - UNTESTED(GC_get_non_gc_bytes); - UNTESTED(GC_get_on_collection_event); - UNTESTED(GC_get_on_heap_resize); - UNTESTED(GC_get_pages_executable); - UNTESTED(GC_get_push_other_roots); - UNTESTED(GC_get_start_callback); - UNTESTED(GC_get_stop_func); - UNTESTED(GC_get_time_limit); - UNTESTED(GC_get_warn_proc); - UNTESTED(GC_is_disabled); - UNTESTED(GC_set_dont_precollect); - UNTESTED(GC_set_finalize_on_demand); - UNTESTED(GC_set_finalizer_notifier); - UNTESTED(GC_set_free_space_divisor); - UNTESTED(GC_set_full_freq); - UNTESTED(GC_set_java_finalization); - UNTESTED(GC_set_max_retries); - UNTESTED(GC_set_no_dls); - UNTESTED(GC_set_non_gc_bytes); - UNTESTED(GC_set_on_collection_event); - UNTESTED(GC_set_on_heap_resize); - UNTESTED(GC_set_oom_fn); - UNTESTED(GC_set_push_other_roots); - UNTESTED(GC_set_start_callback); - UNTESTED(GC_set_stop_func); - UNTESTED(GC_set_time_limit); UNTESTED(GC_malloc_explicitly_typed_ignore_off_page); - UNTESTED(GC_debug_change_stubborn); UNTESTED(GC_debug_strndup); UNTESTED(GC_deinit); UNTESTED(GC_strndup); UNTESTED(GC_posix_memalign); - UNTESTED(GC_new_free_list); - UNTESTED(GC_new_kind); UNTESTED(GC_new_proc); UNTESTED(GC_clear_roots); UNTESTED(GC_exclude_static_roots); UNTESTED(GC_expand_hp); UNTESTED(GC_register_describe_type_fn); UNTESTED(GC_register_has_static_roots_callback); -# if !defined(PCR) && !defined(SMALL_CONFIG) - UNTESTED(GC_get_abort_func); - UNTESTED(GC_set_abort_func); -# endif # ifdef GC_GCJ_SUPPORT UNTESTED(GC_gcj_malloc_ignore_off_page); # endif @@ -2019,9 +2089,7 @@ # endif # ifndef GC_NO_FINALIZATION UNTESTED(GC_debug_register_finalizer_unreachable); - UNTESTED(GC_get_await_finalize_proc); UNTESTED(GC_register_disappearing_link); - UNTESTED(GC_set_await_finalize_proc); UNTESTED(GC_should_invoke_finalizers); # ifndef JAVA_FINALIZATION_NOT_NEEDED UNTESTED(GC_finalize_all); @@ -2030,8 +2098,6 @@ UNTESTED(GC_dump_finalization); # endif # ifndef GC_TOGGLE_REFS_NOT_NEEDED - UNTESTED(GC_get_toggleref_func); - UNTESTED(GC_set_toggleref_func); UNTESTED(GC_toggleref_add); # endif # endif @@ -2057,9 +2123,10 @@ UNTESTED(GC_debug_wcsdup); # endif # endif -# ifdef MSWIN32 +# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) GC_win32_free_heap(); # endif + CRTMEM_DUMP_LEAKS(); # ifdef RTEMS exit(0); # else @@ -2173,27 +2240,24 @@ GC_noop1((GC_word)&WinMain); # endif # if defined(GC_DLL) && !defined(GC_NO_THREADS_DISCOVERY) \ - && !defined(MSWINCE) && !defined(THREAD_LOCAL_ALLOC) \ - && !defined(PARALLEL_MARK) + && !defined(MSWINCE) && !defined(THREAD_LOCAL_ALLOC) GC_use_threads_discovery(); /* Test with implicit thread registration if possible. */ GC_printf("Using DllMain to track threads\n"); # endif GC_COND_INIT(); -# if !defined(MAKE_BACK_GRAPH) && !defined(NO_INCREMENTAL) - GC_enable_incremental(); -# endif + enable_incremental_mode(); InitializeCriticalSection(&incr_cs); GC_set_warn_proc(warn_proc); # ifdef MSWINCE win_created_h = CreateEvent(NULL, FALSE, FALSE, NULL); if (win_created_h == (HANDLE)NULL) { - GC_printf("Event creation failed %d\n", (int)GetLastError()); + GC_printf("Event creation failed, errcode= %d\n", (int)GetLastError()); FAIL; } - win_thr_h = GC_CreateThread(NULL, 0, thr_window, 0, 0, &thread_id); + win_thr_h = CreateThread(NULL, 0, thr_window, 0, 0, &thread_id); if (win_thr_h == (HANDLE)NULL) { - GC_printf("Thread creation failed %d\n", (int)GetLastError()); + GC_printf("Thread creation failed, errcode= %d\n", (int)GetLastError()); FAIL; } if (WaitForSingleObject(win_created_h, INFINITE) != WAIT_OBJECT_0) @@ -2203,9 +2267,9 @@ set_print_procs(); # if NTHREADS > 0 for (i = 0; i < NTHREADS; i++) { - hi = GC_CreateThread(NULL, 0, thr_run_one_test, 0, 0, &thread_id); + hi = CreateThread(NULL, 0, thr_run_one_test, 0, 0, &thread_id); if (hi == (HANDLE)NULL) { - GC_printf("Thread creation failed %d\n", (int)GetLastError()); + GC_printf("Thread creation failed, errcode= %d\n", (int)GetLastError()); FAIL; } } @@ -2214,7 +2278,7 @@ # if NTHREADS > 0 for (i = 0; i < NTHREADS; i++) { if (WaitForSingleObject(hi, INFINITE) != WAIT_OBJECT_0) { - GC_printf("Thread wait failed %d\n", (int)GetLastError()); + GC_printf("Thread wait failed, errcode= %d\n", (int)GetLastError()); FAIL; } } @@ -2273,6 +2337,8 @@ #endif #if defined(GC_PTHREADS) +# include <errno.h> /* for EAGAIN */ + void * thr_run_one_test(void * arg GC_ATTR_UNUSED) { run_one_test(); @@ -2287,7 +2353,7 @@ { # if NTHREADS > 0 pthread_t thNTHREADS; - int i; + int i, nthreads; # endif pthread_attr_t attr; int code; @@ -2313,42 +2379,23 @@ GC_use_threads_discovery(); GC_printf("Using Darwin task-threads-based world stop and push\n"); # endif + GC_set_markers_count(0); GC_COND_INIT(); if ((code = pthread_attr_init(&attr)) != 0) { - GC_printf("pthread_attr_init failed, error=%d\n", code); + GC_printf("pthread_attr_init failed, errno= %d\n", code); FAIL; } # if defined(GC_IRIX_THREADS) || defined(GC_FREEBSD_THREADS) \ || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) \ || defined(GC_OPENBSD_THREADS) if ((code = pthread_attr_setstacksize(&attr, 1000 * 1024)) != 0) { - GC_printf("pthread_attr_setstacksize failed, error=%d\n", code); + GC_printf("pthread_attr_setstacksize failed, errno= %d\n", code); FAIL; } # endif n_tests = 0; -# if !defined(GC_DISABLE_INCREMENTAL) \ - && (defined(TEST_DEFAULT_VDB) || !defined(DEFAULT_VDB)) -# if !defined(REDIRECT_MALLOC) && !defined(MAKE_BACK_GRAPH) \ - && !defined(USE_PROC_FOR_LIBRARIES) && !defined(NO_INCREMENTAL) \ - && !defined(USE_MUNMAP) - GC_enable_incremental(); -# endif - if (GC_is_incremental_mode()) { -# ifndef SMALL_CONFIG - if (GC_get_manual_vdb_allowed()) { - GC_printf("Switched to incremental mode (manual VDB)\n"); - } else -# endif - /* else */ { - GC_printf("Switched to incremental mode\n"); -# ifdef MPROTECT_VDB - GC_printf("Emulating dirty bits with mprotect/signals\n"); -# endif - } - } -# endif + enable_incremental_mode(); GC_set_min_bytes_allocd(1); if (GC_get_min_bytes_allocd() != 1) FAIL; @@ -2358,38 +2405,80 @@ FAIL; GC_set_warn_proc(warn_proc); if ((code = pthread_key_create(&fl_key, 0)) != 0) { - GC_printf("Key creation failed %d\n", code); + GC_printf("Key creation failed, errno= %d\n", code); FAIL; } set_print_procs(); # if NTHREADS > 0 for (i = 0; i < NTHREADS; ++i) { if ((code = pthread_create(th+i, &attr, thr_run_one_test, 0)) != 0) { - GC_printf("Thread %d creation failed %d\n", i, code); + GC_printf("Thread %d creation failed, errno= %d\n", i, code); + if (i > 0 && EAGAIN == code) + break; /* Resource temporarily unavailable */ FAIL; } } -# endif - run_one_test(); -# if NTHREADS > 0 - for (i = 0; i < NTHREADS; ++i) { + nthreads = i; + for (; i <= NTHREADS; i++) + run_one_test(); + for (i = 0; i < nthreads; ++i) { if ((code = pthread_join(thi, 0)) != 0) { - GC_printf("Thread %d failed %d\n", i, code); + GC_printf("Thread %d join failed, errno= %d\n", i, code); FAIL; } } +# else + run_one_test(); # endif run_single_threaded_test(); check_heap_stats(); (void)fflush(stdout); (void)pthread_attr_destroy(&attr); + + /* Dummy checking of various getters and setters. */ + (void)GC_get_bytes_since_gc(); + (void)GC_get_free_bytes(); + (void)GC_get_pages_executable(); + (void)GC_get_warn_proc(); + (void)GC_is_disabled(); + GC_set_allocd_bytes_per_finalizer(GC_get_allocd_bytes_per_finalizer()); + GC_set_disable_automatic_collection(GC_get_disable_automatic_collection()); + GC_set_dont_expand(GC_get_dont_expand()); + GC_set_dont_precollect(GC_get_dont_precollect()); + GC_set_finalize_on_demand(GC_get_finalize_on_demand()); + GC_set_finalizer_notifier(GC_get_finalizer_notifier()); + GC_set_force_unmap_on_gcollect(GC_get_force_unmap_on_gcollect()); + GC_set_free_space_divisor(GC_get_free_space_divisor()); + GC_set_full_freq(GC_get_full_freq()); + GC_set_java_finalization(GC_get_java_finalization()); + GC_set_max_retries(GC_get_max_retries()); + GC_set_no_dls(GC_get_no_dls()); + GC_set_non_gc_bytes(GC_get_non_gc_bytes()); + GC_set_on_collection_event(GC_get_on_collection_event()); + GC_set_on_heap_resize(GC_get_on_heap_resize()); + GC_set_on_thread_event(GC_get_on_thread_event()); + GC_set_oom_fn(GC_get_oom_fn()); + GC_set_push_other_roots(GC_get_push_other_roots()); + GC_set_start_callback(GC_get_start_callback()); + GC_set_stop_func(GC_get_stop_func()); + GC_set_suspend_signal(GC_get_suspend_signal()); + GC_set_thr_restart_signal(GC_get_thr_restart_signal()); + GC_set_time_limit(GC_get_time_limit()); +# if !defined(PCR) && !defined(SMALL_CONFIG) + GC_set_abort_func(GC_get_abort_func()); +# endif +# ifndef NO_CLOCK + GC_set_time_limit_tv(GC_get_time_limit_tv()); +# endif +# ifndef GC_NO_FINALIZATION + GC_set_await_finalize_proc(GC_get_await_finalize_proc()); +# ifndef GC_TOGGLE_REFS_NOT_NEEDED + GC_set_toggleref_func(GC_get_toggleref_func()); +# endif +# endif # if defined(CPPCHECK) UNTESTED(GC_allow_register_threads); - UNTESTED(GC_get_on_thread_event); UNTESTED(GC_register_altstack); - UNTESTED(GC_set_on_thread_event); - UNTESTED(GC_set_suspend_signal); - UNTESTED(GC_set_thr_restart_signal); UNTESTED(GC_stop_world_external); UNTESTED(GC_start_world_external); # ifndef GC_NO_DLOPEN
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/test_cpp.cc -> _service:tar_scm:gc-8.2.2.tar.gz/tests/test_cpp.cc
Changed
@@ -1,16 +1,17 @@ -/**************************************************************************** -Copyright (c) 1994 by Xerox Corporation. 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. -**************************************************************************** +/* + * Copyright (c) 1994 by Xerox Corporation. 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. + */ +/**************************************************************************** usage: test_cpp number-of-iterations This program tries to test the specific C++ functionality provided by @@ -35,12 +36,7 @@ #include <stdlib.h> #include <string.h> -#ifndef DONT_USE_STD_ALLOCATOR -# include "gc_allocator.h" -#else - /* Note: This works only for ancient STL versions. */ -# include "new_gc_alloc.h" -#endif +#include "gc_allocator.h" # include "private/gcconfig.h" @@ -75,23 +71,21 @@ __LINE__ ); \ exit( 1 ); } -#ifndef GC_ATTR_EXPLICIT -# if __cplusplus >= 201103L && !defined(__clang__) || _MSVC_LANG >= 201103L \ - || defined(CPPCHECK) -# define GC_ATTR_EXPLICIT explicit -# else -# define GC_ATTR_EXPLICIT /* empty */ -# endif +#if defined(__powerpc64__) && !defined(__clang__) && GC_GNUC_PREREQ(10, 0) + /* Suppress "layout of aggregates ... has changed" GCC note. */ +# define A_I_TYPE short +#else +# define A_I_TYPE int #endif class A {public: /* An uncollectible class. */ - GC_ATTR_EXPLICIT A( int iArg ): i( iArg ) {} + GC_ATTR_EXPLICIT A( int iArg ): i((A_I_TYPE)iArg) {} void Test( int iArg ) { my_assert( i == iArg );} virtual ~A() {} - int i;}; + A_I_TYPE i; }; class B: public GC_NS_QUALIFY(gc), public A { public: @@ -165,7 +159,9 @@ GC_gcollect(); } my_assert(nFreed <= nAllocated); - my_assert(nFreed >= (nAllocated / 5) * 4 || GC_get_find_leak()); +# ifndef GC_NO_FINALIZATION + my_assert(nFreed >= (nAllocated / 5) * 4 || GC_get_find_leak()); +# endif } static int nFreed; @@ -189,7 +185,9 @@ nFreed++; my_assert( (GC_word)self->i == (GC_word)data );} static void Test() { - my_assert(nFreed >= (nAllocated / 5) * 4 || GC_get_find_leak()); +# ifndef GC_NO_FINALIZATION + my_assert(nFreed >= (nAllocated / 5) * 4 || GC_get_find_leak()); +# endif } int i; @@ -228,7 +226,9 @@ } static void Test() { - my_assert(nFreedF >= (nAllocatedF / 5) * 4 || GC_get_find_leak()); +# ifndef GC_NO_FINALIZATION + my_assert(nFreedF >= (nAllocatedF / 5) * 4 || GC_get_find_leak()); +# endif my_assert(2 * nFreedF == nFreed); } @@ -318,24 +318,18 @@ GC_printf("This test program is not designed for leak detection mode\n"); int i, iters, n; -# ifndef DONT_USE_STD_ALLOCATOR - int *x = gc_allocator<int>().allocate(1); - int *xio; - xio = gc_allocator_ignore_off_page<int>().allocate(1); - (void)xio; - int **xptr = traceable_allocator<int *>().allocate(1); -# else - int *x = (int *)gc_alloc::allocate(sizeof(int)); -# endif + int *x = gc_allocator<int>().allocate(1); + int *xio; + xio = gc_allocator_ignore_off_page<int>().allocate(1); + GC_reachable_here(xio); + int **xptr = traceable_allocator<int *>().allocate(1); *x = 29; -# ifndef DONT_USE_STD_ALLOCATOR - if (!xptr) { - fprintf(stderr, "Out of memory!\n"); - exit(3); - } - GC_PTR_STORE_AND_DIRTY(xptr, x); - x = 0; -# endif + if (!xptr) { + fprintf(stderr, "Out of memory!\n"); + exit(3); + } + GC_PTR_STORE_AND_DIRTY(xptr, x); + x = 0; if (argc != 2 || (n = (int)COVERT_DATAFLOW(atoi(argv1))) <= 0) { GC_printf("usage: test_cpp number-of-iterations\n" @@ -363,7 +357,7 @@ D* d; F* f; d = ::new (USE_GC, D::CleanUp, (void*)(GC_word)i) D( i ); - (void)d; + GC_reachable_here(d); f = new F; F** fa = new F*1; fa0 = f; @@ -379,7 +373,7 @@ for (i = 0; i < 1000000; i++) { A* a; a = new (USE_GC) A( i ); - (void)a; + GC_reachable_here(a); B* b; b = new B( i ); (void)b; @@ -388,7 +382,7 @@ B::Deleting( 1 ); GC_CHECKED_DELETE(b); B::Deleting( 0 );} -# ifdef FINALIZE_ON_DEMAND +# if defined(FINALIZE_ON_DEMAND) && !defined(GC_NO_FINALIZATION) GC_invoke_finalizers(); # endif } @@ -410,7 +404,7 @@ B::Deleting( 1 ); GC_CHECKED_DELETE(b); B::Deleting( 0 ); -# ifdef FINALIZE_ON_DEMAND +# if defined(FINALIZE_ON_DEMAND) && !defined(GC_NO_FINALIZATION) GC_invoke_finalizers(); # endif } @@ -421,9 +415,7 @@ D::Test(); F::Test();} -# ifndef DONT_USE_STD_ALLOCATOR - x = *xptr; -# endif + x = *xptr; my_assert (29 == x0); GC_printf( "The test appears to have succeeded.\n" ); return( 0 );
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/tests.am -> _service:tar_scm:gc-8.2.2.tar.gz/tests/tests.am
Changed
@@ -21,6 +21,17 @@ endif gctest_DEPENDENCIES = $(top_builddir)/libgc.la +if EMSCRIPTEN +# Note: because of libtool, you'll need to point your browser to +# .libs/gctest.html, not gctest.html at topdir. +check_PROGRAMS += gctest.html +gctest_html_SOURCES = $(gctest_SOURCES) +gctest_html_LDADD = $(gctest_LDADD) +# Bug in the linker not being able to determine that _memalign and +# _memalign is needed? it's part of mmap. +gctest_html_LDFLAGS = -s "EXPORTED_FUNCTIONS='_memalign', '_main', '_memset'" +endif + TESTS += leaktest$(EXEEXT) check_PROGRAMS += leaktest leaktest_SOURCES = tests/leak_test.c @@ -107,7 +118,7 @@ check_PROGRAMS += test_cpp test_cpp_SOURCES = tests/test_cpp.cc if AVOID_CPP_LIB -test_cpp_LDADD = gc_cpp.o $(test_ldadd) $(CXXLIBS) +test_cpp_LDADD = gc_badalc.o gc_cpp.o $(test_ldadd) $(CXXLIBS) else test_cpp_LDADD = libgccpp.la $(nodist_libgc_la_OBJECTS) \ $(EXTRA_TEST_LIBS) $(CXXLIBS)
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/thread_leak_test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/thread_leak_test.c
Changed
@@ -11,6 +11,7 @@ #include "leak_detector.h" #ifdef GC_PTHREADS +# include <errno.h> /* for EAGAIN */ # include <pthread.h> #else # ifndef WIN32_LEAN_AND_MEAN @@ -50,7 +51,7 @@ int main(void) { # if NTHREADS > 0 - int i; + int i, n; # ifdef GC_PTHREADS pthread_t tNTHREADS; # else @@ -73,12 +74,15 @@ code = ti != NULL ? 0 : (int)GetLastError(); # endif if (code != 0) { - fprintf(stderr, "Thread creation failed %d\n", code); + fprintf(stderr, "Thread creation failed, errcode= %d\n", code); +# ifdef GC_PTHREADS + if (i > 1 && EAGAIN == code) break; +# endif exit(2); } } - - for (i = 0; i < NTHREADS; ++i) { + n = i; + for (i = 0; i < n; ++i) { # ifdef GC_PTHREADS code = pthread_join(ti, 0); # else @@ -86,7 +90,7 @@ (int)GetLastError(); # endif if (code != 0) { - fprintf(stderr, "Thread join failed %d\n", code); + fprintf(stderr, "Thread join failed, errcode= %d\n", code); exit(2); } }
View file
_service:tar_scm:gc-8.0.6.tar.gz/tests/threadkey_test.c -> _service:tar_scm:gc-8.2.2.tar.gz/tests/threadkey_test.c
Changed
@@ -24,7 +24,7 @@ #ifdef SKIP_THREADKEY_TEST -int main (void) +int main(void) { printf("threadkey_test skipped\n"); return 0; @@ -81,10 +81,12 @@ } #ifndef NTHREADS -# define NTHREADS 30 /* number of initial threads */ +# define NTHREADS 5 #endif -int main (void) +#define NTHREADS_INNER (NTHREADS * 6) /* number of threads to create */ + +int main(void) { int i; @@ -96,7 +98,7 @@ # else pthread_once (&key_once, make_key); # endif - for (i = 0; i < NTHREADS; i++) { + for (i = 0; i < NTHREADS_INNER; i++) { pthread_t t; if (GC_pthread_create(&t, NULL, entry, NULL) == 0) { @@ -105,7 +107,7 @@ : GC_pthread_detach(t); if (code != 0) { - fprintf(stderr, "Thread %s failed %d\n", + fprintf(stderr, "Thread %s failed, errno= %d\n", (i & 1) != 0 ? "join" : "detach", code); exit(2); }
View file
_service:tar_scm:gc-8.0.6.tar.gz/thread_local_alloc.c -> _service:tar_scm:gc-8.2.2.tar.gz/thread_local_alloc.c
Changed
@@ -97,7 +97,10 @@ GC_ASSERT(I_HOLD_LOCK()); if (!EXPECT(keys_initialized, TRUE)) { - GC_ASSERT((word)&GC_thread_key % sizeof(word) == 0); +# ifdef USE_CUSTOM_SPECIFIC + /* Ensure proper alignment of a "pushed" GC symbol. */ + GC_ASSERT((word)&GC_thread_key % sizeof(word) == 0); +# endif res = GC_key_create(&GC_thread_key, reset_thread_key); if (COVERT_DATAFLOW(res) != 0) { ABORT("Failed to create key for local allocator"); @@ -176,10 +179,15 @@ GC_ASSERT(GC_is_initialized); GC_ASSERT(GC_is_thread_tsd_valid(tsd)); granules = ROUNDED_UP_GRANULES(bytes); +# if defined(CPPCHECK) +# define MALLOC_KIND_PTRFREE_INIT (void*)1 +# else +# define MALLOC_KIND_PTRFREE_INIT NULL +# endif GC_FAST_MALLOC_GRANS(result, granules, ((GC_tlfs)tsd) -> _freelistskind, DIRECT_GRANULES, kind, GC_malloc_kind_global(bytes, kind), - (void)(kind == PTRFREE ? NULL + (void)(kind == PTRFREE ? MALLOC_KIND_PTRFREE_INIT : (obj_link(result) = 0))); # ifdef LOG_ALLOCS GC_log_printf("GC_malloc_kind(%lu, %d) returned %p, recent GC #%lu\n", @@ -223,7 +231,7 @@ void *result; void **tiny_fl; - GC_ASSERT(GC_gcj_malloc_initialized); + GC_ASSERT(GC_gcjobjfreelist != NULL); tiny_fl = ((GC_tlfs)GC_getspecific(GC_thread_key))->gcj_freelists; GC_FAST_MALLOC_GRANS(result, granules, tiny_fl, DIRECT_GRANULES, GC_gcj_kind,
View file
_service:tar_scm:gc-8.0.6.tar.gz/tools/setjmp_t.c -> _service:tar_scm:gc-8.2.2.tar.gz/tools/setjmp_t.c
Changed
@@ -45,13 +45,8 @@ } return((int)(result0)); } -#elif defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# define NOSERVICE -# include <windows.h> +#elif defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) int getpagesize(void) { SYSTEM_INFO sysinfo; @@ -81,12 +76,18 @@ int g(int x); +#if defined(CPPCHECK) || !defined(__cplusplus) + const char *a_str = "a"; +#else +# define a_str "a" +#endif + int main(void) { volatile word sp; unsigned ps = GETPAGESIZE(); JMP_BUF b; - register int x = (int)strlen("a"); /* 1, slightly disguised */ + register int x = (int)strlen(a_str); /* 1, slightly disguised */ static volatile int y = 0; sp = (word)(&sp);
View file
_service:tar_scm:gc-8.0.6.tar.gz/typd_mlc.c -> _service:tar_scm:gc-8.2.2.tar.gz/typd_mlc.c
Changed
@@ -50,20 +50,12 @@ /* Object kind for objects with complex */ /* descriptors and GC_array_mark_proc. */ -/* Extended descriptors. GC_typed_mark_proc understands these. */ -/* These are used for simple objects that are larger than what */ -/* can be described by a BITMAP_BITS sized bitmap. */ -typedef struct { - word ed_bitmap; /* lsb corresponds to first word. */ - GC_bool ed_continued; /* next entry is continuation. */ -} ext_descr; - /* Array descriptors. GC_array_mark_proc understands these. */ /* We may eventually need to add provisions for headers and */ /* trailers. Hence we provide for tree structured descriptors, */ /* though we don't really use them currently. */ - struct LeafDescriptor { /* Describes simple array */ +struct LeafDescriptor { /* Describes simple array. */ word ld_tag; # define LEAF_TAG 1 size_t ld_size; /* bytes per element */ @@ -71,21 +63,21 @@ size_t ld_nelements; /* Number of elements. */ GC_descr ld_descriptor; /* A simple length, bitmap, */ /* or procedure descriptor. */ - }; +}; - struct ComplexArrayDescriptor { +struct ComplexArrayDescriptor { word ad_tag; # define ARRAY_TAG 2 size_t ad_nelements; union ComplexDescriptor * ad_element_descr; - }; +}; - struct SequenceDescriptor { +struct SequenceDescriptor { word sd_tag; # define SEQUENCE_TAG 3 union ComplexDescriptor * sd_first; union ComplexDescriptor * sd_second; - }; +}; typedef union ComplexDescriptor { struct LeafDescriptor ld; @@ -94,24 +86,11 @@ } complex_descriptor; #define TAG ad.ad_tag -STATIC ext_descr * GC_ext_descriptors = NULL; - /* Points to array of extended */ - /* descriptors. */ - -STATIC size_t GC_ed_size = 0; /* Current size of above arrays. */ #define ED_INITIAL_SIZE 100 -STATIC size_t GC_avail_descr = 0; /* Next available slot. */ - STATIC int GC_typed_mark_proc_index = 0; /* Indices of my mark */ STATIC int GC_array_mark_proc_index = 0; /* procedures. */ -#ifdef AO_HAVE_load_acquire - STATIC volatile AO_t GC_explicit_typing_initialized = FALSE; -#else - STATIC GC_bool GC_explicit_typing_initialized = FALSE; -#endif - STATIC void GC_push_typed_structures_proc(void) { GC_PUSH_ALL_SYM(GC_ext_descriptors); @@ -132,7 +111,7 @@ LOCK(); while (GC_avail_descr + nwords >= GC_ed_size) { - ext_descr * newExtD; + typed_ext_descr_t *newExtD; size_t new_size; word ed_size = GC_ed_size; @@ -146,14 +125,15 @@ new_size = 2 * ed_size; if (new_size > MAX_ENV) return(-1); } - newExtD = (ext_descr *)GC_malloc_atomic(new_size * sizeof(ext_descr)); + newExtD = (typed_ext_descr_t*)GC_malloc_atomic(new_size + * sizeof(typed_ext_descr_t)); if (NULL == newExtD) return -1; LOCK(); if (ed_size == GC_ed_size) { if (GC_avail_descr != 0) { BCOPY(GC_ext_descriptors, newExtD, - GC_avail_descr * sizeof(ext_descr)); + GC_avail_descr * sizeof(typed_ext_descr_t)); } GC_ed_size = new_size; GC_ext_descriptors = newExtD; @@ -188,7 +168,7 @@ { if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { descriptor = GC_bm_tableBYTES_TO_WORDS((word)descriptor); - }; + } descriptor |= (descriptor & ~GC_DS_TAGS) >> nwords; return(descriptor); } @@ -227,7 +207,7 @@ /* of space needed on the mark stack. */ if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) { if (descriptor == (GC_descr)size) { - *simple_d = nelements * descriptor; + *simple_d = nelements * descriptor; /* no overflow */ return(SIMPLE); } else if ((word)descriptor == 0) { *simple_d = (GC_descr)0; @@ -301,6 +281,8 @@ (complex_descriptor *)one_element); break; } + if (EXPECT(NULL == *complex_d, FALSE)) return NO_MEM; + return(COMPLEX); } } @@ -332,8 +314,6 @@ return((complex_descriptor *)result); } -STATIC ptr_t * GC_eobjfreelist = NULL; - STATIC mse * GC_typed_mark_proc(word * addr, mse * mark_stack_ptr, mse * mark_stack_limit, word env); @@ -346,9 +326,7 @@ GC_STATIC_ASSERT(sizeof(struct LeafDescriptor) % sizeof(word) == 0); /* Set up object kind with simple indirect descriptor. */ - GC_eobjfreelist = (ptr_t *)GC_new_free_list_inner(); - GC_explicit_kind = GC_new_kind_inner( - (void **)GC_eobjfreelist, + GC_explicit_kind = GC_new_kind_inner(GC_new_free_list_inner(), (WORDS_TO_BYTES((word)-1) | GC_DS_PER_OBJECT), TRUE, TRUE); /* Descriptors are in the last word of the object. */ @@ -478,6 +456,20 @@ } } +GC_ATTR_NO_SANITIZE_THREAD +static complex_descriptor *get_complex_descr(word *addr, word nwords) +{ + return (complex_descriptor *)addrnwords - 1; +} + +#ifdef AO_HAVE_store_release +# define set_obj_descr(op, nwords, d) \ + AO_store_release((volatile AO_t *)(op) + (nwords) - 1, (AO_t)(d)) +#else +# define set_obj_descr(op, nwords, d) \ + (void)(((word *)(op))(nwords) - 1 = (word)(d)) +#endif + STATIC mse * GC_array_mark_proc(word * addr, mse * mark_stack_ptr, mse * mark_stack_limit, word env GC_ATTR_UNUSED) @@ -485,7 +477,7 @@ hdr * hhdr = HDR(addr); word sz = hhdr -> hb_sz; word nwords = BYTES_TO_WORDS(sz); - complex_descriptor * descr = (complex_descriptor *)(addrnwords-1); + complex_descriptor *descr = get_complex_descr(addr, nwords); mse * orig_mark_stack_ptr = mark_stack_ptr; mse * new_mark_stack_ptr; @@ -528,7 +520,7 @@ GC_API GC_descr GC_CALL GC_make_descriptor(const GC_word * bm, size_t len) { - signed_word last_set_bit = len - 1; + signed_word last_set_bit = (signed_word)len - 1; GC_descr result; DCL_LOCK_STATE; @@ -597,14 +589,15 @@ size_t lg; GC_ASSERT(GC_explicit_typing_initialized); + if (EXPECT(0 == lb, FALSE)) lb = 1; /* ensure nwords > 1 */ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); op = (word *)GC_malloc_kind(lb, GC_explicit_kind); if (EXPECT(NULL == op, FALSE)) return NULL; - /* It is not safe to use GC_size_maplb to compute lg here as the */ + /* It is not safe to use GC_size_maplb to compute lg here as */ /* the former might be updated asynchronously. */ lg = BYTES_TO_GRANULES(GC_size(op)); - opGRANULES_TO_WORDS(lg) - 1 = d; + set_obj_descr(op, GRANULES_TO_WORDS(lg), d); GC_dirty(op + GRANULES_TO_WORDS(lg) - 1); REACHABLE_AFTER_DIRTY(d); return op; @@ -623,12 +616,16 @@ DCL_LOCK_STATE; GC_ASSERT(GC_explicit_typing_initialized); + if (EXPECT(0 == lb, FALSE)) lb = 1; lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); if (SMALL_OBJ(lb)) { + void **opp; + GC_DBG_COLLECT_AT_MALLOC(lb); LOCK(); lg = GC_size_maplb; - op = GC_eobjfreelistlg; + opp = &GC_obj_kindsGC_explicit_kind.ok_freelistlg; + op = (ptr_t)(*opp); if (EXPECT(0 == op, FALSE)) { UNLOCK(); op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_explicit_kind); @@ -636,7 +633,7 @@ /* See the comment in GC_malloc_explicitly_typed. */ lg = BYTES_TO_GRANULES(GC_size(op)); } else { - GC_eobjfreelistlg = (ptr_t)obj_link(op); + *opp = obj_link(op); obj_link(op) = 0; GC_bytes_allocd += GRANULES_TO_BYTES((word)lg); UNLOCK(); @@ -646,8 +643,8 @@ if (NULL == op) return NULL; lg = BYTES_TO_GRANULES(GC_size(op)); } - ((word *)op)GRANULES_TO_WORDS(lg) - 1 = d; - GC_dirty(op + GRANULES_TO_WORDS(lg) - 1); + set_obj_descr(op, GRANULES_TO_WORDS(lg), d); + GC_dirty((word *)op + GRANULES_TO_WORDS(lg) - 1); REACHABLE_AFTER_DIRTY(d); return op; } @@ -661,13 +658,16 @@ complex_descriptor *complex_descr; int descr_type; struct LeafDescriptor leaf; + DCL_LOCK_STATE; GC_ASSERT(GC_explicit_typing_initialized); - descr_type = GC_make_array_descriptor((word)n, (word)lb, d, &simple_descr, - &complex_descr, &leaf); + if (EXPECT(0 == lb || 0 == n, FALSE)) lb = n = 1; if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial check */ - && lb > 0 && n > GC_SIZE_MAX / lb) + && n > GC_SIZE_MAX / lb) return (*GC_get_oom_fn())(GC_SIZE_MAX); /* n*lb overflow */ + + descr_type = GC_make_array_descriptor((word)n, (word)lb, d, &simple_descr, + &complex_descr, &leaf); lb *= n; switch(descr_type) { case NO_MEM: return(0); @@ -687,7 +687,7 @@ lg = BYTES_TO_GRANULES(GC_size(op)); if (descr_type == LEAF) { /* Set up the descriptor inside the object itself. */ - volatile struct LeafDescriptor * lp = + struct LeafDescriptor * lp = (struct LeafDescriptor *) (op + GRANULES_TO_WORDS(lg) - (BYTES_TO_WORDS(sizeof(struct LeafDescriptor)) + 1)); @@ -696,12 +696,25 @@ lp -> ld_size = leaf.ld_size; lp -> ld_nelements = leaf.ld_nelements; lp -> ld_descriptor = leaf.ld_descriptor; - ((volatile word *)op)GRANULES_TO_WORDS(lg) - 1 = (word)lp; + /* Hold the allocation lock while writing the descriptor word */ + /* to the object to ensure that the descriptor contents are */ + /* seen by GC_array_mark_proc as expected. */ + /* TODO: It should be possible to replace locking with the */ + /* atomic operations (with the release barrier here) but, in */ + /* this case, avoiding the acquire barrier in */ + /* GC_array_mark_proc seems to be tricky as GC_mark_some might */ + /* be invoked with the world running. */ + LOCK(); + opGRANULES_TO_WORDS(lg) - 1 = (word)lp; + UNLOCK(); } else { # ifndef GC_NO_FINALIZATION size_t lw = GRANULES_TO_WORDS(lg); + LOCK(); oplw - 1 = (word)complex_descr; + UNLOCK(); + GC_dirty(op + lw - 1); REACHABLE_AFTER_DIRTY(complex_descr);
View file
_service:tar_scm:gc-8.0.6.tar.gz/win32_threads.c -> _service:tar_scm:gc-8.2.2.tar.gz/win32_threads.c
Changed
@@ -4,6 +4,7 @@ * Copyright (c) 1998 by Fergus Henderson. All rights reserved. * Copyright (c) 2000-2008 by Hewlett-Packard Development Company. * All rights reserved. + * Copyright (c) 2008-2021 Ivan Maidanski * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. @@ -19,12 +20,6 @@ #if defined(GC_WIN32_THREADS) -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -#endif -#define NOSERVICE -#include <windows.h> - #ifdef THREAD_LOCAL_ALLOC # include "private/thread_local_alloc.h" #endif /* THREAD_LOCAL_ALLOC */ @@ -96,7 +91,7 @@ /* DllMain-based thread registration is currently incompatible */ /* with thread-local allocation, pthreads and WinCE. */ -#if (defined(GC_DLL) || defined(GC_INSIDE_DLL)) \ +#if (defined(GC_DLL) || defined(GC_INSIDE_DLL)) && !defined(NO_CRT) \ && !defined(GC_NO_THREADS_DISCOVERY) && !defined(MSWINCE) \ && !defined(THREAD_LOCAL_ALLOC) && !defined(GC_PTHREADS) @@ -186,8 +181,6 @@ # endif } -STATIC DWORD GC_main_thread = 0; - #define ADDR_LIMIT ((ptr_t)GC_WORD_MAX) struct GC_Thread_Rep { @@ -236,6 +229,11 @@ # ifdef IA64 ptr_t backing_store_end; ptr_t backing_store_ptr; +# elif defined(I386) + ptr_t initial_stack_base; + /* The cold end of the stack saved by */ + /* GC_record_stack_base (never modified */ + /* by GC_set_stackbottom). */ # endif ptr_t thread_blocked_sp; /* Protected by GC lock. */ @@ -251,12 +249,14 @@ /* GC_call_with_gc_active() of this */ /* thread. May be NULL. */ - unsigned short finalizer_skipped; - unsigned char finalizer_nested; +# ifndef GC_NO_FINALIZATION + unsigned short finalizer_skipped; + unsigned char finalizer_nested; /* Used by GC_check_finalizer_nested() */ /* to minimize the level of recursion */ /* when a client finalizer allocates */ /* memory (initially both are 0). */ +# endif unsigned char suspended; /* really of GC_bool type */ @@ -288,23 +288,20 @@ typedef volatile struct GC_Thread_Rep * GC_vthread; #ifndef GC_NO_THREADS_DISCOVERY + STATIC DWORD GC_main_thread = 0; + + /* We track thread attachments while the world is supposed to be */ + /* stopped. Unfortunately, we cannot stop them from starting, since */ + /* blocking in DllMain seems to cause the world to deadlock. Thus, */ + /* we have to recover if we notice this in the middle of marking. */ + STATIC volatile AO_t GC_attached_thread = FALSE; + /* We assumed that volatile ==> memory ordering, at least among */ /* volatiles. This code should consistently use atomic_ops. */ STATIC volatile GC_bool GC_please_stop = FALSE; #elif defined(GC_ASSERTIONS) STATIC GC_bool GC_please_stop = FALSE; -#endif - -/* - * We track thread attachments while the world is supposed to be stopped. - * Unfortunately, we can't stop them from starting, since blocking in - * DllMain seems to cause the world to deadlock. Thus we have to recover - * If we notice this in the middle of marking. - */ - -#ifndef GC_NO_THREADS_DISCOVERY - STATIC volatile AO_t GC_attached_thread = FALSE; -#endif +#endif /* GC_NO_THREADS_DISCOVERY && GC_ASSERTIONS */ #if defined(WRAP_MARK_SOME) && !defined(GC_PTHREADS) /* Return TRUE if an thread was attached since we last asked or */ @@ -407,6 +404,8 @@ me -> stack_base = (ptr_t)sb->mem_base; # ifdef IA64 me -> backing_store_end = (ptr_t)sb->reg_base; +# elif defined(I386) + me -> initial_stack_base = (ptr_t)sb->mem_base; # endif if (me -> stack_base == NULL) ABORT("Bad stack base in GC_register_my_thread"); @@ -580,37 +579,36 @@ # define CHECK_LOOKUP_MY_THREAD(me) /* empty */ #endif -/* Called by GC_finalize() (in case of an allocation failure observed). */ -/* GC_reset_finalizer_nested() is the same as in pthread_support.c. */ -GC_INNER void GC_reset_finalizer_nested(void) -{ - GC_thread me = GC_lookup_thread_inner(GetCurrentThreadId()); - CHECK_LOOKUP_MY_THREAD(me); - me->finalizer_nested = 0; -} +#ifndef GC_NO_FINALIZATION + /* Called by GC_finalize() (in case of an allocation failure observed). */ + /* GC_reset_finalizer_nested() is the same as in pthread_support.c. */ + GC_INNER void GC_reset_finalizer_nested(void) + { + GC_thread me = GC_lookup_thread_inner(GetCurrentThreadId()); -/* Checks and updates the thread-local level of finalizers recursion. */ -/* Returns NULL if GC_invoke_finalizers() should not be called by the */ -/* collector (to minimize the risk of a deep finalizers recursion), */ -/* otherwise returns a pointer to the thread-local finalizer_nested. */ -/* Called by GC_notify_or_invoke_finalizers() only (the lock is held). */ -/* GC_check_finalizer_nested() is the same as in pthread_support.c. */ -GC_INNER unsigned char *GC_check_finalizer_nested(void) -{ - GC_thread me = GC_lookup_thread_inner(GetCurrentThreadId()); - unsigned nesting_level; - CHECK_LOOKUP_MY_THREAD(me); - nesting_level = me->finalizer_nested; - if (nesting_level) { - /* We are inside another GC_invoke_finalizers(). */ - /* Skip some implicitly-called GC_invoke_finalizers() */ - /* depending on the nesting (recursion) level. */ - if (++me->finalizer_skipped < (1U << nesting_level)) return NULL; - me->finalizer_skipped = 0; + CHECK_LOOKUP_MY_THREAD(me); + me->finalizer_nested = 0; } - me->finalizer_nested = (unsigned char)(nesting_level + 1); - return &me->finalizer_nested; -} + + /* GC_check_finalizer_nested() is the same as in pthread_support.c. */ + GC_INNER unsigned char *GC_check_finalizer_nested(void) + { + GC_thread me = GC_lookup_thread_inner(GetCurrentThreadId()); + unsigned nesting_level; + + CHECK_LOOKUP_MY_THREAD(me); + nesting_level = me->finalizer_nested; + if (nesting_level) { + /* We are inside another GC_invoke_finalizers(). */ + /* Skip some implicitly-called GC_invoke_finalizers() */ + /* depending on the nesting (recursion) level. */ + if (++me->finalizer_skipped < (1U << nesting_level)) return NULL; + me->finalizer_skipped = 0; + } + me->finalizer_nested = (unsigned char)(nesting_level + 1); + return &me->finalizer_nested; + } +#endif /* !GC_NO_FINALIZATION */ #if defined(GC_ASSERTIONS) && defined(THREAD_LOCAL_ALLOC) /* This is called from thread-local GC_malloc(). */ @@ -739,7 +737,7 @@ GC_vthread t = GC_lookup_thread_inner(id); if (0 == t) { - WARN("Removing nonexistent thread, id = %" WARN_PRIdPTR "\n", id); + WARN("Removing nonexistent thread, id= %" WARN_PRIdPTR "\n", id); } else { GC_delete_gc_thread_no_free(t); } @@ -771,13 +769,20 @@ GC_API void GC_CALL GC_allow_register_threads(void) { - /* Check GC is initialized and the current thread is registered. */ - GC_ASSERT(GC_lookup_thread_inner(GetCurrentThreadId()) != 0); +# ifdef GC_ASSERTIONS + DCL_LOCK_STATE; + + /* Check GC is initialized and the current thread is registered. */ + LOCK(); + GC_ASSERT(GC_lookup_thread_inner(GetCurrentThreadId()) != 0); + UNLOCK(); +# endif # if !defined(GC_ALWAYS_MULTITHREADED) && !defined(PARALLEL_MARK) \ && !defined(GC_NO_THREADS_DISCOVERY) /* GC_init() does not call GC_init_parallel() in this case. */ parallel_initialized = TRUE; # endif + GC_start_mark_threads(); set_need_to_lock(); } @@ -796,6 +801,9 @@ if (me == 0) { # ifdef GC_PTHREADS me = GC_register_my_thread_inner(sb, thread_id); +# if defined(CPPCHECK) + GC_noop1(me->flags); +# endif me -> flags |= DETACHED; /* Treat as detached, since we do not need to worry about */ /* pointer results. */ @@ -822,6 +830,9 @@ } } +#ifdef GC_DISABLE_INCREMENTAL +# define GC_wait_for_gc_completion(wait_for_all) (void)(wait_for_all) +#else /* Similar to that in pthread_support.c. */ STATIC void GC_wait_for_gc_completion(GC_bool wait_for_all) { @@ -845,6 +856,7 @@ && (wait_for_all || old_gc_no == GC_gc_no)); } } +#endif /* !GC_DISABLE_INCREMENTAL */ GC_API int GC_CALL GC_unregister_my_thread(void) { @@ -944,11 +956,15 @@ LOCK(); /* This will block if the world is stopped. */ me = GC_lookup_thread_inner(thread_id); CHECK_LOOKUP_MY_THREAD(me); - /* Adjust our stack base value (this could happen unless */ + /* Adjust our stack bottom pointer (this could happen unless */ /* GC_get_stack_base() was used which returned GC_SUCCESS). */ GC_ASSERT(me -> stack_base != NULL); - if ((word)me->stack_base < (word)(&stacksect)) + if ((word)me->stack_base < (word)(&stacksect)) { me -> stack_base = (ptr_t)(&stacksect); +# if defined(I386) + me -> initial_stack_base = me -> stack_base; +# endif + } if (me -> thread_blocked_sp == NULL) { /* We are not inside GC_do_blocking() - do nothing more. */ @@ -992,6 +1008,53 @@ return client_data; /* result */ } +GC_API void GC_CALL GC_set_stackbottom(void *gc_thread_handle, + const struct GC_stack_base *sb) +{ + GC_thread t = (GC_thread)gc_thread_handle; + + GC_ASSERT(sb -> mem_base != NULL); + if (!EXPECT(GC_is_initialized, TRUE)) { + GC_ASSERT(NULL == t); + GC_stackbottom = (char *)sb->mem_base; +# ifdef IA64 + GC_register_stackbottom = (ptr_t)sb->reg_base; +# endif + return; + } + + GC_ASSERT(I_HOLD_LOCK()); + if (NULL == t) { /* current thread? */ + t = GC_lookup_thread_inner(GetCurrentThreadId()); + CHECK_LOOKUP_MY_THREAD(t); + } + GC_ASSERT(!KNOWN_FINISHED(t)); + GC_ASSERT(NULL == t -> thread_blocked_sp + && NULL == t -> traced_stack_sect); /* for now */ + t -> stack_base = (ptr_t)sb->mem_base; + t -> last_stack_min = ADDR_LIMIT; /* reset the known minimum */ +# ifdef IA64 + t -> backing_store_end = (ptr_t)sb->reg_base; +# endif +} + +GC_API void * GC_CALL GC_get_my_stackbottom(struct GC_stack_base *sb) +{ + DWORD thread_id = GetCurrentThreadId(); + GC_thread me; + DCL_LOCK_STATE; + + LOCK(); + me = GC_lookup_thread_inner(thread_id); + CHECK_LOOKUP_MY_THREAD(me); /* the thread is assumed to be registered */ + sb -> mem_base = me -> stack_base; +# ifdef IA64 + sb -> reg_base = me -> backing_store_end; +# endif + UNLOCK(); + return (void *)me; /* gc_thread_handle */ +} + #ifdef GC_PTHREADS /* A quick-and-dirty cache of the mapping between pthread_t */ @@ -1192,7 +1255,7 @@ /* else */ { GC_PUSH_ALL_SYM(GC_threads); } -# if defined(THREAD_LOCAL_ALLOC) +# if defined(THREAD_LOCAL_ALLOC) && defined(USE_CUSTOM_SPECIFIC) GC_PUSH_ALL_SYM(GC_thread_key); /* Just in case we ever use our own TLS implementation. */ # endif @@ -1218,12 +1281,15 @@ { # ifndef MSWINCE DWORD exitCode; -# endif -# ifdef RETRY_GET_THREAD_CONTEXT - int retry_cnt = 0; -# define MAX_SUSPEND_THREAD_RETRIES (1000 * 1000) +# ifdef RETRY_GET_THREAD_CONTEXT + int retry_cnt; +# define MAX_SUSPEND_THREAD_RETRIES (1000 * 1000) +# endif # endif +# ifdef DEBUG_THREADS + GC_log_printf("Suspending 0x%x\n", (int)t->id); +# endif UNPROTECT_THREAD(t); GC_acquire_dirty_lock(); @@ -1235,7 +1301,7 @@ GC_acquire_dirty_lock(); } # elif defined(RETRY_GET_THREAD_CONTEXT) - for (;;) { + for (retry_cnt = 0;;) { /* Apparently the Windows 95 GetOpenFileName call creates */ /* a thread that does not properly get cleaned up, and */ /* SuspendThread on its descriptor may provoke a crash. */ @@ -1299,7 +1365,8 @@ GC_on_thread_event(GC_EVENT_THREAD_SUSPENDED, THREAD_HANDLE(t)); } -#if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE)) +#if defined(GC_ASSERTIONS) \ + && ((defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE)) GC_INNER GC_bool GC_write_disabled = FALSE; /* TRUE only if GC_stop_world() acquired GC_write_cs. */ #endif @@ -1324,18 +1391,16 @@ # if !defined(GC_NO_THREADS_DISCOVERY) || defined(GC_ASSERTIONS) GC_please_stop = TRUE; # endif -# ifndef CYGWIN32 -# ifndef MSWIN_XBOX1 - GC_ASSERT(!GC_write_disabled); -# endif +# if (defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE) + GC_ASSERT(!GC_write_disabled); EnterCriticalSection(&GC_write_cs); -# endif -# if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE)) /* It's not allowed to call GC_printf() (and friends) here down to */ /* LeaveCriticalSection (same applies recursively to GC_suspend, */ /* GC_delete_gc_thread_no_free, GC_get_max_thread_index, GC_size */ /* and GC_remove_protection). */ - GC_write_disabled = TRUE; +# ifdef GC_ASSERTIONS + GC_write_disabled = TRUE; +# endif # endif # ifndef GC_NO_THREADS_DISCOVERY if (GC_win32_dll_threads) { @@ -1368,10 +1433,10 @@ } } } -# if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE)) - GC_write_disabled = FALSE; -# endif -# ifndef CYGWIN32 +# if (defined(MSWIN32) && !defined(CONSOLE_LOG)) || defined(MSWINCE) +# ifdef GC_ASSERTIONS + GC_write_disabled = FALSE; +# endif LeaveCriticalSection(&GC_write_cs); # endif # ifdef PARALLEL_MARK @@ -1394,6 +1459,9 @@ for (i = 0; i <= my_max; i++) { GC_thread t = (GC_thread)(dll_thread_table + i); if (t -> suspended) { +# ifdef DEBUG_THREADS + GC_log_printf("Resuming 0x%x\n", (int)t->id); +# endif GC_ASSERT(t -> stack_base != 0 && t -> id != thread_id); if (ResumeThread(THREAD_HANDLE(t)) == (DWORD)-1) ABORT("ResumeThread failed"); @@ -1401,6 +1469,7 @@ if (GC_on_thread_event) GC_on_thread_event(GC_EVENT_THREAD_UNSUSPENDED, THREAD_HANDLE(t)); } + /* Else thread is unregistered or not suspended. */ } } else { GC_thread t; @@ -1409,6 +1478,9 @@ for (i = 0; i < THREAD_TABLE_SZ; i++) { for (t = GC_threadsi; t != 0; t = t -> tm.next) { if (t -> suspended) { +# ifdef DEBUG_THREADS + GC_log_printf("Resuming 0x%x\n", (int)t->id); +# endif GC_ASSERT(t -> stack_base != 0 && t -> id != thread_id); if (ResumeThread(THREAD_HANDLE(t)) == (DWORD)-1) ABORT("ResumeThread failed"); @@ -1416,6 +1488,11 @@ t -> suspended = FALSE; if (GC_on_thread_event) GC_on_thread_event(GC_EVENT_THREAD_UNSUSPENDED, THREAD_HANDLE(t)); + } else { +# ifdef DEBUG_THREADS + GC_log_printf("Not resuming thread 0x%x as it is not suspended\n", + (int)t->id); +# endif } } } @@ -1554,7 +1631,6 @@ sp = GC_approx_sp(); } else if ((sp = thread -> thread_blocked_sp) == NULL) { /* Use saved sp value for blocked threads. */ - int i = 0; # ifdef RETRY_GET_THREAD_CONTEXT /* We cache context when suspending the thread since it may */ /* require looping. */ @@ -1588,14 +1664,16 @@ # endif } } - -# ifdef WOW64_THREAD_CONTEXT_WORKAROUND - i += 2; /* skip ContextFlags and SegFs */ +# ifdef THREAD_LOCAL_ALLOC + GC_ASSERT(thread->suspended || !GC_world_stopped); # endif - for (; i < PUSHED_REGS_COUNT; i++) - GC_push_one(regsi); -# ifdef WOW64_THREAD_CONTEXT_WORKAROUND +# ifndef WOW64_THREAD_CONTEXT_WORKAROUND + GC_push_many_regs(regs, PUSHED_REGS_COUNT); +# else + GC_push_many_regs(regs + 2, PUSHED_REGS_COUNT - 2); + /* skip ContextFlags and SegFs */ + /* WoW64 workaround. */ if (isWow64) { DWORD ContextFlags = (DWORD)regs0; @@ -1618,13 +1696,25 @@ # endif GC_ASSERT(!((word)thread->stack_base COOLER_THAN (word)tib->StackBase)); - + if (thread->stack_base != thread->initial_stack_base + /* We are in a coroutine. */ + && ((word)thread->stack_base <= (word)tib->StackLimit + || (word)tib->StackBase < (word)thread->stack_base)) { + /* The coroutine stack is not within TIB stack. */ + WARN("GetThreadContext might return stale register values" + " including ESP= %p\n", sp); + /* TODO: Because of WoW64 bug, there is no guarantee that */ + /* sp really points to the stack top but, for now, we do */ + /* our best as the TIB stack limit/base cannot be used */ + /* while we are inside a coroutine. */ + } else { /* GetThreadContext() might return stale register values, */ /* so we scan the entire stack region (down to the stack */ /* limit). There is no 100% guarantee that all the */ /* registers are pushed but we do our best (the proper */ /* solution would be to fix it inside Windows OS). */ sp = (ptr_t)tib->StackLimit; + } } /* else */ # ifdef DEBUG_THREADS else { @@ -1924,6 +2014,56 @@ /* only a few entries). */ # endif +# if defined(GC_PTHREADS) && defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) + static void set_marker_thread_name(unsigned id) + { + /* This code is the same as in pthread_support.c. */ + char name_buf16; /* pthread_setname_np may fail for longer names */ + int len = sizeof("GC-marker-") - 1; + + /* Compose the name manually as snprintf may be unavailable or */ + /* "%u directive output may be truncated" warning may occur. */ + BCOPY("GC-marker-", name_buf, len); + if (id >= 10) + name_buflen++ = (char)('0' + (id / 10) % 10); + name_buflen = (char)('0' + id % 10); + name_buflen + 1 = '\0'; + + if (pthread_setname_np(pthread_self(), name_buf) != 0) + WARN("pthread_setname_np failed\n", 0); + } + +# elif !defined(MSWINCE) + /* A pointer to SetThreadDescription() which is available since */ + /* Windows 10. The function prototype is in processthreadsapi.h. */ + static FARPROC setThreadDescription_fn; + + static void set_marker_thread_name(unsigned id) + { + WCHAR name_buf16; + int len = sizeof(L"GC-marker-") / sizeof(WCHAR) - 1; + HRESULT hr; + + if (!setThreadDescription_fn) return; /* missing SetThreadDescription */ + + /* Compose the name manually as swprintf may be unavailable. */ + BCOPY(L"GC-marker-", name_buf, len * sizeof(WCHAR)); + if (id >= 10) + name_buflen++ = (WCHAR)('0' + (id / 10) % 10); + name_buflen = (WCHAR)('0' + id % 10); + name_buflen + 1 = 0; + + /* Invoke SetThreadDescription(). Cast the function pointer to word */ + /* first to avoid "incompatible function types" compiler warning. */ + hr = (*(HRESULT (WINAPI *)(HANDLE, const WCHAR *)) + (word)setThreadDescription_fn)(GetCurrentThread(), name_buf); + if (FAILED(hr)) + WARN("SetThreadDescription failed\n", 0); + } +# else +# define set_marker_thread_name(id) (void)(id) +# endif + /* GC_mark_thread() is the same as in pthread_support.c */ # ifdef GC_PTHREADS_PARAMARK STATIC void * GC_mark_thread(void * id) @@ -1936,6 +2076,7 @@ word my_mark_no = 0; if ((word)id == GC_WORD_MAX) return 0; /* to prevent a compiler warning */ + set_marker_thread_name((unsigned)(word)id); marker_sp(word)id = GC_approx_sp(); # ifdef IA64 marker_bsp(word)id = GC_save_regs_in_stack(); @@ -1970,11 +2111,7 @@ /* GC_mark_threads is unused here unlike that in pthread_support.c */ -# ifdef CAN_HANDLE_FORK - static int available_markers_m1 = 0; -# else -# define available_markers_m1 GC_markers_m1 -# endif + static int available_markers_m1 = 0; # ifdef GC_PTHREADS_PARAMARK # include <pthread.h> @@ -2003,12 +2140,13 @@ sigset_t set, oldset; # endif - GC_ASSERT(I_DONT_HOLD_LOCK()); - if (available_markers_m1 <= 0) return; + GC_ASSERT(I_HOLD_LOCK()); + ASSERT_CANCEL_DISABLED(); + if (available_markers_m1 <= 0 || GC_parallel) return; /* Skip if parallel markers disabled or already started. */ -# ifdef CAN_HANDLE_FORK - if (GC_parallel) return; + GC_wait_for_gc_completion(TRUE); +# ifdef CAN_HANDLE_FORK /* Reset mark_cv state after forking (as in pthread_support.c). */ { pthread_cond_t mark_cv_local = PTHREAD_COND_INITIALIZER; @@ -2028,17 +2166,16 @@ ABORT("sigfillset failed"); if (pthread_sigmask(SIG_BLOCK, &set, &oldset) < 0) { WARN("pthread_sigmask set failed, no markers started," - " errno = %" WARN_PRIdPTR "\n", errno); + " errno= %" WARN_PRIdPTR "\n", errno); GC_markers_m1 = 0; (void)pthread_attr_destroy(&attr); return; } # endif /* !NO_MARKER_SPECIAL_SIGMASK */ -# ifdef CAN_HANDLE_FORK - /* To have proper GC_parallel value in GC_help_marker. */ - GC_markers_m1 = available_markers_m1; -# endif + /* To have proper GC_parallel value in GC_help_marker. */ + GC_markers_m1 = available_markers_m1; + for (i = 0; i < available_markers_m1; ++i) { marker_last_stack_mini = ADDR_LIMIT; if (0 != pthread_create(&new_thread, &attr, @@ -2053,7 +2190,7 @@ # ifndef NO_MARKER_SPECIAL_SIGMASK /* Restore previous signal mask. */ if (pthread_sigmask(SIG_SETMASK, &oldset, NULL) < 0) { - WARN("pthread_sigmask restore failed, errno = %" WARN_PRIdPTR "\n", + WARN("pthread_sigmask restore failed, errno= %" WARN_PRIdPTR "\n", errno); } # endif @@ -2089,7 +2226,7 @@ GC_INNER void GC_acquire_mark_lock(void) { -# if defined(NUMERIC_THREAD_ID_UNIQUE) && !defined(THREAD_SANITIZER) +# ifdef NUMERIC_THREAD_ID_UNIQUE GC_ASSERT(GC_mark_lock_holder != NUMERIC_THREAD_ID(pthread_self())); # endif if (pthread_mutex_lock(&mark_mutex) != 0) { @@ -2176,12 +2313,15 @@ { int i; - GC_ASSERT(I_DONT_HOLD_LOCK()); - if (available_markers_m1 <= 0) return; + GC_ASSERT(I_HOLD_LOCK()); + ASSERT_CANCEL_DISABLED(); + if (available_markers_m1 <= 0 || GC_parallel) return; + GC_wait_for_gc_completion(TRUE); GC_ASSERT(GC_fl_builder_count == 0); /* Initialize GC_marker_cv fully before starting the */ /* first helper thread. */ + GC_markers_m1 = available_markers_m1; for (i = 0; i < GC_markers_m1; ++i) { if ((GC_marker_cvi = CreateEvent(NULL /* attrs */, TRUE /* isManualReset */, @@ -2267,9 +2407,7 @@ GC_INNER void GC_acquire_mark_lock(void) { -# ifndef THREAD_SANITIZER - GC_ASSERT(GC_mark_lock_holder != GetCurrentThreadId()); -# endif + GC_ASSERT(GC_mark_lock_holder != GetCurrentThreadId()); if (InterlockedExchange(&GC_mark_mutex_state, 1 /* locked */) != 0) { # ifdef LOCK_STATS (void)AO_fetch_and_add1(&GC_block_count); @@ -2371,7 +2509,17 @@ # endif /* ! GC_PTHREADS_PARAMARK */ -#endif /* PARALLEL_MARK */ + static unsigned required_markers_cnt = 0; + /* The default value (0) means the number of */ + /* markers should be selected automatically. */ + +# define START_MARK_THREADS() \ + if (EXPECT(GC_parallel || available_markers_m1 <= 0, TRUE)) {} \ + else GC_start_mark_threads() +#else + +# define START_MARK_THREADS() (void)0 +#endif /* !PARALLEL_MARK */ /* We have no DllMain to take care of new threads. Thus we */ /* must properly intercept thread creation. */ @@ -2399,14 +2547,14 @@ /* Clear the thread entry even if we exit with an exception. */ /* This is probably pointless, since an uncaught exception is */ /* supposed to result in the process being killed. */ -# ifndef __GNUC__ +# if !defined(__GNUC__) && !defined(NO_CRT) ret = NULL; /* to suppress "might be uninitialized" compiler warning */ __try # endif { ret = (void *)(word)(*start)(param); } -# ifndef __GNUC__ +# if !defined(__GNUC__) && !defined(NO_CRT) __finally # endif { @@ -2461,6 +2609,7 @@ GC_dirty(args); REACHABLE_AFTER_DIRTY(lpParameter); + START_MARK_THREADS(); set_need_to_lock(); thread_h = CreateThread(lpThreadAttributes, dwStackSize, GC_win32_start, args, dwCreationFlags, lpThreadId); @@ -2475,7 +2624,8 @@ ExitThread(dwExitCode); } -# if !defined(CYGWIN32) && !defined(MSWINCE) && !defined(MSWIN_XBOX1) +# if !defined(CYGWIN32) && !defined(MSWINCE) && !defined(MSWIN_XBOX1) \ + && !defined(NO_CRT) GC_API GC_uintptr_t GC_CALL GC_beginthreadex( void *security, unsigned stack_size, unsigned (__stdcall *start_address)(void *), @@ -2515,6 +2665,7 @@ GC_dirty(args); REACHABLE_AFTER_DIRTY(arglist); + START_MARK_THREADS(); set_need_to_lock(); thread_h = _beginthreadex(security, stack_size, (unsigned (__stdcall *)(void *))GC_win32_start, @@ -2529,7 +2680,7 @@ GC_unregister_my_thread(); _endthreadex(retval); } -# endif /* !CYGWIN32 && !MSWINCE && !MSWIN_XBOX1 */ +# endif /* !CYGWIN32 && !MSWINCE && !MSWIN_XBOX1 && !NO_CRT */ #ifdef GC_WINMAIN_REDIRECT /* This might be useful on WinCE. Shouldn't be used with GC_DLL. */ @@ -2607,15 +2758,41 @@ #endif /* GC_WINMAIN_REDIRECT */ +GC_API void GC_CALL GC_set_markers_count(unsigned markers GC_ATTR_UNUSED) +{ + /* The same implementation as in pthread_support.c. */ +# ifdef PARALLEL_MARK + required_markers_cnt = markers < MAX_MARKERS ? markers : MAX_MARKERS; +# endif +} + GC_INNER void GC_thr_init(void) { struct GC_stack_base sb; +# if (!defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) && !defined(MSWINCE) \ + && defined(PARALLEL_MARK)) || defined(WOW64_THREAD_CONTEXT_WORKAROUND) + HMODULE hK32; +# ifdef MSWINRT_FLAVOR + MEMORY_BASIC_INFORMATION memInfo; + + if (VirtualQuery((void*)(word)GetProcAddress, &memInfo, sizeof(memInfo)) + != sizeof(memInfo)) + ABORT("Weird VirtualQuery result"); + hK32 = (HMODULE)memInfo.AllocationBase; +# else + hK32 = GetModuleHandle(TEXT("kernel32.dll")); +# endif +# endif GC_ASSERT(I_HOLD_LOCK()); if (GC_thr_initialized) return; GC_ASSERT((word)&GC_threads % sizeof(word) == 0); - GC_main_thread = GetCurrentThreadId(); +# ifdef GC_NO_THREADS_DISCOVERY +# define GC_main_thread GetCurrentThreadId() +# else + GC_main_thread = GetCurrentThreadId(); +# endif GC_thr_initialized = TRUE; # ifdef CAN_HANDLE_FORK @@ -2635,8 +2812,6 @@ # ifdef WOW64_THREAD_CONTEXT_WORKAROUND /* Set isWow64 flag. */ - { - HMODULE hK32 = GetModuleHandle(TEXT("kernel32.dll")); if (hK32) { FARPROC pfn = GetProcAddress(hK32, "IsWow64Process"); if (pfn @@ -2644,7 +2819,6 @@ GetCurrentProcess(), &isWow64)) isWow64 = FALSE; /* IsWow64Process failed */ } - } # endif /* Add the initial thread, so we can stop it. */ @@ -2657,7 +2831,7 @@ # if defined(PARALLEL_MARK) { char * markers_string = GETENV("GC_MARKERS"); - int markers; + int markers = required_markers_cnt; if (markers_string != NULL) { markers = atoi(markers_string); @@ -2666,7 +2840,10 @@ "; using maximum threads\n", (signed_word)markers); markers = MAX_MARKERS; } - } else { + } else if (0 == markers) { + /* Unless the client sets the desired number of */ + /* parallel markers, it is determined based on the */ + /* number of CPU cores. */ # ifdef MSWINCE /* There is no GetProcessAffinityMask() in WinCE. */ /* GC_sysinfo is already initialized. */ @@ -2707,7 +2884,6 @@ } /* Check whether parallel mode could be enabled. */ - { if (GC_win32_dll_threads || available_markers_m1 <= 0) { /* Disable parallel marking. */ GC_parallel = FALSE; @@ -2728,14 +2904,17 @@ || mark_cv == (HANDLE)0) ABORT("CreateEvent failed"); # endif - /* Disable true incremental collection, but generational is OK. */ - GC_time_limit = GC_TIME_UNLIMITED; +# if !defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) && !defined(MSWINCE) + if (hK32) + setThreadDescription_fn = GetProcAddress(hK32, + "SetThreadDescription"); +# endif } - } # endif /* PARALLEL_MARK */ GC_ASSERT(0 == GC_lookup_thread_inner(GC_main_thread)); GC_register_my_thread_inner(&sb, GC_main_thread); +# undef GC_main_thread } #ifdef GC_PTHREADS @@ -2832,6 +3011,7 @@ (void *)GC_PTHREAD_PTRVAL(pthread_self()), (long)GetCurrentThreadId()); # endif + START_MARK_THREADS(); set_need_to_lock(); result = pthread_create(new_thread, attr, GC_pthread_start, si); @@ -2983,7 +3163,7 @@ /* Note that GC_use_threads_discovery should be called by the */ /* client application at start-up to activate automatic thread */ - /* registration (it is the default GC behavior since v7.0alpha7); */ + /* registration (it is the default GC behavior); */ /* to always have automatic thread registration turned on, the GC */ /* should be compiled with -D GC_DISCOVER_TASK_THREADS. */ if (!GC_win32_dll_threads && parallel_initialized) return TRUE; @@ -3002,9 +3182,6 @@ /* This may run with the collector uninitialized. */ thread_id = GetCurrentThreadId(); if (parallel_initialized && GC_main_thread != thread_id) { -# ifdef PARALLEL_MARK - ABORT("Cannot initialize parallel marker from DllMain"); -# else struct GC_stack_base sb; /* Don't lock here. */ # ifdef GC_ASSERTIONS @@ -3013,13 +3190,11 @@ GC_get_stack_base(&sb); GC_ASSERT(sb_result == GC_SUCCESS); GC_register_my_thread_inner(&sb, thread_id); -# endif } /* o.w. we already did it during GC_thr_init, called by GC_init */ break; case DLL_THREAD_DETACH: /* We are hopefully running in the context of the exiting thread. */ - GC_ASSERT(parallel_initialized); if (GC_win32_dll_threads) { GC_delete_thread(GetCurrentThreadId()); }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2