[perl-Glib-Object-Introspection] Use the stack in favor of heap allocation during marshalling



commit a31d977f739dab871d6b95e36992b70e705d0216
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date:   Sun Oct 23 14:24:00 2016 +0200

    Use the stack in favor of heap allocation during marshalling
    
    In theory, this should be a little more efficient, but the effect is
    hard to measure.

 GObjectIntrospection.xs       |    6 +++---
 gperl-i11n-invoke-c.c         |   36 ++++++++++++++++++------------------
 gperl-i11n-invoke-perl.c      |   14 +++++++-------
 gperl-i11n-invoke.c           |   22 +++++++---------------
 gperl-i11n-marshal-array.c    |    2 +-
 gperl-i11n-marshal-callback.c |   14 +++++++-------
 6 files changed, 43 insertions(+), 51 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index e3f0028..7351e9e 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -104,15 +104,15 @@ typedef struct {
        guint current_pos;
 
        /* Information about the args from the typelib. */
-       GIArgInfo ** arg_infos;
-       GITypeInfo ** arg_types;
+       GIArgInfo * arg_infos;
+       GITypeInfo * arg_types;
 
        /* An array of places for storing out out/in-out or automatic args. */
        GIArgument * aux_args;
 
        gboolean has_return_value;
        ffi_type * return_type_ffi;
-       GITypeInfo * return_type_info;
+       GITypeInfo return_type_info;
        GITransfer return_type_transfer;
 
        GSList * callback_infos;
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index a0678f5..11a8170 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -63,8 +63,8 @@ invoke_c_code (GICallableInfo *info,
                gint perl_stack_pos, ffi_stack_pos;
                SV *current_sv;
 
-               arg_info = iinfo.base.arg_infos[i];
-               arg_type = iinfo.base.arg_types[i];
+               arg_info = &(iinfo.base.arg_infos[i]);
+               arg_type = &(iinfo.base.arg_types[i]);
                transfer = g_arg_info_get_ownership_transfer (arg_info);
                may_be_null = g_arg_info_may_be_null (arg_info);
 #if GI_CHECK_VERSION (1, 29, 0)
@@ -157,8 +157,8 @@ invoke_c_code (GICallableInfo *info,
                GITypeInfo * arg_type;
                if (!iinfo.is_automatic_arg[i])
                        continue;
-               arg_info = iinfo.base.arg_infos[i];
-               arg_type = iinfo.base.arg_types[i];
+               arg_info = &(iinfo.base.arg_infos[i]);
+               arg_type = &(iinfo.base.arg_types[i]);
                switch (g_arg_info_get_direction (arg_info)) {
                    case GI_DIRECTION_IN:
                        _handle_automatic_arg (i, arg_info, arg_type, &iinfo.in_args[i], &iinfo);
@@ -217,7 +217,7 @@ invoke_c_code (GICallableInfo *info,
 #if GI_CHECK_VERSION (1, 32, 0)
        /* libffi has special semantics for return value storage; see `man
         * ffi_call`.  We use gobject-introspection's extraction helper. */
-       gi_type_info_extract_ffi_return_value (iinfo.base.return_type_info,
+       gi_type_info_extract_ffi_return_value (&iinfo.base.return_type_info,
                                               &ffi_return_value,
                                               &return_value);
 #endif
@@ -232,9 +232,9 @@ invoke_c_code (GICallableInfo *info,
           )
        {
                SV *value;
-               dwarn ("return value: type = %p\n", iinfo.base.return_type_info);
+               dwarn ("return value: type = %p\n", &iinfo.base.return_type_info);
                value = SAVED_STACK_SV (arg_to_sv (&return_value,
-                                                  iinfo.base.return_type_info,
+                                                  &iinfo.base.return_type_info,
                                                   iinfo.base.return_type_transfer,
                                                   &iinfo.base));
                if (value) {
@@ -248,7 +248,7 @@ invoke_c_code (GICallableInfo *info,
                GIArgInfo * arg_info;
                if (iinfo.is_automatic_arg[i])
                        continue;
-               arg_info = iinfo.base.arg_infos[i];
+               arg_info = &(iinfo.base.arg_infos[i]);
 #if GI_CHECK_VERSION (1, 29, 0)
                if (g_arg_info_is_skip (arg_info)) {
                        continue;
@@ -266,7 +266,7 @@ invoke_c_code (GICallableInfo *info,
                                 ? GI_TRANSFER_CONTAINER
                                 : g_arg_info_get_ownership_transfer (arg_info);
                        sv = SAVED_STACK_SV (arg_to_sv (iinfo.out_args[i].v_pointer,
-                                                       iinfo.base.arg_types[i],
+                                                       &(iinfo.base.arg_types[i]),
                                                        transfer,
                                                        &iinfo.base));
                        if (sv) {
@@ -380,8 +380,8 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
        /* Make a first pass to mark args that are filled in automatically, and
         * thus have no counterpart on the Perl side. */
        for (i = 0 ; i < iinfo->base.n_args ; i++) {
-               GIArgInfo * arg_info = iinfo->base.arg_infos[i];
-               GITypeInfo * arg_type = iinfo->base.arg_types[i];
+               GIArgInfo * arg_info = &(iinfo->base.arg_infos[i]);
+               GITypeInfo * arg_type = &(iinfo->base.arg_types[i]);
                GITypeTag arg_tag = g_type_info_get_tag (arg_type);
 
                if (arg_tag == GI_TYPE_TAG_ARRAY) {
@@ -410,8 +410,8 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
        iinfo->n_expected_args = iinfo->constructor_offset + iinfo->method_offset;
        iinfo->n_nullable_args = 0;
        for (i = 0 ; i < iinfo->base.n_args ; i++) {
-               GIArgInfo * arg_info = iinfo->base.arg_infos[i];
-               GITypeInfo * arg_type = iinfo->base.arg_types[i];
+               GIArgInfo * arg_info = &(iinfo->base.arg_infos[i]);
+               GITypeInfo * arg_type = &(iinfo->base.arg_types[i]);
                GITypeTag arg_tag = g_type_info_get_tag (arg_type);
                gboolean is_out = GI_DIRECTION_OUT == g_arg_info_get_direction (arg_info);
                gboolean is_automatic = iinfo->is_automatic_arg[i];
@@ -429,10 +429,10 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
 
        /* If the return value is an array which comes with an outbound length
         * arg, then mark that length arg as automatic, too. */
-       if (g_type_info_get_tag (iinfo->base.return_type_info) == GI_TYPE_TAG_ARRAY) {
-               gint pos = g_type_info_get_array_length (iinfo->base.return_type_info);
+       if (g_type_info_get_tag (&iinfo->base.return_type_info) == GI_TYPE_TAG_ARRAY) {
+               gint pos = g_type_info_get_array_length (&iinfo->base.return_type_info);
                if (pos >= 0) {
-                       GIArgInfo * arg_info = iinfo->base.arg_infos[pos];
+                       GIArgInfo * arg_info = &(iinfo->base.arg_infos[pos]);
                        if (GI_DIRECTION_OUT == g_arg_info_get_direction (arg_info)) {
                                dwarn ("  pos %d is automatic (array length)\n", pos);
                                iinfo->is_automatic_arg[pos] = TRUE;
@@ -461,9 +461,9 @@ _prepare_c_invocation_info (GPerlI11nCInvocationInfo *iinfo,
         * descendant that returns a floating object but passes no reference on
         * to us, then we need to revisit this. */
        if (iinfo->is_constructor &&
-           g_type_info_get_tag (iinfo->base.return_type_info) == GI_TYPE_TAG_INTERFACE)
+           g_type_info_get_tag (&iinfo->base.return_type_info) == GI_TYPE_TAG_INTERFACE)
        {
-               GIBaseInfo * interface = g_type_info_get_interface (iinfo->base.return_type_info);
+               GIBaseInfo * interface = g_type_info_get_interface (&iinfo->base.return_type_info);
                if (GI_IS_REGISTERED_TYPE_INFO (interface) &&
                    g_type_is_a (get_gtype (interface),
                                 G_TYPE_INITIALLY_UNOWNED))
diff --git a/gperl-i11n-invoke-perl.c b/gperl-i11n-invoke-perl.c
index a037bec..2638f56 100644
--- a/gperl-i11n-invoke-perl.c
+++ b/gperl-i11n-invoke-perl.c
@@ -78,8 +78,8 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
         * stack */
        in_inout = 0;
        for (i = 0; i < iinfo.base.n_args; i++) {
-               GIArgInfo *arg_info = iinfo.base.arg_infos[i];
-               GITypeInfo *arg_type = iinfo.base.arg_types[i];
+               GIArgInfo *arg_info = &(iinfo.base.arg_infos[i]);
+               GITypeInfo *arg_type = &(iinfo.base.arg_types[i]);
                GITransfer transfer = g_arg_info_get_ownership_transfer (arg_info);
                GIDirection direction = g_arg_info_get_direction (arg_info);
 
@@ -191,8 +191,8 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
 
                out_index = 0;
                for (i = 0; i < iinfo.base.n_args; i++) {
-                       GIArgInfo *arg_info = iinfo.base.arg_infos[i];
-                       GITypeInfo *arg_type = iinfo.base.arg_types[i];
+                       GIArgInfo *arg_info = &(iinfo.base.arg_infos[i]);
+                       GITypeInfo *arg_type = &(iinfo.base.arg_types[i]);
                        GIDirection direction = g_arg_info_get_direction (arg_info);
                        gpointer out_pointer = * (gpointer *) args[i+args_offset];
 
@@ -240,7 +240,7 @@ invoke_perl_code (ffi_cif* cif, gpointer resp, gpointer* args, gpointer userdata
                GITransfer transfer;
                gboolean may_be_null;
 
-               type_info = iinfo.base.return_type_info;
+               type_info = &iinfo.base.return_type_info;
                transfer = iinfo.base.return_type_transfer;
                may_be_null = g_callable_info_may_return_null (cb_interface); /* FIXME */
 
@@ -352,13 +352,13 @@ _prepare_perl_invocation_info (GPerlI11nPerlInvocationInfo *iinfo,
        /* Find array length arguments and store their value in aux_args so
         * that array_to_sv can later fetch them. */
        for (i = 0 ; i < iinfo->base.n_args ; i++) {
-               GITypeInfo *arg_type = iinfo->base.arg_types[i];
+               GITypeInfo *arg_type = &(iinfo->base.arg_types[i]);
                GITypeTag arg_tag = g_type_info_get_tag (arg_type);
 
                if (arg_tag == GI_TYPE_TAG_ARRAY) {
                        gint pos = g_type_info_get_array_length (arg_type);
                        if (pos >= 0) {
-                               GITypeInfo *length_arg_type = iinfo->base.arg_types[pos];
+                               GITypeInfo *length_arg_type = &(iinfo->base.arg_types[pos]);
                                raw_to_arg (args[pos], &iinfo->base.aux_args[pos], length_arg_type);
                                dwarn ("  pos %d is array length => %"G_GSIZE_FORMAT"\n",
                                       pos, iinfo->base.aux_args[pos].v_size);
diff --git a/gperl-i11n-invoke.c b/gperl-i11n-invoke.c
index 3023e8b..f4011a0 100644
--- a/gperl-i11n-invoke.c
+++ b/gperl-i11n-invoke.c
@@ -24,8 +24,8 @@ prepare_invocation_info (GPerlI11nInvocationInfo *iinfo,
        dwarn ("  n_args = %u\n", iinfo->n_args);
 
        if (iinfo->n_args) {
-               iinfo->arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args);
-               iinfo->arg_types = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args);
+               iinfo->arg_infos = gperl_alloc_temp (sizeof (GITypeInfo) * iinfo->n_args);
+               iinfo->arg_types = gperl_alloc_temp (sizeof (GITypeInfo) * iinfo->n_args);
                iinfo->aux_args = gperl_alloc_temp (sizeof (GIArgument) * iinfo->n_args);
        } else {
                iinfo->arg_infos = NULL;
@@ -34,14 +34,14 @@ prepare_invocation_info (GPerlI11nInvocationInfo *iinfo,
        }
 
        for (i = 0 ; i < iinfo->n_args ; i++) {
-               iinfo->arg_infos[i] = g_callable_info_get_arg (info, (gint) i);
-               iinfo->arg_types[i] = g_arg_info_get_type (iinfo->arg_infos[i]);
+               g_callable_info_load_arg (info, (gint) i, &(iinfo->arg_infos[i]));
+               g_arg_info_load_type (&(iinfo->arg_infos[i]), &(iinfo->arg_types[i]));
        }
 
-       iinfo->return_type_info = g_callable_info_get_return_type (info);
+       g_callable_info_load_return_type (info, &iinfo->return_type_info);
        iinfo->has_return_value =
-               GI_TYPE_TAG_VOID != g_type_info_get_tag (iinfo->return_type_info);
-       iinfo->return_type_ffi = g_type_info_get_ffi_type (iinfo->return_type_info);
+               GI_TYPE_TAG_VOID != g_type_info_get_tag (&iinfo->return_type_info);
+       iinfo->return_type_ffi = g_type_info_get_ffi_type (&iinfo->return_type_info);
        iinfo->return_type_transfer = g_callable_info_get_caller_owns (info);
 
        iinfo->callback_infos = NULL;
@@ -55,11 +55,6 @@ clear_invocation_info (GPerlI11nInvocationInfo *iinfo)
 {
        guint i;
 
-       for (i = 0 ; i < iinfo->n_args ; i++) {
-               g_base_info_unref ((GIBaseInfo *) iinfo->arg_types[i]);
-               g_base_info_unref ((GIBaseInfo *) iinfo->arg_infos[i]);
-       }
-
        g_slist_free (iinfo->free_after_call);
        iinfo->free_after_call = NULL;
 
@@ -71,9 +66,6 @@ clear_invocation_info (GPerlI11nInvocationInfo *iinfo)
        g_slist_foreach (iinfo->array_infos, (GFunc) g_free, NULL);
        g_slist_free (iinfo->array_infos);
        iinfo->array_infos = NULL;
-
-       g_base_info_unref ((GIBaseInfo *) iinfo->return_type_info);
-       iinfo->return_type_info = NULL;
 }
 
 /* ------------------------------------------------------------------------- */
diff --git a/gperl-i11n-marshal-array.c b/gperl-i11n-marshal-array.c
index fca757a..da106b9 100644
--- a/gperl-i11n-marshal-array.c
+++ b/gperl-i11n-marshal-array.c
@@ -106,7 +106,7 @@ array_to_sv (GITypeInfo *info,
                                gint length_pos = g_type_info_get_array_length (info);
                                g_assert (iinfo && iinfo->aux_args);
                                conversion_sv = arg_to_sv (&(iinfo->aux_args[length_pos]),
-                                                          iinfo->arg_types[length_pos],
+                                                          &(iinfo->arg_types[length_pos]),
                                                           GI_TRANSFER_NOTHING, NULL);
                                length = SvIV (conversion_sv);
                                SvREFCNT_dec (conversion_sv);
diff --git a/gperl-i11n-marshal-callback.c b/gperl-i11n-marshal-callback.c
index af93b63..51e09ec 100644
--- a/gperl-i11n-marshal-callback.c
+++ b/gperl-i11n-marshal-callback.c
@@ -98,7 +98,7 @@ sv_to_callback_data (SV * sv,
 static SV *
 callback_to_sv (GICallableInfo *interface, gpointer func, GPerlI11nInvocationInfo *invocation_info)
 {
-       GIArgInfo *arg_info;
+       GIArgInfo arg_info;
        GPerlI11nCCallbackInfo *callback_info;
        HV *stash;
        SV *code_sv, *data_sv;
@@ -116,17 +116,17 @@ callback_to_sv (GICallableInfo *interface, gpointer func, GPerlI11nInvocationInf
                }
        }
 
-       arg_info = g_callable_info_get_arg (invocation_info->interface,
-                                           (gint) invocation_info->current_pos);
+       g_callable_info_load_arg (invocation_info->interface,
+                                 (gint) invocation_info->current_pos,
+                                 &arg_info);
 
        dwarn ("C callback: pos = %d, name = %s\n",
               invocation_info->current_pos,
-              g_base_info_get_name (arg_info));
+              g_base_info_get_name (&arg_info));
 
        callback_info = create_c_callback_closure (interface, func);
-       callback_info->data_pos = g_arg_info_get_closure (arg_info);
-       callback_info->destroy_pos = g_arg_info_get_destroy (arg_info);
-       g_base_info_unref (arg_info);
+       callback_info->data_pos = g_arg_info_get_closure (&arg_info);
+       callback_info->destroy_pos = g_arg_info_get_destroy (&arg_info);
 
        if (func) {
                data_sv = newSViv (PTR2IV (callback_info));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]