diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2013-07-28 16:44:01 -0700 |
---|---|---|
committer | Simon Feltman <sfeltman@src.gnome.org> | 2013-09-25 23:50:29 -0700 |
commit | c19bed69c669160737e12d92cc29f3e6d1b008cc (patch) | |
tree | cd3f45dae65ff254064a5044b72551f61315126d | |
parent | 52ea3afb0a6494423eca36a54af928d4ae5d9954 (diff) | |
download | pygobject-c19bed69c669160737e12d92cc29f3e6d1b008cc.tar.gz |
cache refactoring: Use GPtrArray for callable arg cache
Replace manual management of the C array holding individual
argument caches with usage of GPtrArray. This provides storage
of the array length along with item memory management.
https://bugzilla.gnome.org/show_bug.cgi?id=640812
-rw-r--r-- | gi/pygi-cache.c | 62 | ||||
-rw-r--r-- | gi/pygi-cache.h | 16 | ||||
-rw-r--r-- | gi/pygi-invoke.c | 16 | ||||
-rw-r--r-- | gi/pygi-marshal-cleanup.c | 8 | ||||
-rw-r--r-- | gi/pygi-marshal-from-py.c | 6 | ||||
-rw-r--r-- | gi/pygi-marshal-to-py.c | 6 |
6 files changed, 62 insertions, 52 deletions
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c index b3acd61f..179dbe7b 100644 --- a/gi/pygi-cache.c +++ b/gi/pygi-cache.c @@ -103,23 +103,17 @@ _callback_cache_free_func (PyGICallbackCache *cache) void _pygi_callable_cache_free (PyGICallableCache *cache) { - gssize i; - if (cache == NULL) return; g_slist_free (cache->to_py_args); g_slist_free (cache->arg_name_list); g_hash_table_destroy (cache->arg_name_hash); + g_ptr_array_unref (cache->args_cache); - for (i = 0; i < cache->n_args; i++) { - PyGIArgCache *tmp = cache->args_cache[i]; - _pygi_arg_cache_free (tmp); - } if (cache->return_cache != NULL) _pygi_arg_cache_free (cache->return_cache); - g_slice_free1 (cache->n_args * sizeof (PyGIArgCache *), cache->args_cache); g_slice_free (PyGICallableCache, cache); } @@ -314,7 +308,7 @@ _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache, if (seq_cache->len_arg_index >= 0) { PyGIArgCache *child_cache = - callable_cache->args_cache[seq_cache->len_arg_index]; + _pygi_callable_cache_get_arg (callable_cache, seq_cache->len_arg_index); if (child_cache == NULL) { child_cache = _arg_cache_alloc (); @@ -333,7 +327,7 @@ _arg_cache_from_py_array_setup (PyGIArgCache *arg_cache, child_cache->to_py_marshaller = NULL; child_cache->from_py_marshaller = NULL; - callable_cache->args_cache[seq_cache->len_arg_index] = child_cache; + _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache); } arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_array; @@ -356,7 +350,8 @@ _arg_cache_to_py_array_setup (PyGIArgCache *arg_cache, seq_cache->array_type = g_type_info_get_array_type (type_info); if (seq_cache->len_arg_index >= 0) { - PyGIArgCache *child_cache = callable_cache->args_cache[seq_cache->len_arg_index]; + PyGIArgCache *child_cache = _pygi_callable_cache_get_arg (callable_cache, + seq_cache->len_arg_index); if (seq_cache->len_arg_index < arg_index) callable_cache->n_to_py_child_args++; @@ -376,7 +371,7 @@ _arg_cache_to_py_array_setup (PyGIArgCache *arg_cache, child_cache->to_py_marshaller = NULL; child_cache->from_py_marshaller = NULL; - callable_cache->args_cache[seq_cache->len_arg_index] = child_cache; + _pygi_callable_cache_set_arg (callable_cache, seq_cache->len_arg_index, child_cache); } return TRUE; @@ -509,14 +504,16 @@ _arg_cache_from_py_interface_callback_setup (PyGIArgCache *arg_cache, PyGIArgCache *user_data_arg_cache = _arg_cache_alloc (); user_data_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD_WITH_PYARG; user_data_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; - callable_cache->args_cache[callback_cache->user_data_index] = user_data_arg_cache; + _pygi_callable_cache_set_arg (callable_cache, callback_cache->user_data_index, + user_data_arg_cache); } if (callback_cache->destroy_notify_index >= 0) { PyGIArgCache *destroy_arg_cache = _arg_cache_alloc (); destroy_arg_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; destroy_arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; - callable_cache->args_cache[callback_cache->destroy_notify_index] = destroy_arg_cache; + _pygi_callable_cache_set_arg (callable_cache, callback_cache->destroy_notify_index, + destroy_arg_cache); } arg_cache->from_py_marshaller = _pygi_marshal_from_py_interface_callback; arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_callback; @@ -780,19 +777,19 @@ _arg_cache_new (GITypeInfo *type_info, * need to update indexes if this happens */ if (seq_cache->len_arg_index > -1 && - callable_cache->args_cache[seq_cache->len_arg_index]->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) { + _pygi_callable_cache_get_arg (callable_cache, + seq_cache->len_arg_index)->meta_type == PYGI_META_ARG_TYPE_CHILD_NEEDS_UPDATE) { gssize i; - PyGIArgCache *child_cache = - callable_cache->args_cache[seq_cache->len_arg_index]; - + PyGIArgCache *child_cache = _pygi_callable_cache_get_arg (callable_cache, + seq_cache->len_arg_index); child_cache->meta_type = PYGI_META_ARG_TYPE_CHILD; py_arg_index -= 1; callable_cache->n_py_args -= 1; for (i = seq_cache->len_arg_index + 1; - i < callable_cache->n_args; + i < _pygi_callable_cache_args_len (callable_cache); i++) { - PyGIArgCache *update_cache = callable_cache->args_cache[i]; + PyGIArgCache *update_cache = _pygi_callable_cache_get_arg (callable_cache, i); if (update_cache == NULL) break; @@ -914,10 +911,10 @@ _arg_name_list_generate (PyGICallableCache *callable_cache) g_hash_table_remove_all (callable_cache->arg_name_hash); } - for (i=0; i < callable_cache->n_args; i++) { + for (i=0; i < _pygi_callable_cache_args_len (callable_cache); i++) { PyGIArgCache *arg_cache = NULL; - arg_cache = callable_cache->args_cache[i]; + arg_cache = _pygi_callable_cache_get_arg (callable_cache, i); if (arg_cache->meta_type != PYGI_META_ARG_TYPE_CHILD && arg_cache->meta_type != PYGI_META_ARG_TYPE_CLOSURE && @@ -1016,7 +1013,7 @@ _args_cache_generate (GICallableInfo *callable_info, if (instance_cache == NULL) return FALSE; - callable_cache->args_cache[arg_index] = instance_cache; + _pygi_callable_cache_set_arg (callable_cache, arg_index, instance_cache); arg_index++; callable_cache->n_from_py_args++; @@ -1024,7 +1021,7 @@ _args_cache_generate (GICallableInfo *callable_info, } - for (i=0; arg_index < callable_cache->n_args; arg_index++, i++) { + for (i=0; arg_index < _pygi_callable_cache_args_len (callable_cache); arg_index++, i++) { PyGIArgCache *arg_cache = NULL; GIArgInfo *arg_info; GITypeInfo *type_info; @@ -1039,7 +1036,7 @@ _args_cache_generate (GICallableInfo *callable_info, if (g_arg_info_get_closure (arg_info) == i) { arg_cache = _arg_cache_alloc (); - callable_cache->args_cache[arg_index] = arg_cache; + _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache); arg_cache->arg_name = g_base_info_get_name ((GIBaseInfo *) arg_info); arg_cache->direction = PYGI_DIRECTION_FROM_PYTHON; @@ -1066,8 +1063,8 @@ _args_cache_generate (GICallableInfo *callable_info, * and continue * fill in it's c_arg_index, add to the in count */ - if (callable_cache->args_cache[arg_index] != NULL) { - arg_cache = callable_cache->args_cache[arg_index]; + arg_cache = _pygi_callable_cache_get_arg (callable_cache, arg_index); + if (arg_cache != NULL) { if (arg_cache->meta_type == PYGI_META_ARG_TYPE_CHILD_WITH_PYARG) { arg_cache->py_arg_index = callable_cache->n_py_args; callable_cache->n_py_args++; @@ -1122,7 +1119,7 @@ _args_cache_generate (GICallableInfo *callable_info, g_slist_append (callable_cache->to_py_args, arg_cache); } - callable_cache->args_cache[arg_index] = arg_cache; + _pygi_callable_cache_set_arg (callable_cache, arg_index, arg_cache); g_base_info_unref( (GIBaseInfo *)type_info); g_base_info_unref( (GIBaseInfo *)arg_info); @@ -1141,6 +1138,7 @@ arg_err: PyGICallableCache * _pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback) { + gint n_args; PyGICallableCache *cache; GIInfoType type = g_base_info_get_type ( (GIBaseInfo *)callable_info); @@ -1185,15 +1183,17 @@ _pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback) cache->function_type = PYGI_FUNCTION_TYPE_METHOD; } - cache->n_args = g_callable_info_get_n_args (callable_info); + n_args = g_callable_info_get_n_args (callable_info); /* if we are a method or vfunc make sure the instance parameter is counted */ if (cache->function_type == PYGI_FUNCTION_TYPE_METHOD || cache->function_type == PYGI_FUNCTION_TYPE_VFUNC) - cache->n_args++; + n_args++; - if (cache->n_args > 0) - cache->args_cache = g_slice_alloc0 (cache->n_args * sizeof (PyGIArgCache *)); + if (n_args >= 0) { + cache->args_cache = g_ptr_array_new_full (n_args, (GDestroyNotify) _pygi_arg_cache_free); + g_ptr_array_set_size (cache->args_cache, n_args); + } if (!_args_cache_generate (callable_info, cache)) goto err; diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h index 25c6db6f..94c8fdf4 100644 --- a/gi/pygi-cache.h +++ b/gi/pygi-cache.h @@ -172,7 +172,7 @@ struct _PyGICallableCache PyGIFunctionType function_type; PyGIArgCache *return_cache; - PyGIArgCache **args_cache; + GPtrArray *args_cache; GSList *to_py_args; GSList *arg_name_list; /* for keyword arg matching */ GHashTable *arg_name_hash; @@ -191,8 +191,6 @@ struct _PyGICallableCache */ gssize n_to_py_child_args; - gssize n_args; - /* Number of Python arguments expected for invoking the gi function. */ gssize n_py_args; }; @@ -203,6 +201,18 @@ void _pygi_callable_cache_free (PyGICallableCache *cache); PyGICallableCache *_pygi_callable_cache_new (GICallableInfo *callable_info, gboolean is_ccallback); +#define _pygi_callable_cache_args_len(cache) ((cache)->args_cache)->len + +inline static PyGIArgCache * +_pygi_callable_cache_get_arg (PyGICallableCache *cache, guint index) { + return (PyGIArgCache *) g_ptr_array_index (cache->args_cache, index); +} + +inline static void +_pygi_callable_cache_set_arg (PyGICallableCache *cache, guint index, PyGIArgCache *arg_cache) { + cache->args_cache->pdata[index] = arg_cache; +} + G_END_DECLS #endif /* __PYGI_CACHE_H__ */ diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c index 17cd278e..7abd9e61 100644 --- a/gi/pygi-invoke.c +++ b/gi/pygi-invoke.c @@ -299,14 +299,14 @@ _invoke_state_init_from_callable_cache (PyGIInvokeState *state, } state->n_py_in_args = PyTuple_Size (state->py_in_args); - state->args = g_slice_alloc0 (cache->n_args * sizeof (GIArgument *)); - if (state->args == NULL && cache->n_args != 0) { + state->args = g_slice_alloc0 (_pygi_callable_cache_args_len (cache) * sizeof (GIArgument *)); + if (state->args == NULL && _pygi_callable_cache_args_len (cache) != 0) { PyErr_NoMemory(); return FALSE; } - state->args_data = g_slice_alloc0 (cache->n_args * sizeof (gpointer)); - if (state->args_data == NULL && cache->n_args != 0) { + state->args_data = g_slice_alloc0 (_pygi_callable_cache_args_len (cache) * sizeof (gpointer)); + if (state->args_data == NULL && _pygi_callable_cache_args_len (cache) != 0) { PyErr_NoMemory(); return FALSE; } @@ -337,8 +337,8 @@ _invoke_state_init_from_callable_cache (PyGIInvokeState *state, static inline void _invoke_state_clear (PyGIInvokeState *state, PyGICallableCache *cache) { - g_slice_free1 (cache->n_args * sizeof(GIArgument *), state->args); - g_slice_free1 (cache->n_args * sizeof(gpointer), state->args_data); + g_slice_free1 (_pygi_callable_cache_args_len (cache) * sizeof(GIArgument *), state->args); + g_slice_free1 (_pygi_callable_cache_args_len (cache) * sizeof(gpointer), state->args_data); g_slice_free1 (cache->n_from_py_args * sizeof(GIArgument), state->in_args); g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_args); g_slice_free1 (cache->n_to_py_args * sizeof(GIArgument), state->out_values); @@ -408,9 +408,9 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache) return FALSE; } - for (i = 0; i < cache->n_args; i++) { + for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) { GIArgument *c_arg; - PyGIArgCache *arg_cache = cache->args_cache[i]; + PyGIArgCache *arg_cache = g_ptr_array_index (cache->args_cache, i); PyObject *py_arg = NULL; switch (arg_cache->direction) { diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c index d7d1b638..57ded65f 100644 --- a/gi/pygi-marshal-cleanup.c +++ b/gi/pygi-marshal-cleanup.c @@ -93,8 +93,8 @@ pygi_marshal_cleanup_args_from_py_marshal_success (PyGIInvokeState *state, gssize i; /* For in success, call cleanup for all GI_DIRECTION_IN values only. */ - for (i = 0; i < cache->n_args; i++) { - PyGIArgCache *arg_cache = cache->args_cache[i]; + for (i = 0; i < _pygi_callable_cache_args_len (cache); i++) { + PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (cache, i); PyGIMarshalCleanupFunc cleanup_func = arg_cache->from_py_cleanup; if (cleanup_func && @@ -157,8 +157,8 @@ pygi_marshal_cleanup_args_from_py_parameter_fail (PyGIInvokeState *state, state->failed = TRUE; - for (i = 0; i < cache->n_args && i <= failed_arg_index; i++) { - PyGIArgCache *arg_cache = cache->args_cache[i]; + for (i = 0; i < _pygi_callable_cache_args_len (cache) && i <= failed_arg_index; i++) { + PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (cache, i); PyGIMarshalCleanupFunc cleanup_func = arg_cache->from_py_cleanup; gpointer data = state->args[i]->v_pointer; diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c index 52c91d92..92f965ff 100644 --- a/gi/pygi-marshal-from-py.c +++ b/gi/pygi-marshal-from-py.c @@ -887,7 +887,7 @@ array_success: if (sequence_cache->len_arg_index >= 0) { /* we have an child arg to handle */ PyGIArgCache *child_cache = - callable_cache->args_cache[sequence_cache->len_arg_index]; + _pygi_callable_cache_get_arg (callable_cache, sequence_cache->len_arg_index); if (child_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL) { gint *len_arg = (gint *)state->in_args[child_cache->c_arg_index].v_pointer; @@ -1249,7 +1249,7 @@ _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, callback_cache = (PyGICallbackCache *)arg_cache; if (callback_cache->user_data_index > 0) { - user_data_cache = callable_cache->args_cache[callback_cache->user_data_index]; + user_data_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->user_data_index); if (user_data_cache->py_arg_index < state->n_py_in_args) { /* py_user_data is a borrowed reference. */ py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index); @@ -1297,7 +1297,7 @@ _pygi_marshal_from_py_interface_callback (PyGIInvokeState *state, * later on in _pygi_destroy_notify_callback_closure. */ if (callback_cache->destroy_notify_index > 0) { - destroy_cache = callable_cache->args_cache[callback_cache->destroy_notify_index]; + destroy_cache = _pygi_callable_cache_get_arg (callable_cache, callback_cache->destroy_notify_index); } if (destroy_cache) { diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c index d59e1e39..c9fbce92 100644 --- a/gi/pygi-marshal-to-py.c +++ b/gi/pygi-marshal-to-py.c @@ -296,10 +296,10 @@ _pygi_marshal_to_py_array (PyGIInvokeState *state, } } else { GIArgument *len_arg = state->args[seq_cache->len_arg_index]; + PyGIArgCache *arg_cache = _pygi_callable_cache_get_arg (callable_cache, + seq_cache->len_arg_index); - if (!gi_argument_to_gsize (len_arg, - &len, - callable_cache->args_cache[seq_cache->len_arg_index]->type_tag)) { + if (!gi_argument_to_gsize (len_arg, &len, arg_cache->type_tag)) { return NULL; } } |