All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Eric Blake <eblake@redhat.com>
Cc: qemu-devel@nongnu.org, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH v10 08/13] qapi: Adjust layout of FooList types
Date: Tue, 16 Feb 2016 17:55:50 +0100	[thread overview]
Message-ID: <8760xoppbd.fsf@blackfin.pond.sub.org> (raw)
In-Reply-To: <1455582057-27565-9-git-send-email-eblake@redhat.com> (Eric Blake's message of "Mon, 15 Feb 2016 17:20:52 -0700")

Eric Blake <eblake@redhat.com> writes:

> By sticking the next pointer first, we don't need a union with
> 64-bit padding for smaller types.  On 32-bit platforms, this
> can reduce the size of uint8List from 16 bytes (or 12, depending
> on whether 64-bit ints can tolerate 4-byte alignment) down to 8.
> It has no effect on 64-bit platforms (where alignment still
> dictates a 16-byte struct); but fewer anonymous unions is still
> a win in my book.
>
> It requires visit_next_list() to gain a size parameter, to know
> what size element to allocate; comparable to the size parameter
> of visit_start_struct().
>
> I debated about going one step further, to allow for fewer casts,
> by doing:
>     typedef GenericList GenericList;
>     struct GenericList {
>         GenericList *next;
>     };
>     struct FooList {
>         GenericList base;
>         Foo value;
>     };
> so that you convert to 'GenericList *' by '&foolist->base', and
> back by 'container_of(generic, GenericList, base)' (as opposed to
> the existing '(GenericList *)foolist' and '(FooList *)generic').
> But doing that would require hoisting the declaration of
> GenericList prior to inclusion of qapi-types.h, rather than its
> current spot in visitor.h; it also makes iteration a bit more
> verbose through 'foolist->base.next' instead of 'foolist->next'.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v10: hoist earlier in series
> v9: no change
> v8: rebase to earlier changes
> v7: new patch; probably too invasive to be worth it, especially if
> we can't prove that our current size for uint8List is a bottleneck
> ---
>  include/qapi/visitor.h       | 14 +++++++-------
>  include/qapi/visitor-impl.h  |  2 +-
>  scripts/qapi-types.py        |  5 +----
>  scripts/qapi-visit.py        |  2 +-
>  qapi/qapi-visit-core.c       |  4 ++--
>  qapi/opts-visitor.c          |  4 ++--
>  qapi/qapi-dealloc-visitor.c  |  3 ++-
>  qapi/qmp-input-visitor.c     |  5 +++--
>  qapi/qmp-output-visitor.c    |  3 ++-
>  qapi/string-input-visitor.c  |  4 ++--
>  qapi/string-output-visitor.c |  2 +-
>  11 files changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
> index 5e581dc..c131a32 100644
> --- a/include/qapi/visitor.h
> +++ b/include/qapi/visitor.h
> @@ -19,13 +19,13 @@
>  #include "qapi/error.h"
>  #include <stdlib.h>
>
> -typedef struct GenericList
> -{
> -    union {
> -        void *value;
> -        uint64_t padding;
> -    };
> +
> +/* This struct is layout-compatible with all other *List structs
> + * created by the qapi generator.  It is used as a typical
> + * singly-linked list. */
> +typedef struct GenericList {
>      struct GenericList *next;
> +    char padding[];
>  } GenericList;
>
>  void visit_start_struct(Visitor *v, const char *name, void **obj,
> @@ -36,7 +36,7 @@ void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
>  void visit_end_implicit_struct(Visitor *v);
>
>  void visit_start_list(Visitor *v, const char *name, Error **errp);
> -GenericList *visit_next_list(Visitor *v, GenericList **list);
> +GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size);
>  void visit_end_list(Visitor *v);
>
>  /**
> diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
> index ea252f8..7905a28 100644
> --- a/include/qapi/visitor-impl.h
> +++ b/include/qapi/visitor-impl.h
> @@ -29,7 +29,7 @@ struct Visitor
>
>      void (*start_list)(Visitor *v, const char *name, Error **errp);
>      /* Must be set */
> -    GenericList *(*next_list)(Visitor *v, GenericList **list);
> +    GenericList *(*next_list)(Visitor *v, GenericList **list, size_t size);
>      /* Must be set */
>      void (*end_list)(Visitor *v);
>
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 7b0dca8..83f230a 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -26,11 +26,8 @@ def gen_array(name, element_type):
>      return mcgen('''
>
>  struct %(c_name)s {
> -    union {
> -        %(c_type)s value;
> -        uint64_t padding;
> -    };
>      %(c_name)s *next;
> +    %(c_type)s value;
>  };
>  ''',
>                   c_name=c_name(name), c_type=element_type.c_type())
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 177dfc4..9ff0337 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -129,7 +129,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
>      }
>
>      for (prev = (GenericList **)obj;
> -         !err && (i = visit_next_list(v, prev)) != NULL;
> +         !err && (i = visit_next_list(v, prev, sizeof(**obj))) != NULL;
>           prev = &i) {
>          %(c_name)s *native_i = (%(c_name)s *)i;
>          visit_type_%(c_elt_type)s(v, NULL, &native_i->value, &err);
> diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
> index f856286..6fa66f1 100644
> --- a/qapi/qapi-visit-core.c
> +++ b/qapi/qapi-visit-core.c
> @@ -50,9 +50,9 @@ void visit_start_list(Visitor *v, const char *name, Error **errp)
>      v->start_list(v, name, errp);
>  }
>
> -GenericList *visit_next_list(Visitor *v, GenericList **list)
> +GenericList *visit_next_list(Visitor *v, GenericList **list, size_t size)
>  {

Lost since v9: assert(size).  In my review of v9, I suggested tightening
the assertion to size >= GenericList.

> -    return v->next_list(v, list);
> +    return v->next_list(v, list, size);
>  }
>
>  void visit_end_list(Visitor *v)
> diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
> index ae5b955..73e4ace 100644
> --- a/qapi/opts-visitor.c
> +++ b/qapi/opts-visitor.c
> @@ -215,7 +215,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)
>
>
>  static GenericList *
> -opts_next_list(Visitor *v, GenericList **list)
> +opts_next_list(Visitor *v, GenericList **list, size_t size)
>  {
>      OptsVisitor *ov = to_ov(v);
>      GenericList **link;
> @@ -258,7 +258,7 @@ opts_next_list(Visitor *v, GenericList **list)
>          abort();
>      }
>
> -    *link = g_malloc0(sizeof **link);
> +    *link = g_malloc0(size);
>      return *link;
>  }
>
> diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
> index 2659d3f..6667e8c 100644
> --- a/qapi/qapi-dealloc-visitor.c
> +++ b/qapi/qapi-dealloc-visitor.c
> @@ -100,7 +100,8 @@ static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp)
>      qapi_dealloc_push(qov, NULL);
>  }
>
> -static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp)
> +static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp,
> +                                           size_t size)
>  {
>      GenericList *list = *listp;
>      QapiDeallocVisitor *qov = to_qov(v);
> diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
> index 2f48b95..2621660 100644
> --- a/qapi/qmp-input-visitor.c
> +++ b/qapi/qmp-input-visitor.c
> @@ -165,7 +165,8 @@ static void qmp_input_start_list(Visitor *v, const char *name, Error **errp)
>      qmp_input_push(qiv, qobj, errp);
>  }
>
> -static GenericList *qmp_input_next_list(Visitor *v, GenericList **list)
> +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
> +                                        size_t size)
>  {
>      QmpInputVisitor *qiv = to_qiv(v);
>      GenericList *entry;
> @@ -184,7 +185,7 @@ static GenericList *qmp_input_next_list(Visitor *v, GenericList **list)
>          return NULL;
>      }
>
> -    entry = g_malloc0(sizeof(*entry));
> +    entry = g_malloc0(size);
>      if (first) {
>          *list = entry;
>      } else {
> diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
> index f47eefa..d44c676 100644
> --- a/qapi/qmp-output-visitor.c
> +++ b/qapi/qmp-output-visitor.c
> @@ -126,7 +126,8 @@ static void qmp_output_start_list(Visitor *v, const char *name, Error **errp)
>      qmp_output_push(qov, list);
>  }
>
> -static GenericList *qmp_output_next_list(Visitor *v, GenericList **listp)
> +static GenericList *qmp_output_next_list(Visitor *v, GenericList **listp,
> +                                         size_t size)
>  {
>      GenericList *list = *listp;
>      QmpOutputVisitor *qov = to_qov(v);
> diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
> index 18b9339..59eb5dc 100644
> --- a/qapi/string-input-visitor.c
> +++ b/qapi/string-input-visitor.c
> @@ -139,7 +139,7 @@ start_list(Visitor *v, const char *name, Error **errp)
>      }
>  }
>
> -static GenericList *next_list(Visitor *v, GenericList **list)
> +static GenericList *next_list(Visitor *v, GenericList **list, size_t size)
>  {
>      StringInputVisitor *siv = to_siv(v);
>      GenericList **link;
> @@ -173,7 +173,7 @@ static GenericList *next_list(Visitor *v, GenericList **list)
>          link = &(*list)->next;
>      }
>
> -    *link = g_malloc0(sizeof **link);
> +    *link = g_malloc0(size);
>      return *link;
>  }
>
> diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
> index b980bd3..c2e5c5b 100644
> --- a/qapi/string-output-visitor.c
> +++ b/qapi/string-output-visitor.c
> @@ -276,7 +276,7 @@ start_list(Visitor *v, const char *name, Error **errp)
>      sov->head = true;
>  }
>
> -static GenericList *next_list(Visitor *v, GenericList **list)
> +static GenericList *next_list(Visitor *v, GenericList **list, size_t size)
>  {
>      StringOutputVisitor *sov = to_sov(v);
>      GenericList *ret = NULL;

Doing this patch earlier in the series halved its size :)

  reply	other threads:[~2016-02-16 16:55 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-16  0:20 [Qemu-devel] [PATCH v10 00/13] prune some QAPI visitor cruft (was qapi cleanups subset E) Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 01/13] qapi: Simplify excess input reporting in input visitors Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 02/13] qapi: Forbid empty unions and useless alternates Eric Blake
