]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/compiler-rt/lib/scudo/scudo_allocator.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / compiler-rt / lib / scudo / scudo_allocator.h
1 //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// Header for scudo_allocator.cpp.
10 ///
11 //===----------------------------------------------------------------------===//
12
13 #ifndef SCUDO_ALLOCATOR_H_
14 #define SCUDO_ALLOCATOR_H_
15
16 #include "scudo_platform.h"
17
18 namespace __scudo {
19
20 enum AllocType : u8 {
21   FromMalloc    = 0,  // Memory block came from malloc, realloc, calloc, etc.
22   FromNew       = 1,  // Memory block came from operator new.
23   FromNewArray  = 2,  // Memory block came from operator new [].
24   FromMemalign  = 3,  // Memory block came from memalign, posix_memalign, etc.
25 };
26
27 enum ChunkState : u8 {
28   ChunkAvailable  = 0,
29   ChunkAllocated  = 1,
30   ChunkQuarantine = 2
31 };
32
33 // Our header requires 64 bits of storage. Having the offset saves us from
34 // using functions such as GetBlockBegin, that is fairly costly. Our first
35 // implementation used the MetaData as well, which offers the advantage of
36 // being stored away from the chunk itself, but accessing it was costly as
37 // well. The header will be atomically loaded and stored.
38 typedef u64 PackedHeader;
39 struct UnpackedHeader {
40   u64 Checksum          : 16;
41   u64 ClassId           : 8;
42   u64 SizeOrUnusedBytes : 20;  // Size for Primary backed allocations, amount of
43                                // unused bytes in the chunk for Secondary ones.
44   u64 State             : 2;   // available, allocated, or quarantined
45   u64 AllocType         : 2;   // malloc, new, new[], or memalign
46   u64 Offset            : 16;  // Offset from the beginning of the backend
47                                // allocation to the beginning of the chunk
48                                // itself, in multiples of MinAlignment. See
49                                // comment about its maximum value and in init().
50 };
51
52 typedef atomic_uint64_t AtomicPackedHeader;
53 COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
54
55 // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
56 const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
57 const uptr MaxAlignmentLog = 24;  // 16 MB
58 const uptr MinAlignment = 1 << MinAlignmentLog;
59 const uptr MaxAlignment = 1 << MaxAlignmentLog;
60
61 // constexpr version of __sanitizer::RoundUp without the extraneous CHECK.
62 // This way we can use it in constexpr variables and functions declarations.
63 constexpr uptr RoundUpTo(uptr Size, uptr Boundary) {
64   return (Size + Boundary - 1) & ~(Boundary - 1);
65 }
66
67 namespace Chunk {
68   constexpr uptr getHeaderSize() {
69     return RoundUpTo(sizeof(PackedHeader), MinAlignment);
70   }
71 }
72
73 #if SANITIZER_CAN_USE_ALLOCATOR64
74 const uptr AllocatorSpace = ~0ULL;
75 struct AP64 {
76   static const uptr kSpaceBeg = AllocatorSpace;
77   static const uptr kSpaceSize = AllocatorSize;
78   static const uptr kMetadataSize = 0;
79   typedef __scudo::SizeClassMap SizeClassMap;
80   typedef NoOpMapUnmapCallback MapUnmapCallback;
81   static const uptr kFlags =
82       SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
83   using AddressSpaceView = LocalAddressSpaceView;
84 };
85 typedef SizeClassAllocator64<AP64> PrimaryT;
86 #else
87 struct AP32 {
88   static const uptr kSpaceBeg = 0;
89   static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
90   static const uptr kMetadataSize = 0;
91   typedef __scudo::SizeClassMap SizeClassMap;
92   static const uptr kRegionSizeLog = RegionSizeLog;
93   using AddressSpaceView = LocalAddressSpaceView;
94   typedef NoOpMapUnmapCallback MapUnmapCallback;
95   static const uptr kFlags =
96       SizeClassAllocator32FlagMasks::kRandomShuffleChunks |
97       SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
98 };
99 typedef SizeClassAllocator32<AP32> PrimaryT;
100 #endif  // SANITIZER_CAN_USE_ALLOCATOR64
101
102 #include "scudo_allocator_secondary.h"
103
104 typedef LargeMmapAllocator SecondaryT;
105
106 #include "scudo_allocator_combined.h"
107
108 typedef CombinedAllocator BackendT;
109 typedef CombinedAllocator::AllocatorCache AllocatorCacheT;
110
111 void initScudo();
112
113 void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type);
114 void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type);
115 void *scudoRealloc(void *Ptr, uptr Size);
116 void *scudoCalloc(uptr NMemB, uptr Size);
117 void *scudoValloc(uptr Size);
118 void *scudoPvalloc(uptr Size);
119 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
120 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
121 uptr scudoMallocUsableSize(void *Ptr);
122
123 }  // namespace __scudo
124
125 #endif  // SCUDO_ALLOCATOR_H_