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 const uptr ChunkHeaderSize = sizeof(PackedHeader);
63 const uptr AlignedChunkHeaderSize =
64 (ChunkHeaderSize + MinAlignment - 1) & ~(MinAlignment - 1);
66 #if SANITIZER_CAN_USE_ALLOCATOR64
67 const uptr AllocatorSpace = ~0ULL;
69 static const uptr kSpaceBeg = AllocatorSpace;
70 static const uptr kSpaceSize = AllocatorSize;
71 static const uptr kMetadataSize = 0;
72 typedef __scudo::SizeClassMap SizeClassMap;
73 typedef NoOpMapUnmapCallback MapUnmapCallback;
74 static const uptr kFlags =
75 SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
77 typedef SizeClassAllocator64<AP64> PrimaryAllocator;
79 static const uptr NumRegions = SANITIZER_MMAP_RANGE_SIZE >> RegionSizeLog;
80 # if SANITIZER_WORDSIZE == 32
81 typedef FlatByteMap<NumRegions> ByteMap;
82 # elif SANITIZER_WORDSIZE == 64
83 typedef TwoLevelByteMap<(NumRegions >> 12), 1 << 12> ByteMap;
84 # endif // SANITIZER_WORDSIZE
86 static const uptr kSpaceBeg = 0;
87 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
88 static const uptr kMetadataSize = 0;
89 typedef __scudo::SizeClassMap SizeClassMap;
90 static const uptr kRegionSizeLog = RegionSizeLog;
91 typedef __scudo::ByteMap ByteMap;
92 typedef NoOpMapUnmapCallback MapUnmapCallback;
93 static const uptr kFlags =
94 SizeClassAllocator32FlagMasks::kRandomShuffleChunks |
95 SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
97 typedef SizeClassAllocator32<AP32> PrimaryAllocator;
98 #endif // SANITIZER_CAN_USE_ALLOCATOR64
100 // __sanitizer::RoundUp has a CHECK that is extraneous for us. Use our own.
101 INLINE uptr RoundUpTo(uptr Size, uptr Boundary) {
102 return (Size + Boundary - 1) & ~(Boundary - 1);
105 #include "scudo_allocator_secondary.h"
106 #include "scudo_allocator_combined.h"
108 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
109 typedef ScudoLargeMmapAllocator SecondaryAllocator;
110 typedef ScudoCombinedAllocator<PrimaryAllocator, AllocatorCache,
111 SecondaryAllocator> ScudoBackendAllocator;
115 void *scudoMalloc(uptr Size, AllocType Type);
116 void scudoFree(void *Ptr, AllocType Type);
117 void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
118 void *scudoRealloc(void *Ptr, uptr Size);
119 void *scudoCalloc(uptr NMemB, uptr Size);
120 void *scudoMemalign(uptr Alignment, uptr Size);
121 void *scudoValloc(uptr Size);
122 void *scudoPvalloc(uptr Size);
123 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
124 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
125 uptr scudoMallocUsableSize(void *Ptr);
127 } // namespace __scudo
129 #endif // SCUDO_ALLOCATOR_H_