📄 gc.h
字号:
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. *//* 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. */GC_API GC_word GC_set_free_space_divisor GC_PROTO((GC_word value)); /* Set free_space_divisor. See above for definition. */ /* Returns old value. */ /* 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. *//* They indicate failure by invoking the corresponding _print_proc. *//* 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# if defined(__STDC__) || defined(_AIX)# 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/* Functions 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) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)# include <windows.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. */ GC_API 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) && !cygwin */ /* * Fully portable code should call GC_INIT() from the main program * before making any other GC_ calls. On most platforms this is a * no-op and the collector self-initializes. But a number of platforms * make that too hard. */#if (defined(sparc) || defined(__sparc)) && defined(sun) /* * 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. */# define GC_INIT() { extern end, etext; \ GC_noop(&end, &etext); }#else# if defined(__CYGWIN32__) || defined (_AIX) /* * Similarly gnu-win32 DLLs need explicit initialization from * the main program, as does AIX. */# ifdef __CYGWIN32__ extern int _data_start__[]; extern int _data_end__[]; extern int _bss_start__[]; extern int _bss_end__[];# define GC_MAX(x,y) ((x) > (y) ? (x) : (y))# define GC_MIN(x,y) ((x) < (y) ? (x) : (y))# define GC_DATASTART ((GC_PTR) GC_MIN(_data_start__, _bss_start__))# define GC_DATAEND ((GC_PTR) GC_MAX(_data_end__, _bss_end__))# ifdef GC_DLL# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); }# else# define GC_INIT()# endif# endif# if defined(_AIX) extern int _data[], _end[];# define GC_DATASTART ((GC_PTR)((ulong)_data))# define GC_DATAEND ((GC_PTR)((ulong)_end))# define GC_INIT() { GC_add_roots(GC_DATASTART, GC_DATAEND); }# endif# else# if defined(__APPLE__) && defined(__MACH__) || defined(GC_WIN32_THREADS)# define GC_INIT() { GC_init(); }# else# define GC_INIT()# endif /* !__MACH && !GC_WIN32_THREADS */# endif /* !AIX && !cygwin */#endif /* !sparc */#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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -