mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-09-19 19:19:05 +01:00
592e182e0f
Summary: tbv2: replace DB template param with Ctx TreeBuilder v2 adds a DB template parameter to every function. This is used as part of the static type to decide what type of DataBuffer is being used: currently `BackInserterDataBuffer<std::vector<uint8_t>>` for OIL and it would be `DataSegmentDataBuffer` for OID. This change replaces the `DB` template parameter with a more general `Ctx`. Due to issues with dependent naming it also adds a `using DB` to each `TypeHandler` which has the same function as before. This allows us to add more "static context" (typedefs and constants) to functions without changing this signature again, because changing the signature of everything is a massive pain. Currently this change achieves nothing because Ctx contains only DB in a static wrapper. In the next change I'm going to pass a reference of type Ctx around to add a "dynamic context" to invocations which will contain the pointer array. In future we'll then be able to add either static or dynamic context without any signature adjustments. Test Plan: - CI --- Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebookexperimental/object-introspection/pull/409). * https://github.com/facebookexperimental/object-introspection/issues/410 * __->__ https://github.com/facebookexperimental/object-introspection/issues/409 Reviewed By: ajor Differential Revision: D51352092 Pulled By: JakeHillion
107 lines
3.2 KiB
TOML
107 lines
3.2 KiB
TOML
[info]
|
|
type_name = "std::unordered_set"
|
|
stub_template_params = [1,2,3]
|
|
ctype = "UNORDERED_SET_TYPE"
|
|
header = "unordered_set"
|
|
|
|
# Old:
|
|
typeName = "std::unordered_set<"
|
|
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([&it](auto ret) {
|
|
return OIInternal::getSizeType<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);
|
|
"""
|