[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 void getSizeType(const %1% &container, size_t& returnArg); """ func = """ template void getSizeType(const %1% &container, size_t& returnArg) { SAVE_SIZE(sizeof(%1%)); 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 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>(category)); """ [[codegen.processor]] type = "types::st::VarInt" func = """ el.pointer = std::get(d.val).value; """ [[codegen.processor]] type = "types::st::VarInt" func = """ uint64_t capacity = std::get(d.val).value; el.container_stats.emplace(result::Element::ContainerStats { .capacity = capacity }); """ [[codegen.processor]] type = "types::st::VarInt" func = """ el.container_stats->length = std::get(d.val).value; """ [[codegen.processor]] type = "types::st::VarInt" func = """ using CharType = T0; enum class Category : uint8_t { InlinedStorage, OwnedHeapStorage, ReferenceCountedStorage, AlreadyAttributed, }; auto category = static_cast(std::get(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 """