1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[Allocator] Make Deallocate() pass alignment and make it use (de)allocate_buffer

This lets it use sized deallocation and make more efficient alignment
decisions. Also adjust BumpPtrAllocator to always allocate at
alignof(std::max_align_t).
This commit is contained in:
Benjamin Kramer 2020-05-02 15:59:10 +02:00
parent 53f483044b
commit 497a019107
6 changed files with 27 additions and 34 deletions

View File

@ -125,7 +125,8 @@ public:
// Free memory referenced by the item.
size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1;
this->~StringMapEntry();
allocator.Deallocate(static_cast<void *>(this), AllocSize);
allocator.Deallocate(static_cast<void *>(this), AllocSize,
alignof(StringMapEntry));
}
};

View File

@ -170,7 +170,7 @@ public:
// If Size is really big, allocate a separate slab for it.
size_t PaddedSize = SizeToAllocate + Alignment.value() - 1;
if (PaddedSize > SizeThreshold) {
void *NewSlab = Allocator.Allocate(PaddedSize, 0);
void *NewSlab = Allocator.Allocate(PaddedSize, alignof(std::max_align_t));
// We own the new slab and don't want anyone reading anyting other than
// pieces returned from this method. So poison the whole slab.
__asan_poison_memory_region(NewSlab, PaddedSize);
@ -208,7 +208,7 @@ public:
// Bump pointer allocators are expected to never free their storage; and
// clients expect pointers to remain valid for non-dereferencing uses even
// after deallocation.
void Deallocate(const void *Ptr, size_t Size) {
void Deallocate(const void *Ptr, size_t Size, size_t /*Alignment*/) {
__asan_poison_memory_region(Ptr, Size);
}
@ -332,7 +332,8 @@ private:
void StartNewSlab() {
size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
void *NewSlab =
Allocator.Allocate(AllocatedSlabSize, alignof(std::max_align_t));
// We own the new slab and don't want anyone reading anything other than
// pieces returned from this method. So poison the whole slab.
__asan_poison_memory_region(NewSlab, AllocatedSlabSize);
@ -348,7 +349,7 @@ private:
for (; I != E; ++I) {
size_t AllocatedSlabSize =
computeSlabSize(std::distance(Slabs.begin(), I));
Allocator.Deallocate(*I, AllocatedSlabSize);
Allocator.Deallocate(*I, AllocatedSlabSize, alignof(std::max_align_t));
}
}
@ -357,7 +358,7 @@ private:
for (auto &PtrAndSize : CustomSizedSlabs) {
void *Ptr = PtrAndSize.first;
size_t Size = PtrAndSize.second;
Allocator.Deallocate(Ptr, Size);
Allocator.Deallocate(Ptr, Size, alignof(std::max_align_t));
}
}
@ -434,17 +435,8 @@ void *
operator new(size_t Size,
llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold,
GrowthDelay> &Allocator) {
struct S {
char c;
union {
double D;
long double LD;
long long L;
void *P;
} x;
};
return Allocator.Allocate(
Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
alignof(std::max_align_t)));
}
template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,

View File

@ -48,16 +48,17 @@ public:
/// Deallocate \a Ptr to \a Size bytes of memory allocated by this
/// allocator.
void Deallocate(const void *Ptr, size_t Size) {
void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
#ifdef __clang__
static_assert(static_cast<void (AllocatorBase::*)(const void *, size_t)>(
&AllocatorBase::Deallocate) !=
static_cast<void (DerivedT::*)(const void *, size_t)>(
&DerivedT::Deallocate),
"Class derives from AllocatorBase without implementing the "
"core Deallocate(void *) overload!");
static_assert(
static_cast<void (AllocatorBase::*)(const void *, size_t, size_t)>(
&AllocatorBase::Deallocate) !=
static_cast<void (DerivedT::*)(const void *, size_t, size_t)>(
&DerivedT::Deallocate),
"Class derives from AllocatorBase without implementing the "
"core Deallocate(void *) overload!");
#endif
return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size);
return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size, Alignment);
}
// The rest of these methods are helpers that redirect to one of the above
@ -72,7 +73,7 @@ public:
template <typename T>
std::enable_if_t<!std::is_same<std::remove_cv_t<T>, void>::value, void>
Deallocate(T *Ptr, size_t Num = 1) {
Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T));
Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T), alignof(T));
}
};
@ -80,16 +81,15 @@ class MallocAllocator : public AllocatorBase<MallocAllocator> {
public:
void Reset() {}
LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size,
size_t /*Alignment*/) {
return safe_malloc(Size);
LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
return allocate_buffer(Size, Alignment);
}
// Pull in base class overloads.
using AllocatorBase<MallocAllocator>::Allocate;
void Deallocate(const void *Ptr, size_t /*Size*/) {
free(const_cast<void *>(Ptr));
void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
deallocate_buffer(const_cast<void *>(Ptr), Size, Alignment);
}
// Pull in base class overloads.

View File

@ -139,7 +139,7 @@ public:
void operator delete(void *Ptr, BumpPtrAllocator &Alloc,
size_t Size) noexcept {
Alloc.Deallocate(Ptr, Size);
Alloc.Deallocate(Ptr, Size, 0);
}
void operator delete(void *) noexcept = delete;

View File

@ -230,7 +230,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
StringRef(testKeyFirst, testKeyLength), Allocator, 1u);
EXPECT_STREQ(testKey, entry->first().data());
EXPECT_EQ(1u, entry->second);
free(entry);
entry->Destroy(Allocator);
}
// Test insert() method.

View File

@ -206,7 +206,7 @@ public:
return Slab;
}
void Deallocate(void *Slab, size_t Size) {
void Deallocate(void *Slab, size_t /*Size*/, size_t /*Alignment*/) {
free(((void**)Slab)[-1]);
}