12dc9ec47SChiaHungDuan //===-- allocator_config_wrapper.h ------------------------------*- C++ -*-===// 22dc9ec47SChiaHungDuan // 32dc9ec47SChiaHungDuan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42dc9ec47SChiaHungDuan // See https://llvm.org/LICENSE.txt for license information. 52dc9ec47SChiaHungDuan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62dc9ec47SChiaHungDuan // 72dc9ec47SChiaHungDuan //===----------------------------------------------------------------------===// 82dc9ec47SChiaHungDuan 92dc9ec47SChiaHungDuan #ifndef SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ 102dc9ec47SChiaHungDuan #define SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ 112dc9ec47SChiaHungDuan 122dc9ec47SChiaHungDuan #include "condition_variable.h" 132dc9ec47SChiaHungDuan #include "internal_defs.h" 142dc9ec47SChiaHungDuan #include "secondary.h" 15*2c0b8b10SChiaHungDuan #include "type_traits.h" 162dc9ec47SChiaHungDuan 172dc9ec47SChiaHungDuan namespace scudo { 182dc9ec47SChiaHungDuan 192dc9ec47SChiaHungDuan #define OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, MEMBER) \ 202dc9ec47SChiaHungDuan template <typename Config, typename = TYPE> struct NAME##State { \ 212dc9ec47SChiaHungDuan static constexpr removeConst<TYPE>::type getValue() { return DEFAULT; } \ 222dc9ec47SChiaHungDuan }; \ 232dc9ec47SChiaHungDuan template <typename Config> \ 24aa8cffb9SChiaHungDuan struct NAME##State< \ 25aa8cffb9SChiaHungDuan Config, typename assertSameType<decltype(Config::MEMBER), TYPE>::type> { \ 262dc9ec47SChiaHungDuan static constexpr removeConst<TYPE>::type getValue() { \ 272dc9ec47SChiaHungDuan return Config::MEMBER; \ 282dc9ec47SChiaHungDuan } \ 292dc9ec47SChiaHungDuan }; 302dc9ec47SChiaHungDuan 312dc9ec47SChiaHungDuan #define OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, MEMBER) \ 322dc9ec47SChiaHungDuan template <typename Config, typename Void = void> struct NAME##Type { \ 332dc9ec47SChiaHungDuan static constexpr bool enabled() { return false; } \ 342dc9ec47SChiaHungDuan using NAME = DEFAULT; \ 352dc9ec47SChiaHungDuan }; \ 362dc9ec47SChiaHungDuan template <typename Config> \ 372dc9ec47SChiaHungDuan struct NAME##Type<Config, \ 382dc9ec47SChiaHungDuan typename voidAdaptor<typename Config::MEMBER>::type> { \ 392dc9ec47SChiaHungDuan static constexpr bool enabled() { return true; } \ 402dc9ec47SChiaHungDuan using NAME = typename Config::MEMBER; \ 412dc9ec47SChiaHungDuan }; 422dc9ec47SChiaHungDuan 432dc9ec47SChiaHungDuan template <typename AllocatorConfig> struct BaseConfig { 442dc9ec47SChiaHungDuan #define BASE_REQUIRED_TEMPLATE_TYPE(NAME) \ 452dc9ec47SChiaHungDuan template <typename T> using NAME = typename AllocatorConfig::template NAME<T>; 462dc9ec47SChiaHungDuan 472dc9ec47SChiaHungDuan #define BASE_OPTIONAL(TYPE, NAME, DEFAULT) \ 482dc9ec47SChiaHungDuan OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME) \ 492dc9ec47SChiaHungDuan static constexpr removeConst<TYPE>::type get##NAME() { \ 502dc9ec47SChiaHungDuan return NAME##State<AllocatorConfig>::getValue(); \ 512dc9ec47SChiaHungDuan } 522dc9ec47SChiaHungDuan 532dc9ec47SChiaHungDuan #include "allocator_config.def" 542dc9ec47SChiaHungDuan }; // BaseConfig 552dc9ec47SChiaHungDuan 562dc9ec47SChiaHungDuan template <typename AllocatorConfig> struct PrimaryConfig { 572dc9ec47SChiaHungDuan // TODO: Pass this flag through template argument to remove this hard-coded 582dc9ec47SChiaHungDuan // function. 592dc9ec47SChiaHungDuan static constexpr bool getMaySupportMemoryTagging() { 602dc9ec47SChiaHungDuan return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging(); 612dc9ec47SChiaHungDuan } 622dc9ec47SChiaHungDuan 632dc9ec47SChiaHungDuan #define PRIMARY_REQUIRED_TYPE(NAME) \ 642dc9ec47SChiaHungDuan using NAME = typename AllocatorConfig::Primary::NAME; 652dc9ec47SChiaHungDuan 662dc9ec47SChiaHungDuan #define PRIMARY_REQUIRED(TYPE, NAME) \ 672dc9ec47SChiaHungDuan static constexpr removeConst<TYPE>::type get##NAME() { \ 682dc9ec47SChiaHungDuan return AllocatorConfig::Primary::NAME; \ 692dc9ec47SChiaHungDuan } 702dc9ec47SChiaHungDuan 712dc9ec47SChiaHungDuan #define PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT) \ 722dc9ec47SChiaHungDuan OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME) \ 732dc9ec47SChiaHungDuan static constexpr removeConst<TYPE>::type get##NAME() { \ 742dc9ec47SChiaHungDuan return NAME##State<typename AllocatorConfig::Primary>::getValue(); \ 752dc9ec47SChiaHungDuan } 762dc9ec47SChiaHungDuan 772dc9ec47SChiaHungDuan #define PRIMARY_OPTIONAL_TYPE(NAME, DEFAULT) \ 782dc9ec47SChiaHungDuan OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, NAME) \ 792dc9ec47SChiaHungDuan static constexpr bool has##NAME() { \ 802dc9ec47SChiaHungDuan return NAME##Type<typename AllocatorConfig::Primary>::enabled(); \ 812dc9ec47SChiaHungDuan } \ 822dc9ec47SChiaHungDuan using NAME = typename NAME##Type<typename AllocatorConfig::Primary>::NAME; 832dc9ec47SChiaHungDuan 842dc9ec47SChiaHungDuan #include "allocator_config.def" 852dc9ec47SChiaHungDuan 862dc9ec47SChiaHungDuan }; // PrimaryConfig 872dc9ec47SChiaHungDuan 882dc9ec47SChiaHungDuan template <typename AllocatorConfig> struct SecondaryConfig { 892dc9ec47SChiaHungDuan // TODO: Pass this flag through template argument to remove this hard-coded 902dc9ec47SChiaHungDuan // function. 912dc9ec47SChiaHungDuan static constexpr bool getMaySupportMemoryTagging() { 922dc9ec47SChiaHungDuan return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging(); 932dc9ec47SChiaHungDuan } 942dc9ec47SChiaHungDuan 952dc9ec47SChiaHungDuan #define SECONDARY_REQUIRED_TEMPLATE_TYPE(NAME) \ 962dc9ec47SChiaHungDuan template <typename T> \ 972dc9ec47SChiaHungDuan using NAME = typename AllocatorConfig::Secondary::template NAME<T>; 982dc9ec47SChiaHungDuan #include "allocator_config.def" 992dc9ec47SChiaHungDuan 1002dc9ec47SChiaHungDuan struct CacheConfig { 1012dc9ec47SChiaHungDuan // TODO: Pass this flag through template argument to remove this hard-coded 1022dc9ec47SChiaHungDuan // function. 1032dc9ec47SChiaHungDuan static constexpr bool getMaySupportMemoryTagging() { 1042dc9ec47SChiaHungDuan return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging(); 1052dc9ec47SChiaHungDuan } 1062dc9ec47SChiaHungDuan 1072dc9ec47SChiaHungDuan #define SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT) \ 1082dc9ec47SChiaHungDuan OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, Cache::NAME) \ 1092dc9ec47SChiaHungDuan static constexpr removeConst<TYPE>::type get##NAME() { \ 1102dc9ec47SChiaHungDuan return NAME##State<typename AllocatorConfig::Secondary>::getValue(); \ 1112dc9ec47SChiaHungDuan } 1122dc9ec47SChiaHungDuan #include "allocator_config.def" 1132dc9ec47SChiaHungDuan }; // CacheConfig 1142dc9ec47SChiaHungDuan }; // SecondaryConfig 1152dc9ec47SChiaHungDuan 1162dc9ec47SChiaHungDuan #undef OPTIONAL_TEMPLATE 1172dc9ec47SChiaHungDuan #undef OPTIONAL_TEMPLATE_TYPE 1182dc9ec47SChiaHungDuan 1192dc9ec47SChiaHungDuan } // namespace scudo 1202dc9ec47SChiaHungDuan 1212dc9ec47SChiaHungDuan #endif // SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ 122