version 1.1, 1999/12/03 07:39:10 |
version 1.3, 2001/04/20 07:39:25 |
|
|
/* |
/* |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers |
* Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. |
* Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved. |
* Copyright 1996 by Silicon Graphics. 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 |
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
|
|
#ifndef _GC_H |
#ifndef _GC_H |
|
|
# define _GC_H |
# define _GC_H |
|
|
|
#if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
|
# define SOLARIS_THREADS |
|
#endif |
|
|
|
/* |
|
* Some tests for old macros. These violate our namespace rules and will |
|
* disappear shortly. |
|
*/ |
|
#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(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 |
|
|
# define __GC |
# define __GC |
# include <stddef.h> |
# 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(__CYGWIN32__) && defined(GC_USE_DLL) |
#if defined(__CYGWIN32__) && defined(GC_USE_DLL) |
#include "libgc_globals.h" |
#include "libgc_globals.h" |
#endif |
#endif |
|
|
#if defined(_MSC_VER) && defined(_DLL) |
#if defined(__MINGW32__) && defined(WIN32_THREADS) |
# ifdef GC_BUILD |
# ifdef GC_BUILD |
# define GC_API __declspec(dllexport) |
# define GC_API __declspec(dllexport) |
# else |
# else |
|
|
# endif |
# endif |
#endif |
#endif |
|
|
|
#if defined(_MSC_VER) && (defined(_DLL) && !defined(NOT_GC_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) |
#if defined(__WATCOMC__) && defined(GC_DLL) |
# ifdef GC_BUILD |
# ifdef GC_BUILD |
# define GC_API extern __declspec(dllexport) |
# define GC_API extern __declspec(dllexport) |
|
|
# if defined(__STDC__) || defined(__cplusplus) |
# if defined(__STDC__) || defined(__cplusplus) |
# define GC_PROTO(args) args |
# define GC_PROTO(args) args |
typedef void * GC_PTR; |
typedef void * GC_PTR; |
|
# define GC_CONST const |
# else |
# else |
# define GC_PROTO(args) () |
# define GC_PROTO(args) () |
typedef char * GC_PTR; |
typedef char * GC_PTR; |
|
# define GC_CONST |
# endif |
# endif |
|
|
# ifdef __cplusplus |
# ifdef __cplusplus |
Line 83 typedef long GC_signed_word; |
|
Line 143 typedef long GC_signed_word; |
|
|
|
GC_API GC_word GC_gc_no;/* Counter incremented per collection. */ |
GC_API GC_word GC_gc_no;/* Counter incremented per collection. */ |
/* Includes empty GCs at startup. */ |
/* 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 aonly partially functional, */ |
|
/* and may not be desirable. */ |
|
|
|
|
/* Public R/W variables */ |
/* Public R/W variables */ |
Line 96 GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requ |
|
Line 166 GC_API GC_PTR (*GC_oom_fn) GC_PROTO((size_t bytes_requ |
|
/* pointer to a previously allocated heap */ |
/* pointer to a previously allocated heap */ |
/* object. */ |
/* 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 */ |
GC_API int GC_quiet; /* Disable statistics output. Only matters if */ |
/* collector has been compiled with statistics */ |
/* collector has been compiled with statistics */ |
/* enabled. This involves a performance cost, */ |
/* enabled. This involves a performance cost, */ |
/* and is thus not the default. */ |
/* 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. */ |
GC_API int GC_dont_gc; /* Dont collect unless explicitly requested, e.g. */ |
/* because it's not safe. */ |
/* because it's not safe. */ |
|
|
Line 108 GC_API int GC_dont_expand; |
|
Line 219 GC_API int GC_dont_expand; |
|
/* Dont expand heap unless explicitly requested */ |
/* Dont expand heap unless explicitly requested */ |
/* or forced to. */ |
/* 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 */ |
GC_API int GC_full_freq; /* Number of partial collections between */ |
/* full collections. Matters only if */ |
/* full collections. Matters only if */ |
/* GC_incremental is set. */ |
/* 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; |
GC_API GC_word GC_non_gc_bytes; |
/* Bytes not considered candidates for collection. */ |
/* Bytes not considered candidates for collection. */ |
/* Used only to control scheduling of collections. */ |
/* 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; |
GC_API GC_word GC_free_space_divisor; |
/* We try to make sure that we allocate at */ |
/* We try to make sure that we allocate at */ |
/* least N/GC_free_space_divisor bytes between */ |
/* least N/GC_free_space_divisor bytes between */ |
Line 145 GC_API char *GC_stackbottom; /* Cool end of user stack |
|
Line 283 GC_API char *GC_stackbottom; /* Cool end of user stack |
|
/* automatically. */ |
/* automatically. */ |
/* For multithreaded code, this is the */ |
/* For multithreaded code, this is the */ |
/* cold end of the stack for the */ |
/* cold end of the stack for the */ |
/* primordial thread. */ |
/* 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. */ |
|
|
/* Public procedures */ |
/* Public procedures */ |
/* |
/* |
* general purpose allocation routines, with roughly malloc calling conv. |
* general purpose allocation routines, with roughly malloc calling conv. |
Line 156 GC_API char *GC_stackbottom; /* Cool end of user stack |
|
Line 302 GC_API char *GC_stackbottom; /* Cool end of user stack |
|
* will occur after GC_end_stubborn_change has been called on the |
* will occur after GC_end_stubborn_change has been called on the |
* result of GC_malloc_stubborn. GC_malloc_uncollectable allocates an object |
* result of GC_malloc_stubborn. GC_malloc_uncollectable allocates an object |
* that is scanned for pointers to collectable objects, but is not itself |
* that is scanned for pointers to collectable objects, but is not itself |
* collectable. GC_malloc_uncollectable and GC_free called on the resulting |
* 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. |
* 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 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_atomic GC_PROTO((size_t size_in_bytes)); |
Line 277 GC_API int GC_try_to_collect GC_PROTO((GC_stop_func st |
|
Line 428 GC_API int GC_try_to_collect GC_PROTO((GC_stop_func st |
|
/* Includes some pages that were allocated but never written. */ |
/* Includes some pages that were allocated but never written. */ |
GC_API size_t GC_get_heap_size GC_PROTO((void)); |
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. */ |
/* Return the number of bytes allocated since the last collection. */ |
GC_API size_t GC_get_bytes_since_gc GC_PROTO((void)); |
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. */ |
/* Enable incremental/generational collection. */ |
/* Not advisable unless dirty bits are */ |
/* Not advisable unless dirty bits are */ |
/* available or most heap objects are */ |
/* available or most heap objects are */ |
/* pointerfree(atomic) or immutable. */ |
/* pointerfree(atomic) or immutable. */ |
/* Don't use in leak finding mode. */ |
/* Don't use in leak finding mode. */ |
/* Ignored if GC_dont_gc is true. */ |
/* Ignored if GC_dont_gc is true. */ |
|
/* Only the generational piece of this is */ |
|
/* functional if GC_parallel is TRUE. */ |
GC_API void GC_enable_incremental GC_PROTO((void)); |
GC_API void GC_enable_incremental GC_PROTO((void)); |
|
|
/* Perform some garbage collection work, if appropriate. */ |
/* Perform some garbage collection work, if appropriate. */ |
Line 321 GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROT |
|
Line 481 GC_API GC_PTR GC_malloc_atomic_ignore_off_page GC_PROT |
|
|
|
#ifdef GC_ADD_CALLER |
#ifdef GC_ADD_CALLER |
# define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__ |
# define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__ |
# define GC_EXTRA_PARAMS GC_word ra, char * descr_string, int descr_int |
# define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * s, int i |
#else |
#else |
# define GC_EXTRAS __FILE__, __LINE__ |
# define GC_EXTRAS __FILE__, __LINE__ |
# define GC_EXTRA_PARAMS char * descr_string, int descr_int |
# define GC_EXTRA_PARAMS GC_CONST char * s, int i |
#endif |
#endif |
|
|
/* Debugging (annotated) allocation. GC_gcollect will check */ |
/* Debugging (annotated) allocation. GC_gcollect will check */ |
Line 355 GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_ |
|
Line 515 GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_ |
|
GC_debug_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) \ |
# define GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) \ |
GC_debug_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_MALLOC_STUBBORN(sz) GC_debug_malloc_stubborn(sz, GC_EXTRAS); |
# define GC_CHANGE_STUBBORN(p) GC_debug_change_stubborn(p) |
# define GC_CHANGE_STUBBORN(p) GC_debug_change_stubborn(p) |
# define GC_END_STUBBORN_CHANGE(p) GC_debug_end_stubborn_change(p) |
# define GC_END_STUBBORN_CHANGE(p) GC_debug_end_stubborn_change(p) |
Line 371 GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_ |
|
Line 533 GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_ |
|
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) \ |
# define GC_REGISTER_FINALIZER_IGNORE_SELF(p, f, d, of, od) \ |
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_MALLOC_STUBBORN(sz) GC_malloc_stubborn(sz) |
# define GC_CHANGE_STUBBORN(p) GC_change_stubborn(p) |
# define GC_CHANGE_STUBBORN(p) GC_change_stubborn(p) |
# define GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p) |
# define GC_END_STUBBORN_CHANGE(p) GC_end_stubborn_change(p) |
Line 442 GC_API void GC_debug_register_finalizer |
|
Line 606 GC_API void GC_debug_register_finalizer |
|
/* but it's unavoidable for C++, since the compiler may */ |
/* but it's unavoidable for C++, since the compiler may */ |
/* silently introduce these. It's also benign in that specific */ |
/* silently introduce these. It's also benign in that specific */ |
/* case. */ |
/* 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_API void GC_register_finalizer_ignore_self |
GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, |
GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, |
GC_finalization_proc *ofn, GC_PTR *ocd)); |
GC_finalization_proc *ofn, GC_PTR *ocd)); |
Line 449 GC_API void GC_debug_register_finalizer_ignore_self |
|
Line 615 GC_API void GC_debug_register_finalizer_ignore_self |
|
GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, |
GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd, |
GC_finalization_proc *ofn, GC_PTR *ocd)); |
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 */ |
/* The following routine may be used to break cycles between */ |
/* finalizable objects, thus causing cyclic finalizable */ |
/* finalizable objects, thus causing cyclic finalizable */ |
/* objects to be finalized in the correct order. Standard */ |
/* objects to be finalized in the correct order. Standard */ |
Line 505 GC_API int GC_unregister_disappearing_link GC_PROTO((G |
|
Line 683 GC_API int GC_unregister_disappearing_link GC_PROTO((G |
|
GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data)); |
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)); |
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)); |
GC_API int GC_invoke_finalizers GC_PROTO((void)); |
/* Run finalizers for all objects that are ready to */ |
/* Run finalizers for all objects that are ready to */ |
/* be finalized. Return the number of finalizers */ |
/* be finalized. Return the number of finalizers */ |
/* that were run. Normally this is also called */ |
/* that were run. Normally this is also called */ |
/* implicitly during some allocations. If */ |
/* implicitly during some allocations. If */ |
/* FINALIZE_ON_DEMAND is defined, it must be called */ |
/* GC-finalize_on_demand is nonzero, it must be called */ |
/* explicitly. */ |
/* explicitly. */ |
|
|
/* GC_set_warn_proc can be used to redirect or filter warning messages. */ |
/* GC_set_warn_proc can be used to redirect or filter warning messages. */ |
Line 540 typedef GC_PTR (*GC_fn_type) GC_PROTO((GC_PTR client_d |
|
Line 721 typedef GC_PTR (*GC_fn_type) GC_PROTO((GC_PTR client_d |
|
GC_API GC_PTR GC_call_with_alloc_lock |
GC_API GC_PTR GC_call_with_alloc_lock |
GC_PROTO((GC_fn_type fn, GC_PTR client_data)); |
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. */ |
/* Check that p and q point to the same object. */ |
/* Fail conspicuously if they don't. */ |
/* Fail conspicuously if they don't. */ |
/* Returns the first argument. */ |
/* Returns the first argument. */ |
Line 567 GC_API GC_PTR GC_is_visible GC_PROTO((GC_PTR p)); |
|
Line 751 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 */ |
/* Check that if p is a pointer to a heap page, then it points to */ |
/* a valid displacement within a heap object. */ |
/* a valid displacement within a heap object. */ |
/* Fail conspicuously if this property does not hold. */ |
/* Fail conspicuously if this property does not hold. */ |
/* Uninteresting with ALL_INTERIOR_POINTERS. */ |
/* Uninteresting with GC_all_interior_pointers. */ |
/* Always returns its argument. */ |
/* Always returns its argument. */ |
GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR p)); |
GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PTR p)); |
|
|
Line 583 GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PT |
|
Line 767 GC_API GC_PTR GC_is_valid_displacement GC_PROTO((GC_PT |
|
# ifdef __GNUC__ |
# ifdef __GNUC__ |
# define GC_PTR_ADD(x, n) \ |
# define GC_PTR_ADD(x, n) \ |
GC_PTR_ADD3(x, n, typeof(x)) |
GC_PTR_ADD3(x, n, typeof(x)) |
# define GC_PRE_INCR(x, n) \ |
# define GC_PRE_INCR(x, n) \ |
GC_PRE_INCR3(x, n, typeof(x)) |
GC_PRE_INCR3(x, n, typeof(x)) |
# define GC_POST_INCR(x, n) \ |
# define GC_POST_INCR(x, n) \ |
GC_POST_INCR3(x, typeof(x)) |
GC_POST_INCR3(x, typeof(x)) |
# else |
# else |
/* We can't do this right without typeof, which ANSI */ |
/* We can't do this right without typeof, which ANSI */ |
Line 625 GC_API void (*GC_is_valid_displacement_print_proc) |
|
Line 809 GC_API void (*GC_is_valid_displacement_print_proc) |
|
GC_API void (*GC_is_visible_print_proc) |
GC_API void (*GC_is_visible_print_proc) |
GC_PROTO((GC_PTR p)); |
GC_PROTO((GC_PTR p)); |
|
|
#if defined(_SOLARIS_PTHREADS) && !defined(SOLARIS_THREADS) |
|
# define SOLARIS_THREADS |
|
#endif |
|
|
|
#ifdef SOLARIS_THREADS |
/* For pthread support, we generally need to intercept a number of */ |
/* We need to intercept calls to many of the threads primitives, so */ |
/* thread library calls. We do that here by macro defining them. */ |
/* 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, which are deallocated using the destructor */ |
|
/* facility in thr_keycreate. */ |
|
# include <thread.h> |
|
# include <signal.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); |
|
|
|
# ifdef _SOLARIS_PTHREADS |
#if !defined(GC_USE_LD_WRAP) && \ |
# include <pthread.h> |
(defined(GC_LINUX_THREADS) || defined(GC_HPUX_THREADS) || \ |
extern int GC_pthread_create(pthread_t *new_thread, |
defined(GC_IRIX_THREADS) || defined(GC_SOLARIS_PTHREADS) || \ |
const pthread_attr_t *attr, |
defined(GC_SOLARIS_THREADS) || defined(GC_OSF1_THREADS)) |
void * (*thread_execp)(void *), void *arg); |
# include "gc_pthread_redirects.h" |
extern int GC_pthread_join(pthread_t wait_for, void **status); |
|
|
|
# undef thread_t |
|
|
|
# define pthread_join GC_pthread_join |
|
# define pthread_create GC_pthread_create |
|
#endif |
#endif |
|
|
# define thr_create GC_thr_create |
# if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ |
# define thr_join GC_thr_join |
defined(GC_SOLARIS_PTHREADS) || defined(GC_WIN32_THREADS) || \ |
# define thr_suspend GC_thr_suspend |
defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \ |
# define thr_continue GC_thr_continue |
defined(GC_HPUX_THREADS) |
# define dlopen GC_dlopen |
|
|
|
# endif /* SOLARIS_THREADS */ |
|
|
|
|
|
#if defined(IRIX_THREADS) || defined(LINUX_THREADS) |
|
/* 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); |
|
|
|
# define pthread_create GC_pthread_create |
|
# define pthread_sigmask GC_pthread_sigmask |
|
# define pthread_join GC_pthread_join |
|
|
|
#endif /* IRIX_THREADS || LINUX_THREADS */ |
|
|
|
# if defined(PCR) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || \ |
|
defined(IRIX_THREADS) || defined(LINUX_THREADS) || \ |
|
defined(IRIX_JDK_THREADS) |
|
/* Any flavor of threads except SRC_M3. */ |
/* Any flavor of threads except SRC_M3. */ |
/* This returns a list of objects, linked through their first */ |
/* This returns a list of objects, linked through their first */ |
/* word. Its use can greatly reduce lock contention problems, since */ |
/* word. Its use can greatly reduce lock contention problems, since */ |
/* the allocation lock can be acquired and released many fewer times. */ |
/* the allocation lock can be acquired and released many fewer times. */ |
/* lb must be large enough to hold the pointer field. */ |
/* 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); |
GC_PTR GC_malloc_many(size_t lb); |
#define GC_NEXT(p) (*(GC_PTR *)(p)) /* Retrieve the next element */ |
#define GC_NEXT(p) (*(GC_PTR *)(p)) /* Retrieve the next element */ |
/* in returned list. */ |
/* in returned list. */ |
Line 700 extern void GC_thr_init(); /* Needed for Solaris/X86 * |
|
Line 838 extern void GC_thr_init(); /* Needed for Solaris/X86 * |
|
|
|
#endif /* THREADS && !SRC_M3 */ |
#endif /* THREADS && !SRC_M3 */ |
|
|
|
#if defined(WIN32_THREADS) && defined(_WIN32_WCE) |
|
# include <windows.h> |
|
|
|
/* |
|
* 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 ); |
|
|
|
/* |
|
* All threads must be created using GC_CreateThread, so that they will be |
|
* recorded in the thread table. |
|
*/ |
|
HANDLE WINAPI GC_CreateThread( |
|
LPSECURITY_ATTRIBUTES lpThreadAttributes, |
|
DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, |
|
LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); |
|
|
|
# ifndef GC_BUILD |
|
# define WinMain GC_WinMain |
|
# define CreateThread GC_CreateThread |
|
# endif |
|
|
|
#endif |
|
|
/* |
/* |
* If you are planning on putting |
* If you are planning on putting |
* the collector in a SunOS 5 dynamic library, you need to call GC_INIT() |
* the collector in a SunOS 5 dynamic library, you need to call GC_INIT() |
Line 720 extern void GC_thr_init(); /* Needed for Solaris/X86 * |
|
Line 887 extern void GC_thr_init(); /* Needed for Solaris/X86 * |
|
# endif |
# endif |
#endif |
#endif |
|
|
#if (defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ |
#if !defined(_WIN32_WCE) \ |
|| defined(_WIN32) |
&& ((defined(_MSDOS) || defined(_MSC_VER)) && (_M_IX86 >= 300) \ |
|
|| defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)) |
/* win32S may not free all resources on process exit. */ |
/* win32S may not free all resources on process exit. */ |
/* This explicitly deallocates the heap. */ |
/* This explicitly deallocates the heap. */ |
GC_API void GC_win32_free_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 |
#endif |
|
|
#ifdef __cplusplus |
#ifdef __cplusplus |