Commit a1946006 authored by Kyle Nekritz's avatar Kyle Nekritz Committed by Facebook Github Bot

Properly align small_vector.

Summary:
Previously the alignment of small_vector did not take into account the alignment of the value_type. Since the value_type is stored directly internally, this is problematic.

This change does increase the sizeof small_vector in a couple cases, but I don't think the previous size was legitimate as sizeof(small_vector<value_type>) was not an even multiple of alignof(value_type).

Reviewed By: yfeldblum

Differential Revision: D7969483

fbshipit-source-id: 968c78bf03d7c0ddfe1338754f12f97be8d0f771
parent 1095ffdb
...@@ -1118,13 +1118,9 @@ class small_vector : public detail::small_vector_base< ...@@ -1118,13 +1118,9 @@ class small_vector : public detail::small_vector_base<
} }
} FOLLY_SV_PACK_ATTR; } FOLLY_SV_PACK_ATTR;
#if (FOLLY_X64 || FOLLY_PPC64)
typedef unsigned char InlineStorageDataType[sizeof(value_type) * MaxInline];
#else
typedef typename std::aligned_storage< typedef typename std::aligned_storage<
sizeof(value_type) * MaxInline, sizeof(value_type) * MaxInline,
alignof(value_type)>::type InlineStorageDataType; alignof(value_type)>::type InlineStorageDataType;
#endif
typedef typename std::conditional< typedef typename std::conditional<
sizeof(value_type) * MaxInline != 0, sizeof(value_type) * MaxInline != 0,
...@@ -1188,8 +1184,8 @@ class small_vector : public detail::small_vector_base< ...@@ -1188,8 +1184,8 @@ class small_vector : public detail::small_vector_base<
auto vp = detail::pointerFlagClear(pdata_.heap_); auto vp = detail::pointerFlagClear(pdata_.heap_);
free(vp); free(vp);
} }
} FOLLY_SV_PACK_ATTR u; } u;
} FOLLY_SV_PACK_ATTR; };
FOLLY_SV_PACK_POP FOLLY_SV_PACK_POP
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
......
...@@ -48,12 +48,22 @@ static_assert(sizeof(small_vector<int,10>) == ...@@ -48,12 +48,22 @@ static_assert(sizeof(small_vector<int,10>) ==
static_assert(sizeof(small_vector<int32_t,1,uint32_t>) == static_assert(sizeof(small_vector<int32_t,1,uint32_t>) ==
8 + 4, 8 + 4,
"small_vector<int32_t,1,uint32_t> is wrong size"); "small_vector<int32_t,1,uint32_t> is wrong size");
static_assert(sizeof(small_vector<int32_t,1,uint16_t>) ==
8 + 2, // Extra 2 bytes needed for alignment.
"small_vector<int32_t,1,uint32_t> is wrong size"); static_assert(
static_assert(sizeof(small_vector<int32_t,1,uint8_t>) == sizeof(small_vector<int32_t, 1, uint16_t>) == 8 + 2 + 2,
8 + 1, "small_vector<int32_t,1,uint32_t> is wrong size");
"small_vector<int32_t,1,uint32_t> is wrong size"); static_assert(
alignof(small_vector<int32_t, 1, uint16_t>) >= 4,
"small_vector not aligned correctly");
// Extra 3 bytes needed for alignment.
static_assert(
sizeof(small_vector<int32_t, 1, uint8_t>) == 8 + 1 + 3,
"small_vector<int32_t,1,uint32_t> is wrong size");
static_assert(
alignof(small_vector<int32_t, 1, uint8_t>) >= 4,
"small_vector not aligned correctly");
static_assert(sizeof(small_vector<int16_t,4,uint16_t>) == 10, static_assert(sizeof(small_vector<int16_t,4,uint16_t>) == 10,
"Sizeof unexpectedly large"); "Sizeof unexpectedly large");
...@@ -63,6 +73,10 @@ static_assert(sizeof(small_vector<int16_t,4,uint16_t>) == 10, ...@@ -63,6 +73,10 @@ static_assert(sizeof(small_vector<int16_t,4,uint16_t>) == 10,
static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(std::unique_ptr<int>), static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(std::unique_ptr<int>),
"std::unique_ptr<> is trivially copyable"); "std::unique_ptr<> is trivially copyable");
static_assert(
alignof(small_vector<std::aligned_storage<32, 32>::type, 4>) == 32,
"small_vector not aligned correctly");
namespace { namespace {
template <typename Key, typename Value, size_t N> template <typename Key, typename Value, size_t N>
......
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