Merge remote-tracking branch 'origin/topic/vern/ZAM-frame-opt'

* origin/topic/vern/ZAM-frame-opt:
  reduce interpreter frames for compiled function bodies
This commit is contained in:
Tim Wojtulewicz 2022-04-05 18:04:15 -07:00
commit e0ad92c9f4
5 changed files with 32 additions and 27 deletions

View file

@ -1,3 +1,7 @@
5.0.0-dev.222 | 2022-04-05 18:04:15 -0700
* reduce interpreter frames for compiled function bodies (Vern Paxson, Corelight)
5.0.0-dev.219 | 2022-04-05 16:07:48 -0700 5.0.0-dev.219 | 2022-04-05 16:07:48 -0700
* Correct origin documentation of the version field in the HTTP log. (Christian Kreibich, Corelight) * Correct origin documentation of the version field in the HTTP log. (Christian Kreibich, Corelight)

View file

@ -1 +1 @@
5.0.0-dev.219 5.0.0-dev.222

View file

@ -508,6 +508,8 @@ static void analyze_scripts_for_ZAM(std::unique_ptr<ProfileFuncs>& pfs)
if ( ! did_one ) if ( ! did_one )
reporter->FatalError("no matching functions/files for -O ZAM"); reporter->FatalError("no matching functions/files for -O ZAM");
finalize_functions(funcs);
} }
void analyze_scripts() void analyze_scripts()

View file

@ -18,7 +18,7 @@ namespace zeek::detail
// can't do this when compiling individual functions since for event handlers // can't do this when compiling individual functions since for event handlers
// and hooks it needs to be computed across all of their bodies. // and hooks it needs to be computed across all of their bodies.
// //
// Note, this is now not really needed, because we no longer use any // Note, this is now not actually needed, because we no longer use any
// interpreter frame entries other than those for the function's arguments. // interpreter frame entries other than those for the function's arguments.
// We keep the code in case that changes, for example when deciding to // We keep the code in case that changes, for example when deciding to
// compile functions that include "return when" conditions. // compile functions that include "return when" conditions.
@ -26,40 +26,39 @@ std::unordered_map<const Func*, int> remapped_intrp_frame_sizes;
void finalize_functions(const std::vector<FuncInfo>& funcs) void finalize_functions(const std::vector<FuncInfo>& funcs)
{ {
// Given we've now compiled all of the function bodies, we // Given we've now compiled all of the function bodies, we can reset
// can reset the interpreter frame sizes of each function // the interpreter frame sizes to what's actually used. This can be
// to be the maximum needed to accommodate all of its // a huge win for massively inlined event handlers, which otherwise
// remapped bodies. // can have frames sized for 100s of variables, none of which (other
// than the arguments) need TLC such as via calls to Frame::Reset().
// Find any functions with bodies that weren't compiled and // Find any functions with bodies that weren't compiled and
// make sure we don't reduce their frame size. For any loaded // make sure we don't reduce their frame size.
// from ZAM save files, use the associated maximum interpreter std::unordered_set<const Func*> leave_alone;
// frame size as a minimum.
for ( auto& f : funcs )
if ( f.Body()->Tag() != STMT_ZAM )
// This function has a body that wasn't compiled,
// don't mess with its size.
leave_alone.insert(f.Func());
for ( auto& f : funcs ) for ( auto& f : funcs )
{ {
auto func = f.Func(); auto func = f.Func();
// If we have non-compiled versions of the function's body, if ( leave_alone.count(func) > 0 )
// preserve the size they need. continue;
int size = func->FrameSize();
if ( f.Body()->Tag() != STMT_ZAM && remapped_intrp_frame_sizes.count(func) > 0 &&
size > remapped_intrp_frame_sizes[func] )
remapped_intrp_frame_sizes[func] = size;
}
for ( auto& f : funcs )
{
auto func = f.Func();
if ( remapped_intrp_frame_sizes.count(func) == 0 ) if ( remapped_intrp_frame_sizes.count(func) == 0 )
// No entry for this function, keep current frame size. // No entry for this function, keep current frame size.
continue; continue;
// Note, functions with multiple bodies appear in "funcs" auto& ft = func->GetType();
// multiple times, but the following doesn't hurt to do auto& params = ft->Params();
// more than once. func->SetFrameSize(params->NumFields());
func->SetFrameSize(remapped_intrp_frame_sizes[func]);
// Don't bother processing any future instances.
leave_alone.insert(func);
} }
} }

View file

@ -34,8 +34,8 @@ public:
~ZBody() override; ~ZBody() override;
// These are split out from the constructor to allow construction // These are split out from the constructor to allow construction
// of a ZBody from either save-file full instructions (first method) // of a ZBody from either save-file full instructions (first method,
// or intermediary instructions (second method). // not currently supported) or intermediary instructions (second method).
void SetInsts(std::vector<ZInst*>& insts); void SetInsts(std::vector<ZInst*>& insts);
void SetInsts(std::vector<ZInstI*>& instsI); void SetInsts(std::vector<ZInstI*>& instsI);