simpler and more robust identification of function parameters for AST profiling

This commit is contained in:
Vern Paxson 2024-08-15 13:02:09 -07:00 committed by Arne Welzel
parent 691a4003b7
commit 2477213619
4 changed files with 27 additions and 38 deletions

View file

@ -24,11 +24,12 @@ p_hash_type p_hash(const Obj* o) {
ProfileFunc::ProfileFunc(const Func* func, const StmtPtr& body, bool _abs_rec_fields) {
profiled_func = func;
profiled_scope = profiled_func->GetScope();
profiled_body = body.get();
abs_rec_fields = _abs_rec_fields;
auto ft = func->GetType()->AsFuncType();
auto& fcaps = ft->GetCaptures();
profiled_func_t = cast_intrusive<FuncType>(func->GetType());
auto& fcaps = profiled_func_t->GetCaptures();
if ( fcaps ) {
int offset = 0;
@ -40,7 +41,7 @@ ProfileFunc::ProfileFunc(const Func* func, const StmtPtr& body, bool _abs_rec_fi
}
}
Profile(ft, body);
Profile(profiled_func_t.get(), body);
}
ProfileFunc::ProfileFunc(const Stmt* s, bool _abs_rec_fields) {
@ -56,6 +57,9 @@ ProfileFunc::ProfileFunc(const Expr* e, bool _abs_rec_fields) {
if ( e->Tag() == EXPR_LAMBDA ) {
auto func = e->AsLambdaExpr();
ASSERT(func->GetType()->Tag() == TYPE_FUNC);
profiled_scope = func->GetScope();
profiled_func_t = cast_intrusive<FuncType>(func->GetType());
int offset = 0;
@ -75,6 +79,11 @@ ProfileFunc::ProfileFunc(const Expr* e, bool _abs_rec_fields) {
void ProfileFunc::Profile(const FuncType* ft, const StmtPtr& body) {
num_params = ft->Params()->NumFields();
auto& ov = profiled_scope->OrderedVars();
for ( int i = 0; i < num_params; ++i )
params.insert(ov[i].get());
TrackType(ft);
body->Traverse(this);
}
@ -181,28 +190,10 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
TrackType(id->GetType());
if ( id->IsGlobal() ) {
globals.insert(id);
all_globals.insert(id);
const auto& t = id->GetType();
if ( t->Tag() == TYPE_FUNC )
if ( t->AsFuncType()->Flavor() == FUNC_FLAVOR_EVENT )
events.insert(id->Name());
PreID(id);
break;
}
// This is a tad ugly. Unfortunately due to the weird way
// that Zeek function *declarations* work, there's no reliable
// way to get the list of parameters for a function *definition*,
// since they can have different names than what's present in the
// declaration. So we identify them directly, by knowing that
// they come at the beginning of the frame ... and being careful
// to avoid misconfusing a lambda capture with a low frame offset
// as a parameter.
if ( captures.count(id) == 0 && id->Offset() < num_params )
params.insert(id);
locals.insert(id);
break;
@ -426,11 +417,6 @@ TraversalCode ProfileFunc::PreExpr(const Expr* e) {
for ( const auto& i : l->OuterIDs() ) {
locals.insert(i);
TrackID(i);
// See above re EXPR_NAME regarding the following
// logic.
if ( captures.count(i) == 0 && i->Offset() < num_params )
params.insert(i);
}
// In general, we don't want to recurse into the body.