Because of intrinsic nature of DOM documents, they often have
numerous child nodes, that can't be allocated by advance.
In order to minimize memory allocation while creating, using, and
rendering a DOM tree, every memory based operation goes to a specific
interface, the
allocator.
This allocator could, like
current
code, simply use the C++ heap (new and delete) to construct
and delete objects on demand.
However, it can also cache and monitor every allocation, and avoid
creating tons of small heap allocated object.
It's expected by the first beta release that UZI will batch allocate
multiple nodes on starting, and reuse returned nodes instead of
unallocating them.
Every part of UZI use its own allocator, so you can tweak almost every
memory-specific behaviour.
Please have a look to:
- HTML::Elements::Allocators
for the HTML::Elements (also seen as HTML tags) and DOM::Nodes
allocator. HTML::Elements are easily mutable, so they could be reused
between different element types. Reusing DOM::Node (Element, Attr,
Document) is more difficult because they are typed, but still possible
(see [1]).
- HTML::Renderer::Allocators
for the HTML::Renderer::Box, HTML::Renderer::BoxHierarchy and
CSS::Length allocator. Both Box and BoxHierarchy are mutable, so they
could be reused between different box types. However, CSS::Length are
typed, so a special care must be taken before reusing.
- HTML::Renderer::RequiredRendererImplementation
for the table layout. Because table layouts are specific to the actual
renderer (a renderer could decide to expand tables, for example), the
mapper ask the renderer to give it a TableLayout for each table it
finds in the DOM's tree. The renderer could decide to reuse table
layout object when they become unreachable, instead of deleting them.
When
reusing strongly typed elements like DOM::Element or DOM::Attr, you'll
have to first return existing allocated members (for example,
DOM::Element own a
pointer on an allocated
HTML::Elements::Element
that must be returned to the allocator, or mutated), then you can use
placing new operator [
C++
code is :
new(oldNodePointer)
DOM::Element(...);
] to recreate a new node,
of
the same type, on the previous node address space.
It's a good idea to read each class destructor or
returnToAllocator
method in order to learn what pointer is owned, and what is returned,
and so on.
In future UZI versions,
profiling
will be able to characterize each allocator, and it'll be possible to
select the best one before releasing a definitive version.
[1] In
HTML::Elements::Allocators, it's required to allocate the different
DOM::Node's child by calling respective methods. However returning
these nodes to the allocator is done by the single returnNode
method. This is because every DOM::Node object must overload
the returnToAllocator
method to return its specific data.
You must call the returnToAllocator
method to return the node to its allocator, and not returnNode method
directly.