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

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

◆ xml_allocator()

xml_allocator::xml_allocator ( xml_memory_page root)
inline

Definition at line 316 of file pugixml.cpp.

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

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.

349  {
350  if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page);
351 
352  void* buf = _root->data + _busy_size;
353 
354  _busy_size += size;
355 
356  out_page = _root;
357 
358  return buf;
359  }

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.

447  {
448  const size_t large_allocation_threshold = xml_memory_page_size / 4;
449 
450  xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size);
451  out_page = page;
452 
453  if (!page) return 0;
454 
455  if (size <= large_allocation_threshold)
456  {
458 
459  // insert page at the end of linked list
460  page->prev = _root;
461  _root->next = page;
462  _root = page;
463 
464  _busy_size = size;
465  }
466  else
467  {
468  // insert page before the end of linked list, so that it is deleted as soon as possible
469  // the last page is not deleted even if it's empty (see deallocate_memory)
470  assert(_root->prev);
471 
472  page->prev = _root->prev;
473  page->next = _root;
474 
475  _root->prev->next = page;
476  _root->prev = page;
477  }
478 
479  // allocate inside page
480  page->busy_size = size;
481 
482  return page->data;
483  }

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.

321  {
322  size_t size = offsetof(xml_memory_page, data) + data_size;
323 
324  // allocate block with some alignment, leaving memory for worst-case padding
325  void* memory = xml_memory::allocate(size + xml_memory_page_alignment);
326  if (!memory) return 0;
327 
328  // align upwards to page boundary
329  void* page_memory = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1));
330 
331  // prepare page structure
332  xml_memory_page* page = xml_memory_page::construct(page_memory);
333  assert(page);
334 
335  page->memory = memory;
336  page->allocator = _root->allocator;
337 
338  return page;
339  }

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.

397  {
398  // allocate memory for string and header block
399  size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t);
400 
401  // round size up to pointer alignment boundary
402  size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1);
403 
404  xml_memory_page* page;
405  xml_memory_string_header* header = static_cast<xml_memory_string_header*>(allocate_memory(full_size, page));
406 
407  if (!header) return 0;
408 
409  // setup header
410  ptrdiff_t page_offset = reinterpret_cast<char*>(header) - page->data;
411 
412  assert(page_offset >= 0 && page_offset < (1 << 16));
413  header->page_offset = static_cast<uint16_t>(page_offset);
414 
415  // full_size == 0 for large strings that occupy the whole page
416  assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0));
417  header->full_size = static_cast<uint16_t>(full_size < (1 << 16) ? full_size : 0);
418 
419  // round-trip through void* to avoid 'cast increases required alignment of target type' warning
420  // header is guaranteed a pointer-sized alignment, which should be enough for char_t
421  return static_cast<char_t*>(static_cast<void*>(header + 1));
422  }

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.

362  {
363  if (page == _root) page->busy_size = _busy_size;
364 
365  assert(ptr >= page->data && ptr < page->data + page->busy_size);
366  (void)!ptr;
367 
368  page->freed_size += size;
369  assert(page->freed_size <= page->busy_size);
370 
371  if (page->freed_size == page->busy_size)
372  {
373  if (page->next == 0)
374  {
375  assert(_root == page);
376 
377  // top page freed, just reset sizes
378  page->busy_size = page->freed_size = 0;
379  _busy_size = 0;
380  }
381  else
382  {
383  assert(_root != page);
384  assert(page->prev);
385 
386  // remove from the list
387  page->prev->next = page->next;
388  page->next->prev = page->prev;
389 
390  // deallocate
391  deallocate_page(page);
392  }
393  }
394  }

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)
inlinestatic

Definition at line 341 of file pugixml.cpp.

342  {
344  }

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.

425  {
426  // this function casts pointers through void* to avoid 'cast increases required alignment of target type' warnings
427  // we're guaranteed the proper (pointer-sized) alignment on the input string if it was allocated via allocate_string
428 
429  // get header
430  xml_memory_string_header* header = static_cast<xml_memory_string_header*>(static_cast<void*>(string)) - 1;
431 
432  // deallocate
433  size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset;
434  xml_memory_page* page = reinterpret_cast<xml_memory_page*>(static_cast<void*>(reinterpret_cast<char*>(header) - page_offset));
435 
436  // if full_size == 0 then this string occupies the whole page
437  size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size;
438 
439  deallocate_memory(header, full_size, page);
440  }

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

The documentation for this struct was generated from the following file:
xml_allocator::_root
xml_memory_page * _root
Definition: pugixml.cpp:442
uint16_t
unsigned short uint16_t
Definition: stdint_msvc.h:80
xml_memory_page::busy_size
size_t busy_size
Definition: pugixml.cpp:302
xml_memory_string_header
Definition: pugixml.cpp:308
xml_memory_page::next
xml_memory_page * next
Definition: pugixml.cpp:300
xml_allocator::_busy_size
size_t _busy_size
Definition: pugixml.cpp:443
xml_allocator::deallocate_memory
void deallocate_memory(void *ptr, size_t size, xml_memory_page *page)
Definition: pugixml.cpp:361
xml_memory_page::memory
void * memory
Definition: pugixml.cpp:297
xml_memory_page_alignment
static const uintptr_t xml_memory_page_alignment
Definition: pugixml.cpp:269
xml_memory_page
Definition: pugixml.cpp:277
xml_memory_management_function_storage::deallocate
static deallocation_function deallocate
Definition: pugixml.cpp:164
xml_allocator::deallocate_page
static void deallocate_page(xml_memory_page *page)
Definition: pugixml.cpp:341
xml_memory_string_header::page_offset
uint16_t page_offset
Definition: pugixml.cpp:310
xml_memory_page::allocator
xml_allocator * allocator
Definition: pugixml.cpp:295
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_size
PUGI__NS_END static const PUGI__NS_BEGIN 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_string_header::full_size
uint16_t full_size
Definition: pugixml.cpp:311
xml_allocator::allocate_memory
void * allocate_memory(size_t size, xml_memory_page *&out_page)
Definition: pugixml.cpp:348
xml_memory_page::data
char data[1]
Definition: pugixml.cpp:305
xml_allocator::allocate_page
xml_memory_page * allocate_page(size_t data_size)
Definition: pugixml.cpp:320
xml_memory_page::prev
xml_memory_page * prev
Definition: pugixml.cpp:299
xml_memory_page::construct
static xml_memory_page * construct(void *memory)
Definition: pugixml.cpp:279
xml_memory_page::freed_size
size_t freed_size
Definition: pugixml.cpp:303

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001