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 }
xml_memory_page * _root
Definition pugixml.cpp:442
size_t _busy_size
Definition pugixml.cpp:443

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 }
PUGI__NS_END static PUGI__NS_BEGIN const size_t xml_memory_page_size
Definition pugixml.cpp:261
void * allocate_memory_oob(size_t size, xml_memory_page *&out_page)
Definition pugixml.cpp:446

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 }
xml_memory_page * allocate_page(size_t data_size)
Definition pugixml.cpp:320
xml_memory_page * prev
Definition pugixml.cpp:299
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.

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 }
static const uintptr_t xml_memory_page_alignment
Definition pugixml.cpp:269
_W64 unsigned int uintptr_t
static allocation_function allocate
Definition pugixml.cpp:163
static xml_memory_page * construct(void *memory)
Definition pugixml.cpp:279
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.

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 }
unsigned short uint16_t
Definition stdint_msvc.h:80
void * allocate_memory(size_t size, xml_memory_page *&out_page)
Definition pugixml.cpp:348

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 }
static void deallocate_page(xml_memory_page *page)
Definition pugixml.cpp:341
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)
inlinestatic

Definition at line 341 of file pugixml.cpp.

342 {
344 }
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.

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 }
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

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

Generated on Fri Sep 27 2024 13:45:21 for QuickFIX by doxygen 1.9.8 written by Dimitri van Heesch, © 1997-2001