Public Member Functions | Static Public Member Functions | Public Attributes
xml_allocator Struct Reference
Inheritance diagram for xml_allocator:
Inheritance graph
[legend]
Collaboration diagram for xml_allocator:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 xml_allocator (xml_memory_page *root)
xml_memory_pageallocate_page (size_t data_size)
void * allocate_memory_oob (size_t size, xml_memory_page *&out_page)
void * allocate_memory (size_t size, xml_memory_page *&out_page)
void deallocate_memory (void *ptr, size_t size, xml_memory_page *page)
char_t * allocate_string (size_t length)
void deallocate_string (char_t *string)

Static Public Member Functions

static void deallocate_page (xml_memory_page *page)

Public Attributes

xml_memory_page_root
size_t _busy_size

Detailed Description

Definition at line 314 of file pugixml.cpp.


Constructor & Destructor Documentation

Definition at line 316 of file pugixml.cpp.

                                                    : _root(root), _busy_size(root->busy_size)
                {
                }

Member Function Documentation

void* xml_allocator::allocate_memory ( size_t  size,
xml_memory_page *&  out_page 
) [inline]

Definition at line 348 of file pugixml.cpp.

References _busy_size, _root, allocate_memory_oob(), and xml_memory_page::data.

Referenced by allocate_attribute(), allocate_node(), and allocate_string().

                {
                        if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page);

                        void* buf = _root->data + _busy_size;

                        _busy_size += size;

                        out_page = _root;

                        return buf;
                }
PUGI__FN_NO_INLINE void * xml_allocator::allocate_memory_oob ( size_t  size,
xml_memory_page *&  out_page 
)

Definition at line 446 of file pugixml.cpp.

References _busy_size, _root, allocate_page(), xml_memory_page::busy_size, xml_memory_page::data, xml_memory_page::next, and xml_memory_page::prev.

Referenced by allocate_memory().

        {
                const size_t large_allocation_threshold = xml_memory_page_size / 4;

                xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size);
                out_page = page;

                if (!page) return 0;

                if (size <= large_allocation_threshold)
                {
                        _root->busy_size = _busy_size;

                        // insert page at the end of linked list
                        page->prev = _root;
                        _root->next = page;
                        _root = page;

                        _busy_size = size;
                }
                else
                {
                        // insert page before the end of linked list, so that it is deleted as soon as possible
                        // the last page is not deleted even if it's empty (see deallocate_memory)
                        assert(_root->prev);

                        page->prev = _root->prev;
                        page->next = _root;

                        _root->prev->next = page;
                        _root->prev = page;
                }

                // allocate inside page
                page->busy_size = size;

                return page->data;
        }
xml_memory_page* xml_allocator::allocate_page ( size_t  data_size) [inline]

Definition at line 320 of file pugixml.cpp.

References _root, xml_memory_management_function_storage< T >::allocate, xml_memory_page::allocator, xml_memory_page::construct(), and xml_memory_page::memory.

Referenced by allocate_memory_oob().

                {
                        size_t size = offsetof(xml_memory_page, data) + data_size;

                        // allocate block with some alignment, leaving memory for worst-case padding
                        void* memory = xml_memory::allocate(size + xml_memory_page_alignment);
                        if (!memory) return 0;

                        // align upwards to page boundary
                        void* page_memory = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1));

                        // prepare page structure
                        xml_memory_page* page = xml_memory_page::construct(page_memory);
                        assert(page);

                        page->memory = memory;
                        page->allocator = _root->allocator;

                        return page;
                }
char_t* xml_allocator::allocate_string ( size_t  length) [inline]

Definition at line 396 of file pugixml.cpp.

References allocate_memory(), xml_memory_page::busy_size, xml_memory_page::data, xml_memory_string_header::full_size, and xml_memory_string_header::page_offset.

Referenced by strcpy_insitu().

                {
                        // allocate memory for string and header block
                        size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t);
                        
                        // round size up to pointer alignment boundary
                        size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1);

                        xml_memory_page* page;
                        xml_memory_string_header* header = static_cast<xml_memory_string_header*>(allocate_memory(full_size, page));

                        if (!header) return 0;

                        // setup header
                        ptrdiff_t page_offset = reinterpret_cast<char*>(header) - page->data;

                        assert(page_offset >= 0 && page_offset < (1 << 16));
                        header->page_offset = static_cast<uint16_t>(page_offset);

                        // full_size == 0 for large strings that occupy the whole page
                        assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0));
                        header->full_size = static_cast<uint16_t>(full_size < (1 << 16) ? full_size : 0);

                        // round-trip through void* to avoid 'cast increases required alignment of target type' warning
                        // header is guaranteed a pointer-sized alignment, which should be enough for char_t
                        return static_cast<char_t*>(static_cast<void*>(header + 1));
                }
void xml_allocator::deallocate_memory ( void *  ptr,
size_t  size,
xml_memory_page page 
) [inline]

Definition at line 361 of file pugixml.cpp.

References _busy_size, _root, xml_memory_page::busy_size, xml_memory_page::data, deallocate_page(), xml_memory_page::freed_size, xml_memory_page::next, and xml_memory_page::prev.

Referenced by deallocate_string(), destroy_attribute(), and destroy_node().

                {
                        if (page == _root) page->busy_size = _busy_size;

                        assert(ptr >= page->data && ptr < page->data + page->busy_size);
                        (void)!ptr;

                        page->freed_size += size;
                        assert(page->freed_size <= page->busy_size);

                        if (page->freed_size == page->busy_size)
                        {
                                if (page->next == 0)
                                {
                                        assert(_root == page);

                                        // top page freed, just reset sizes
                                        page->busy_size = page->freed_size = 0;
                                        _busy_size = 0;
                                }
                                else
                                {
                                        assert(_root != page);
                                        assert(page->prev);

                                        // remove from the list
                                        page->prev->next = page->next;
                                        page->next->prev = page->prev;

                                        // deallocate
                                        deallocate_page(page);
                                }
                        }
                }
static void xml_allocator::deallocate_page ( xml_memory_page page) [inline, static]
void xml_allocator::deallocate_string ( char_t *  string) [inline]

Definition at line 424 of file pugixml.cpp.

References xml_memory_page::busy_size, deallocate_memory(), xml_memory_string_header::full_size, and xml_memory_string_header::page_offset.

Referenced by destroy_attribute(), destroy_node(), and strcpy_insitu().

                {
                        // this function casts pointers through void* to avoid 'cast increases required alignment of target type' warnings
                        // we're guaranteed the proper (pointer-sized) alignment on the input string if it was allocated via allocate_string

                        // get header
                        xml_memory_string_header* header = static_cast<xml_memory_string_header*>(static_cast<void*>(string)) - 1;

                        // deallocate
                        size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset;
                        xml_memory_page* page = reinterpret_cast<xml_memory_page*>(static_cast<void*>(reinterpret_cast<char*>(header) - page_offset));

                        // if full_size == 0 then this string occupies the whole page
                        size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size;

                        deallocate_memory(header, full_size, page);
                }

Member Data Documentation

Definition at line 443 of file pugixml.cpp.

Referenced by allocate_memory(), allocate_memory_oob(), and deallocate_memory().


The documentation for this struct was generated from the following file:

Generated on Mon Sep 15 2014 01:23:55 for QuickFIX by doxygen 1.7.6.1 written by Dimitri van Heesch, © 1997-2001