xml_allocator Struct Reference
Inheritance diagram for xml_allocator:
[legend]
Collaboration diagram for xml_allocator:
[legend]

## Public Member Functions

| xml_allocator (xml_memory_page *root)
xml_memory_page * | allocate_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

## xml_allocator()

xml_allocator::xml_allocator | ( | xml_memory_page * | root | ) |

inline

Definition at line 316 of file pugixml.cpp.

: _root(root), _busy_size(root->busy_size)
{
}
xml_allocator::_root
xml_memory_page * _root
Definition: pugixml.cpp:442
xml_allocator::_busy_size
size_t _busy_size
Definition: pugixml.cpp:443
xml_memory_page::busy_size
size_t busy_size
Definition: pugixml.cpp:302

## Member Function Documentation

## allocate_memory()

void* xml_allocator::allocate_memory | ( | size_t | size,
|  | xml_memory_page *& | out_page
| ) |  |

inline

Definition at line 348 of file pugixml.cpp.

{
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;
}
xml_memory_page_size
PUGI__NS_END static PUGI__NS_BEGIN const size_t xml_memory_page_size
Definition: pugixml.cpp:261
xml_allocator::allocate_memory_oob
void * allocate_memory_oob(size_t size, xml_memory_page *&out_page)
Definition: pugixml.cpp:446
xml_memory_page::data
char data[1]
Definition: pugixml.cpp:305

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

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

## allocate_memory_oob()

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.

{
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_allocator::allocate_page
xml_memory_page * allocate_page(size_t data_size)
Definition: pugixml.cpp:320
xml_memory_page
Definition: pugixml.cpp:278
xml_memory_page::prev
xml_memory_page * prev
Definition: pugixml.cpp:299
xml_memory_page::next
xml_memory_page * next
Definition: pugixml.cpp:300

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

Referenced by allocate_memory().

## allocate_page()

xml_memory_page* xml_allocator::allocate_page | ( | size_t | data_size | ) |

inline

Definition at line 320 of file pugixml.cpp.

{
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;
}
xml_memory_page_alignment
static const uintptr_t xml_memory_page_alignment
Definition: pugixml.cpp:269
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint_msvc.h:120
xml_memory_management_function_storage::allocate
static allocation_function allocate
Definition: pugixml.cpp:163
xml_memory_page::construct
static xml_memory_page * construct(void *memory)
Definition: pugixml.cpp:279
xml_memory_page::memory
void * memory
Definition: pugixml.cpp:297
xml_memory_page::allocator
xml_allocator * allocator
Definition: pugixml.cpp:295

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

Referenced by allocate_memory_oob().

## allocate_string()

char_t* xml_allocator::allocate_string | ( | size_t | length | ) |

inline

Definition at line 396 of file pugixml.cpp.

{
// 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));
}
uint16_t
unsigned short uint16_t
Definition: stdint_msvc.h:80
xml_allocator::allocate_memory
void * allocate_memory(size_t size, xml_memory_page *&out_page)
Definition: pugixml.cpp:348
xml_memory_string_header
Definition: pugixml.cpp:309
xml_memory_string_header::page_offset
uint16_t page_offset
Definition: pugixml.cpp:310
xml_memory_string_header::full_size
uint16_t full_size
Definition: pugixml.cpp:311

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().

## deallocate_memory()

void xml_allocator::deallocate_memory | ( | void * | ptr,
|  | size_t | size,
|  | xml_memory_page * | page
| ) |  |

inline

Definition at line 361 of file pugixml.cpp.

{
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);
}
}
}
xml_allocator::deallocate_page
static void deallocate_page(xml_memory_page *page)
Definition: pugixml.cpp:341
xml_memory_page::freed_size
size_t freed_size
Definition: pugixml.cpp:303

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().

## deallocate_page()

static void xml_allocator::deallocate_page | ( | xml_memory_page * | page | ) |

inline static

Definition at line 341 of file pugixml.cpp.

{
xml_memory::deallocate(page->memory);
}
xml_memory_management_function_storage::deallocate
static deallocation_function deallocate
Definition: pugixml.cpp:164

References xml_memory_management_function_storage< T >::deallocate, and xml_memory_page::memory.

Referenced by deallocate_memory().

## deallocate_string()

void xml_allocator::deallocate_string | ( | char_t * | string | ) |

inline

Definition at line 424 of file pugixml.cpp.

{
// 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);
}
xml_allocator::deallocate_memory
void deallocate_memory(void *ptr, size_t size, xml_memory_page *page)
Definition: pugixml.cpp:361

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().

## Member Data Documentation

## _busy_size

size_t xml_allocator::_busy_size

Definition at line 443 of file pugixml.cpp.

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

## _root

xml_memory_page* xml_allocator::_root

Definition at line 442 of file pugixml.cpp.

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

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

- pugixml.cpp