xref: /llvm-project/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h (revision 2c0b8b10dd1a9f57eb8d8663f2697b5071cdb65d)
1 //===-- allocator_config_wrapper.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 #ifndef SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_
10 #define SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_
11 
12 #include "condition_variable.h"
13 #include "internal_defs.h"
14 #include "secondary.h"
15 #include "type_traits.h"
16 
17 namespace scudo {
18 
19 #define OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, MEMBER)                         \
20   template <typename Config, typename = TYPE> struct NAME##State {             \
21     static constexpr removeConst<TYPE>::type getValue() { return DEFAULT; }    \
22   };                                                                           \
23   template <typename Config>                                                   \
24   struct NAME##State<                                                          \
25       Config, typename assertSameType<decltype(Config::MEMBER), TYPE>::type> { \
26     static constexpr removeConst<TYPE>::type getValue() {                      \
27       return Config::MEMBER;                                                   \
28     }                                                                          \
29   };
30 
31 #define OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, MEMBER)                          \
32   template <typename Config, typename Void = void> struct NAME##Type {         \
33     static constexpr bool enabled() { return false; }                          \
34     using NAME = DEFAULT;                                                      \
35   };                                                                           \
36   template <typename Config>                                                   \
37   struct NAME##Type<Config,                                                    \
38                     typename voidAdaptor<typename Config::MEMBER>::type> {     \
39     static constexpr bool enabled() { return true; }                           \
40     using NAME = typename Config::MEMBER;                                      \
41   };
42 
43 template <typename AllocatorConfig> struct BaseConfig {
44 #define BASE_REQUIRED_TEMPLATE_TYPE(NAME)                                      \
45   template <typename T> using NAME = typename AllocatorConfig::template NAME<T>;
46 
47 #define BASE_OPTIONAL(TYPE, NAME, DEFAULT)                                     \
48   OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME)                                 \
49   static constexpr removeConst<TYPE>::type get##NAME() {                       \
50     return NAME##State<AllocatorConfig>::getValue();                           \
51   }
52 
53 #include "allocator_config.def"
54 }; // BaseConfig
55 
56 template <typename AllocatorConfig> struct PrimaryConfig {
57   // TODO: Pass this flag through template argument to remove this hard-coded
58   //       function.
59   static constexpr bool getMaySupportMemoryTagging() {
60     return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging();
61   }
62 
63 #define PRIMARY_REQUIRED_TYPE(NAME)                                            \
64   using NAME = typename AllocatorConfig::Primary::NAME;
65 
66 #define PRIMARY_REQUIRED(TYPE, NAME)                                           \
67   static constexpr removeConst<TYPE>::type get##NAME() {                       \
68     return AllocatorConfig::Primary::NAME;                                     \
69   }
70 
71 #define PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT)                                  \
72   OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME)                                 \
73   static constexpr removeConst<TYPE>::type get##NAME() {                       \
74     return NAME##State<typename AllocatorConfig::Primary>::getValue();         \
75   }
76 
77 #define PRIMARY_OPTIONAL_TYPE(NAME, DEFAULT)                                   \
78   OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, NAME)                                  \
79   static constexpr bool has##NAME() {                                          \
80     return NAME##Type<typename AllocatorConfig::Primary>::enabled();           \
81   }                                                                            \
82   using NAME = typename NAME##Type<typename AllocatorConfig::Primary>::NAME;
83 
84 #include "allocator_config.def"
85 
86 }; // PrimaryConfig
87 
88 template <typename AllocatorConfig> struct SecondaryConfig {
89   // TODO: Pass this flag through template argument to remove this hard-coded
90   //       function.
91   static constexpr bool getMaySupportMemoryTagging() {
92     return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging();
93   }
94 
95 #define SECONDARY_REQUIRED_TEMPLATE_TYPE(NAME)                                 \
96   template <typename T>                                                        \
97   using NAME = typename AllocatorConfig::Secondary::template NAME<T>;
98 #include "allocator_config.def"
99 
100   struct CacheConfig {
101     // TODO: Pass this flag through template argument to remove this hard-coded
102     //       function.
103     static constexpr bool getMaySupportMemoryTagging() {
104       return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging();
105     }
106 
107 #define SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT)                          \
108   OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, Cache::NAME)                          \
109   static constexpr removeConst<TYPE>::type get##NAME() {                       \
110     return NAME##State<typename AllocatorConfig::Secondary>::getValue();       \
111   }
112 #include "allocator_config.def"
113   }; // CacheConfig
114 };   // SecondaryConfig
115 
116 #undef OPTIONAL_TEMPLATE
117 #undef OPTIONAL_TEMPLATE_TYPE
118 
119 } // namespace scudo
120 
121 #endif // SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_
122