codegen: remove reliance on drgn type for top level name

Currently we rely on `SymbolService::getTypeName` for getting the hash that's
included in the generated function's name. The value of this must stay the same
to match with the value expected by OIDebugger - changing it causes failure to
relocate when attaching with OID and JIT OIL.

Calculate this name in the `codegenFromDrgn` method and pass it through where
appropriate rather than passing the `drgn_type` itself through.

We don't need to name the type like that when using AoT OIL. Let's
hash the linkage name instead as that is more unique.

Test Plan:
- CI
This commit is contained in:
Jake Hillion 2023-12-19 15:00:35 +00:00 committed by Jake Hillion
parent 2060a0491e
commit 37b89d789d
2 changed files with 45 additions and 18 deletions

View File

@ -43,6 +43,9 @@
#include "type_graph/TypeIdentifier.h" #include "type_graph/TypeIdentifier.h"
#include "type_graph/Types.h" #include "type_graph/Types.h"
template <typename T>
inline constexpr bool always_false_v = false;
namespace oi::detail { namespace oi::detail {
using type_graph::AddChildren; using type_graph::AddChildren;
@ -1101,11 +1104,17 @@ void CodeGen::addTypeHandlers(const TypeGraph& typeGraph, std::string& code) {
bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType,
std::string linkageName, std::string linkageName,
std::string& code) { std::string& code) {
linkageName_ = std::move(linkageName); return codegenFromDrgn(drgnType, code, ExactName{std::move(linkageName)});
return codegenFromDrgn(drgnType, code);
} }
bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) { bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) {
return codegenFromDrgn(
drgnType, code, HashedComponent{SymbolService::getTypeName(drgnType)});
}
bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType,
std::string& code,
RootFunctionName name) {
try { try {
containerInfos_.reserve(config_.containerConfigPaths.size()); containerInfos_.reserve(config_.containerConfigPaths.size());
for (const auto& path : config_.containerConfigPaths) { for (const auto& path : config_.containerConfigPaths) {
@ -1124,7 +1133,7 @@ bool CodeGen::codegenFromDrgn(struct drgn_type* drgnType, std::string& code) {
} }
transform(typeGraph_); transform(typeGraph_);
generate(typeGraph_, code, drgnType); generate(typeGraph_, code, std::move(name));
return true; return true;
} }
@ -1213,11 +1222,9 @@ void CodeGen::transform(TypeGraph& typeGraph) {
}; };
} }
void CodeGen::generate( void CodeGen::generate(TypeGraph& typeGraph,
TypeGraph& typeGraph, std::string& code,
std::string& code, RootFunctionName rootName) {
struct drgn_type* drgnType /* TODO: this argument should not be required */
) {
code = headers::oi_OITraceCode_cpp; code = headers::oi_OITraceCode_cpp;
if (!config_.features[Feature::Library]) { if (!config_.features[Feature::Library]) {
FuncGen::DeclareExterns(code); FuncGen::DeclareExterns(code);
@ -1296,22 +1303,33 @@ void CodeGen::generate(
code += "\nusing __ROOT_TYPE__ = " + rootType.name() + ";\n"; code += "\nusing __ROOT_TYPE__ = " + rootType.name() + ";\n";
code += "} // namespace\n} // namespace OIInternal\n"; code += "} // namespace\n} // namespace OIInternal\n";
const auto typeName = SymbolService::getTypeName(drgnType); const auto& typeToHash = std::visit(
[](const auto& v) -> const std::string& {
using T = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<ExactName, T> ||
std::is_same_v<HashedComponent, T>) {
return v.name;
} else {
static_assert(always_false_v<T>, "missing visit");
}
},
rootName);
if (config_.features[Feature::TreeBuilderV2]) { if (config_.features[Feature::TreeBuilderV2]) {
FuncGen::DefineTopLevelIntrospect(code, typeName); FuncGen::DefineTopLevelIntrospect(code, typeToHash);
} else { } else {
FuncGen::DefineTopLevelGetSizeRef(code, typeName, config_.features); FuncGen::DefineTopLevelGetSizeRef(code, typeToHash, config_.features);
} }
if (config_.features[Feature::TreeBuilderV2]) { if (config_.features[Feature::TreeBuilderV2]) {
FuncGen::DefineTreeBuilderInstructions(code, FuncGen::DefineTreeBuilderInstructions(code,
typeName, typeToHash,
calculateExclusiveSize(rootType), calculateExclusiveSize(rootType),
enumerateTypeNames(rootType)); enumerateTypeNames(rootType));
} }
if (!linkageName_.empty()) if (auto* n = std::get_if<ExactName>(&rootName))
FuncGen::DefineTopLevelIntrospectNamed(code, typeName, linkageName_); FuncGen::DefineTopLevelIntrospectNamed(code, typeToHash, n->name);
if (VLOG_IS_ON(3)) { if (VLOG_IS_ON(3)) {
VLOG(3) << "Generated trace code:\n"; VLOG(3) << "Generated trace code:\n";

View File

@ -45,6 +45,14 @@ class CodeGen {
: config_(config), symbols_(symbols) { : config_(config), symbols_(symbols) {
} }
struct ExactName {
std::string name;
};
struct HashedComponent {
std::string name;
};
using RootFunctionName = std::variant<ExactName, HashedComponent>;
/* /*
* Helper function to perform all the steps required for code generation for a * Helper function to perform all the steps required for code generation for a
* single drgn_type. * single drgn_type.
@ -64,9 +72,7 @@ class CodeGen {
void transform(type_graph::TypeGraph& typeGraph); void transform(type_graph::TypeGraph& typeGraph);
void generate(type_graph::TypeGraph& typeGraph, void generate(type_graph::TypeGraph& typeGraph,
std::string& code, std::string& code,
struct drgn_type* RootFunctionName rootName);
drgnType /* TODO: this argument should not be required */
);
private: private:
type_graph::TypeGraph typeGraph_; type_graph::TypeGraph typeGraph_;
@ -76,7 +82,10 @@ class CodeGen {
std::unordered_set<const ContainerInfo*> definedContainers_; std::unordered_set<const ContainerInfo*> definedContainers_;
std::unordered_map<const type_graph::Class*, const type_graph::Member*> std::unordered_map<const type_graph::Class*, const type_graph::Member*>
thriftIssetMembers_; thriftIssetMembers_;
std::string linkageName_;
bool codegenFromDrgn(struct drgn_type* drgnType,
std::string& code,
RootFunctionName name);
void genDefsThrift(const type_graph::TypeGraph& typeGraph, std::string& code); void genDefsThrift(const type_graph::TypeGraph& typeGraph, std::string& code);
void addGetSizeFuncDefs(const type_graph::TypeGraph& typeGraph, void addGetSizeFuncDefs(const type_graph::TypeGraph& typeGraph,