summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2013-07-28 16:44:01 -0700
committerSimon Feltman <sfeltman@src.gnome.org>2013-09-25 23:50:29 -0700
commitc19bed69c669160737e12d92cc29f3e6d1b008cc (patch)
treecd3f45dae65ff254064a5044b72551f61315126d
parent52ea3afb0a6494423eca36a54af928d4ae5d9954 (diff)
downloadpygobject-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.c62
-rw-r--r--gi/pygi-cache.h16
-rw-r--r--gi/pygi-invoke.c16
-rw-r--r--gi/pygi-marshal-cleanup.c8
-rw-r--r--gi/pygi-marshal-from-py.c6
-rw-r--r--gi/pygi-marshal-to-py.c6
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;
}
}