summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/pugixml/tests/allocator.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/pugixml/tests/allocator.cpp')
-rw-r--r--3rdparty/pugixml/tests/allocator.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/3rdparty/pugixml/tests/allocator.cpp b/3rdparty/pugixml/tests/allocator.cpp
new file mode 100644
index 00000000000..c3ade48a980
--- /dev/null
+++ b/3rdparty/pugixml/tests/allocator.cpp
@@ -0,0 +1,171 @@
+#include "allocator.hpp"
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+// Address sanitizer
+#if defined(__has_feature)
+# define ADDRESS_SANITIZER __has_feature(address_sanitizer)
+#else
+# define ADDRESS_SANITIZER defined(__SANITIZE_ADDRESS__)
+#endif
+
+// Low-level allocation functions
+#if defined(_WIN32) || defined(_WIN64)
+# ifdef __MWERKS__
+# pragma ANSI_strict off // disable ANSI strictness to include windows.h
+# pragma cpp_extensions on // enable some extensions to include windows.h
+# endif
+
+# if defined(_MSC_VER)
+# pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
+# endif
+
+# ifdef _XBOX_VER
+# define NOD3D
+# include <xtl.h>
+# else
+# include <windows.h>
+# endif
+
+namespace
+{
+ const size_t page_size = 4096;
+
+ size_t align_to_page(size_t value)
+ {
+ return (value + page_size - 1) & ~(page_size - 1);
+ }
+
+ void* allocate_page_aligned(size_t size)
+ {
+ // We can't use VirtualAlloc because it has 64Kb granularity so we run out of address space quickly
+ // We can't use malloc because of occasional problems with CW on CRT termination
+ static HANDLE heap = HeapCreate(0, 0, 0);
+
+ void* result = HeapAlloc(heap, 0, size + page_size);
+
+ return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
+ }
+
+ void* allocate(size_t size)
+ {
+ size_t aligned_size = align_to_page(size);
+
+ void* ptr = allocate_page_aligned(aligned_size + page_size);
+ if (!ptr) return 0;
+
+ char* end = static_cast<char*>(ptr) + aligned_size;
+
+ DWORD old_flags;
+ VirtualProtect(end, page_size, PAGE_NOACCESS, &old_flags);
+
+ return end - size;
+ }
+
+ void deallocate(void* ptr, size_t size)
+ {
+ size_t aligned_size = align_to_page(size);
+
+ void* rptr = static_cast<char*>(ptr) + size - aligned_size;
+
+ DWORD old_flags;
+ VirtualProtect(rptr, aligned_size + page_size, PAGE_NOACCESS, &old_flags);
+ }
+}
+#elif (defined(__APPLE__) || defined(__linux__)) && (defined(__i386) || defined(__x86_64)) && !ADDRESS_SANITIZER
+# include <sys/mman.h>
+
+namespace
+{
+ const size_t page_size = 4096;
+
+ size_t align_to_page(size_t value)
+ {
+ return (value + page_size - 1) & ~(page_size - 1);
+ }
+
+ void* allocate_page_aligned(size_t size)
+ {
+ void* result = malloc(size + page_size);
+
+ return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
+ }
+
+ void* allocate(size_t size)
+ {
+ size_t aligned_size = align_to_page(size);
+
+ void* ptr = allocate_page_aligned(aligned_size + page_size);
+ if (!ptr) return 0;
+
+ char* end = static_cast<char*>(ptr) + aligned_size;
+
+ int res = mprotect(end, page_size, PROT_NONE);
+ assert(res == 0);
+ (void)!res;
+
+ return end - size;
+ }
+
+ void deallocate(void* ptr, size_t size)
+ {
+ size_t aligned_size = align_to_page(size);
+
+ void* rptr = static_cast<char*>(ptr) + size - aligned_size;
+
+ int res = mprotect(rptr, aligned_size + page_size, PROT_NONE);
+ assert(res == 0);
+ (void)!res;
+ }
+}
+#else
+namespace
+{
+ void* allocate(size_t size)
+ {
+ return malloc(size);
+ }
+
+ void deallocate(void* ptr, size_t size)
+ {
+ (void)size;
+
+ free(ptr);
+ }
+}
+#endif
+
+// High-level allocation functions
+const size_t memory_alignment = sizeof(double) > sizeof(void*) ? sizeof(double) : sizeof(void*);
+
+void* memory_allocate(size_t size)
+{
+ void* result = allocate(size + memory_alignment);
+ if (!result) return 0;
+
+ memcpy(result, &size, sizeof(size_t));
+
+ return static_cast<char*>(result) + memory_alignment;
+}
+
+size_t memory_size(void* ptr)
+{
+ assert(ptr);
+
+ size_t result;
+ memcpy(&result, static_cast<char*>(ptr) - memory_alignment, sizeof(size_t));
+
+ return result;
+}
+
+void memory_deallocate(void* ptr)
+{
+ if (!ptr) return;
+
+ size_t size = memory_size(ptr);
+
+ deallocate(static_cast<char*>(ptr) - memory_alignment, size + memory_alignment);
+}
+