diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -892,6 +892,21 @@ /// well-defined. template struct alignas(T) SmallVectorStorage {}; +// Parameter controlling the default small size for SmallVector. +// +// We guarantee that a default-small-sized SmallVector has sizeof no more than +// kDefaultSmallSizeHeaderSizeMultiplier times bigger than just the header. +// +// This prevents unexpected variation based on `sizeof(value_type)`. +constexpr size_t kDefaultSmallSizeHeaderSizeMultiplier = 3; +template constexpr size_t calculateDefaultSmallSize() { + // Discount the size of the header itself when calculating the maximum inline + // bytes, so subtract one from the multiplier. + size_t MaxInlineBytes = (kDefaultSmallSizeHeaderSizeMultiplier - 1) * + sizeof(SmallVectorImpl); + return MaxInlineBytes / sizeof(ElementTy); +} + /// This is a 'vector' (really, a variable-sized array), optimized /// for the case when the array is small. It contains some number of elements /// in-place, which allows it to avoid heap allocation when the actual number of @@ -900,7 +915,7 @@ /// /// Note that this does not attempt to be exception safe. /// -template +template ()> class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl, SmallVectorStorage { public: diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp @@ -1029,4 +1029,29 @@ EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2})); } +struct BigElementType { + char Arr[10000] = {0}; +}; +typedef ::testing::Types, SmallVector, + SmallVector, SmallVector, + SmallVector, SmallVector> + SmallVectorDefaultSmallSizeTestTypes; +// Test fixture class +template +class SmallVectorDefaultSmallSizeTest : public testing::Test { +protected: + VectorT theVector; +}; + +TYPED_TEST_CASE(SmallVectorDefaultSmallSizeTest, + SmallVectorDefaultSmallSizeTestTypes); + +TYPED_TEST(SmallVectorDefaultSmallSizeTest, DefaultSmallSize) { + using ValueT = typename decltype(this->theVector)::value_type; + static_assert(sizeof(this->theVector) <= + kDefaultSmallSizeHeaderSizeMultiplier * + sizeof(SmallVectorImpl), + ""); +} + } // end namespace