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