object-introspection/types/fb_string_type.toml
Janeczko Jakub cc401c1e5b
fix string type sso computation (#469)
* fix string type sso computation

* fix rest of sbo/sso calculation

* make placement of uintptr_t cast consistent

* separate check-inline into function
2024-01-31 11:19:24 +00:00

112 lines
3.0 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 = isStorageInline(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>
"""