Commit 9b2b633c authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Move max_align_v and max_align_t to folly/lang/Align.h

Summary:
[Folly] Move `max_align_v` and `max_align_t` to `folly/lang/Align.h`.

And drop the macro `FOLLY_ALIGNED_MAX` - just use `alignas(max_align_v)` instead.

Reviewed By: Orvid

Differential Revision: D6554677

fbshipit-source-id: cacb335b141623506a41e95e0740613374279c6f
parent 0a1444e7
......@@ -20,6 +20,7 @@
#include <folly/Portability.h>
#include <folly/concurrency/CacheLocality.h>
#include <folly/lang/Align.h>
namespace folly {
......@@ -33,7 +34,7 @@ namespace folly {
template <typename T>
class CachelinePadded {
static_assert(
alignof(T) <= folly::max_align_v,
alignof(T) <= max_align_v,
"CachelinePadded does not support over-aligned types.");
public:
......
......@@ -324,6 +324,7 @@ nobase_follyinclude_HEADERS = \
io/async/test/UndelayedDestruction.h \
io/async/test/Util.h \
json.h \
lang/Align.h \
lang/Assume.h \
lang/Bits.h \
lang/ColdClass.h \
......
......@@ -46,6 +46,7 @@
#include <folly/Portability.h>
#include <folly/detail/Sleeper.h>
#include <folly/lang/Align.h>
namespace folly {
......@@ -118,7 +119,7 @@ static_assert(
#define FOLLY_CACHE_LINE_SIZE 64
template <class T, size_t N>
struct FOLLY_ALIGNED_MAX SpinLockArray {
struct alignas(max_align_v) SpinLockArray {
T& operator[](size_t i) {
return data_[i].lock;
}
......@@ -140,9 +141,8 @@ struct FOLLY_ALIGNED_MAX SpinLockArray {
// Check if T can theoretically cross a cache line.
static_assert(
folly::max_align_v > 0 &&
FOLLY_CACHE_LINE_SIZE % folly::max_align_v == 0 &&
sizeof(T) <= folly::max_align_v,
max_align_v > 0 && FOLLY_CACHE_LINE_SIZE % max_align_v == 0 &&
sizeof(T) <= max_align_v,
"T can cross cache line boundaries");
char padding_[FOLLY_CACHE_LINE_SIZE];
......
......@@ -17,7 +17,6 @@
#pragma once
#include <cstddef>
#include <type_traits>
#include <folly/portability/Config.h>
......@@ -30,73 +29,6 @@ constexpr bool kHasUnalignedAccess = true;
#else
constexpr bool kHasUnalignedAccess = false;
#endif
namespace portability_detail {
template <typename I, I A, I B>
using integral_max = std::integral_constant<I, (A < B) ? B : A>;
template <typename I, I A, I... Bs>
struct integral_sequence_max
: integral_max<I, A, integral_sequence_max<I, Bs...>::value> {};
template <typename I, I A>
struct integral_sequence_max<I, A> : std::integral_constant<I, A> {};
template <typename... Ts>
using max_alignment = integral_sequence_max<size_t, alignof(Ts)...>;
using max_basic_alignment = max_alignment<
std::max_align_t,
long double,
double,
float,
long long int,
long int,
int,
short int,
bool,
char,
char16_t,
char32_t,
wchar_t,
std::nullptr_t>;
} // namespace portability_detail
constexpr size_t max_align_v = portability_detail::max_basic_alignment::value;
// max_align_t is a type which is aligned at least as strictly as the
// most-aligned basic type (see the specification of std::max_align_t). This
// implementation exists because 32-bit iOS platforms have a broken
// std::max_align_t (see below).
//
// You should refer to this as `::folly::max_align_t` in portable code, even if
// you have `using namespace folly;` because C11 defines a global namespace
// `max_align_t` type.
//
// To be certain, we consider every non-void fundamental type specified by the
// standard. On most platforms `long double` would be enough, but iOS 32-bit
// has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
// `long double`.
//
// So far we've covered locals and other non-allocated storage, but we also need
// confidence that allocated storage from `malloc`, `new`, etc will also be
// suitable for objects with this alignment reuirement.
//
// Apple document that their implementation of malloc will issue 16-byte
// granularity chunks for small allocations (large allocations are page-size
// granularity and page-aligned). We think that allocated storage will be
// suitable for these objects based on the following assumptions:
//
// 1. 16-byte granularity also means 16-byte aligned.
// 2. `new` and other allocators follow the `malloc` rules.
//
// We also have some anecdotal evidence: we don't see lots of misaligned-storage
// crashes on 32-bit iOS apps that use `double`.
//
// Apple's allocation reference: http://bit.ly/malloc-small
struct alignas(max_align_v) max_align_t {};
} // namespace folly
// compiler specific attribute translation
......@@ -109,7 +41,6 @@ struct alignas(max_align_v) max_align_t {};
#else
# error Cannot define FOLLY_ALIGNED on this platform
#endif
#define FOLLY_ALIGNED_MAX FOLLY_ALIGNED(::folly::max_align_v)
// NOTE: this will only do checking in msvc with versions that support /analyze
#if _MSC_VER
......
......@@ -256,9 +256,8 @@ void* SimpleAllocator::allocateHard() {
// Install a pointer to ourselves as the allocator.
*reinterpret_cast<SimpleAllocator**>(mem_) = this;
static_assert(
folly::max_align_v >= sizeof(SimpleAllocator*), "alignment too small");
mem_ += std::min(sz_, folly::max_align_v);
static_assert(max_align_v >= sizeof(SimpleAllocator*), "alignment too small");
mem_ += std::min(sz_, max_align_v);
// New allocation.
auto mem = mem_;
......
......@@ -33,6 +33,7 @@
#include <folly/Memory.h>
#include <folly/Portability.h>
#include <folly/hash/Hash.h>
#include <folly/lang/Align.h>
#include <folly/portability/BitsFunctexcept.h>
#include <folly/portability/Memory.h>
#include <folly/system/ThreadId.h>
......@@ -390,7 +391,7 @@ class SimpleAllocator {
if (intptr_t(mem_) % 128 == 0) {
// Avoid allocating pointers that may look like malloc
// pointers.
mem_ += std::min(sz_, folly::max_align_v);
mem_ += std::min(sz_, max_align_v);
}
if (mem_ && (mem_ + sz_ <= end_)) {
auto mem = mem_;
......
......@@ -39,9 +39,8 @@ void set_default_resource(memory_resource* mr) {
memory_resource* new_delete_resource() {
class new_delete : public memory_resource {
public:
void* allocate(
const size_t bytes,
const size_t alignment = folly::max_align_v) override {
void* allocate(const size_t bytes, const size_t alignment = max_align_v)
override {
(void)alignment;
void* p = static_cast<void*>(new char[bytes]);
DEBUG_PRINT(this << " " << p << " " << bytes);
......@@ -50,7 +49,7 @@ memory_resource* new_delete_resource() {
void deallocate(
void* p,
const size_t bytes,
const size_t alignment = folly::max_align_v) override {
const size_t alignment = max_align_v) override {
(void)alignment;
(void)bytes;
DEBUG_PRINT(p << " " << bytes);
......
......@@ -23,9 +23,11 @@
/// hazptr prototype.
////////////////////////////////////////////////////////////////////////////////
#include <folly/Portability.h>
#include <memory>
#include <folly/Portability.h>
#include <folly/lang/Align.h>
namespace folly {
namespace hazptr {
......@@ -34,11 +36,11 @@ class memory_resource {
virtual ~memory_resource() = default;
virtual void* allocate(
const size_t bytes,
const size_t alignment = folly::max_align_v) = 0;
const size_t alignment = max_align_v) = 0;
virtual void deallocate(
void* p,
const size_t bytes,
const size_t alignment = folly::max_align_v) = 0;
const size_t alignment = max_align_v) = 0;
};
memory_resource* get_default_resource();
......
......@@ -31,6 +31,7 @@
#include <folly/ScopeGuard.h>
#include <folly/hash/SpookyHashV2.h>
#include <folly/io/Cursor.h>
#include <folly/lang/Align.h>
#include <folly/memory/Malloc.h>
using std::unique_ptr;
......
/*
* Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cstddef>
namespace folly {
namespace detail {
union max_align_ {
std::max_align_t mat;
long double ld;
double d;
float f;
long long int lli;
long int li;
int i;
short int si;
bool b;
char c;
char16_t c16;
char32_t c32;
wchar_t wc;
std::nullptr_t n;
};
} // namespace detail
// max_align_v is the alignment of max_align_t.
//
// max_align_t is a type which is aligned at least as strictly as the
// most-aligned basic type (see the specification of std::max_align_t). This
// implementation exists because 32-bit iOS platforms have a broken
// std::max_align_t (see below).
//
// You should refer to this as `::folly::max_align_t` in portable code, even if
// you have `using namespace folly;` because C11 defines a global namespace
// `max_align_t` type.
//
// To be certain, we consider every non-void fundamental type specified by the
// standard. On most platforms `long double` would be enough, but iOS 32-bit
// has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
// `long double`.
//
// So far we've covered locals and other non-allocated storage, but we also need
// confidence that allocated storage from `malloc`, `new`, etc will also be
// suitable for objects with this alignment requirement.
//
// Apple document that their implementation of malloc will issue 16-byte
// granularity chunks for small allocations (large allocations are page-size
// granularity and page-aligned). We think that allocated storage will be
// suitable for these objects based on the following assumptions:
//
// 1. 16-byte granularity also means 16-byte aligned.
// 2. `new` and other allocators follow the `malloc` rules.
//
// We also have some anecdotal evidence: we don't see lots of misaligned-storage
// crashes on 32-bit iOS apps that use `double`.
//
// Apple's allocation reference: http://bit.ly/malloc-small
constexpr std::size_t max_align_v = alignof(detail::max_align_);
struct alignas(max_align_v) max_align_t {};
} // namespace folly
......@@ -27,6 +27,7 @@
#include <folly/Conv.h>
#include <folly/Likely.h>
#include <folly/Memory.h>
#include <folly/lang/Align.h>
#include <folly/memory/Malloc.h>
namespace folly {
......@@ -133,7 +134,7 @@ class Arena {
typedef boost::intrusive::slist_member_hook<
boost::intrusive::tag<Arena>> BlockLink;
struct FOLLY_ALIGNED_MAX Block {
struct alignas(max_align_v) Block {
BlockLink link;
// Allocate a block with at least size bytes of storage.
......
......@@ -29,6 +29,7 @@
#include <folly/Benchmark.h>
#include <folly/Memory.h>
#include <folly/Range.h>
#include <folly/lang/Align.h>
#include <folly/portability/GTest.h>
using namespace folly;
......@@ -92,7 +93,7 @@ void ArenaTester::merge(ArenaTester&& other) {
} // namespace
TEST(ThreadCachedArena, BlockSize) {
static const size_t alignment = folly::max_align_v;
static const size_t alignment = max_align_v;
static const size_t requestedBlockSize = 64;
ThreadCachedArena arena(requestedBlockSize);
......
......@@ -18,6 +18,7 @@
#include <type_traits>
#include <folly/lang/Align.h>
#include <folly/portability/GTest.h>
using folly::CachelinePadded;
......
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