Commit 0d92b69f authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Let AlignedSysAllocator consider the type's alignment

Summary: [Folly] Let AlignedSysAllocator consider the natural or specified alignment of the type for which memory is being allocated, rather than only considering a constant or fixed alignment.

Reviewed By: nbronson

Differential Revision: D19174932

fbshipit-source-id: e8ed0fbaf30d285cadd061d0fe5d69fcbb16f9e2
parent 4762e080
......@@ -403,8 +403,8 @@ class DefaultAlign {
assert(!(align_ < sizeof(void*)) && bool("bad align: too small"));
assert(!(align_ & (align_ - 1)) && bool("bad align: not power-of-two"));
}
std::size_t operator()() const noexcept {
return align_;
std::size_t operator()(std::size_t align) const noexcept {
return align_ < align ? align : align_;
}
friend bool operator==(Self const& a, Self const& b) noexcept {
......@@ -423,8 +423,8 @@ class FixedAlign {
using Self = FixedAlign<Align>;
public:
constexpr std::size_t operator()() const noexcept {
return Align;
constexpr std::size_t operator()(std::size_t align) const noexcept {
return Align < align ? align : Align;
}
friend bool operator==(Self const&, Self const&) noexcept {
......@@ -442,7 +442,8 @@ class FixedAlign {
* aligned_free.
*
* Accepts a policy parameter for providing the alignment, which must:
* * be invocable as std::size_t() noexcept, returning the alignment
* * be invocable as std::size_t(std::size_t) noexcept
* * taking the type alignment and returning the allocation alignment
* * be noexcept-copy-constructible
* * have noexcept operator==
* * have noexcept operator!=
......@@ -464,7 +465,9 @@ class AlignedSysAllocator : private Align {
public:
static_assert(std::is_nothrow_copy_constructible<Align>::value, "");
static_assert(is_nothrow_invocable_r<std::size_t, Align>::value, "");
static_assert(
is_nothrow_invocable_r<std::size_t, Align, std::size_t>::value,
"");
using value_type = T;
......@@ -481,7 +484,8 @@ class AlignedSysAllocator : private Align {
T* allocate(size_t count) {
using lifted = typename detail::lift_void_to_char<T>::type;
auto const p = aligned_malloc(sizeof(lifted) * count, align()());
auto const a = align()(alignof(lifted));
auto const p = aligned_malloc(sizeof(lifted) * count, a);
if (!p) {
if (FOLLY_UNLIKELY(errno != ENOMEM)) {
std::terminate();
......
......@@ -138,6 +138,18 @@ TEST(AlignedSysAllocator, allocate_unique_fixed) {
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % 1024);
}
TEST(AlignedSysAllocator, undersized_fixed) {
constexpr auto align = has_extended_alignment ? 1024 : max_align_v;
struct alignas(align) Big {
float value;
};
using Alloc = AlignedSysAllocator<Big, FixedAlign<sizeof(void*)>>;
Alloc const alloc;
auto ptr = allocate_unique<Big>(alloc, Big{3.});
EXPECT_EQ(3., ptr->value);
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % align);
}
TEST(AlignedSysAllocator, vector_fixed) {
using Alloc = AlignedSysAllocator<float, FixedAlign<1024>>;
Alloc const alloc;
......@@ -174,6 +186,18 @@ TEST(AlignedSysAllocator, allocate_unique_default) {
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % 1024);
}
TEST(AlignedSysAllocator, undersized_default) {
constexpr auto align = has_extended_alignment ? 1024 : max_align_v;
struct alignas(align) Big {
float value;
};
using Alloc = AlignedSysAllocator<Big, DefaultAlign>;
Alloc const alloc(sizeof(void*));
auto ptr = allocate_unique<Big>(alloc, Big{3.});
EXPECT_EQ(3., ptr->value);
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % align);
}
TEST(AlignedSysAllocator, vector_default) {
using Alloc = AlignedSysAllocator<float>;
Alloc const alloc(1024);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment