mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[SmallVector] Move error handling out of line
This reduces duplication and avoids emitting ice cold code into every instance of grow().
This commit is contained in:
parent
ea26a20118
commit
c3337b0542
@ -32,9 +32,6 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#ifdef LLVM_ENABLE_EXCEPTIONS
|
|
||||||
#include <stdexcept>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -65,6 +62,13 @@ protected:
|
|||||||
/// This function will report a fatal error if it cannot increase capacity.
|
/// This function will report a fatal error if it cannot increase capacity.
|
||||||
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
|
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
|
||||||
|
|
||||||
|
/// Report that MinSize doesn't fit into this vector's size type. Throws
|
||||||
|
/// std::length_error or calls report_fatal_error.
|
||||||
|
LLVM_ATTRIBUTE_NORETURN static void report_size_overflow(size_t MinSize);
|
||||||
|
/// Report that this vector is already at maximum capacity. Throws
|
||||||
|
/// std::length_error or calls report_fatal_error.
|
||||||
|
LLVM_ATTRIBUTE_NORETURN static void report_at_maximum_capacity();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
size_t size() const { return Size; }
|
size_t size() const { return Size; }
|
||||||
size_t capacity() const { return Capacity; }
|
size_t capacity() const { return Capacity; }
|
||||||
@ -271,32 +275,16 @@ template <typename T, bool TriviallyCopyable>
|
|||||||
void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
|
void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
|
||||||
// Ensure we can fit the new capacity.
|
// Ensure we can fit the new capacity.
|
||||||
// This is only going to be applicable when the capacity is 32 bit.
|
// This is only going to be applicable when the capacity is 32 bit.
|
||||||
if (MinSize > this->SizeTypeMax()) {
|
if (MinSize > this->SizeTypeMax())
|
||||||
std::string Reason = "SmallVector unable to grow. Requested capacity (" +
|
this->report_size_overflow(MinSize);
|
||||||
std::to_string(MinSize) +
|
|
||||||
") is larger than maximum value for size type (" +
|
|
||||||
std::to_string(this->SizeTypeMax()) + ")";
|
|
||||||
#ifdef LLVM_ENABLE_EXCEPTIONS
|
|
||||||
throw std::length_error(Reason);
|
|
||||||
#else
|
|
||||||
report_fatal_error(Reason);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we can meet the guarantee of space for at least one more element.
|
// Ensure we can meet the guarantee of space for at least one more element.
|
||||||
// The above check alone will not catch the case where grow is called with a
|
// The above check alone will not catch the case where grow is called with a
|
||||||
// default MinSize of 0, but the current capacity cannot be increased.
|
// default MinSize of 0, but the current capacity cannot be increased.
|
||||||
// This is only going to be applicable when the capacity is 32 bit.
|
// This is only going to be applicable when the capacity is 32 bit.
|
||||||
if (this->capacity() == this->SizeTypeMax()) {
|
if (this->capacity() == this->SizeTypeMax())
|
||||||
std::string Reason =
|
this->report_at_maximum_capacity();
|
||||||
"SmallVector capacity unable to grow. Already at maximum size " +
|
|
||||||
std::to_string(this->SizeTypeMax());
|
|
||||||
#ifdef LLVM_ENABLE_EXCEPTIONS
|
|
||||||
throw std::length_error(Reason);
|
|
||||||
#else
|
|
||||||
report_fatal_error(Reason);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
// Always grow, even from zero.
|
// Always grow, even from zero.
|
||||||
size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2));
|
size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2));
|
||||||
NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax());
|
NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax());
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#ifdef LLVM_ENABLE_EXCEPTIONS
|
||||||
|
#include <stdexcept>
|
||||||
|
#endif
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// Check that no bytes are wasted and everything is well-aligned.
|
// Check that no bytes are wasted and everything is well-aligned.
|
||||||
@ -42,37 +45,45 @@ static_assert(sizeof(SmallVector<char, 0>) ==
|
|||||||
sizeof(void *) * 2 + sizeof(void *),
|
sizeof(void *) * 2 + sizeof(void *),
|
||||||
"1 byte elements have word-sized type for size and capacity");
|
"1 byte elements have word-sized type for size and capacity");
|
||||||
|
|
||||||
|
template <class Size_T>
|
||||||
|
void SmallVectorBase<Size_T>::report_size_overflow(size_t MinSize) {
|
||||||
|
std::string Reason = "SmallVector unable to grow. Requested capacity (" +
|
||||||
|
std::to_string(MinSize) +
|
||||||
|
") is larger than maximum value for size type (" +
|
||||||
|
std::to_string(SizeTypeMax()) + ")";
|
||||||
|
#ifdef LLVM_ENABLE_EXCEPTIONS
|
||||||
|
throw std::length_error(Reason);
|
||||||
|
#else
|
||||||
|
report_fatal_error(Reason);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Size_T> void SmallVectorBase<Size_T>::report_at_maximum_capacity() {
|
||||||
|
std::string Reason =
|
||||||
|
"SmallVector capacity unable to grow. Already at maximum size " +
|
||||||
|
std::to_string(SizeTypeMax());
|
||||||
|
#ifdef LLVM_ENABLE_EXCEPTIONS
|
||||||
|
throw std::length_error(Reason);
|
||||||
|
#else
|
||||||
|
report_fatal_error(Reason);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Note: Moving this function into the header may cause performance regression.
|
// Note: Moving this function into the header may cause performance regression.
|
||||||
template <class Size_T>
|
template <class Size_T>
|
||||||
void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
|
void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
|
||||||
size_t TSize) {
|
size_t TSize) {
|
||||||
// Ensure we can fit the new capacity.
|
// Ensure we can fit the new capacity.
|
||||||
// This is only going to be applicable when the capacity is 32 bit.
|
// This is only going to be applicable when the capacity is 32 bit.
|
||||||
if (MinSize > SizeTypeMax()) {
|
if (MinSize > SizeTypeMax())
|
||||||
std::string Reason = "SmallVector unable to grow. Requested capacity (" +
|
report_size_overflow(MinSize);
|
||||||
std::to_string(MinSize) +
|
|
||||||
") is larger than maximum value for size type (" +
|
|
||||||
std::to_string(SizeTypeMax()) + ")";
|
|
||||||
#ifdef LLVM_ENABLE_EXCEPTIONS
|
|
||||||
throw std::length_error(Reason);
|
|
||||||
#else
|
|
||||||
report_fatal_error(Reason);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure we can meet the guarantee of space for at least one more element.
|
// Ensure we can meet the guarantee of space for at least one more element.
|
||||||
// The above check alone will not catch the case where grow is called with a
|
// The above check alone will not catch the case where grow is called with a
|
||||||
// default MinSize of 0, but the current capacity cannot be increased.
|
// default MinSize of 0, but the current capacity cannot be increased.
|
||||||
// This is only going to be applicable when the capacity is 32 bit.
|
// This is only going to be applicable when the capacity is 32 bit.
|
||||||
if (capacity() == SizeTypeMax()) {
|
if (capacity() == SizeTypeMax())
|
||||||
std::string Reason =
|
report_at_maximum_capacity();
|
||||||
"SmallVector capacity unable to grow. Already at maximum size " +
|
|
||||||
std::to_string(SizeTypeMax());
|
|
||||||
#ifdef LLVM_ENABLE_EXCEPTIONS
|
|
||||||
throw std::length_error(Reason);
|
|
||||||
#endif
|
|
||||||
report_fatal_error(Reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
// In theory 2*capacity can overflow if the capacity is 64 bit, but the
|
// In theory 2*capacity can overflow if the capacity is 64 bit, but the
|
||||||
// original capacity would never be large enough for this to be a problem.
|
// original capacity would never be large enough for this to be a problem.
|
||||||
|
Loading…
Reference in New Issue
Block a user