diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-03-05 12:50:29 -0800 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2015-03-05 13:02:05 -0800 | 
| commit | 23060d095447ca7c47a9c0698ec731197cebc80b (patch) | |
| tree | 9536f45a6e9bd86ad7317e48a3b8defbb356f9f8 | |
| parent | 12e137d12fe6e6492e669cfa6c333f4a8911b1b2 (diff) | |
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.
| -rw-r--r-- | src/pugixml.cpp | 18 | 
1 files 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<char*>(header) - reinterpret_cast<char*>(page) - sizeof(xml_memory_page); -			assert(page_offset >= 0 && page_offset < (1 << 16)); -			header->page_offset = static_cast<uint16_t>(page_offset); +			assert(page_offset % sizeof(void*) == 0); +			assert(page_offset >= 0 && static_cast<size_t>(page_offset) < max_encoded_offset); +			header->page_offset = static_cast<uint16_t>(static_cast<size_t>(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<uint16_t>(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<uint16_t>(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<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; +			size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size * sizeof(void*);  			deallocate_memory(header, full_size, page);  		}  | 
