mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-09-19 11:09:05 +01:00
b117150f83
Summary: tbv2: add dynamic context passed through all functions Previously for we had some shared state between all requests, noticeably the pointers set. This change adds a by reference value to all requests which can hold additional mutable state. The pointers set is moved into this mutable state for OIL, which means each concurrent request will have its own pointer set. Doing things this way allows more features to be added in the future without such a big code modification. Closes https://github.com/facebookexperimental/object-introspection/issues/404 Pull Request resolved: https://github.com/facebookexperimental/object-introspection/pull/410 Test Plan: - CI Differential Revision: D51394035 Pulled By: JakeHillion fbshipit-source-id: 55d2ba9b5e056148a29dc821020cfc3d94e5175a
107 lines
3.3 KiB
TOML
107 lines
3.3 KiB
TOML
[info]
|
|
type_name = "std::unordered_multiset"
|
|
stub_template_params = [1,2,3]
|
|
ctype = "UNORDERED_MULTISET_TYPE"
|
|
header = "unordered_set"
|
|
|
|
# Old:
|
|
typeName = "std::unordered_multiset<"
|
|
ns = ["namespace std"]
|
|
numTemplateParams = 1
|
|
replaceTemplateParamIndex = [1, 2]
|
|
allocatorIndex = 3
|
|
|
|
[codegen]
|
|
decl = """
|
|
template <typename Key, typename Hasher, typename KeyEqual, typename Alloc>
|
|
void getSizeType(const %1%<Key, Hasher, KeyEqual, Alloc> &container, size_t& returnArg);
|
|
"""
|
|
|
|
func = """
|
|
template <typename Key, typename Hasher, typename KeyEqual, typename Alloc>
|
|
void getSizeType(const %1%<Key, Hasher, KeyEqual, Alloc> &container, size_t& returnArg)
|
|
{
|
|
constexpr size_t nodeSize = sizeof(typename %1%<Key, Hasher, KeyEqual, Alloc>::node_type);
|
|
size_t bucketCount = container.bucket_count();
|
|
size_t numElems = container.size();
|
|
SAVE_SIZE(sizeof(%1%<Key, Hasher, KeyEqual, Alloc>) + (numElems * nodeSize) + (bucketCount * sizeof(uintptr_t)));
|
|
|
|
SAVE_DATA((uintptr_t)nodeSize);
|
|
SAVE_DATA((uintptr_t)bucketCount);
|
|
SAVE_DATA((uintptr_t)numElems);
|
|
|
|
// The double ampersand is needed otherwise this loop doesn't work with vector<bool>
|
|
for (auto&& it: container) {
|
|
getSizeType(it, returnArg);
|
|
}
|
|
}
|
|
"""
|
|
|
|
traversal_func = """
|
|
auto tail = returnArg
|
|
.write((uintptr_t)&container)
|
|
.write(container.bucket_count())
|
|
.write(container.size());
|
|
|
|
for (const auto &it : container) {
|
|
tail = tail.delegate([&ctx, &it](auto ret) {
|
|
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
|
|
});
|
|
}
|
|
|
|
return tail.finish();
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::VarInt<DB>"
|
|
func = """
|
|
el.pointer = std::get<ParsedData::VarInt>(d.val).value;
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::VarInt<DB>"
|
|
func = """
|
|
// Using the container's capacity to temporarily store the number of buckets
|
|
// TODO: Is there another way to pass a value across processors?
|
|
el.container_stats.emplace(result::Element::ContainerStats {
|
|
.capacity = std::get<ParsedData::VarInt>(d.val).value,
|
|
});
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::List<DB, typename TypeHandler<Ctx, T0>::type>"
|
|
func = """
|
|
#ifdef __GLIBCXX__
|
|
/* Use libstdc++ implementation __details to compute the size of Nodes and Buckets.
|
|
*
|
|
* See the source of <bits/hashtable_policy.h>:
|
|
* https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00536_source.html
|
|
*/
|
|
using OI_Hash_node =
|
|
std::__detail::_Hash_node<T0, std::__cache_default<T0, T1>::value>;
|
|
|
|
using OI_bucket = std::__detail::_Hash_node_base;
|
|
|
|
static constexpr size_t element_size = sizeof(OI_Hash_node);
|
|
static constexpr size_t bucket_size = sizeof(OI_bucket);
|
|
#else
|
|
static_assert(false && "No known element_size for sets. See types/set_type.toml");
|
|
#endif
|
|
|
|
auto list = std::get<ParsedData::List>(d.val);
|
|
// Reading the bucket count that was stored in `capacity` by the processor above.
|
|
size_t bucket_count = el.container_stats->capacity;
|
|
el.exclusive_size += bucket_count * bucket_size;
|
|
el.exclusive_size += list.length * (element_size - sizeof(T0));
|
|
|
|
// Overwrite the bucket count stored in `capacity` with the actual container's values.
|
|
el.container_stats.emplace(result::Element::ContainerStats {
|
|
.capacity = list.length,
|
|
.length = list.length,
|
|
});
|
|
|
|
static constexpr auto childField = make_field<Ctx, T0>("[]");
|
|
for (size_t i = 0; i < list.length; i++)
|
|
stack_ins(childField);
|
|
"""
|