xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/memprof/memprof_allocator.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1*e8d8bef9SDimitry Andric //===-- memprof_allocator.h ------------------------------------*- C++ -*-===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // This file is a part of MemProfiler, a memory profiler.
10*e8d8bef9SDimitry Andric //
11*e8d8bef9SDimitry Andric // MemProf-private header for memprof_allocator.cpp.
12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
13*e8d8bef9SDimitry Andric 
14*e8d8bef9SDimitry Andric #ifndef MEMPROF_ALLOCATOR_H
15*e8d8bef9SDimitry Andric #define MEMPROF_ALLOCATOR_H
16*e8d8bef9SDimitry Andric 
17*e8d8bef9SDimitry Andric #include "memprof_flags.h"
18*e8d8bef9SDimitry Andric #include "memprof_interceptors.h"
19*e8d8bef9SDimitry Andric #include "memprof_internal.h"
20*e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_allocator.h"
21*e8d8bef9SDimitry Andric #include "sanitizer_common/sanitizer_list.h"
22*e8d8bef9SDimitry Andric 
23*e8d8bef9SDimitry Andric #if !defined(__x86_64__)
24*e8d8bef9SDimitry Andric #error Unsupported platform
25*e8d8bef9SDimitry Andric #endif
26*e8d8bef9SDimitry Andric #if !SANITIZER_CAN_USE_ALLOCATOR64
27*e8d8bef9SDimitry Andric #error Only 64-bit allocator supported
28*e8d8bef9SDimitry Andric #endif
29*e8d8bef9SDimitry Andric 
30*e8d8bef9SDimitry Andric namespace __memprof {
31*e8d8bef9SDimitry Andric 
32*e8d8bef9SDimitry Andric enum AllocType {
33*e8d8bef9SDimitry Andric   FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
34*e8d8bef9SDimitry Andric   FROM_NEW = 2,    // Memory block came from operator new.
35*e8d8bef9SDimitry Andric   FROM_NEW_BR = 3  // Memory block came from operator new [ ]
36*e8d8bef9SDimitry Andric };
37*e8d8bef9SDimitry Andric 
38*e8d8bef9SDimitry Andric void InitializeAllocator();
39*e8d8bef9SDimitry Andric 
40*e8d8bef9SDimitry Andric struct MemprofMapUnmapCallback {
41*e8d8bef9SDimitry Andric   void OnMap(uptr p, uptr size) const;
42*e8d8bef9SDimitry Andric   void OnUnmap(uptr p, uptr size) const;
43*e8d8bef9SDimitry Andric };
44*e8d8bef9SDimitry Andric 
45*e8d8bef9SDimitry Andric constexpr uptr kAllocatorSpace = 0x600000000000ULL;
46*e8d8bef9SDimitry Andric constexpr uptr kAllocatorSize = 0x40000000000ULL; // 4T.
47*e8d8bef9SDimitry Andric typedef DefaultSizeClassMap SizeClassMap;
48*e8d8bef9SDimitry Andric template <typename AddressSpaceViewTy>
49*e8d8bef9SDimitry Andric struct AP64 { // Allocator64 parameters. Deliberately using a short name.
50*e8d8bef9SDimitry Andric   static const uptr kSpaceBeg = kAllocatorSpace;
51*e8d8bef9SDimitry Andric   static const uptr kSpaceSize = kAllocatorSize;
52*e8d8bef9SDimitry Andric   static const uptr kMetadataSize = 0;
53*e8d8bef9SDimitry Andric   typedef __memprof::SizeClassMap SizeClassMap;
54*e8d8bef9SDimitry Andric   typedef MemprofMapUnmapCallback MapUnmapCallback;
55*e8d8bef9SDimitry Andric   static const uptr kFlags = 0;
56*e8d8bef9SDimitry Andric   using AddressSpaceView = AddressSpaceViewTy;
57*e8d8bef9SDimitry Andric };
58*e8d8bef9SDimitry Andric 
59*e8d8bef9SDimitry Andric template <typename AddressSpaceView>
60*e8d8bef9SDimitry Andric using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
61*e8d8bef9SDimitry Andric using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
62*e8d8bef9SDimitry Andric 
63*e8d8bef9SDimitry Andric static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;
64*e8d8bef9SDimitry Andric 
65*e8d8bef9SDimitry Andric template <typename AddressSpaceView>
66*e8d8bef9SDimitry Andric using MemprofAllocatorASVT =
67*e8d8bef9SDimitry Andric     CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>>;
68*e8d8bef9SDimitry Andric using MemprofAllocator = MemprofAllocatorASVT<LocalAddressSpaceView>;
69*e8d8bef9SDimitry Andric using AllocatorCache = MemprofAllocator::AllocatorCache;
70*e8d8bef9SDimitry Andric 
71*e8d8bef9SDimitry Andric struct MemprofThreadLocalMallocStorage {
72*e8d8bef9SDimitry Andric   uptr quarantine_cache[16];
73*e8d8bef9SDimitry Andric   AllocatorCache allocator_cache;
74*e8d8bef9SDimitry Andric   void CommitBack();
75*e8d8bef9SDimitry Andric 
76*e8d8bef9SDimitry Andric private:
77*e8d8bef9SDimitry Andric   // These objects are allocated via mmap() and are zero-initialized.
78*e8d8bef9SDimitry Andric   MemprofThreadLocalMallocStorage() {}
79*e8d8bef9SDimitry Andric };
80*e8d8bef9SDimitry Andric 
81*e8d8bef9SDimitry Andric void *memprof_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
82*e8d8bef9SDimitry Andric                        AllocType alloc_type);
83*e8d8bef9SDimitry Andric void memprof_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type);
84*e8d8bef9SDimitry Andric void memprof_delete(void *ptr, uptr size, uptr alignment,
85*e8d8bef9SDimitry Andric                     BufferedStackTrace *stack, AllocType alloc_type);
86*e8d8bef9SDimitry Andric 
87*e8d8bef9SDimitry Andric void *memprof_malloc(uptr size, BufferedStackTrace *stack);
88*e8d8bef9SDimitry Andric void *memprof_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
89*e8d8bef9SDimitry Andric void *memprof_realloc(void *p, uptr size, BufferedStackTrace *stack);
90*e8d8bef9SDimitry Andric void *memprof_reallocarray(void *p, uptr nmemb, uptr size,
91*e8d8bef9SDimitry Andric                            BufferedStackTrace *stack);
92*e8d8bef9SDimitry Andric void *memprof_valloc(uptr size, BufferedStackTrace *stack);
93*e8d8bef9SDimitry Andric void *memprof_pvalloc(uptr size, BufferedStackTrace *stack);
94*e8d8bef9SDimitry Andric 
95*e8d8bef9SDimitry Andric void *memprof_aligned_alloc(uptr alignment, uptr size,
96*e8d8bef9SDimitry Andric                             BufferedStackTrace *stack);
97*e8d8bef9SDimitry Andric int memprof_posix_memalign(void **memptr, uptr alignment, uptr size,
98*e8d8bef9SDimitry Andric                            BufferedStackTrace *stack);
99*e8d8bef9SDimitry Andric uptr memprof_malloc_usable_size(const void *ptr, uptr pc, uptr bp);
100*e8d8bef9SDimitry Andric 
101*e8d8bef9SDimitry Andric void PrintInternalAllocatorStats();
102*e8d8bef9SDimitry Andric void MemprofSoftRssLimitExceededCallback(bool exceeded);
103*e8d8bef9SDimitry Andric 
104*e8d8bef9SDimitry Andric } // namespace __memprof
105*e8d8bef9SDimitry Andric #endif // MEMPROF_ALLOCATOR_H
106