object-introspection/types/set_type.toml
Jake Hillion b117150f83 tbv2: add dynamic context passed through all functions (#410)
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
2023-11-16 08:03:32 -08:00

119 lines
3.7 KiB
TOML

[info]
type_name = "std::set"
stub_template_params = [1,2]
ctype = "SET_TYPE"
header = "set"
# Old:
typeName = "std::set<"
ns = ["namespace std"]
numTemplateParams = 1
replaceTemplateParamIndex = [1]
allocatorIndex = 2
[codegen]
decl = """
template<typename Key, typename Compare, typename Alloc>
void getSizeType(const %1%<Key, Compare, Alloc> &container, size_t& returnArg);
"""
func = """
template<typename Key, typename Compare, typename Alloc>
void getSizeType(const %1%<Key, Compare, Alloc> &container, size_t& returnArg)
{
constexpr size_t nodeSize = sizeof(typename %1%<Key, Compare, Alloc>::node_type);
size_t numElems = container.size();
SAVE_SIZE(sizeof(%1%<Key, Compare, Alloc>) + (nodeSize * numElems));
SAVE_DATA((uintptr_t)nodeSize);
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.size());
// The double ampersand is needed otherwise this loop doesn't work with
// vector<bool>
for (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::List<DB, typename TypeHandler<Ctx, T0>::type>"
func = """
#ifdef __GLIBCXX__
/* We don't have access to the _Rb_tree_node struct, so we manually re-create it
* to get the effective size of a set entry. Is there a better way to do this?
*
* https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00716_source.html#l00216
* From the source of <bits/stl_tree.h>, an _Rb_tree_node has the following members:
*/
struct OI_Rb_tree_node {
using _Rb_tree_color = int; // enum
using _Base_ptr = std::nullptr_t; // pointer
_Rb_tree_color _M_color; // from parent _Rb_tree_node_base
_Base_ptr _M_parent; // from parent _Rb_tree_node_base
_Base_ptr _M_left; // from parent _Rb_tree_node_base
_Base_ptr _M_right; // from parent _Rb_tree_node_base
T0 _M_value;
};
static constexpr size_t element_size = sizeof(OI_Rb_tree_node);
#elif _LIBCPP_VERSION
static_assert(false && "libc++ is currently not supported");
/* We don't have access to the __tree_node struct, so we manually re-create it
* to get the effective size of a set entry. Is there a better way to do this?
*
* https://github.com/llvm/llvm-project/blob/1b10920164695a487669405223f8bbe93799430c/libcxx/include/__tree#L729-L781
* From the source of <__tree>, a __tree_node has the following members:
*/
struct OI__tree_node {
using pointer = std::nullptr_t; // pointer
using __parent_pointer = std::nullptr_t; // pointer
pointer __left_; // from parent __tree_end_node
pointer __right_; // from parent __tree_node_base
__parent_pointer __parent_; // from parent __tree_node_base
bool __is_black_; // from parent __tree_node_base
T0 __value_;
};
static constexpr size_t element_size = sizeof(OI__tree_node);
#else
static_assert(false && "No known element_size for sets. See types/set_type.toml");
#endif
static constexpr auto childField = make_field<Ctx, T0>("[]");
auto list = std::get<ParsedData::List>(d.val);
el.container_stats.emplace(result::Element::ContainerStats {
.capacity = list.length,
.length = list.length,
});
el.exclusive_size += el.container_stats->length * (element_size - sizeof(T0));
for (size_t i = 0; i < list.length; i++)
stack_ins(childField);
"""