tbv2: fix exclusive size of elements in containers

This commit is contained in:
Jake Hillion 2023-10-16 10:42:24 -07:00 committed by Jake Hillion
parent e867178ebd
commit f7bb1e75ad
3 changed files with 58 additions and 19 deletions

View File

@ -188,6 +188,22 @@ void genDecls(const TypeGraph& typeGraph, std::string& code) {
}
}
namespace {
size_t calculateExclusiveSize(const Type& t) {
if (const auto* c = dynamic_cast<const Class*>(&t)) {
return std::accumulate(c->members.cbegin(), c->members.cend(), 0,
[](size_t a, const auto& m) {
if (m.name.starts_with(AddPadding::MemberPrefix))
return a + m.type().size();
return a;
});
}
return t.size();
}
} // namespace
void genNames(const TypeGraph& typeGraph, std::string& code) {
code += R"(
template <typename T>
@ -206,6 +222,26 @@ struct NameProvider {};
}
}
void genExclusiveSizes(const TypeGraph& typeGraph, std::string& code) {
code += R"(
template <typename T>
struct ExclusiveSizeProvider {
static constexpr size_t size = sizeof(T);
};
)";
for (const Type& t : typeGraph.finalTypes) {
size_t exclusiveSize = calculateExclusiveSize(t);
if (exclusiveSize != t.size()) {
code += "template <> struct ExclusiveSizeProvider<";
code += t.name();
code += "> { static constexpr size_t size = ";
code += std::to_string(exclusiveSize);
code += "; };\n";
}
}
}
/*
* Generates a declaration for a given fully-qualified type.
*
@ -714,22 +750,6 @@ void CodeGen::genClassStaticType(const Class& c, std::string& code) {
}
}
namespace {
size_t calculateExclusiveSize(const Type& t) {
if (const auto* c = dynamic_cast<const Class*>(&t)) {
return std::accumulate(c->members.cbegin(), c->members.cend(), 0,
[](size_t a, const auto& m) {
if (m.name.starts_with(AddPadding::MemberPrefix))
return a + m.type().size();
return a;
});
}
return t.size();
}
} // namespace
void CodeGen::genClassTreeBuilderInstructions(const Class& c,
std::string& code) {
code += " private:\n";
@ -1047,7 +1067,7 @@ template <typename DB, typename T>
constexpr inst::Field make_field(std::string_view name) {
return inst::Field{
sizeof(T),
sizeof(T), // TODO: this is incorrect for excl size
ExclusiveSizeProvider<T>::size,
name,
NameProvider<T>::names,
TypeHandler<DB, T>::fields,
@ -1245,8 +1265,10 @@ void CodeGen::generate(
genDecls(typeGraph, code);
genDefs(typeGraph, code);
genStaticAsserts(typeGraph, code);
if (config_.features[Feature::TreeBuilderV2])
if (config_.features[Feature::TreeBuilderV2]) {
genNames(typeGraph, code);
genExclusiveSizes(typeGraph, code);
}
if (config_.features[Feature::TypedDataSegment]) {
addStandardTypeHandlers(typeGraph, config_.features, code);

View File

@ -1,4 +1,13 @@
includes = ["vector"]
definitions = '''
struct SimpleStruct {
int a;
char b;
long long c;
};
'''
[cases]
[cases.int_empty]
param_types = ["const std::vector<int>&"]
@ -14,6 +23,15 @@ includes = ["vector"]
{"staticSize":4, "exclusiveSize":4},
{"staticSize":4, "exclusiveSize":4}
]}]'''
[cases.struct_some]
param_types = ["const std::vector<SimpleStruct>&"]
setup = "return {{{}, {}, {}}};"
expect_json = '[{"staticSize":24, "dynamicSize":48, "length":3, "capacity":3, "elementStaticSize":16}]'
expect_json_v2 = '''[{"staticSize":24, "exclusiveSize":24, "length":3, "capacity":3, "members":[
{"staticSize":16, "exclusiveSize":3},
{"staticSize":16, "exclusiveSize":3},
{"staticSize":16, "exclusiveSize":3}
]}]'''
[cases.bool_empty]
skip = true # https://github.com/facebookexperimental/object-introspection/issues/14
param_types = ["const std::vector<bool>&"]

View File

@ -27,7 +27,6 @@ includes = ["vector"]
[cases]
[cases.a]
oil_skip = "oil gets the exclusive size of vector subfields wrong" # https://github.com/facebookexperimental/object-introspection/issues/301
param_types = ["const Foo&"]
setup = '''
Foo foo;