summaryrefslogtreecommitdiff
path: root/lib/scudo/scudo_allocator.h
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2016-10-26 16:16:58 +0000
committerKostya Kortchinsky <kostyak@google.com>2016-10-26 16:16:58 +0000
commit52d212a07c87b0fcb5292af2fc990bf2da9079f0 (patch)
tree602aaeeb8e15e0375ece77178d60d6c334d9f092 /lib/scudo/scudo_allocator.h
parent34e89ba88dbd702beea62bb80138079295955369 (diff)
[scudo] Lay the foundation for 32-bit support
Summary: In order to support 32-bit platforms, we have to make some adjustments in multiple locations, one of them being the Scudo chunk header. For it to fit on 64 bits (as a reminder, on x64 it's 128 bits), I had to crunch the space taken by some of the fields. In order to keep the offset field small, the secondary allocator was changed to accomodate aligned allocations for larger alignments, hence making the offset constant for chunks serviced by it. The resulting header candidate has been added, and further modifications to allow 32-bit support will follow. Another notable change is the addition of MaybeStartBackgroudThread() to allow release of the memory to the OS. Reviewers: kcc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D25688 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@285209 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/scudo/scudo_allocator.h')
-rw-r--r--lib/scudo/scudo_allocator.h61
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/scudo/scudo_allocator.h b/lib/scudo/scudo_allocator.h
index 7e9c78860..c4f3ebd38 100644
--- a/lib/scudo/scudo_allocator.h
+++ b/lib/scudo/scudo_allocator.h
@@ -22,6 +22,8 @@
#include "sanitizer_common/sanitizer_allocator.h"
+#include <atomic>
+
namespace __scudo {
enum AllocType : u8 {
@@ -31,6 +33,63 @@ enum AllocType : u8 {
FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
};
+enum ChunkState : u8 {
+ ChunkAvailable = 0,
+ ChunkAllocated = 1,
+ ChunkQuarantine = 2
+};
+
+#if SANITIZER_WORDSIZE == 64
+// Our header requires 128 bits of storage on 64-bit platforms, which fits
+// nicely with the alignment requirements. Having the offset saves us from
+// using functions such as GetBlockBegin, that is fairly costly. Our first
+// implementation used the MetaData as well, which offers the advantage of
+// being stored away from the chunk itself, but accessing it was costly as
+// well. The header will be atomically loaded and stored using the 16-byte
+// primitives offered by the platform (likely requires cmpxchg16b support).
+typedef unsigned __int128 PackedHeader;
+struct UnpackedHeader {
+ u16 Checksum : 16;
+ uptr RequestedSize : 40; // Needed for reallocation purposes.
+ u8 State : 2; // available, allocated, or quarantined
+ u8 AllocType : 2; // malloc, new, new[], or memalign
+ u8 Unused_0_ : 4;
+ uptr Offset : 12; // Offset from the beginning of the backend
+ // allocation to the beginning of the chunk itself,
+ // in multiples of MinAlignment. See comment about
+ // its maximum value and test in init().
+ u64 Unused_1_ : 36;
+ u16 Salt : 16;
+};
+#elif SANITIZER_WORDSIZE == 32
+// On 32-bit platforms, our header requires 64 bits.
+typedef u64 PackedHeader;
+struct UnpackedHeader {
+ u16 Checksum : 12;
+ uptr RequestedSize : 32; // Needed for reallocation purposes.
+ u8 State : 2; // available, allocated, or quarantined
+ u8 AllocType : 2; // malloc, new, new[], or memalign
+ uptr Offset : 12; // Offset from the beginning of the backend
+ // allocation to the beginning of the chunk itself,
+ // in multiples of MinAlignment. See comment about
+ // its maximum value and test in Allocator::init().
+ u16 Salt : 4;
+};
+#else
+# error "Unsupported SANITIZER_WORDSIZE."
+#endif // SANITIZER_WORDSIZE
+
+typedef std::atomic<PackedHeader> AtomicPackedHeader;
+COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
+
+const uptr ChunkHeaderSize = sizeof(PackedHeader);
+
+// Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
+const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
+const uptr MaxAlignmentLog = 24; // 16 MB
+const uptr MinAlignment = 1 << MinAlignmentLog;
+const uptr MaxAlignment = 1 << MaxAlignmentLog;
+
struct AllocatorOptions {
u32 QuarantineSizeMb;
u32 ThreadLocalQuarantineSizeKb;
@@ -58,6 +117,8 @@ int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
void *scudoAlignedAlloc(uptr Alignment, uptr Size);
uptr scudoMallocUsableSize(void *Ptr);
+#include "scudo_allocator_secondary.h"
+
} // namespace __scudo
#endif // SCUDO_ALLOCATOR_H_