From 7239dd61b90b52644cc71bf26e74770e129c6639 Mon Sep 17 00:00:00 2001 From: Mike Ash Date: Fri, 2 Feb 2018 17:13:34 -0500 Subject: [PATCH 1/2] [Runtime] Fix swift_slowAlloc to respect its alignMask parameter. Instead of calling malloc, call AlignedAlloc. That calls posix_memalign on platforms where it's available. The man page cautions to use it judiciously, but Apple OSes and Linux implement it to call through to malloc when the alignment is suitable. Presumably/hopefully other OSes do the same. rdar://problem/22975669 --- stdlib/public/runtime/Heap.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index 90bd56a3de5ad..d3a249d9a30b4 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -23,12 +23,11 @@ using namespace swift; void *swift::swift_slowAlloc(size_t size, size_t alignMask) { - // FIXME: use posix_memalign if alignMask is larger than the system guarantee. - void *p = malloc(size); + void *p = AlignedAlloc(size, alignMask + 1); if (!p) swift::crash("Could not allocate memory."); return p; } void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) { - free(ptr); + AlignedFree(ptr); } From 7b091bf91d08a242315f039f89c6758f006fa687 Mon Sep 17 00:00:00 2001 From: Mike Ash Date: Wed, 7 Feb 2018 13:32:47 -0500 Subject: [PATCH 2/2] [Runtime] Have swift_slowAlloc malloc directly if the alignMask is sufficiently small. rdar://problem/22975669 --- stdlib/public/runtime/Heap.cpp | 41 ++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index d3a249d9a30b4..8f7258a2f2c2e 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -18,16 +18,53 @@ #include "swift/Runtime/Heap.h" #include "Private.h" #include "swift/Runtime/Debug.h" +#include #include using namespace swift; +#if defined(__APPLE__) +// Apple malloc is always 16-byte aligned. +# define MALLOC_ALIGN_MASK 15 + +#elif defined(__linux__) +// Linux malloc is 16-byte aligned on 64-bit, and 8-byte aligned on 32-bit. +# if defined(__LP64) +# define MALLOC_ALIGN_MASK 15 +# else +# define MALLOC_ALIGN_MASK 7 +# endif + +#elif defined(_WIN64) +// Windows malloc is 16-byte aligned on 64-bit and 8-byte aligned on 32-bit. +# define MALLOC_ALIGN_MASK 15 +#elif defined(_WIN32) +# define MALLOC_ALIGN_MASK 7 + +#else +// Unknown alignment, but the standard requires alignment suitable for the largest +// standard types. +# define MALLOC_ALIGN_MASK std::max(alignof(void *), alignof(double)) + +#endif + + + void *swift::swift_slowAlloc(size_t size, size_t alignMask) { - void *p = AlignedAlloc(size, alignMask + 1); + void *p; + if (alignMask <= MALLOC_ALIGN_MASK) { + p = malloc(size); + } else { + p = AlignedAlloc(size, alignMask + 1); + } if (!p) swift::crash("Could not allocate memory."); return p; } void swift::swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask) { - AlignedFree(ptr); + if (alignMask <= MALLOC_ALIGN_MASK) { + free(ptr); + } else { + AlignedFree(ptr); + } }