-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[scudo] Refactor allocator config to support optional flags #81805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ChiaHungDuan
merged 6 commits into
llvm:main
from
ChiaHungDuan:allocator-config-refactor
Mar 13, 2024
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
159c068
[scudo] Refactor allocator config to support optional flags
ChiaHungDuan e479863
[scudo] Minor macro clean up
ChiaHungDuan fff15fd
Fix template specialization for optional type and add a test
ChiaHungDuan afe7a67
Comment revised and fix lint
ChiaHungDuan 3ca01a7
Slightly improve the test coverage
ChiaHungDuan 60687e7
Address Review Comment
ChiaHungDuan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
//===-- allocator_config.def ------------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file defines all the flags and types supported in Scudo. For optional | ||
// flags and types, only explicitly define them when interested (i.e., unused | ||
// optional flags or types can be skipped). | ||
|
||
#ifndef BASE_REQUIRED_TEMPLATE_TYPE | ||
#define BASE_REQUIRED_TEMPLATE_TYPE(...) | ||
#endif | ||
#ifndef BASE_OPTIONAL | ||
#define BASE_OPTIONAL(...) | ||
#endif | ||
#ifndef PRIMARY_REQUIRED_TYPE | ||
#define PRIMARY_REQUIRED_TYPE(...) | ||
#endif | ||
#ifndef PRIMARY_REQUIRED | ||
#define PRIMARY_REQUIRED(...) | ||
#endif | ||
#ifndef PRIMARY_OPTIONAL | ||
#define PRIMARY_OPTIONAL(...) | ||
#endif | ||
#ifndef PRIMARY_OPTIONAL_TYPE | ||
#define PRIMARY_OPTIONAL_TYPE(...) | ||
#endif | ||
#ifndef SECONDARY_REQUIRED_TEMPLATE_TYPE | ||
#define SECONDARY_REQUIRED_TEMPLATE_TYPE(...) | ||
#endif | ||
#ifndef SECONDARY_CACHE_OPTIONAL | ||
#define SECONDARY_CACHE_OPTIONAL(...) | ||
#endif | ||
|
||
// BASE_REQUIRED_TEMPLATE_TYPE(NAME) | ||
// | ||
// Thread-Specific Data Registry used, shared or exclusive. | ||
BASE_REQUIRED_TEMPLATE_TYPE(TSDRegistryT) | ||
|
||
// Defines the type of Primary allocator to use. | ||
BASE_REQUIRED_TEMPLATE_TYPE(PrimaryT) | ||
|
||
// Defines the type of Secondary allocator to use. | ||
BASE_REQUIRED_TEMPLATE_TYPE(SecondaryT) | ||
|
||
// BASE_OPTIONAL(TYPE, NAME, DEFAULT) | ||
// | ||
// Indicates possible support for Memory Tagging. | ||
BASE_OPTIONAL(const bool, MaySupportMemoryTagging, false) | ||
|
||
// PRIMARY_REQUIRED_TYPE(NAME) | ||
// | ||
// SizeClassMap to use with the Primary. | ||
PRIMARY_REQUIRED_TYPE(SizeClassMap) | ||
|
||
// Defines the type and scale of a compact pointer. A compact pointer can | ||
// be understood as the offset of a pointer within the region it belongs | ||
// to, in increments of a power-of-2 scale. See `CompactPtrScale` also. | ||
PRIMARY_REQUIRED_TYPE(CompactPtrT) | ||
|
||
// PRIMARY_REQUIRED(TYPE, NAME) | ||
// | ||
// The scale of a compact pointer. E.g., Ptr = Base + (CompactPtr << Scale). | ||
PRIMARY_REQUIRED(const uptr, CompactPtrScale) | ||
|
||
// Log2 of the size of a size class region, as used by the Primary. | ||
PRIMARY_REQUIRED(const uptr, RegionSizeLog) | ||
|
||
// Conceptually, a region will be divided into groups based on the address | ||
// range. Each allocation consumes blocks in the same group until exhaustion | ||
// then it pops out blocks in a new group. Therefore, `GroupSizeLog` is always | ||
// smaller or equal to `RegionSizeLog`. Note that `GroupSizeLog` needs to be | ||
// equal to `RegionSizeLog` for SizeClassAllocator32 because of certain | ||
// constraints. | ||
PRIMARY_REQUIRED(const uptr, GroupSizeLog) | ||
|
||
// Call map for user memory with at least this size. Only used with primary64. | ||
PRIMARY_REQUIRED(const uptr, MapSizeIncrement) | ||
|
||
// Defines the minimal & maximal release interval that can be set. | ||
PRIMARY_REQUIRED(const s32, MinReleaseToOsIntervalMs) | ||
PRIMARY_REQUIRED(const s32, MaxReleaseToOsIntervalMs) | ||
|
||
// PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT) | ||
// | ||
// Indicates support for offsetting the start of a region by a random number of | ||
// pages. Only used with primary64. | ||
PRIMARY_OPTIONAL(const bool, EnableRandomOffset, false) | ||
|
||
// PRIMARY_OPTIONAL_TYPE(NAME, DEFAULT) | ||
// | ||
// Use condition variable to shorten the waiting time of refillment of | ||
// freelist. Note that this depends on the implementation of condition | ||
// variable on each platform and the performance may vary so that it does not | ||
// guarantee a performance benefit. | ||
PRIMARY_OPTIONAL_TYPE(ConditionVariableT, ConditionVariableDummy) | ||
|
||
// SECONDARY_REQUIRED_TEMPLATE_TYPE(NAME) | ||
// | ||
// Defines the type of Secondary Cache to use. | ||
SECONDARY_REQUIRED_TEMPLATE_TYPE(CacheT) | ||
|
||
// SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT) | ||
// | ||
// Defines the type of cache used by the Secondary. Some additional | ||
// configuration entries can be necessary depending on the Cache. | ||
SECONDARY_CACHE_OPTIONAL(const u32, EntriesArraySize, 0) | ||
SECONDARY_CACHE_OPTIONAL(const u32, QuarantineSize, 0) | ||
SECONDARY_CACHE_OPTIONAL(const u32, DefaultMaxEntriesCount, 0) | ||
SECONDARY_CACHE_OPTIONAL(const u32, DefaultMaxEntrySize, 0) | ||
SECONDARY_CACHE_OPTIONAL(const s32, MinReleaseToOsIntervalMs, INT32_MIN) | ||
SECONDARY_CACHE_OPTIONAL(const s32, MaxReleaseToOsIntervalMs, INT32_MAX) | ||
|
||
#undef SECONDARY_CACHE_OPTIONAL | ||
#undef SECONDARY_REQUIRED_TEMPLATE_TYPE | ||
#undef PRIMARY_OPTIONAL_TYPE | ||
#undef PRIMARY_OPTIONAL | ||
#undef PRIMARY_REQUIRED | ||
#undef PRIMARY_REQUIRED_TYPE | ||
#undef BASE_OPTIONAL | ||
#undef BASE_REQUIRED_TEMPLATE_TYPE |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
//===-- allocator_config_wrapper.h ------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ | ||
#define SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ | ||
|
||
#include "condition_variable.h" | ||
#include "internal_defs.h" | ||
#include "secondary.h" | ||
|
||
namespace { | ||
|
||
template <typename T> struct removeConst { | ||
using type = T; | ||
}; | ||
template <typename T> struct removeConst<const T> { | ||
using type = T; | ||
}; | ||
|
||
// This is only used for SFINAE when detecting if a type is defined. | ||
template <typename T> struct voidAdaptor { | ||
using type = void; | ||
}; | ||
|
||
} // namespace | ||
|
||
namespace scudo { | ||
|
||
#define OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, MEMBER) \ | ||
template <typename Config, typename = TYPE> struct NAME##State { \ | ||
static constexpr removeConst<TYPE>::type getValue() { return DEFAULT; } \ | ||
}; \ | ||
template <typename Config> \ | ||
struct NAME##State<Config, decltype(Config::MEMBER)> { \ | ||
static constexpr removeConst<TYPE>::type getValue() { \ | ||
return Config::MEMBER; \ | ||
} \ | ||
}; | ||
|
||
#define OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, MEMBER) \ | ||
template <typename Config, typename Void = void> struct NAME##Type { \ | ||
static constexpr bool enabled() { return false; } \ | ||
using NAME = DEFAULT; \ | ||
}; \ | ||
template <typename Config> \ | ||
struct NAME##Type<Config, \ | ||
typename voidAdaptor<typename Config::MEMBER>::type> { \ | ||
static constexpr bool enabled() { return true; } \ | ||
using NAME = typename Config::MEMBER; \ | ||
}; | ||
|
||
template <typename AllocatorConfig> struct BaseConfig { | ||
#define BASE_REQUIRED_TEMPLATE_TYPE(NAME) \ | ||
template <typename T> using NAME = typename AllocatorConfig::template NAME<T>; | ||
|
||
#define BASE_OPTIONAL(TYPE, NAME, DEFAULT) \ | ||
OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME) \ | ||
static constexpr removeConst<TYPE>::type get##NAME() { \ | ||
return NAME##State<AllocatorConfig>::getValue(); \ | ||
} | ||
|
||
#include "allocator_config.def" | ||
}; // BaseConfig | ||
|
||
template <typename AllocatorConfig> struct PrimaryConfig { | ||
// TODO: Pass this flag through template argument to remove this hard-coded | ||
// function. | ||
static constexpr bool getMaySupportMemoryTagging() { | ||
return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging(); | ||
} | ||
|
||
#define PRIMARY_REQUIRED_TYPE(NAME) \ | ||
using NAME = typename AllocatorConfig::Primary::NAME; | ||
|
||
#define PRIMARY_REQUIRED(TYPE, NAME) \ | ||
static constexpr removeConst<TYPE>::type get##NAME() { \ | ||
return AllocatorConfig::Primary::NAME; \ | ||
} | ||
|
||
#define PRIMARY_OPTIONAL(TYPE, NAME, DEFAULT) \ | ||
OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, NAME) \ | ||
static constexpr removeConst<TYPE>::type get##NAME() { \ | ||
return NAME##State<typename AllocatorConfig::Primary>::getValue(); \ | ||
} | ||
|
||
#define PRIMARY_OPTIONAL_TYPE(NAME, DEFAULT) \ | ||
OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, NAME) \ | ||
static constexpr bool has##NAME() { \ | ||
return NAME##Type<typename AllocatorConfig::Primary>::enabled(); \ | ||
} \ | ||
using NAME = typename NAME##Type<typename AllocatorConfig::Primary>::NAME; | ||
|
||
#include "allocator_config.def" | ||
|
||
}; // PrimaryConfig | ||
|
||
template <typename AllocatorConfig> struct SecondaryConfig { | ||
// TODO: Pass this flag through template argument to remove this hard-coded | ||
// function. | ||
static constexpr bool getMaySupportMemoryTagging() { | ||
return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging(); | ||
} | ||
|
||
#define SECONDARY_REQUIRED_TEMPLATE_TYPE(NAME) \ | ||
template <typename T> \ | ||
using NAME = typename AllocatorConfig::Secondary::template NAME<T>; | ||
#include "allocator_config.def" | ||
|
||
struct CacheConfig { | ||
// TODO: Pass this flag through template argument to remove this hard-coded | ||
// function. | ||
static constexpr bool getMaySupportMemoryTagging() { | ||
return BaseConfig<AllocatorConfig>::getMaySupportMemoryTagging(); | ||
} | ||
|
||
#define SECONDARY_CACHE_OPTIONAL(TYPE, NAME, DEFAULT) \ | ||
OPTIONAL_TEMPLATE(TYPE, NAME, DEFAULT, Cache::NAME) \ | ||
static constexpr removeConst<TYPE>::type get##NAME() { \ | ||
return NAME##State<typename AllocatorConfig::Secondary>::getValue(); \ | ||
} | ||
#include "allocator_config.def" | ||
}; // CacheConfig | ||
}; // SecondaryConfig | ||
|
||
#undef OPTIONAL_TEMPLATE | ||
#undef OPTIONAL_TEMPLATE_TYPE | ||
|
||
} // namespace scudo | ||
|
||
#endif // SCUDO_ALLOCATOR_CONFIG_WRAPPER_H_ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.