fix build when sanitizers are enabled and jemalloc is disabled
[folly.git] / folly / experimental / JemallocNodumpAllocator.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // http://www.canonware.com/download/jemalloc/jemalloc-latest/doc/jemalloc.html
18
19 #pragma once
20
21 #include <folly/CPortability.h>
22 #include <folly/portability/Config.h>
23
24 #if defined(FOLLY_HAVE_LIBJEMALLOC) && !defined(FOLLY_SANITIZE)
25
26 #include <folly/portability/SysMman.h>
27 #include <jemalloc/jemalloc.h>
28
29 #if (JEMALLOC_VERSION_MAJOR > 3) && defined(MADV_DONTDUMP)
30 #define FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED 1
31 #if (JEMALLOC_VERSION_MAJOR == 4)
32 #define FOLLY_JEMALLOC_NODUMP_ALLOCATOR_CHUNK
33 #define JEMALLOC_CHUNK_OR_EXTENT chunk
34 #else
35 #define FOLLY_JEMALLOC_NODUMP_ALLOCATOR_EXTENT
36 #define JEMALLOC_CHUNK_OR_EXTENT extent
37 #endif
38 #endif
39
40 #endif // FOLLY_HAVE_LIBJEMALLOC
41
42 #include <cstddef>
43
44 namespace folly {
45
46 /**
47  * An allocator which uses Jemalloc to create an dedicated arena to allocate
48  * memory from. The only special property set on the allocated memory is that
49  * the memory is not dump-able.
50  *
51  * This is done by setting MADV_DONTDUMP using the `madvise` system call. A
52  * custom hook installed which is called when allocating a new chunk / extent of
53  * memory.  All it does is call the original jemalloc hook to allocate the
54  * memory and then set the advise on it before returning the pointer to the
55  * allocated memory. Jemalloc does not use allocated chunks / extents across
56  * different arenas, without `munmap`-ing them first, and the advises are not
57  * sticky i.e. they are unset if `munmap` is done. Also this arena can't be used
58  * by any other part of the code by just calling `malloc`.
59  *
60  * If target system doesn't support MADV_DONTDUMP or jemalloc doesn't support
61  * custom arena hook, JemallocNodumpAllocator would fall back to using malloc /
62  * free. Such behavior can be identified by using
63  * !defined(FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED).
64  *
65  * Similarly, if binary isn't linked with jemalloc, the logic would fall back to
66  * malloc / free.
67  */
68 class JemallocNodumpAllocator {
69  public:
70   enum class State {
71     ENABLED,
72     DISABLED,
73   };
74
75   // To be used as IOBuf::FreeFunction, userData should be set to
76   // reinterpret_cast<void*>(getFlags()).
77   static void deallocate(void* p, void* userData);
78
79   explicit JemallocNodumpAllocator(State state = State::ENABLED);
80
81   void* allocate(size_t size);
82   void* reallocate(void* p, size_t size);
83   void deallocate(void* p);
84
85   unsigned getArenaIndex() const { return arena_index_; }
86   int getFlags() const { return flags_; }
87
88  private:
89 #ifdef FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED
90 #ifdef FOLLY_JEMALLOC_NODUMP_ALLOCATOR_CHUNK
91   static chunk_alloc_t* original_alloc_;
92   static void* alloc(
93       void* chunk,
94 #else
95   static extent_hooks_t extent_hooks_;
96   static extent_alloc_t* original_alloc_;
97   static void* alloc(
98       extent_hooks_t* extent,
99       void* new_addr,
100 #endif
101       size_t size,
102       size_t alignment,
103       bool* zero,
104       bool* commit,
105       unsigned arena_ind);
106 #endif // FOLLY_JEMALLOC_NODUMP_ALLOCATOR_SUPPORTED
107
108   bool extend_and_setup_arena();
109
110   unsigned arena_index_{0};
111   int flags_{0};
112 };
113
114 /**
115  * JemallocNodumpAllocator singleton.
116  */
117 JemallocNodumpAllocator& globalJemallocNodumpAllocator();
118
119 } // namespace folly