2016-02-16 16:08   ` Markus Armbruster
2016-02-16 23:18     ` Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 03/13] qapi: Reposition error checks in gen_visit_fields() Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 04/13] qapi: Drop pointless gotos in generated code Eric Blake
2016-02-16 16:27   ` Markus Armbruster
2016-02-16 17:14     ` Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 05/13] qapi-visit: Simplify how we visit common union members Eric Blake
2016-02-16 16:31   ` Markus Armbruster
2016-02-16 17:17     ` Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 06/13] qapi-visit: Unify struct and union visit Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 07/13] qapi-visit: Less indirection in visit_type_Foo_fields() Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 08/13] qapi: Adjust layout of FooList types Eric Blake
2016-02-16 16:55   ` Markus Armbruster [this message]
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 09/13] qapi: Emit structs used as variants in topological order Eric Blake
2016-02-16 17:03   ` Markus Armbruster
2016-02-16 17:32     ` Eric Blake
2016-02-16 21:00       ` Markus Armbruster
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 10/13] qapi: Don't box struct branch of alternate Eric Blake
2016-02-16 19:07   ` Markus Armbruster
2016-02-16 19:53     ` Eric Blake
2016-02-17 14:40       ` Markus Armbruster
2016-02-17 20:34         ` Eric Blake
2016-02-18  8:21           ` Markus Armbruster
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 11/13] qapi: Don't box branches of flat unions Eric Blake
2016-02-17 17:44   ` Markus Armbruster
2016-02-17 20:53     ` Eric Blake
2016-02-18  8:51       ` Markus Armbruster
2016-02-18 16:51         ` Eric Blake
2016-02-18 17:11           ` Markus Armbruster
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 12/13] qapi: Delete unused visit_start_union() Eric Blake
2016-02-17 18:08   ` Markus Armbruster
2016-02-17 21:19     ` Eric Blake
2016-02-18  8:24       ` Markus Armbruster
2016-02-18 16:47         ` Eric Blake
2016-02-16  0:20 ` [Qemu-devel] [PATCH v10 13/13] qapi: Change visit_start_implicit_struct to visit_start_alternate Eric Blake
2016-02-17 18:13   ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8760xoppbd.fsf@blackfin.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.