Index: base/allocator/allocator_shim.cc |
diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc |
index fd6d741c04d3e195c00305477fbf9a26553e38dc..9d3d932d59f2e80787a62c4c2af1565bfe43a2f4 100644 |
--- a/base/allocator/allocator_shim.cc |
+++ b/base/allocator/allocator_shim.cc |
@@ -65,6 +65,7 @@ void* je_realloc(void* p, size_t s); |
void je_free(void* s); |
size_t je_msize(void* p); |
bool je_malloc_init_hard(); |
+void* je_memalign(size_t a, size_t s); |
} |
extern "C" { |
@@ -299,6 +300,66 @@ extern "C" void _heap_term() {} |
// the rest of the CRT is still usable. |
extern "C" void* _crtheap = reinterpret_cast<void*>(1); |
+// Provide support for aligned memory through Windows only _aligned_malloc(). |
+void* _aligned_malloc(size_t size, size_t alignment) { |
+ // _aligned_malloc guarantees parameter validation, so do so here. These |
+ // checks are somewhat stricter than _aligned_malloc() since we're effectively |
+ // using memalign() under the hood. |
+ DCHECK_GT(size, 0U); |
+ DCHECK_EQ(alignment & (alignment - 1), 0U); |
+ DCHECK_EQ(alignment % sizeof(void*), 0U); |
+ |
+ void* ptr; |
+ for (;;) { |
+#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING |
+ switch (allocator) { |
+ case JEMALLOC: |
+ ptr = je_memalign(alignment, size); |
+ break; |
+ case WINHEAP: |
+ case WINLFH: |
+ ptr = win_heap_memalign(alignment, size); |
+ break; |
+ case TCMALLOC: |
+ default: |
+ ptr = tc_memalign(alignment, size); |
+ break; |
+ } |
+#else |
+ // TCMalloc case. |
+ ptr = tc_memalign(alignment, size); |
+#endif |
+ if (ptr) { |
+ // Sanity check alignment. |
+ DCHECK_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U); |
+ return ptr; |
+ } |
+ |
+ if (!new_mode || !call_new_handler(true)) |
+ break; |
+ } |
+ return ptr; |
+} |
+ |
+void _aligned_free(void* p) { |
+ // Both JEMalloc and TCMalloc return pointers from memalign() that are safe to |
+ // use with free(). Pointers allocated with win_heap_memalign() MUST be freed |
+ // via win_heap_memalign_free() since the aligned pointer is not the real one. |
+#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING |
+ switch (allocator) { |
+ case JEMALLOC: |
+ je_free(p); |
+ return; |
+ case WINHEAP: |
+ case WINLFH: |
+ win_heap_memalign_free(p); |
+ return; |
+ } |
+#endif |
+ // TCMalloc case. |
+ do_free(p); |
+} |
+ |
#endif // WIN32 |
#include "generic_allocators.cc" |