diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2015-08-28 01:37:33 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2015-08-28 11:20:47 +0300 |
commit | 86991cba3cbce83bfd3a0619f11f86cc1ee56917 (patch) | |
tree | 5523311ce472f5d7141b769876c3ea9c402e09e6 /include | |
parent | 467b279de834a48f9d5ba731727f75949afa4000 (diff) | |
download | bdwgc-86991cba3cbce83bfd3a0619f11f86cc1ee56917.tar.gz |
Code refactoring of toggle-ref support
* alloc.c (GC_stopped_mark): Move GC_process_togglerefs() call from
GC_stop_world; do not call it if GC_NO_FINALIZATION or
GC_TOGGLE_REFS_NOT_NEEDED.
* darwin_stop_world.c (GC_stop_world): Remove GC_process_togglerefs()
call.
* pthread_stop_world.c (GC_stop_world): Likewise.
* doc/README.macros (GC_TOGGLE_REFS_NOT_NEEDED): Document.
* finalize.c (GCToggleRef, GC_process_togglerefs, push_and_mark_object,
GC_clear_togglerefs, GC_toggleref_add): Replace GC_PTR with void*.
* include/gc.h (GC_toggleref_add): Likewise.
* finalize.c (GCToggleRef, GC_toggleref_callback, GC_toggleref_arr,
GC_toggleref_array_size, GC_toggleref_array_capacity,
GC_process_togglerefs, push_and_mark_object, GC_mark_togglerefs,
GC_clear_togglerefs, GC_set_toggleref_func, ensure_toggleref_capacity,
GC_toggleref_add): Do not defined if GC_TOGGLE_REFS_NOT_NEEDED.
* finalize.c (GCToggleRef): Add comment.
* finalize.c (GC_toggleref_array): Rename to GC_toggleref_arr.
* finalize.c (GC_toggleref_callback, GC_toggleref_array,
GC_toggleref_array_size, GC_toggleref_array_capacity): Make it STATIC
(instead "static").
* finalize.c (GC_process_togglerefs): Decorate with GC_INNER; remove
"toggle_ref_counts", "res" local variables; rename "w" local variable
to "new_size"; add assertion on lock state; use GC_TOGGLE_REF_* enum
element in switch statement; use BZERO to clear moved elements of
GC_toggleref_arr.
* finalize.c (GC_normal_finalize_mark_proc): Declare (before use).
* finalize.c (push_and_mark_object): Replace PUSH_OBJ with
GC_normal_finalize_mark_proc call.
* finalize.c (GC_mark_togglerefs, GC_clear_togglerefs): Remove
"object" local variable.
* finalize.c (GC_toggleref_register_callback): Rename to
GC_set_toggleref_func; change argument to GC_toggleref_func (which
returns GC_ToggleRefStatus instead of int).
* finalize.c (GC_toggleref_register_callback, GC_toggleref_add):
Decorate with GC_API and GC_CALL.
* include/gc.h (GC_toggleref_register_callback): Likewise.
* finalize.c (GC_set_toggleref_func): Acquire allocation lock.
* finalize.c (GC_get_toggleref_func): New API function.
* finalize.c (ensure_toggleref_capacity): Rename "capacity" argument
to "capacity_inc"; add assertion on argument value; rename "tmp" local
variable to "new_array"; remove unused "old_capacity" variable; replace
memcpy() with BCOPY() call.
* finalize.c (GC_toggleref_add): Rename "strong_ref" argument to
"is_strong_ref".
* finalize.c (GC_finalize): Do not call GC_clear_togglerefs and
GC_mark_togglerefs if GC_TOGGLE_REFS_NOT_NEEDED.
* include/gc.h (GC_ToggleRefStatus, GC_toggleref_func): New type.
* include/gc.h (GC_toggleref_register_callback): Add comment
(including about locking).
* include/gc.h (GC_get_toggleref_func): New API function declaration.
* include/gc.h (GC_toggleref_add): Decorate with GC_CALL; add comment;
add GC_ATTR_NONNULL attribute.
* include/private/gc_priv.h (GC_process_togglerefs): Do not declare if
GC_TOGGLE_REFS_NOT_NEEDED; decorate with GC_INNER.
Diffstat (limited to 'include')
-rw-r--r-- | include/gc.h | 40 | ||||
-rw-r--r-- | include/private/gc_priv.h | 21 |
2 files changed, 47 insertions, 14 deletions
diff --git a/include/gc.h b/include/gc.h index 5a407cba..83f724c8 100644 --- a/include/gc.h +++ b/include/gc.h @@ -1172,10 +1172,42 @@ GC_API int GC_CALL GC_unregister_long_link(void ** /* link */); /* Similar to GC_unregister_disappearing_link but for a */ /* registration by either of the above two routines. */ - -/* toggleref support */ -GC_API void GC_toggleref_register_callback (int (*proccess_toggleref) (GC_PTR obj)); -GC_API int GC_toggleref_add (GC_PTR object, int strong_ref); +/* Support of toggle-ref style of external memory management */ +/* without hooking up to the host retain/release machinery. */ +/* The idea of toggle-ref is that an external reference to */ +/* an object is kept and it can be either a strong or weak */ +/* reference; a weak reference is used when the external peer */ +/* has no interest in the object, and a strong otherwise. */ +typedef enum { + GC_TOGGLE_REF_DROP, + GC_TOGGLE_REF_STRONG, + GC_TOGGLE_REF_WEAK +} GC_ToggleRefStatus; + +/* The callback is to decide (return) the new state of a given */ +/* object. Invoked by the collector for all objects registered */ +/* for toggle-ref processing. Invoked with the allocation lock */ +/* held (but the "world" is running). */ +typedef GC_ToggleRefStatus (GC_CALLBACK *GC_toggleref_func)(void * /* obj */); + +/* Set (register) a callback that decides the state of a given */ +/* object (by, probably, inspecting its native state). */ +/* The argument may be 0 (means no callback). Both the setter */ +/* and the getter acquire the allocation lock (to avoid data */ +/* races). */ +GC_API void GC_CALL GC_set_toggleref_func(GC_toggleref_func); +GC_API GC_toggleref_func GC_CALL GC_get_toggleref_func(void); + +/* Register a given object for toggle-ref processing. It will */ +/* be stored internally and the toggle-ref callback will be */ +/* invoked on the object until the callback returns */ +/* GC_TOGGLE_REF_DROP or the object is collected. If is_strong */ +/* is true then the object is registered with a strong ref, */ +/* a weak one otherwise. Returns GC_SUCCESS if registration */ +/* succeeded (or no callback registered yet), GC_NO_MEMORY if */ +/* it failed for lack of memory. */ +GC_API int GC_CALL GC_toggleref_add(void * /* obj */, int /* is_strong */) + GC_ATTR_NONNULL(1); /* Finalizer callback support. Invoked by the collector (with */ /* the allocation lock held) for each unreachable object */ diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 14b02ad7..ed9fc566 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -255,29 +255,30 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ #ifndef GC_NO_FINALIZATION -# define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers() - GC_INNER void GC_notify_or_invoke_finalizers(void); +# define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers() + GC_INNER void GC_notify_or_invoke_finalizers(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. */ - GC_INNER void GC_finalize(void); + GC_INNER void GC_finalize(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_process_togglerefs (void); - /*Process the togglerefs before GC starts */ - -# ifndef SMALL_CONFIG - GC_INNER void GC_print_finalization_stats(void); -# endif +# ifndef GC_TOGGLE_REFS_NOT_NEEDED + GC_INNER void GC_process_togglerefs(void); + /* Process the toggle-refs before GC starts. */ +# endif +# ifndef SMALL_CONFIG + GC_INNER void GC_print_finalization_stats(void); +# endif #else -# define GC_INVOKE_FINALIZERS() (void)0 +# define GC_INVOKE_FINALIZERS() (void)0 #endif /* GC_NO_FINALIZATION */ #if !defined(DONT_ADD_BYTE_AT_END) |