Skip to content
Permalink
Browse files
[ADT] Move allocate_buffer to MemAlloc.h and out of line
There's an ABI breakage here if LLVM is compiled in C++14 without
aligned allocation and a user tries to use the result with aligned
allocation. If DenseMap or unique_function is used across that ABI
boundary it will break (PR45413). Moving it out of line is a bit of
a band-aid and LLVM doesn't really give ABI guarantees at this level,
but given the number of complaints I've received over this it still
seems worth fixing.
  • Loading branch information
d0k committed Apr 24, 2020
1 parent 0517255 commit 7aaff8fd2da2812a2b3cbc8a41af29774b10a7d6
Showing 6 changed files with 58 additions and 45 deletions.
@@ -18,6 +18,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/ReverseIteration.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
@@ -34,6 +34,7 @@

#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/type_traits.h"
#include <memory>

@@ -551,48 +551,4 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
#define LLVM_ENABLE_EXCEPTIONS 1
#endif

#ifdef __cplusplus
namespace llvm {

/// Allocate a buffer of memory with the given size and alignment.
///
/// When the compiler supports aligned operator new, this will use it to to
/// handle even over-aligned allocations.
///
/// However, this doesn't make any attempt to leverage the fancier techniques
/// like posix_memalign due to portability. It is mostly intended to allow
/// compatibility with platforms that, after aligned allocation was added, use
/// reduced default alignment.
inline void *allocate_buffer(size_t Size, size_t Alignment) {
return ::operator new(Size
#ifdef __cpp_aligned_new
,
std::align_val_t(Alignment)
#endif
);
}

/// Deallocate a buffer of memory with the given size and alignment.
///
/// If supported, this will used the sized delete operator. Also if supported,
/// this will pass the alignment to the delete operator.
///
/// The pointer must have been allocated with the corresponding new operator,
/// most likely using the above helper.
inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
::operator delete(Ptr
#ifdef __cpp_sized_deallocation
,
Size
#endif
#ifdef __cpp_aligned_new
,
std::align_val_t(Alignment)
#endif
);
}

} // End namespace llvm

#endif // __cplusplus
#endif
@@ -62,5 +62,26 @@ LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) {
return Result;
}

}
/// Allocate a buffer of memory with the given size and alignment.
///
/// When the compiler supports aligned operator new, this will use it to to
/// handle even over-aligned allocations.
///
/// However, this doesn't make any attempt to leverage the fancier techniques
/// like posix_memalign due to portability. It is mostly intended to allow
/// compatibility with platforms that, after aligned allocation was added, use
/// reduced default alignment.
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void *
allocate_buffer(size_t Size, size_t Alignment);

/// Deallocate a buffer of memory with the given size and alignment.
///
/// If supported, this will used the sized delete operator. Also if supported,
/// this will pass the alignment to the delete operator.
///
/// The pointer must have been allocated with the corresponding new operator,
/// most likely using the above helper.
void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment);

} // namespace llvm
#endif
@@ -115,6 +115,7 @@ add_llvm_component_library(LLVMSupport
LowLevelType.cpp
ManagedStatic.cpp
MathExtras.cpp
MemAlloc.cpp
MemoryBuffer.cpp
MD5.cpp
NativeFormatting.cpp
@@ -0,0 +1,33 @@
//===- MemAlloc.cpp - Memory allocation functions -------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/MemAlloc.h"

// These are out of line to have __cpp_aligned_new not affect ABI.

void *llvm::allocate_buffer(size_t Size, size_t Alignment) {
return ::operator new(Size
#ifdef __cpp_aligned_new
,
std::align_val_t(Alignment)
#endif
);
}

void llvm::deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
::operator delete(Ptr
#ifdef __cpp_sized_deallocation
,
Size
#endif
#ifdef __cpp_aligned_new
,
std::align_val_t(Alignment)
#endif
);
}

0 comments on commit 7aaff8f

Please sign in to comment.