]> git.proxmox.com Git - rustc.git/blob - src/libcompiler_builtins/compiler-rt/lib/scudo/scudo_allocator.h
New upstream version 1.20.0+dfsg1
[rustc.git] / src / libcompiler_builtins / compiler-rt / lib / scudo / scudo_allocator.h
1 //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// Header for scudo_allocator.cpp.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef SCUDO_ALLOCATOR_H_
15 #define SCUDO_ALLOCATOR_H_
16
17 #include "scudo_flags.h"
18
19 #include "sanitizer_common/sanitizer_allocator.h"
20
21 #include <atomic>
22
23 namespace __scudo {
24
25 enum AllocType : u8 {
26 FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
27 FromNew = 1, // Memory block came from operator new.
28 FromNewArray = 2, // Memory block came from operator new [].
29 FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
30 };
31
32 enum ChunkState : u8 {
33 ChunkAvailable = 0,
34 ChunkAllocated = 1,
35 ChunkQuarantine = 2
36 };
37
38 // Our header requires 64 bits of storage. Having the offset saves us from
39 // using functions such as GetBlockBegin, that is fairly costly. Our first
40 // implementation used the MetaData as well, which offers the advantage of
41 // being stored away from the chunk itself, but accessing it was costly as
42 // well. The header will be atomically loaded and stored using the 16-byte
43 // primitives offered by the platform (likely requires cmpxchg16b support).
44 typedef u64 PackedHeader;
45 struct UnpackedHeader {
46 u64 Checksum : 16;
47 u64 UnusedBytes : 20; // Needed for reallocation purposes.
48 u64 State : 2; // available, allocated, or quarantined
49 u64 AllocType : 2; // malloc, new, new[], or memalign
50 u64 Offset : 16; // Offset from the beginning of the backend
51 // allocation to the beginning of the chunk itself,
52 // in multiples of MinAlignment. See comment about
53 // its maximum value and test in init().
54 u64 Salt : 8;
55 };
56
57 typedef std::atomic<PackedHeader> AtomicPackedHeader;
58 COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
59
60 // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
61 const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
62 const uptr MaxAlignmentLog = 24; // 16 MB
63 const uptr MinAlignment = 1 << MinAlignmentLog;
64 const uptr MaxAlignment = 1 << MaxAlignmentLog;
65
66 const uptr ChunkHeaderSize = sizeof(PackedHeader);
67 const uptr AlignedChunkHeaderSize =
68 (ChunkHeaderSize + MinAlignment - 1) & ~(MinAlignment - 1);
69
70 struct AllocatorOptions {
71 u32 QuarantineSizeMb;
72 u32 ThreadLocalQuarantineSizeKb;
73 bool MayReturnNull;
74 s32 ReleaseToOSIntervalMs;
75 bool DeallocationTypeMismatch;
76 bool DeleteSizeMismatch;
77 bool ZeroContents;
78
79 void setFrom(const Flags *f, const CommonFlags *cf);
80 void copyTo(Flags *f, CommonFlags *cf) const;
81 };
82
83 void initAllocator(const AllocatorOptions &options);
84 void drainQuarantine();
85
86 void *scudoMalloc(uptr Size, AllocType Type);
87 void scudoFree(void *Ptr, AllocType Type);
88 void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
89 void *scudoRealloc(void *Ptr, uptr Size);
90 void *scudoCalloc(uptr NMemB, uptr Size);
91 void *scudoMemalign(uptr Alignment, uptr Size);
92 void *scudoValloc(uptr Size);
93 void *scudoPvalloc(uptr Size);
94 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
95 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
96 uptr scudoMallocUsableSize(void *Ptr);
97
98 #include "scudo_allocator_secondary.h"
99
100 } // namespace __scudo
101
102 #endif // SCUDO_ALLOCATOR_H_