mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-09-19 19:19: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
104 lines
3.2 KiB
TOML
104 lines
3.2 KiB
TOML
[info]
|
|
type_name = "folly::small_vector"
|
|
ctype = "SMALL_VEC_TYPE"
|
|
header = "folly/small_vector.h"
|
|
stub_template_params = [2]
|
|
|
|
# Old:
|
|
typeName = "folly::small_vector<"
|
|
ns = ["folly::small_vector_policy::policy_size_type", "folly::small_vector"]
|
|
numTemplateParams = 1
|
|
replaceTemplateParamIndex = []
|
|
|
|
[codegen]
|
|
decl = """
|
|
template <class V, std::size_t N, class P>
|
|
void getSizeType(const %1%<V, N, P> &container, size_t& returnArg);
|
|
"""
|
|
|
|
func = """
|
|
template <class V, std::size_t N, class P>
|
|
void getSizeType(const %1%<V, N, P> &container, size_t& returnArg)
|
|
{
|
|
SAVE_SIZE(sizeof(%1%<V, N, P>));
|
|
|
|
bool dataInlined = ((uintptr_t)container.data() >= (uintptr_t)&container) &&
|
|
((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<V, N, P>)));
|
|
if (dataInlined) {
|
|
// Don't double count inlined elements
|
|
SAVE_SIZE(-(container.size() * sizeof(V)));
|
|
} else {
|
|
// Account for wasted space in the buffer
|
|
SAVE_SIZE((container.capacity() - container.size()) * sizeof(V));
|
|
}
|
|
|
|
SAVE_DATA((uintptr_t)(N));
|
|
SAVE_DATA((uintptr_t)container.capacity());
|
|
SAVE_DATA((uintptr_t)container.size());
|
|
|
|
for (auto & it: container) {
|
|
getSizeType(it, returnArg);
|
|
}
|
|
}
|
|
"""
|
|
|
|
traversal_func = """
|
|
// If `container.data()` pointer is within the container struct,
|
|
// then the container's storage is inlined and doesn't uses the heap.
|
|
// TODO: Is there an API to get this information?
|
|
bool uses_intern_storage =
|
|
(uintptr_t)&container <= (uintptr_t)container.data() &&
|
|
(uintptr_t)container.data() < ((uintptr_t)&container + sizeof(container));
|
|
|
|
auto tail = returnArg
|
|
.write((uintptr_t)uses_intern_storage)
|
|
.write(container.capacity())
|
|
.write(container.size());
|
|
|
|
for (auto &&it: container) {
|
|
tail = tail.delegate([&ctx, &it](typename TypeHandler<Ctx, T0>::type ret) {
|
|
return OIInternal::getSizeType<Ctx>(ctx, it, ret);
|
|
});
|
|
}
|
|
|
|
return tail.finish();
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::VarInt<DB>"
|
|
func = """
|
|
// Using the container's pointer to temporarily store the uses_intern_storage boolean.
|
|
// TODO: Is there another way to pass a value across processors?
|
|
el.pointer = std::get<ParsedData::VarInt>(d.val).value;
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::VarInt<DB>"
|
|
func = """
|
|
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 = """
|
|
// Reading the `uses_intern_storage` boolean that was stored in `pointer` by the processor above.
|
|
bool uses_intern_storage = std::exchange(el.pointer.value(), (uintptr_t)0);
|
|
|
|
auto list = std::get<ParsedData::List>(d.val);
|
|
el.container_stats->length = list.length;
|
|
|
|
if (uses_intern_storage) {
|
|
// The storage is inlined, so don't double count for items using the intern storage.
|
|
el.exclusive_size -= list.length * sizeof(T0);
|
|
} else {
|
|
// The storage is heap allocated, so add any unused capacity.
|
|
el.exclusive_size += (el.container_stats->capacity - el.container_stats->length) * sizeof(T0);
|
|
}
|
|
|
|
static constexpr auto childField = make_field<Ctx, T0>("[]");
|
|
for (size_t i = 0; i < list.length; i++)
|
|
stack_ins(childField);
|
|
"""
|