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
114 lines
3.1 KiB
TOML
114 lines
3.1 KiB
TOML
[info]
|
|
type_name = "folly::basic_fbstring"
|
|
ctype = "FB_STRING_TYPE"
|
|
header = "folly/FBString.h"
|
|
|
|
# Old:
|
|
typeName = "folly::basic_fbstring<"
|
|
ns = ["folly::basic_fbstring", "folly::fbstring_core"]
|
|
numTemplateParams = 1
|
|
replaceTemplateParamIndex = []
|
|
|
|
[codegen]
|
|
decl = """
|
|
template <typename E,class T,class A,class Storage>
|
|
void getSizeType(const %1%<E, T, A, Storage> &container, size_t& returnArg);
|
|
"""
|
|
|
|
func = """
|
|
template <typename E,class T,class A,class Storage>
|
|
void getSizeType(const %1%<E, T, A, Storage> &container, size_t& returnArg)
|
|
{
|
|
SAVE_SIZE(sizeof(%1%<E, T, A, Storage>));
|
|
|
|
SAVE_DATA((uintptr_t)(container.data()));
|
|
SAVE_DATA((uintptr_t)container.capacity());
|
|
SAVE_DATA((uintptr_t)container.size());
|
|
|
|
bool inlined = ((uintptr_t)container.data() < (uintptr_t)(&container + sizeof(%1%<E, T, A, Storage>)))
|
|
&&
|
|
((uintptr_t)container.data() >= (uintptr_t)&container);
|
|
|
|
if (!inlined && ctx.pointers.add((uintptr_t)container.data())) {
|
|
SAVE_SIZE(container.capacity() * sizeof(T));
|
|
SAVE_DATA(1);
|
|
} else {
|
|
SAVE_DATA(0);
|
|
}
|
|
}
|
|
"""
|
|
|
|
traversal_func = """
|
|
// fbstring has inlining (SSO) and allocates large strings as
|
|
// reference counted strings. Reference counted strings have an
|
|
// overhead of a single std::atomic<size_t> at the beginning. To
|
|
// correctly attribute the size in the processor we need the
|
|
// following 4 categories as well as the usual metadata.
|
|
|
|
enum class Category : uint8_t {
|
|
InlinedStorage,
|
|
OwnedHeapStorage,
|
|
ReferenceCountedStorage,
|
|
AlreadyAttributed,
|
|
};
|
|
|
|
constexpr static size_t minLargeSize = 255;
|
|
size_t capacity = container.capacity();
|
|
|
|
Category category;
|
|
if (isStorageInline(container)) {
|
|
category = Category::InlinedStorage;
|
|
} else if (capacity < minLargeSize) {
|
|
category = Category::OwnedHeapStorage;
|
|
} else if (ctx.pointers.add(container.data())) {
|
|
category = Category::ReferenceCountedStorage;
|
|
} else {
|
|
category = Category::AlreadyAttributed;
|
|
}
|
|
|
|
return returnArg.write((uintptr_t)container.data())
|
|
.write(capacity)
|
|
.write(container.size())
|
|
.write(static_cast<std::underlying_type_t<Category>>(category));
|
|
"""
|
|
|
|
[[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 = """
|
|
uint64_t capacity = std::get<ParsedData::VarInt>(d.val).value;
|
|
el.container_stats.emplace(result::Element::ContainerStats { .capacity = capacity });
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::VarInt<DB>"
|
|
func = """
|
|
el.container_stats->length = std::get<ParsedData::VarInt>(d.val).value;
|
|
"""
|
|
|
|
[[codegen.processor]]
|
|
type = "types::st::VarInt<DB>"
|
|
func = """
|
|
using CharType = T0;
|
|
|
|
enum class Category : uint8_t {
|
|
InlinedStorage,
|
|
OwnedHeapStorage,
|
|
ReferenceCountedStorage,
|
|
AlreadyAttributed,
|
|
};
|
|
|
|
auto category = static_cast<Category>(std::get<ParsedData::VarInt>(d.val).value);
|
|
if (category == Category::InlinedStorage || category == Category::AlreadyAttributed)
|
|
return;
|
|
|
|
el.exclusive_size += el.container_stats->capacity * sizeof(CharType);
|
|
if (category == Category::ReferenceCountedStorage)
|
|
el.exclusive_size += 8; // 8 bytes for std::atomic<size_t>
|
|
"""
|