Lazy-initalize some of the fields in Frame to reduce the size of all Frames when they're not used

This commit is contained in:
Tim Wojtulewicz 2020-04-06 15:32:39 -07:00
parent 6f8bbadcf9
commit f5865b6b97
2 changed files with 46 additions and 22 deletions

View file

@ -36,10 +36,13 @@ Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
Frame::~Frame() Frame::~Frame()
{ {
for ( auto& func : functions_with_closure_frame_reference ) if ( functions_with_closure_frame_reference )
{ {
func->StrengthenClosureReference(this); for ( auto& func : *functions_with_closure_frame_reference )
Unref(func); {
func->StrengthenClosureReference(this);
Unref(func);
}
} }
if ( ! weak_closure_ref ) if ( ! weak_closure_ref )
@ -56,7 +59,11 @@ Frame::~Frame()
void Frame::AddFunctionWithClosureRef(BroFunc* func) void Frame::AddFunctionWithClosureRef(BroFunc* func)
{ {
::Ref(func); ::Ref(func);
functions_with_closure_frame_reference.emplace_back(func);
if ( ! functions_with_closure_frame_reference )
functions_with_closure_frame_reference = make_unique<std::vector<BroFunc*>>();
functions_with_closure_frame_reference->emplace_back(func);
} }
void Frame::SetElement(int n, Val* v, bool weak_ref) void Frame::SetElement(int n, Val* v, bool weak_ref)
@ -95,11 +102,11 @@ void Frame::SetElement(const ID* id, Val* v)
} }
// do we have an offset for it? // do we have an offset for it?
if ( offset_map.size() ) if ( offset_map && ! offset_map->empty() )
{ {
auto where = offset_map.find(std::string(id->Name())); auto where = offset_map->find(std::string(id->Name()));
if ( where != offset_map.end() ) if ( where != offset_map->end() )
{ {
// Need to add a Ref to 'v' since the SetElement() for // Need to add a Ref to 'v' since the SetElement() for
// id->Offset() below is otherwise responsible for keeping track // id->Offset() below is otherwise responsible for keeping track
@ -121,10 +128,10 @@ Val* Frame::GetElement(const ID* id) const
} }
// do we have an offset for it? // do we have an offset for it?
if ( offset_map.size() ) if ( offset_map && ! offset_map->empty() )
{ {
auto where = offset_map.find(std::string(id->Name())); auto where = offset_map->find(std::string(id->Name()));
if ( where != offset_map.end() ) if ( where != offset_map->end() )
return frame[where->second]; return frame[where->second];
} }
@ -174,7 +181,10 @@ void Frame::Describe(ODesc* d) const
Frame* Frame::Clone() const Frame* Frame::Clone() const
{ {
Frame* other = new Frame(size, function, func_args); Frame* other = new Frame(size, function, func_args);
other->offset_map = offset_map;
if ( offset_map )
other->offset_map = make_unique<OffsetMap>(*offset_map);
other->CaptureClosure(closure, outer_ids); other->CaptureClosure(closure, outer_ids);
other->call = call; other->call = call;
@ -233,10 +243,10 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
for ( const auto& id : us ) for ( const auto& id : us )
{ {
if ( offset_map.size() ) if ( offset_map && ! offset_map->empty() )
{ {
auto where = offset_map.find(std::string(id->Name())); auto where = offset_map->find(std::string(id->Name()));
if ( where != offset_map.end() ) if ( where != offset_map->end() )
{ {
clone_if_not_func(frame, where->second, func, other); clone_if_not_func(frame, where->second, func, other);
continue; continue;
@ -265,7 +275,13 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
if( closure ) if( closure )
other->CaptureClosure(closure, outer_ids); other->CaptureClosure(closure, outer_ids);
other->offset_map = offset_map; if ( offset_map )
{
if ( ! other->offset_map )
other->offset_map = make_unique<OffsetMap>(*offset_map);
else
*(other->offset_map) = *offset_map;
}
return other; return other;
} }
@ -281,7 +297,9 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const id_li
// and // and
id_list them; id_list them;
std::unordered_map<std::string, int> new_map(target->offset_map); std::unordered_map<std::string, int> new_map;
if ( target->offset_map )
new_map = *(target->offset_map);
for (const auto& we : selection) for (const auto& we : selection)
{ {
@ -358,7 +376,7 @@ std::pair<bool, IntrusivePtr<Frame>> Frame::Unserialize(const broker::vector& da
return std::make_pair(true, nullptr); return std::make_pair(true, nullptr);
id_list outer_ids; id_list outer_ids;
std::unordered_map<std::string, int> offset_map; OffsetMap offset_map;
IntrusivePtr<Frame> closure; IntrusivePtr<Frame> closure;
auto where = data.begin(); auto where = data.begin();
@ -442,7 +460,8 @@ std::pair<bool, IntrusivePtr<Frame>> Frame::Unserialize(const broker::vector& da
// We'll associate this frame with a function later. // We'll associate this frame with a function later.
auto rf = make_intrusive<Frame>(frame_size, nullptr, nullptr); auto rf = make_intrusive<Frame>(frame_size, nullptr, nullptr);
rf->offset_map = std::move(offset_map); rf->offset_map = make_unique<OffsetMap>(offset_map);
// Frame takes ownership of unref'ing elements in outer_ids // Frame takes ownership of unref'ing elements in outer_ids
rf->outer_ids = std::move(outer_ids); rf->outer_ids = std::move(outer_ids);
rf->closure = closure.release(); rf->closure = closure.release();
@ -477,7 +496,10 @@ std::pair<bool, IntrusivePtr<Frame>> Frame::Unserialize(const broker::vector& da
void Frame::AddKnownOffsets(const id_list& ids) void Frame::AddKnownOffsets(const id_list& ids)
{ {
std::transform(ids.begin(), ids.end(), std::inserter(offset_map, offset_map.end()), if ( ! offset_map )
offset_map = make_unique<OffsetMap>();
std::transform(ids.begin(), ids.end(), std::inserter(*offset_map, offset_map->end()),
[] (const ID* id) -> std::pair<std::string, int> [] (const ID* id) -> std::pair<std::string, int>
{ {
return std::make_pair(std::string(id->Name()), id->Offset()); return std::make_pair(std::string(id->Name()), id->Offset());

View file

@ -234,6 +234,8 @@ public:
private: private:
using OffsetMap = std::unordered_map<std::string, int>;
/** /**
* Unrefs the value at offset 'n' frame unless it's a weak reference. * Unrefs the value at offset 'n' frame unless it's a weak reference.
*/ */
@ -244,7 +246,7 @@ private:
/** Serializes an offset_map */ /** Serializes an offset_map */
static broker::expected<broker::data> static broker::expected<broker::data>
SerializeOffsetMap(const std::unordered_map<std::string, int>& in); SerializeOffsetMap(const OffsetMap& in);
/** Serializes an id_list */ /** Serializes an id_list */
static broker::expected<broker::data> static broker::expected<broker::data>
@ -283,7 +285,7 @@ private:
* Maps ID names to offsets. Used if this frame is serialized * Maps ID names to offsets. Used if this frame is serialized
* to maintain proper offsets after being sent elsewhere. * to maintain proper offsets after being sent elsewhere.
*/ */
std::unordered_map<std::string, int> offset_map; std::unique_ptr<OffsetMap> offset_map;
/** The function this frame is associated with. */ /** The function this frame is associated with. */
const BroFunc* function; const BroFunc* function;
@ -296,7 +298,7 @@ private:
IntrusivePtr<trigger::Trigger> trigger; IntrusivePtr<trigger::Trigger> trigger;
const CallExpr* call; const CallExpr* call;
std::vector<BroFunc*> functions_with_closure_frame_reference; std::unique_ptr<std::vector<BroFunc*>> functions_with_closure_frame_reference;
}; };
/** /**