1 //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// Header for scudo_allocator.cpp.
12 //===----------------------------------------------------------------------===//
14 #ifndef SCUDO_ALLOCATOR_H_
15 #define SCUDO_ALLOCATOR_H_
17 #include "scudo_platform.h"
22 FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
23 FromNew = 1, // Memory block came from operator new.
24 FromNewArray = 2, // Memory block came from operator new [].
25 FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
28 enum ChunkState : u8 {
34 // Our header requires 64 bits of storage. Having the offset saves us from
35 // using functions such as GetBlockBegin, that is fairly costly. Our first
36 // implementation used the MetaData as well, which offers the advantage of
37 // being stored away from the chunk itself, but accessing it was costly as
38 // well. The header will be atomically loaded and stored.
39 typedef u64 PackedHeader;
40 struct UnpackedHeader {
43 u64 SizeOrUnusedBytes : 20; // Size for Primary backed allocations, amount of
44 // unused bytes in the chunk for Secondary ones.
45 u64 State : 2; // available, allocated, or quarantined
46 u64 AllocType : 2; // malloc, new, new[], or memalign
47 u64 Offset : 16; // Offset from the beginning of the backend
48 // allocation to the beginning of the chunk
49 // itself, in multiples of MinAlignment. See
50 // comment about its maximum value and in init().
53 typedef atomic_uint64_t AtomicPackedHeader;
54 COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
56 // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
57 const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
58 const uptr MaxAlignmentLog = 24; // 16 MB
59 const uptr MinAlignment = 1 << MinAlignmentLog;
60 const uptr MaxAlignment = 1 << MaxAlignmentLog;
62 // constexpr version of __sanitizer::RoundUp without the extraneous CHECK.
63 // This way we can use it in constexpr variables and functions declarations.
64 constexpr uptr RoundUpTo(uptr Size, uptr Boundary) {
65 return (Size + Boundary - 1) & ~(Boundary - 1);
69 constexpr uptr getHeaderSize() {
70 return RoundUpTo(sizeof(PackedHeader), MinAlignment);
74 #if SANITIZER_CAN_USE_ALLOCATOR64
75 const uptr AllocatorSpace = ~0ULL;
77 static const uptr kSpaceBeg = AllocatorSpace;
78 static const uptr kSpaceSize = AllocatorSize;
79 static const uptr kMetadataSize = 0;
80 typedef __scudo::SizeClassMap SizeClassMap;
81 typedef NoOpMapUnmapCallback MapUnmapCallback;
82 static const uptr kFlags =
83 SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
84 using AddressSpaceView = LocalAddressSpaceView;
86 typedef SizeClassAllocator64<AP64> PrimaryT;
88 static const uptr NumRegions = SANITIZER_MMAP_RANGE_SIZE >> RegionSizeLog;
89 # if SANITIZER_WORDSIZE == 32
90 typedef FlatByteMap<NumRegions> ByteMap;
91 # elif SANITIZER_WORDSIZE == 64
92 typedef TwoLevelByteMap<(NumRegions >> 12), 1 << 12> ByteMap;
93 # endif // SANITIZER_WORDSIZE
95 static const uptr kSpaceBeg = 0;
96 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
97 static const uptr kMetadataSize = 0;
98 typedef __scudo::SizeClassMap SizeClassMap;
99 static const uptr kRegionSizeLog = RegionSizeLog;
100 using AddressSpaceView = LocalAddressSpaceView;
101 using ByteMap = __scudo::ByteMap;
102 typedef NoOpMapUnmapCallback MapUnmapCallback;
103 static const uptr kFlags =
104 SizeClassAllocator32FlagMasks::kRandomShuffleChunks |
105 SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
107 typedef SizeClassAllocator32<AP32> PrimaryT;
108 #endif // SANITIZER_CAN_USE_ALLOCATOR64
110 #include "scudo_allocator_secondary.h"
111 #include "scudo_allocator_combined.h"
113 typedef SizeClassAllocatorLocalCache<PrimaryT> AllocatorCacheT;
114 typedef LargeMmapAllocator SecondaryT;
115 typedef CombinedAllocator<PrimaryT, AllocatorCacheT, SecondaryT> BackendT;
119 void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type);
120 void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type);
121 void *scudoRealloc(void *Ptr, uptr Size);
122 void *scudoCalloc(uptr NMemB, uptr Size);
123 void *scudoValloc(uptr Size);
124 void *scudoPvalloc(uptr Size);
125 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
126 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
127 uptr scudoMallocUsableSize(void *Ptr);
129 } // namespace __scudo
131 #endif // SCUDO_ALLOCATOR_H_