mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
This adds a new copy of LLVMSupport into the runtime. This is the final step before changing the inline namespace for the runtime support. This will allow us to avoid the ODR violations from the header definitions of LLVMSupport. LLVMSupport forked at: 22492eead218ec91d349c8c50439880fbeacf2b7 Changes made to LLVMSupport from that revision: process.inc forward declares `_beginthreadex` due to compilation issues due to custom flag handling API changes required that we alter the `Deallocate` routine to account for the alignment. This is a temporary state, meant to simplify the process. We do not use the entire LLVMSupport library and there is no value in keeping the entire library. Subsequent commits will prune the library to the needs for the runtime.
97 lines
4.0 KiB
C++
97 lines
4.0 KiB
C++
//===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the SmallVector class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include <cstdint>
|
|
using namespace llvm;
|
|
|
|
// Check that no bytes are wasted and everything is well-aligned.
|
|
namespace {
|
|
struct Struct16B {
|
|
alignas(16) void *X;
|
|
};
|
|
struct Struct32B {
|
|
alignas(32) void *X;
|
|
};
|
|
}
|
|
static_assert(sizeof(SmallVector<void *, 0>) ==
|
|
sizeof(unsigned) * 2 + sizeof(void *),
|
|
"wasted space in SmallVector size 0");
|
|
static_assert(alignof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
|
|
"wrong alignment for 16-byte aligned T");
|
|
static_assert(alignof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
|
|
"wrong alignment for 32-byte aligned T");
|
|
static_assert(sizeof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
|
|
"missing padding for 16-byte aligned T");
|
|
static_assert(sizeof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
|
|
"missing padding for 32-byte aligned T");
|
|
static_assert(sizeof(SmallVector<void *, 1>) ==
|
|
sizeof(unsigned) * 2 + sizeof(void *) * 2,
|
|
"wasted space in SmallVector size 1");
|
|
|
|
static_assert(sizeof(SmallVector<char, 0>) ==
|
|
sizeof(void *) * 2 + sizeof(void *),
|
|
"1 byte elements have word-sized type for size and capacity");
|
|
|
|
// Note: Moving this function into the header may cause performance regression.
|
|
template <class Size_T>
|
|
void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinCapacity,
|
|
size_t TSize) {
|
|
// Ensure we can fit the new capacity.
|
|
// This is only going to be applicable when the capacity is 32 bit.
|
|
if (MinCapacity > SizeTypeMax())
|
|
report_bad_alloc_error("SmallVector capacity overflow during allocation");
|
|
|
|
// 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
|
|
// default MinCapacity of 0, but the current capacity cannot be increased.
|
|
// This is only going to be applicable when the capacity is 32 bit.
|
|
if (capacity() == SizeTypeMax())
|
|
report_bad_alloc_error("SmallVector capacity unable to grow");
|
|
|
|
// 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.
|
|
size_t NewCapacity = 2 * capacity() + 1; // Always grow.
|
|
NewCapacity = std::min(std::max(NewCapacity, MinCapacity), SizeTypeMax());
|
|
|
|
void *NewElts;
|
|
if (BeginX == FirstEl) {
|
|
NewElts = safe_malloc(NewCapacity * TSize);
|
|
|
|
// Copy the elements over. No need to run dtors on PODs.
|
|
memcpy(NewElts, this->BeginX, size() * TSize);
|
|
} else {
|
|
// If this wasn't grown from the inline copy, grow the allocated space.
|
|
NewElts = safe_realloc(this->BeginX, NewCapacity * TSize);
|
|
}
|
|
|
|
this->BeginX = NewElts;
|
|
this->Capacity = NewCapacity;
|
|
}
|
|
|
|
template class llvm::SmallVectorBase<uint32_t>;
|
|
|
|
// Disable the uint64_t instantiation for 32-bit builds.
|
|
// Both uint32_t and uint64_t instantations are needed for 64-bit builds.
|
|
// This instantiation will never be used in 32-bit builds, and will cause
|
|
// warnings when sizeof(Size_T) > sizeof(size_t).
|
|
#if SIZE_MAX > UINT32_MAX
|
|
template class llvm::SmallVectorBase<uint64_t>;
|
|
|
|
// Assertions to ensure this #if stays in sync with SmallVectorSizeType.
|
|
static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint64_t),
|
|
"Expected SmallVectorBase<uint64_t> variant to be in use.");
|
|
#else
|
|
static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t),
|
|
"Expected SmallVectorBase<uint32_t> variant to be in use.");
|
|
#endif
|