[cairo] mallocs in gstate_save
Baz
brian.ewins at gmail.com
Wed Nov 14 03:54:53 PST 2007
Hi all,
Just looking at Stuart Parmenter's allocation dumps:
http://pavlovdotnet.wordpress.com/2007/11/13/allocation-data/ ...
there was some chat on irc about the mass of
_cairo_clip_intersect_path allocs, but I didn't see gstate
save/restore discussed - seems we have 5.9 meg of allocs in
gstate_save. I'm wondering if there's an easy win here.
In the 5-deep traces there are 323+330+389+918+1776 allocs in
cairo_create, and 174+378+977+1776+2789+8104+8689 calls to gstate_save
(not adding up the figures so you can see where they're coming from).
So unsurprisingly, save/restore happens multiple times on each
cairo_t. It seems likely that this is going to be several save/restore
pairs in sequence, rather than stack of save/restores, so we're
freeing allocations we could reuse.
So, my question is - would it be sensible in this case to just hang on
to the previous alloc (just reducing allocs rather than addressing the
fragmentation issue). Something like the code below;
_cairo_gstate_destroy would become tail-recursive to free this up
later.
cairo_status_t
_cairo_gstate_save (cairo_gstate_t **gstate)
{
cairo_gstate_t *top;
/* a new member pointing at the previous allocation. better name?
preallocated? */
if (*gstate->allocated) {
top = *gstate->allocated;
status = _cairo_gstate_init_copy (top, *gstate);
if (status)
return status;
} else {
top = _cairo_gstate_clone (*gstate);
if (top == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
*gstate->allocated = top;
}
top->next = *gstate;
*gstate = top;
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_gstate_restore (cairo_gstate_t **gstate)
{
cairo_gstate_t *top;
top = *gstate;
if (top->next == NULL)
return _cairo_error (CAIRO_STATUS_INVALID_RESTORE);
*gstate = top->next;
/* No need to destroy top; *gstate->allocated is still pointing to it */
/* _cairo_gstate_destroy (top); */
return CAIRO_STATUS_SUCCESS;
}
More information about the cairo
mailing list