[xsde-users] memory management of "variable length" elements
boris at codesynthesis.com
Thu Sep 16 13:20:25 EDT 2010
Ivan Le Lann <ivan.lelann at free.fr> writes:
> In var_sequence as in generated code, we need free functions to wrap
> code like "p = 0" or "delete p". Without template specialization,
> how to implement these functions ? Overloading can help in generated
> code, but not in libxsde, as you spotted.
> This looks like a dead end to me.
Looks like it. The only alternative would be to make a copy of the
var_sequence template with the second template argument which is
assumed to be a smart pointer. But having essentially the same
functionality in two places is quite ugly.
> > Also, provided there is a way to clone var-length nodes, would you
> > still need this feature?
> I need both to get a COW-pointer.
I don't think you will be able to achieve COW even if there was pointer
customization support. You would be able share nodes in several object
models, but not COW.
For COW you would need to completely encapsulate modification of a node
so that you can intercept them and make a copy. For example, the generated
accessor function which return a non-const reference to an object, allows
me to modify the node and there is no way you will be able to intercept
that. Unless you resort to something like COA (copy on access) instead.
> Not that I really like COW but it seemed to fit here :
> The code is basically a "solid request" builder from various parts.
> Some parts are most of the time inserted as is, some are always,
> and some are rebuilt from scratch each time.
> My current state (with my smart ptr aware xsde) is that parts that
> are known never to be modified use a shared ptr.
> But I'm playing with fire here and especially with side-effects.
> Before the move to vanilla XSD/e, this code was *much* slower.
> This was pure DOM and XPath manipulation with TinyXML.
> While performance with vanilla XSD/e is a great achievement, I had the
> feeling I could easily be both safe and optimal with few pointer tweaks.
It is not clear to me where there is COW in your logic. Sounds like just
sharing of nodes among multiple object models. If that's all you need,
then I might have an interesting workaround for you.
For the upcoming release of XSD/e we have implemented support for
custom allocators. You can basically provide your own alloc and
free functions and all the dynamic memory allocated by XSD/e will
go through these functions. The idea is to implement the so-called
arenas where you would place your shared fragments. Your custom
free() function will know about these arenas and if there is a
request to free a memory block from one of them, it will simply
be ignored. This way the object models can act as if they were
the sole "owners" of such shared fragments when in reality your
application controls when the these arenas (and therefore object
model fragments placed in them) will be freed. When a fragment is
no longer needed, the arena that hosts it is destroyed and all the
memory allocated is freed.
The only issue with this model is if you use std::string which won't
be automatically allocated in the arena. But if you disable STL, then
I think this approach could work quite well.
> I might even try this idea on XSD (not /e). What do you think?
XSD is a lot more feature-rich so there could be more places where
you will have to change things. But you can definitely try.
More information about the xsde-users