summaryrefslogtreecommitdiff
path: root/gi/pygi-invoke-state-struct.h
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2014-02-07 20:16:21 -0800
committerSimon Feltman <sfeltman@src.gnome.org>2014-03-03 05:28:27 -0800
commit5798f94b6a727b930b07fe840b0aef264f98a80e (patch)
treefa0b0636c6d1ac9b2992bb0e32bf93be4b9ade3e /gi/pygi-invoke-state-struct.h
parentad680ae9c37a0091628a7d66010fbf70aa1a2e43 (diff)
downloadpygobject-5798f94b6a727b930b07fe840b0aef264f98a80e.tar.gz
Use ffi_call directly instead of g_callable_info_invoke
Cleanup internal callable cache and state tracking by removing multiple counting schemes for differently sized "in" and "out" argument arrays. Use a single count based on the total number of arguments passed to C (inclusive of instance argument and GError exception where applicable). Size all state tracking arrays to the same size and ensure argument cache indices always line up with these arrays. This cleans up logic which was required by g_callable_info_invoke for splitting "in" and "out" arguments up. Cleanup array marshaling which can now rely on the new scheme which ensures the "arg_values" array always points to the correct location for length argument values. Cache the ffi_cif struct in PyGICallableCache via GIFunctionInvoker and related GI methods. Overall, these changes can give a performance boost of almost 2x for simple function calls (see ticket for micro benchmarks). https://bugzilla.gnome.org/show_bug.cgi?id=723642
Diffstat (limited to 'gi/pygi-invoke-state-struct.h')
-rw-r--r--gi/pygi-invoke-state-struct.h42
1 files changed, 26 insertions, 16 deletions
diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h
index 139b8786..174f473a 100644
--- a/gi/pygi-invoke-state-struct.h
+++ b/gi/pygi-invoke-state-struct.h
@@ -11,39 +11,49 @@ typedef struct _PyGIInvokeState
{
PyObject *py_in_args;
gssize n_py_in_args;
- gssize current_arg;
GType implementor_gtype;
+ /* Number of arguments the ffi wrapped C function takes. Used as the exact
+ * count for argument related arrays held in this struct.
+ */
+ gssize n_args;
+
+ /* List of arguments passed to ffi. Elements can point directly to values held in
+ * arg_values for "in/from Python" or indirectly via arg_pointers for
+ * "out/inout/to Python". In the latter case, the arg_pointers[x]->v_pointer
+ * member points to memory for the value storage.
+ */
GIArgument **args;
- GIArgument *in_args;
+
+ /* Holds memory for the C value of arguments marshaled "to" or "from" Python. */
+ GIArgument *arg_values;
+
+ /* Holds pointers to values in arg_values or a caller allocated chunk of
+ * memory via arg_pointers[x].v_pointer.
+ */
+ GIArgument *arg_pointers;
/* Array of pointers allocated to the same length as args which holds from_py
* marshaler cleanup data.
*/
gpointer *args_cleanup_data;
- /* Out args and out values
- * In order to pass a parameter and get something back out in C
- * we need to pass a pointer to the value, e.g.
- * int *out_integer;
- *
- * so while out_args == out_integer, out_value == *out_integer
- * or in other words out_args = &out_values
- *
- * We do all of our processing on out_values but we pass out_args to
- * the actual function.
- */
- GIArgument *out_args;
- GIArgument *out_values;
-
+ /* Memory to receive the result of the C ffi function call. */
GIArgument return_arg;
+ /* A GError exception which is indirectly bound into the last position of
+ * the "args" array if the callable caches "throws" member is set.
+ */
GError *error;
gboolean failed;
gpointer user_data;
+
+ /* Function pointer to call with ffi. */
+ gpointer function_ptr;
+
} PyGIInvokeState;
G_END_DECLS