From 23060d095447ca7c47a9c0698ec731197cebc80b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 5 Mar 2015 12:50:29 -0800 Subject: Use more efficient encoding for string headers Since all string allocations are pointer-aligned to avoid aligning more frequent node allocations, we can rely on that in string encoding. Encoding page offset and block size in sizeof(void*) units increases the maximum memory page size from 64k to 256k on 32-bit and 512k on 64-bit platforms. Fixes #35. --- src/pugixml.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/pugixml.cpp b/src/pugixml.cpp index fa41058..6c88d55 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -400,7 +400,9 @@ PUGI__NS_BEGIN char_t* allocate_string(size_t length) { - PUGI__STATIC_ASSERT(xml_memory_page_size <= (1 << 16)); + static const size_t max_encoded_offset = (1 << 16) * sizeof(void*); + + PUGI__STATIC_ASSERT(xml_memory_page_size <= max_encoded_offset); // allocate memory for string and header block size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); @@ -416,12 +418,14 @@ PUGI__NS_BEGIN // setup header ptrdiff_t page_offset = reinterpret_cast(header) - reinterpret_cast(page) - sizeof(xml_memory_page); - assert(page_offset >= 0 && page_offset < (1 << 16)); - header->page_offset = static_cast(page_offset); + assert(page_offset % sizeof(void*) == 0); + assert(page_offset >= 0 && static_cast(page_offset) < max_encoded_offset); + header->page_offset = static_cast(static_cast(page_offset) / sizeof(void*)); // 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(full_size < (1 << 16) ? full_size : 0); + assert(full_size % sizeof(void*) == 0); + assert(full_size < max_encoded_offset || (page->busy_size == full_size && page_offset == 0)); + header->full_size = static_cast(full_size < max_encoded_offset ? full_size / sizeof(void*) : 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 @@ -438,11 +442,11 @@ PUGI__NS_BEGIN assert(header); // deallocate - size_t page_offset = sizeof(xml_memory_page) + header->page_offset; + size_t page_offset = sizeof(xml_memory_page) + header->page_offset * sizeof(void*); xml_memory_page* page = reinterpret_cast(static_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; + size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size * sizeof(void*); deallocate_memory(header, full_size, page); } -- cgit v1.2.3