📄 gc.h
字号:
# define GC_REGISTER_FINALIZER_UNREACHABLE(p, f, d, of, od) \ GC_debug_register_finalizer_unreachable(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_STRDUP(s) GC_strdup(s)# define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \ GC_malloc_ignore_off_page(sz)# define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \ GC_malloc_atomic_ignore_off_page(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_REGISTER_FINALIZER_UNREACHABLE(p, f, d, of, od) \ GC_register_finalizer_unreachable(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 Modula-3, Java, or 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) (void * obj, void * client_data);GC_API void GC_register_finalizer(void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *ocd);GC_API void GC_debug_register_finalizer (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *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. And it helps if finalizable objects are split to *//* avoid cycles. *//* 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 (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *ocd);GC_API void GC_debug_register_finalizer_ignore_self (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *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 (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *ocd);GC_API void GC_debug_register_finalizer_no_order (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *ocd);/* This is a special finalizer that is useful when an object's *//* finalizer must be run when the object is known to be no *//* longer reachable, not even from other finalizable objects. *//* It behaves like "normal" finalization, except that the *//* finalizer is not run while the object is reachable from *//* other objects specifying unordered finalization. *//* Effectively it allows an object referenced, possibly *//* indirectly, from an unordered finalizable object to override *//* the unordered finalization request. *//* This can be used in combination with finalizer_no_order so *//* as to release resources that must not be released while an *//* object can still be brought back to life by other *//* finalizers. *//* Only works if GC_java_finalization is set. Probably only *//* of interest when implementing a language that requires *//* unordered finalization (e.g. Java, C#). */GC_API void GC_register_finalizer_unreachable (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *ocd);GC_API void GC_debug_register_finalizer_unreachable (void * obj, GC_finalization_proc fn, void * cd, GC_finalization_proc *ofn, void * *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(void * * 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 (void * * link, void * 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. */ /* This can be used to implement certain types of */ /* weak pointers. Note however that this generally */ /* requires that thje allocation lock is held (see */ /* GC_call_with_allock_lock() below) when the disguised */ /* pointer is accessed. Otherwise a strong pointer */ /* could be recreated between the time the collector */ /* decides to reclaim the object and the link is */ /* cleared. */GC_API int GC_unregister_disappearing_link (void * * 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(void);GC_API int GC_invoke_finalizers(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. *//* Explicitly tell the collector that an object is reachable *//* at a particular program point. This prevents the argument *//* pointer from being optimized away, even it is otherwise no *//* longer needed. It should have no visible effect in the *//* absence of finalizers or disappearing links. But it may be *//* needed to prevent finalizers from running while the *//* associated external resource is still in use. *//* The function is sometimes called keep_alive in other *//* settings. */# if defined(__GNUC__) && !defined(__INTEL_COMPILER)# define GC_reachable_here(ptr) \ __asm__ volatile(" " : : "X"(ptr) : "memory");# else GC_API void GC_noop1(GC_word x);# define GC_reachable_here(ptr) GC_noop1((GC_word)(ptr));#endif/* 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) (char *msg, GC_word arg);GC_API GC_warn_proc GC_set_warn_proc(GC_warn_proc p); /* Returns old warning procedure. */GC_API GC_word GC_set_free_space_divisor(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) ((void *)(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 void * (*GC_fn_type) (void * client_data);GC_API void * GC_call_with_alloc_lock (GC_fn_type fn, void * client_data);/* These routines are intended to explicitly notify the collector *//* of new threads. Often this is unnecessary because thread creation *//* is implicitly intercepted by the collector, using header-file *//* defines, or linker-based interception. In the long run the intent *//* is to always make redundant registration safe. In the short run, *//* this is being implemented a platform at a time. *//* The interface is complicated by the fact that we probably will not *//* ever be able to automatically determine the stack base for thread *//* stacks on all platforms. *//* Structure representing the base of a thread stack. On most *//* platforms this contains just a single address. */struct GC_stack_base { void * mem_base; /* Base of memory stack. */# if defined(__ia64) || defined(__ia64__) void * reg_base; /* Base of separate register stack. */# endif};typedef void * (*GC_stack_base_func)(struct GC_stack_base *sb, void *arg);/* Call a function with a stack base structure corresponding to *//* somewhere in the GC_call_with_stack_base frame. This often can *//* be used to provide a sufficiently accurate stack base. And we *//* implement it everywhere. */void * GC_call_with_stack_base(GC_stack_base_func fn, void *arg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -