diff --git a/src/Frame.cc b/src/Frame.cc index 1c093398dc..3ddab79c56 100644 --- a/src/Frame.cc +++ b/src/Frame.cc @@ -36,10 +36,13 @@ Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args) Frame::~Frame() { - for ( auto& func : functions_with_closure_frame_reference ) + if ( functions_with_closure_frame_reference ) { - func->StrengthenClosureReference(this); - Unref(func); + for ( auto& func : *functions_with_closure_frame_reference ) + { + func->StrengthenClosureReference(this); + Unref(func); + } } if ( ! weak_closure_ref ) @@ -56,7 +59,11 @@ Frame::~Frame() void Frame::AddFunctionWithClosureRef(BroFunc* func) { ::Ref(func); - functions_with_closure_frame_reference.emplace_back(func); + + if ( ! functions_with_closure_frame_reference ) + functions_with_closure_frame_reference = make_unique>(); + + functions_with_closure_frame_reference->emplace_back(func); } 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? - 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 // 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? - if ( offset_map.size() ) + if ( offset_map && ! offset_map->empty() ) { - auto where = offset_map.find(std::string(id->Name())); - if ( where != offset_map.end() ) + auto where = offset_map->find(std::string(id->Name())); + if ( where != offset_map->end() ) return frame[where->second]; } @@ -174,7 +181,10 @@ void Frame::Describe(ODesc* d) const Frame* Frame::Clone() const { Frame* other = new Frame(size, function, func_args); - other->offset_map = offset_map; + + if ( offset_map ) + other->offset_map = make_unique(*offset_map); + other->CaptureClosure(closure, outer_ids); other->call = call; @@ -233,10 +243,10 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const for ( const auto& id : us ) { - if ( offset_map.size() ) + if ( offset_map && ! offset_map->empty() ) { - auto where = offset_map.find(std::string(id->Name())); - if ( where != offset_map.end() ) + auto where = offset_map->find(std::string(id->Name())); + if ( where != offset_map->end() ) { clone_if_not_func(frame, where->second, func, other); continue; @@ -265,7 +275,13 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const if( closure ) other->CaptureClosure(closure, outer_ids); - other->offset_map = offset_map; + if ( offset_map ) + { + if ( ! other->offset_map ) + other->offset_map = make_unique(*offset_map); + else + *(other->offset_map) = *offset_map; + } return other; } @@ -281,7 +297,9 @@ broker::expected Frame::Serialize(const Frame* target, const id_li // and id_list them; - std::unordered_map new_map(target->offset_map); + std::unordered_map new_map; + if ( target->offset_map ) + new_map = *(target->offset_map); for (const auto& we : selection) { @@ -358,7 +376,7 @@ std::pair> Frame::Unserialize(const broker::vector& da return std::make_pair(true, nullptr); id_list outer_ids; - std::unordered_map offset_map; + OffsetMap offset_map; IntrusivePtr closure; auto where = data.begin(); @@ -442,7 +460,8 @@ std::pair> Frame::Unserialize(const broker::vector& da // We'll associate this frame with a function later. auto rf = make_intrusive(frame_size, nullptr, nullptr); - rf->offset_map = std::move(offset_map); + rf->offset_map = make_unique(offset_map); + // Frame takes ownership of unref'ing elements in outer_ids rf->outer_ids = std::move(outer_ids); rf->closure = closure.release(); @@ -477,7 +496,10 @@ std::pair> Frame::Unserialize(const broker::vector& da 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(); + + std::transform(ids.begin(), ids.end(), std::inserter(*offset_map, offset_map->end()), [] (const ID* id) -> std::pair { return std::make_pair(std::string(id->Name()), id->Offset()); diff --git a/src/Frame.h b/src/Frame.h index 6df91b7afa..e5ebd22724 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -234,6 +234,8 @@ public: private: + using OffsetMap = std::unordered_map; + /** * Unrefs the value at offset 'n' frame unless it's a weak reference. */ @@ -244,7 +246,7 @@ private: /** Serializes an offset_map */ static broker::expected - SerializeOffsetMap(const std::unordered_map& in); + SerializeOffsetMap(const OffsetMap& in); /** Serializes an id_list */ static broker::expected @@ -283,7 +285,7 @@ private: * Maps ID names to offsets. Used if this frame is serialized * to maintain proper offsets after being sent elsewhere. */ - std::unordered_map offset_map; + std::unique_ptr offset_map; /** The function this frame is associated with. */ const BroFunc* function; @@ -296,7 +298,7 @@ private: IntrusivePtr trigger; const CallExpr* call; - std::vector functions_with_closure_frame_reference; + std::unique_ptr> functions_with_closure_frame_reference; }; /**