diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index 937671a600..347b0d3348 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -508,6 +508,8 @@ static void analyze_scripts_for_ZAM(std::unique_ptr& pfs) if ( ! did_one ) reporter->FatalError("no matching functions/files for -O ZAM"); + + finalize_functions(funcs); } void analyze_scripts() diff --git a/src/script_opt/ZAM/AM-Opt.cc b/src/script_opt/ZAM/AM-Opt.cc index f32ccf1fc4..3593da3dc5 100644 --- a/src/script_opt/ZAM/AM-Opt.cc +++ b/src/script_opt/ZAM/AM-Opt.cc @@ -18,7 +18,7 @@ namespace zeek::detail // can't do this when compiling individual functions since for event handlers // 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. // We keep the code in case that changes, for example when deciding to // compile functions that include "return when" conditions. @@ -26,40 +26,39 @@ std::unordered_map remapped_intrp_frame_sizes; void finalize_functions(const std::vector& funcs) { - // Given we've now compiled all of the function bodies, we - // can reset the interpreter frame sizes of each function - // to be the maximum needed to accommodate all of its - // remapped bodies. + // Given we've now compiled all of the function bodies, we can reset + // the interpreter frame sizes to what's actually used. This can be + // a huge win for massively inlined event handlers, which otherwise + // 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 - // make sure we don't reduce their frame size. For any loaded - // from ZAM save files, use the associated maximum interpreter - // frame size as a minimum. + // make sure we don't reduce their frame size. + std::unordered_set leave_alone; + + 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 ) { auto func = f.Func(); - // If we have non-compiled versions of the function's body, - // preserve the size they need. - 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 ( leave_alone.count(func) > 0 ) + continue; if ( remapped_intrp_frame_sizes.count(func) == 0 ) // No entry for this function, keep current frame size. continue; - // Note, functions with multiple bodies appear in "funcs" - // multiple times, but the following doesn't hurt to do - // more than once. - func->SetFrameSize(remapped_intrp_frame_sizes[func]); + auto& ft = func->GetType(); + auto& params = ft->Params(); + func->SetFrameSize(params->NumFields()); + + // Don't bother processing any future instances. + leave_alone.insert(func); } } diff --git a/src/script_opt/ZAM/ZBody.h b/src/script_opt/ZAM/ZBody.h index 3e39bc8b03..11699a848b 100644 --- a/src/script_opt/ZAM/ZBody.h +++ b/src/script_opt/ZAM/ZBody.h @@ -34,8 +34,8 @@ public: ~ZBody() override; // These are split out from the constructor to allow construction - // of a ZBody from either save-file full instructions (first method) - // or intermediary instructions (second method). + // of a ZBody from either save-file full instructions (first method, + // not currently supported) or intermediary instructions (second method). void SetInsts(std::vector& insts); void SetInsts(std::vector& instsI);