From: Eric Blake <eblake@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: qemu-devel@nongnu.org, famz@redhat.com,
Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH v3 15/18] qapi: Add new clone visitor
Date: Mon, 2 May 2016 13:25:29 -0600 [thread overview]
Message-ID: <5727A9A9.5090707@redhat.com> (raw)
In-Reply-To: <87lh3sgxb1.fsf@dusky.pond.sub.org>
[-- Attachment #1: Type: text/plain, Size: 6575 bytes --]
On 05/02/2016 11:54 AM, Markus Armbruster wrote:
>
> qapi-types.h grows by 492 lines (19KiB, +19%). Roughly one non-blank
> line per non-simple type, including list types. It's included all over
> the place.
>
> qapi-types.c grows by 4212 lines (92KiB, +90%).
>
> Is it a good idea to generate all clone functions? As far as I can see,
> we use only a fraction of them.
Would it be worth creating a separate .h file, and only include that
file in the few places that actually want a clone, rather than making
every file pay the price of a larger .h?
>
> A sufficiently smart link-time optimizer can get rid of the ones we
> don't use. But I consider the "sufficiently smart optimizer" argument a
> cop out until proven otherwise.
We could also teach the qapi generator to mark specific types as
cloneable (and then the transitive closure of all subtypes included by
those types are also cloneable), and only generate the clone functions
where it matters, rather than for every type. I can play with that idea
(basically, adding a 'clone':true flag in the .json file, then figuring
out how to propagate that through all subtypes).
>
> We already generate plenty of code we don't use, but that's not exactly
> a reason for generating more code we don't use.
I guess it's a trade-off of whether we will find new uses rather than
the two immediate places that I fix in the next couple of patches - if
we need more types to be cloneable, how much maintenance effort is it to
mark those additional types cloneable?
>> +++ b/include/qapi/visitor-impl.h
>> @@ -35,6 +35,7 @@ typedef enum VisitorType {
>> VISITOR_INPUT,
>> VISITOR_OUTPUT,
>> VISITOR_DEALLOC,
>> + VISITOR_CLONE,
>
> It's *two* visitors, running in lockstep: an input visitor visiting
> @src, and an output visitor visiting the clone.
>
> To which one does the Visitor's type apply?
>
> Let's review how it's used:
>
> * visit_start_struct()
>
> if (obj && v->type == VISITOR_INPUT) {
> assert(!err != !*obj);
> }
>
> The clone visitor behaves like an input visitor here.
It doesn't actually set err, but is indeed allocating *obj.
> * visit_type_enum()
>
> if (v->type == VISITOR_INPUT) {
> input_type_enum(v, name, obj, strings, errp);
> } else if (v->type == VISITOR_OUTPUT) {
> output_type_enum(v, name, obj, strings, errp);
> }
>
> The clone visitor wants to override this completely.
The override is to have visit_type_enum() be a no-op (because we don't
visit top-level enums, and an enum which is a member of a struct or list
is cloned as part of the memdup() of pushing into the struct or list).
The dealloc visitor also has visit_type_enum() be a no-op.
>
> Hypothetical input from / output to binary visitors would probably
> want the same. Perhaps this part of commit da72ab0 wasn't a good
> idea.
The clone visitor is cloning C structs, not other representations (that
is, this is NOT a QObject cloner, and therefore even if we add
hypothetical binary representation input/output visitors, this wil NOT
be cloning those binary representations). The fact that we now have a
fourth category of visitor, where dealloc and clone visitors behave the
same for visit_type_enum, didn't seem too bad.
>> +def gen_type_clone_decl(name):
>> + return mcgen('''
>> +
>> +%(c_name)s *qapi_%(c_name)s_clone(const %(c_name)s *src);
>
> Hmm. It's qapi_free_FOO(), but qapi_FOO_clone().
and qapi_visit_FOO_members(). I'm fine swapping names to whatever you
find nicer, but think qapi_clone_FOO() is probably best now that you
mention it.
>> +static void qapi_clone_start_struct(Visitor *v, const char *name, void **obj,
>> + size_t size, Error **errp)
>> +{
>> + QapiCloneVisitor *qcv = to_qcv(v);
>> +
>> + if (!obj) {
>> + /* Nothing to allocate on the virtual walk during an
>> + * alternate, but we still have to push depth.
>
> I don't quite get this comment. I understand why we don't memdup() ---
> it's pointless without a place to store the duplicate. I think I
> understand why we want to increment qcv->depth unconditionally, but I
> might be wrong. What exactly is the meaning of member depth?
>
> What's the relation to alternate?
>
> I see this is temporary. Should I not worry and move on?
I can still make the comment better.
Basically, when we are doing visit_type_ALTERNATE() and happen to pick
the object branch of the alternate, we call visit_start_struct(NULL)
under the hood; the 'if (!obj)' should NOT be reachable for a top-level
visit (because we state that this visitor is limited and cannot do
virtual walks), but it IS reachable under the hood when walking an
alternate.
So maybe the comment should read:
if (!obj) {
/*
* Reachable only when visiting an alternate. Nothing to allocate,
* and visit_start_alternate() already copied memory, so we have
* nothing further to do except increment depth for proper
* bookkeeping during visit_end_struct().
*/
>
>> + * FIXME: passing obj to visit_end_struct would make this easier */
>> + assert(qcv->depth);
>> + qcv->depth++;
>> + return;
>> + }
>> +
>> + *obj = g_memdup(qcv->depth ? *obj : qcv->root, size);
>> + qcv->depth++;
>> +}
>> +static void qapi_clone_type_any(Visitor *v, const char *name, QObject **obj,
>> + Error **errp)
>> +{
>> + QapiCloneVisitor *qcv = to_qcv(v);
>> + assert(qcv->depth);
>> + /* Pointer was already copied by g_memdup; fix the refcount */
>> + qobject_incref(*obj);
>
> 'any' values are shared?
Unless you know of a way to deep clone QObject, and a reason that a deep
clone is better than sharing. The reason we have to deep clone the rest
of the QAPI object is that QAPI doesn't have ref-counting the way
QObject does.
>> + UserDefOne *qapi_UserDefOne_clone(const UserDefOne *src)
>> + {
>> + QapiCloneVisitor *qcv;
>> + Visitor *v;
>> + UserDefOne *dst;
>
> Tab damage. More of the same below.
I can't make emacs figure out that the docs file doesn't need TABs, so
it's not the first time I've tab-damaged a patch (although sometimes
I've managed to catch it before leaking it to the list - not this time,
though).
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
next prev parent reply other threads:[~2016-05-02 19:26 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-29 4:23 [Qemu-devel] [PATCH v3 00/18] Add qapi-to-JSON and clone visitors Eric Blake
2016-04-29 4:23 ` [PATCH v3 01/18] qapi: Rename (one) qjson.h to qobject-json.h Eric Blake
2016-04-29 4:23 ` [Qemu-devel] " Eric Blake
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 02/18] qapi: Improve use of qmp/types.h Eric Blake
2016-04-29 11:46 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 03/18] qapi: Factor out JSON string escaping Eric Blake
2016-04-29 12:09 ` Markus Armbruster
2016-04-29 17:57 ` Eric Blake
2016-05-03 7:36 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 04/18] qapi: Factor out JSON number formatting Eric Blake
2016-04-29 13:22 ` Markus Armbruster
2016-04-29 13:43 ` Eric Blake
2016-05-03 8:02 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 05/18] qapi: Use qstring_append_chr() where appropriate Eric Blake
2016-04-29 13:25 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 06/18] qapi: Add qstring_append_format() Eric Blake
2016-04-29 13:40 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 07/18] qapi: Add json output visitor Eric Blake
2016-05-02 9:15 ` Markus Armbruster
2016-05-02 15:11 ` Eric Blake
2016-05-03 8:22 ` Markus Armbruster
2016-05-04 15:45 ` Markus Armbruster
2016-05-06 4:16 ` Eric Blake
2016-05-06 12:31 ` Markus Armbruster
2016-05-06 14:08 ` Eric Blake
2016-05-10 4:22 ` Eric Blake
2016-05-18 15:16 ` Eric Blake
2016-05-18 15:24 ` Eric Blake
2016-05-02 15:00 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 08/18] qjson: Simplify by using json-output-visitor Eric Blake
2016-05-02 12:45 ` Markus Armbruster
2016-05-02 12:49 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 09/18] Revert "qjson: Simplify by using json-output-visitor" Eric Blake
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 10/18] vmstate: Use new JSON output visitor Eric Blake
2016-05-02 13:26 ` Markus Armbruster
2016-05-02 14:23 ` Eric Blake
2016-05-03 8:30 ` Markus Armbruster
2016-05-03 9:44 ` Dr. David Alan Gilbert
2016-05-03 12:26 ` Markus Armbruster
2016-05-03 12:34 ` Eric Blake
2016-05-03 13:27 ` Dr. David Alan Gilbert
2016-05-04 8:39 ` Markus Armbruster
2016-05-04 8:54 ` Dr. David Alan Gilbert
2016-05-24 7:15 ` Paolo Bonzini
2016-05-03 13:23 ` Dr. David Alan Gilbert
2016-05-04 9:11 ` Markus Armbruster
2016-05-04 9:22 ` Dr. David Alan Gilbert
2016-05-04 11:37 ` Markus Armbruster
2016-05-04 11:56 ` Dr. David Alan Gilbert
2016-05-04 13:00 ` Markus Armbruster
2016-05-04 13:19 ` Dr. David Alan Gilbert
2016-05-04 14:10 ` Markus Armbruster
2016-05-04 14:53 ` Dr. David Alan Gilbert
2016-05-04 15:17 ` Eric Blake
2016-05-04 15:42 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 11/18] qjson: Remove unused file Eric Blake
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 12/18] qapi: Add qobject_to_json_pretty_prefix() Eric Blake
2016-05-02 13:56 ` Markus Armbruster
2016-05-02 15:14 ` Eric Blake
2016-05-03 8:32 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 13/18] qapi: Support pretty printing in JSON output visitor Eric Blake
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 14/18] qemu-img: Use new JSON output formatter Eric Blake
2016-05-02 14:04 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 15/18] qapi: Add new clone visitor Eric Blake
2016-05-02 17:54 ` Markus Armbruster
2016-05-02 19:25 ` Eric Blake [this message]
2016-05-03 11:36 ` Markus Armbruster
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 16/18] sockets: Use new QAPI cloning Eric Blake
2016-04-29 8:30 ` Daniel P. Berrange
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 17/18] replay: " Eric Blake
2016-04-29 4:23 ` [Qemu-devel] [PATCH v3 18/18] qapi: Add parameter to visit_end_* Eric Blake
2016-05-02 18:20 ` Markus Armbruster
2016-05-02 19:31 ` Eric Blake
2016-05-03 11:53 ` Markus Armbruster
2016-05-03 12:41 ` Eric Blake
2016-05-09 8:50 ` [Qemu-devel] [PATCH v3 00/18] Add qapi-to-JSON and clone visitors Paolo Bonzini
2016-05-09 9:29 ` Paolo Bonzini
2016-05-09 14:52 ` Eric Blake
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=5727A9A9.5090707@redhat.com \
--to=eblake@redhat.com \
--cc=armbru@redhat.com \
--cc=famz@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.