From 9ec7db4c0cdf945eddb30a1630dcc96fd3763b1c Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Sun, 29 Aug 2010 15:18:22 +0000 Subject: Reduced allocation header for strings from 8/16 to 4 bytes git-svn-id: http://pugixml.googlecode.com/svn/trunk@653 99668b35-9821-0410-8761-19e4c4f06640 --- src/pugixml.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/pugixml.cpp b/src/pugixml.cpp index f093a8b..c9b0046 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -277,8 +277,8 @@ namespace pugi struct xml_memory_string_header { - xml_memory_page* page; - size_t full_size; + uint16_t page_offset; // offset from page->data + uint16_t full_size; // 0 if string occupies whole page }; struct xml_allocator @@ -364,11 +364,11 @@ namespace pugi char_t* allocate_string(size_t length) { - // get actual size, rounded up to pointer alignment boundary - size_t size = ((length * sizeof(char_t)) + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1); - // allocate memory for string and header block - size_t full_size = sizeof(xml_memory_string_header) + size; + 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(allocate_memory(full_size, page)); @@ -376,8 +376,14 @@ namespace pugi if (!header) return 0; // setup header - header->page = page; - header->full_size = full_size; + ptrdiff_t page_offset = reinterpret_cast(header) - page->data; + + assert(page_offset >= 0 && page_offset < (1 << 16)); + header->page_offset = static_cast(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 = full_size < (1 << 16) ? static_cast(full_size) : 0; return reinterpret_cast(header + 1); } @@ -388,7 +394,13 @@ namespace pugi xml_memory_string_header* header = reinterpret_cast(string) - 1; // deallocate - deallocate_memory(header, header->full_size, header->page); + size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset; + xml_memory_page* page = reinterpret_cast(reinterpret_cast(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_memory_page* _root; -- cgit v1.2.3