[PATCH] D48889: [demangler] Ensure proper alignment in BumpPointerAllocator
Serge Pavlov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 3 11:51:02 PDT 2018
sepavloff created this revision.
sepavloff added a reviewer: erik.pilkington.
This change slightly modifies algorithm of `BumpPointerAllocator` so that it
provides alignment of allocated memory blocks in runtime without specific
compiler support. It allows getting rid of the specifier `alignas(16)` in the
declaration of `BumpPointerAllocator::InitialBuffer`. Object of the class
`BumpPointerAllocator` is created as a part of another object allocated in heap,
so this specifier actually cannot guarantee proper alignment. Microsoft
compiler emits a warning in this case.
It fixes https://bugs.llvm.org/show_bug.cgi?id=37944.
Repository:
rL LLVM
https://reviews.llvm.org/D48889
Files:
lib/Demangle/ItaniumDemangle.cpp
Index: lib/Demangle/ItaniumDemangle.cpp
===================================================================
--- lib/Demangle/ItaniumDemangle.cpp
+++ lib/Demangle/ItaniumDemangle.cpp
@@ -1945,40 +1945,53 @@
struct BlockMeta {
BlockMeta* Next;
size_t Current;
+
+ BlockMeta(BlockMeta *N) : Next(N),
+ Current(Alignment -
+ (reinterpret_cast<size_t>(this + 1) & (Alignment - 1))) { }
+ void *getTail() { return reinterpret_cast<char*>(this + 1) + Current; }
};
+ static constexpr size_t Alignment = 16;
static constexpr size_t AllocSize = 4096;
- static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
+ static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta) -
+ Alignment;
- alignas(16) char InitialBuffer[AllocSize];
+ char InitialBuffer[AllocSize];
BlockMeta* BlockList = nullptr;
void grow() {
char* NewMeta = new char[AllocSize];
- BlockList = new (NewMeta) BlockMeta{BlockList, 0};
+ BlockList = new (NewMeta) BlockMeta(BlockList);
}
void* allocateMassive(size_t NBytes) {
- NBytes += sizeof(BlockMeta);
- BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]);
- BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
- return static_cast<void*>(NewMeta + 1);
+ size_t AllocSz = NBytes + sizeof(BlockMeta) + Alignment;
+ char *Mem = new char[AllocSz];
+ BlockList->Next = new (Mem) BlockMeta(BlockList->Next);
+ void *Result = BlockList->getTail();
+ BlockList->Current += NBytes;
+ return Result;
+ }
+
+ static constexpr size_t getAlignedSize(size_t Sz) {
+ return (Sz + (Alignment - 1)) & ~(Alignment - 1);
}
public:
BumpPointerAllocator()
- : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
+ : BlockList(new (InitialBuffer) BlockMeta(nullptr)) {}
void* allocate(size_t N) {
- N = (N + 15u) & ~15u;
+ N = getAlignedSize(N);
if (N + BlockList->Current >= UsableAllocSize) {
if (N > UsableAllocSize)
return allocateMassive(N);
grow();
}
+ void *Result = BlockList->getTail();
BlockList->Current += N;
- return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
- BlockList->Current - N);
+ return Result;
}
void reset() {
@@ -1988,7 +2001,7 @@
if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
delete[] reinterpret_cast<char*>(Tmp);
}
- BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
+ BlockList = new (InitialBuffer) BlockMeta(nullptr);
}
~BumpPointerAllocator() { reset(); }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48889.153949.patch
Type: text/x-patch
Size: 2671 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180703/e24aed4b/attachment.bin>
More information about the llvm-commits
mailing list