diff options
Diffstat (limited to 'gc/include')
28 files changed, 0 insertions, 9173 deletions
| diff --git a/gc/include/cord.h b/gc/include/cord.h deleted file mode 100644 index 926089e..0000000 --- a/gc/include/cord.h +++ /dev/null @@ -1,327 +0,0 @@ -/*  - * 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. - * - * Author: Hans-J. Boehm (boehm@parc.xerox.com) - */ -/* Boehm, October 5, 1995 4:20 pm PDT */ -  -/* - * Cords are immutable character strings.  A number of operations - * on long cords are much more efficient than their strings.h counterpart. - * In particular, concatenation takes constant time independent of the length - * of the arguments.  (Cords are represented as trees, with internal - * nodes representing concatenation and leaves consisting of either C - * strings or a functional description of the string.) - * - * The following are reasonable applications of cords.  They would perform - * unacceptably if C strings were used: - * - A compiler that produces assembly language output by repeatedly - *   concatenating instructions onto a cord representing the output file. - * - 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 echa character change (and keeping the old ones in an - *   edit history) - * - * For optimal performance, cords should be built by - * concatenating short sections. - * This interface is designed for maximum compatibility with C strings. - * ASCII NUL characters may be embedded in cords using CORD_from_fn. - * This is handled correctly, but CORD_to_char_star will produce a string - * with embedded NULs when given such a cord.  - * - * This interface is fairly big, largely for performance reasons. - * The most basic constants and functions: - * - * CORD - the type of a cord; - * CORD_EMPTY - empty cord; - * CORD_len(cord) - length of a cord; - * 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. - */ -# ifndef CORD_H - -# define CORD_H -# include <stddef.h> -# include <stdio.h> -/* Cords have type const char *.  This is cheating quite a bit, and not	*/ -/* 100% portable.  But it means that nonempty character string		*/ -/* constants may be used as cords directly, provided the string is	*/ -/* never modified in place.  The empty cord is represented by, and	*/ -/* can be written as, 0.						*/ - -typedef const char * CORD; - -/* An empty cord is always represented as nil 	*/ -# define CORD_EMPTY 0 - -/* Is a nonempty cord represented as a C string? */ -#define CORD_IS_STRING(s) (*(s) != '\0') - -/* Concatenate two cords.  If the arguments are C strings, they may 	*/ -/* not be subsequently altered.						*/ -CORD CORD_cat(CORD x, CORD y); - -/* Concatenate a cord and a C string with known length.  Except for the	*/ -/* empty string case, this is a special case of CORD_cat.  Since the	*/ -/* length is known, it can be faster.					*/ -/* The string y is shared with the resulting CORD.  Hence it should	*/ -/* not be altered by the caller.					*/ -CORD CORD_cat_char_star(CORD x, const char * y, size_t leny); - -/* Compute the length of a cord */ -size_t CORD_len(CORD x); - -/* 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. 	*/ -CORD CORD_from_fn(CORD_fn fn, void * client_data, size_t len); - -/* Return the substring (subcord really) of x with length at most n,	*/ -/* starting at position i.  (The initial character has position 0.)	*/ -CORD CORD_substr(CORD x, size_t i, size_t n); - -/* Return the argument, but rebalanced to allow more efficient   	*/ -/* character retrieval, substring operations, and comparisons.		*/ -/* This is useful only for cords that were built using repeated 	*/ -/* concatenation.  Guarantees log time access to the result, unless	*/ -/* x was obtained through a large number of repeated substring ops	*/ -/* or the embedded functional descriptions take longer to evaluate.	*/ -/* May reallocate significant parts of the cord.  The argument is not	*/ -/* modified; only the result is balanced.				*/ -CORD CORD_balance(CORD x); - -/* The following traverse a cord by applying a function to each 	*/ -/* character.  This is occasionally appropriate, especially where	*/ -/* speed is crucial.  But, since C doesn't have nested functions,	*/ -/* clients of this sort of traversal are clumsy to write.  Consider	*/ -/* the functions that operate on cord positions instead.		*/ - -/* Function to iteratively apply to individual characters in cord.	*/ -typedef int (* CORD_iter_fn)(char c, void * client_data); - -/* Function to apply to substrings of a cord.  Each substring is a 	*/ -/* a C character string, not a general cord.				*/ -typedef int (* CORD_batched_iter_fn)(const char * s, void * client_data); -# 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	*/ -/* 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	*/ -/* latter case CORD_iter returns != 0.  Otherwise it returns 0.		*/ -/* The specified value of i must be < CORD_len(x).			*/ -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:	*/ -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	*/ -/* CORD_batched_iter_fn.						*/ -int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data); - -/* A simpler version that starts at the end:	*/ -int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data); - -/* Functions that operate on cord positions.  The easy way to traverse	*/ -/* cords.  A cord position is logically a pair consisting of a cord	*/ -/* and an index into that cord.  But it is much faster to retrieve a	*/ -/* charcter based on a position than on an index.  Unfortunately,	*/ -/* 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. */ -# include "private/cord_pos.h" - -/* -	Visible definitions from above: -	 -	typedef <OPAQUE but fairly big> CORD_pos[1]; -	 -	* Extract the cord from a position: -	CORD CORD_pos_to_cord(CORD_pos p); -	 -	* Extract the current index from a position: -	size_t CORD_pos_to_index(CORD_pos p); -	 -	* Fetch the character located at the given position: -	char CORD_pos_fetch(CORD_pos p); -	 -	* Initialize the position to refer to the given cord and index. -	* Note that this is the most expensive function on positions: -	void CORD_set_pos(CORD_pos p, CORD x, size_t i); -	 -	* Advance the position to the next character. -	* P must be initialized and valid. -	* Invalidates p if past end: -	void CORD_next(CORD_pos p); -	 -	* Move the position to the preceding character. -	* P must be initialized and valid. -	* Invalidates p if past beginning: -	void CORD_prev(CORD_pos p); -	 -	* Is the position valid, i.e. inside the cord? -	int CORD_pos_valid(CORD_pos p); -*/ -# define CORD_FOR(pos, cord) \ -    for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos)) - -			 -/* An out of memory handler to call.  May be supplied by client.	*/ -/* Must not return.							*/ -extern void (* CORD_oom_fn)(void); - -/* Dump the representation of x to stdout in an implementation defined	*/ -/* manner.  Intended for debugging only.				*/ -void CORD_dump(CORD x); - -/* The following could easily be implemented by the client.  They are	*/ -/* provided in cordxtra.c for convenience.				*/ - -/* Concatenate a character to the end of a cord.	*/ -CORD CORD_cat_char(CORD x, char c); - -/* Concatenate n cords.	*/ -CORD CORD_catn(int n, /* CORD */ ...); - -/* Return the character in CORD_substr(x, i, 1)  	*/ -char CORD_fetch(CORD x, size_t i); - -/* Return < 0, 0, or > 0, depending on whether x < y, x = y, x > y	*/ -int CORD_cmp(CORD x, CORD y); - -/* A generalization that takes both starting positions for the 		*/ -/* comparison, and a limit on the number of characters to be compared.	*/ -int CORD_ncmp(CORD x, size_t x_start, CORD y, size_t y_start, size_t len); - -/* Find the first occurrence of s in x at position start or later.	*/ -/* Return the position of the first character of s in x, or		*/ -/* CORD_NOT_FOUND if there is none.					*/ -size_t CORD_str(CORD x, size_t start, CORD s); - -/* Return a cord consisting of i copies of (possibly NUL) c.  Dangerous	*/ -/* in conjunction with CORD_to_char_star.				*/ -/* The resulting representation takes constant space, independent of i.	*/ -CORD CORD_chars(char c, size_t i); -# define CORD_nul(i) CORD_chars('\0', (i)) - -/* Turn a file into cord.  The file must be seekable.  Its contents	*/ -/* must remain constant.  The file may be accessed as an immediate	*/ -/* result of this call and/or as a result of subsequent accesses to 	*/ -/* the cord.  Short files are likely to be immediately read, but	*/ -/* long files are likely to be read on demand, possibly relying on 	*/ -/* stdio for buffering.							*/ -/* 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 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.			*/ -CORD CORD_from_file(FILE * f); - -/* Equivalent to the above, except that the entire file will be read	*/ -/* and the file pointer will be closed immediately.			*/ -/* The binary mode restriction from above does not apply.		*/ -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.					*/ -CORD CORD_from_file_lazy(FILE * f); - -/* Turn a cord into a C string.	The result shares no structure with	*/ -/* x, and is thus modifiable.						*/ -char * CORD_to_char_star(CORD x); - -/* Turn a C string into a CORD.  The C string is copied, and so may	*/ -/* subsequently be modified.						*/ -CORD CORD_from_char_star(const char *s); - -/* Identical to the above, but the result may share structure with	*/ -/* the argument and is thus not modifiable.				*/ -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.				*/ -/* Returns EOF if a write error occurs, 1 otherwise.			*/ -int CORD_put(CORD x, FILE * f); - -/* "Not found" result for the following two functions.			*/ -# define CORD_NOT_FOUND ((size_t)(-1)) - -/* 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).			*/ -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		*/ -/* must be < CORD_len(x).						*/ -size_t CORD_rchr(CORD x, size_t i, int c); - - -/* The following are also not primitive, but are implemented in 	*/ -/* cordprnt.c.  They provide functionality similar to the ANSI C	*/ -/* functions with corresponding names, but with the following		*/ -/* additions and changes:						*/ -/* 1. A %r conversion specification specifies a CORD argument.  Field	*/ -/*    width, precision, etc. have the same semantics as for %s.		*/ -/*    (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.						*/ -/* 4. Most of the conversions are implement through the native 		*/ -/*    vsprintf.  Hence they are usually no faster, and 			*/ -/*    idiosyncracies of the native printf are preserved.  However,	*/ -/*    CORD arguments to CORD_sprintf and CORD_vsprintf are NOT copied;	*/ -/*    the result shares the original structure.  This may make them	*/ -/*    very efficient in some unusual applications.			*/ -/*    The format string is copied.					*/ -/* All functions return the number of characters generated or -1 on	*/ -/* error.  This complies with the ANSI standard, but is inconsistent	*/ -/* with some older implementations of sprintf.				*/ - -/* The implementation of these is probably less portable than the rest	*/ -/* of this package.							*/ - -#ifndef CORD_NO_IO - -#include <stdarg.h> - -int CORD_sprintf(CORD * out, CORD format, ...); -int CORD_vsprintf(CORD * out, CORD format, va_list args); -int CORD_fprintf(FILE * f, CORD format, ...); -int CORD_vfprintf(FILE * f, CORD format, va_list args); -int CORD_printf(CORD format, ...); -int CORD_vprintf(CORD format, va_list args); - -#endif /* CORD_NO_IO */ - -# endif /* CORD_H */ diff --git a/gc/include/ec.h b/gc/include/ec.h deleted file mode 100644 index c829b83..0000000 --- a/gc/include/ec.h +++ /dev/null @@ -1,70 +0,0 @@ -# ifndef EC_H -# define EC_H - -# ifndef CORD_H -#  include "cord.h" -# endif - -/* Extensible cords are strings that may be destructively appended to.	*/ -/* They allow fast construction of cords from characters that are	*/ -/* being read from a stream.						*/ -/* - * A client might look like: - * - *	{ - *	    CORD_ec x; - *	    CORD result; - *	    char c; - *	    FILE *f; - * - *	    ... - *	    CORD_ec_init(x); - *	    while(...) { - *		c = getc(f); - *		... - *		CORD_ec_append(x, c); - *	    } - *	    result = CORD_balance(CORD_ec_to_cord(x)); - * - * If a C string is desired as the final result, the call to CORD_balance - * may be replaced by a call to CORD_to_char_star. - */ - -# ifndef CORD_BUFSZ -#   define CORD_BUFSZ 128 -# endif - -typedef struct CORD_ec_struct { -    CORD ec_cord; -    char * ec_bufptr; -    char ec_buf[CORD_BUFSZ+1]; -} CORD_ec[1]; - -/* This structure represents the concatenation of ec_cord with		*/ -/* ec_buf[0 ... (ec_bufptr-ec_buf-1)]					*/ - -/* Flush the buffer part of the extended chord into ec_cord.	*/ -/* Note that this is almost the only real function, and it is	*/ -/* implemented in 6 lines in cordxtra.c				*/ -void CORD_ec_flush_buf(CORD_ec x); -       -/* Convert an extensible cord to a cord. */ -# define CORD_ec_to_cord(x) (CORD_ec_flush_buf(x), (x)[0].ec_cord) - -/* Initialize an extensible cord. */ -# define CORD_ec_init(x) ((x)[0].ec_cord = 0, (x)[0].ec_bufptr = (x)[0].ec_buf) - -/* Append a character to an extensible cord.	*/ -# define CORD_ec_append(x, c) \ -    {  \ -	if ((x)[0].ec_bufptr == (x)[0].ec_buf + CORD_BUFSZ) { \ -	  	CORD_ec_flush_buf(x); \ -	} \ -	*((x)[0].ec_bufptr)++ = (c); \ -    } - -/* Append a cord to an extensible cord.  Structure remains shared with 	*/ -/* original.								*/ -void CORD_ec_append_cord(CORD_ec x, CORD s); - -# endif /* EC_H */ diff --git a/gc/include/gc.h b/gc/include/gc.h deleted file mode 100644 index 6ea7165..0000000 --- a/gc/include/gc.h +++ /dev/null @@ -1,968 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved. - * Copyright 1996-1999 by Silicon Graphics.  All rights reserved. - * Copyright 1999 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. - */ - -/* - * Note that this defines a large number of tuning hooks, which can - * safely be ignored in nearly all cases.  For normal use it suffices - * to call only GC_MALLOC and perhaps GC_REALLOC. - * For better performance, also look at GC_MALLOC_ATOMIC, and - * GC_enable_incremental.  If you need an action to be performed - * immediately before an object is collected, look at GC_register_finalizer. - * If you are using Solaris threads, look at the end of this file. - * Everything else is best ignored unless you encounter performance - * problems. - */ -  -#ifndef _GC_H - -# define _GC_H - -/* - * Some tests for old macros.  These violate our namespace rules and will - * disappear shortly.  Use the GC_ names. - */ -#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) -# define GC_SOLARIS_THREADS -#endif -#if defined(_SOLARIS_PTHREADS) -# define GC_SOLARIS_PTHREADS -#endif -#if defined(IRIX_THREADS) -# define GC_IRIX_THREADS -#endif -#if defined(DGUX_THREADS) -# if !defined(GC_DGUX386_THREADS) -#  define GC_DGUX386_THREADS -# endif -#endif -#if defined(HPUX_THREADS) -# define GC_HPUX_THREADS -#endif -#if defined(OSF1_THREADS) -# define GC_OSF1_THREADS -#endif -#if defined(LINUX_THREADS) -# define GC_LINUX_THREADS -#endif -#if defined(WIN32_THREADS) -# define GC_WIN32_THREADS -#endif -#if defined(USE_LD_WRAP) -# define GC_USE_LD_WRAP -#endif - -#if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \ -		             || defined(GC_SOLARIS_PTHREADS) \ -			     || defined(GC_HPUX_THREADS) \ -			     || defined(GC_LINUX_THREADS)) -# define _REENTRANT -	/* Better late than never.  This fails if system headers that	*/ -	/* depend on this were previously included.			*/ -#endif - -#if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE) -# define _POSIX4A_DRAFT10_SOURCE 1 -#endif - -#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS) -#   define GC_SOLARIS_THREADS -#endif - -# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \ -	defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \ -	defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \ -	defined(GC_DGUX386_THREADS) || \ -        (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__)) -#   define GC_PTHREADS -# endif - -# define __GC -# include <stddef.h> -# ifdef _WIN32_WCE -/* Yet more kluges for WinCE */ -#   include <stdlib.h>		/* size_t is defined here */ -    typedef long ptrdiff_t;	/* ptrdiff_t is not defined */ -# endif - -#if defined(__MINGW32__) && defined(_DLL) && !defined(GC_NOT_DLL) -# ifdef GC_BUILD -#   define GC_API __declspec(dllexport) -# else -#   define GC_API __declspec(dllimport) -# endif -#endif - -#if (defined(__DMC__) || defined(_MSC_VER)) \ -		&& (defined(_DLL) && !defined(GC_NOT_DLL) \ -	            || defined(GC_DLL)) -# ifdef GC_BUILD -#   define GC_API extern __declspec(dllexport) -# else -#   define GC_API __declspec(dllimport) -# endif -#endif - -#if defined(__WATCOMC__) && defined(GC_DLL) -# ifdef GC_BUILD -#   define GC_API extern __declspec(dllexport) -# else -#   define GC_API extern __declspec(dllimport) -# endif -#endif - -#ifndef GC_API -#define GC_API extern -#endif - -# if defined(__STDC__) || defined(__cplusplus) -#   define GC_PROTO(args) args -    typedef void * GC_PTR; -#   define GC_CONST const -# else -#   define GC_PROTO(args) () -    typedef char * GC_PTR; -#   define GC_CONST -#  endif - -# ifdef __cplusplus -    extern "C" { -# endif - - -/* Define word and signed_word to be unsigned and signed types of the 	*/ -/* size as char * or void *.  There seems to be no way to do this	*/ -/* even semi-portably.  The following is probably no better/worse 	*/ -/* than almost anything else.						*/ -/* The ANSI standard suggests that size_t and ptr_diff_t might be 	*/ -/* better choices.  But those appear to have incorrect definitions	*/ -/* on may systems.  Notably "typedef int size_t" seems to be both	*/ -/* frequent and WRONG.							*/ -typedef unsigned long GC_word; -typedef long GC_signed_word; - -/* Public read-only variables */ - -GC_API GC_word GC_gc_no;/* Counter incremented per collection.  	*/ -			/* Includes empty GCs at startup.		*/ - -GC_API int GC_parallel;	/* GC is parallelized for performance on	*/ -			/* multiprocessors.  Currently set only		*/ -			/* implicitly if collector is built with	*/ -			/* -DPARALLEL_MARK and if either:		*/ -			/*  Env variable GC_NPROC is set to > 1, or	*/ -			/*  GC_NPROC is not set and this is an MP.	*/ -			/* If GC_parallel is set, incremental		*/ -			/* collection is only partially functional,	*/ -			/* and may not be desirable.			*/ -			 - -/* Public R/W variables */ - -GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requested)); -			/* When there is insufficient memory to satisfy */ -			/* an allocation request, we return		*/ -			/* (*GC_oom_fn)().  By default this just	*/ -			/* returns 0.					*/ -			/* If it returns, it must return 0 or a valid	*/ -			/* pointer to a previously allocated heap 	*/ -			/* object.					*/ - -GC_API int GC_find_leak; -			/* Do not actually garbage collect, but simply	*/ -			/* report inaccessible memory that was not	*/ -			/* deallocated with GC_free.  Initial value	*/ -			/* is determined by FIND_LEAK macro.		*/ - -GC_API int GC_all_interior_pointers; -			/* Arrange for pointers to object interiors to	*/ -			/* be recognized as valid.  May not be changed	*/ -			/* after GC initialization.			*/ -			/* Initial value is determined by 		*/ -			/* -DALL_INTERIOR_POINTERS.			*/ -			/* Unless DONT_ADD_BYTE_AT_END is defined, this	*/ -			/* also affects whether sizes are increased by	*/ -			/* at least a byte to allow "off the end"	*/ -			/* pointer recognition.				*/ -			/* MUST BE 0 or 1.				*/ - -GC_API int GC_quiet;	/* Disable statistics output.  Only matters if	*/ -			/* collector has been compiled with statistics	*/ -			/* enabled.  This involves a performance cost,	*/ -			/* and is thus not the default.			*/ - -GC_API int GC_finalize_on_demand; -			/* If nonzero, finalizers will only be run in 	*/ -			/* response to an explicit GC_invoke_finalizers	*/ -			/* call.  The default is determined by whether	*/ -			/* the FINALIZE_ON_DEMAND macro is defined	*/ -			/* when the collector is built.			*/ - -GC_API int GC_java_finalization; -			/* Mark objects reachable from finalizable 	*/ -			/* objects in a separate postpass.  This makes	*/ -			/* it a bit safer to use non-topologically-	*/ -			/* ordered finalization.  Default value is	*/ -			/* determined by JAVA_FINALIZATION macro.	*/ - -GC_API void (* GC_finalizer_notifier)(); -			/* Invoked by the collector when there are 	*/ -			/* objects to be finalized.  Invoked at most	*/ -			/* once per GC cycle.  Never invoked unless 	*/ -			/* GC_finalize_on_demand is set.		*/ -			/* Typically this will notify a finalization	*/ -			/* thread, which will call GC_invoke_finalizers */ -			/* in response.					*/ - -GC_API int GC_dont_gc;	/* Dont collect unless explicitly requested, e.g. */ -			/* because it's not safe.			  */ - -GC_API int GC_dont_expand; -			/* Dont expand heap unless explicitly requested */ -			/* or forced to.				*/ - -GC_API int GC_use_entire_heap; -		/* Causes the nonincremental collector to use the	*/ -		/* entire heap before collecting.  This was the only 	*/ -		/* option for GC versions < 5.0.  This sometimes	*/ -		/* results in more large block fragmentation, since	*/ -		/* very larg blocks will tend to get broken up		*/ -		/* during each GC cycle.  It is likely to result in a	*/ -		/* larger working set, but lower collection		*/ -		/* frequencies, and hence fewer instructions executed	*/ -		/* in the collector.					*/ - -GC_API int GC_full_freq;    /* Number of partial collections between	*/ -			    /* full collections.  Matters only if	*/ -			    /* GC_incremental is set.			*/ -			    /* Full collections are also triggered if	*/ -			    /* the collector detects a substantial	*/ -			    /* increase in the number of in-use heap	*/ -			    /* blocks.  Values in the tens are now	*/ -			    /* perfectly reasonable, unlike for		*/ -			    /* earlier GC versions.			*/ -			 -GC_API GC_word GC_non_gc_bytes; -			/* Bytes not considered candidates for collection. */ -			/* Used only to control scheduling of collections. */ -			/* Updated by GC_malloc_uncollectable and GC_free. */ -			/* Wizards only.				   */ - -GC_API int GC_no_dls; -			/* Don't register dynamic library data segments. */ -			/* Wizards only.  Should be used only if the	 */ -			/* application explicitly registers all roots.	 */ -			/* In Microsoft Windows environments, this will	 */ -			/* usually also prevent registration of the	 */ -			/* main data segment as part of the root set.	 */ - -GC_API GC_word GC_free_space_divisor; -			/* We try to make sure that we allocate at 	*/ -			/* least N/GC_free_space_divisor bytes between	*/ -			/* collections, where N is the heap size plus	*/ -			/* a rough estimate of the root set size.	*/ -			/* Initially, GC_free_space_divisor = 4.	*/ -			/* Increasing its value will use less space	*/ -			/* but more collection time.  Decreasing it	*/ -			/* will appreciably decrease collection time	*/ -			/* at the expense of space.			*/ -			/* GC_free_space_divisor = 1 will effectively	*/ -			/* disable collections.				*/ - -GC_API GC_word GC_max_retries; -			/* The maximum number of GCs attempted before	*/ -			/* reporting out of memory after heap		*/ -			/* expansion fails.  Initially 0.		*/ -			 - -GC_API char *GC_stackbottom;	/* Cool end of user stack.		*/ -				/* May be set in the client prior to	*/ -				/* calling any GC_ routines.  This	*/ -				/* avoids some overhead, and 		*/ -				/* potentially some signals that can 	*/ -				/* confuse debuggers.  Otherwise the	*/ -				/* collector attempts to set it 	*/ -				/* automatically.			*/ -				/* For multithreaded code, this is the	*/ -				/* cold end of the stack for the	*/ -				/* primordial thread.			*/	 -				 -GC_API int GC_dont_precollect;  /* Don't collect as part of 		*/ -				/* initialization.  Should be set only	*/ -				/* if the client wants a chance to	*/ -				/* manually initialize the root set	*/ -				/* before the first collection.		*/ -				/* Interferes with blacklisting.	*/ -				/* Wizards only.			*/ - -GC_API 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 	 */ -				/* GC_TIME_UNLIMITED will essentially	 */ -				/* disable incremental collection while  */ -				/* leaving generational collection	 */ -				/* enabled.	 			 */ -#	define GC_TIME_UNLIMITED 999999 -				/* Setting GC_time_limit to this value	 */ -				/* will disable the "pause time exceeded"*/ -				/* tests.				 */ - -/* Public procedures */ - -/* Initialize the collector.  This is only required when using thread-local - * allocation, since unlike the regular allocation routines, GC_local_malloc - * is not self-initializing.  If you use GC_local_malloc you should arrange - * to call this somehow (e.g. from a constructor) before doing any allocation. - */ -GC_API void GC_init GC_PROTO((void)); - -/* - * general purpose allocation routines, with roughly malloc calling conv. - * The atomic versions promise that no relevant pointers are contained - * in the object.  The nonatomic versions guarantee that the new object - * is cleared.  GC_malloc_stubborn promises that no changes to the object - * will occur after GC_end_stubborn_change has been called on the - * result of GC_malloc_stubborn. GC_malloc_uncollectable allocates an object - * that is scanned for pointers to collectable objects, but is not itself - * collectable.  The object is scanned even if it does not appear to - * be reachable.  GC_malloc_uncollectable and GC_free called on the resulting - * object implicitly update GC_non_gc_bytes appropriately. - * - * Note that the GC_malloc_stubborn support is stubbed out by default - * starting in 6.0.  GC_malloc_stubborn is an alias for GC_malloc unless - * the collector is built with STUBBORN_ALLOC defined. - */ -GC_API GC_PTR GC_malloc GC_PROTO((size_t size_in_bytes)); -GC_API GC_PTR GC_malloc_atomic GC_PROTO((size_t size_in_bytes)); -GC_API GC_PTR GC_malloc_uncollectable GC_PROTO((size_t size_in_bytes)); -GC_API GC_PTR GC_malloc_stubborn GC_PROTO((size_t size_in_bytes)); - -/* The following is only defined if the library has been suitably	*/ -/* compiled:								*/ -GC_API GC_PTR GC_malloc_atomic_uncollectable GC_PROTO((size_t size_in_bytes)); - -/* Explicitly deallocate an object.  Dangerous if used incorrectly.     */ -/* Requires a pointer to the base of an object.				*/ -/* If the argument is stubborn, it should not be changeable when freed. */ -/* An object should not be enable for finalization when it is 		*/ -/* explicitly deallocated.						*/ -/* GC_free(0) is a no-op, as required by ANSI C for free.		*/ -GC_API void GC_free GC_PROTO((GC_PTR object_addr)); - -/* - * Stubborn objects may be changed only if the collector is explicitly informed. - * The collector is implicitly informed of coming change when such - * an object is first allocated.  The following routines inform the - * collector that an object will no longer be changed, or that it will - * once again be changed.  Only nonNIL pointer stores into the object - * are considered to be changes.  The argument to GC_end_stubborn_change - * must be exacly the value returned by GC_malloc_stubborn or passed to - * GC_change_stubborn.  (In the second case it may be an interior pointer - * within 512 bytes of the beginning of the objects.) - * There is a performance penalty for allowing more than - * one stubborn object to be changed at once, but it is acceptable to - * do so.  The same applies to dropping stubborn objects that are still - * changeable. - */ -GC_API void GC_change_stubborn GC_PROTO((GC_PTR)); -GC_API void GC_end_stubborn_change GC_PROTO((GC_PTR)); - -/* Return a pointer to the base (lowest address) of an object given	*/ -/* a pointer to a location within the object.				*/ -/* I.e. map an interior pointer to the corresponding bas pointer.	*/ -/* Note that with debugging allocation, this returns a pointer to the	*/ -/* actual base of the object, i.e. the debug information, not to	*/ -/* the base of the user object.						*/ -/* Return 0 if displaced_pointer doesn't point to within a valid	*/ -/* object.								*/ -GC_API GC_PTR GC_base GC_PROTO((GC_PTR displaced_pointer)); - -/* Given a pointer to the base of an object, return its size in bytes.	*/ -/* The returned size may be slightly larger than what was originally	*/ -/* requested.								*/ -GC_API size_t GC_size GC_PROTO((GC_PTR object_addr)); - -/* For compatibility with C library.  This is occasionally faster than	*/ -/* a malloc followed by a bcopy.  But if you rely on that, either here	*/ -/* or with the standard C library, your code is broken.  In my		*/ -/* opinion, it shouldn't have been invented, but now we're stuck. -HB	*/ -/* The resulting object has the same kind as the original.		*/ -/* If the argument is stubborn, the result will have changes enabled.	*/ -/* It is an error to have changes enabled for the original object.	*/ -/* Follows ANSI comventions for NULL old_object.			*/ -GC_API GC_PTR GC_realloc -	GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes)); -				    -/* Explicitly increase the heap size.	*/ -/* Returns 0 on failure, 1 on success.  */ -GC_API int GC_expand_hp GC_PROTO((size_t number_of_bytes)); - -/* Limit the heap size to n bytes.  Useful when you're debugging, 	*/ -/* especially on systems that don't handle running out of memory well.	*/ -/* n == 0 ==> unbounded.  This is the default.				*/ -GC_API void GC_set_max_heap_size GC_PROTO((GC_word n)); - -/* Inform the collector that a certain section of statically allocated	*/ -/* memory contains no pointers to garbage collected memory.  Thus it 	*/ -/* need not be scanned.  This is sometimes important if the application */ -/* maps large read/write files into the address space, which could be	*/ -/* mistaken for dynamic library data segments on some systems.		*/ -GC_API void GC_exclude_static_roots GC_PROTO((GC_PTR start, GC_PTR finish)); - -/* Clear the set of root segments.  Wizards only. */ -GC_API void GC_clear_roots GC_PROTO((void)); - -/* Add a root segment.  Wizards only. */ -GC_API void GC_add_roots GC_PROTO((char * low_address, -				   char * high_address_plus_1)); - -/* Add a displacement to the set of those considered valid by the	*/ -/* collector.  GC_register_displacement(n) means that if p was returned */ -/* by GC_malloc, then (char *)p + n will be considered to be a valid	*/ -/* pointer to n.  N must be small and less than the size of p.		*/ -/* (All pointers to the interior of objects from the stack are		*/ -/* considered valid in any case.  This applies to heap objects and	*/ -/* static data.)							*/ -/* Preferably, this should be called before any other GC procedures.	*/ -/* Calling it later adds to the probability of excess memory		*/ -/* retention.								*/ -/* This is a no-op if the collector was compiled with recognition of	*/ -/* arbitrary interior pointers enabled, which is now the default.	*/ -GC_API void GC_register_displacement GC_PROTO((GC_word n)); - -/* The following version should be used if any debugging allocation is	*/ -/* being done.								*/ -GC_API void GC_debug_register_displacement GC_PROTO((GC_word n)); - -/* Explicitly trigger a full, world-stop collection. 	*/ -GC_API void GC_gcollect GC_PROTO((void)); - -/* Trigger a full world-stopped collection.  Abort the collection if 	*/ -/* and when stop_func returns a nonzero value.  Stop_func will be 	*/ -/* called frequently, and should be reasonably fast.  This works even	*/ -/* if virtual dirty bits, and hence incremental collection is not 	*/ -/* available for this architecture.  Collections can be aborted faster	*/ -/* than normal pause times for incremental collection.  However,	*/ -/* aborted collections do no useful work; the next collection needs	*/ -/* to start from the beginning.						*/ -/* Return 0 if the collection was aborted, 1 if it succeeded.		*/ -typedef int (* GC_stop_func) GC_PROTO((void)); -GC_API int GC_try_to_collect GC_PROTO((GC_stop_func stop_func)); - -/* Return the number of bytes in the heap.  Excludes collector private	*/ -/* data structures.  Includes empty blocks and fragmentation loss.	*/ -/* Includes some pages that were allocated but never written.		*/ -GC_API size_t GC_get_heap_size GC_PROTO((void)); - -/* Return a lower bound on the number of free bytes in the heap.	*/ -GC_API size_t GC_get_free_bytes GC_PROTO((void)); - -/* Return the number of bytes allocated since the last collection.	*/ -GC_API size_t GC_get_bytes_since_gc GC_PROTO((void)); - -/* Return the total number of bytes allocated in this process.		*/ -/* Never decreases.							*/ -GC_API size_t GC_get_total_bytes GC_PROTO((void)); - -/* Enable incremental/generational collection.	*/ -/* Not advisable unless dirty bits are 		*/ -/* available or most heap objects are		*/ -/* pointerfree(atomic) or immutable.		*/ -/* Don't use in leak finding mode.		*/ -/* Ignored if GC_dont_gc is true.		*/ -/* Only the generational piece of this is	*/ -/* functional if GC_parallel is TRUE		*/ -/* or if GC_time_limit is GC_TIME_UNLIMITED.	*/ -/* Causes GC_local_gcj_malloc() to revert to	*/ -/* locked allocation.  Must be called 		*/ -/* before any GC_local_gcj_malloc() calls.	*/ -GC_API void GC_enable_incremental GC_PROTO((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 objs.	*/ -#define GC_PROTECTS_PTRFREE_HEAP  2 -#define GC_PROTECTS_STATIC_DATA   4 /* Curently never.			*/ -#define GC_PROTECTS_STACK	  8 /* Probably impractical.		*/ - -#define GC_PROTECTS_NONE 0 -GC_API int GC_incremental_protection_needs GC_PROTO((void)); - -/* Perform some garbage collection work, if appropriate.	*/ -/* Return 0 if there is no more work to be done.		*/ -/* Typically performs an amount of work corresponding roughly	*/ -/* to marking from one page.  May do more work if further	*/ -/* progress requires it, e.g. if incremental collection is	*/ -/* disabled.  It is reasonable to call this in a wait loop	*/ -/* until it returns 0.						*/ -GC_API int GC_collect_a_little GC_PROTO((void)); - -/* Allocate an object of size lb bytes.  The client guarantees that	*/ -/* as long as the object is live, it will be referenced by a pointer	*/ -/* that points to somewhere within the first 256 bytes of the object.	*/ -/* (This should normally be declared volatile to prevent the compiler	*/ -/* from invalidating this assertion.)  This routine is only useful	*/ -/* if a large array is being allocated.  It reduces the chance of 	*/ -/* accidentally retaining such an array as a result of scanning an	*/ -/* integer that happens to be an address inside the array.  (Actually,	*/ -/* 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,	*/ -/* or if the collector is not configured to recognize all interior	*/ -/* pointers, the threshold is normally much higher.			*/ -GC_API GC_PTR GC_malloc_ignore_off_page GC_PROTO((size_t lb)); -GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROTO((size_t lb)); - -#if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720 -#   define GC_ADD_CALLER -#   define GC_RETURN_ADDR (GC_word)__return_address -#endif - -#ifdef GC_ADD_CALLER -#  define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__ -#  define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * s, int i -#else -#  define GC_EXTRAS __FILE__, __LINE__ -#  define GC_EXTRA_PARAMS GC_CONST char * s, int i -#endif - -/* Debugging (annotated) allocation.  GC_gcollect will check 		*/ -/* objects allocated in this way for overwrites, etc.			*/ -GC_API GC_PTR GC_debug_malloc -	GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); -GC_API GC_PTR GC_debug_malloc_atomic -	GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); -GC_API GC_PTR GC_debug_malloc_uncollectable -	GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); -GC_API GC_PTR GC_debug_malloc_stubborn -	GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS)); -GC_API void GC_debug_free GC_PROTO((GC_PTR object_addr)); -GC_API GC_PTR GC_debug_realloc -	GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes, -  		  GC_EXTRA_PARAMS)); -  			 	  -GC_API void GC_debug_change_stubborn GC_PROTO((GC_PTR)); -GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_PTR)); -# ifdef GC_DEBUG -#   define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS) -#   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS) -#   define GC_MALLOC_UNCOLLECTABLE(sz) GC_debug_malloc_uncollectable(sz, \ -							GC_EXTRAS) -#   define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS) -#   define GC_FREE(p) GC_debug_free(p) -#   define GC_REGISTER_FINALIZER(p, f, d, of, od) \ -	GC_debug_register_finalizer(p, f, d, of, od) -#   define GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) \ -	GC_debug_register_finalizer_ignore_self(p, f, d, of, od) -#   define GC_REGISTER_FINALIZER_NO_ORDER(p, f, d, of, od) \ -	GC_debug_register_finalizer_no_order(p, f, d, of, od) -#   define GC_MALLOC_STUBBORN(sz) GC_debug_malloc_stubborn(sz, GC_EXTRAS); -#   define GC_CHANGE_STUBBORN(p) GC_debug_change_stubborn(p) -#   define GC_END_STUBBORN_CHANGE(p) GC_debug_end_stubborn_change(p) -#   define GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) \ -	GC_general_register_disappearing_link(link, GC_base(obj)) -#   define GC_REGISTER_DISPLACEMENT(n) GC_debug_register_displacement(n) -# else -#   define GC_MALLOC(sz) GC_malloc(sz) -#   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz) -#   define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz) -#   define GC_REALLOC(old, sz) GC_realloc(old, sz) -#   define GC_FREE(p) GC_free(p) -#   define GC_REGISTER_FINALIZER(p, f, d, of, od) \ -	GC_register_finalizer(p, f, d, of, od) -#   define GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) \ -	GC_register_finalizer_ignore_self(p, f, d, of, od) -#   define GC_REGISTER_FINALIZER_NO_ORDER(p, f, d, of, od) \ -	GC_register_finalizer_no_order(p, f, d, of, od) -#   define GC_MALLOC_STUBBORN(sz) GC_malloc_stubborn(sz) -#   define GC_CHANGE_STUBBORN(p) GC_change_stubborn(p) -#   define GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p) -#   define GC_GENERAL_REGISTER_DISAPPEARING_LINK(link, obj) \ -	GC_general_register_disappearing_link(link, obj) -#   define GC_REGISTER_DISPLACEMENT(n) GC_register_displacement(n) -# endif -/* The following are included because they are often convenient, and	*/ -/* reduce the chance for a misspecifed size argument.  But calls may	*/ -/* expand to something syntactically incorrect if t is a complicated	*/ -/* type expression.  							*/ -# define GC_NEW(t) (t *)GC_MALLOC(sizeof (t)) -# define GC_NEW_ATOMIC(t) (t *)GC_MALLOC_ATOMIC(sizeof (t)) -# define GC_NEW_STUBBORN(t) (t *)GC_MALLOC_STUBBORN(sizeof (t)) -# define GC_NEW_UNCOLLECTABLE(t) (t *)GC_MALLOC_UNCOLLECTABLE(sizeof (t)) - -/* Finalization.  Some of these primitives are grossly unsafe.		*/ -/* The idea is to make them both cheap, and sufficient to build		*/ -/* a safer layer, closer to PCedar finalization.			*/ -/* The interface represents my conclusions from a long discussion	*/ -/* with Alan Demers, Dan Greene, Carl Hauser, Barry Hayes, 		*/ -/* Christian Jacobi, and Russ Atkinson.  It's not perfect, and		*/ -/* probably nobody else agrees with it.	    Hans-J. Boehm  3/13/92	*/ -typedef void (*GC_finalization_proc) -  	GC_PROTO((GC_PTR obj, GC_PTR client_data)); - -GC_API void GC_register_finalizer -    	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, -		  GC_finalization_proc *ofn, GC_PTR *ocd)); -GC_API void GC_debug_register_finalizer -    	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, -		  GC_finalization_proc *ofn, GC_PTR *ocd)); -	/* When obj is no longer accessible, invoke		*/ -	/* (*fn)(obj, cd).  If a and b are inaccessible, and	*/ -	/* a points to b (after disappearing links have been	*/ -	/* made to disappear), then only a will be		*/ -	/* finalized.  (If this does not create any new		*/ -	/* pointers to b, then b will be finalized after the	*/ -	/* next collection.)  Any finalizable object that	*/ -	/* is reachable from itself by following one or more	*/ -	/* pointers will not be finalized (or collected).	*/ -	/* Thus cycles involving finalizable objects should	*/ -	/* be avoided, or broken by disappearing links.		*/ -	/* All but the last finalizer registered for an object  */ -	/* is ignored.						*/ -	/* Finalization may be removed by passing 0 as fn.	*/ -	/* Finalizers are implicitly unregistered just before   */ -	/* they are invoked.					*/ -	/* The old finalizer and client data are stored in	*/ -	/* *ofn and *ocd.					*/  -	/* Fn is never invoked on an accessible object,		*/ -	/* provided hidden pointers are converted to real 	*/ -	/* pointers only if the allocation lock is held, and	*/ -	/* such conversions are not performed by finalization	*/ -	/* routines.						*/ -	/* If GC_register_finalizer is aborted as a result of	*/ -	/* a signal, the object may be left with no		*/ -	/* finalization, even if neither the old nor new	*/ -	/* finalizer were NULL.					*/ -	/* Obj should be the nonNULL starting address of an 	*/ -	/* object allocated by GC_malloc or friends.		*/ -	/* Note that any garbage collectable object referenced	*/ -	/* by cd will be considered accessible until the	*/ -	/* finalizer is invoked.				*/ - -/* Another versions of the above follow.  It ignores		*/ -/* self-cycles, i.e. pointers from a finalizable object to	*/ -/* itself.  There is a stylistic argument that this is wrong,	*/ -/* but it's unavoidable for C++, since the compiler may		*/ -/* silently introduce these.  It's also benign in that specific	*/ -/* case.							*/ -/* Note that cd will still be viewed as accessible, even if it	*/ -/* refers to the object itself.					*/ -GC_API void GC_register_finalizer_ignore_self -	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, -		  GC_finalization_proc *ofn, GC_PTR *ocd)); -GC_API void GC_debug_register_finalizer_ignore_self -	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, -		  GC_finalization_proc *ofn, GC_PTR *ocd)); - -/* Another version of the above.  It ignores all cycles.        */ -/* It should probably only be used by Java implementations.     */ -/* Note that cd will still be viewed as accessible, even if it	*/ -/* refers to the object itself.					*/ -GC_API void GC_register_finalizer_no_order -	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, -		  GC_finalization_proc *ofn, GC_PTR *ocd)); -GC_API void GC_debug_register_finalizer_no_order -	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, -		  GC_finalization_proc *ofn, GC_PTR *ocd)); - - -/* The following routine may be used to break cycles between	*/ -/* finalizable objects, thus causing cyclic finalizable		*/ -/* objects to be finalized in the correct order.  Standard	*/ -/* use involves calling GC_register_disappearing_link(&p),	*/ -/* where p is a pointer that is not followed by finalization	*/ -/* code, and should not be considered in determining 		*/ -/* finalization order.						*/ -GC_API int GC_register_disappearing_link GC_PROTO((GC_PTR * /* link */)); -	/* Link should point to a field of a heap allocated 	*/ -	/* object obj.  *link will be cleared when obj is	*/ -	/* found to be inaccessible.  This happens BEFORE any	*/ -	/* finalization code is invoked, and BEFORE any		*/ -	/* decisions about finalization order are made.		*/ -	/* This is useful in telling the finalizer that 	*/ -	/* some pointers are not essential for proper		*/ -	/* finalization.  This may avoid finalization cycles.	*/ -	/* Note that obj may be resurrected by another		*/ -	/* finalizer, and thus the clearing of *link may	*/ -	/* be visible to non-finalization code.  		*/ -	/* There's an argument that an arbitrary action should  */ -	/* be allowed here, instead of just clearing a pointer. */ -	/* But this causes problems if that action alters, or 	*/ -	/* examines connectivity.				*/ -	/* Returns 1 if link was already registered, 0		*/ -	/* otherwise.						*/ -	/* Only exists for backward compatibility.  See below:	*/ -	 -GC_API int GC_general_register_disappearing_link -	GC_PROTO((GC_PTR * /* link */, GC_PTR obj)); -	/* A slight generalization of the above. *link is	*/ -	/* cleared when obj first becomes inaccessible.  This	*/ -	/* can be used to implement weak pointers easily and	*/ -	/* safely. Typically link will point to a location	*/ -	/* holding a disguised pointer to obj.  (A pointer 	*/ -	/* inside an "atomic" object is effectively  		*/ -	/* disguised.)   In this way soft			*/ -	/* pointers are broken before any object		*/ -	/* reachable from them are finalized.  Each link	*/ -	/* May be registered only once, i.e. with one obj	*/ -	/* value.  This was added after a long email discussion */ -	/* with John Ellis.					*/ -	/* Obj must be a pointer to the first word of an object */ -	/* we allocated.  It is unsafe to explicitly deallocate */ -	/* the object containing link.  Explicitly deallocating */ -	/* obj may or may not cause link to eventually be	*/ -	/* cleared.						*/ -GC_API int GC_unregister_disappearing_link GC_PROTO((GC_PTR * /* link */)); -	/* Returns 0 if link was not actually registered.	*/ -	/* Undoes a registration by either of the above two	*/ -	/* routines.						*/ - -/* Auxiliary fns to make finalization work correctly with displaced	*/ -/* pointers introduced by the debugging allocators.			*/ -GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data)); -GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data)); - -/* Returns !=0  if GC_invoke_finalizers has something to do. 		*/ -GC_API int GC_should_invoke_finalizers GC_PROTO((void)); - -GC_API int GC_invoke_finalizers GC_PROTO((void)); -	/* Run finalizers for all objects that are ready to	*/ -	/* be finalized.  Return the number of finalizers	*/ -	/* that were run.  Normally this is also called		*/ -	/* implicitly during some allocations.	If		*/ -	/* GC-finalize_on_demand is nonzero, it must be called	*/ -	/* explicitly.						*/ - -/* GC_set_warn_proc can be used to redirect or filter warning messages.	*/ -/* p may not be a NULL pointer.						*/ -typedef void (*GC_warn_proc) GC_PROTO((char *msg, GC_word arg)); -GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p)); -    /* Returns old warning procedure.	*/ -	 -/* The following is intended to be used by a higher level	*/ -/* (e.g. Java-like) finalization facility.  It is expected	*/ -/* that finalization code will arrange for hidden pointers to	*/ -/* disappear.  Otherwise objects can be accessed after they	*/ -/* have been collected.						*/ -/* Note that putting pointers in atomic objects or in 		*/ -/* nonpointer slots of "typed" objects is equivalent to 	*/ -/* disguising them in this way, and may have other advantages.	*/ -# if defined(I_HIDE_POINTERS) || defined(GC_I_HIDE_POINTERS) -    typedef GC_word GC_hidden_pointer; -#   define HIDE_POINTER(p) (~(GC_hidden_pointer)(p)) -#   define REVEAL_POINTER(p) ((GC_PTR)(HIDE_POINTER(p))) -    /* Converting a hidden pointer to a real pointer requires verifying	*/ -    /* that the object still exists.  This involves acquiring the  	*/ -    /* allocator lock to avoid a race with the collector.		*/ -# endif /* I_HIDE_POINTERS */ - -typedef GC_PTR (*GC_fn_type) GC_PROTO((GC_PTR client_data)); -GC_API GC_PTR GC_call_with_alloc_lock -        	GC_PROTO((GC_fn_type fn, GC_PTR client_data)); - -/* The following routines are primarily intended for use with a 	*/ -/* preprocessor which inserts calls to check C pointer arithmetic.	*/ - -/* Check that p and q point to the same object.  		*/ -/* Fail conspicuously if they don't.				*/ -/* Returns the first argument.  				*/ -/* Succeeds if neither p nor q points to the heap.		*/ -/* May succeed if both p and q point to between heap objects.	*/ -GC_API GC_PTR GC_same_obj GC_PROTO((GC_PTR p, GC_PTR q)); - -/* Checked pointer pre- and post- increment operations.  Note that	*/ -/* the second argument is in units of bytes, not multiples of the	*/ -/* object size.  This should either be invoked from a macro, or the	*/ -/* call should be automatically generated.				*/ -GC_API GC_PTR GC_pre_incr GC_PROTO((GC_PTR *p, size_t how_much)); -GC_API GC_PTR GC_post_incr GC_PROTO((GC_PTR *p, size_t how_much)); - -/* Check that p is visible						*/ -/* to the collector as a possibly pointer containing location.		*/ -/* If it isn't fail conspicuously.					*/ -/* Returns the argument in all cases.  May erroneously succeed		*/ -/* in hard cases.  (This is intended for debugging use with		*/ -/* untyped allocations.  The idea is that it should be possible, though	*/ -/* slow, to add such a call to all indirect pointer stores.)		*/ -/* Currently useless for multithreaded worlds.				*/ -GC_API GC_PTR GC_is_visible GC_PROTO((GC_PTR p)); - -/* Check that if p is a pointer to a heap page, then it points to	*/ -/* a valid displacement within a heap object.				*/ -/* Fail conspicuously if this property does not hold.			*/ -/* Uninteresting with GC_all_interior_pointers.				*/ -/* Always returns its argument.						*/ -GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR	p)); - -/* Safer, but slow, pointer addition.  Probably useful mainly with 	*/ -/* a preprocessor.  Useful only for heap pointers.			*/ -#ifdef GC_DEBUG -#   define GC_PTR_ADD3(x, n, type_of_result) \ -	((type_of_result)GC_same_obj((x)+(n), (x))) -#   define GC_PRE_INCR3(x, n, type_of_result) \ -	((type_of_result)GC_pre_incr(&(x), (n)*sizeof(*x)) -#   define GC_POST_INCR2(x, type_of_result) \ -	((type_of_result)GC_post_incr(&(x), sizeof(*x)) -#   ifdef __GNUC__ -#       define GC_PTR_ADD(x, n) \ -	    GC_PTR_ADD3(x, n, typeof(x)) -#       define GC_PRE_INCR(x, n) \ -	    GC_PRE_INCR3(x, n, typeof(x)) -#       define GC_POST_INCR(x, n) \ -	    GC_POST_INCR3(x, typeof(x)) -#   else -	/* We can't do this right without typeof, which ANSI	*/ -	/* decided was not sufficiently useful.  Repeatedly	*/ -	/* mentioning the arguments seems too dangerous to be	*/ -	/* useful.  So does not casting the result.		*/ -#   	define GC_PTR_ADD(x, n) ((x)+(n)) -#   endif -#else	/* !GC_DEBUG */ -#   define GC_PTR_ADD3(x, n, type_of_result) ((x)+(n)) -#   define GC_PTR_ADD(x, n) ((x)+(n)) -#   define GC_PRE_INCR3(x, n, type_of_result) ((x) += (n)) -#   define GC_PRE_INCR(x, n) ((x) += (n)) -#   define GC_POST_INCR2(x, n, type_of_result) ((x)++) -#   define GC_POST_INCR(x, n) ((x)++) -#endif - -/* Safer assignment of a pointer to a nonstack location.	*/ -#ifdef GC_DEBUG -# ifdef __STDC__ -#   define GC_PTR_STORE(p, q) \ -	(*(void **)GC_is_visible(p) = GC_is_valid_displacement(q)) -# else -#   define GC_PTR_STORE(p, q) \ -	(*(char **)GC_is_visible(p) = GC_is_valid_displacement(q)) -# endif -#else /* !GC_DEBUG */ -#   define GC_PTR_STORE(p, q) *((p) = (q)) -#endif - -/* Fynctions called to report pointer checking errors */ -GC_API void (*GC_same_obj_print_proc) GC_PROTO((GC_PTR p, GC_PTR q)); - -GC_API void (*GC_is_valid_displacement_print_proc) -	GC_PROTO((GC_PTR p)); - -GC_API void (*GC_is_visible_print_proc) -	GC_PROTO((GC_PTR p)); - - -/* For pthread support, we generally need to intercept a number of 	*/ -/* thread library calls.  We do that here by macro defining them.	*/ - -#if !defined(GC_USE_LD_WRAP) && \ -    (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)) -# include "gc_pthread_redirects.h" -#endif - -# if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ -     defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) -   	/* Any flavor of threads except SRC_M3.	*/ -/* This returns a list of objects, linked through their first		*/ -/* word.  Its use can greatly reduce lock contention problems, since	*/ -/* the allocation lock can be acquired and released many fewer times.	*/ -/* lb must be large enough to hold the pointer field.			*/ -/* It is used internally by gc_local_alloc.h, which provides a simpler	*/ -/* programming interface on Linux.					*/ -GC_PTR GC_malloc_many(size_t lb); -#define GC_NEXT(p) (*(GC_PTR *)(p)) 	/* Retrieve the next element	*/ -					/* in returned list.		*/ -extern void GC_thr_init();	/* Needed for Solaris/X86	*/ - -#endif /* THREADS && !SRC_M3 */ - -#if defined(GC_WIN32_THREADS) -# include <windows.h> -# include <winbase.h> - -  /* -   * All threads must be created using GC_CreateThread, so that they will be -   * recorded in the thread table.  For backwards compatibility, this is not -   * technically true if the GC is built as a dynamic library, since it can -   * and does then use DllMain to keep track of thread creations.  But new code -   * should be built to call GC_CreateThread. -   */ -  HANDLE WINAPI GC_CreateThread( -      LPSECURITY_ATTRIBUTES lpThreadAttributes, -      DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, -      LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); - -# if defined(_WIN32_WCE) -  /* -   * win32_threads.c implements the real WinMain, which will start a new thread -   * to call GC_WinMain after initializing the garbage collector. -   */ -  int WINAPI GC_WinMain( -      HINSTANCE hInstance, -      HINSTANCE hPrevInstance, -      LPWSTR lpCmdLine, -      int nCmdShow ); - -#  ifndef GC_BUILD -#    define WinMain GC_WinMain -#    define CreateThread GC_CreateThread -#  endif -# endif /* defined(_WIN32_WCE) */ - -#endif /* defined(GC_WIN32_THREADS) */ - -/* - * If you are planning on putting - * the collector in a SunOS 5 dynamic library, you need to call GC_INIT() - * from the statically loaded program section. - * This circumvents a Solaris 2.X (X<=4) linker bug. - */ -#if defined(sparc) || defined(__sparc) -#   define GC_INIT() { extern end, etext; \ -		       GC_noop(&end, &etext); } -#else -# if defined(__CYGWIN32__) && defined(GC_USE_DLL) || defined (_AIX) -    /* -     * Similarly gnu-win32 DLLs need explicit initialization from -     * the main program, as does AIX. -     */ -#   define GC_INIT() { GC_add_roots(DATASTART, DATAEND); } -# else -#   define GC_INIT() -# endif -#endif - -#if !defined(_WIN32_WCE) \ -    && ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ -        || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)) -  /* win32S may not free all resources on process exit.  */ -  /* This explicitly deallocates the heap.		 */ -    GC_API void GC_win32_free_heap (); -#endif - -#if ( defined(_AMIGA) && !defined(GC_AMIGA_MAKINGLIB) ) -  /* Allocation really goes through GC_amiga_allocwrapper_do */ -# include "gc_amiga_redirects.h" -#endif - -#if defined(GC_REDIRECT_TO_LOCAL) && !defined(GC_LOCAL_ALLOC_H) -#  include  "gc_local_alloc.h" -#endif - -#ifdef __cplusplus -    }  /* end of extern "C" */ -#endif - -#endif /* _GC_H */ diff --git a/gc/include/gc_alloc.h b/gc/include/gc_alloc.h deleted file mode 100644 index c50a758..0000000 --- a/gc/include/gc_alloc.h +++ /dev/null @@ -1,383 +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 C++ header file that is intended to replace the SGI STL -// alloc.h.  This assumes SGI STL version < 3.0. -// -// This assumes the collector has been compiled with -DATOMIC_UNCOLLECTABLE -// and -DALL_INTERIOR_POINTERS.  We also recommend -// -DREDIRECT_MALLOC=GC_uncollectable_malloc. -// -// 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. -// -// This code assumes that the collector itself has been compiled with a -// compiler that defines __STDC__ . -// - -#include "gc.h" - -#ifndef GC_ALLOC_H - -#define GC_ALLOC_H -#define __ALLOC_H	// Prevent inclusion of the default version.  Ugly. -#define __SGI_STL_ALLOC_H -#define __SGI_STL_INTERNAL_ALLOC_H - -#ifndef __ALLOC -#   define __ALLOC alloc -#endif - -#include <stddef.h> -#include <string.h> - -// The following is just replicated from the conventional SGI alloc.h: - -template<class T, class alloc> -class simple_alloc { - -public: -    static T *allocate(size_t n) -                { return 0 == n? 0 : (T*) alloc::allocate(n * sizeof (T)); } -    static T *allocate(void) -                { return (T*) alloc::allocate(sizeof (T)); } -    static void deallocate(T *p, size_t n) -                { if (0 != n) alloc::deallocate(p, n * sizeof (T)); } -    static void deallocate(T *p) -                { alloc::deallocate(p, sizeof (T)); } -}; - -#include "gc.h" - -// The following need to match collector data structures. -// We can't include gc_priv.h, since that pulls in way too much stuff. -// This should eventually be factored out into another include file. - -extern "C" { -    extern void ** const GC_objfreelist_ptr; -    extern void ** const GC_aobjfreelist_ptr; -    extern void ** const GC_uobjfreelist_ptr; -    extern void ** const GC_auobjfreelist_ptr; - -    extern void GC_incr_words_allocd(size_t words); -    extern void GC_incr_mem_freed(size_t words); - -    extern char * GC_generic_malloc_words_small(size_t word, int kind); -} - -// 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_bytes_per_word = sizeof(char *) }; - -enum { GC_byte_alignment = 8 }; - -enum { GC_word_alignment = GC_byte_alignment/GC_bytes_per_word }; - -inline void * &GC_obj_link(void * p) -{   return *(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_words_recently_allocd; - -  // Same for uncollectable mmory.  Not yet reflected in either -  // GC_words_recently_allocd or GC_non_gc_bytes. -  static size_t GC_uncollectable_words_recently_allocd; - -  // Similar counter for explicitly deallocated memory. -  static size_t GC_mem_recently_freed; - -  // Again for uncollectable memory. -  static size_t GC_uncollectable_mem_recently_freed; - -  static void * GC_out_of_line_malloc(size_t nwords, int kind); -}; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_words_recently_allocd = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_uncollectable_words_recently_allocd = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_mem_recently_freed = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_uncollectable_mem_recently_freed = 0; - -template <int dummy> -void * GC_aux_template<dummy>::GC_out_of_line_malloc(size_t nwords, int kind) -{ -    GC_words_recently_allocd += GC_uncollectable_words_recently_allocd; -    GC_non_gc_bytes += -                GC_bytes_per_word * GC_uncollectable_words_recently_allocd; -    GC_uncollectable_words_recently_allocd = 0; - -    GC_mem_recently_freed += GC_uncollectable_mem_recently_freed; -    GC_non_gc_bytes -=  -                GC_bytes_per_word * GC_uncollectable_mem_recently_freed; -    GC_uncollectable_mem_recently_freed = 0; - -    GC_incr_words_allocd(GC_words_recently_allocd); -    GC_words_recently_allocd = 0; - -    GC_incr_mem_freed(GC_mem_recently_freed); -    GC_mem_recently_freed = 0; - -    return GC_generic_malloc_words_small(nwords, kind); -} - -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 noop, 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) return GC_malloc(n); -	    flh = GC_objfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_NORMAL); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_words_recently_allocd += nwords; -	    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) return GC_malloc_atomic(n); -	    flh = GC_aobjfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_PTRFREE); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_words_recently_allocd += nwords; -	    return op; -        } -	static void deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes)  { -		GC_free(p); -	    } else { -	        flh = GC_objfreelist_ptr + nwords; -	        GC_obj_link(p) = *flh; -		memset((char *)p + GC_bytes_per_word, 0, -		       GC_bytes_per_word * (nwords - 1)); -	        *flh = p; -	        GC_aux::GC_mem_recently_freed += nwords; -	    } -	} -	static void ptr_free_deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes) { -		GC_free(p); -	    } else { -	    	flh = GC_aobjfreelist_ptr + nwords; -	    	GC_obj_link(p) = *flh; -	    	*flh = p; -	    	GC_aux::GC_mem_recently_freed += nwords; -	    } -	} -}; - -typedef single_client_gc_alloc_template<0> single_client_gc_alloc; - -// Once more, for uncollectable objects. -template <int dummy> -class single_client_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) return GC_malloc_uncollectable(n); -	    flh = GC_uobjfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_UNCOLLECTABLE); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_uncollectable_words_recently_allocd += nwords; -	    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) return GC_malloc_atomic_uncollectable(n); -	    flh = GC_auobjfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_AUNCOLLECTABLE); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_uncollectable_words_recently_allocd += nwords; -	    return op; -        } -	static void deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up_uncollectable(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes)  { -		GC_free(p); -	    } else { -	        flh = GC_uobjfreelist_ptr + nwords; -	        GC_obj_link(p) = *flh; -	        *flh = p; -	        GC_aux::GC_uncollectable_mem_recently_freed += nwords; -	    } -	} -	static void ptr_free_deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up_uncollectable(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes) { -		GC_free(p); -	    } else { -	    	flh = GC_auobjfreelist_ptr + nwords; -	    	GC_obj_link(p) = *flh; -	    	*flh = p; -	    	GC_aux::GC_uncollectable_mem_recently_freed += nwords; -	    } -	} -}; - -typedef single_client_alloc_template<0> single_client_alloc; - -template < int dummy > -class gc_alloc_template { -    public: -     	static void * allocate(size_t n) { return GC_malloc(n); } -     	static void * ptr_free_allocate(size_t n) -		{ return GC_malloc_atomic(n); } -	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 alloc_template { -    public: -     	static void * allocate(size_t n) { return GC_malloc_uncollectable(n); } -     	static void * ptr_free_allocate(size_t n) -		{ return GC_malloc_atomic_uncollectable(n); } -	static void deallocate(void *p, size_t) { GC_free(p); } -	static void ptr_free_deallocate(void *p, size_t) { GC_free(p); } -}; - -typedef alloc_template < 0 > alloc; - -#ifdef _SGI_SOURCE - -// We want to specialize simple_alloc so that it does the right thing -// for all pointerfree types.  At the moment there is no portable way to -// even approximate that.  The following approximation should work for -// SGI compilers, and perhaps some others. - -# define __GC_SPECIALIZE(T,alloc) \ -class simple_alloc<T, alloc> { \ -public: \ -    static T *allocate(size_t n) \ -	{ return 0 == n? 0 : \ -			 (T*) alloc::ptr_free_allocate(n * sizeof (T)); } \ -    static T *allocate(void) \ -	{ return (T*) alloc::ptr_free_allocate(sizeof (T)); } \ -    static void deallocate(T *p, size_t n) \ -	{ if (0 != n) alloc::ptr_free_deallocate(p, n * sizeof (T)); } \ -    static void deallocate(T *p) \ -	{ alloc::ptr_free_deallocate(p, sizeof (T)); } \ -}; - -__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, alloc) -__GC_SPECIALIZE(int, alloc) -__GC_SPECIALIZE(unsigned, alloc) -__GC_SPECIALIZE(float, alloc) -__GC_SPECIALIZE(double, 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_alloc) -__GC_SPECIALIZE(int, single_client_alloc) -__GC_SPECIALIZE(unsigned, single_client_alloc) -__GC_SPECIALIZE(float, single_client_alloc) -__GC_SPECIALIZE(double, single_client_alloc) - -#ifdef __STL_USE_STD_ALLOCATORS - -???copy stuff from stl_alloc.h or remove it to a different file ??? - -#endif /* __STL_USE_STD_ALLOCATORS */ - -#endif /* _SGI_SOURCE */ - -#endif /* GC_ALLOC_H */ diff --git a/gc/include/gc_allocator.h b/gc/include/gc_allocator.h deleted file mode 100644 index 87c8509..0000000 --- a/gc/include/gc_allocator.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 1996-1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation.  Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose.  It is provided "as is" without express or implied warranty. - * - * Copyright (c) 2002 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation.  Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose.  It is provided "as is" without express or implied warranty. - */ - -/* - * This implements standard-conforming allocators that interact with - * the garbage collector.  Gc_alloctor<T> allocates garbage-collectable - * objects of type T.  Traceable_allocator<T> allocates objects that - * are not temselves garbage collected, but are scanned by the - * collector for pointers to collectable objects.  Traceable_alloc - * should be used for explicitly managed STL containers that may - * point to collectable objects. - * - * This code was derived from an earlier version of the GNU C++ standard - * library, which itself was derived from the SGI STL implementation. - */ - -#include "gc.h" 	// For size_t - -/* First some helpers to allow us to dispatch on whether or not a type - * is known to be pointerfree. - * These are private, except that the client may invoke the - * GC_DECLARE_PTRFREE macro. - */ - -struct GC_true_type {}; -struct GC_false_type {}; - -template <class GC_tp> -struct GC_type_traits { -  GC_false_type GC_is_ptr_free; -}; - -# define GC_DECLARE_PTRFREE(T) \ -template<> struct GC_type_traits<T> { GC_true_type GC_is_ptr_free; } - -GC_DECLARE_PTRFREE(signed char); -GC_DECLARE_PTRFREE(unsigned char); -GC_DECLARE_PTRFREE(signed short); -GC_DECLARE_PTRFREE(unsigned short); -GC_DECLARE_PTRFREE(signed int); -GC_DECLARE_PTRFREE(unsigned int); -GC_DECLARE_PTRFREE(signed long); -GC_DECLARE_PTRFREE(unsigned long); -GC_DECLARE_PTRFREE(float); -GC_DECLARE_PTRFREE(double); -/* The client may want to add others.	*/ - -// In the following GC_Tp is GC_true_type iff we are allocating a -// pointerfree object. -template <class GC_Tp> -inline void * GC_selective_alloc(size_t n, GC_Tp) { -    return GC_MALLOC(n); -} - -template <> -inline void * GC_selective_alloc<GC_true_type>(size_t n, GC_true_type) { -    return GC_MALLOC_ATOMIC(n); -} - -/* Now the public gc_allocator<T> class: - */ -template <class GC_Tp> -class gc_allocator { -public: -  typedef size_t     size_type; -  typedef ptrdiff_t  difference_type; -  typedef GC_Tp*       pointer; -  typedef const GC_Tp* const_pointer; -  typedef GC_Tp&       reference; -  typedef const GC_Tp& const_reference; -  typedef GC_Tp        value_type; - -  template <class GC_Tp1> struct rebind { -    typedef gc_allocator<GC_Tp1> other; -  }; - -  gc_allocator()  {} -# ifndef _MSC_VER -    // I'm not sure why this is needed here in addition to the following. -    // The standard specifies it for the standard allocator, but VC++ rejects -    // it.	-HB -    gc_allocator(const gc_allocator&) throw() {} -# endif -  template <class GC_Tp1> gc_allocator(const gc_allocator<GC_Tp1>&) throw() {} -  ~gc_allocator() throw() {} - -  pointer address(reference GC_x) const { return &GC_x; } -  const_pointer address(const_reference GC_x) const { return &GC_x; } - -  // GC_n is permitted to be 0.  The C++ standard says nothing about what -  // the return value is when GC_n == 0. -  GC_Tp* allocate(size_type GC_n, const void* = 0) { -    GC_type_traits<GC_Tp> traits; -    return static_cast<GC_Tp *> -	    (GC_selective_alloc(GC_n * sizeof(GC_Tp), -			        traits.GC_is_ptr_free)); -  } - -  // __p is not permitted to be a null pointer. -  void deallocate(pointer __p, size_type GC_n) -    { GC_FREE(__p); } - -  size_type max_size() const throw() -    { return size_t(-1) / sizeof(GC_Tp); } - -  void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); } -  void destroy(pointer __p) { __p->~GC_Tp(); } -}; - -template<> -class gc_allocator<void> { -  typedef size_t      size_type; -  typedef ptrdiff_t   difference_type; -  typedef void*       pointer; -  typedef const void* const_pointer; -  typedef void        value_type; - -  template <class GC_Tp1> struct rebind { -    typedef gc_allocator<GC_Tp1> other; -  }; -}; - - -template <class GC_T1, class GC_T2> -inline bool operator==(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&) -{ -  return true; -} - -template <class GC_T1, class GC_T2> -inline bool operator!=(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&) -{ -  return false; -} - -/* - * And the public traceable_allocator class. - */ - -// Note that we currently don't specialize the pointer-free case, since a -// pointer-free traceable container doesn't make that much sense, -// though it could become an issue due to abstraction boundaries. -template <class GC_Tp> -class traceable_allocator { -public: -  typedef size_t     size_type; -  typedef ptrdiff_t  difference_type; -  typedef GC_Tp*       pointer; -  typedef const GC_Tp* const_pointer; -  typedef GC_Tp&       reference; -  typedef const GC_Tp& const_reference; -  typedef GC_Tp        value_type; - -  template <class GC_Tp1> struct rebind { -    typedef traceable_allocator<GC_Tp1> other; -  }; - -  traceable_allocator() throw() {} -# ifndef _MSC_VER -    traceable_allocator(const traceable_allocator&) throw() {} -# endif -  template <class GC_Tp1> traceable_allocator -	  (const traceable_allocator<GC_Tp1>&) throw() {} -  ~traceable_allocator() throw() {} - -  pointer address(reference GC_x) const { return &GC_x; } -  const_pointer address(const_reference GC_x) const { return &GC_x; } - -  // GC_n is permitted to be 0.  The C++ standard says nothing about what -  // the return value is when GC_n == 0. -  GC_Tp* allocate(size_type GC_n, const void* = 0) { -    return static_cast<GC_Tp*>(GC_MALLOC_UNCOLLECTABLE(GC_n * sizeof(GC_Tp))); -  } - -  // __p is not permitted to be a null pointer. -  void deallocate(pointer __p, size_type GC_n) -    { GC_FREE(__p); } - -  size_type max_size() const throw() -    { return size_t(-1) / sizeof(GC_Tp); } - -  void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); } -  void destroy(pointer __p) { __p->~GC_Tp(); } -}; - -template<> -class traceable_allocator<void> { -  typedef size_t      size_type; -  typedef ptrdiff_t   difference_type; -  typedef void*       pointer; -  typedef const void* const_pointer; -  typedef void        value_type; - -  template <class GC_Tp1> struct rebind { -    typedef traceable_allocator<GC_Tp1> other; -  }; -}; - - -template <class GC_T1, class GC_T2> -inline bool operator==(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&) -{ -  return true; -} - -template <class GC_T1, class GC_T2> -inline bool operator!=(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&) -{ -  return false; -} - diff --git a/gc/include/gc_amiga_redirects.h b/gc/include/gc_amiga_redirects.h deleted file mode 100644 index 9e975c8..0000000 --- a/gc/include/gc_amiga_redirects.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef GC_AMIGA_REDIRECTS_H - -# define GC_AMIGA_REDIRECTS_H - -# if ( defined(_AMIGA) && !defined(GC_AMIGA_MAKINGLIB) ) -    extern void *GC_amiga_realloc(void *old_object,size_t new_size_in_bytes); -#   define GC_realloc(a,b) GC_amiga_realloc(a,b) -    extern void GC_amiga_set_toany(void (*func)(void)); -    extern int GC_amiga_free_space_divisor_inc; -    extern void *(*GC_amiga_allocwrapper_do) \ -	(size_t size,void *(*AllocFunction)(size_t size2)); -#   define GC_malloc(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc) -#   define GC_malloc_atomic(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic) -#   define GC_malloc_uncollectable(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc_uncollectable) -#   define GC_malloc_stubborn(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc_stubborn) -#   define GC_malloc_atomic_uncollectable(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic_uncollectable) -#   define GC_malloc_ignore_off_page(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc_ignore_off_page) -#   define GC_malloc_atomic_ignore_off_page(a) \ -	(*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic_ignore_off_page) -# endif /* _AMIGA && !GC_AMIGA_MAKINGLIB */ - -#endif /* GC_AMIGA_REDIRECTS_H */ - - diff --git a/gc/include/gc_backptr.h b/gc/include/gc_backptr.h deleted file mode 100644 index 5899496..0000000 --- a/gc/include/gc_backptr.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This is a simple API to implement pointer back tracing, i.e. - * to answer questions such as "who is pointing to this" or - * "why is this object being retained by the collector" - * - * This API assumes that we have an ANSI C compiler. - * - * Most of these calls yield useful information on only after - * a garbage collection.  Usually the client will first force - * a full collection and then gather information, preferably - * before much intervening allocation. - * - * The implementation of the interface is only about 99.9999% - * correct.  It is intended to be good enough for profiling, - * but is not intended to be used with production code. - * - * Results are likely to be much more useful if all allocation is - * accomplished through the debugging allocators. - * - * The implementation idea is due to A. Demers. - */ - -#ifndef GC_BACKPTR_H -#define GC_BACKPTR_H -/* Store information about the object referencing dest in *base_p     */ -/* and *offset_p.                                                     */ -/* If multiple objects or roots point to dest, the one reported	      */ -/* will be the last on used by the garbage collector to trace the     */ -/* object.							      */ -/*   source is root ==> *base_p = address, *offset_p = 0	      */ -/*   source is heap object ==> *base_p != 0, *offset_p = offset       */ -/*   Returns 1 on success, 0 if source couldn't be determined.        */ -/* Dest can be any address within a heap object.                      */ -typedef enum {  GC_UNREFERENCED, /* No reference info available.	*/ -		GC_NO_SPACE,	/* Dest not allocated with debug alloc  */ -		GC_REFD_FROM_ROOT, /* Referenced directly by root *base_p */ -		GC_REFD_FROM_REG,  /* Referenced from a register, i.e.	*/ -				   /* a root without an address.	*/ -		GC_REFD_FROM_HEAP, /* Referenced from another heap obj. */ -		GC_FINALIZER_REFD /* Finalizable and hence accessible.  */ -} GC_ref_kind; - -GC_ref_kind GC_get_back_ptr_info(void *dest, void **base_p, size_t *offset_p); - -/* Generate a random heap address.            */ -/* The resulting address is in the heap, but  */ -/* not necessarily inside a valid object.     */ -void * GC_generate_random_heap_address(void); - -/* Generate a random address inside a valid marked heap object. */ -void * GC_generate_random_valid_address(void); - -/* Force a garbage collection and generate a backtrace from a */ -/* random heap address.                                       */ -/* This uses the GC logging mechanism (GC_printf) to produce  */ -/* output.  It can often be called from a debugger.  The      */ -/* source in dbg_mlc.c also serves as a sample client.	      */ -void GC_generate_random_backtrace(void); - -/* Print a backtrace from a specific address.  Used by the 	*/ -/* above.  The client should call GC_gcollect() immediately	*/ -/* before invocation.						*/ -void GC_print_backtrace(void *); - -#endif /* GC_BACKPTR_H */ diff --git a/gc/include/gc_cpp.h b/gc/include/gc_cpp.h deleted file mode 100644 index 2b3a138..0000000 --- a/gc/include/gc_cpp.h +++ /dev/null @@ -1,352 +0,0 @@ -#ifndef GC_CPP_H -#define GC_CPP_H -/**************************************************************************** -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. -**************************************************************************** - -C++ Interface to the Boehm Collector - -    John R. Ellis and Jesse Hull  - -This interface provides access to the Boehm collector.  It provides -basic facilities similar to those described in "Safe, Efficient -Garbage Collection for C++", by John R. Elis and David L. Detlefs -(ftp://ftp.parc.xerox.com/pub/ellis/gc). - -All heap-allocated objects are either "collectable" or -"uncollectable".  Programs must explicitly delete uncollectable -objects, whereas the garbage collector will automatically delete -collectable objects when it discovers them to be inaccessible. -Collectable objects may freely point at uncollectable objects and vice -versa. - -Objects allocated with the built-in "::operator new" are uncollectable. - -Objects derived from class "gc" are collectable.  For example: - -    class A: public gc {...}; -    A* a = new A;       // a is collectable.  - -Collectable instances of non-class types can be allocated using the GC -(or UseGC) placement: - -    typedef int A[ 10 ]; -    A* a = new (GC) A; - -Uncollectable instances of classes derived from "gc" can be allocated -using the NoGC placement: - -    class A: public gc {...}; -    A* a = new (NoGC) A;   // a is uncollectable. - -Both uncollectable and collectable objects can be explicitly deleted -with "delete", which invokes an object's destructors and frees its -storage immediately. - -A collectable object may have a clean-up function, which will be -invoked when the collector discovers the object to be inaccessible. -An object derived from "gc_cleanup" or containing a member derived -from "gc_cleanup" has a default clean-up function that invokes the -object's destructors.  Explicit clean-up functions may be specified as -an additional placement argument: - -    A* a = ::new (GC, MyCleanup) A; - -An object is considered "accessible" by the collector if it can be -reached by a path of pointers from static variables, automatic -variables of active functions, or from some object with clean-up -enabled; pointers from an object to itself are ignored. - -Thus, if objects A and B both have clean-up functions, and A points at -B, B is considered accessible.  After A's clean-up is invoked and its -storage released, B will then become inaccessible and will have its -clean-up invoked.  If A points at B and B points to A, forming a -cycle, then that's considered a storage leak, and neither will be -collectable.  See the interface gc.h for low-level facilities for -handling such cycles of objects with clean-up. - -The collector cannot guarrantee that it will find all inaccessible -objects.  In practice, it finds almost all of them. - - -Cautions: - -1. Be sure the collector has been augmented with "make c++". - -2.  If your compiler supports the new "operator new[]" syntax, then -add -DGC_OPERATOR_NEW_ARRAY to the Makefile. - -If your compiler doesn't support "operator new[]", beware that an -array of type T, where T is derived from "gc", may or may not be -allocated as a collectable object (it depends on the compiler).  Use -the explicit GC placement to make the array collectable.  For example: - -    class A: public gc {...}; -    A* a1 = new A[ 10 ];        // collectable or uncollectable? -    A* a2 = new (GC) A[ 10 ];   // collectable - -3. The destructors of collectable arrays of objects derived from -"gc_cleanup" will not be invoked properly.  For example: - -    class A: public gc_cleanup {...}; -    A* a = new (GC) A[ 10 ];    // destructors not invoked correctly - -Typically, only the destructor for the first element of the array will -be invoked when the array is garbage-collected.  To get all the -destructors of any array executed, you must supply an explicit -clean-up function: - -    A* a = new (GC, MyCleanUp) A[ 10 ]; - -(Implementing clean-up of arrays correctly, portably, and in a way -that preserves the correct exception semantics requires a language -extension, e.g. the "gc" keyword.) - -4. Compiler bugs: - -* Solaris 2's CC (SC3.0) doesn't implement t->~T() correctly, so the -destructors of classes derived from gc_cleanup won't be invoked. -You'll have to explicitly register a clean-up function with -new-placement syntax. - -* Evidently cfront 3.0 does not allow destructors to be explicitly -invoked using the ANSI-conforming syntax t->~T().  If you're using -cfront 3.0, you'll have to comment out the class gc_cleanup, which -uses explicit invocation. - -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 -by UseGC.  GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. - -****************************************************************************/ - -#include "gc.h" - -#ifndef THINK_CPLUS -#define _cdecl -#endif - -#if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \ -    && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \ -    && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \ -	|| (defined(__GNUC__) && \ -	    (__GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 6)) \ -	|| (defined(__WATCOMC__) && __WATCOMC__ < 1050)) -#   define GC_NO_OPERATOR_NEW_ARRAY -#endif - -#if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY) -#   define GC_OPERATOR_NEW_ARRAY -#endif - -enum GCPlacement {UseGC, -#ifndef GC_NAME_CONFLICT -		  GC=UseGC, -#endif -                  NoGC, PointerFreeGC}; - -class gc {public: -    inline void* operator new( size_t size ); -    inline void* operator new( size_t size, GCPlacement gcp ); -    inline void* operator new( size_t size, void *p ); -    	/* Must be redefined here, since the other overloadings	*/ -    	/* hide the global definition.				*/ -    inline void operator delete( void* obj ); -    inline void operator delete( void*, void* ); - -#ifdef GC_OPERATOR_NEW_ARRAY -    inline void* operator new[]( size_t size ); -    inline void* operator new[]( size_t size, GCPlacement gcp ); -    inline void* operator new[]( size_t size, void *p ); -    inline void operator delete[]( void* obj ); -    inline void gc::operator delete[]( void*, void* ); -#endif /* GC_OPERATOR_NEW_ARRAY */ -    };     -    /* -    Instances of classes derived from "gc" will be allocated in the  -    collected heap by default, unless an explicit NoGC placement is -    specified. */ - -class gc_cleanup: virtual public gc {public: -    inline gc_cleanup(); -    inline virtual ~gc_cleanup(); -private: -    inline static void _cdecl cleanup( void* obj, void* clientData );}; -    /* -    Instances of classes derived from "gc_cleanup" will be allocated -    in the collected heap by default.  When the collector discovers an -    inaccessible object derived from "gc_cleanup" or containing a -    member derived from "gc_cleanup", its destructors will be -    invoked. */ - -extern "C" {typedef void (*GCCleanUpFunc)( void* obj, void* clientData );} - -#ifdef _MSC_VER -  // Disable warning that "no matching operator delete found; memory will -  // not be freed if initialization throws an exception" -# pragma warning(disable:4291) -#endif - -inline void* operator new(  -    size_t size,  -    GCPlacement gcp, -    GCCleanUpFunc cleanup = 0, -    void* clientData = 0 ); -    /* -    Allocates a collectable or uncollected object, according to the -    value of "gcp". - -    For collectable objects, if "cleanup" is non-null, then when the -    allocated object "obj" becomes inaccessible, the collector will -    invoke the function "cleanup( obj, clientData )" but will not -    invoke the object's destructors.  It is an error to explicitly -    delete an object allocated with a non-null "cleanup". - -    It is an error to specify a non-null "cleanup" with NoGC or for -    classes derived from "gc_cleanup" or containing members derived -    from "gc_cleanup". */ - - -#ifdef _MSC_VER - /** This ensures that the system default operator new[] doesn't get -  *  undefined, which is what seems to happen on VC++ 6 for some reason -  *  if we define a multi-argument operator new[]. -  *  There seems to be really redirect new in this environment without -  *  including this everywhere.  -  */ - void *operator new[]( size_t size ); -  - void operator delete[](void* obj); - - void* operator new( size_t size); - - void operator delete(void* obj); - - // This new operator is used by VC++ in case of Debug builds ! - void* operator new(  size_t size, -		      int ,//nBlockUse, -		      const char * szFileName, -		      int nLine ); -#endif /* _MSC_VER */ - - -#ifdef GC_OPERATOR_NEW_ARRAY - -inline void* operator new[]( -    size_t size,  -    GCPlacement gcp, -    GCCleanUpFunc cleanup = 0, -    void* clientData = 0 ); -    /* -    The operator new for arrays, identical to the above. */ - -#endif /* GC_OPERATOR_NEW_ARRAY */ - -/**************************************************************************** - -Inline implementation - -****************************************************************************/ - -inline void* gc::operator new( size_t size ) { -    return GC_MALLOC( size );} -     -inline void* gc::operator new( size_t size, GCPlacement gcp ) { -    if (gcp == UseGC)  -        return GC_MALLOC( size ); -    else if (gcp == PointerFreeGC) -	return GC_MALLOC_ATOMIC( size ); -    else -        return GC_MALLOC_UNCOLLECTABLE( size );} - -inline void* gc::operator new( size_t size, void *p ) { -    return p;} - -inline void gc::operator delete( void* obj ) { -    GC_FREE( obj );} -     -inline void gc::operator delete( void*, void* ) {} - -#ifdef GC_OPERATOR_NEW_ARRAY - -inline void* gc::operator new[]( size_t size ) { -    return gc::operator new( size );} -     -inline void* gc::operator new[]( size_t size, GCPlacement gcp ) { -    return gc::operator new( size, gcp );} - -inline void* gc::operator new[]( size_t size, void *p ) { -    return p;} - -inline void gc::operator delete[]( void* obj ) { -    gc::operator delete( obj );} - -inline void gc::operator delete[]( void*, void* ) {} -     -#endif /* GC_OPERATOR_NEW_ARRAY */ - - -inline gc_cleanup::~gc_cleanup() { -    GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );} - -inline void gc_cleanup::cleanup( void* obj, void* displ ) { -    ((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();} - -inline gc_cleanup::gc_cleanup() { -    GC_finalization_proc oldProc; -    void* oldData; -    void* base = GC_base( (void *) this ); -    if (0 != base)  { -      // 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 - (char*) base),  -        &oldProc, &oldData ); -      if (0 != oldProc) { -        GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );}}} - -inline void* operator new(  -    size_t size,  -    GCPlacement gcp, -    GCCleanUpFunc cleanup, -    void* clientData ) -{ -    void* obj; - -    if (gcp == UseGC) { -        obj = GC_MALLOC( size ); -        if (cleanup != 0)  -            GC_REGISTER_FINALIZER_IGNORE_SELF(  -                obj, cleanup, clientData, 0, 0 );} -    else if (gcp == PointerFreeGC) { -        obj = GC_MALLOC_ATOMIC( size );} -    else { -        obj = GC_MALLOC_UNCOLLECTABLE( size );}; -    return obj;} -         - -#ifdef GC_OPERATOR_NEW_ARRAY - -inline void* operator new[](  -    size_t size,  -    GCPlacement gcp, -    GCCleanUpFunc cleanup, -    void* clientData ) -{ -    return ::operator new( size, gcp, cleanup, clientData );} - -#endif /* GC_OPERATOR_NEW_ARRAY */ - - -#endif /* GC_CPP_H */ - diff --git a/gc/include/gc_gcj.h b/gc/include/gc_gcj.h deleted file mode 100644 index 5e932af..0000000 --- a/gc/include/gc_gcj.h +++ /dev/null @@ -1,102 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved. - * Copyright 1996-1999 by Silicon Graphics.  All rights reserved. - * Copyright 1999 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 file assumes the collector has been compiled with GC_GCJ_SUPPORT */ -/* and that an ANSI C compiler is available.				 */ - -/* - * We allocate objects whose first word contains a pointer to a struct - * describing the object type.  This struct contains a garbage collector mark - * descriptor at offset MARK_DESCR_OFFSET.  Alternatively, the objects - * may be marked by the mark procedure passed to GC_init_gcj_malloc. - */ - -#ifndef GC_GCJ_H - -#define GC_GCJ_H - -#ifndef MARK_DESCR_OFFSET -#  define MARK_DESCR_OFFSET	sizeof(word) -#endif -	/* Gcj keeps GC descriptor as second word of vtable.	This	*/ -	/* probably needs to be adjusted for other clients.		*/ -	/* We currently assume that this offset is such that:		*/ -	/*	- all objects of this kind are large enough to have	*/ -	/*	  a value at that offset, and				*/ -	/* 	- it is not zero.					*/ -	/* These assumptions allow objects on the free list to be 	*/ -	/* marked normally.						*/ - -#ifndef _GC_H -#   include "gc.h" -#endif - -/* The following allocators signal an out of memory condition with	*/ -/* return GC_oom_fn(bytes);						*/ - -/* The following function must be called before the gcj allocators	*/ -/* can be invoked.							*/ -/* mp_index and mp are the index and mark_proc (see gc_mark.h)		*/ -/* respectively for the allocated objects.  Mark_proc will be 		*/ -/* used to build the descriptor for objects allocated through the	*/ -/* debugging interface.  The mark_proc will be invoked on all such 	*/ -/* objects with an "environment" value of 1.  The client may chose	*/ -/* to use the same mark_proc for some of its generated mark descriptors.*/ -/* In that case, it should use a different "environment" value to	*/ -/* detect the presence or absence of the debug header.			*/ -/* Mp is really of type mark_proc, as defined in gc_mark.h.  We don't 	*/ -/* want to include that here for namespace pollution reasons.		*/ -extern void GC_init_gcj_malloc(int mp_index, void * /* really mark_proc */mp); - -/* Allocate an object, clear it, and store the pointer to the	*/ -/* type structure (vtable in gcj).				*/ -/* This adds a byte at the end of the object if GC_malloc would.*/ -extern void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr); -/* The debug versions allocate such that the specified mark_proc	*/ -/* is always invoked.							*/ -extern void * GC_debug_gcj_malloc(size_t lb, -				  void * ptr_to_struct_containing_descr, -				  GC_EXTRA_PARAMS); - -/* Similar to the above, but the size is in words, and we don't	*/ -/* adjust it.  The size is assumed to be such that it can be 	*/ -/* allocated as a small object.					*/ -/* Unless it is known that the collector is not configured 	*/ -/* with USE_MARK_BYTES and unless it is known that the object	*/ -/* has weak alignment requirements, lw must be even.		*/ -extern void * GC_gcj_fast_malloc(size_t lw, -				 void * ptr_to_struct_containing_descr); -extern void * GC_debug_gcj_fast_malloc(size_t lw, -				 void * ptr_to_struct_containing_descr, -				 GC_EXTRA_PARAMS); - -/* Similar to GC_gcj_malloc, but assumes that a pointer to near the	*/ -/* beginning of the resulting object is always maintained.		*/ -extern void * GC_gcj_malloc_ignore_off_page(size_t lb, -				void * ptr_to_struct_containing_descr); - -# ifdef GC_DEBUG -#   define GC_GCJ_MALLOC(s,d) GC_debug_gcj_malloc(s,d,GC_EXTRAS) -#   define GC_GCJ_FAST_MALLOC(s,d) GC_debug_gcj_fast_malloc(s,d,GC_EXTRAS) -#   define GC_GCJ_MALLOC_IGNORE_OFF_PAGE(s,d) GC_debug_gcj_malloc(s,d,GC_EXTRAS) -# else -#   define GC_GCJ_MALLOC(s,d) GC_gcj_malloc(s,d) -#   define GC_GCJ_FAST_MALLOC(s,d) GC_gcj_fast_malloc(s,d) -#   define GC_GCJ_MALLOC_IGNORE_OFF_PAGE(s,d) \ -	GC_gcj_malloc_ignore_off_page(s,d) -# endif - -#endif /* GC_GCJ_H */ diff --git a/gc/include/gc_inl.h b/gc/include/gc_inl.h deleted file mode 100644 index c535cfd..0000000 --- a/gc/include/gc_inl.h +++ /dev/null @@ -1,107 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1995 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. - */ -/* Boehm, October 3, 1995 2:07 pm PDT */ -  -# ifndef GC_PRIVATE_H -#   include "private/gc_priv.h" -# endif - -/* USE OF THIS FILE IS NOT RECOMMENDED unless GC_all_interior_pointers	*/ -/* is always set, or the collector has been built with			*/ -/* -DDONT_ADD_BYTE_AT_END, or the specified size includes a pointerfree	*/ -/* word at the end.  In the standard collector configuration,		*/ -/* the final word of each object may not be scanned.			*/ -/* This iinterface is most useful for compilers that generate C.	*/ -/* Manual use is hereby discouraged.					*/ - -/* Allocate n words (NOT BYTES).  X is made to point to the result.	*/ -/* It is assumed that n < MAXOBJSZ, and					*/ -/* that n > 0.  On machines requiring double word alignment of some	*/ -/* data, we also assume that n is 1 or even.				*/ -/* If the collector is built with -DUSE_MARK_BYTES or -DPARALLEL_MARK,	*/ -/* the n = 1 case is also disallowed.					*/ -/* Effectively this means that portable code should make sure n is even.*/ -/* This bypasses the							*/ -/* MERGE_SIZES mechanism.  In order to minimize the number of distinct	*/ -/* free lists that are maintained, the caller should ensure that a 	*/ -/* small number of distinct values of n are used.  (The MERGE_SIZES	*/ -/* mechanism normally does this by ensuring that only the leading three	*/ -/* bits of n may be nonzero.  See misc.c for details.)  We really 	*/ -/* recommend this only in cases in which n is a constant, and no	*/ -/* locking is required.							*/ -/* In that case it may allow the compiler to perform substantial	*/ -/* additional optimizations.						*/ -# define GC_MALLOC_WORDS(result,n) \ -{	\ -    register ptr_t op;	\ -    register ptr_t *opp;	\ -    DCL_LOCK_STATE;	\ -	\ -    opp = &(GC_objfreelist[n]);	\ -    FASTLOCK();	\ -    if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {	\ -        FASTUNLOCK();	\ -        (result) = GC_generic_malloc_words_small((n), NORMAL);	\ -    } else { 	\ -        *opp = obj_link(op);	\ -        obj_link(op) = 0;	\ -        GC_words_allocd += (n);	\ -        FASTUNLOCK();	\ -        (result) = (GC_PTR) op;	\ -    }	\ -} - - -/* The same for atomic objects:	*/ -# define GC_MALLOC_ATOMIC_WORDS(result,n) \ -{	\ -    register ptr_t op;	\ -    register ptr_t *opp;	\ -    DCL_LOCK_STATE;	\ -	\ -    opp = &(GC_aobjfreelist[n]);	\ -    FASTLOCK();	\ -    if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {	\ -        FASTUNLOCK();	\ -        (result) = GC_generic_malloc_words_small((n), PTRFREE);	\ -    } else { 	\ -        *opp = obj_link(op);	\ -        obj_link(op) = 0;	\ -        GC_words_allocd += (n);	\ -        FASTUNLOCK();	\ -        (result) = (GC_PTR) op;	\ -    }	\ -} - -/* And once more for two word initialized objects: */ -# define GC_CONS(result, first, second) \ -{	\ -    register ptr_t op;	\ -    register ptr_t *opp;	\ -    DCL_LOCK_STATE;	\ -	\ -    opp = &(GC_objfreelist[2]);	\ -    FASTLOCK();	\ -    if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {	\ -        FASTUNLOCK();	\ -        op = GC_generic_malloc_words_small(2, NORMAL);	\ -    } else {	\ -        *opp = obj_link(op);	\ -        GC_words_allocd += 2;	\ -        FASTUNLOCK();	\ -    } \ -    ((word *)op)[0] = (word)(first);	\ -    ((word *)op)[1] = (word)(second);	\ -    (result) = (GC_PTR) op;	\ -} diff --git a/gc/include/gc_inline.h b/gc/include/gc_inline.h deleted file mode 100644 index db62d1d..0000000 --- a/gc/include/gc_inline.h +++ /dev/null @@ -1 +0,0 @@ -# include "gc_inl.h" diff --git a/gc/include/gc_local_alloc.h b/gc/include/gc_local_alloc.h deleted file mode 100644 index 88e29e9..0000000 --- a/gc/include/gc_local_alloc.h +++ /dev/null @@ -1,88 +0,0 @@ -/*  - * 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. - */ - -/* - * Interface for thread local allocation.  Memory obtained - * this way can be used by all threads, as though it were obtained - * from an allocator like GC_malloc.  The difference is that GC_local_malloc - * counts the number of allocations of a given size from the current thread, - * and uses GC_malloc_many to perform the allocations once a threashold - * is exceeded.  Thus far less synchronization may be needed. - * Allocation of known large objects should not use this interface. - * This interface is designed primarily for fast allocation of small - * objects on multiprocessors, e.g. for a JVM running on an MP server. - * - * If this file is included with GC_GCJ_SUPPORT defined, GCJ-style - * bitmap allocation primitives will also be included. - * - * If this file is included with GC_REDIRECT_TO_LOCAL defined, then - * GC_MALLOC, GC_MALLOC_ATOMIC, and possibly GC_GCJ_MALLOC will - * be redefined to use the thread local allocatoor. - * - * The interface is available only if the collector is built with - * -DTHREAD_LOCAL_ALLOC, which is currently supported only on Linux. - * - * The debugging allocators use standard, not thread-local allocation. - * - * These routines normally require an explicit call to GC_init(), though - * that may be done from a constructor function. - */ - -#ifndef GC_LOCAL_ALLOC_H -#define GC_LOCAL_ALLOC_H - -#ifndef _GC_H -#   include "gc.h" -#endif - -#if defined(GC_GCJ_SUPPORT) && !defined(GC_GCJ_H) -#   include "gc_gcj.h" -#endif - -/* We assume ANSI C for this interface.	*/ - -GC_PTR GC_local_malloc(size_t bytes); - -GC_PTR GC_local_malloc_atomic(size_t bytes); - -#if defined(GC_GCJ_SUPPORT) -  GC_PTR GC_local_gcj_malloc(size_t bytes, -			     void * ptr_to_struct_containing_descr); -#endif - -# ifdef GC_DEBUG -#   define GC_LOCAL_MALLOC(s) GC_debug_malloc(s,GC_EXTRAS) -#   define GC_LOCAL_MALLOC_ATOMIC(s) GC_debug_malloc_atomic(s,GC_EXTRAS) -#   ifdef GC_GCJ_SUPPORT -#	define GC_LOCAL_GCJ_MALLOC(s,d) GC_debug_gcj_malloc(s,d,GC_EXTRAS) -#   endif -# else -#   define GC_LOCAL_MALLOC(s) GC_local_malloc(s) -#   define GC_LOCAL_MALLOC_ATOMIC(s) GC_local_malloc_atomic(s) -#   ifdef GC_GCJ_SUPPORT -#	define GC_LOCAL_GCJ_MALLOC(s,d) GC_local_gcj_malloc(s,d) -#   endif -# endif - -# ifdef GC_REDIRECT_TO_LOCAL -#   undef GC_MALLOC -#   define GC_MALLOC(s) GC_LOCAL_MALLOC(s) -#   undef GC_MALLOC_ATOMIC -#   define GC_MALLOC_ATOMIC(s) GC_LOCAL_MALLOC_ATOMIC(s) -#   ifdef GC_GCJ_SUPPORT -#	undef GC_GCJ_MALLOC -# 	define GC_GCJ_MALLOC(s,d) GC_LOCAL_GCJ_MALLOC(s,d) -#   endif -# endif - -#endif /* GC_LOCAL_ALLOC_H */ diff --git a/gc/include/gc_mark.h b/gc/include/gc_mark.h deleted file mode 100644 index 0856d16..0000000 --- a/gc/include/gc_mark.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. - * Copyright (c) 2001 by Hewlett-Packard Company. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose,  provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - */ - -/* - * This contains interfaces to the GC marker that are likely to be useful to - * clients that provide detailed heap layout information to the collector. - * This interface should not be used by normal C or C++ clients. - * It will be useful to runtimes for other languages. - *  - * Note that this file is not "namespace-clean", i.e. it introduces names - * not prefixed with GC_, which may collide with the client's names.  It - * should be included only in those few places that directly provide - * information to the collector. - */ -#ifndef GC_MARK_H -# define GC_MARK_H - -# ifndef GC_H -#   include "gc.h" -# 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.	*/ -/* Global variables decribing mark stack are not necessarily valid.	*/ -/* (This usually saves a few cycles by keeping things in registers.)	*/ -/* Assumed to scan about GC_PROC_BYTES on average.  If it needs to do	*/ -/* much more work than that, it should do it in smaller pieces by	*/ -/* pushing itself back on the mark stack.				*/ -/* Note that it should always do some work (defined as marking some	*/ -/* objects) before pushing more than one entry on the mark stack.	*/ -/* This is required to ensure termination in the event of mark stack	*/ -/* overflows.								*/ -/* This procedure is always called with at least one empty entry on the */ -/* mark stack.								*/ -/* Currently we require that mark procedures look for pointers in a	*/ -/* subset of the places the conservative marker would.  It must be safe	*/ -/* to invoke the normal mark procedure instead.				*/ -/* WARNING: Such a mark procedure may be invoked on an unused object    */ -/* 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 -struct GC_ms_entry; -typedef struct GC_ms_entry * (*GC_mark_proc) GC_PROTO(( -		GC_word * addr, struct GC_ms_entry * mark_stack_ptr, -		struct GC_ms_entry * mark_stack_limit, GC_word env)); - -# define GC_LOG_MAX_MARK_PROCS 6 -# define GC_MAX_MARK_PROCS (1 << GC_LOG_MAX_MARK_PROCS) - -/* In a few cases it's necessary to assign statically known indices to	*/ -/* certain mark procs.  Thus we reserve a few for well known clients.	*/ -/* (This is necessary if mark descriptors are compiler generated.)	*/ -#define GC_RESERVED_MARK_PROCS 8 -#   define GC_GCJ_RESERVED_MARK_PROC_INDEX 0 - -/* Object descriptors on mark stack or in objects.  Low order two	*/ -/* bits are tags distinguishing among the following 4 possibilities	*/ -/* for the high order 30 bits.						*/ -#define GC_DS_TAG_BITS 2 -#define GC_DS_TAGS   ((1 << GC_DS_TAG_BITS) - 1) -#define GC_DS_LENGTH 0	/* The entire word is a length in bytes that	*/ -			/* must be a multiple of 4.			*/ -#define GC_DS_BITMAP 1	/* 30 (62) bits are a bitmap describing pointer	*/ -			/* fields.  The msb is 1 iff the first word	*/ -			/* is a pointer.				*/ -			/* (This unconventional ordering sometimes	*/ -			/* makes the marker slightly faster.)		*/ -			/* Zeroes indicate definite nonpointers.  Ones	*/ -			/* indicate possible pointers.			*/ -			/* Only usable if pointers are word aligned.	*/ -#define GC_DS_PROC   2 -			/* The objects referenced by this object can be */ -			/* pushed on the mark stack by invoking		*/ -			/* PROC(descr).  ENV(descr) is passed as the	*/ -			/* last argument.				*/ -#   define GC_MAKE_PROC(proc_index, env) \ -	    (((((env) << GC_LOG_MAX_MARK_PROCS) \ -	       | (proc_index)) << GC_DS_TAG_BITS) | GC_DS_PROC) -#define GC_DS_PER_OBJECT 3  /* The real descriptor is at the		*/ -			/* byte displacement from the beginning of the	*/ -			/* object given by descr & ~DS_TAGS		*/ -			/* If the descriptor is negative, the real	*/ -			/* descriptor is at (*<object_start>) -		*/ -			/* (descr & ~DS_TAGS) - GC_INDIR_PER_OBJ_BIAS	*/ -			/* The latter alternative can be used if each	*/ -			/* object contains a type descriptor in the	*/ -			/* first word.					*/ -			/* Note that in multithreaded environments	*/ -			/* per object descriptors maust be located in	*/ -			/* either the first two or last two words of	*/ -			/* the object, since only those are guaranteed	*/ -			/* to be cleared while the allocation lock is	*/ -			/* held.					*/ -#define GC_INDIR_PER_OBJ_BIAS 0x10 -			 -extern GC_PTR GC_least_plausible_heap_addr; -extern GC_PTR GC_greatest_plausible_heap_addr; -			/* Bounds on the heap.  Guaranteed valid	*/ -			/* Likely to include future heap expansion.	*/ - -/* Handle nested references in a custom mark procedure.			*/ -/* Check if obj is a valid object. If so, ensure that it is marked.	*/ -/* If it was not previously marked, push its contents onto the mark 	*/ -/* stack for future scanning.  The object will then be scanned using	*/ -/* its mark descriptor.  						*/ -/* Returns the new mark stack pointer.					*/ -/* Handles mark stack overflows correctly.				*/ -/* Since this marks first, it makes progress even if there are mark	*/ -/* stack overflows.							*/ -/* Src is the address of the pointer to obj, which is used only		*/ -/* for back pointer-based heap debugging.				*/ -/* It is strongly recommended that most objects be handled without mark	*/ -/* procedures, e.g. with bitmap descriptors, and that mark procedures	*/ -/* be reserved for exceptional cases.  That will ensure that 		*/ -/* performance of this call is not extremely performance critical.	*/ -/* (Otherwise we would need to inline GC_mark_and_push completely,	*/ -/* which would tie the client code to a fixed colllector version.)	*/ -struct GC_ms_entry *GC_mark_and_push -		GC_PROTO((GC_PTR obj, -			  struct GC_ms_entry * mark_stack_ptr, -		          struct GC_ms_entry * mark_stack_limit, GC_PTR *src)); - -#define GC_MARK_AND_PUSH(obj, msp, lim, src) \ -	(((GC_word)obj >= (GC_word)GC_least_plausible_heap_addr && \ -	  (GC_word)obj <= (GC_word)GC_greatest_plausible_heap_addr)? \ -	  GC_mark_and_push(obj, msp, lim, src) : \ -	  msp) - -#endif  /* GC_MARK_H */ - diff --git a/gc/include/gc_pthread_redirects.h b/gc/include/gc_pthread_redirects.h deleted file mode 100644 index 47284fb..0000000 --- a/gc/include/gc_pthread_redirects.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Our pthread support normally needs to intercept a number of thread	*/ -/* calls.  We arrange to do that here, if appropriate.			*/ - -#ifndef GC_PTHREAD_REDIRECTS_H - -#define GC_PTHREAD_REDIRECTS_H - -#if defined(GC_SOLARIS_THREADS) -/* We need to intercept calls to many of the threads primitives, so 	*/ -/* that we can locate thread stacks and stop the world.			*/ -/* Note also that the collector cannot see thread specific data.	*/ -/* Thread specific data should generally consist of pointers to		*/ -/* uncollectable objects (allocated with GC_malloc_uncollectable,	*/ -/* not the system malloc), which are deallocated using the destructor	*/ -/* facility in thr_keycreate.  Alternatively, keep a redundant pointer	*/ -/* to thread specific data on the thread stack.			        */ -# include <thread.h> -  int GC_thr_create(void *stack_base, size_t stack_size, -                    void *(*start_routine)(void *), void *arg, long flags, -                    thread_t *new_thread); -  int GC_thr_join(thread_t wait_for, thread_t *departed, void **status); -  int GC_thr_suspend(thread_t target_thread); -  int GC_thr_continue(thread_t target_thread); -  void * GC_dlopen(const char *path, int mode); -# define thr_create GC_thr_create -# define thr_join GC_thr_join -# define thr_suspend GC_thr_suspend -# define thr_continue GC_thr_continue -#endif /* GC_SOLARIS_THREADS */ - -#if defined(GC_SOLARIS_PTHREADS) -# include <pthread.h> -# include <signal.h> -  extern int GC_pthread_create(pthread_t *new_thread, -    			         const pthread_attr_t *attr, -          			 void * (*thread_execp)(void *), void *arg); -  extern int GC_pthread_join(pthread_t wait_for, void **status); -# define pthread_join GC_pthread_join -# define pthread_create GC_pthread_create -#endif - -#if defined(GC_SOLARIS_PTHREADS) || defined(GC_SOLARIS_THREADS) -# define dlopen GC_dlopen -#endif /* SOLARIS_THREADS || SOLARIS_PTHREADS */ - - -#if !defined(GC_USE_LD_WRAP) && defined(GC_PTHREADS) && !defined(GC_SOLARIS_PTHREADS) -/* We treat these similarly. */ -# include <pthread.h> -# include <signal.h> - -  int GC_pthread_create(pthread_t *new_thread, -                        const pthread_attr_t *attr, -		        void *(*start_routine)(void *), void *arg); -  int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset); -  int GC_pthread_join(pthread_t thread, void **retval); -  int GC_pthread_detach(pthread_t thread); - -# define pthread_create GC_pthread_create -# define pthread_sigmask GC_pthread_sigmask -# define pthread_join GC_pthread_join -# define pthread_detach GC_pthread_detach -# define dlopen GC_dlopen - -#endif /* GC_xxxxx_THREADS */ - -#endif /* GC_PTHREAD_REDIRECTS_H */ diff --git a/gc/include/gc_typed.h b/gc/include/gc_typed.h deleted file mode 100644 index 2e0598f..0000000 --- a/gc/include/gc_typed.h +++ /dev/null @@ -1,93 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. - * Copyright 1996 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. - */ -/* - * Some simple primitives for allocation with explicit type information. - * Facilities for dynamic type inference may be added later. - * Should be used only for extremely performance critical applications, - * or if conservative collector leakage is otherwise a problem (unlikely). - * Note that this is implemented completely separately from the rest - * of the collector, and is not linked in unless referenced. - * This does not currently support GC_DEBUG in any interesting way. - */ -/* Boehm, May 19, 1994 2:13 pm PDT */ - -#ifndef _GC_TYPED_H -# define _GC_TYPED_H -# ifndef _GC_H -#   include "gc.h" -# endif - -typedef GC_word * GC_bitmap; -	/* The least significant bit of the first word is one if	*/ -	/* the first word in the object may be a pointer.		*/ -	 -# define GC_get_bit(bm, index) \ -		(((bm)[divWORDSZ(index)] >> modWORDSZ(index)) & 1) -# define GC_set_bit(bm, index) \ -		(bm)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index) - -typedef GC_word GC_descr; - -GC_API GC_descr GC_make_descriptor GC_PROTO((GC_bitmap bm, size_t len)); -		/* Return a type descriptor for the object whose layout	*/ -		/* is described by the argument.			*/ -		/* The least significant bit of the first word is one	*/ -		/* if the first word in the object may be a pointer.	*/ -		/* The second argument specifies the number of		*/ -		/* meaningful bits in the bitmap.  The actual object 	*/ -		/* may be larger (but not smaller).  Any additional	*/ -		/* words in the object are assumed not to contain 	*/ -		/* pointers.						*/ -		/* Returns a conservative approximation in the		*/ -		/* (unlikely) case of insufficient memory to build	*/ -		/* the descriptor.  Calls to GC_make_descriptor		*/ -		/* may consume some amount of a finite resource.  This	*/ -		/* is intended to be called once per type, not once	*/ -		/* per allocation.					*/ - -GC_API GC_PTR GC_malloc_explicitly_typed -			GC_PROTO((size_t size_in_bytes, GC_descr d)); -		/* Allocate an object whose layout is described by d.	*/ -		/* The resulting object MAY NOT BE PASSED TO REALLOC.	*/ -		/* The returned object is cleared.			*/ - -GC_API GC_PTR GC_malloc_explicitly_typed_ignore_off_page -                        GC_PROTO((size_t size_in_bytes, GC_descr d)); -		 -GC_API GC_PTR GC_calloc_explicitly_typed -			GC_PROTO((size_t nelements, -  				  size_t element_size_in_bytes, -  				  GC_descr d)); -  	/* Allocate an array of nelements elements, each of the	*/ -  	/* given size, and with the given descriptor.		*/ -  	/* The elemnt size must be a multiple of the byte	*/ -  	/* alignment required for pointers.  E.g. on a 32-bit	*/ -  	/* machine with 16-bit aligned pointers, size_in_bytes	*/ -  	/* must be a multiple of 2.				*/ -	/* Returned object is cleared.				*/ - -#ifdef GC_DEBUG -#   define GC_MALLOC_EXPLICTLY_TYPED(bytes, d) GC_MALLOC(bytes) -#   define GC_CALLOC_EXPLICTLY_TYPED(n, bytes, d) GC_MALLOC(n*bytes) -#else -#  define GC_MALLOC_EXPLICTLY_TYPED(bytes, d) \ -	GC_malloc_explicitly_typed(bytes, d) -#  define GC_CALLOC_EXPLICTLY_TYPED(n, bytes, d) \ -	GC_calloc_explicitly_typed(n, bytes, d) -#endif /* !GC_DEBUG */ - - -#endif /* _GC_TYPED_H */ - diff --git a/gc/include/javaxfc.h b/gc/include/javaxfc.h deleted file mode 100644 index 880020c..0000000 --- a/gc/include/javaxfc.h +++ /dev/null @@ -1,41 +0,0 @@ -# ifndef GC_H -#   include "gc.h" -# endif - -/* - * Invoke all remaining finalizers that haven't yet been run. - * This is needed for strict compliance with the Java standard,  - * which can make the runtime guarantee that all finalizers are run. - * This is problematic for several reasons: - * 1) It means that finalizers, and all methods calle by them, - *    must be prepared to deal with objects that have been finalized in - *    spite of the fact that they are still referenced by statically - *    allocated pointer variables. - * 1) It may mean that we get stuck in an infinite loop running - *    finalizers which create new finalizable objects, though that's - *    probably unlikely. - * Thus this is not recommended for general use. - */ -void GC_finalize_all(); - -/* - * A version of GC_register_finalizer that allows the object to be - * finalized before the objects it references.  This is again error - * prone, in that it makes it easy to accidentally reference finalized - * objects.  Again, recommended only for JVM implementors. - */ -void GC_register_finalizer_no_order(GC_PTR obj, -			       GC_finalization_proc fn, GC_PTR cd, -			       GC_finalization_proc *ofn, GC_PTR * ocd); - -void GC_debug_register_finalizer_no_order(GC_PTR obj, -			       GC_finalization_proc fn, GC_PTR cd, -			       GC_finalization_proc *ofn, GC_PTR * ocd); - -#ifdef GC_DEBUG -#   define GC_REGISTER_FINALIZER(p, f, d, of, od) \ -	GC_debug_register_finalizer_no_order(p, f, d, of, od) -#else -#   define GC_REGISTER_FINALIZER(p, f, d, of, od) \ -	GC_register_finalizer_no_order(p, f, d, of, od) -#endif diff --git a/gc/include/leak_detector.h b/gc/include/leak_detector.h deleted file mode 100644 index 0674ab4..0000000 --- a/gc/include/leak_detector.h +++ /dev/null @@ -1,7 +0,0 @@ -#define GC_DEBUG -#include "gc.h" -#define malloc(n) GC_MALLOC(n) -#define calloc(m,n) GC_MALLOC((m)*(n)) -#define free(p) GC_FREE(p) -#define realloc(p,n) GC_REALLOC((p),(n)) -#define CHECK_LEAKS() GC_gcollect() diff --git a/gc/include/new_gc_alloc.h b/gc/include/new_gc_alloc.h deleted file mode 100644 index aad9446..0000000 --- a/gc/include/new_gc_alloc.h +++ /dev/null @@ -1,472 +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_alloc.h for SGI STL versions > 3.0 -// Unlike earlier versions, it supplements the standard "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 -DATOMIC_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.) -// -// This code assumes that the collector itself has been compiled with a -// compiler that defines __STDC__ . -// - -#ifndef GC_ALLOC_H - -#include "gc.h" - -#if (__GNUC__ < 3) -# include <stack>  // A more portable way to get stl_alloc.h . -#else -# include <bits/stl_alloc.h> -# ifndef __STL_BEGIN_NAMESPACE -# define __STL_BEGIN_NAMESPACE namespace std { -# define __STL_END_NAMESPACE }; -# endif -#ifndef __STL_USE_STD_ALLOCATORS -#define __STL_USE_STD_ALLOCATORS -#endif -#endif - - -#define GC_ALLOC_H - -#include <stddef.h> -#include <string.h> - -// The following need to match collector data structures. -// We can't include gc_priv.h, since that pulls in way too much stuff. -// This should eventually be factored out into another include file. - -extern "C" { -    extern void ** const GC_objfreelist_ptr; -    extern void ** const GC_aobjfreelist_ptr; -    extern void ** const GC_uobjfreelist_ptr; -    extern void ** const GC_auobjfreelist_ptr; - -    extern void GC_incr_words_allocd(size_t words); -    extern void GC_incr_mem_freed(size_t words); - -    extern char * GC_generic_malloc_words_small(size_t word, int kind); -} - -// 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_bytes_per_word = sizeof(char *) }; - -enum { GC_byte_alignment = 8 }; - -enum { GC_word_alignment = GC_byte_alignment/GC_bytes_per_word }; - -inline void * &GC_obj_link(void * p) -{   return *(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_words_recently_allocd; - -  // Same for uncollectable mmory.  Not yet reflected in either -  // GC_words_recently_allocd or GC_non_gc_bytes. -  static size_t GC_uncollectable_words_recently_allocd; - -  // Similar counter for explicitly deallocated memory. -  static size_t GC_mem_recently_freed; - -  // Again for uncollectable memory. -  static size_t GC_uncollectable_mem_recently_freed; - -  static void * GC_out_of_line_malloc(size_t nwords, int kind); -}; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_words_recently_allocd = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_uncollectable_words_recently_allocd = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_mem_recently_freed = 0; - -template <int dummy> -size_t GC_aux_template<dummy>::GC_uncollectable_mem_recently_freed = 0; - -template <int dummy> -void * GC_aux_template<dummy>::GC_out_of_line_malloc(size_t nwords, int kind) -{ -    GC_words_recently_allocd += GC_uncollectable_words_recently_allocd; -    GC_non_gc_bytes += -                GC_bytes_per_word * GC_uncollectable_words_recently_allocd; -    GC_uncollectable_words_recently_allocd = 0; - -    GC_mem_recently_freed += GC_uncollectable_mem_recently_freed; -    GC_non_gc_bytes -=  -                GC_bytes_per_word * GC_uncollectable_mem_recently_freed; -    GC_uncollectable_mem_recently_freed = 0; - -    GC_incr_words_allocd(GC_words_recently_allocd); -    GC_words_recently_allocd = 0; - -    GC_incr_mem_freed(GC_mem_recently_freed); -    GC_mem_recently_freed = 0; - -    return GC_generic_malloc_words_small(nwords, kind); -} - -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 noop, 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) return GC_malloc(n); -	    flh = GC_objfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_NORMAL); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_words_recently_allocd += nwords; -	    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) return GC_malloc_atomic(n); -	    flh = GC_aobjfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_PTRFREE); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_words_recently_allocd += nwords; -	    return op; -        } -	static void deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes)  { -		GC_free(p); -	    } else { -	        flh = GC_objfreelist_ptr + nwords; -	        GC_obj_link(p) = *flh; -		memset((char *)p + GC_bytes_per_word, 0, -		       GC_bytes_per_word * (nwords - 1)); -	        *flh = p; -	        GC_aux::GC_mem_recently_freed += nwords; -	    } -	} -	static void ptr_free_deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes) { -		GC_free(p); -	    } else { -	    	flh = GC_aobjfreelist_ptr + nwords; -	    	GC_obj_link(p) = *flh; -	    	*flh = p; -	    	GC_aux::GC_mem_recently_freed += nwords; -	    } -	} -}; - -typedef single_client_gc_alloc_template<0> single_client_gc_alloc; - -// Once more, for uncollectable 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) return GC_malloc_uncollectable(n); -	    flh = GC_uobjfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_UNCOLLECTABLE); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_uncollectable_words_recently_allocd += nwords; -	    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) return GC_malloc_atomic_uncollectable(n); -	    flh = GC_auobjfreelist_ptr + nwords; -	    if (0 == (op = *flh)) { -		return GC_aux::GC_out_of_line_malloc(nwords, GC_AUNCOLLECTABLE); -	    } -	    *flh = GC_obj_link(op); -	    GC_aux::GC_uncollectable_words_recently_allocd += nwords; -	    return op; -        } -	static void deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up_uncollectable(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes)  { -		GC_free(p); -	    } else { -	        flh = GC_uobjfreelist_ptr + nwords; -	        GC_obj_link(p) = *flh; -	        *flh = p; -	        GC_aux::GC_uncollectable_mem_recently_freed += nwords; -	    } -	} -	static void ptr_free_deallocate(void *p, size_t n) -	{ -            size_t nwords = GC_round_up_uncollectable(n); -            void ** flh; -	    -	    if (n > GC_max_fast_bytes) { -		GC_free(p); -	    } else { -	    	flh = GC_auobjfreelist_ptr + nwords; -	    	GC_obj_link(p) = *flh; -	    	*flh = p; -	    	GC_aux::GC_uncollectable_mem_recently_freed += nwords; -	    } -	} -}; - -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) { return GC_malloc(n); } -     	static void * ptr_free_allocate(size_t n) -		{ return GC_malloc_atomic(n); } -	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) { return GC_malloc_uncollectable(n); } -     	static void * ptr_free_allocate(size_t n) -		{ return GC_malloc_atomic_uncollectable(n); } -	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 pointerfree 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++. - -# define __GC_SPECIALIZE(T,alloc) \ -class simple_alloc<T, alloc> { \ -public: \ -    static T *allocate(size_t n) \ -	{ return 0 == n? 0 : \ -			 (T*) alloc::ptr_free_allocate(n * sizeof (T)); } \ -    static T *allocate(void) \ -	{ return (T*) alloc::ptr_free_allocate(sizeof (T)); } \ -    static void deallocate(T *p, size_t n) \ -	{ if (0 != n) alloc::ptr_free_deallocate(p, 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 _T> -struct _Alloc_traits<_T, gc_alloc > -{ -  static const bool _S_instanceless = true; -  typedef simple_alloc<_T, gc_alloc > _Alloc_type; -  typedef __allocator<_T, 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 _T> -struct _Alloc_traits<_T, single_client_gc_alloc > -{ -  static const bool _S_instanceless = true; -  typedef simple_alloc<_T, single_client_gc_alloc > _Alloc_type; -  typedef __allocator<_T, 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 _T> -struct _Alloc_traits<_T, traceable_alloc > -{ -  static const bool _S_instanceless = true; -  typedef simple_alloc<_T, traceable_alloc > _Alloc_type; -  typedef __allocator<_T, 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 _T> -struct _Alloc_traits<_T, single_client_traceable_alloc > -{ -  static const bool _S_instanceless = true; -  typedef simple_alloc<_T, single_client_traceable_alloc > _Alloc_type; -  typedef __allocator<_T, 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_ALLOC_H */ diff --git a/gc/include/private/cord_pos.h b/gc/include/private/cord_pos.h deleted file mode 100644 index d2b24bb..0000000 --- a/gc/include/private/cord_pos.h +++ /dev/null @@ -1,118 +0,0 @@ -/*  - * 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. - */ -/* Boehm, May 19, 1994 2:23 pm PDT */ -# ifndef CORD_POSITION_H - -/* The representation of CORD_position.  This is private to the	*/ -/* implementation, but the size is known to clients.  Also	*/ -/* the implementation of some exported macros relies on it.	*/ -/* Don't use anything defined here and not in cord.h.		*/ - -# define MAX_DEPTH 48 -	/* The maximum depth of a balanced cord + 1.		*/ -	/* We don't let cords get deeper than MAX_DEPTH.	*/ - -struct CORD_pe { -    CORD pe_cord; -    size_t pe_start_pos; -}; - -/* A structure describing an entry on the path from the root 	*/ -/* to current position.						*/ -typedef struct CORD_Pos { -    size_t cur_pos; -    int path_len; -#	define CORD_POS_INVALID (0x55555555) -		/* path_len == INVALID <==> position invalid */ -    const char *cur_leaf;	/* Current leaf, if it is a string.	*/ -    				/* If the current leaf is a function,	*/ -    				/* then this may point to function_buf	*/ -    				/* containing the next few characters.	*/ -    				/* 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	*/ -    			/* 0 if cur_leaf is invalid.	*/ -    struct CORD_pe path[MAX_DEPTH + 1]; -    	/* path[path_len] is the leaf corresponding to cur_pos	*/ -    	/* path[0].pe_cord is the cord we point to.		*/ -#   define FUNCTION_BUF_SZ 8 -    char function_buf[FUNCTION_BUF_SZ];	/* Space for next few chars	*/ -    					/* from function node.		*/ -} CORD_pos[1]; - -/* Extract the cord from a position:	*/ -CORD CORD_pos_to_cord(CORD_pos p); -	 -/* Extract the current index from a position:	*/ -size_t CORD_pos_to_index(CORD_pos p); -	 -/* Fetch the character located at the given position:	*/ -char CORD_pos_fetch(CORD_pos p); -	 -/* Initialize the position to refer to the give cord and index.	*/ -/* Note that this is the most expensive function on positions:	*/ -void CORD_set_pos(CORD_pos p, CORD x, size_t i); -	 -/* Advance the position to the next character.	*/ -/* P must be initialized and valid.		*/ -/* Invalidates p if past end:			*/ -void CORD_next(CORD_pos p); - -/* Move the position to the preceding character.	*/ -/* P must be initialized and valid.			*/ -/* Invalidates p if past beginning:			*/ -void CORD_prev(CORD_pos p); -	 -/* Is the position valid, i.e. inside the cord?		*/ -int CORD_pos_valid(CORD_pos p); - -char CORD__pos_fetch(CORD_pos); -void CORD__next(CORD_pos); -void CORD__prev(CORD_pos); - -#define CORD_pos_fetch(p)	\ -    (((p)[0].cur_end != 0)? \ -     	(p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \ -     	: CORD__pos_fetch(p)) - -#define CORD_next(p)	\ -    (((p)[0].cur_pos + 1 < (p)[0].cur_end)? \ -    	(p)[0].cur_pos++ \ -    	: (CORD__next(p), 0)) - -#define CORD_prev(p)	\ -    (((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \ -    	(p)[0].cur_pos-- \ -    	: (CORD__prev(p), 0)) - -#define CORD_pos_to_index(p) ((p)[0].cur_pos) - -#define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord) - -#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)) -	/* 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)	*/ - -#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.	*/ - -#endif diff --git a/gc/include/private/dbg_mlc.h b/gc/include/private/dbg_mlc.h deleted file mode 100644 index e2003e6..0000000 --- a/gc/include/private/dbg_mlc.h +++ /dev/null @@ -1,176 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved. - * Copyright (c) 1997 by Silicon Graphics.  All rights reserved. - * Copyright (c) 1999 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 mostly an internal header file.  Typical clients should - * not use it.  Clients that define their own object kinds with - * debugging allocators will probably want to include this, however. - * No attempt is made to keep the namespace clean.  This should not be - * included from header files that are frequently included by clients. - */ - -#ifndef _DBG_MLC_H - -#define _DBG_MLC_H - -# define I_HIDE_POINTERS -# include "gc_priv.h" -# ifdef KEEP_BACK_PTRS -#   include "gc_backptr.h" -# endif - -#ifndef HIDE_POINTER -  /* Gc.h was previously included, and hence the I_HIDE_POINTERS	*/ -  /* definition had no effect.  Repeat the gc.h definitions here to	*/ -  /* get them anyway.							*/ -    typedef GC_word GC_hidden_pointer; -#   define HIDE_POINTER(p) (~(GC_hidden_pointer)(p)) -#   define REVEAL_POINTER(p) ((GC_PTR)(HIDE_POINTER(p))) -#endif /* HIDE_POINTER */ - -# define START_FLAG ((word)0xfedcedcb) -# define END_FLAG ((word)0xbcdecdef) -	/* Stored both one past the end of user object, and one before	*/ -	/* the end of the object as seen by the allocator.		*/ - -# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) \ -     || defined(MAKE_BACK_GRAPH) -    /* Pointer "source"s that aren't real locations.	*/ -    /* Used in oh_back_ptr fields and as "source"	*/ -    /* argument to some marking functions.		*/ -#	define NOT_MARKED (ptr_t)(0) -#	define MARKED_FOR_FINALIZATION (ptr_t)(2) -	    /* Object was marked because it is finalizable.	*/ -#	define MARKED_FROM_REGISTER (ptr_t)(4) -	    /* Object was marked from a rgister.  Hence the	*/ -	    /* source of the reference doesn't have an address.	*/ -# endif /* KEEP_BACK_PTRS || PRINT_BLACK_LIST */ - -/* Object header */ -typedef struct { -#   if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) -	/* We potentially keep two different kinds of back 	*/ -	/* pointers.  KEEP_BACK_PTRS stores a single back 	*/ -	/* pointer in each reachable object to allow reporting	*/ -	/* of why an object was retained.  MAKE_BACK_GRAPH	*/ -	/* builds a graph containing the inverse of all 	*/ -	/* "points-to" edges including those involving 		*/ -	/* objects that have just become unreachable. This	*/ -	/* allows detection of growing chains of unreachable	*/ -	/* objects.  It may be possible to eventually combine	*/ -	/* both, but for now we keep them separate.  Both	*/ -	/* kinds of back pointers are hidden using the 		*/ -	/* following macros.  In both cases, the plain version	*/ -	/* is constrained to have an least significant bit of 1,*/ -	/* to allow it to be distinguished from a free list 	*/ -	/* link.  This means the plain version must have an	*/ -	/* lsb of 0.						*/ -	/* Note that blocks dropped by black-listing will	*/ -	/* also have the lsb clear once debugging has		*/ -	/* started.						*/ -	/* We're careful never to overwrite a value with lsb 0.	*/ -#       if ALIGNMENT == 1 -	  /* Fudge back pointer to be even.  */ -#	  define HIDE_BACK_PTR(p) HIDE_POINTER(~1 & (GC_word)(p)) -#	else -#	  define HIDE_BACK_PTR(p) HIDE_POINTER(p) -#	endif -	 -#       ifdef KEEP_BACK_PTRS -	  GC_hidden_pointer oh_back_ptr; -#	endif -#	ifdef MAKE_BACK_GRAPH -	  GC_hidden_pointer oh_bg_ptr; -#	endif -#	if defined(ALIGN_DOUBLE) && \ -	    (defined(KEEP_BACK_PTRS) != defined(MAKE_BACK_GRAPH)) -	  word oh_dummy; -#	endif -#   endif -    GC_CONST char * oh_string;	/* object descriptor string	*/ -    word oh_int;		/* object descriptor integers	*/ -#   ifdef NEED_CALLINFO -      struct callinfo oh_ci[NFRAMES]; -#   endif -#   ifndef SHORT_DBG_HDRS -      word oh_sz;			/* Original malloc arg.		*/ -      word oh_sf;			/* start flag */ -#   endif /* SHORT_DBG_HDRS */ -} oh; -/* The size of the above structure is assumed not to dealign things,	*/ -/* and to be a multiple of the word length.				*/ - -#ifdef SHORT_DBG_HDRS -#   define DEBUG_BYTES (sizeof (oh)) -#   define UNCOLLECTABLE_DEBUG_BYTES DEBUG_BYTES -#else -    /* Add space for END_FLAG, but use any extra space that was already	*/ -    /* added to catch off-the-end pointers.				*/ -    /* For uncollectable objects, the extra byte is not added.		*/ -#   define UNCOLLECTABLE_DEBUG_BYTES (sizeof (oh) + sizeof (word)) -#   define DEBUG_BYTES (UNCOLLECTABLE_DEBUG_BYTES - EXTRA_BYTES) -#endif -#define USR_PTR_FROM_BASE(p) ((ptr_t)(p) + sizeof(oh)) - -/* Round bytes to words without adding extra byte at end.	*/ -#define SIMPLE_ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1) - -/* ADD_CALL_CHAIN stores a (partial) call chain into an object	*/ -/* header.  It may be called with or without the allocation 	*/ -/* lock.							*/ -/* PRINT_CALL_CHAIN prints the call chain stored in an object	*/ -/* to stderr.  It requires that we do not hold the lock.	*/ -#ifdef SAVE_CALL_CHAIN -#   define ADD_CALL_CHAIN(base, ra) GC_save_callers(((oh *)(base)) -> oh_ci) -#   define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci) -#else -# ifdef GC_ADD_CALLER -#   define ADD_CALL_CHAIN(base, ra) ((oh *)(base)) -> oh_ci[0].ci_pc = (ra) -#   define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci) -# else -#   define ADD_CALL_CHAIN(base, ra) -#   define PRINT_CALL_CHAIN(base) -# endif -#endif - -# ifdef GC_ADD_CALLER -#   define OPT_RA ra, -# else -#   define OPT_RA -# endif - - -/* Check whether object with base pointer p has debugging info	*/  -/* p is assumed to point to a legitimate object in our part	*/ -/* of the heap.							*/ -#ifdef SHORT_DBG_HDRS -# define GC_has_other_debug_info(p) TRUE -#else -  GC_bool GC_has_other_debug_info(/* p */); -#endif - -#if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH) -# define GC_HAS_DEBUG_INFO(p) \ -	((*((word *)p) & 1) && GC_has_other_debug_info(p)) -#else -# define GC_HAS_DEBUG_INFO(p) GC_has_other_debug_info(p) -#endif - -/* Store debugging info into p.  Return displaced pointer. */ -/* Assumes we don't hold allocation lock.		   */ -ptr_t GC_store_debug_info(/* p, sz, string, integer */); - -#endif /* _DBG_MLC_H */ diff --git a/gc/include/private/gc_hdrs.h b/gc/include/private/gc_hdrs.h deleted file mode 100644 index 96749ab..0000000 --- a/gc/include/private/gc_hdrs.h +++ /dev/null @@ -1,233 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-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. - */ -/* Boehm, July 11, 1995 11:54 am PDT */ -# ifndef GC_HEADERS_H -# define GC_HEADERS_H -typedef struct hblkhdr hdr; - -# if CPP_WORDSZ != 32 && CPP_WORDSZ < 36 -	--> Get a real machine. -# endif - -/* - * The 2 level tree data structure that is used to find block headers. - * If there are more than 32 bits in a pointer, the top level is a hash - * table. - * - * This defines HDR, GET_HDR, and SET_HDR, the main macros used to - * retrieve and set object headers. - * - * Since 5.0 alpha 5, we can also take advantage of a header lookup - * cache.  This is a locally declared direct mapped cache, used inside - * the marker.  The HC_GET_HDR macro uses and maintains this - * cache.  Assuming we get reasonable hit rates, this shaves a few - * memory references from each pointer validation. - */ - -# if CPP_WORDSZ > 32 -#   define HASH_TL -# endif - -/* Define appropriate out-degrees for each of the two tree levels	*/ -# ifdef SMALL_CONFIG -#   define LOG_BOTTOM_SZ 11 -	/* Keep top index size reasonable with smaller blocks. */ -# else -#   define LOG_BOTTOM_SZ 10 -# endif -# ifndef HASH_TL -#   define LOG_TOP_SZ (WORDSZ - LOG_BOTTOM_SZ - LOG_HBLKSIZE) -# else -#   define LOG_TOP_SZ 11 -# endif -# define TOP_SZ (1 << LOG_TOP_SZ) -# define BOTTOM_SZ (1 << LOG_BOTTOM_SZ) - -#ifndef SMALL_CONFIG -# define USE_HDR_CACHE -#endif - -/* #define COUNT_HDR_CACHE_HITS  */ - -extern hdr * GC_invalid_header; /* header for an imaginary block 	*/ -				/* containing no objects.		*/ - - -/* Check whether p and corresponding hhdr point to long or invalid	*/ -/* object.  If so, advance hhdr	to					*/ -/* beginning of	block, or set hhdr to GC_invalid_header.		*/ -#define ADVANCE(p, hhdr, source) \ -	    { \ -	      hdr * new_hdr = GC_invalid_header; \ -              p = GC_find_start(p, hhdr, &new_hdr); \ -	      hhdr = new_hdr; \ -    	    } - -#ifdef USE_HDR_CACHE - -# ifdef COUNT_HDR_CACHE_HITS -    extern word GC_hdr_cache_hits; -    extern word GC_hdr_cache_misses; -#   define HC_HIT() ++GC_hdr_cache_hits -#   define HC_MISS() ++GC_hdr_cache_misses -# else -#   define HC_HIT() -#   define HC_MISS() -# endif - -  typedef struct hce { -    word block_addr;  	/* right shifted by LOG_HBLKSIZE */ -    hdr * hce_hdr; -  } hdr_cache_entry; - -# define HDR_CACHE_SIZE 8  /* power of 2 */ - -# define DECLARE_HDR_CACHE \ -	hdr_cache_entry hdr_cache[HDR_CACHE_SIZE] - -# define INIT_HDR_CACHE BZERO(hdr_cache, sizeof(hdr_cache)); - -# define HCE(h) hdr_cache + (((word)(h) >> LOG_HBLKSIZE) & (HDR_CACHE_SIZE-1)) - -# define HCE_VALID_FOR(hce,h) ((hce) -> block_addr == \ -				((word)(h) >> LOG_HBLKSIZE)) - -# define HCE_HDR(h) ((hce) -> hce_hdr) - - -/* Analogous to GET_HDR, except that in the case of large objects, it	*/ -/* Returns the header for the object beginning, and updates p.		*/ -/* Returns &GC_bad_header instead of 0.  All of this saves a branch	*/ -/* in the fast path.							*/ -# define HC_GET_HDR(p, hhdr, source) \ -	{ \ -	  hdr_cache_entry * hce = HCE(p); \ -	  if (HCE_VALID_FOR(hce, p)) { \ -	    HC_HIT(); \ -	    hhdr = hce -> hce_hdr; \ -	  } else { \ -	    HC_MISS(); \ -	    GET_HDR(p, hhdr); \ -            if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ -	      ADVANCE(p, hhdr, source); \ -	    } else { \ -	      hce -> block_addr = (word)(p) >> LOG_HBLKSIZE; \ -	      hce -> hce_hdr = hhdr; \ -	    } \ -	  } \ -	} - -#else /* !USE_HDR_CACHE */ - -# define DECLARE_HDR_CACHE - -# define INIT_HDR_CACHE - -# define HC_GET_HDR(p, hhdr, source) \ -	{ \ -	  GET_HDR(p, hhdr); \ -          if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ -	    ADVANCE(p, hhdr, source); \ -	  } \ -	} -#endif - -typedef struct bi { -    hdr * index[BOTTOM_SZ]; -	/* - 	 * The bottom level index contains one of three kinds of values: -	 * 0 means we're not responsible for this block, -	 *   or this is a block other than the first one in a free block. -	 * 1 < (long)X <= MAX_JUMP means the block starts at least -	 *        X * HBLKSIZE bytes before the current address. -	 * A valid pointer points to a hdr structure. (The above can't be -	 * valid pointers due to the GET_MEM return convention.) -	 */ -    struct bi * asc_link;	/* All indices are linked in	*/ -    				/* ascending order...		*/ -    struct bi * desc_link;	/* ... and in descending order.	*/ -    word key;			/* high order address bits.	*/ -# ifdef HASH_TL -    struct bi * hash_link;	/* Hash chain link.		*/ -# endif -} bottom_index; - -/* extern bottom_index GC_all_nils; - really part of GC_arrays */ - -/* extern bottom_index * GC_top_index []; - really part of GC_arrays */ -				/* Each entry points to a bottom_index.	*/ -				/* On a 32 bit machine, it points to 	*/ -				/* the index for a set of high order	*/ -				/* bits equal to the index.  For longer	*/ -				/* addresses, we hash the high order	*/ -				/* bits to compute the index in 	*/ -				/* GC_top_index, and each entry points	*/ -				/* to a hash chain.			*/ -				/* The last entry in each chain is	*/ -				/* GC_all_nils.				*/ - - -# define MAX_JUMP (HBLKSIZE - 1) - -# define HDR_FROM_BI(bi, p) \ -		((bi)->index[((word)(p) >> LOG_HBLKSIZE) & (BOTTOM_SZ - 1)]) -# ifndef HASH_TL -#   define BI(p) (GC_top_index \ -		[(word)(p) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE)]) -#   define HDR_INNER(p) HDR_FROM_BI(BI(p),p) -#   ifdef SMALL_CONFIG -#	define HDR(p) GC_find_header((ptr_t)(p)) -#   else -#	define HDR(p) HDR_INNER(p) -#   endif -#   define GET_BI(p, bottom_indx) (bottom_indx) = BI(p) -#   define GET_HDR(p, hhdr) (hhdr) = HDR(p) -#   define SET_HDR(p, hhdr) HDR_INNER(p) = (hhdr) -#   define GET_HDR_ADDR(p, ha) (ha) = &(HDR_INNER(p)) -# else /* hash */ -/*  Hash function for tree top level */ -#   define TL_HASH(hi) ((hi) & (TOP_SZ - 1)) -/*  Set bottom_indx to point to the bottom index for address p */ -#   define GET_BI(p, bottom_indx) \ -	{ \ -	    register word hi = \ -	        (word)(p) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); \ -	    register bottom_index * _bi = GC_top_index[TL_HASH(hi)]; \ -	    \ -	    while (_bi -> key != hi && _bi != GC_all_nils) \ -	    	_bi = _bi -> hash_link; \ -	    (bottom_indx) = _bi; \ -	} -#   define GET_HDR_ADDR(p, ha) \ -	{ \ -	    register bottom_index * bi; \ -	    \ -	    GET_BI(p, bi);	\ -	    (ha) = &(HDR_FROM_BI(bi, p)); \ -	} -#   define GET_HDR(p, hhdr) { register hdr ** _ha; GET_HDR_ADDR(p, _ha); \ -			      (hhdr) = *_ha; } -#   define SET_HDR(p, hhdr) { register hdr ** _ha; GET_HDR_ADDR(p, _ha); \ -			      *_ha = (hhdr); } -#   define HDR(p) GC_find_header((ptr_t)(p)) -# endif -			     -/* Is the result a forwarding address to someplace closer to the	*/ -/* beginning of the block or NIL?					*/ -# define IS_FORWARDING_ADDR_OR_NIL(hhdr) ((unsigned long) (hhdr) <= MAX_JUMP) - -/* Get an HBLKSIZE aligned address closer to the beginning of the block */ -/* h.  Assumes hhdr == HDR(h) and IS_FORWARDING_ADDR(hhdr).		*/ -# define FORWARDED_ADDR(h, hhdr) ((struct hblk *)(h) - (unsigned long)(hhdr)) -# endif /*  GC_HEADERS_H */ diff --git a/gc/include/private/gc_locks.h b/gc/include/private/gc_locks.h deleted file mode 100644 index 2dbc6ca..0000000 --- a/gc/include/private/gc_locks.h +++ /dev/null @@ -1,496 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1994 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. - * - * - * 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 GC_LOCKS_H -#define GC_LOCKS_H - -/* - * Mutual exclusion between allocator/collector routines. - * Needed if there is more than one allocator thread. - * FASTLOCK() is assumed to try to acquire the lock in a cheap and - * dirty way that is acceptable for a few instructions, e.g. by - * inhibiting preemption.  This is assumed to have succeeded only - * if a subsequent call to FASTLOCK_SUCCEEDED() returns TRUE. - * FASTUNLOCK() is called whether or not FASTLOCK_SUCCEEDED(). - * If signals cannot be tolerated with the FASTLOCK held, then - * FASTLOCK should disable signals.  The code executed under - * FASTLOCK is otherwise immune to interruption, provided it is - * not restarted. - * DCL_LOCK_STATE declares any local variables needed by LOCK and UNLOCK - * and/or DISABLE_SIGNALS and ENABLE_SIGNALS and/or FASTLOCK. - * (There is currently no equivalent for FASTLOCK.) - * - * In the PARALLEL_MARK case, we also need to define a number of - * other inline finctions here: - *   GC_bool GC_compare_and_exchange( volatile GC_word *addr, - *   				      GC_word old, GC_word new ) - *   GC_word GC_atomic_add( volatile GC_word *addr, GC_word how_much ) - *   void GC_memory_barrier( ) - *    - */   -# ifdef THREADS -   void GC_noop1 GC_PROTO((word)); -#  ifdef PCR_OBSOLETE	/* Faster, but broken with multiple lwp's	*/ -#    include  "th/PCR_Th.h" -#    include  "th/PCR_ThCrSec.h" -     extern struct PCR_Th_MLRep GC_allocate_ml; -#    define DCL_LOCK_STATE  PCR_sigset_t GC_old_sig_mask -#    define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml)  -#    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml) -#    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml) -#    define FASTLOCK() PCR_ThCrSec_EnterSys() -     /* Here we cheat (a lot): */ -#        define FASTLOCK_SUCCEEDED() (*(int *)(&GC_allocate_ml) == 0) -		/* TRUE if nobody currently holds the lock */ -#    define FASTUNLOCK() PCR_ThCrSec_ExitSys() -#  endif -#  ifdef PCR -#    include <base/PCR_Base.h> -#    include <th/PCR_Th.h> -     extern PCR_Th_ML GC_allocate_ml; -#    define DCL_LOCK_STATE \ -	 PCR_ERes GC_fastLockRes; PCR_sigset_t GC_old_sig_mask -#    define LOCK() PCR_Th_ML_Acquire(&GC_allocate_ml) -#    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml) -#    define FASTLOCK() (GC_fastLockRes = PCR_Th_ML_Try(&GC_allocate_ml)) -#    define FASTLOCK_SUCCEEDED() (GC_fastLockRes == PCR_ERes_okay) -#    define FASTUNLOCK()  {\ -        if( FASTLOCK_SUCCEEDED() ) PCR_Th_ML_Release(&GC_allocate_ml); } -#  endif -#  ifdef SRC_M3 -     extern GC_word RT0u__inCritical; -#    define LOCK() RT0u__inCritical++ -#    define UNLOCK() RT0u__inCritical-- -#  endif -#  ifdef GC_SOLARIS_THREADS -#    include <thread.h> -#    include <signal.h> -     extern mutex_t GC_allocate_ml; -#    define LOCK() mutex_lock(&GC_allocate_ml); -#    define UNLOCK() mutex_unlock(&GC_allocate_ml); -#  endif - -/* Try to define GC_TEST_AND_SET and a matching GC_CLEAR for spin lock	*/ -/* acquisition and release.  We need this for correct operation of the	*/ -/* incremental GC.							*/ -#  ifdef __GNUC__ -#    if defined(I386) -       inline static int GC_test_and_set(volatile unsigned int *addr) { -	  int oldval; -	  /* Note: the "xchg" instruction does not need a "lock" prefix */ -	  __asm__ __volatile__("xchgl %0, %1" -		: "=r"(oldval), "=m"(*(addr)) -		: "0"(1), "m"(*(addr)) : "memory"); -	  return oldval; -       } -#      define GC_TEST_AND_SET_DEFINED -#    endif -#    if defined(IA64) -       inline static int GC_test_and_set(volatile unsigned int *addr) { -	  long oldval, n = 1; -	  __asm__ __volatile__("xchg4 %0=%1,%2" -		: "=r"(oldval), "=m"(*addr) -		: "r"(n), "1"(*addr) : "memory"); -	  return oldval; -       } -#      define GC_TEST_AND_SET_DEFINED -       /* Should this handle post-increment addressing?? */ -       inline static void GC_clear(volatile unsigned int *addr) { -	 __asm__ __volatile__("st4.rel %0=r0" : "=m" (*addr) : : "memory"); -       } -#      define GC_CLEAR_DEFINED -#    endif -#    ifdef SPARC -       inline static int GC_test_and_set(volatile unsigned int *addr) { -	 int oldval; - -	 __asm__ __volatile__("ldstub %1,%0" -	 : "=r"(oldval), "=m"(*addr) -	 : "m"(*addr) : "memory"); -	 return oldval; -       } -#      define GC_TEST_AND_SET_DEFINED -#    endif -#    ifdef M68K -       /* Contributed by Tony Mantler.  I'm not sure how well it was	*/ -       /* tested.							*/ -       inline static int GC_test_and_set(volatile unsigned int *addr) { -          char oldval; /* this must be no longer than 8 bits */ - -          /* The return value is semi-phony. */ -          /* 'tas' sets bit 7 while the return */ -          /* value pretends bit 0 was set */ -          __asm__ __volatile__( -                 "tas %1@; sne %0; negb %0" -                 : "=d" (oldval) -                 : "a" (addr) : "memory"); -          return oldval; -       } -#      define GC_TEST_AND_SET_DEFINED -#    endif -#    if defined(POWERPC) -        inline static int GC_test_and_set(volatile unsigned int *addr) { -          int oldval; -          int temp = 1; /* locked value */ - -          __asm__ __volatile__( -               "1:\tlwarx %0,0,%3\n"   /* load and reserve               */ -               "\tcmpwi %0, 0\n"       /* if load is                     */ -               "\tbne 2f\n"            /*   non-zero, return already set */ -               "\tstwcx. %2,0,%1\n"    /* else store conditional         */ -               "\tbne- 1b\n"           /* retry if lost reservation      */ -               "2:\t\n"                /* oldval is zero if we set       */ -              : "=&r"(oldval), "=p"(addr) -              : "r"(temp), "1"(addr) -              : "memory"); -          return (int)oldval; -        } -#       define GC_TEST_AND_SET_DEFINED -        inline static void GC_clear(volatile unsigned int *addr) { -	  __asm__ __volatile__("eieio" : : : "memory"); -          *(addr) = 0; -        } -#       define GC_CLEAR_DEFINED -#    endif -#    if defined(ALPHA)  -        inline static int GC_test_and_set(volatile unsigned int * addr) -        { -          unsigned long oldvalue; -          unsigned long temp; - -          __asm__ __volatile__( -                             "1:     ldl_l %0,%1\n" -                             "       and %0,%3,%2\n" -                             "       bne %2,2f\n" -                             "       xor %0,%3,%0\n" -                             "       stl_c %0,%1\n" -                             "       beq %0,3f\n" -                             "       mb\n" -                             "2:\n" -                             ".section .text2,\"ax\"\n" -                             "3:     br 1b\n" -                             ".previous" -                             :"=&r" (temp), "=m" (*addr), "=&r" (oldvalue) -                             :"Ir" (1), "m" (*addr) -			     :"memory"); - -          return oldvalue; -        } -#       define GC_TEST_AND_SET_DEFINED -        /* Should probably also define GC_clear, since it needs	*/ -        /* a memory barrier ??					*/ -#    endif /* ALPHA */ -#    ifdef ARM32 -        inline static int GC_test_and_set(volatile unsigned int *addr) { -          int oldval; -          /* SWP on ARM is very similar to XCHG on x86.  Doesn't lock the -           * bus because there are no SMP ARM machines.  If/when there are, -           * this code will likely need to be updated. */ -          /* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */ -          __asm__ __volatile__("swp %0, %1, [%2]" -      		  	     : "=r"(oldval) -      			     : "r"(1), "r"(addr) -			     : "memory"); -          return oldval; -        } -#       define GC_TEST_AND_SET_DEFINED -#    endif /* ARM32 */ -#  endif /* __GNUC__ */ -#  if (defined(ALPHA) && !defined(__GNUC__)) -#    define GC_test_and_set(addr) __cxx_test_and_set_atomic(addr, 1) -#    define GC_TEST_AND_SET_DEFINED -#  endif -#  if defined(MSWIN32) -#    define GC_test_and_set(addr) InterlockedExchange((LPLONG)addr,1) -#    define GC_TEST_AND_SET_DEFINED -#  endif -#  ifdef MIPS -#    ifdef LINUX -#      include <sys/tas.h> -#      define GC_test_and_set(addr) _test_and_set((int *) addr,1) -#      define GC_TEST_AND_SET_DEFINED -#    elif __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \ -	|| !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700 -#	 ifdef __GNUC__ -#          define GC_test_and_set(addr) _test_and_set(addr,1) -#	 else -#          define GC_test_and_set(addr) test_and_set(addr,1) -#	 endif -#    else -#	 define GC_test_and_set(addr) __test_and_set(addr,1) -#	 define GC_clear(addr) __lock_release(addr); -#	 define GC_CLEAR_DEFINED -#    endif -#    define GC_TEST_AND_SET_DEFINED -#  endif /* MIPS */ -#  if 0 /* defined(HP_PA) */ -     /* The official recommendation seems to be to not use ldcw from	*/ -     /* user mode.  Since multithreaded incremental collection doesn't	*/ -     /* work anyway on HP_PA, this shouldn't be a major loss.		*/ - -     /* "set" means 0 and "clear" means 1 here.		*/ -#    define GC_test_and_set(addr) !GC_test_and_clear(addr); -#    define GC_TEST_AND_SET_DEFINED -#    define GC_clear(addr) GC_noop1((word)(addr)); *(volatile unsigned int *)addr = 1; -	/* The above needs a memory barrier! */ -#    define GC_CLEAR_DEFINED -#  endif -#  if defined(GC_TEST_AND_SET_DEFINED) && !defined(GC_CLEAR_DEFINED) -#    ifdef __GNUC__ -       inline static void GC_clear(volatile unsigned int *addr) { -         /* Try to discourage gcc from moving anything past this. */ -         __asm__ __volatile__(" " : : : "memory"); -         *(addr) = 0; -       } -#    else -	    /* The function call in the following should prevent the	*/ -	    /* compiler from moving assignments to below the UNLOCK.	*/ -#      define GC_clear(addr) GC_noop1((word)(addr)); \ -			     *((volatile unsigned int *)(addr)) = 0; -#    endif -#    define GC_CLEAR_DEFINED -#  endif /* !GC_CLEAR_DEFINED */ - -#  if !defined(GC_TEST_AND_SET_DEFINED) -#    define USE_PTHREAD_LOCKS -#  endif - -#  if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ -      && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) -#    define NO_THREAD (pthread_t)(-1) -#    include <pthread.h> -#    if defined(PARALLEL_MARK)  -      /* We need compare-and-swap to update mark bits, where it's	*/ -      /* performance critical.  If USE_MARK_BYTES is defined, it is	*/ -      /* no longer needed for this purpose.  However we use it in	*/ -      /* either case to implement atomic fetch-and-add, though that's	*/ -      /* less performance critical, and could perhaps be done with	*/ -      /* a lock.							*/ -#     if defined(GENERIC_COMPARE_AND_SWAP) -	/* Probably not useful, except for debugging.	*/ -	/* We do use GENERIC_COMPARE_AND_SWAP on PA_RISC, but we 	*/ -	/* minimize its use.						*/ -	extern pthread_mutex_t GC_compare_and_swap_lock; - -	/* Note that if GC_word updates are not atomic, a concurrent 	*/ -	/* reader should acquire GC_compare_and_swap_lock.  On 		*/ -	/* currently supported platforms, such updates are atomic.	*/ -	extern GC_bool GC_compare_and_exchange(volatile GC_word *addr, -					       GC_word old, GC_word new_val); -#     endif /* GENERIC_COMPARE_AND_SWAP */ -#     if defined(I386) -#      if !defined(GENERIC_COMPARE_AND_SWAP) -         /* Returns TRUE if the comparison succeeded. */ -         inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, -		  				       GC_word old, -						       GC_word new_val)  -         { -	   char result; -	   __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1" -	    	: "=m"(*(addr)), "=r"(result) -		: "r" (new_val), "0"(*(addr)), "a"(old) : "memory"); -	   return (GC_bool) result; -         } -#      endif /* !GENERIC_COMPARE_AND_SWAP */ -       inline static void GC_memory_write_barrier() -       { -	 /* We believe the processor ensures at least processor	*/ -	 /* consistent ordering.  Thus a compiler barrier	*/ -	 /* should suffice.					*/ -         __asm__ __volatile__("" : : : "memory"); -       } -#     endif /* I386 */ -#     if defined(IA64) -#      if !defined(GENERIC_COMPARE_AND_SWAP) -         inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr, -						       GC_word old, GC_word new_val)  -	 { -	  unsigned long oldval; -	  __asm__ __volatile__("mov ar.ccv=%4 ;; cmpxchg8.rel %0=%1,%2,ar.ccv" -		: "=r"(oldval), "=m"(*addr) -		: "r"(new_val), "1"(*addr), "r"(old) : "memory"); -	  return (oldval == old); -         } -#      endif /* !GENERIC_COMPARE_AND_SWAP */ -#      if 0 -	/* Shouldn't be needed; we use volatile stores instead. */ -        inline static void GC_memory_write_barrier() -        { -          __asm__ __volatile__("mf" : : : "memory"); -        } -#      endif /* 0 */ -#     endif /* IA64 */ -#     if !defined(GENERIC_COMPARE_AND_SWAP) -        /* Returns the original value of *addr.	*/ -        inline static GC_word GC_atomic_add(volatile GC_word *addr, -					    GC_word how_much) -        { -	  GC_word old; -	  do { -	    old = *addr; -	  } while (!GC_compare_and_exchange(addr, old, old+how_much)); -          return old; -        } -#     else /* GENERIC_COMPARE_AND_SWAP */ -	/* So long as a GC_word can be atomically updated, it should	*/ -	/* be OK to read *addr without a lock.				*/ -	extern GC_word GC_atomic_add(volatile GC_word *addr, GC_word how_much); -#     endif /* GENERIC_COMPARE_AND_SWAP */ - -#    endif /* PARALLEL_MARK */ - -#    if !defined(THREAD_LOCAL_ALLOC) && !defined(USE_PTHREAD_LOCKS) -      /* In the THREAD_LOCAL_ALLOC case, the allocation lock tends to	*/ -      /* be held for long periods, if it is held at all.  Thus spinning	*/ -      /* and sleeping for fixed periods are likely to result in 	*/ -      /* significant wasted time.  We thus rely mostly on queued locks. */ -#     define USE_SPIN_LOCK -      extern volatile unsigned int GC_allocate_lock; -      extern void GC_lock(void); -	/* Allocation lock holder.  Only set if acquired by client through */ -	/* GC_call_with_alloc_lock.					   */ -#     ifdef GC_ASSERTIONS -#        define LOCK() \ -		{ if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); \ -		  SET_LOCK_HOLDER(); } -#        define UNLOCK() \ -		{ GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \ -	          GC_clear(&GC_allocate_lock); } -#     else -#        define LOCK() \ -		{ if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); } -#        define UNLOCK() \ -		GC_clear(&GC_allocate_lock) -#     endif /* !GC_ASSERTIONS */ -#     if 0 -	/* Another alternative for OSF1 might be:		*/ -#       include <sys/mman.h> -        extern msemaphore GC_allocate_semaphore; -#       define LOCK() { if (msem_lock(&GC_allocate_semaphore, MSEM_IF_NOWAIT) \ - 			    != 0) GC_lock(); else GC_allocate_lock = 1; } -        /* The following is INCORRECT, since the memory model is too weak. */ -	/* Is this true?  Presumably msem_unlock has the right semantics?  */ -	/*		- HB						   */ -#       define UNLOCK() { GC_allocate_lock = 0; \ -                          msem_unlock(&GC_allocate_semaphore, 0); } -#     endif /* 0 */ -#    else /* THREAD_LOCAL_ALLOC  || USE_PTHREAD_LOCKS */ -#      ifndef USE_PTHREAD_LOCKS -#        define USE_PTHREAD_LOCKS -#      endif -#    endif /* THREAD_LOCAL_ALLOC */ -#   ifdef USE_PTHREAD_LOCKS -#      include <pthread.h> -       extern pthread_mutex_t GC_allocate_ml; -#      ifdef GC_ASSERTIONS -#        define LOCK() \ -		{ GC_lock(); \ -		  SET_LOCK_HOLDER(); } -#        define UNLOCK() \ -		{ GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \ -	          pthread_mutex_unlock(&GC_allocate_ml); } -#      else /* !GC_ASSERTIONS */ -#        define LOCK() \ -	   { if (0 != pthread_mutex_trylock(&GC_allocate_ml)) GC_lock(); } -#        define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml) -#      endif /* !GC_ASSERTIONS */ -#   endif /* USE_PTHREAD_LOCKS */ -#   define SET_LOCK_HOLDER() GC_lock_holder = pthread_self() -#   define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD -#   define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self())) -    extern VOLATILE GC_bool GC_collecting; -#   define ENTER_GC() GC_collecting = 1; -#   define EXIT_GC() GC_collecting = 0; -    extern void GC_lock(void); -    extern pthread_t GC_lock_holder; -#   ifdef GC_ASSERTIONS -      extern pthread_t GC_mark_lock_holder; -#   endif -#  endif /* GC_PTHREADS with linux_threads.c implementation */ -#  if defined(GC_IRIX_THREADS) -#    include <pthread.h> -     /* This probably should never be included, but I can't test	*/ -     /* on Irix anymore.						*/ -#    include <mutex.h> - -     extern unsigned long GC_allocate_lock; -	/* This is not a mutex because mutexes that obey the (optional) 	*/ -	/* POSIX scheduling rules are subject to convoys in high contention	*/ -	/* applications.  This is basically a spin lock.			*/ -     extern pthread_t GC_lock_holder; -     extern void GC_lock(void); -	/* Allocation lock holder.  Only set if acquired by client through */ -	/* GC_call_with_alloc_lock.					   */ -#    define SET_LOCK_HOLDER() GC_lock_holder = pthread_self() -#    define NO_THREAD (pthread_t)(-1) -#    define UNSET_LOCK_HOLDER() GC_lock_holder = NO_THREAD -#    define I_HOLD_LOCK() (pthread_equal(GC_lock_holder, pthread_self())) -#    define LOCK() { if (GC_test_and_set(&GC_allocate_lock)) GC_lock(); } -#    define UNLOCK() GC_clear(&GC_allocate_lock); -     extern VOLATILE GC_bool GC_collecting; -#    define ENTER_GC() \ -		{ \ -		    GC_collecting = 1; \ -		} -#    define EXIT_GC() GC_collecting = 0; -#  endif /* GC_IRIX_THREADS */ -#  if defined(GC_WIN32_THREADS) -#    if defined(GC_PTHREADS) -#      include <pthread.h> -       extern pthread_mutex_t GC_allocate_ml; -#      define LOCK()   pthread_mutex_lock(&GC_allocate_ml) -#      define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml) -#    else -#      include <windows.h> -       GC_API CRITICAL_SECTION GC_allocate_ml; -#      define LOCK() EnterCriticalSection(&GC_allocate_ml); -#      define UNLOCK() LeaveCriticalSection(&GC_allocate_ml); -#    endif -#  endif -#  ifndef SET_LOCK_HOLDER -#      define SET_LOCK_HOLDER() -#      define UNSET_LOCK_HOLDER() -#      define I_HOLD_LOCK() FALSE -		/* Used on platforms were locks can be reacquired,	*/ -		/* so it doesn't matter if we lie.			*/ -#  endif -# else /* !THREADS */ -#    define LOCK() -#    define UNLOCK() -# endif /* !THREADS */ -# ifndef SET_LOCK_HOLDER -#   define SET_LOCK_HOLDER() -#   define UNSET_LOCK_HOLDER() -#   define I_HOLD_LOCK() FALSE -		/* Used on platforms were locks can be reacquired,	*/ -		/* so it doesn't matter if we lie.			*/ -# endif -# ifndef ENTER_GC -#   define ENTER_GC() -#   define EXIT_GC() -# endif - -# ifndef DCL_LOCK_STATE -#   define DCL_LOCK_STATE -# endif -# ifndef FASTLOCK -#   define FASTLOCK() LOCK() -#   define FASTLOCK_SUCCEEDED() TRUE -#   define FASTUNLOCK() UNLOCK() -# endif - -#endif /* GC_LOCKS_H */ diff --git a/gc/include/private/gc_pmark.h b/gc/include/private/gc_pmark.h deleted file mode 100644 index cf85d4d..0000000 --- a/gc/include/private/gc_pmark.h +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. - * Copyright (c) 2001 by Hewlett-Packard Company. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose,  provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - */ - -/* Private declarations of GC marker data structures and macros */ - -/* - * Declarations of mark stack.  Needed by marker and client supplied mark - * routines.  Transitively include gc_priv.h. - * (Note that gc_priv.h should not be included before this, since this - * includes dbg_mlc.h, which wants to include gc_priv.h AFTER defining - * I_HIDE_POINTERS.) - */ -#ifndef GC_PMARK_H -# define GC_PMARK_H - -# if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) -#   include "dbg_mlc.h" -# endif -# ifndef GC_MARK_H -#   include "../gc_mark.h" -# endif -# ifndef GC_PRIVATE_H -#   include "gc_priv.h" -# endif - -/* The real declarations of the following is in gc_priv.h, so that	*/ -/* we can avoid scanning the following table.				*/ -/* -extern mark_proc GC_mark_procs[MAX_MARK_PROCS]; -*/ - -/* - * Mark descriptor stuff that should remain private for now, mostly - * because it's hard to export WORDSZ without including gcconfig.h. - */ -# define BITMAP_BITS (WORDSZ - GC_DS_TAG_BITS) -# define PROC(descr) \ -	(GC_mark_procs[((descr) >> GC_DS_TAG_BITS) & (GC_MAX_MARK_PROCS-1)]) -# define ENV(descr) \ -	((descr) >> (GC_DS_TAG_BITS + GC_LOG_MAX_MARK_PROCS)) -# define MAX_ENV \ -  	(((word)1 << (WORDSZ - GC_DS_TAG_BITS - GC_LOG_MAX_MARK_PROCS)) - 1) - - -extern word GC_n_mark_procs; - -/* Number of mark stack entries to discard on overflow.	*/ -#define GC_MARK_STACK_DISCARDS (INITIAL_MARK_STACK_SIZE/8) - -typedef struct GC_ms_entry { -    GC_word * mse_start;   /* First word of object */ -    GC_word mse_descr;	/* Descriptor; low order two bits are tags,	*/ -    			/* identifying the upper 30 bits as one of the	*/ -    			/* following:					*/ -} mse; - -extern word GC_mark_stack_size; - -extern mse * GC_mark_stack_limit; - -#ifdef PARALLEL_MARK -  extern mse * VOLATILE GC_mark_stack_top; -#else -  extern mse * GC_mark_stack_top; -#endif - -extern mse * GC_mark_stack; - -#ifdef PARALLEL_MARK -    /* -     * Allow multiple threads to participate in the marking process. -     * This works roughly as follows: -     *  The main mark stack never shrinks, but it can grow. -     * -     *	The initiating threads holds the GC lock, and sets GC_help_wanted. -     *   -     *  Other threads: -     *     1) update helper_count (while holding mark_lock.) -     *	   2) allocate a local mark stack -     *     repeatedly: -     *		3) Steal a global mark stack entry by atomically replacing -     *		   its descriptor with 0. -     *		4) Copy it to the local stack. -     *	        5) Mark on the local stack until it is empty, or -     *		   it may be profitable to copy it back. -     *	        6) If necessary, copy local stack to global one, -     *		   holding mark lock. -     *    7) Stop when the global mark stack is empty. -     *    8) decrement helper_count (holding mark_lock). -     * -     * This is an experiment to see if we can do something along the lines -     * of the University of Tokyo SGC in a less intrusive, though probably -     * also less performant, way. -     */ -    void GC_do_parallel_mark(); -		/* inititate parallel marking.	*/ - -    extern GC_bool GC_help_wanted;	/* Protected by mark lock	*/ -    extern unsigned GC_helper_count;	/* Number of running helpers.	*/ -					/* Protected by mark lock	*/ -    extern unsigned GC_active_count;	/* Number of active helpers.	*/ -					/* Protected by mark lock	*/ -					/* May increase and decrease	*/ -					/* within each mark cycle.  But	*/ -					/* once it returns to 0, it	*/ -					/* stays zero for the cycle.	*/ -    /* GC_mark_stack_top is also protected by mark lock.	*/ -    extern mse * VOLATILE GC_first_nonempty; -					/* Lowest entry on mark stack	*/ -					/* that may be nonempty.	*/ -					/* Updated only by initiating 	*/ -					/* thread.			*/ -    /* -     * GC_notify_all_marker() is used when GC_help_wanted is first set, -     * when the last helper becomes inactive, -     * when something is added to the global mark stack, and just after -     * GC_mark_no is incremented. -     * This could be split into multiple CVs (and probably should be to -     * scale to really large numbers of processors.) -     */ -#endif /* PARALLEL_MARK */ - -/* Return a pointer to within 1st page of object.  	*/ -/* Set *new_hdr_p to corr. hdr.				*/ -#ifdef __STDC__ -# ifdef PRINT_BLACK_LIST -    ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p, -		    	word source); -# else -    ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p); -# endif -#else -  ptr_t GC_find_start(); -#endif - -mse * GC_signal_mark_stack_overflow GC_PROTO((mse *msp)); - -# ifdef GATHERSTATS -#   define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz) -#   define ADD_TO_COMPOSITE(sz) GC_composite_in_use += (sz) -# else -#   define ADD_TO_ATOMIC(sz) -#   define ADD_TO_COMPOSITE(sz) -# endif - -/* Push the object obj with corresponding heap block header hhdr onto 	*/ -/* the mark stack.							*/ -# define PUSH_OBJ(obj, hhdr, mark_stack_top, mark_stack_limit) \ -{ \ -    register word _descr = (hhdr) -> hb_descr; \ -        \ -    if (_descr == 0) { \ -    	ADD_TO_ATOMIC((hhdr) -> hb_sz); \ -    } else { \ -        ADD_TO_COMPOSITE((hhdr) -> hb_sz); \ -        mark_stack_top++; \ -        if (mark_stack_top >= mark_stack_limit) { \ -          mark_stack_top = GC_signal_mark_stack_overflow(mark_stack_top); \ -        } \ -        mark_stack_top -> mse_start = (obj); \ -        mark_stack_top -> mse_descr = _descr; \ -    } \ -} - -/* Push the contents of current onto the mark stack if it is a valid	*/ -/* ptr to a currently unmarked object.  Mark it.			*/ -/* If we assumed a standard-conforming compiler, we could probably	*/ -/* generate the exit_label transparently.				*/ -# define PUSH_CONTENTS(current, mark_stack_top, mark_stack_limit, \ -		       source, exit_label) \ -{ \ -    hdr * my_hhdr; \ -    ptr_t my_current = current; \ - \ -    GET_HDR(my_current, my_hhdr); \ -    if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \ -	 hdr * new_hdr = GC_invalid_header; \ -         my_current = GC_find_start(my_current, my_hhdr, &new_hdr); \ -         my_hhdr = new_hdr; \ -    } \ -    PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ -		  source, exit_label, my_hhdr);	\ -exit_label: ; \ -} - -/* As above, but use header cache for header lookup.	*/ -# define HC_PUSH_CONTENTS(current, mark_stack_top, mark_stack_limit, \ -		       source, exit_label) \ -{ \ -    hdr * my_hhdr; \ -    ptr_t my_current = current; \ - \ -    HC_GET_HDR(my_current, my_hhdr, source); \ -    PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \ -		  source, exit_label, my_hhdr);	\ -exit_label: ; \ -} - -/* Set mark bit, exit if it was already set.	*/ - -# ifdef USE_MARK_BYTES -    /* Unlike the mark bit case, there is a race here, and we may set	*/ -    /* the bit twice in the concurrent case.  This can result in the	*/ -    /* object being pushed twice.  But that's only a performance issue.	*/ -#   define SET_MARK_BIT_EXIT_IF_SET(hhdr,displ,exit_label) \ -    { \ -        register VOLATILE char * mark_byte_addr = \ -				hhdr -> hb_marks + ((displ) >> 1); \ -        register char mark_byte = *mark_byte_addr; \ -          \ -	if (mark_byte) goto exit_label; \ -	*mark_byte_addr = 1;  \ -    }  -# else -#   define SET_MARK_BIT_EXIT_IF_SET(hhdr,displ,exit_label) \ -    { \ -        register word * mark_word_addr = hhdr -> hb_marks + divWORDSZ(displ); \ -          \ -        OR_WORD_EXIT_IF_SET(mark_word_addr, (word)1 << modWORDSZ(displ), \ -			    exit_label); \ -    }  -# endif /* USE_MARK_BYTES */ - -/* If the mark bit corresponding to current is not set, set it, and 	*/ -/* push the contents of the object on the mark stack.  For a small 	*/ -/* object we assume that current is the (possibly interior) pointer	*/ -/* to the object.  For large objects we assume that current points	*/ -/* to somewhere inside the first page of the object.  If		*/ -/* GC_all_interior_pointers is set, it may have been previously 	*/ -/* adjusted to make that true.						*/ -# define PUSH_CONTENTS_HDR(current, mark_stack_top, mark_stack_limit, \ -		           source, exit_label, hhdr) \ -{ \ -    int displ;  /* Displacement in block; first bytes, then words */ \ -    int map_entry; \ -    \ -    displ = HBLKDISPL(current); \ -    map_entry = MAP_ENTRY((hhdr -> hb_map), displ); \ -    displ = BYTES_TO_WORDS(displ); \ -    if (map_entry > CPP_MAX_OFFSET) { \ -	if (map_entry == OFFSET_TOO_BIG) { \ -	  map_entry = displ % (hhdr -> hb_sz); \ -	  displ -= map_entry; \ -	  if (displ + (hhdr -> hb_sz) > BYTES_TO_WORDS(HBLKSIZE)) { \ -	    GC_ADD_TO_BLACK_LIST_NORMAL((word)current, source); \ -	    goto exit_label; \ -	  } \ -	} else { \ -          GC_ADD_TO_BLACK_LIST_NORMAL((word)current, source); goto exit_label; \ -	} \ -    } else { \ -        displ -= map_entry; \ -    } \ -    GC_ASSERT(displ >= 0 && displ < MARK_BITS_PER_HBLK); \ -    SET_MARK_BIT_EXIT_IF_SET(hhdr, displ, exit_label); \ -    GC_STORE_BACK_PTR((ptr_t)source, (ptr_t)HBLKPTR(current) \ -				      + WORDS_TO_BYTES(displ)); \ -    PUSH_OBJ(((word *)(HBLKPTR(current)) + displ), hhdr, \ -    	     mark_stack_top, mark_stack_limit) \ -} - -#if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) -#   define PUSH_ONE_CHECKED_STACK(p, source) \ -	GC_mark_and_push_stack(p, (ptr_t)(source)) -#else -#   define PUSH_ONE_CHECKED_STACK(p, source) \ -	GC_mark_and_push_stack(p) -#endif - -/* - * Push a single value onto mark stack. Mark from the object pointed to by p. - * P is considered valid even if it is an interior pointer. - * Previously marked objects are not pushed.  Hence we make progress even - * if the mark stack overflows. - */ -# define GC_PUSH_ONE_STACK(p, source) \ -    if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr 	\ -	 && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) {	\ -	 PUSH_ONE_CHECKED_STACK(p, source);	\ -    } - -/* - * As above, but interior pointer recognition as for - * normal for heap pointers. - */ -# define GC_PUSH_ONE_HEAP(p,source) \ -    if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr 	\ -	 && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) {	\ -	    GC_mark_stack_top = GC_mark_and_push( \ -			    (GC_PTR)(p), GC_mark_stack_top, \ -			    GC_mark_stack_limit, (GC_PTR *)(source)); \ -    } - -/* Mark starting at mark stack entry top (incl.) down to	*/ -/* mark stack entry bottom (incl.).  Stop after performing	*/ -/* about one page worth of work.  Return the new mark stack	*/ -/* top entry.							*/ -mse * GC_mark_from GC_PROTO((mse * top, mse * bottom, mse *limit)); - -#define MARK_FROM_MARK_STACK() \ -	GC_mark_stack_top = GC_mark_from(GC_mark_stack_top, \ -					 GC_mark_stack, \ -					 GC_mark_stack + GC_mark_stack_size); - -/* - * Mark from one finalizable object using the specified - * mark proc. May not mark the object pointed to by  - * real_ptr. That is the job of the caller, if appropriate - */ -# define GC_MARK_FO(real_ptr, mark_proc) \ -{ \ -    (*(mark_proc))(real_ptr); \ -    while (!GC_mark_stack_empty()) MARK_FROM_MARK_STACK(); \ -    if (GC_mark_state != MS_NONE) { \ -        GC_set_mark_bit(real_ptr); \ -        while (!GC_mark_some((ptr_t)0)) {} \ -    } \ -} - -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.			*/ - -				/* We say something is dirty if it was	*/ -				/* written since the last time we	*/ -				/* retrieved dirty bits.  We say it's 	*/ -				/* grungy if it was marked dirty in the	*/ -				/* last set of bits we retrieved.	*/ -				 -				/* Invariant I: all roots and marked	*/ -				/* objects p are either dirty, or point */ -				/* to objects q that are either marked 	*/ -				/* or a pointer to q appears in a range	*/ -				/* on the mark stack.			*/ - -# define MS_NONE 0		/* No marking in progress. I holds.	*/ -				/* Mark stack is empty.			*/ - -# define MS_PUSH_RESCUERS 1	/* Rescuing objects are currently 	*/ -				/* being pushed.  I holds, except	*/ -				/* that grungy roots may point to 	*/ -				/* unmarked objects, as may marked	*/ -				/* grungy objects above scan_ptr.	*/ - -# define MS_PUSH_UNCOLLECTABLE 2 -				/* I holds, except that marked 		*/ -				/* uncollectable objects above 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 M.S. */ -				/* overflow.  However marked heap	*/ -				/* objects below scan_ptr point to	*/ -				/* marked or stacked objects.		*/ - -# define MS_INVALID 5		/* I may not hold.			*/ - -extern mark_state_t GC_mark_state; - -#endif  /* GC_PMARK_H */ - diff --git a/gc/include/private/gc_priv.h b/gc/include/private/gc_priv.h deleted file mode 100644 index 2cf07d1..0000000 --- a/gc/include/private/gc_priv.h +++ /dev/null @@ -1,1884 +0,0 @@ -/*  - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. - * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved. - * Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved. - * - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. - * - * 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 GC_PRIVATE_H -# define GC_PRIVATE_H - -#if defined(mips) && defined(SYSTYPE_BSD) && defined(sony_news) -    /* sony RISC NEWS, NEWSOS 4 */ -#   define BSD_TIME -/*    typedef long ptrdiff_t;   -- necessary on some really old systems	*/ -#endif - -#if defined(mips) && defined(SYSTYPE_BSD43) -    /* MIPS RISCOS 4 */ -#   define BSD_TIME -#endif - -#ifdef DGUX -#   include <sys/types.h> -#   include <sys/time.h> -#   include <sys/resource.h> -#endif /* DGUX */ - -#ifdef BSD_TIME -#   include <sys/types.h> -#   include <sys/time.h> -#   include <sys/resource.h> -#endif /* BSD_TIME */ - -# ifndef GC_H -#   include "gc.h" -# endif - -# ifndef GC_MARK_H -#   include "../gc_mark.h" -# endif - -typedef GC_word word; -typedef GC_signed_word signed_word; - -typedef int GC_bool; -# define TRUE 1 -# define FALSE 0 - -typedef char * ptr_t;	/* A generic pointer to which we can add	*/ -			/* byte displacements.				*/ -			/* Preferably identical to caddr_t, if it 	*/ -			/* exists.					*/ -			 -# ifndef GCCONFIG_H -#   include "gcconfig.h" -# endif - -# ifndef HEADERS_H -#   include "gc_hdrs.h" -# endif - -#if defined(__STDC__) -#   include <stdlib.h> -#   if !(defined( sony_news ) ) -#       include <stddef.h> -#   endif -#   define VOLATILE volatile -#else -#   ifdef MSWIN32 -#   	include <stdlib.h> -#   endif -#   define VOLATILE -#endif - -#if 0 /* defined(__GNUC__) doesn't work yet */ -# define EXPECT(expr, outcome) __builtin_expect(expr,outcome) -  /* Equivalent to (expr), but predict that usually (expr)==outcome. */ -#else -# define EXPECT(expr, outcome) (expr) -#endif /* __GNUC__ */ - -# ifndef GC_LOCKS_H -#   include "gc_locks.h" -# endif - -# ifdef STACK_GROWS_DOWN -#   define COOLER_THAN > -#   define HOTTER_THAN < -#   define MAKE_COOLER(x,y) if ((word)(x)+(y) > (word)(x)) {(x) += (y);} \ -			    else {(x) = (word)ONES;} -#   define MAKE_HOTTER(x,y) (x) -= (y) -# else -#   define COOLER_THAN < -#   define HOTTER_THAN > -#   define MAKE_COOLER(x,y) if ((word)(x)-(y) < (word)(x)) {(x) -= (y);} else {(x) = 0;} -#   define MAKE_HOTTER(x,y) (x) += (y) -# endif - -#if defined(AMIGA) && defined(__SASC) -#   define GC_FAR __far -#else -#   define GC_FAR -#endif - - -/*********************************/ -/*                               */ -/* Definitions for conservative  */ -/* collector                     */ -/*                               */ -/*********************************/ - -/*********************************/ -/*                               */ -/* Easily changeable parameters  */ -/*                               */ -/*********************************/ - -/* #define STUBBORN_ALLOC */ -		    /* Enable stubborm allocation, and thus a limited	*/ -		    /* form of incremental collection w/o dirty bits.	*/ - -/* #define ALL_INTERIOR_POINTERS */ -		    /* Forces all pointers into the interior of an 	*/ -		    /* object to be considered valid.  Also causes the	*/ -		    /* sizes of all objects to be inflated by at least 	*/ -		    /* one byte.  This should suffice to guarantee	*/ -		    /* that in the presence of a compiler that does	*/ -		    /* not perform garbage-collector-unsafe		*/ -		    /* optimizations, all portable, strictly ANSI	*/ -		    /* conforming C programs should be safely usable	*/ -		    /* with malloc replaced by GC_malloc and free	*/ -		    /* calls removed.  There are several disadvantages: */ -		    /* 1. There are probably no interesting, portable,	*/ -		    /*    strictly ANSI	conforming C programs.		*/ -		    /* 2. This option makes it hard for the collector	*/ -		    /*    to allocate space that is not ``pointed to''  */ -		    /*    by integers, etc.  Under SunOS 4.X with a 	*/ -		    /*    statically linked libc, we empiricaly		*/ -		    /*    observed that it would be difficult to 	*/ -		    /*	  allocate individual objects larger than 100K.	*/ -		    /* 	  Even if only smaller objects are allocated,	*/ -		    /*    more swap space is likely to be needed.       */ -		    /*    Fortunately, much of this will never be	*/ -		    /*    touched.					*/ -		    /* If you can easily avoid using this option, do.	*/ -		    /* If not, try to keep individual objects small.	*/ -		    /* This is now really controlled at startup,	*/ -		    /* through GC_all_interior_pointers.		*/ -		     -#define PRINTSTATS  /* Print garbage collection statistics          	*/ -		    /* For less verbose output, undefine in reclaim.c 	*/ - -#define PRINTTIMES  /* Print the amount of time consumed by each garbage   */ -		    /* collection.                                         */ - -#define PRINTBLOCKS /* Print object sizes associated with heap blocks,     */ -		    /* whether the objects are atomic or composite, and    */ -		    /* whether or not the block was found to be empty      */ -		    /* during the reclaim phase.  Typically generates       */ -		    /* about one screenful per garbage collection.         */ -#undef PRINTBLOCKS - -#ifdef SILENT -#  ifdef PRINTSTATS -#    undef PRINTSTATS -#  endif -#  ifdef PRINTTIMES -#    undef PRINTTIMES -#  endif -#  ifdef PRINTNBLOCKS -#    undef PRINTNBLOCKS -#  endif -#endif - -#if defined(PRINTSTATS) && !defined(GATHERSTATS) -#   define GATHERSTATS -#endif - -#if defined(PRINTSTATS) || !defined(SMALL_CONFIG) -#   define CONDPRINT  /* Print some things if GC_print_stats is set */ -#endif - -#define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers() - -#define MERGE_SIZES /* Round up some object sizes, so that fewer distinct */ -		    /* free lists are actually maintained.  This applies  */ -		    /* only to the top level routines in misc.c, not to   */ -		    /* user generated code that calls GC_allocobj and     */ -		    /* GC_allocaobj directly.                             */ -		    /* Slows down average programs slightly.  May however */ -		    /* substantially reduce fragmentation if allocation   */ -		    /* request sizes are widely scattered.                */ -		    /* May save significant amounts of space for obj_map  */ -		    /* entries.						  */ - -#if defined(USE_MARK_BYTES) && !defined(ALIGN_DOUBLE) -#  define ALIGN_DOUBLE -   /* We use one byte for every 2 words, which doesn't allow for	*/ -   /* odd numbered words to have mark bits.				*/ -#endif - -#if defined(GC_GCJ_SUPPORT) && ALIGNMENT < 8 && !defined(ALIGN_DOUBLE) -   /* GCJ's Hashtable synchronization code requires 64-bit alignment.  */ -#  define ALIGN_DOUBLE -#endif - -/* ALIGN_DOUBLE requires MERGE_SIZES at present. */ -# if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES) -#   define MERGE_SIZES -# endif - -#if !defined(DONT_ADD_BYTE_AT_END) -# define EXTRA_BYTES GC_all_interior_pointers -#else -# define EXTRA_BYTES 0 -#endif - - -# ifndef LARGE_CONFIG -#   define MINHINCR 16	 /* Minimum heap increment, in blocks of HBLKSIZE  */ -			 /* Must be multiple of largest page size.	   */ -#   define MAXHINCR 2048 /* Maximum heap increment, in blocks              */ -# else -#   define MINHINCR 64 -#   define MAXHINCR 4096 -# endif - -# define TIME_LIMIT 50	   /* We try to keep pause times from exceeding	 */ -			   /* this by much. In milliseconds.		 */ - -# define BL_LIMIT GC_black_list_spacing -			   /* If we need a block of N bytes, and we have */ -			   /* a block of N + BL_LIMIT bytes available, 	 */ -			   /* and N > BL_LIMIT,				 */ -			   /* but all possible positions in it are 	 */ -			   /* blacklisted, we just use it anyway (and	 */ -			   /* print a warning, if warnings are enabled). */ -			   /* This risks subsequently leaking the block	 */ -			   /* due to a false reference.  But not using	 */ -			   /* the block risks unreasonable immediate	 */ -			   /* heap growth.				 */ - -/*********************************/ -/*                               */ -/* Stack saving for debugging	 */ -/*                               */ -/*********************************/ - -#ifdef SAVE_CALL_CHAIN - -/* Fill in the pc and argument information for up to NFRAMES of my	*/ -/* callers.  Ignore my frame and my callers frame.			*/ -struct callinfo; -void GC_save_callers GC_PROTO((struct callinfo info[NFRAMES])); -   -void GC_print_callers GC_PROTO((struct callinfo info[NFRAMES])); - -#endif - -#ifdef NEED_CALLINFO -    struct callinfo { -	word ci_pc;  	/* Caller, not callee, pc	*/ -#	if NARGS > 0 -	    word ci_arg[NARGS];	/* bit-wise complement to avoid retention */ -#	endif -#	if defined(ALIGN_DOUBLE) && (NFRAMES * (NARGS + 1)) % 2 == 1 -	    /* Likely alignment problem. */ -	    word ci_dummy; -#	endif -    }; -#endif - - -/*********************************/ -/*                               */ -/* OS interface routines	 */ -/*                               */ -/*********************************/ - -#ifdef BSD_TIME -#   undef CLOCK_TYPE -#   undef GET_TIME -#   undef MS_TIME_DIFF -#   define CLOCK_TYPE struct timeval -#   define GET_TIME(x) { struct rusage rusage; \ -			 getrusage (RUSAGE_SELF,  &rusage); \ -			 x = rusage.ru_utime; } -#   define MS_TIME_DIFF(a,b) ((double) (a.tv_sec - b.tv_sec) * 1000.0 \ -                               + (double) (a.tv_usec - b.tv_usec) / 1000.0) -#else /* !BSD_TIME */ -# if defined(MSWIN32) || defined(MSWINCE) -#   include <windows.h> -#   include <winbase.h> -#   define CLOCK_TYPE DWORD -#   define GET_TIME(x) x = GetTickCount() -#   define MS_TIME_DIFF(a,b) ((long)((a)-(b))) -# else /* !MSWIN32, !MSWINCE, !BSD_TIME */ -#   include <time.h> -#   if !defined(__STDC__) && defined(SPARC) && defined(SUNOS4) -      clock_t clock();	/* Not in time.h, where it belongs	*/ -#   endif -#   if defined(FREEBSD) && !defined(CLOCKS_PER_SEC) -#     include <machine/limits.h> -#     define CLOCKS_PER_SEC CLK_TCK -#   endif -#   if !defined(CLOCKS_PER_SEC) -#     define CLOCKS_PER_SEC 1000000 -/* - * This is technically a bug in the implementation.  ANSI requires that - * CLOCKS_PER_SEC be defined.  But at least under SunOS4.1.1, it isn't. - * Also note that the combination of ANSI C and POSIX is incredibly gross - * here. The type clock_t is used by both clock() and times().  But on - * some machines these use different notions of a clock tick,  CLOCKS_PER_SEC - * seems to apply only to clock.  Hence we use it here.  On many machines, - * including SunOS, clock actually uses units of microseconds (which are - * not really clock ticks). - */ -#   endif -#   define CLOCK_TYPE clock_t -#   define GET_TIME(x) x = clock() -#   define MS_TIME_DIFF(a,b) ((unsigned long) \ -		(1000.0*(double)((a)-(b))/(double)CLOCKS_PER_SEC)) -# endif /* !MSWIN32 */ -#endif /* !BSD_TIME */ - -/* We use bzero and bcopy internally.  They may not be available.	*/ -# if defined(SPARC) && defined(SUNOS4) -#   define BCOPY_EXISTS -# endif -# if defined(M68K) && defined(AMIGA) -#   define BCOPY_EXISTS -# endif -# if defined(M68K) && defined(NEXT) -#   define BCOPY_EXISTS -# endif -# if defined(VAX) -#   define BCOPY_EXISTS -# endif -# if defined(AMIGA) -#   include <string.h> -#   define BCOPY_EXISTS -# endif -# if defined(MACOSX) -#   define BCOPY_EXISTS -# endif - -# ifndef BCOPY_EXISTS -#   include <string.h> -#   define BCOPY(x,y,n) memcpy(y, x, (size_t)(n)) -#   define BZERO(x,n)  memset(x, 0, (size_t)(n)) -# else -#   define BCOPY(x,y,n) bcopy((char *)(x),(char *)(y),(int)(n)) -#   define BZERO(x,n) bzero((char *)(x),(int)(n)) -# endif - -/* Delay any interrupts or signals that may abort this thread.  Data	*/ -/* structures are in a consistent state outside this pair of calls.	*/ -/* ANSI C allows both to be empty (though the standard isn't very	*/ -/* clear on that point).  Standard malloc implementations are usually	*/ -/* neither interruptable nor thread-safe, and thus correspond to	*/ -/* empty definitions.							*/ -/* It probably doesn't make any sense to declare these to be nonempty	*/ -/* if the code is being optimized, since signal safety relies on some	*/ -/* ordering constraints that are typically not obeyed by optimizing	*/ -/* compilers.								*/ -# ifdef PCR -#   define DISABLE_SIGNALS() \ -		 PCR_Th_SetSigMask(PCR_allSigsBlocked,&GC_old_sig_mask) -#   define ENABLE_SIGNALS() \ -		PCR_Th_SetSigMask(&GC_old_sig_mask, NIL) -# else -#   if defined(THREADS) || defined(AMIGA)  \ -	|| defined(MSWIN32) || defined(MSWINCE) || defined(MACOS) \ -	|| defined(DJGPP) || defined(NO_SIGNALS)  -			/* Also useful for debugging.		*/ -	/* Should probably use thr_sigsetmask for GC_SOLARIS_THREADS. */ -#     define DISABLE_SIGNALS() -#     define ENABLE_SIGNALS() -#   else -#     define DISABLE_SIGNALS() GC_disable_signals() -	void GC_disable_signals(); -#     define ENABLE_SIGNALS() GC_enable_signals() -	void GC_enable_signals(); -#   endif -# endif - -/* - * Stop and restart mutator threads. - */ -# ifdef PCR -#     include "th/PCR_ThCtl.h" -#     define STOP_WORLD() \ - 	PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_stopNormal, \ - 				   PCR_allSigsBlocked, \ - 				   PCR_waitForever) -#     define START_WORLD() \ -	PCR_ThCtl_SetExclusiveMode(PCR_ThCtl_ExclusiveMode_null, \ - 				   PCR_allSigsBlocked, \ - 				   PCR_waitForever); -# else -#   if defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \ -	|| defined(GC_PTHREADS) -      void GC_stop_world(); -      void GC_start_world(); -#     define STOP_WORLD() GC_stop_world() -#     define START_WORLD() GC_start_world() -#   else -#     define STOP_WORLD() -#     define START_WORLD() -#   endif -# endif - -/* Abandon ship */ -# ifdef PCR -#   define ABORT(s) PCR_Base_Panic(s) -# else -#   ifdef SMALL_CONFIG -#	define ABORT(msg) abort(); -#   else -	GC_API void GC_abort GC_PROTO((GC_CONST char * msg)); -#       define ABORT(msg) GC_abort(msg); -#   endif -# endif - -/* Exit abnormally, but without making a mess (e.g. out of memory) */ -# ifdef PCR -#   define EXIT() PCR_Base_Exit(1,PCR_waitForever) -# else -#   define EXIT() (void)exit(1) -# endif - -/* Print warning message, e.g. almost out of memory.	*/ -# define WARN(msg,arg) (*GC_current_warn_proc)("GC Warning: " msg, (GC_word)(arg)) -extern GC_warn_proc GC_current_warn_proc; - -/* Get environment entry */ -#if !defined(NO_GETENV) -#   define GETENV(name) getenv(name) -#else -#   define GETENV(name) 0 -#endif - -/*********************************/ -/*                               */ -/* Word-size-dependent defines   */ -/*                               */ -/*********************************/ - -#if CPP_WORDSZ == 32 -#  define WORDS_TO_BYTES(x)   ((x)<<2) -#  define BYTES_TO_WORDS(x)   ((x)>>2) -#  define LOGWL               ((word)5)    /* log[2] of CPP_WORDSZ */ -#  define modWORDSZ(n) ((n) & 0x1f)        /* n mod size of word	    */ -#  if ALIGNMENT != 4 -#	define UNALIGNED -#  endif -#endif - -#if CPP_WORDSZ == 64 -#  define WORDS_TO_BYTES(x)   ((x)<<3) -#  define BYTES_TO_WORDS(x)   ((x)>>3) -#  define LOGWL               ((word)6)    /* log[2] of CPP_WORDSZ */ -#  define modWORDSZ(n) ((n) & 0x3f)        /* n mod size of word	    */ -#  if ALIGNMENT != 8 -#	define UNALIGNED -#  endif -#endif - -#define WORDSZ ((word)CPP_WORDSZ) -#define SIGNB  ((word)1 << (WORDSZ-1)) -#define BYTES_PER_WORD      ((word)(sizeof (word))) -#define ONES                ((word)(signed_word)(-1)) -#define divWORDSZ(n) ((n) >> LOGWL)	   /* divide n by size of word      */ - -/*********************/ -/*                   */ -/*  Size Parameters  */ -/*                   */ -/*********************/ - -/*  heap block size, bytes. Should be power of 2 */ - -#ifndef HBLKSIZE -# ifdef SMALL_CONFIG -#   define CPP_LOG_HBLKSIZE 10 -# else -#   if (CPP_WORDSZ == 32) || (defined(HPUX) && defined(HP_PA)) -      /* HPUX/PA seems to use 4K pages with the 64 bit ABI */ -#     define CPP_LOG_HBLKSIZE 12 -#   else -#     define CPP_LOG_HBLKSIZE 13 -#   endif -# endif -#else -# if HBLKSIZE == 512 -#   define CPP_LOG_HBLKSIZE 9 -# endif -# if HBLKSIZE == 1024 -#   define CPP_LOG_HBLKSIZE 10 -# endif -# if HBLKSIZE == 2048 -#   define CPP_LOG_HBLKSIZE 11 -# endif -# if HBLKSIZE == 4096 -#   define CPP_LOG_HBLKSIZE 12 -# endif -# if HBLKSIZE == 8192 -#   define CPP_LOG_HBLKSIZE 13 -# endif -# if HBLKSIZE == 16384 -#   define CPP_LOG_HBLKSIZE 14 -# endif -# ifndef CPP_LOG_HBLKSIZE -    --> fix HBLKSIZE -# endif -# undef HBLKSIZE -#endif -# define CPP_HBLKSIZE (1 << CPP_LOG_HBLKSIZE) -# define LOG_HBLKSIZE   ((word)CPP_LOG_HBLKSIZE) -# define HBLKSIZE ((word)CPP_HBLKSIZE) - - -/*  max size objects supported by freelist (larger objects may be   */ -/*  allocated, but less efficiently)                                */ - -#define CPP_MAXOBJBYTES (CPP_HBLKSIZE/2) -#define MAXOBJBYTES ((word)CPP_MAXOBJBYTES) -#define CPP_MAXOBJSZ    BYTES_TO_WORDS(CPP_HBLKSIZE/2) -#define MAXOBJSZ ((word)CPP_MAXOBJSZ) -		 -# define divHBLKSZ(n) ((n) >> LOG_HBLKSIZE) - -# define HBLK_PTR_DIFF(p,q) divHBLKSZ((ptr_t)p - (ptr_t)q) -	/* Equivalent to subtracting 2 hblk pointers.	*/ -	/* We do it this way because a compiler should	*/ -	/* find it hard to use an integer division	*/ -	/* instead of a shift.  The bundled SunOS 4.1	*/ -	/* o.w. sometimes pessimizes the subtraction to	*/ -	/* involve a call to .div.			*/ -  -# define modHBLKSZ(n) ((n) & (HBLKSIZE-1)) -  -# define HBLKPTR(objptr) ((struct hblk *)(((word) (objptr)) & ~(HBLKSIZE-1))) - -# define HBLKDISPL(objptr) (((word) (objptr)) & (HBLKSIZE-1)) - -/* Round up byte allocation requests to integral number of words, etc. */ -# define ROUNDED_UP_WORDS(n) \ -	BYTES_TO_WORDS((n) + (WORDS_TO_BYTES(1) - 1 + EXTRA_BYTES)) -# ifdef ALIGN_DOUBLE -#       define ALIGNED_WORDS(n) \ -	    (BYTES_TO_WORDS((n) + WORDS_TO_BYTES(2) - 1 + EXTRA_BYTES) & ~1) -# else -#       define ALIGNED_WORDS(n) ROUNDED_UP_WORDS(n) -# endif -# define SMALL_OBJ(bytes) ((bytes) < (MAXOBJBYTES - EXTRA_BYTES)) -# define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES) -# ifndef MIN_WORDS -    /* MIN_WORDS is the size of the smallest allocated object.	*/ -    /* 1 and 2 are the only valid values.			*/ -    /* 2 must be used if:					*/ -    /* - GC_gcj_malloc can be used for objects of requested 	*/ -    /*   size  smaller than 2 words, or				*/ -    /* - USE_MARK_BYTES is defined.				*/ -#   if defined(USE_MARK_BYTES) || defined(GC_GCJ_SUPPORT) -#     define MIN_WORDS 2   	/* Smallest allocated object.	*/ -#   else -#     define MIN_WORDS 1 -#   endif -# endif - - -/* - * Hash table representation of sets of pages.  This assumes it is - * OK to add spurious entries to sets. - * Used by black-listing code, and perhaps by dirty bit maintenance code. - */ -  -# ifdef LARGE_CONFIG -#   define LOG_PHT_ENTRIES  19  /* Collisions likely at 512K blocks,	*/ -				/* which is >= 2GB.  Each table takes	*/ -				/* 64KB.				*/ -# else -#   ifdef SMALL_CONFIG -#     define LOG_PHT_ENTRIES  14 /* Collisions are likely if heap grows	*/ -				 /* to more than 16K hblks = 64MB.	*/ -				 /* Each hash table occupies 2K bytes.   */ -#   else /* default "medium" configuration */ -#     define LOG_PHT_ENTRIES  16 /* Collisions are likely if heap grows	*/ -				 /* to more than 16K hblks >= 256MB.	*/ -				 /* Each hash table occupies 8K bytes.  */ -#   endif -# endif -# define PHT_ENTRIES ((word)1 << LOG_PHT_ENTRIES) -# define PHT_SIZE (PHT_ENTRIES >> LOGWL) -typedef word page_hash_table[PHT_SIZE]; - -# define PHT_HASH(addr) ((((word)(addr)) >> LOG_HBLKSIZE) & (PHT_ENTRIES - 1)) - -# define get_pht_entry_from_index(bl, index) \ -		(((bl)[divWORDSZ(index)] >> modWORDSZ(index)) & 1) -# define set_pht_entry_from_index(bl, index) \ -		(bl)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index) -# define clear_pht_entry_from_index(bl, index) \ -		(bl)[divWORDSZ(index)] &= ~((word)1 << modWORDSZ(index)) -/* And a dumb but thread-safe version of set_pht_entry_from_index.	*/ -/* This sets (many) extra bits.						*/ -# define set_pht_entry_from_index_safe(bl, index) \ -		(bl)[divWORDSZ(index)] = ONES -	 - - -/********************************************/ -/*                                          */ -/*    H e a p   B l o c k s                 */ -/*                                          */ -/********************************************/ - -/*  heap block header */ -#define HBLKMASK   (HBLKSIZE-1) - -#define BITS_PER_HBLK (CPP_HBLKSIZE * 8) - -#define MARK_BITS_PER_HBLK (BITS_PER_HBLK/CPP_WORDSZ) -	   /* upper bound                                    */ -	   /* We allocate 1 bit/word, unless USE_MARK_BYTES  */ -	   /* is defined.  Only the first word   	     */ -	   /* in each object is actually marked.             */ - -# ifdef USE_MARK_BYTES -#   define MARK_BITS_SZ (MARK_BITS_PER_HBLK/2) -	/* Unlike the other case, this is in units of bytes.		*/ -	/* We actually allocate only every second mark bit, since we	*/ -	/* force all objects to be doubleword aligned.			*/ -	/* However, each mark bit is allocated as a byte.		*/ -# else -#   define MARK_BITS_SZ (MARK_BITS_PER_HBLK/CPP_WORDSZ) -# endif - -/* We maintain layout maps for heap blocks containing objects of a given */ -/* size.  Each entry in this map describes a byte offset and has the	 */ -/* following type.							 */ -typedef unsigned char map_entry_type; - -struct hblkhdr { -    word hb_sz;  /* If in use, size in words, of objects in the block. */ -		 /* if free, the size in bytes of the whole block      */ -    struct hblk * hb_next; 	/* Link field for hblk free list	 */ -    				/* and for lists of chunks waiting to be */ -    				/* reclaimed.				 */ -    struct hblk * hb_prev;	/* Backwards link for free list.	*/ -    word hb_descr;   		/* object descriptor for marking.  See	*/ -    				/* mark.h.				*/ -    map_entry_type * hb_map;	 -    			/* A pointer to a pointer validity map of the block. */ -    		      	/* See GC_obj_map.				     */ -    		     	/* Valid for all blocks with headers.		     */ -    		     	/* Free blocks point to GC_invalid_map.		     */ -    unsigned char hb_obj_kind; -    			 /* Kind of objects in the block.  Each kind 	*/ -    			 /* identifies a mark procedure and a set of 	*/ -    			 /* list headers.  Sometimes called regions.	*/ -    unsigned char hb_flags; -#	define IGNORE_OFF_PAGE	1	/* Ignore pointers that do not	*/ -					/* point to the first page of 	*/ -					/* this object.			*/ -#	define WAS_UNMAPPED 2	/* This is a free block, which has	*/ -				/* been unmapped from the address 	*/ -				/* space.				*/ -				/* GC_remap must be invoked on it	*/ -				/* before it can be reallocated.	*/ -				/* Only set with USE_MUNMAP.		*/ -    unsigned short hb_last_reclaimed; -    				/* Value of GC_gc_no when block was	*/ -    				/* last allocated or swept. May wrap.   */ -				/* For a free block, this is maintained */ -				/* only for USE_MUNMAP, and indicates	*/ -				/* when the header was allocated, or	*/ -				/* when the size of the block last	*/ -				/* changed.				*/ -#   ifdef USE_MARK_BYTES -      union { -        char _hb_marks[MARK_BITS_SZ]; -			    /* The i'th byte is 1 if the object 	*/ -			    /* starting at word 2i is marked, 0 o.w.	*/ -	word dummy;	/* Force word alignment of mark bytes. */ -      } _mark_byte_union; -#     define hb_marks _mark_byte_union._hb_marks -#   else -      word hb_marks[MARK_BITS_SZ]; -			    /* Bit i in the array refers to the             */ -			    /* object starting at the ith word (header      */ -			    /* INCLUDED) in the heap block.                 */ -			    /* The lsb of word 0 is numbered 0.		    */ -			    /* Unused bits are invalid, and are 	    */ -			    /* occasionally set, e.g for uncollectable	    */ -			    /* objects.					    */ -#   endif /* !USE_MARK_BYTES */ -}; - -/*  heap block body */ - -# define BODY_SZ (HBLKSIZE/sizeof(word)) - -struct hblk { -    word hb_body[BODY_SZ]; -}; - -# define HBLK_IS_FREE(hdr) ((hdr) -> hb_map == GC_invalid_map) - -# define OBJ_SZ_TO_BLOCKS(sz) \ -    divHBLKSZ(WORDS_TO_BYTES(sz) + HBLKSIZE-1) -    /* Size of block (in units of HBLKSIZE) needed to hold objects of	*/ -    /* given sz (in words).						*/ - -/* Object free list link */ -# define obj_link(p) (*(ptr_t *)(p)) - -# define LOG_MAX_MARK_PROCS 6 -# define MAX_MARK_PROCS (1 << LOG_MAX_MARK_PROCS) - -/* Root sets.  Logically private to mark_rts.c.  But we don't want the	*/ -/* tables scanned, so we put them here.					*/ -/* MAX_ROOT_SETS is the maximum number of ranges that can be 	*/ -/* registered as static roots. 					*/ -# ifdef LARGE_CONFIG -#   define MAX_ROOT_SETS 4096 -# else -#   ifdef PCR -#     define MAX_ROOT_SETS 1024 -#   else -#     if defined(MSWIN32) || defined(MSWINCE) -#	define MAX_ROOT_SETS 1024 -	    /* Under NT, we add only written pages, which can result 	*/ -	    /* in many small root sets.					*/ -#     else -#       define MAX_ROOT_SETS 256 -#     endif -#   endif -# endif - -# define MAX_EXCLUSIONS (MAX_ROOT_SETS/4) -/* Maximum number of segments that can be excluded from root sets.	*/ - -/* - * Data structure for excluded static roots. - */ -struct exclusion { -    ptr_t e_start; -    ptr_t e_end; -}; - -/* Data structure for list of root sets.				*/ -/* We keep a hash table, so that we can filter out duplicate additions.	*/ -/* Under Win32, we need to do a better job of filtering overlaps, so	*/ -/* we resort to sequential search, and pay the price.			*/ -struct roots { -	ptr_t r_start; -	ptr_t r_end; -#	if !defined(MSWIN32) && !defined(MSWINCE) -	  struct roots * r_next; -#	endif -	GC_bool r_tmp; -	  	/* Delete before registering new dynamic libraries */ -}; - -#if !defined(MSWIN32) && !defined(MSWINCE) -    /* Size of hash table index to roots.	*/ -#   define LOG_RT_SIZE 6 -#   define RT_SIZE (1 << LOG_RT_SIZE) /* Power of 2, may be != MAX_ROOT_SETS */ -#endif - -/* Lists of all heap blocks and free lists	*/ -/* as well as other random data structures	*/ -/* that should not be scanned by the		*/ -/* collector.					*/ -/* These are grouped together in a struct	*/ -/* so that they can be easily skipped by the	*/ -/* GC_mark routine.				*/ -/* The ordering is weird to make GC_malloc	*/ -/* faster by keeping the important fields	*/ -/* sufficiently close together that a		*/ -/* single load of a base register will do.	*/ -/* Scalars that could easily appear to		*/ -/* be pointers are also put here.		*/ -/* The main fields should precede any 		*/ -/* conditionally included fields, so that	*/ -/* gc_inl.h will work even if a different set	*/ -/* of macros is defined when the client is	*/ -/* compiled.					*/ - -struct _GC_arrays { -  word _heapsize; -  word _max_heapsize; -  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.						*/ -  word _large_allocd_bytes; -  	/* Total number of bytes in allocated large objects blocks.	*/ -  	/* For the purposes of this counter and the next one only, a 	*/ -  	/* large object is one that occupies a block of at least	*/ -  	/* 2*HBLKSIZE.							*/ -  word _max_large_allocd_bytes; -  	/* Maximum number of bytes that were ever allocated in		*/ -  	/* large object blocks.  This is used to help decide when it	*/ -  	/* is safe to split up a large block.				*/ -  word _words_allocd_before_gc; -		/* Number of words allocated before this	*/ -		/* collection cycle.				*/ -# ifndef SEPARATE_GLOBALS -    word _words_allocd; -  	/* Number of words allocated during this collection cycle */ -# endif -  word _words_wasted; -  	/* Number of words wasted due to internal fragmentation	*/ -  	/* in large objects, or due to dropping blacklisted     */ -	/* blocks, since last gc.  Approximate.                 */ -  word _words_finalized; -  	/* Approximate number of words in objects (and headers)	*/ -  	/* That became ready for finalization in the last 	*/ -  	/* collection.						*/ -  word _non_gc_bytes_at_gc; -  	/* Number of explicitly managed bytes of storage 	*/ -  	/* at last collection.					*/ -  word _mem_freed; -  	/* Number of explicitly deallocated words of memory	*/ -  	/* since last collection.				*/ -  word _finalizer_mem_freed; -  	/* Words of memory explicitly deallocated while 	*/ -  	/* finalizers were running.  Used to approximate mem.	*/ -  	/* explicitly deallocated by finalizers.		*/ -  ptr_t _scratch_end_ptr; -  ptr_t _scratch_last_end_ptr; -	/* Used by headers.c, and can easily appear to point to	*/ -	/* heap.						*/ -  GC_mark_proc _mark_procs[MAX_MARK_PROCS]; -  	/* Table of user-defined mark procedures.  There is	*/ -	/* a small number of these, which can be referenced	*/ -	/* by DS_PROC mark descriptors.  See gc_mark.h.		*/ - -# ifndef SEPARATE_GLOBALS -    ptr_t _objfreelist[MAXOBJSZ+1]; -			  /* free list for objects */ -    ptr_t _aobjfreelist[MAXOBJSZ+1]; -			  /* free list for atomic objs 	*/ -# endif - -  ptr_t _uobjfreelist[MAXOBJSZ+1]; -			  /* uncollectable but traced objs 	*/ -			  /* objects on this and auobjfreelist  */ -			  /* are always marked, except during   */ -			  /* garbage collections.		*/ -# ifdef ATOMIC_UNCOLLECTABLE -    ptr_t _auobjfreelist[MAXOBJSZ+1]; -# endif -			  /* uncollectable but traced objs 	*/ - -# ifdef GATHERSTATS -    word _composite_in_use; -   		/* Number of words in accessible composite	*/ -		/* objects.					*/ -    word _atomic_in_use; -   		/* Number of words in accessible atomic		*/ -		/* objects.					*/ -# endif -# ifdef USE_MUNMAP -    word _unmapped_bytes; -# endif -# ifdef MERGE_SIZES -    unsigned _size_map[WORDS_TO_BYTES(MAXOBJSZ+1)]; -    	/* Number of words to allocate for a given allocation request in */ -    	/* bytes.							 */ -# endif  - -# ifdef STUBBORN_ALLOC -    ptr_t _sobjfreelist[MAXOBJSZ+1]; -# endif -  			  /* free list for immutable objects	*/ -  map_entry_type * _obj_map[MAXOBJSZ+1]; -                       /* If not NIL, then a pointer to a map of valid  */ -    		       /* object addresses. _obj_map[sz][i] is j if the	*/ -    		       /* address block_start+i is a valid pointer      */ -    		       /* to an object at block_start +			*/ - 		       /* WORDS_TO_BYTES(BYTES_TO_WORDS(i) - j)		*/ -  		       /* I.e. j is a word displacement from the	*/ -  		       /* object beginning.				*/ -  		       /* The entry is OBJ_INVALID if the corresponding	*/ -  		       /* address is not a valid pointer.  It is 	*/ -  		       /* OFFSET_TOO_BIG if the value j would be too 	*/ -  		       /* large to fit in the entry.  (Note that the	*/ -  		       /* size of these entries matters, both for 	*/ -  		       /* space consumption and for cache utilization.	*/ -#   define OFFSET_TOO_BIG 0xfe -#   define OBJ_INVALID 0xff -#   define MAP_ENTRY(map, bytes) (map)[bytes] -#   define MAP_ENTRIES HBLKSIZE -#   define MAP_SIZE MAP_ENTRIES -#   define CPP_MAX_OFFSET (OFFSET_TOO_BIG - 1)	 -#   define MAX_OFFSET ((word)CPP_MAX_OFFSET) -    /* The following are used only if GC_all_interior_ptrs != 0 */ -# 	define VALID_OFFSET_SZ \ -	  (CPP_MAX_OFFSET > WORDS_TO_BYTES(CPP_MAXOBJSZ)? \ -	   CPP_MAX_OFFSET+1 \ -	   : WORDS_TO_BYTES(CPP_MAXOBJSZ)+1) -  	char _valid_offsets[VALID_OFFSET_SZ]; -				/* GC_valid_offsets[i] == TRUE ==> i 	*/ -				/* is registered as a displacement.	*/ -#	define OFFSET_VALID(displ) \ -	  (GC_all_interior_pointers || GC_valid_offsets[displ]) -  	char _modws_valid_offsets[sizeof(word)]; -				/* GC_valid_offsets[i] ==>		  */ -				/* GC_modws_valid_offsets[i%sizeof(word)] */ -# ifdef STUBBORN_ALLOC -    page_hash_table _changed_pages; -        /* Stubborn object pages that were changes since last call to	*/ -	/* GC_read_changed.						*/ -    page_hash_table _prev_changed_pages; -        /* Stubborn object pages that were changes before last call to	*/ -	/* GC_read_changed.						*/ -# endif -# if defined(PROC_VDB) || defined(MPROTECT_VDB) -    page_hash_table _grungy_pages; /* Pages that were dirty at last 	   */ -				     /* GC_read_dirty.			   */ -# endif -# ifdef MPROTECT_VDB -    VOLATILE page_hash_table _dirty_pages;	 -			/* Pages dirtied since last GC_read_dirty. */ -# endif -# ifdef PROC_VDB -    page_hash_table _written_pages;	/* Pages ever dirtied	*/ -# endif -# ifdef LARGE_CONFIG -#   if CPP_WORDSZ > 32 -#     define MAX_HEAP_SECTS 4096 	/* overflows at roughly 64 GB	   */ -#   else -#     define MAX_HEAP_SECTS 768		/* Separately added heap sections. */ -#   endif -# else -#   ifdef SMALL_CONFIG -#     define MAX_HEAP_SECTS 128		/* Roughly 1GB			*/ -#   else -#     define MAX_HEAP_SECTS 384		/* Roughly 3GB			*/ -#   endif -# endif -  struct HeapSect { -      ptr_t hs_start; word hs_bytes; -  } _heap_sects[MAX_HEAP_SECTS]; -# if defined(MSWIN32) || defined(MSWINCE) -    ptr_t _heap_bases[MAX_HEAP_SECTS]; -    		/* Start address of memory regions obtained from kernel. */ -# endif -# ifdef MSWINCE -    word _heap_lengths[MAX_HEAP_SECTS]; -    		/* Commited lengths of memory regions obtained from kernel. */ -# endif -  struct roots _static_roots[MAX_ROOT_SETS]; -# if !defined(MSWIN32) && !defined(MSWINCE) -    struct roots * _root_index[RT_SIZE]; -# endif -  struct exclusion _excl_table[MAX_EXCLUSIONS]; -  /* Block header index; see gc_headers.h */ -  bottom_index * _all_nils; -  bottom_index * _top_index [TOP_SZ]; -#ifdef SAVE_CALL_CHAIN -  struct callinfo _last_stack[NFRAMES];	/* Stack at last garbage collection.*/ -  					/* Useful for debugging	mysterious  */ -  					/* object disappearances.	    */ -  					/* In the multithreaded case, we    */ -  					/* currently only save the calling  */ -  					/* stack.			    */ -#endif -}; - -GC_API GC_FAR struct _GC_arrays GC_arrays;  - -# ifndef SEPARATE_GLOBALS -#   define GC_objfreelist GC_arrays._objfreelist -#   define GC_aobjfreelist GC_arrays._aobjfreelist -#   define GC_words_allocd GC_arrays._words_allocd -# endif -# define GC_uobjfreelist GC_arrays._uobjfreelist -# ifdef ATOMIC_UNCOLLECTABLE -#   define GC_auobjfreelist GC_arrays._auobjfreelist -# endif -# define GC_sobjfreelist GC_arrays._sobjfreelist -# define GC_valid_offsets GC_arrays._valid_offsets -# define GC_modws_valid_offsets GC_arrays._modws_valid_offsets -# ifdef STUBBORN_ALLOC -#    define GC_changed_pages GC_arrays._changed_pages -#    define GC_prev_changed_pages GC_arrays._prev_changed_pages -# endif -# define GC_obj_map GC_arrays._obj_map -# define GC_last_heap_addr GC_arrays._last_heap_addr -# define GC_prev_heap_addr GC_arrays._prev_heap_addr -# define GC_words_wasted GC_arrays._words_wasted -# define GC_large_free_bytes GC_arrays._large_free_bytes -# define GC_large_allocd_bytes GC_arrays._large_allocd_bytes -# define GC_max_large_allocd_bytes GC_arrays._max_large_allocd_bytes -# define GC_words_finalized GC_arrays._words_finalized -# define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc -# define GC_mem_freed GC_arrays._mem_freed -# define GC_finalizer_mem_freed GC_arrays._finalizer_mem_freed -# define GC_scratch_end_ptr GC_arrays._scratch_end_ptr -# define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr -# define GC_mark_procs GC_arrays._mark_procs -# define GC_heapsize GC_arrays._heapsize -# define GC_max_heapsize GC_arrays._max_heapsize -# define GC_requested_heapsize GC_arrays._requested_heapsize -# define GC_words_allocd_before_gc GC_arrays._words_allocd_before_gc -# define GC_heap_sects GC_arrays._heap_sects -# define GC_last_stack GC_arrays._last_stack -# ifdef USE_MUNMAP -#   define GC_unmapped_bytes GC_arrays._unmapped_bytes -# endif -# if defined(MSWIN32) || defined(MSWINCE) -#   define GC_heap_bases GC_arrays._heap_bases -# endif -# ifdef MSWINCE -#   define GC_heap_lengths GC_arrays._heap_lengths -# endif -# define GC_static_roots GC_arrays._static_roots -# define GC_root_index GC_arrays._root_index -# define GC_excl_table GC_arrays._excl_table -# define GC_all_nils GC_arrays._all_nils -# define GC_top_index GC_arrays._top_index -# if defined(PROC_VDB) || defined(MPROTECT_VDB) -#   define GC_grungy_pages GC_arrays._grungy_pages -# endif -# ifdef MPROTECT_VDB -#   define GC_dirty_pages GC_arrays._dirty_pages -# endif -# ifdef PROC_VDB -#   define GC_written_pages GC_arrays._written_pages -# endif -# ifdef GATHERSTATS -#   define GC_composite_in_use GC_arrays._composite_in_use -#   define GC_atomic_in_use GC_arrays._atomic_in_use -# endif -# ifdef MERGE_SIZES -#   define GC_size_map GC_arrays._size_map -# endif - -# define beginGC_arrays ((ptr_t)(&GC_arrays)) -# define endGC_arrays (((ptr_t)(&GC_arrays)) + (sizeof GC_arrays)) - -#define USED_HEAP_SIZE (GC_heapsize - GC_large_free_bytes) - -/* Object kinds: */ -# define MAXOBJKINDS 16 - -extern struct obj_kind { -   ptr_t *ok_freelist;	/* Array of free listheaders for this kind of object */ -   			/* Point either to GC_arrays or to storage allocated */ -   			/* with GC_scratch_alloc.			     */ -   struct hblk **ok_reclaim_list; -   			/* List headers for lists of blocks waiting to be */ -   			/* swept.					  */ -   word ok_descriptor;  /* Descriptor template for objects in this	*/ -   			/* block.					*/ -   GC_bool ok_relocate_descr; -   			/* Add object size in bytes to descriptor 	*/ -   			/* template to obtain descriptor.  Otherwise	*/ -   			/* template is used as is.			*/ -   GC_bool ok_init;   /* Clear objects before putting them on the free list. */ -} GC_obj_kinds[MAXOBJKINDS]; - -# define beginGC_obj_kinds ((ptr_t)(&GC_obj_kinds)) -# define endGC_obj_kinds (beginGC_obj_kinds + (sizeof GC_obj_kinds)) - -/* Variables that used to be in GC_arrays, but need to be accessed by 	*/ -/* inline allocation code.  If they were in GC_arrays, the inlined 	*/ -/* allocation code would include GC_arrays offsets (as it did), which	*/ -/* introduce maintenance problems.					*/ - -#ifdef SEPARATE_GLOBALS -  word GC_words_allocd; -  	/* Number of words allocated during this collection cycle */ -  ptr_t GC_objfreelist[MAXOBJSZ+1]; -			  /* free list for NORMAL objects */ -# define beginGC_objfreelist ((ptr_t)(&GC_objfreelist)) -# define endGC_objfreelist (beginGC_objfreelist + sizeof(GC_objfreelist)) - -  ptr_t GC_aobjfreelist[MAXOBJSZ+1]; -			  /* free list for atomic (PTRFREE) objs 	*/ -# define beginGC_aobjfreelist ((ptr_t)(&GC_aobjfreelist)) -# define endGC_aobjfreelist (beginGC_aobjfreelist + sizeof(GC_aobjfreelist)) -#endif - -/* Predefined kinds: */ -# define PTRFREE 0 -# define NORMAL  1 -# define UNCOLLECTABLE 2 -# ifdef ATOMIC_UNCOLLECTABLE -#   define AUNCOLLECTABLE 3 -#   define STUBBORN 4 -#   define IS_UNCOLLECTABLE(k) (((k) & ~1) == UNCOLLECTABLE) -# else -#   define STUBBORN 3 -#   define IS_UNCOLLECTABLE(k) ((k) == UNCOLLECTABLE) -# endif - -extern int GC_n_kinds; - -GC_API word GC_fo_entries; - -extern word GC_n_heap_sects;	/* Number of separately added heap	*/ -				/* sections.				*/ - -extern word GC_page_size; - -# if defined(MSWIN32) || defined(MSWINCE) -  struct _SYSTEM_INFO; -  extern struct _SYSTEM_INFO GC_sysinfo; -  extern word GC_n_heap_bases;	/* See GC_heap_bases.	*/ -# endif - -extern word GC_total_stack_black_listed; -			/* Number of bytes on stack blacklist. 	*/ - -extern word GC_black_list_spacing; -			/* Average number of bytes between blacklisted	*/ -			/* blocks. Approximate.				*/ -			/* Counts only blocks that are 			*/ -			/* "stack-blacklisted", i.e. that are 		*/ -			/* problematic in the interior of an object.	*/ - -extern map_entry_type * GC_invalid_map; -			/* Pointer to the nowhere valid hblk map */ -			/* Blocks pointing to this map are free. */ - -extern struct hblk * GC_hblkfreelist[]; -				/* List of completely empty heap blocks	*/ -				/* Linked through hb_next field of 	*/ -				/* header structure associated with	*/ -				/* block.				*/ - -extern GC_bool GC_objects_are_marked;	/* There are marked objects in  */ -					/* the heap.			*/ - -#ifndef SMALL_CONFIG -  extern GC_bool GC_incremental; -			/* Using incremental/generational collection. */ -# define TRUE_INCREMENTAL \ -	(GC_incremental && GC_time_limit != GC_TIME_UNLIMITED) -	/* True incremental, not just generational, mode */ -#else -# define GC_incremental FALSE -			/* Hopefully allow optimizer to remove some code. */ -# define TRUE_INCREMENTAL FALSE -#endif - -extern GC_bool GC_dirty_maintained; -				/* Dirty bits are being maintained, 	*/ -				/* either for incremental collection,	*/ -				/* or to limit the root set.		*/ - -extern word GC_root_size;	/* Total size of registered root sections */ - -extern GC_bool GC_debugging_started;	/* GC_debug_malloc has been called. */  - -extern long GC_large_alloc_warn_interval; -	/* Interval between unsuppressed warnings.	*/ - -extern long GC_large_alloc_warn_suppressed; -	/* Number of warnings suppressed so far.	*/ - -/* Operations */ -# ifndef abs -#   define abs(x)  ((x) < 0? (-(x)) : (x)) -# endif - - -/*  Marks are in a reserved area in                          */ -/*  each heap block.  Each word has one mark bit associated  */ -/*  with it. Only those corresponding to the beginning of an */ -/*  object are used.                                         */ - -/* Set mark bit correctly, even if mark bits may be concurrently 	*/ -/* accessed.								*/ -#ifdef PARALLEL_MARK -# define OR_WORD(addr, bits) \ -	{ word old; \ -	  do { \ -	    old = *((volatile word *)addr); \ -	  } while (!GC_compare_and_exchange((addr), old, old | (bits))); \ -	} -# define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \ -	{ word old; \ -	  word my_bits = (bits); \ -	  do { \ -	    old = *((volatile word *)addr); \ -	    if (old & my_bits) goto exit_label; \ -	  } while (!GC_compare_and_exchange((addr), old, old | my_bits)); \ -	} -#else -# define OR_WORD(addr, bits) *(addr) |= (bits) -# define OR_WORD_EXIT_IF_SET(addr, bits, exit_label) \ -	{ \ -	  word old = *(addr); \ -	  word my_bits = (bits); \ -	  if (old & my_bits) goto exit_label; \ -	  *(addr) = (old | my_bits); \ -	} -#endif - -/* Mark bit operations */ - -/* - * Retrieve, set, clear the mark bit corresponding - * to the nth word in a given heap block. - * - * (Recall that bit n corresponds to object beginning at word n - * relative to the beginning of the block, including unused words) - */ - -#ifdef USE_MARK_BYTES -# define mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n) >> 1]) -# define set_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n)>>1]) = 1 -# define clear_mark_bit_from_hdr(hhdr,n) ((hhdr)->hb_marks[(n)>>1]) = 0 -#else /* !USE_MARK_BYTES */ -# define mark_bit_from_hdr(hhdr,n) (((hhdr)->hb_marks[divWORDSZ(n)] \ -			    >> (modWORDSZ(n))) & (word)1) -# define set_mark_bit_from_hdr(hhdr,n) \ -			    OR_WORD((hhdr)->hb_marks+divWORDSZ(n), \ -				    (word)1 << modWORDSZ(n)) -# define clear_mark_bit_from_hdr(hhdr,n) (hhdr)->hb_marks[divWORDSZ(n)] \ -				&= ~((word)1 << modWORDSZ(n)) -#endif /* !USE_MARK_BYTES */ - -/* Important internal collector routines */ - -ptr_t GC_approx_sp GC_PROTO((void)); -   -GC_bool GC_should_collect GC_PROTO((void)); -   -void GC_apply_to_all_blocks GC_PROTO(( \ -    void (*fn) GC_PROTO((struct hblk *h, word client_data)), \ -    word client_data)); -  			/* Invoke fn(hbp, client_data) for each 	*/ -  			/* allocated heap block.			*/ -struct hblk * GC_next_used_block GC_PROTO((struct hblk * h)); -  			/* Return first in-use block >= h	*/ -struct hblk * GC_prev_block GC_PROTO((struct hblk * h)); -  			/* Return last block <= h.  Returned block	*/ -  			/* is managed by GC, but may or may not be in	*/ -			/* use.						*/ -void GC_mark_init GC_PROTO((void)); -void GC_clear_marks GC_PROTO((void));	/* Clear mark bits for all heap objects. */ -void GC_invalidate_mark_state GC_PROTO((void)); -					/* Tell the marker that	marked 	   */ -  					/* objects may point to	unmarked   */ -  					/* ones, and roots may point to	   */ -  					/* unmarked objects.		   */ -  					/* Reset mark stack.		   */ -GC_bool GC_mark_stack_empty GC_PROTO((void)); -GC_bool GC_mark_some GC_PROTO((ptr_t cold_gc_frame)); -  			/* Perform about one pages worth of marking	*/ -  			/* work of whatever kind is needed.  Returns	*/ -  			/* quickly if no collection is in progress.	*/ -  			/* Return TRUE if mark phase finished.		*/ -void GC_initiate_gc GC_PROTO((void)); -				/* initiate collection.			*/ -  				/* If the mark state is invalid, this	*/ -  				/* becomes full colleection.  Otherwise */ -  				/* it's partial.			*/ -void GC_push_all GC_PROTO((ptr_t bottom, ptr_t top)); -				/* Push everything in a range 		*/ -  				/* onto mark stack.			*/ -void GC_push_selected GC_PROTO(( \ -    ptr_t bottom, \ -    ptr_t top, \ -    int (*dirty_fn) GC_PROTO((struct hblk *h)), \ -    void (*push_fn) GC_PROTO((ptr_t bottom, ptr_t top)) )); -				  /* Push all pages h in [b,t) s.t. 	*/ -				  /* select_fn(h) != 0 onto mark stack. */ -#ifndef SMALL_CONFIG -  void GC_push_conditional GC_PROTO((ptr_t b, ptr_t t, GC_bool all)); -#else -# define GC_push_conditional(b, t, all) GC_push_all(b, t) -#endif -                                /* Do either of the above, depending	*/ -				/* on the third arg.			*/ -void GC_push_all_stack GC_PROTO((ptr_t b, ptr_t t)); -				    /* As above, but consider		*/ -				    /*  interior pointers as valid  	*/ -void GC_push_all_eager GC_PROTO((ptr_t b, ptr_t t)); -				    /* Same as GC_push_all_stack, but   */ -				    /* ensures that stack is scanned	*/ -				    /* immediately, not just scheduled  */ -				    /* for scanning.			*/ -#ifndef THREADS -  void GC_push_all_stack_partially_eager GC_PROTO(( \ -      ptr_t bottom, ptr_t top, ptr_t cold_gc_frame )); -			/* Similar to GC_push_all_eager, but only the	*/ -			/* part hotter than cold_gc_frame is scanned	*/ -			/* immediately.  Needed to ensure that callee-	*/ -			/* save registers are not missed.		*/ -#else -  /* In the threads case, we push part of the current thread stack	*/ -  /* with GC_push_all_eager when we push the registers.  This gets the  */ -  /* callee-save registers that may disappear.  The remainder of the	*/ -  /* stacks are scheduled for scanning in *GC_push_other_roots, which	*/ -  /* is thread-package-specific.					*/ -#endif -void GC_push_current_stack GC_PROTO((ptr_t cold_gc_frame)); -  			/* 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.				*/ -void GC_push_roots GC_PROTO((GC_bool all, ptr_t cold_gc_frame)); -  			/* Push all or dirty roots.	*/ -extern void (*GC_push_other_roots) GC_PROTO((void)); -  			/* Push system or application specific roots	*/ -  			/* onto the mark stack.  In some environments	*/ -  			/* (e.g. threads environments) this is		*/ -  			/* predfined to be non-zero.  A client supplied */ -  			/* replacement should also call the original	*/ -  			/* function.					*/ -extern void GC_push_gc_structures GC_PROTO((void)); -			/* 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.  Calls the following:		*/ -	extern void GC_push_finalizer_structures GC_PROTO((void)); -	extern void GC_push_stubborn_structures GC_PROTO((void)); -#	ifdef THREADS -	  extern void GC_push_thread_structures GC_PROTO((void)); -#	endif -extern void (*GC_start_call_back) GC_PROTO((void)); -  			/* Called at start of full collections.		*/ -  			/* Not called if 0.  Called with allocation 	*/ -  			/* lock held.					*/ -  			/* 0 by default.				*/ -# if defined(USE_GENERIC_PUSH_REGS) -  void GC_generic_push_regs GC_PROTO((ptr_t cold_gc_frame)); -# else -  void GC_push_regs GC_PROTO((void)); -# endif -			/* Push register contents onto mark stack.	*/ -  			/* If NURSERY is defined, the default push	*/ -  			/* action can be overridden with GC_push_proc	*/ - -# ifdef NURSERY -    extern void (*GC_push_proc)(ptr_t); -# endif -# if defined(MSWIN32) || defined(MSWINCE) -  void __cdecl GC_push_one GC_PROTO((word p)); -# else -  void GC_push_one GC_PROTO((word p)); -			      /* If p points to an object, mark it    */ -                              /* and push contents on the mark stack  */ -  			      /* Pointer recognition test always      */ -  			      /* accepts interior pointers, i.e. this */ -  			      /* is appropriate for pointers found on */ -  			      /* stack.				      */ -# endif -# if defined(PRINT_BLACK_LIST) || defined(KEEP_BACK_PTRS) -  void GC_mark_and_push_stack GC_PROTO((word p, ptr_t source)); -				/* Ditto, omits plausibility test	*/ -# else -  void GC_mark_and_push_stack GC_PROTO((word p)); -# endif -void GC_push_marked GC_PROTO((struct hblk * h, hdr * hhdr)); -		/* Push contents of all marked objects in h onto	*/ -		/* mark stack.						*/ -#ifdef SMALL_CONFIG -# define GC_push_next_marked_dirty(h) GC_push_next_marked(h) -#else -  struct hblk * GC_push_next_marked_dirty GC_PROTO((struct hblk * h)); -		/* Invoke GC_push_marked on next dirty block above h.	*/ -		/* Return a pointer just past the end of this block.	*/ -#endif /* !SMALL_CONFIG */ -struct hblk * GC_push_next_marked GC_PROTO((struct hblk * h)); -  		/* Ditto, but also mark from clean pages.	*/ -struct hblk * GC_push_next_marked_uncollectable GC_PROTO((struct hblk * h)); -  		/* Ditto, but mark only from uncollectable pages.	*/ -GC_bool GC_stopped_mark GC_PROTO((GC_stop_func stop_func)); - 			/* Stop world and mark from all roots	*/ -  			/* and rescuers.			*/ -void GC_clear_hdr_marks GC_PROTO((hdr * hhdr)); -				    /* Clear the mark bits in a header */ -void GC_set_hdr_marks GC_PROTO((hdr * hhdr)); - 				    /* Set the mark bits in a header */ -void GC_set_fl_marks GC_PROTO((ptr_t p)); -				    /* Set all mark bits associated with */ -				    /* a free list.			 */ -void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp)); -GC_bool GC_is_static_root GC_PROTO((ptr_t p)); -  		/* Is the address p in one of the registered static	*/ -  		/* root sections?					*/ -# if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION) -GC_bool GC_is_tmp_root GC_PROTO((ptr_t p)); -		/* Is the address p in one of the temporary static	*/ -		/* root sections?					*/ -# endif -void GC_register_dynamic_libraries GC_PROTO((void)); -  		/* Add dynamic library data sections to the root set. */ -   -/* Machine dependent startup routines */ -ptr_t GC_get_stack_base GC_PROTO((void));	/* Cold end of stack */ -#ifdef IA64 -  ptr_t GC_get_register_stack_base GC_PROTO((void)); -  					/* Cold end of register stack.	*/ -#endif -void GC_register_data_segments GC_PROTO((void)); -   -/* Black listing: */ -void GC_bl_init GC_PROTO((void)); -# ifdef PRINT_BLACK_LIST -      void GC_add_to_black_list_normal GC_PROTO((word p, ptr_t source)); -			/* Register bits as a possible future false	*/ -			/* reference from the heap or static data	*/ -#     define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \ -      		if (GC_all_interior_pointers) { \ -		  GC_add_to_black_list_stack(bits, (ptr_t)(source)); \ -		} else { \ -  		  GC_add_to_black_list_normal(bits, (ptr_t)(source)); \ -		} -# else -      void GC_add_to_black_list_normal GC_PROTO((word p)); -#     define GC_ADD_TO_BLACK_LIST_NORMAL(bits, source) \ -      		if (GC_all_interior_pointers) { \ -		  GC_add_to_black_list_stack(bits); \ -		} else { \ -  		  GC_add_to_black_list_normal(bits); \ -		} -# endif - -# ifdef PRINT_BLACK_LIST -    void GC_add_to_black_list_stack GC_PROTO((word p, ptr_t source)); -# else -    void GC_add_to_black_list_stack GC_PROTO((word p)); -# endif -struct hblk * GC_is_black_listed GC_PROTO((struct hblk * h, word len)); -  			/* If there are likely to be false references	*/ -  			/* to a block starting at h of the indicated    */ -  			/* length, then return the next plausible	*/ -  			/* starting location for h that might avoid	*/ -  			/* these false references.			*/ -void GC_promote_black_lists GC_PROTO((void)); -  			/* Declare an end to a black listing phase.	*/ -void GC_unpromote_black_lists GC_PROTO((void)); -  			/* Approximately undo the effect of the above.	*/ -  			/* This actually loses some information, but	*/ -  			/* only in a reasonably safe way.		*/ -word GC_number_stack_black_listed GC_PROTO(( \ -	struct hblk *start, struct hblk *endp1)); -  			/* Return the number of (stack) blacklisted	*/ -  			/* blocks in the range for statistical		*/ -  			/* purposes.					*/ -  		 	 -ptr_t GC_scratch_alloc GC_PROTO((word bytes)); -  				/* GC internal memory allocation for	*/ -  				/* small objects.  Deallocation is not  */ -  				/* possible.				*/ -  	 -/* Heap block layout maps: */			 -void GC_invalidate_map GC_PROTO((hdr * hhdr)); -  				/* Remove the object map associated	*/ -  				/* with the block.  This identifies	*/ -  				/* the block as invalid to the mark	*/ -  				/* routines.				*/ -GC_bool GC_add_map_entry GC_PROTO((word sz)); -  				/* Add a heap block map for objects of	*/ -  				/* size sz to obj_map.			*/ -  				/* Return FALSE on failure.		*/ -void GC_register_displacement_inner GC_PROTO((word offset)); -  				/* Version of GC_register_displacement	*/ -  				/* that assumes lock is already held	*/ -  				/* and signals are already disabled.	*/ -   -/*  hblk allocation: */		 -void GC_new_hblk GC_PROTO((word size_in_words, int kind)); -  				/* Allocate a new heap block, and build */ -  				/* a free list in it.			*/				 - -ptr_t GC_build_fl GC_PROTO((struct hblk *h, word sz, -			   GC_bool clear,  ptr_t list)); -				/* Build a free list for objects of 	*/ -				/* size sz in block h.  Append list to	*/ -				/* end of the free lists.  Possibly	*/ -				/* clear objects on the list.  Normally	*/ -				/* called by GC_new_hblk, but also	*/ -				/* called explicitly without GC lock.	*/ - -struct hblk * GC_allochblk GC_PROTO(( \ -	word size_in_words, int kind, unsigned flags)); -				/* Allocate a heap block, inform	*/ -				/* the marker that block is valid	*/ -				/* for objects of indicated size.	*/ - -ptr_t GC_alloc_large GC_PROTO((word lw, int k, unsigned flags)); -			/* Allocate a large block of size lw words.	*/ -			/* The block is not cleared.			*/ -			/* Flags is 0 or IGNORE_OFF_PAGE.		*/ -			/* Calls GC_allchblk to do the actual 		*/ -			/* allocation, but also triggers GC and/or	*/ -			/* heap expansion as appropriate.		*/ -			/* Does not update GC_words_allocd, but does	*/ -			/* other accounting.				*/ - -ptr_t GC_alloc_large_and_clear GC_PROTO((word lw, int k, unsigned flags)); -			/* As above, but clear block if appropriate	*/ -			/* for kind k.					*/ - -void GC_freehblk GC_PROTO((struct hblk * p)); -				/* Deallocate a heap block and mark it  */ -  				/* as invalid.				*/ -  				 -/*  Misc GC: */ -void GC_init_inner GC_PROTO((void)); -GC_bool GC_expand_hp_inner GC_PROTO((word n)); -void GC_start_reclaim GC_PROTO((int abort_if_found)); -  				/* Restore unmarked objects to free	*/ -  				/* lists, or (if abort_if_found is	*/ -  				/* TRUE) report them.			*/ -  				/* Sweeping of small object pages is	*/ -  				/* largely deferred.			*/ -void GC_continue_reclaim GC_PROTO((word sz, int kind)); -  				/* Sweep pages of the given size and	*/ -  				/* kind, as long as possible, and	*/ -  				/* as long as the corr. free list is    */ -  				/* empty.				*/ -void GC_reclaim_or_delete_all GC_PROTO((void)); -  				/* Arrange for all reclaim lists to be	*/ -  				/* empty.  Judiciously choose between	*/ -  				/* sweeping and discarding each page.	*/ -GC_bool GC_reclaim_all GC_PROTO((GC_stop_func stop_func, GC_bool ignore_old)); -  				/* Reclaim all blocks.  Abort (in a	*/ -  				/* consistent state) if f returns TRUE. */ -GC_bool GC_block_empty GC_PROTO((hdr * hhdr)); - 				/* Block completely unmarked? 	*/ -GC_bool GC_never_stop_func GC_PROTO((void)); -				/* Returns FALSE.		*/ -GC_bool GC_try_to_collect_inner GC_PROTO((GC_stop_func f)); - -				/* Collect; caller must have acquired	*/ -				/* lock and disabled signals.		*/ -				/* Collection is aborted if f returns	*/ -				/* TRUE.  Returns TRUE if it completes	*/ -				/* successfully.			*/ -# define GC_gcollect_inner() \ -	(void) GC_try_to_collect_inner(GC_never_stop_func) -void GC_finish_collection GC_PROTO((void)); - 				/* Finish collection.  Mark bits are	*/ -  				/* consistent and lock is still held.	*/ -GC_bool GC_collect_or_expand GC_PROTO(( \ -	word needed_blocks, GC_bool ignore_off_page)); -  				/* Collect or expand heap in an attempt */ -  				/* make the indicated number of free	*/ -  				/* blocks available.  Should be called	*/ -  				/* until the blocks are available or	*/ -  				/* until it fails by returning FALSE.	*/ - -extern GC_bool GC_is_initialized;	/* GC_init() has been run.	*/ - -#if defined(MSWIN32) || defined(MSWINCE) -  void GC_deinit GC_PROTO((void)); -                                /* Free any resources allocated by      */ -                                /* GC_init                              */ -#endif - -void GC_collect_a_little_inner GC_PROTO((int n)); -  				/* Do n units worth of garbage 		*/ -  				/* collection work, if appropriate.	*/ -  				/* A unit is an amount appropriate for  */ -  				/* HBLKSIZE bytes of allocation.	*/ -ptr_t GC_generic_malloc GC_PROTO((word lb, int k)); -  				/* Allocate an object of the given	*/ -  				/* kind.  By default, there are only	*/ -  				/* a few kinds: composite(pointerfree), */ -				/* atomic, uncollectable, etc.		*/ -				/* We claim it's possible for clever	*/ -				/* client code that understands GC	*/ -				/* internals to add more, e.g. to	*/ -				/* communicate object layout info	*/ -				/* to the collector.			*/ -ptr_t GC_generic_malloc_ignore_off_page GC_PROTO((size_t b, int k)); -  				/* As above, but pointers past the 	*/ -  				/* first page of the resulting object	*/ -  				/* are ignored.				*/ -ptr_t GC_generic_malloc_inner GC_PROTO((word lb, int k)); -  				/* Ditto, but I already hold lock, etc.	*/ -ptr_t GC_generic_malloc_words_small GC_PROTO((size_t lw, int k)); -  				/* As above, but size in units of words */ -  				/* Bypasses MERGE_SIZES.  Assumes	*/ -  				/* words <= MAXOBJSZ.			*/ -ptr_t GC_generic_malloc_inner_ignore_off_page GC_PROTO((size_t lb, int k)); -  				/* Allocate an object, where		*/ -  				/* the client guarantees that there	*/ -  				/* will always be a pointer to the 	*/ -  				/* beginning of the object while the	*/ -  				/* object is live.			*/ -ptr_t GC_allocobj GC_PROTO((word sz, int kind)); -  				/* Make the indicated 			*/ -  				/* free list nonempty, and return its	*/ -  				/* head.				*/ -   -void GC_init_headers GC_PROTO((void)); -struct hblkhdr * GC_install_header GC_PROTO((struct hblk *h)); -  				/* Install a header for block h.	*/ -  				/* Return 0 on failure, or the header	*/ -  				/* otherwise.				*/ -GC_bool GC_install_counts GC_PROTO((struct hblk * h, word sz)); -  				/* Set up forwarding counts for block	*/ -  				/* h of size sz.			*/ -  				/* Return FALSE on failure.		*/ -void GC_remove_header GC_PROTO((struct hblk * h)); -  				/* Remove the header for block h.	*/ -void GC_remove_counts GC_PROTO((struct hblk * h, word sz)); -  				/* Remove forwarding counts for h.	*/ -hdr * GC_find_header GC_PROTO((ptr_t h)); /* Debugging only.		*/ -   -void GC_finalize GC_PROTO((void)); - 			/* Perform all indicated finalization actions	*/ -  			/* on unmarked objects.				*/ -  			/* Unreachable finalizable objects are enqueued	*/ -  			/* for processing by GC_invoke_finalizers.	*/ -  			/* Invoked with lock.				*/ - -void GC_notify_or_invoke_finalizers GC_PROTO((void)); -			/* If GC_finalize_on_demand is not set, invoke	*/ -			/* eligible finalizers. Otherwise:		*/ -			/* Call *GC_finalizer_notifier if there are	*/ -			/* finalizers to be run, and we haven't called	*/ -			/* this procedure yet this GC cycle.		*/ -  			 -void GC_add_to_heap GC_PROTO((struct hblk *p, word bytes)); -  			/* Add a HBLKSIZE aligned chunk to the heap.	*/ -   -void GC_print_obj GC_PROTO((ptr_t p)); -  			/* P points to somewhere inside an object with	*/ -  			/* debugging info.  Print a human readable	*/ -  			/* description of the object to stderr.		*/ -extern void (*GC_check_heap) GC_PROTO((void)); -  			/* Check that all objects in the heap with 	*/ -  			/* debugging info are intact.  			*/ -  			/* Add any that are not to GC_smashed list.	*/ -extern void (*GC_print_all_smashed) GC_PROTO((void)); -			/* Print GC_smashed if it's not empty.		*/ -			/* Clear GC_smashed list.			*/ -extern void (*GC_print_heap_obj) GC_PROTO((ptr_t p)); -  			/* If possible print s followed by a more	*/ -  			/* detailed description of the object 		*/ -  			/* referred to by p.				*/ - -extern GC_bool GC_print_stats;	/* Produce at least some logging output	*/ -				/* Set from environment variable.	*/ - -/* Macros used for collector internal allocation.	*/ -/* These assume the collector lock is held.		*/ -#ifdef DBG_HDRS_ALL -    extern GC_PTR GC_debug_generic_malloc_inner(size_t lb, int k); -    extern GC_PTR GC_debug_generic_malloc_inner_ignore_off_page(size_t lb, -								int k); -#   define GC_INTERNAL_MALLOC GC_debug_generic_malloc_inner -#   define GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE \ -		 GC_debug_generic_malloc_inner_ignore_off_page -#   ifdef THREADS -#       define GC_INTERNAL_FREE GC_debug_free_inner -#   else -#       define GC_INTERNAL_FREE GC_debug_free -#   endif -#else -#   define GC_INTERNAL_MALLOC GC_generic_malloc_inner -#   define GC_INTERNAL_MALLOC_IGNORE_OFF_PAGE \ -		 GC_generic_malloc_inner_ignore_off_page -#   ifdef THREADS -#       define GC_INTERNAL_FREE GC_free_inner -#   else -#       define GC_INTERNAL_FREE GC_free -#   endif -#endif - -/* Memory unmapping: */ -#ifdef USE_MUNMAP -  void GC_unmap_old(void); -  void GC_merge_unmapped(void); -  void GC_unmap(ptr_t start, word bytes); -  void GC_remap(ptr_t start, word bytes); -  void GC_unmap_gap(ptr_t start1, word bytes1, ptr_t start2, word bytes2); -#endif - -/* Virtual dirty bit implementation:		*/ -/* Each implementation exports the following:	*/ -void GC_read_dirty GC_PROTO((void)); -			/* Retrieve dirty bits.	*/ -GC_bool GC_page_was_dirty GC_PROTO((struct hblk *h)); -  			/* Read retrieved dirty bits.	*/ -GC_bool GC_page_was_ever_dirty GC_PROTO((struct hblk *h)); -  			/* Could the page contain valid heap pointers?	*/ -void GC_is_fresh GC_PROTO((struct hblk *h, word n)); -  			/* Assert the region currently contains no	*/ -  			/* valid pointers.				*/ -void GC_remove_protection GC_PROTO((struct hblk *h, word nblocks, -			   	    GC_bool pointerfree)); -  			/* h is about to be writteni or allocated.  Ensure  */ -			/* that it's not write protected by the virtual	    */ -			/* dirty bit implementation.			    */ -			 -void GC_dirty_init GC_PROTO((void)); -   -/* Slow/general mark bit manipulation: */ -GC_API GC_bool GC_is_marked GC_PROTO((ptr_t p)); -void GC_clear_mark_bit GC_PROTO((ptr_t p)); -void GC_set_mark_bit GC_PROTO((ptr_t p)); -   -/* Stubborn objects: */ -void GC_read_changed GC_PROTO((void));	/* Analogous to GC_read_dirty */ -GC_bool GC_page_was_changed GC_PROTO((struct hblk * h)); - 				/* Analogous to GC_page_was_dirty */ -void GC_clean_changing_list GC_PROTO((void)); - 				/* Collect obsolete changing list entries */ -void GC_stubborn_init GC_PROTO((void)); -   -/* Debugging print routines: */ -void GC_print_block_list GC_PROTO((void)); -void GC_print_hblkfreelist GC_PROTO((void)); -void GC_print_heap_sects GC_PROTO((void)); -void GC_print_static_roots GC_PROTO((void)); -void GC_dump GC_PROTO((void)); - -#ifdef KEEP_BACK_PTRS -   void GC_store_back_pointer(ptr_t source, ptr_t dest); -   void GC_marked_for_finalization(ptr_t dest); -#  define GC_STORE_BACK_PTR(source, dest) GC_store_back_pointer(source, dest) -#  define GC_MARKED_FOR_FINALIZATION(dest) GC_marked_for_finalization(dest) -#else -#  define GC_STORE_BACK_PTR(source, dest)  -#  define GC_MARKED_FOR_FINALIZATION(dest) -#endif - -/* Make arguments appear live to compiler */ -# ifdef __WATCOMC__ -    void GC_noop(void*, ...); -# else -#   ifdef __DMC__ -      GC_API void GC_noop(...); -#   else -      GC_API void GC_noop(); -#   endif -# endif - -void GC_noop1 GC_PROTO((word)); - -/* Logging and diagnostic output: 	*/ -GC_API void GC_printf GC_PROTO((GC_CONST char * format, long, long, long, long, long, long)); -			/* A version of printf that doesn't allocate,	*/ -			/* is restricted to long arguments, and		*/ -			/* (unfortunately) doesn't use varargs for	*/ -			/* portability.  Restricted to 6 args and	*/ -			/* 1K total output length.			*/ -			/* (We use sprintf.  Hopefully that doesn't	*/ -			/* allocate for long arguments.)  		*/ -# define GC_printf0(f) GC_printf(f, 0l, 0l, 0l, 0l, 0l, 0l) -# define GC_printf1(f,a) GC_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l) -# define GC_printf2(f,a,b) GC_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l) -# define GC_printf3(f,a,b,c) GC_printf(f, (long)a, (long)b, (long)c, 0l, 0l, 0l) -# define GC_printf4(f,a,b,c,d) GC_printf(f, (long)a, (long)b, (long)c, \ -					    (long)d, 0l, 0l) -# define GC_printf5(f,a,b,c,d,e) GC_printf(f, (long)a, (long)b, (long)c, \ -					      (long)d, (long)e, 0l) -# define GC_printf6(f,a,b,c,d,e,g) GC_printf(f, (long)a, (long)b, (long)c, \ -						(long)d, (long)e, (long)g) - -GC_API void GC_err_printf GC_PROTO((GC_CONST char * format, long, long, long, long, long, long)); -# define GC_err_printf0(f) GC_err_puts(f) -# define GC_err_printf1(f,a) GC_err_printf(f, (long)a, 0l, 0l, 0l, 0l, 0l) -# define GC_err_printf2(f,a,b) GC_err_printf(f, (long)a, (long)b, 0l, 0l, 0l, 0l) -# define GC_err_printf3(f,a,b,c) GC_err_printf(f, (long)a, (long)b, (long)c, \ -						  0l, 0l, 0l) -# define GC_err_printf4(f,a,b,c,d) GC_err_printf(f, (long)a, (long)b, \ -						    (long)c, (long)d, 0l, 0l) -# define GC_err_printf5(f,a,b,c,d,e) GC_err_printf(f, (long)a, (long)b, \ -						      (long)c, (long)d, \ -						      (long)e, 0l) -# define GC_err_printf6(f,a,b,c,d,e,g) GC_err_printf(f, (long)a, (long)b, \ -							(long)c, (long)d, \ -							(long)e, (long)g) -			/* Ditto, writes to stderr.			*/ -			 -void GC_err_puts GC_PROTO((GC_CONST char *s)); -			/* Write s to stderr, don't buffer, don't add	*/ -			/* newlines, don't ...				*/ - -#if defined(LINUX) && !defined(SMALL_CONFIG) -  void GC_err_write GC_PROTO((GC_CONST char *buf, size_t len)); - 			/* Write buf to stderr, don't buffer, don't add	*/ -  			/* newlines, don't ...				*/ -#endif - - -# ifdef GC_ASSERTIONS -#	define GC_ASSERT(expr) if(!(expr)) {\ -		GC_err_printf2("Assertion failure: %s:%ld\n", \ -				__FILE__, (unsigned long)__LINE__); \ -		ABORT("assertion failure"); } -# else  -#	define GC_ASSERT(expr) -# endif - -# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC) -    /* We need additional synchronization facilities from the thread	*/ -    /* support.  We believe these are less performance critical		*/ -    /* than the main garbage collector lock; standard pthreads-based	*/ -    /* implementations should be sufficient.				*/ - -    /* 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		*/ -    /* marker, and to protect GC_fl_builder_count, below.		*/ -    /* GC_notify_all_marker() is called when				*/  -    /* the state of the parallel marker changes				*/ -    /* in some significant way (see gc_mark.h for details).  The	*/ -    /* latter set of events includes incrementing GC_mark_no.		*/ -    /* GC_notify_all_builder() is called when GC_fl_builder_count	*/ -    /* reaches 0.							*/ - -     extern void GC_acquire_mark_lock(); -     extern void GC_release_mark_lock(); -     extern void GC_notify_all_builder(); -     /* extern void GC_wait_builder(); */ -     extern void GC_wait_for_reclaim(); - -     extern word GC_fl_builder_count;	/* Protected by mark lock.	*/ -# endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */ -# ifdef PARALLEL_MARK -     extern void GC_notify_all_marker(); -     extern void GC_wait_marker(); -     extern word GC_mark_no;		/* Protected by mark lock.	*/ - -     extern void GC_help_marker(word my_mark_no); -		/* Try to help out parallel marker for mark cycle 	*/ -		/* my_mark_no.  Returns if the mark cycle finishes or	*/ -		/* was already done, or there was nothing to do for	*/ -		/* some other reason.					*/ -# endif /* PARALLEL_MARK */ - -# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) -  /* We define the thread suspension signal here, so that we can refer	*/ -  /* to it in the dirty bit implementation, if necessary.  Ideally we	*/ -  /* would allocate a (real-time ?) signal using the standard mechanism.*/ -  /* 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(SIG_SUSPEND) -#   if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS) -#    if defined(SPARC) && !defined(SIGPWR) -       /* SPARC/Linux doesn't properly define SIGPWR in <signal.h>. -        * It is aliased to SIGLOST in asm/signal.h, though.		*/ -#      define SIG_SUSPEND SIGLOST -#    else -       /* Linuxthreads itself uses SIGUSR1 and SIGUSR2.			*/ -#      define SIG_SUSPEND SIGPWR -#    endif -#   else  /* !GC_LINUX_THREADS */ -#     if defined(_SIGRTMIN) -#       define SIG_SUSPEND _SIGRTMIN + 6 -#     else -#       define SIG_SUSPEND SIGRTMIN + 6 -#     endif        -#   endif -#  endif /* !SIG_SUSPEND */ -   -# endif - -# endif /* GC_PRIVATE_H */ diff --git a/gc/include/private/gcconfig.h b/gc/include/private/gcconfig.h deleted file mode 100644 index c3adaa2..0000000 --- a/gc/include/private/gcconfig.h +++ /dev/null @@ -1,1986 +0,0 @@ -/*  - * 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) 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. - */ -  -#ifndef GCCONFIG_H - -# define GCCONFIG_H - -/* Machine dependent parameters.  Some tuning parameters can be found	*/ -/* near the top of gc_private.h.					*/ - -/* Machine specific parts contributed by various people.  See README file. */ - -/* First a unified test for Linux: */ -# if defined(linux) || defined(__linux__) -#    define LINUX -# endif - -/* And one for NetBSD: */ -# if defined(__NetBSD__) -#    define NETBSD -# endif - -/* And one for OpenBSD: */ -# if defined(__OpenBSD__) -#    define OPENBSD -# endif - -/* And one for FreeBSD: */ -# if defined(__FreeBSD__) -#    define FREEBSD -# endif - -/* Determine the machine type: */ -# if defined(__XSCALE__) -#    define ARM32 -#    if !defined(LINUX) -#      define NOSYS -#      define mach_type_known -#    endif -# endif -# if defined(sun) && defined(mc68000) -#    define M68K -#    define SUNOS4 -#    define mach_type_known -# endif -# if defined(hp9000s300) -#    define M68K -#    define HP -#    define mach_type_known -# endif -# if defined(OPENBSD) && defined(m68k) -#    define M68K -#    define mach_type_known -# endif -# if defined(OPENBSD) && defined(__sparc__) -#    define SPARC -#    define mach_type_known -# endif -# if defined(NETBSD) && defined(m68k) -#    define M68K -#    define mach_type_known -# endif -# if defined(NETBSD) && defined(__powerpc__) -#    define POWERPC -#    define mach_type_known -# endif -# if defined(NETBSD) && defined(__arm32__) -#    define ARM32 -#    define mach_type_known -# endif -# if defined(vax) -#    define VAX -#    ifdef ultrix -#	define ULTRIX -#    else -#	define BSD -#    endif -#    define mach_type_known -# endif -# if defined(mips) || defined(__mips) || defined(_mips) -#    define MIPS -#    if defined(nec_ews) || defined(_nec_ews) -#      define EWS4800 -#    endif -#    if !defined(LINUX) && !defined(EWS4800) -#      if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__) -#	 define ULTRIX -#      else -#	 if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) \ -	    || defined(__SYSTYPE_SVR4__) -#	   define IRIX5   /* or IRIX 6.X */ -#	 else -#	   define RISCOS  /* or IRIX 4.X */ -#	 endif -#      endif -#    endif /* !LINUX */ -#    if defined(__NetBSD__) && defined(__MIPSEL__) -#      undef ULTRIX -#    endif -#    define mach_type_known -# endif -# if defined(DGUX) && (defined(i386) || defined(__i386__)) -#    define I386 -#    ifndef _USING_DGUX -#    define _USING_DGUX -#    endif -#    define mach_type_known -# endif -# if defined(sequent) && (defined(i386) || defined(__i386__)) -#    define I386 -#    define SEQUENT -#    define mach_type_known -# endif -# if defined(sun) && (defined(i386) || defined(__i386__)) -#    define I386 -#    define SUNOS5 -#    define mach_type_known -# endif -# if (defined(__OS2__) || defined(__EMX__)) && defined(__32BIT__) -#    define I386 -#    define OS2 -#    define mach_type_known -# endif -# if defined(ibm032) -#   define RT -#   define mach_type_known -# endif -# if defined(sun) && (defined(sparc) || defined(__sparc)) -#   define SPARC -    /* Test for SunOS 5.x */ -#     include <errno.h> -#     ifdef ECHRNG -#       define SUNOS5 -#     else -#	define SUNOS4 -#     endif -#   define mach_type_known -# endif -# if defined(sparc) && defined(unix) && !defined(sun) && !defined(linux) \ -     && !defined(__OpenBSD__) && !(__NetBSD__) -#   define SPARC -#   define DRSNX -#   define mach_type_known -# endif -# if defined(_IBMR2) -#   define RS6000 -#   define mach_type_known -# endif -# if defined(__NetBSD__) && defined(__sparc__) -#   define SPARC -#   define mach_type_known -# endif -# if defined(_M_XENIX) && defined(_M_SYSV) && defined(_M_I386) -	/* The above test may need refinement	*/ -#   define I386 -#   if defined(_SCO_ELF) -#     define SCO_ELF -#   else -#     define SCO -#   endif -#   define mach_type_known -# endif -# if defined(_AUX_SOURCE) -#   define M68K -#   define SYSV -#   define mach_type_known -# endif -# if defined(_PA_RISC1_0) || defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \ -     || defined(hppa) || defined(__hppa__) -#   define HP_PA -#   ifndef LINUX -#     define HPUX -#   endif -#   define mach_type_known -# endif -# if defined(__ia64) && defined(_HPUX_SOURCE) -#   define IA64 -#   define HPUX -#   define mach_type_known -# endif -# if defined(__BEOS__) && defined(_X86_) -#    define I386 -#    define BEOS -#    define mach_type_known -# endif -# if defined(LINUX) && (defined(i386) || defined(__i386__)) -#    define I386 -#    define mach_type_known -# endif -# if defined(LINUX) && (defined(__ia64__) || defined(__ia64)) -#    define IA64 -#    define mach_type_known -# endif -# if defined(LINUX) && defined(__arm__) -#    define ARM32 -#    define mach_type_known -# endif -# if defined(LINUX) && (defined(powerpc) || defined(__powerpc__)) -#    define POWERPC -#    define mach_type_known -# endif -# if defined(LINUX) && defined(__mc68000__) -#    define M68K -#    define mach_type_known -# endif -# if defined(LINUX) && (defined(sparc) || defined(__sparc__)) -#    define SPARC -#    define mach_type_known -# endif -# if defined(LINUX) && defined(__arm__) -#    define ARM32 -#    define mach_type_known -# endif -# if defined(LINUX) && defined(__sh__) -#    define SH -#    define mach_type_known -# endif -# if defined(__alpha) || defined(__alpha__) -#   define ALPHA -#   if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) && !defined(FREEBSD) -#     define OSF1	/* a.k.a Digital Unix */ -#   endif -#   define mach_type_known -# endif -# if defined(_AMIGA) && !defined(AMIGA) -#   define AMIGA -# endif -# ifdef AMIGA  -#   define M68K -#   define mach_type_known -# endif -# if defined(THINK_C) || defined(__MWERKS__) && !defined(__powerc) -#   define M68K -#   define MACOS -#   define mach_type_known -# endif -# if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__) -#   define POWERPC -#   define MACOS -#   define mach_type_known -# endif -# if defined(macosx) || \ -     defined(__APPLE__) && defined(__MACH__) && defined(__ppc__) -#    define MACOSX -#    define POWERPC -#    define mach_type_known -# endif -# if defined(__APPLE__) && defined(__MACH__) && defined(__i386__) -#    define MACOSX -#    define I386 -     --> Not really supported, but at least we recognize it. -# endif -# if defined(NeXT) && defined(mc68000) -#   define M68K -#   define NEXT -#   define mach_type_known -# endif -# if defined(NeXT) && (defined(i386) || defined(__i386__)) -#   define I386 -#   define NEXT -#   define mach_type_known -# endif -# if defined(__OpenBSD__) && (defined(i386) || defined(__i386__)) -#   define I386 -#   define OPENBSD -#   define mach_type_known -# endif -# if defined(FREEBSD) && (defined(i386) || defined(__i386__)) -#   define I386 -#   define mach_type_known -# endif -# if defined(__NetBSD__) && (defined(i386) || defined(__i386__)) -#   define I386 -#   define mach_type_known -# endif -# if defined(bsdi) && (defined(i386) || defined(__i386__)) -#    define I386 -#    define BSDI -#    define mach_type_known -# endif -# if !defined(mach_type_known) && defined(__386BSD__) -#   define I386 -#   define THREE86BSD -#   define mach_type_known -# endif -# if defined(_CX_UX) && defined(_M88K) -#   define M88K -#   define CX_UX -#   define mach_type_known -# endif -# if defined(DGUX) && defined(m88k) -#   define M88K -    /* DGUX defined */ -#   define mach_type_known -# endif -# if defined(_WIN32_WCE) -    /* SH3, SH4, MIPS already defined for corresponding architectures */ -#   if defined(SH3) || defined(SH4) -#     define SH -#   endif -#   if defined(x86) -#     define I386 -#   endif -#   if defined(ARM) -#     define ARM32 -#   endif -#   define MSWINCE -#   define mach_type_known -# else -#   if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ -        || defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) -#     define I386 -#     define MSWIN32	/* or Win32s */ -#     define mach_type_known -#   endif -# endif -# if defined(__DJGPP__) -#   define I386 -#   ifndef DJGPP -#     define DJGPP  /* MSDOS running the DJGPP port of GCC */ -#   endif -#   define mach_type_known -# endif -# if defined(__CYGWIN32__) || defined(__CYGWIN__) -#   define I386 -#   define CYGWIN32 -#   define mach_type_known -# endif -# if defined(__MINGW32__) -#   define I386 -#   define MSWIN32 -#   define mach_type_known -# endif -# if defined(__BORLANDC__) -#   define I386 -#   define MSWIN32 -#   define mach_type_known -# endif -# if defined(_UTS) && !defined(mach_type_known) -#   define S370 -#   define UTS4 -#   define mach_type_known -# endif -# if defined(__pj__) -#   define PJ -#   define mach_type_known -# endif -# if defined(__embedded__) && defined(PPC) -#   define POWERPC -#   define NOSYS -#   define mach_type_known -# endif -/* Ivan Demakov */ -# if defined(__WATCOMC__) && defined(__386__) -#   define I386 -#   if !defined(OS2) && !defined(MSWIN32) && !defined(DOS4GW) -#     if defined(__OS2__) -#       define OS2 -#     else -#       if defined(__WINDOWS_386__) || defined(__NT__) -#         define MSWIN32 -#       else -#         define DOS4GW -#       endif -#     endif -#   endif -#   define mach_type_known -# endif -# if defined(__s390__) && defined(LINUX) -#    define S370 -#    define mach_type_known -# endif -# if defined(__GNU__) -#   if defined(__i386__) -/* The Debian Hurd running on generic PC */   -#     define  HURD -#     define  I386 -#     define  mach_type_known -#    endif  -# endif - -/* Feel free to add more clauses here */ - -/* Or manually define the machine type here.  A machine type is 	*/ -/* characterized by the architecture.  Some				*/ -/* machine types are further subdivided by OS.				*/ -/* the macros ULTRIX, RISCOS, and BSD to distinguish.			*/ -/* Note that SGI IRIX is treated identically to RISCOS.			*/ -/* SYSV on an M68K actually means A/UX.					*/ -/* The distinction in these cases is usually the stack starting address */ -# ifndef mach_type_known -	--> unknown machine type -# endif -		    /* Mapping is: M68K       ==> Motorola 680X0	*/ -		    /*		   (SUNOS4,HP,NEXT, and SYSV (A/UX),	*/ -		    /*		   MACOS and AMIGA variants)		*/ -		    /*             I386       ==> Intel 386	 	*/ -		    /*		    (SEQUENT, OS2, SCO, LINUX, NETBSD,	*/ -		    /*		     FREEBSD, THREE86BSD, MSWIN32,	*/ -		    /* 		     BSDI,SUNOS5, NEXT, other variants)	*/ -                    /*             NS32K      ==> Encore Multimax 	*/ -                    /*             MIPS       ==> R2000 or R3000	*/ -                    /*			(RISCOS, ULTRIX variants)	*/ -                    /*		   VAX	      ==> DEC VAX		*/ -                    /*			(BSD, ULTRIX variants)		*/ -                    /*		   RS6000     ==> IBM RS/6000 AIX3.X	*/ -                    /*		   RT	      ==> IBM PC/RT		*/ -                    /*		   HP_PA      ==> HP9000/700 & /800	*/ -                    /*				  HP/UX, LINUX		*/ -		    /*		   SPARC      ==> SPARC	v7/v8/v9	*/ -		    /*			(SUNOS4, SUNOS5, LINUX,		*/ -		    /*			 DRSNX variants)		*/ -		    /* 		   ALPHA      ==> DEC Alpha 		*/ -		    /*			(OSF1 and LINUX variants)	*/ -		    /* 		   M88K       ==> Motorola 88XX0        */ -		    /* 		        (CX_UX and DGUX)		*/ -		    /* 		   S370	      ==> 370-like machine	*/ -		    /* 			running Amdahl UTS4		*/ -		    /*			or a 390 running LINUX		*/ -		    /* 		   ARM32      ==> Intel StrongARM	*/ -		    /* 		   IA64	      ==> Intel IPF		*/ -		    /*				  (e.g. Itanium)	*/ -		    /*			(LINUX and HPUX)	        */ -		    /* 		   IA64_32    ==> IA64 w/32 bit ABI	*/ -		    /* 			(HPUX)				*/ -		    /*		   SH	      ==> Hitachi SuperH	*/ -		    /* 			(LINUX & MSWINCE)		*/ - - -/* - * For each architecture and OS, the following need to be defined: - * - * CPP_WORD_SZ is a simple integer constant representing the word size. - * in bits.  We assume byte addressibility, where a byte has 8 bits. - * We also assume CPP_WORD_SZ is either 32 or 64. - * (We care about the length of pointers, not hardware - * bus widths.  Thus a 64 bit processor with a C compiler that uses - * 32 bit pointers should use CPP_WORD_SZ of 32, not 64. Default is 32.) - * - * MACH_TYPE is a string representation of the machine type. - * OS_TYPE is analogous for the OS. - * - * ALIGNMENT is the largest N, such that - * all pointer are guaranteed to be aligned on N byte boundaries. - * defining it to be 1 will always work, but perform poorly. - * - * DATASTART is the beginning of the data segment. - * On some platforms SEARCH_FOR_DATA_START is defined. - * SEARCH_FOR_DATASTART will cause GC_data_start to - * be set to an address determined by accessing data backwards from _end - * until an unmapped page is found.  DATASTART will be defined to be - * GC_data_start. - * On UNIX-like systems, the collector will scan the area between DATASTART - * and DATAEND for root pointers. - * - * DATAEND, if not `end' where `end' is defined as ``extern int end[];''. - * RTH suggests gaining access to linker script synth'd values with - * this idiom instead of `&end' where `end' is defined as ``extern int end;'' . - * - * ALIGN_DOUBLE of GC_malloc should return blocks aligned to twice - * the pointer size. - * - * STACKBOTTOM is the cool 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: - * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and - * 2) define exactly one of - *	STACKBOTTOM (should be defined to be an expression) - *	LINUX_STACKBOTTOM - *	HEURISTIC1 - *	HEURISTIC2 - * If STACKBOTTOM is defined, then it's value will be used directly as the - * stack base.  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, and if that fails read it from /proc. - * If either of the last two macros are defined, then STACKBOTTOM is computed - * during collector startup using one of the following two heuristics: - * HEURISTIC1:  Take an address inside GC_init's frame, and round it up to - *		the next multiple of STACK_GRAN. - * HEURISTIC2:  Take an address inside GC_init's frame, increment it repeatedly - *		in small steps (decrement if STACK_GROWS_UP), and read the value - *		at each location.  Remember the value when the first - *		Segmentation violation or Bus error is signalled.  Round that - *		to the nearest plausible page boundary, and use that instead - *		of STACKBOTTOM. - * - * Gustavo Rodriguez-Rivera points out that on most (all?) Unix machines, - * the value of environ is a pointer that can serve as STACKBOTTOM. - * I expect that HEURISTIC2 can be replaced by this approach, which - * interferes far less with debugging.  However it has the disadvantage - * that it's confused by a putenv call before the collector is initialized. - * This could be dealt with by intercepting putenv ... - * - * If no expression for STACKBOTTOM can be found, and neither of the above - * heuristics are usable, the collector can still be used with all of the above - * undefined, provided one of the following is done: - * 1) GC_mark_roots can be changed to somehow mark from the correct stack(s) - *    without reference to STACKBOTTOM.  This is appropriate for use in - *    conjunction with thread packages, since there will be multiple stacks. - *    (Allocating thread stacks in the heap, and treating them as ordinary - *    heap data objects is also possible as a last resort.  However, this is - *    likely to introduce significant amounts of excess storage retention - *    unless the dead parts of the thread stacks are periodically cleared.) - * 2) Client code may set GC_stackbottom before calling any GC_ routines. - *    If the author of the client code controls the main program, this is - *    easily accomplished by introducing a new main program, setting - *    GC_stackbottom to the address of a local variable, and then calling - *    the original main program.  The new main program would read something - *    like: - * - *		# include "gc_private.h" - * - *		main(argc, argv, envp) - *		int argc; - *		char **argv, **envp; - *		{ - *		    int dummy; - * - *		    GC_stackbottom = (ptr_t)(&dummy); - *		    return(real_main(argc, argv, envp)); - *		} - * - * - * Each architecture may also define the style of virtual dirty bit - * implementation to be used: - *   MPROTECT_VDB: Write protect the heap and catch faults. - *   PROC_VDB: Use the SVR4 /proc primitives to read dirty bits. - * - * An architecture may define DYNAMIC_LOADING if dynamic_load.c - * defined GC_register_dynamic_libraries() for the architecture. - * - * An architecture may define PREFETCH(x) to preload the cache with *x. - * This defaults to a no-op. - * - * PREFETCH_FOR_WRITE(x) is used if *x is about to be written. - * - * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to - * clear the two words at GC_malloc-aligned address x.  By default, - * word stores of 0 are used instead. - * - * HEAP_START may be defined as the initial address hint for mmap-based - * allocation. - */ - -/* If we are using a recent version of gcc, we can use __builtin_unwind_init() - * to push the relevant registers onto the stack.  This generally makes - * USE_GENERIC_PUSH_REGS the preferred approach for marking from registers. - */ -# if defined(__GNUC__) && ((__GNUC__ >= 3) || \ -			   (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) -#   define HAVE_BUILTIN_UNWIND_INIT -# endif - -# define STACK_GRAN 0x1000000 -# ifdef M68K -#   define MACH_TYPE "M68K" -#   define ALIGNMENT 2 -#   ifdef OPENBSD -#	define OS_TYPE "OPENBSD" -#	define HEURISTIC2 -	extern char etext[]; -#	define DATASTART ((ptr_t)(etext)) -#   endif -#   ifdef NETBSD -#	define OS_TYPE "NETBSD" -#	define HEURISTIC2 -	extern char etext[]; -#	define DATASTART ((ptr_t)(etext)) -#   endif -#   ifdef LINUX -#       define OS_TYPE "LINUX" -#       define STACKBOTTOM ((ptr_t)0xf0000000) -/* #       define MPROTECT_VDB - Reported to not work  9/17/01 */ -#       ifdef __ELF__ -#            define DYNAMIC_LOADING -#	     include <features.h> -#	     if defined(__GLIBC__)&& __GLIBC__>=2 -#              define LINUX_DATA_START -#	     else /* !GLIBC2 */ -               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   */ -                             /* ld options were passed through.        */ -                             /* We could use _etext instead, but that  */ -                             /* would include .rodata, which may       */ -                             /* contain large read-only data tables    */ -                             /* that we'd rather not scan.             */ -#	     endif /* !GLIBC2 */ -             extern int _end[]; -#            define DATAEND (_end) -#       else -             extern int etext[]; -#            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) -#       endif -#   endif -#   ifdef SUNOS4 -#	define OS_TYPE "SUNOS4" -	extern char etext[]; -#	define DATASTART ((ptr_t)((((word) (etext)) + 0x1ffff) & ~0x1ffff)) -#	define HEURISTIC1	/* differs	*/ -#	define DYNAMIC_LOADING -#   endif -#   ifdef HP -#	define OS_TYPE "HP" -	extern char etext[]; -#       define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) -#       define STACKBOTTOM ((ptr_t) 0xffeffffc) -			      /* empirically determined.  seems to work. */ -#  	include <unistd.h> -#	define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) -#   endif -#   ifdef SYSV -#	define OS_TYPE "SYSV" -	extern etext[]; -#   	define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \ -				   & ~0x3fffff) \ -				  +((word)etext & 0x1fff)) -	/* This only works for shared-text binaries with magic number 0413. -	   The other sorts of SysV binaries put the data at the end of the text, -	   in which case the default of etext would work.  Unfortunately, -	   handling both would require having the magic-number available. -	   	   		-- Parag -	   */ -#	define STACKBOTTOM ((ptr_t)0xFFFFFFFE) -			/* The stack starts at the top of memory, but   */ -			/* 0x0 cannot be used as setjump_test complains */ -			/* that the stack direction is incorrect.  Two  */ -			/* bytes down from 0x0 should be safe enough.   */ -			/* 		--Parag				*/ -#   	include <sys/mmu.h> -#	define GETPAGESIZE() PAGESIZE	/* Is this still right? */ -#   endif -#   ifdef AMIGA -#	define OS_TYPE "AMIGA" - 	    	/* STACKBOTTOM and DATASTART handled specially	*/ - 	    	/* in os_dep.c					*/ -# 	define DATAEND	/* not needed */ -#	define GETPAGESIZE() 4096 -#   endif -#   ifdef MACOS -#     ifndef __LOWMEM__ -#     include <LowMem.h> -#     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 STACKBOTTOM ((ptr_t) 0x4000000) -#	define DATAEND	/* not needed */ -#   endif -# endif - -# ifdef POWERPC -#   define MACH_TYPE "POWERPC" -#   ifdef MACOS -#     define ALIGNMENT 2  /* Still necessary?  Could it be 4?	*/ -#     ifndef __LOWMEM__ -#     include <LowMem.h> -#     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 -#     define ALIGNMENT 4	/* Guess.  Can someone verify?	*/ -				/* This was 2, but that didn't sound right. */ -#     define OS_TYPE "LINUX" -#     define HEURISTIC1 -#     define DYNAMIC_LOADING -#     undef STACK_GRAN -#     define STACK_GRAN 0x10000000 -	/* Stack usually starts at 0x80000000 */ -#     define LINUX_DATA_START -      extern int _end[]; -#     define DATAEND (_end) -#   endif -#   ifdef MACOSX -      /* There are reasons to suspect this may not be reliable. 	*/ -#     define ALIGNMENT 4 -#     define OS_TYPE "MACOSX" -#     define DATASTART ((ptr_t) get_etext()) -#     define STACKBOTTOM ((ptr_t) 0xc0000000) -#     define DATAEND	/* not needed */ -#     define MPROTECT_VDB -#     include <unistd.h> -#     define GETPAGESIZE() getpagesize() -#   endif -#   ifdef NETBSD -#     define ALIGNMENT 4 -#     define OS_TYPE "NETBSD" -#     define HEURISTIC2 -      extern char etext[]; -#     define DATASTART GC_data_start -#     define DYNAMIC_LOADING -#   endif -#   ifdef NOSYS -#     define ALIGNMENT 4 -#     define OS_TYPE "NOSYS" -      extern void __end[], __dso_handle[]; -#     define DATASTART (__dso_handle)  /* OK, that's ugly.  */ -#     define DATAEND (__end) -	/* Stack starts at 0xE0000000 for the simulator.  */ -#     undef STACK_GRAN -#     define STACK_GRAN 0x10000000 -#     define HEURISTIC1 -#   endif -# endif - -# ifdef VAX -#   define MACH_TYPE "VAX" -#   define ALIGNMENT 4	/* Pointers are longword aligned by 4.2 C compiler */ -    extern char etext[]; -#   define DATASTART ((ptr_t)(etext)) -#   ifdef BSD -#	define OS_TYPE "BSD" -#	define HEURISTIC1 -			/* HEURISTIC2 may be OK, but it's hard to test. */ -#   endif -#   ifdef ULTRIX -#	define OS_TYPE "ULTRIX" -#	define STACKBOTTOM ((ptr_t) 0x7fffc800) -#   endif -# endif - -# ifdef RT -#   define MACH_TYPE "RT" -#   define ALIGNMENT 4 -#   define DATASTART ((ptr_t) 0x10000000) -#   define STACKBOTTOM ((ptr_t) 0x1fffd800) -# endif - -# ifdef SPARC -#   define MACH_TYPE "SPARC" -#   if defined(__arch64__) || defined(__sparcv9) -#     define ALIGNMENT 8 -#     define CPP_WORDSZ 64 -#     define ELF_CLASS ELFCLASS64 -#   else -#     define ALIGNMENT 4	/* Required by hardware	*/ -#     define CPP_WORDSZ 32 -#   endif -#   define ALIGN_DOUBLE -#   ifdef SUNOS5 -#	define OS_TYPE "SUNOS5" -	extern int _etext[]; -	extern int _end[]; -	extern char * GC_SysVGetDataStart(); -#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext) -#	define DATAEND (_end) -#	if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) -#	    define USE_MMAP -	    /* Otherwise we now use calloc.  Mmap may result in the	*/ -	    /* heap interleaved with thread stacks, which can result in	*/ -	    /* excessive blacklisting.  Sbrk is unusable since it	*/ -	    /* doesn't interact correctly with the system malloc.	*/ -#	endif -#       ifdef USE_MMAP -#         define HEAP_START (ptr_t)0x40000000 -#       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:							*/ -#       include <sys/vmparam.h> -#	ifdef USERLIMIT -	  /* This should work everywhere, but doesn't.	*/ -#	  define STACKBOTTOM USRSTACK -#       else -#	  define HEURISTIC2 -#       endif -#	include <unistd.h> -#       define GETPAGESIZE()  sysconf(_SC_PAGESIZE) -		/* getpagesize() appeared to be missing from at least one */ -		/* Solaris 5.4 installation.  Weird.			  */ -#	define DYNAMIC_LOADING -#   endif -#   ifdef SUNOS4 -#	define OS_TYPE "SUNOS4" -	/* [If you have a weak stomach, don't read this.]		*/ -	/* We would like to use:					*/ -/* #       define DATASTART ((ptr_t)((((word) (etext)) + 0x1fff) & ~0x1fff)) */ -	/* This fails occasionally, due to an ancient, but very 	*/ -	/* persistent ld bug.  etext is set 32 bytes too high.		*/ -	/* We instead read the text segment size from the a.out		*/ -	/* header, which happens to be mapped into our address space	*/ -	/* at the start of the text segment.  The detective work here	*/ -	/* was done by Robert Ehrlich, Manuel Serrano, and Bernard	*/ -	/* Serpette of INRIA.						*/ -	/* This assumes ZMAGIC, i.e. demand-loadable executables.	*/ -#	define TEXTSTART 0x2000 -#       define DATASTART ((ptr_t)(*(int *)(TEXTSTART+0x4)+TEXTSTART)) -#	define MPROTECT_VDB -#	define HEURISTIC1 -# 	define DYNAMIC_LOADING -#   endif -#   ifdef DRSNX -#	define OS_TYPE "DRSNX" -	extern char * GC_SysVGetDataStart(); -	extern int etext[]; -#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext) -#	define MPROTECT_VDB -#       define STACKBOTTOM ((ptr_t) 0xdfff0000) -#	define DYNAMIC_LOADING -#   endif -#   ifdef LINUX -#     define OS_TYPE "LINUX" -#     ifdef __ELF__ -#       define DYNAMIC_LOADING -#     else -          Linux Sparc/a.out not supported -#     endif -      extern int _end[]; -      extern int _etext[]; -#     define DATAEND (_end) -#     define SVR4 -#     ifdef __arch64__ -#	define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, _etext) -	/* libc_stack_end is not set reliably for sparc64 */ -#       define STACKBOTTOM ((ptr_t) 0x80000000000ULL) -#     else -#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext) -#	define LINUX_STACKBOTTOM -#     endif -#   endif -#   ifdef OPENBSD -#     define OS_TYPE "OPENBSD" -#     define STACKBOTTOM ((ptr_t) 0xf8000000) -      extern int etext[]; -#     define DATASTART ((ptr_t)(etext)) -#   endif -#   ifdef NETBSD -#     define OS_TYPE "NETBSD" -#     define HEURISTIC2 -#     ifdef __ELF__ -#	define DATASTART GC_data_start -#	define DYNAMIC_LOADING -#     else -	extern char etext[]; -#	define DATASTART ((ptr_t)(etext)) -#     endif -#   endif -# endif - -# ifdef I386 -#   define MACH_TYPE "I386" -#   define ALIGNMENT 4	/* Appears to hold for all "32 bit" compilers	*/ -			/* except Borland.  The -a4 option fixes 	*/ -			/* Borland.					*/ -                        /* Ivan Demakov: For Watcom the option is -zp4. */ -#   ifndef SMALL_CONFIG -#     define ALIGN_DOUBLE /* Not strictly necessary, but may give speed   */ -			  /* improvement on Pentiums.			  */ -#   endif -#   ifdef HAVE_BUILTIN_UNWIND_INIT -#	define USE_GENERIC_PUSH_REGS -#   endif -#   ifdef SEQUENT -#	define OS_TYPE "SEQUENT" -	extern int etext[]; -#       define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) -#       define STACKBOTTOM ((ptr_t) 0x3ffff000)  -#   endif -#   ifdef BEOS -#     define OS_TYPE "BEOS" -#     include <OS.h> -#     define GETPAGESIZE() B_PAGE_SIZE -      extern int etext[]; -#     define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) -#   endif -#   ifdef SUNOS5 -#	define OS_TYPE "SUNOS5" -        extern int _etext[], _end[]; -  	extern char * GC_SysVGetDataStart(); -#       define DATASTART GC_SysVGetDataStart(0x1000, _etext) -#	define DATAEND (_end) -/*	# define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,  	*/ -/*      but reportedly breaks under 2.8.  It appears that the stack	*/ -/* 	base is a property of the executable, so this should not break	*/ -/* 	old executables.						*/ -/*  	HEURISTIC2 probably works, but this appears to be preferable.	*/ -#       include <sys/vm.h> -#	define STACKBOTTOM USRSTACK -/* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */ -/* It appears to be fixed in 2.8 and 2.9.				*/ -#	ifdef SOLARIS25_PROC_VDB_BUG_FIXED -#	  define PROC_VDB -#	endif -#	define DYNAMIC_LOADING -#	if !defined(USE_MMAP) && defined(REDIRECT_MALLOC) -#	    define USE_MMAP -	    /* Otherwise we now use calloc.  Mmap may result in the	*/ -	    /* heap interleaved with thread stacks, which can result in	*/ -	    /* excessive blacklisting.  Sbrk is unusable since it	*/ -	    /* doesn't interact correctly with the system malloc.	*/ -#	endif -#       ifdef USE_MMAP -#         define HEAP_START (ptr_t)0x40000000 -#       else -#	  define HEAP_START DATAEND -#       endif -#   endif -#   ifdef SCO -#	define OS_TYPE "SCO" -	extern int etext[]; -#   	define DATASTART ((ptr_t)((((word) (etext)) + 0x3fffff) \ -				  & ~0x3fffff) \ -				 +((word)etext & 0xfff)) -#	define STACKBOTTOM ((ptr_t) 0x7ffffffc) -#   endif -#   ifdef SCO_ELF -#       define OS_TYPE "SCO_ELF" -        extern int etext[]; -#       define DATASTART ((ptr_t)(etext)) -#       define STACKBOTTOM ((ptr_t) 0x08048000) -#       define DYNAMIC_LOADING -#	define ELF_CLASS ELFCLASS32 -#   endif -#   ifdef DGUX -#	define OS_TYPE "DGUX" -	extern int _etext, _end; -	extern char * GC_SysVGetDataStart(); -#	define DATASTART GC_SysVGetDataStart(0x1000, &_etext) -#	define DATAEND (&_end) -#	define STACK_GROWS_DOWN -#	define HEURISTIC2 -#	include <unistd.h> -#	define GETPAGESIZE()  sysconf(_SC_PAGESIZE) -#	define DYNAMIC_LOADING -#	ifndef USE_MMAP -#	  define USE_MMAP -#	endif /* USE_MMAP */ -#	define MAP_FAILED (void *) -1 -#	ifdef USE_MMAP -#	  define HEAP_START (ptr_t)0x40000000 -#	else /* USE_MMAP */ -#	  define HEAP_START DATAEND -#	endif /* USE_MMAP */ -#   endif /* DGUX */ - -#   ifdef LINUX -#	ifndef __GNUC__ -	  /* The Intel compiler doesn't like inline assembly */ -#	  define USE_GENERIC_PUSH_REGS -# 	endif -#	define OS_TYPE "LINUX" -#       define LINUX_STACKBOTTOM -#	if 0 -#	  define HEURISTIC1 -#         undef STACK_GRAN -#         define STACK_GRAN 0x10000000 -	  /* STACKBOTTOM is usually 0xc0000000, but this changes with	*/ -	  /* different kernel configurations.  In particular, systems	*/ -	  /* with 2GB physical memory will usually move the user	*/ -	  /* address space limit, and hence initial SP to 0x80000000.	*/ -#       endif -#       if !defined(GC_LINUX_THREADS) || !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 HEAP_START 0x1000 -		/* This encourages mmap to give us low addresses,	*/ -		/* thus allowing the heap to grow to ~3GB		*/ -#       ifdef __ELF__ -#            define DYNAMIC_LOADING -#	     ifdef UNDEFINED	/* includes ro data */ -	       extern int _etext[]; -#              define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff)) -#	     endif -#	     include <features.h> -#	     if defined(__GLIBC__) && __GLIBC__ >= 2 -#		 define LINUX_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   */ -			      /* ld options were passed through.        */ -			      /* We could use _etext instead, but that  */ -			      /* would include .rodata, which may       */ -			      /* contain large read-only data tables    */ -			      /* that we'd rather not scan.		*/ -#	     endif -	     extern int _end[]; -#	     define DATAEND (_end) -#	else -	     extern int etext[]; -#            define DATASTART ((ptr_t)((((word) (etext)) + 0xfff) & ~0xfff)) -#       endif -#	ifdef USE_I686_PREFETCH -#	  define PREFETCH(x) \ -	    __asm__ __volatile__ ("	prefetchnta	%0": : "m"(*(char *)(x))) -	    /* Empirically prefetcht0 is much more effective at reducing	*/ -	    /* cache miss stalls for the targetted load instructions.  But it	*/ -	    /* seems to interfere enough with other cache traffic that the net	*/ -	    /* result is worse than prefetchnta.				*/ -#         if 0  -	    /* Using prefetches for write seems to have a slight negative	*/ -	    /* impact on performance, at least for a PIII/500.			*/ -#	    define PREFETCH_FOR_WRITE(x) \ -	      __asm__ __volatile__ ("	prefetcht0	%0": : "m"(*(char *)(x))) -#	  endif -#	endif -#	ifdef USE_3DNOW_PREFETCH -#	  define PREFETCH(x) \ -	    __asm__ __volatile__ ("	prefetch	%0": : "m"(*(char *)(x))) -#	  define PREFETCH_FOR_WRITE(x) \ -	    __asm__ __volatile__ ("	prefetchw	%0": : "m"(*(char *)(x))) -#	endif -#   endif -#   ifdef CYGWIN32 -#       define OS_TYPE "CYGWIN32" -          extern int _data_start__[]; -          extern int _data_end__[]; -          extern int _bss_start__[]; -          extern int _bss_end__[]; -  	/* For binutils 2.9.1, we have			*/ -  	/*	DATASTART   = _data_start__		*/ -  	/*	DATAEND	    = _bss_end__		*/ -  	/* whereas for some earlier versions it was	*/ -  	/*	DATASTART   = _bss_start__		*/ -  	/*	DATAEND	    = _data_end__		*/ -  	/* To get it right for both, we take the	*/ -  	/* minumum/maximum of the two.			*/ -#   	define MAX(x,y) ((x) > (y) ? (x) : (y)) -#   	define MIN(x,y) ((x) < (y) ? (x) : (y)) -#       define DATASTART ((ptr_t) MIN(_data_start__, _bss_start__)) -#       define DATAEND	 ((ptr_t) MAX(_data_end__, _bss_end__)) -#	undef STACK_GRAN -#       define STACK_GRAN 0x10000 -#       define HEURISTIC1 -#   endif -#   ifdef OS2 -#	define OS_TYPE "OS2" - 	    	/* STACKBOTTOM and DATASTART are handled specially in 	*/ -		/* os_dep.c. OS2 actually has the right			*/ -		/* system call!						*/ -#	define DATAEND	/* not needed */ -#	define USE_GENERIC_PUSH_REGS -#   endif -#   ifdef MSWIN32 -#	define OS_TYPE "MSWIN32" -		/* STACKBOTTOM and DATASTART are handled specially in 	*/ -		/* os_dep.c.						*/ -#       ifndef __WATCOMC__ -#	  define MPROTECT_VDB -#	endif -#       define DATAEND  /* not needed */ -#   endif -#   ifdef MSWINCE -#	define OS_TYPE "MSWINCE" -#       define DATAEND  /* not needed */ -#   endif -#   ifdef DJGPP -#       define OS_TYPE "DJGPP" -#       include "stubinfo.h" -        extern int etext[]; -        extern int _stklen; -        extern int __djgpp_stack_limit; -#       define DATASTART ((ptr_t)((((word) (etext)) + 0x1ff) & ~0x1ff)) -/* #       define STACKBOTTOM ((ptr_t)((word) _stubinfo + _stubinfo->size \ -                                                     + _stklen)) */ -#       define STACKBOTTOM ((ptr_t)((word) __djgpp_stack_limit + _stklen)) -		/* This may not be right.  */ -#   endif -#   ifdef OPENBSD -#	define OS_TYPE "OPENBSD" -#   endif -#   ifdef FREEBSD -#	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 ((ptr_t)(etext)) -#   endif -#   ifdef NETBSD -#	define OS_TYPE "NETBSD" -#	ifdef __ELF__ -#	    define DYNAMIC_LOADING -#	endif -#   endif -#   ifdef THREE86BSD -#	define OS_TYPE "THREE86BSD" -#   endif -#   ifdef BSDI -#	define OS_TYPE "BSDI" -#   endif -#   if defined(OPENBSD) || 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 STACKBOTTOM ((ptr_t)0xc0000000) -#	define DATAEND	/* not needed */ -#   endif -#   ifdef DOS4GW -#     define OS_TYPE "DOS4GW" -      extern long __nullarea; -      extern char _end; -      extern char *_STACKTOP; -      /* Depending on calling conventions Watcom C either precedes -         or does not precedes with undescore names of C-variables. -         Make sure startup code variables always have the same names.  */ -      #pragma aux __nullarea "*"; -      #pragma aux _end "*"; -#     define STACKBOTTOM ((ptr_t) _STACKTOP) -                         /* confused? me too. */ -#     define DATASTART ((ptr_t) &__nullarea) -#     define DATAEND ((ptr_t) &_end) -#   endif -#   ifdef HURD -#     define OS_TYPE "HURD" -#     define STACK_GROWS_DOWN -#     define HEURISTIC2 -      extern int  __data_start[]; -#     define DATASTART ( (ptr_t) (__data_start)) -      extern int   _end[]; -#     define DATAEND ( (ptr_t) (_end)) -/* #     define MPROTECT_VDB  Not quite working yet? */ -#     define DYNAMIC_LOADING -#   endif -# endif - -# ifdef NS32K -#   define MACH_TYPE "NS32K" -#   define ALIGNMENT 4 -    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   */ -			      /* ld options were passed through.        */ -#   define STACKBOTTOM ((ptr_t) 0xfffff000) /* for Encore */ -# endif - -# ifdef MIPS -#   define MACH_TYPE "MIPS" -#   ifdef LINUX -      /* This was developed for a linuxce style platform.  Probably	*/ -      /* needs to be tweaked for workstation class machines.		*/ -#     define OS_TYPE "LINUX" -#     define DYNAMIC_LOADING -      extern int _end[]; -#     define DATAEND (_end) -      extern int __data_start[]; -#     define DATASTART ((ptr_t)(__data_start)) -#     define ALIGNMENT 4 -#     define USE_GENERIC_PUSH_REGS -#     if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2 -#        define LINUX_STACKBOTTOM -#     else -#        define STACKBOTTOM 0x80000000 -#     endif -#   endif /* Linux */ -#   ifdef EWS4800 -#      define HEURISTIC2 -#      if defined(_MIPS_SZPTR) && (_MIPS_SZPTR == 64) -         extern int _fdata[], _end[]; -#        define DATASTART ((ptr_t)_fdata) -#        define DATAEND ((ptr_t)_end) -#        define CPP_WORDSZ _MIPS_SZPTR -#        define ALIGNMENT (_MIPS_SZPTR/8) -#      else -         extern int etext[], edata[], end[]; -         extern int _DYNAMIC_LINKING[], _gp[]; -#        define DATASTART ((ptr_t)((((word)etext + 0x3ffff) & ~0x3ffff) \ -               + ((word)etext & 0xffff))) -#        define DATAEND (edata) -#        define DATASTART2 (_DYNAMIC_LINKING \ -               ? (ptr_t)(((word)_gp + 0x8000 + 0x3ffff) & ~0x3ffff) \ -               : (ptr_t)edata) -#        define DATAEND2 (end) -#        define ALIGNMENT 4 -#      endif -#      define OS_TYPE "EWS4800" -#      define USE_GENERIC_PUSH_REGS 1 -#   endif -#   ifdef ULTRIX -#	define HEURISTIC2 -#       define DATASTART (ptr_t)0x10000000 -			      /* Could probably be slightly higher since */ -			      /* startup code allocates lots of stuff.   */ -#	define OS_TYPE "ULTRIX" -#       define ALIGNMENT 4 -#   endif -#   ifdef RISCOS -#	define HEURISTIC2 -#       define DATASTART (ptr_t)0x10000000 -#	define OS_TYPE "RISCOS" -#   	define ALIGNMENT 4  /* Required by hardware */ -#   endif -#   ifdef IRIX5 -#	define HEURISTIC2 -        extern int _fdata[]; -#       define DATASTART ((ptr_t)(_fdata)) -#       ifdef USE_MMAP -#         define HEAP_START (ptr_t)0x30000000 -#       else -#	  define HEAP_START DATASTART -#       endif -			      /* Lowest plausible heap address.		*/ -			      /* In the MMAP case, we map there.	*/ -			      /* In either case it is used to identify	*/ -			      /* heap sections so they're not 		*/ -			      /* considered as roots.			*/ -#	define OS_TYPE "IRIX5" -#       define MPROTECT_VDB -#       ifdef _MIPS_SZPTR -#	  define CPP_WORDSZ _MIPS_SZPTR -#	  define ALIGNMENT (_MIPS_SZPTR/8) -#	  if CPP_WORDSZ != 64 -#	    define ALIGN_DOUBLE -#	  endif -#	else -#         define ALIGNMENT 4 -#	  define ALIGN_DOUBLE -#	endif -#	define DYNAMIC_LOADING -#   endif -#   ifdef MSWINCE -#       define OS_TYPE "MSWINCE" -#       define ALIGNMENT 4 -#       define DATAEND /* not needed */ -#   endif -#   if defined(NETBSD) -      /* This also checked for __MIPSEL__ .  Why?  NETBSD recognition	*/ -      /* should be handled at the top of the file.			*/ -#     define ALIGNMENT 4 -#     define OS_TYPE "NETBSD" -#     define HEURISTIC2 -#     define USE_GENERIC_PUSH_REGS -#     ifdef __ELF__ -        extern int etext[]; -#       define DATASTART GC_data_start -#       define NEED_FIND_LIMIT -#       define DYNAMIC_LOADING -#     else -#       define DATASTART ((ptr_t) 0x10000000) -#       define STACKBOTTOM ((ptr_t) 0x7ffff000) -#     endif /* _ELF_ */ -#  endif -# endif - -# ifdef RS6000 -#   define MACH_TYPE "RS6000" -#   ifdef __64BIT__ -#     define ALIGNMENT 8 -#     define CPP_WORDSZ 64 -#     define STACKBOTTOM 0x1000000000000000 -#   else -#     define ALIGNMENT 4 -#     define CPP_WORDSZ 32 -#     define STACKBOTTOM ((ptr_t)((ulong)&errno)) -#   endif -    extern int _data[], _end[]; -#   define DATASTART ((ptr_t)((ulong)_data)) -#   define DATAEND ((ptr_t)((ulong)_end)) -    extern int errno; -#   define USE_GENERIC_PUSH_REGS -#   define DYNAMIC_LOADING -	/* For really old versions of AIX, this may have to be removed. */ -# endif - -# ifdef HP_PA -#   define MACH_TYPE "HP_PA" -#   ifdef __LP64__ -#     define CPP_WORDSZ 64 -#     define ALIGNMENT 8 -#   else -#     define CPP_WORDSZ 32 -#     define ALIGNMENT 4 -#     define ALIGN_DOUBLE -#   endif -#   if !defined(GC_HPUX_THREADS) && !defined(GC_LINUX_THREADS) -#     ifndef LINUX /* For now. */ -#       define MPROTECT_VDB -#     endif -#   else -#     define GENERIC_COMPARE_AND_SWAP -	/* No compare-and-swap instruction.  Use pthread mutexes 	*/ -	/* when we absolutely have to.					*/ -#     ifdef PARALLEL_MARK -#	define USE_MARK_BYTES -		/* Minimize compare-and-swap usage.		*/ -#     endif -#   endif -#   define STACK_GROWS_UP -#   ifdef HPUX -#     define OS_TYPE "HPUX" -      extern int __data_start[]; -#     define DATASTART ((ptr_t)(__data_start)) -#     if 0 -	/* The following appears to work for 7xx systems running HP/UX	*/ -	/* 9.xx Furthermore, it might result in much faster		*/ -	/* collections than HEURISTIC2, which may involve scanning	*/ -	/* segments that directly precede the stack.  It is not the	*/ -	/* default, since it may not work on older machine/OS		*/ -	/* combinations. (Thanks to Raymond X.T. Nijssen for uncovering	*/ -	/* this.)							*/ -#       define STACKBOTTOM ((ptr_t) 0x7b033000)  /* from /etc/conf/h/param.h */ -#     else -	/* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2	*/ -	/* to this.  Note that the GC must be initialized before the	*/ -    	/* first putenv call.						*/ -	extern char ** environ; -#       define STACKBOTTOM ((ptr_t)environ) -#     endif -#     define DYNAMIC_LOADING -#     include <unistd.h> -#     define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) -#     ifndef __GNUC__ -#       define PREFETCH(x)  { \ -                              register long addr = (long)(x); \ -                              (void) _asm ("LDW", 0, 0, addr, 0); \ -                            } -#     endif -#   endif /* HPUX */ -#   ifdef LINUX -#     define OS_TYPE "LINUX" -#     define LINUX_STACKBOTTOM -#     define DYNAMIC_LOADING -#     define SEARCH_FOR_DATA_START -      extern int _end[]; -#     define DATAEND (&_end) -#   endif /* LINUX */ -# endif /* HP_PA */ - -# ifdef ALPHA -#   define MACH_TYPE "ALPHA" -#   define ALIGNMENT 8 -#   ifndef LINUX -#     define USE_GENERIC_PUSH_REGS -      /* Gcc and probably the DEC/Compaq compiler spill pointers to preserved */ -      /* fp registers in some cases when the target is a 21264.  The assembly */ -      /* code doesn't handle that yet, and version dependencies make that a   */ -      /* bit tricky.  Do the easy thing for now.				    */ -#   endif -#   ifdef NETBSD -#	define OS_TYPE "NETBSD" -#	define HEURISTIC2 -#	define DATASTART GC_data_start -#	define ELFCLASS32 32 -#	define ELFCLASS64 64 -#	define ELF_CLASS ELFCLASS64 -#   	define CPP_WORDSZ 64 -#       define DYNAMIC_LOADING -#   endif -#   ifdef OPENBSD -#	define OS_TYPE "OPENBSD" -#	define HEURISTIC2 -#   	define CPP_WORDSZ 64 -#   	ifdef __ELF__	/* since OpenBSD/Alpha 2.9 */ -#	   define DATASTART GC_data_start -#   	   define ELFCLASS32 32 -#   	   define ELFCLASS64 64 -#   	   define ELF_CLASS ELFCLASS64 -#       else		/* ECOFF, until OpenBSD/Alpha 2.7 */ -#   	   define DATASTART ((ptr_t) 0x140000000) -#   	endif -#   endif -#   ifdef 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 -#	define FREEBSD_STACKBOTTOM -#	ifdef __ELF__ -#	    define DYNAMIC_LOADING -#	endif -/* Handle unmapped hole alpha*-*-freebsd[45]* puts between etext and edata. */ -	extern char etext[]; -	extern char edata[]; -	extern char end[]; -#	define NEED_FIND_LIMIT -#	define DATASTART ((ptr_t)(&etext)) -#	define DATAEND (GC_find_limit (DATASTART, TRUE)) -#	define DATASTART2 ((ptr_t)(&edata)) -#	define DATAEND2 ((ptr_t)(&end)) -#	define CPP_WORDSZ 64 -#   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 conervative, 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))) -#   	define CPP_WORDSZ 64 -#   	define MPROTECT_VDB -#   	define DYNAMIC_LOADING -#   endif -#   ifdef LINUX -#       define OS_TYPE "LINUX" -#       define CPP_WORDSZ 64 -#       define STACKBOTTOM ((ptr_t) 0x120000000) -#       ifdef __ELF__ -#	  define SEARCH_FOR_DATA_START -#         define DYNAMIC_LOADING -#       else -#           define DATASTART ((ptr_t) 0x140000000) -#       endif -	extern int _end[]; -#	define DATAEND (_end) -#	define MPROTECT_VDB -		/* Has only been superficially tested.  May not	*/ -		/* work on all versions.			*/ -#   endif -# endif - -# ifdef IA64 -#   define MACH_TYPE "IA64" -#   define USE_GENERIC_PUSH_REGS -	/* We need to get preserved registers in addition to register   */ -	/* windows.   That's easiest to do with setjmp.			*/ -#   ifdef PARALLEL_MARK -#	define USE_MARK_BYTES -	    /* Compare-and-exchange is too expensive to use for 	*/ -	    /* setting mark bits.					*/ -#   endif -#   ifdef HPUX -#	ifdef _ILP32 -#	  define CPP_WORDSZ 32 -#         define ALIGN_DOUBLE -	    /* Requires 8 byte alignment for malloc */ -#   	  define ALIGNMENT 4 -#       else -#	  ifndef _LP64 -		---> unknown ABI -#         endif -#	  define CPP_WORDSZ 64 -#   	  define ALIGN_DOUBLE -	    /* Requires 16 byte alignment for malloc */ -#         define ALIGNMENT 8 -#       endif -#       define OS_TYPE "HPUX"	 -        extern int __data_start[]; -#       define DATASTART ((ptr_t)(__data_start)) -        /* Gustavo Rodriguez-Rivera suggested changing HEURISTIC2	*/ -        /* to this.  Note that the GC must be initialized before the	*/ -    	/* first putenv call.						*/ -	extern char ** environ; -#       define STACKBOTTOM ((ptr_t)environ) -#       define DYNAMIC_LOADING -#       include <unistd.h> -#       define GETPAGESIZE() sysconf(_SC_PAGE_SIZE) - 	/* The following was empirically determined, and is probably	*/ -	/* not very robust.						*/ -	/* Note that the backing store base seems to be at a nice 	*/ -	/* address minus one page.					*/ -#	define BACKING_STORE_DISPLACEMENT 0x1000000 -#	define BACKING_STORE_ALIGNMENT 0x1000 -#       define BACKING_STORE_BASE \ -	  (ptr_t)(((word)GC_stackbottom - BACKING_STORE_DISPLACEMENT - 1) \ -			& ~(BACKING_STORE_ALIGNMENT - 1)) -#   endif -#   ifdef LINUX -#   	define CPP_WORDSZ 64 -#   	define ALIGN_DOUBLE -	  /* Requires 16 byte alignment for malloc */ -#   	define ALIGNMENT 8 -#       define OS_TYPE "LINUX" -	/* The following works on NUE and older kernels:	*/ -/* #       define STACKBOTTOM ((ptr_t) 0xa000000000000000l)	*/ -	/* This does not work on NUE:				*/ -#       define LINUX_STACKBOTTOM -	/* We also need the base address of the register stack	*/ -	/* backing store.  This is computed in 			*/ -	/* GC_linux_register_stack_base based on the following	*/ -	/* constants:						*/ -#       define BACKING_STORE_ALIGNMENT 0x100000 -#       define BACKING_STORE_DISPLACEMENT 0x80000000 -	extern char * GC_register_stackbottom; -#	define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom) -#	define SEARCH_FOR_DATA_START -#	ifdef __GNUC__ -#         define DYNAMIC_LOADING -#	else -	  /* In the Intel compiler environment, we seem to end up with  */ -	  /* statically linked executables and an undefined reference	*/ -	  /* to _DYNAMIC						*/ -#  	endif -#	define MPROTECT_VDB -		/* Requires Linux 2.3.47 or later.	*/ -	extern int _end[]; -#	define DATAEND (_end) -#       ifdef __GNUC__ -#	  define PREFETCH(x) \ -	    __asm__ ("	lfetch	[%0]": : "r"((void *)(x))) -#	  define PREFETCH_FOR_WRITE(x) \ -	    __asm__ ("	lfetch.excl	[%0]": : "r"((void *)(x))) -#	  define CLEAR_DOUBLE(x) \ -	    __asm__ ("	stf.spill	[%0]=f0": : "r"((void *)(x))) -#       endif -#   endif -# endif - -# ifdef M88K -#   define MACH_TYPE "M88K" -#   define ALIGNMENT 4 -#   define ALIGN_DOUBLE -    extern int etext[]; -#   ifdef CX_UX -#	define OS_TYPE "CX_UX" -#       define DATASTART ((((word)etext + 0x3fffff) & ~0x3fffff) + 0x10000) -#   endif -#   ifdef  DGUX -#	define OS_TYPE "DGUX" -	extern char * GC_SysVGetDataStart(); -#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext) -#   endif -#   define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */ -# endif - -# ifdef S370 -#   define MACH_TYPE "S370" -#   define ALIGNMENT 4	/* Required by hardware	*/ -#   define USE_GENERIC_PUSH_REGS -#   ifdef UTS4 -#       define OS_TYPE "UTS4" -        extern int etext[]; -	extern int _etext[]; -	extern int _end[]; -	extern char * GC_SysVGetDataStart(); -#       define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext) -#	define DATAEND (_end) -#	define HEURISTIC2 -#   endif -#   ifdef LINUX -#       define OS_TYPE "LINUX" -#       define HEURISTIC1 -#       define DYNAMIC_LOADING -        extern int __data_start[]; -#       define DATASTART ((ptr_t)(__data_start)) -#   endif -# endif - -# if defined(PJ) -#   define ALIGNMENT 4 -    extern int _etext[]; -#   define DATASTART ((ptr_t)(_etext)) -#   define HEURISTIC1 -# endif - -# ifdef ARM32 -#   define CPP_WORDSZ 32 -#   define MACH_TYPE "ARM32" -#   define ALIGNMENT 4 -#   ifdef NETBSD -#       define OS_TYPE "NETBSD" -#       define HEURISTIC2 -        extern char etext[]; -#       define DATASTART ((ptr_t)(etext)) -#       define USE_GENERIC_PUSH_REGS -#   endif -#   ifdef LINUX -#       define OS_TYPE "LINUX" -#       define HEURISTIC1 -#       undef STACK_GRAN -#       define STACK_GRAN 0x10000000 -#       define USE_GENERIC_PUSH_REGS -#       ifdef __ELF__ -#            define DYNAMIC_LOADING -#	     include <features.h> -#	     if defined(__GLIBC__) && __GLIBC__ >= 2 -#		 define LINUX_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   */ -			      /* ld options were passed through.        */ -			      /* We could use _etext instead, but that  */ -			      /* would include .rodata, which may       */ -			      /* contain large read-only data tables    */ -			      /* that we'd rather not scan.		*/ -#	     endif -	     extern int _end[]; -#	     define DATAEND (_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 */ -#   endif -#   ifdef NOSYS -      /* __data_start is usually defined in the target linker script.  */ -      extern int __data_start[]; -#     define DATASTART (ptr_t)(__data_start) -#     define USE_GENERIC_PUSH_REGS -      /* __stack_base__ is set in newlib/libc/sys/arm/crt0.S  */ -      extern void *__stack_base__; -#     define STACKBOTTOM ((ptr_t) (__stack_base__)) -#   endif -#endif - -# ifdef SH -#   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 STACKBOTTOM ((ptr_t) 0x7c000000) -#     define USE_GENERIC_PUSH_REGS -#     define DYNAMIC_LOADING -#     define LINUX_DATA_START -      extern int _end[]; -#     define DATAEND (_end) -#   endif -# endif -  -# ifdef SH4 -#   define MACH_TYPE "SH4" -#   define OS_TYPE "MSWINCE" -#   define ALIGNMENT 4 -#   define DATAEND /* not needed */ -# endif - -#ifdef LINUX_DATA_START -    /* Some Linux distributions arrange to define __data_start.  Some	*/ -    /* define data_start as a weak symbol.  The latter is technically	*/ -    /* broken, since the user program may define data_start, in which	*/ -    /* case we lose.  Nonetheless, we try both, prefering __data_start.	*/ -    /* We assume gcc.	*/ -#   pragma weak __data_start -    extern int __data_start[]; -#   pragma weak data_start -    extern int data_start[]; -#   define DATASTART ((ptr_t)(__data_start != 0? __data_start : data_start)) -#endif - -#if defined(LINUX) && defined(REDIRECT_MALLOC) -    /* Rld appears to allocate some memory with its own allocator, and	*/ -    /* some through malloc, which might be redirected.  To make this	*/ -    /* work with collectable memory, we have to scan memory allocated	*/ -    /* by rld's internal malloc.					*/ -#   define USE_PROC_FOR_LIBRARIES -#endif -     -# ifndef STACK_GROWS_UP -#   define STACK_GROWS_DOWN -# endif - -# ifndef CPP_WORDSZ -#   define CPP_WORDSZ 32 -# endif - -# ifndef OS_TYPE -#   define OS_TYPE "" -# endif - -# ifndef DATAEND -    extern int end[]; -#   define DATAEND (end) -# endif - -# if defined(SVR4) && !defined(GETPAGESIZE) -#    include <unistd.h> -#    define GETPAGESIZE()  sysconf(_SC_PAGESIZE) -# endif - -# ifndef GETPAGESIZE -#   if defined(SUNOS5) || defined(IRIX5) -#	include <unistd.h> -#   endif -#   define GETPAGESIZE() getpagesize() -# endif - -# if defined(SUNOS5) || defined(DRSNX) || defined(UTS4) -	    /* OS has SVR4 generic features.  Probably others also qualify.	*/ -#   define SVR4 -# endif - -# if defined(SUNOS5) || defined(DRSNX) -	    /* OS has SUNOS5 style semi-undocumented interface to dynamic 	*/ -	    /* loader.								*/ -#   define SUNOS5DL -	    /* OS has SUNOS5 style signal handlers.				*/ -#   define SUNOS5SIGS -# endif - -# if defined(HPUX) -#   define SUNOS5SIGS -# endif - -# if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \ -	    || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) || defined(DGUX) \ -	    || defined(BSD) || defined(AIX) || defined(MACOSX) || defined(OSF1) -#   define UNIX_LIKE   /* Basic Unix-like system calls work.	*/ -# endif - -# if CPP_WORDSZ != 32 && CPP_WORDSZ != 64 -	   -> bad word size -# endif - -# ifdef PCR -#   undef DYNAMIC_LOADING -#   undef STACKBOTTOM -#   undef HEURISTIC1 -#   undef HEURISTIC2 -#   undef PROC_VDB -#   undef MPROTECT_VDB -#   define PCR_VDB -# endif - -# ifdef SRC_M3 -	/* Postponed for now. */ -#   undef PROC_VDB -#   undef MPROTECT_VDB -# endif - -# ifdef SMALL_CONFIG -	/* Presumably not worth the space it takes. */ -#   undef PROC_VDB -#   undef MPROTECT_VDB -# endif - -# ifdef USE_MUNMAP -#   undef MPROTECT_VDB  /* Can't deal with address space holes. */ -# endif - -# ifdef PARALLEL_MARK -#   undef MPROTECT_VDB  /* For now.	*/ -# endif - -# if !defined(PCR_VDB) && !defined(PROC_VDB) && !defined(MPROTECT_VDB) -#   define DEFAULT_VDB -# endif - -# ifndef PREFETCH -#   define PREFETCH(x) -#   define NO_PREFETCH -# endif - -# ifndef PREFETCH_FOR_WRITE -#   define PREFETCH_FOR_WRITE(x) -#   define NO_PREFETCH_FOR_WRITE -# endif - -# ifndef CACHE_LINE_SIZE -#   define CACHE_LINE_SIZE 32	/* Wild guess	*/ -# endif - -# if defined(SEARCH_FOR_DATA_START) -    extern ptr_t GC_data_start; -#   define DATASTART GC_data_start -# endif - -# ifndef CLEAR_DOUBLE -#   define CLEAR_DOUBLE(x) \ -		((word*)x)[0] = 0; \ -		((word*)x)[1] = 0; -# endif /* CLEAR_DOUBLE */ - -	/* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */ -# if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS) -#   define GC_SOLARIS_THREADS -# endif - -# if defined(GC_IRIX_THREADS) && !defined(IRIX5) -	--> inconsistent configuration -# endif -# if defined(GC_LINUX_THREADS) && !defined(LINUX) -	--> inconsistent configuration -# endif -# if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5) -	--> inconsistent configuration -# endif -# if defined(GC_HPUX_THREADS) && !defined(HPUX) -	--> inconsistent configuration -# endif -# if defined(GC_WIN32_THREADS) && !defined(MSWIN32) -	    /* Ideally CYGWIN32 should work, in addition to MSWIN32.  I suspect	*/ -	    /* the necessary code is mostly there, but nobody has actually made */ -	    /* sure the right combination of pieces is compiled in, etc.	*/ -	--> inconsistent configuration -# endif - -# if defined(PCR) || defined(SRC_M3) || \ -		defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) || \ -		defined(GC_PTHREADS) -#   define THREADS -# endif - -# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \ -	     || defined(LINT) || defined(MSWINCE) || defined(ARM32) \ -	     || (defined(I386) && defined(__LCC__)) -		/* Use setjmp based hack to mark from callee-save registers.    */ -		/* The define should move to the individual platform 		*/ -		/* descriptions.						*/ -#	define USE_GENERIC_PUSH_REGS -# endif - -# if defined(SPARC) -#   define ASM_CLEAR_CODE	/* Stack clearing is crucial, and we 	*/ -					/* include assembly code to do it well.	*/ -# endif - -	/* Can we save call chain in objects for debugging?   		        */ -	/* SET NFRAMES (# of saved frames) and NARGS (#of args for each frame)	*/ -	/* to reasonable values for the platform.				*/ -	/* Set SAVE_CALL_CHAIN if we can.  SAVE_CALL_COUNT can be specified at	*/ -	/* build time, though we feel free to adjust it slightly.		*/ -	/* Define NEED_CALLINFO if we either save the call stack or 		*/ -	/* GC_ADD_CALLER is defined.						*/ -#ifdef LINUX -# include <features.h> -# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2 -#   define HAVE_BUILTIN_BACKTRACE -# endif -#endif - -#if defined(SPARC) -# define CAN_SAVE_CALL_STACKS -# define CAN_SAVE_CALL_ARGS -#endif -#if defined(I386) && defined(LINUX) -	    /* SAVE_CALL_CHAIN is supported if the code is compiled to save	*/ -	    /* frame pointers by default, i.e. no -fomit-frame-pointer flag.	*/ -# define CAN_SAVE_CALL_STACKS -# define CAN_SAVE_CALL_ARGS -#endif -#if defined(HAVE_BUILTIN_BACKTRACE) && !defined(CAN_SAVE_CALL_STACKS) -# define CAN_SAVE_CALL_STACKS -#endif - -# if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \ -	     && defined(CAN_SAVE_CALL_STACKS) -#   define SAVE_CALL_CHAIN  -# endif -# ifdef SAVE_CALL_CHAIN -#   if defined(SAVE_CALL_NARGS) && defined(CAN_SAVE_CALL_ARGS) -#     define NARGS SAVE_CALL_NARGS -#   else -#     define NARGS 0	/* Number of arguments to save for each call.	*/ -#   endif -# endif -# ifdef SAVE_CALL_CHAIN -#   ifndef SAVE_CALL_COUNT -#     define NFRAMES 6	/* Number of frames to save. Even for		*/ -				/* alignment reasons.				*/ -#   else -#     define NFRAMES ((SAVE_CALL_COUNT + 1) & ~1) -#   endif -#   define NEED_CALLINFO -# endif /* SAVE_CALL_CHAIN */ -# ifdef GC_ADD_CALLER -#   define NFRAMES 1 -#   define NARGS 0 -#   define NEED_CALLINFO -# endif - -# if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL) -#   define DBG_HDRS_ALL -# endif - -#ifdef GC_PRIVATE_H -	/* This relies on some type definitions from gc_priv.h, from	*/ -        /* where it's normally included.				*/ -	/*								*/ -	/* How to get heap memory from the OS:				*/ -	/* Note that sbrk()-like allocation is preferred, since it 	*/ -	/* usually makes it possible to merge consecutively allocated	*/ -	/* chunks.  It also avoids unintented recursion with		*/ -	/* -DREDIRECT_MALLOC.						*/ -	/* GET_MEM() returns a HLKSIZE aligned chunk.			*/ -	/* 0 is taken to mean failure. 					*/ -	/* In the case os USE_MMAP, the argument must also be a 	*/ -	/* physical page size.						*/ -	/* GET_MEM is currently not assumed to retrieve 0 filled space, */ -	/* though we should perhaps take advantage of the case in which */ -	/* does.							*/ -	struct hblk;	/* See gc_priv.h.	*/ -# ifdef PCR -	    char * real_malloc(); -#   define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \ -					  + GC_page_size-1) -# else -#   ifdef OS2 -	      void * os2_alloc(size_t bytes); -#     define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \ -					    + GC_page_size) \ -					    + GC_page_size-1) -#   else -#     if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \ -		 (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \ -		 (defined(SUNOS5) && !defined(USE_MMAP)) -#       define GET_MEM(bytes) HBLKPTR((size_t) \ -					      calloc(1, (size_t)bytes + GC_page_size) \ -					      + GC_page_size-1) -#     else -#	ifdef MSWIN32 -		  extern ptr_t GC_win32_get_mem(); -#         define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes) -#	else -#	  ifdef MACOS -#	    if defined(USE_TEMPORARY_MEMORY) -			extern Ptr GC_MacTemporaryNewPtr(size_t size, -							 Boolean clearMemory); -#               define GET_MEM(bytes) HBLKPTR( \ -			    GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \ -			    + GC_page_size-1) -#	    else -#         	    define GET_MEM(bytes) HBLKPTR( \ -				NewPtrClear(bytes + GC_page_size) + GC_page_size-1) -#	    endif -#	  else -#	    ifdef MSWINCE -		      extern ptr_t GC_wince_get_mem(); -#	      define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes) -#	    else -#	      if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC) -			extern void *GC_amiga_get_mem(size_t size); -			define GET_MEM(bytes) HBLKPTR((size_t) \ -			  GC_amiga_get_mem((size_t)bytes + GC_page_size) \ -			  + GC_page_size-1) -#	      else -			extern ptr_t GC_unix_get_mem(); -#               define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes) -#	      endif -#	    endif -#	  endif -#	endif -#     endif -#   endif -# endif - -#endif /* GC_PRIVATE_H */ - -# endif /* GCCONFIG_H */ diff --git a/gc/include/private/solaris_threads.h b/gc/include/private/solaris_threads.h deleted file mode 100644 index 7d49c29..0000000 --- a/gc/include/private/solaris_threads.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifdef GC_SOLARIS_THREADS - -/* The set of all known threads.  We intercept thread creation and     */ -/* joins.  We never actually create detached threads.  We allocate all */ -/* new thread stacks ourselves.  These allow us to maintain this       */ -/* data structure.                                                     */ -/* Protected by GC_thr_lock.                                           */ -/* Some of this should be declared volatile, but that's incosnsistent  */ -/* with some library routine declarations.  In particular, the 	       */ -/* definition of cond_t doesn't mention volatile!                      */ -  typedef struct GC_Thread_Rep { -    struct GC_Thread_Rep * next; -    thread_t id; -    word flags; -#      define FINISHED 1       /* Thread has exited.   */ -#      define DETACHED 2       /* Thread is intended to be detached.   */ -#      define CLIENT_OWNS_STACK        4 -                               /* Stack was supplied by client.        */ -#      define SUSPNDED 8       /* Currently suspended.			*/ -    			       /* SUSPENDED is used insystem header.	*/ -    ptr_t stack; -    size_t stack_size; -    cond_t join_cv; -    void * status; -  } * GC_thread; -  extern GC_thread GC_new_thread(thread_t id); - -  extern GC_bool GC_thr_initialized; -  extern volatile GC_thread GC_threads[]; -  extern size_t GC_min_stack_sz; -  extern size_t GC_page_sz; -  extern void GC_thr_init(void); - -# endif /* GC_SOLARIS_THREADS */ - diff --git a/gc/include/private/specific.h b/gc/include/private/specific.h deleted file mode 100644 index 399f84f..0000000 --- a/gc/include/private/specific.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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. - * The major restriction is that each thread may only make a single - * pthread_setspecific call on a single key.  (The current data structure - * doesn't really require that.  The restriction should be easily removable.) - * We don't currently support the destruction functions, though that - * could be done. - * We also currently assume that only one pthread_setspecific call - * can be executed at a time, though that assumption would be easy to remove - * by adding a lock. - */ - -#include <errno.h> - -/* Called during key creation or setspecific.		*/ -/* For the GC we already hold lock.			*/ -/* Currently allocated objects leak on thread exit.	*/ -/* That's hard to fix, but OK if we allocate garbage	*/ -/* collected memory.					*/ -#define MALLOC_CLEAR(n) GC_INTERNAL_MALLOC(n, NORMAL) -#define PREFIXED(name) GC_##name - -#define TS_CACHE_SIZE 1024 -#define CACHE_HASH(n) (((((long)n) >> 8) ^ (long)n) & (TS_CACHE_SIZE - 1)) -#define TS_HASH_SIZE 1024 -#define HASH(n) (((((long)n) >> 8) ^ (long)n) & (TS_HASH_SIZE - 1)) - -/* An entry describing a thread-specific value for a given thread.	*/ -/* All such accessible structures preserve the invariant that if either	*/ -/* thread is a valid pthread id or qtid is a valid "quick tread id"	*/ -/* for a thread, then value holds the corresponding thread specific	*/ -/* value.  This invariant must be preserved at ALL times, since		*/ -/* asynchronous reads are allowed.					*/ -typedef struct thread_specific_entry { -	unsigned long qtid;	/* quick thread id, only for cache */ -	void * value; -	struct thread_specific_entry *next; -	pthread_t thread; -} tse; - - -/* We represent each thread-specific datum as two tables.  The first is	*/ -/* a cache, indexed by a "quick thread identifier".  The "quick" thread	*/ -/* identifier is an easy to compute value, which is guaranteed to	*/ -/* determine the thread, though a thread may correspond to more than	*/ -/* one value.  We typically use the address of a page in the stack.	*/ -/* The second is a hash table, indexed by pthread_self().  It is used	*/ -/* only as a backup.							*/ - -/* Return the "quick thread id".  Default version.  Assumes page size,	*/ -/* or at least thread stack separation, is at least 4K.			*/ -/* 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.)*/ -static __inline__ unsigned long quick_thread_id() { -    int dummy; -    return (unsigned long)(&dummy) >> 12; -} - -#define INVALID_QTID ((unsigned long)0) -#define INVALID_THREADID ((pthread_t)0) - -typedef struct thread_specific_data { -    tse * volatile cache[TS_CACHE_SIZE]; -			/* A faster index to the hash table */ -    tse * hash[TS_HASH_SIZE]; -    pthread_mutex_t lock; -} tsd; - -typedef tsd * PREFIXED(key_t); - -extern int PREFIXED(key_create) (tsd ** key_ptr, void (* destructor)(void *)); - -extern int PREFIXED(setspecific) (tsd * key, void * value); - -extern void PREFIXED(remove_specific) (tsd * key); - -/* An internal version of getspecific that assumes a cache miss.	*/ -void * PREFIXED(slow_getspecific) (tsd * key, unsigned long qtid, -				   tse * volatile * cache_entry); - -static __inline__ void * PREFIXED(getspecific) (tsd * key) { -    long qtid = quick_thread_id(); -    unsigned hash_val = CACHE_HASH(qtid); -    tse * volatile * entry_ptr = key -> cache + hash_val; -    tse * entry = *entry_ptr;   /* Must be loaded only once.	*/ -    if (entry -> qtid == qtid) { -      GC_ASSERT(entry -> thread == pthread_self()); -      return entry -> value; -    } -    return PREFIXED(slow_getspecific) (key, qtid, entry_ptr); -} - - diff --git a/gc/include/weakpointer.h b/gc/include/weakpointer.h deleted file mode 100644 index 84906b0..0000000 --- a/gc/include/weakpointer.h +++ /dev/null @@ -1,221 +0,0 @@ -#ifndef	_weakpointer_h_ -#define	_weakpointer_h_ - -/**************************************************************************** - -WeakPointer and CleanUp - -    Copyright (c) 1991 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 copy this code for any purpose, -    provided the above notices are retained on all copies. - -    Last modified on Mon Jul 17 18:16:01 PDT 1995 by ellis - -****************************************************************************/ - -/**************************************************************************** - -WeakPointer - -A weak pointer is a pointer to a heap-allocated object that doesn't -prevent the object from being garbage collected. Weak pointers can be -used to track which objects haven't yet been reclaimed by the -collector. A weak pointer is deactivated when the collector discovers -its referent object is unreachable by normal pointers (reachability -and deactivation are defined more precisely below). A deactivated weak -pointer remains deactivated forever. - -****************************************************************************/ - - -template< class T > class WeakPointer { -public: - -WeakPointer( T* t = 0 ) -    /* Constructs a weak pointer for *t. t may be null. It is an error -       if t is non-null and *t is not a collected object. */ -    {impl = _WeakPointer_New( t );} - -T* Pointer() -    /* wp.Pointer() returns a pointer to the referent object of wp or -       null if wp has been deactivated (because its referent object -       has been discovered unreachable by the collector). */ -    {return (T*) _WeakPointer_Pointer( this->impl );} - -int operator==( WeakPointer< T > wp2 ) -    /* Given weak pointers wp1 and wp2, if wp1 == wp2, then wp1 and -       wp2 refer to the same object. If wp1 != wp2, then either wp1 -       and wp2 don't refer to the same object, or if they do, one or -       both of them has been deactivated. (Note: If objects t1 and t2 -       are never made reachable by their clean-up functions, then -       WeakPointer<T>(t1) == WeakPointer<T>(t2) if and only t1 == t2.) */ -    {return _WeakPointer_Equal( this->impl, wp2.impl );} - -int Hash() -    /* Returns a hash code suitable for use by multiplicative- and -       division-based hash tables. If wp1 == wp2, then wp1.Hash() == -       wp2.Hash(). */ -    {return _WeakPointer_Hash( this->impl );} - -private: -void* impl; -}; - -/***************************************************************************** - -CleanUp - -A garbage-collected object can have an associated clean-up function -that will be invoked some time after the collector discovers the -object is unreachable via normal pointers. Clean-up functions can be -used to release resources such as open-file handles or window handles -when their containing objects become unreachable.  If a C++ object has -a non-empty explicit destructor (i.e. it contains programmer-written -code), the destructor will be automatically registered as the object's -initial clean-up function. - -There is no guarantee that the collector will detect every unreachable -object (though it will find almost all of them). Clients should not -rely on clean-up to cause some action to occur immediately -- clean-up -is only a mechanism for improving resource usage. - -Every object with a clean-up function also has a clean-up queue. When -the collector finds the object is unreachable, it enqueues it on its -queue. The clean-up function is applied when the object is removed -from the queue. By default, objects are enqueued on the garbage -collector's queue, and the collector removes all objects from its -queue after each collection. If a client supplies another queue for -objects, it is his responsibility to remove objects (and cause their -functions to be called) by polling it periodically. - -Clean-up queues allow clean-up functions accessing global data to -synchronize with the main program. Garbage collection can occur at any -time, and clean-ups invoked by the collector might access data in an -inconsistent state. A client can control this by defining an explicit -queue for objects and polling it at safe points. - -The following definitions are used by the specification below: - -Given a pointer t to a collected object, the base object BO(t) is the -value returned by new when it created the object. (Because of multiple -inheritance, t and BO(t) may not be the same address.) - -A weak pointer wp references an object *t if BO(wp.Pointer()) == -BO(t). - -***************************************************************************/ - -template< class T, class Data > class CleanUp { -public: - -static void Set( T* t, void c( Data* d, T* t ), Data* d = 0 ) -    /* Sets the clean-up function of object BO(t) to be <c, d>, -       replacing any previously defined clean-up function for BO(t); c -       and d can be null, but t cannot. Sets the clean-up queue for -       BO(t) to be the collector's queue. When t is removed from its -       clean-up queue, its clean-up will be applied by calling c(d, -       t). It is an error if *t is not a collected object. */  -       {_CleanUp_Set( t, c, d );} - -static void Call( T* t ) -    /* Sets the new clean-up function for BO(t) to be null and, if the -       old one is non-null, calls it immediately, even if BO(t) is -       still reachable. Deactivates any weak pointers to BO(t). */ -       {_CleanUp_Call( t );} - -class Queue {public: -    Queue() -        /* Constructs a new queue. */ -            {this->head = _CleanUp_Queue_NewHead();} - -    void Set( T* t ) -        /* q.Set(t) sets the clean-up queue of BO(t) to be q. */ -            {_CleanUp_Queue_Set( this->head, t );} - -    int Call() -        /* If q is non-empty, q.Call() removes the first object and -           calls its clean-up function; does nothing if q is -           empty. Returns true if there are more objects in the -           queue. */ -           {return _CleanUp_Queue_Call( this->head );} - -    private: -    void* head; -    }; -}; - -/********************************************************************** - -Reachability and Clean-up - -An object O is reachable if it can be reached via a non-empty path of -normal pointers from the registers, stacks, global variables, or an -object with a non-null clean-up function (including O itself), -ignoring pointers from an object to itself. - -This definition of reachability ensures that if object B is accessible -from object A (and not vice versa) and if both A and B have clean-up -functions, then A will always be cleaned up before B. Note that as -long as an object with a clean-up function is contained in a cycle of -pointers, it will always be reachable and will never be cleaned up or -collected. - -When the collector finds an unreachable object with a null clean-up -function, it atomically deactivates all weak pointers referencing the -object and recycles its storage. If object B is accessible from object -A via a path of normal pointers, A will be discovered unreachable no -later than B, and a weak pointer to A will be deactivated no later -than a weak pointer to B. - -When the collector finds an unreachable object with a non-null -clean-up function, the collector atomically deactivates all weak -pointers referencing the object, redefines its clean-up function to be -null, and enqueues it on its clean-up queue. The object then becomes -reachable again and remains reachable at least until its clean-up -function executes. - -The clean-up function is assured that its argument is the only -accessible pointer to the object. Nothing prevents the function from -redefining the object's clean-up function or making the object -reachable again (for example, by storing the pointer in a global -variable). - -If the clean-up function does not make its object reachable again and -does not redefine its clean-up function, then the object will be -collected by a subsequent collection (because the object remains -unreachable and now has a null clean-up function). If the clean-up -function does make its object reachable again and a clean-up function -is subsequently redefined for the object, then the new clean-up -function will be invoked the next time the collector finds the object -unreachable. - -Note that a destructor for a collected object cannot safely redefine a -clean-up function for its object, since after the destructor executes, -the object has been destroyed into "raw memory". (In most -implementations, destroying an object mutates its vtbl.) - -Finally, note that calling delete t on a collected object first -deactivates any weak pointers to t and then invokes its clean-up -function (destructor). - -**********************************************************************/ - -extern "C" { -    void* _WeakPointer_New( void* t ); -    void* _WeakPointer_Pointer( void* wp ); -    int _WeakPointer_Equal( void* wp1, void* wp2 ); -    int _WeakPointer_Hash( void* wp ); -    void _CleanUp_Set( void* t, void (*c)( void* d, void* t ), void* d ); -    void _CleanUp_Call( void* t ); -    void* _CleanUp_Queue_NewHead (); -    void _CleanUp_Queue_Set( void* h, void* t ); -    int _CleanUp_Queue_Call( void* h ); -} - -#endif /* _weakpointer_h_ */ - - | 
