|
@@ -425,6 +425,37 @@ void* malloc(size_t size)
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
|
+// This is a Microsoft extension, and is not found on other Unix-like systems.
|
|
|
+// FIXME: Implement aligned_alloc() instead
|
|
|
+//
|
|
|
+// This is used in libc++ to implement C++17 aligned new/delete.
|
|
|
+//
|
|
|
+// Both Unix-y alternatives to _aligned_malloc(), the C11 aligned_alloc() and
|
|
|
+// posix_memalign() say that the resulting pointer can be deallocated with
|
|
|
+// regular free(), which means that the allocator has to keep track of the
|
|
|
+// requested alignments. By contrast, _aligned_malloc() is paired with
|
|
|
+// _aligned_free(), so it can be easily implemented on top of malloc().
|
|
|
+void* _aligned_malloc(size_t size, size_t alignment)
|
|
|
+{
|
|
|
+ if (__builtin_popcount(alignment) != 1) {
|
|
|
+ errno = EINVAL;
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+ alignment = max(alignment, sizeof(void*));
|
|
|
+ if (Checked<size_t>::addition_would_overflow(size, alignment)) {
|
|
|
+ errno = ENOMEM;
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+ void* ptr = malloc(size + alignment);
|
|
|
+ if (!ptr) {
|
|
|
+ errno = ENOMEM;
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+ auto aligned_ptr = (void*)(((FlatPtr)ptr + alignment) & ~(alignment - 1));
|
|
|
+ ((void**)aligned_ptr)[-1] = ptr;
|
|
|
+ return aligned_ptr;
|
|
|
+}
|
|
|
+
|
|
|
void free(void* ptr)
|
|
|
{
|
|
|
MemoryAuditingSuppressor suppressor;
|
|
@@ -434,6 +465,12 @@ void free(void* ptr)
|
|
|
free_impl(ptr);
|
|
|
}
|
|
|
|
|
|
+void _aligned_free(void* ptr)
|
|
|
+{
|
|
|
+ if (ptr)
|
|
|
+ free(((void**)ptr)[-1]);
|
|
|
+}
|
|
|
+
|
|
|
void* calloc(size_t count, size_t size)
|
|
|
{
|
|
|
MemoryAuditingSuppressor suppressor;
|