Store IntrusivePtrs in Frame

This commit is contained in:
Jon Siwek 2020-05-22 23:42:42 -07:00
parent 272db640aa
commit 1c617c4f7a
2 changed files with 23 additions and 36 deletions

View file

@ -17,7 +17,7 @@ std::vector<Frame*> g_frame_stack;
Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args) Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
{ {
size = arg_size; size = arg_size;
frame = new Val*[size]; frame = std::make_unique<IntrusivePtr<Val>[]>(size);
function = func; function = func;
func_args = fn_args; func_args = fn_args;
@ -29,9 +29,6 @@ Frame::Frame(int arg_size, const BroFunc* func, const zeek::Args* fn_args)
delayed = false; delayed = false;
closure = nullptr; closure = nullptr;
for (int i = 0; i < size; ++i)
frame[i] = nullptr;
} }
Frame::~Frame() Frame::~Frame()
@ -51,7 +48,8 @@ Frame::~Frame()
for ( auto& i : outer_ids ) for ( auto& i : outer_ids )
Unref(i); Unref(i);
Release(); for ( int i = 0; i < size; ++i )
UnrefElement(i);
delete [] weak_refs; delete [] weak_refs;
} }
@ -69,7 +67,7 @@ void Frame::AddFunctionWithClosureRef(BroFunc* func)
void Frame::SetElement(int n, Val* v, bool weak_ref) void Frame::SetElement(int n, Val* v, bool weak_ref)
{ {
UnrefElement(n); UnrefElement(n);
frame[n] = v; frame[n] = {AdoptRef{}, v};
if ( weak_ref ) if ( weak_ref )
{ {
@ -132,10 +130,10 @@ Val* Frame::GetElement(const ID* id) const
{ {
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].get();
} }
return frame[id->Offset()]; return frame[id->Offset()].get();
} }
void Frame::Reset(int startIdx) void Frame::Reset(int startIdx)
@ -147,14 +145,6 @@ void Frame::Reset(int startIdx)
} }
} }
void Frame::Release()
{
for ( int i = 0; i < size; ++i )
UnrefElement(i);
delete [] frame;
}
void Frame::Describe(ODesc* d) const void Frame::Describe(ODesc* d) const
{ {
if ( ! d->IsBinary() ) if ( ! d->IsBinary() )
@ -191,12 +181,13 @@ Frame* Frame::Clone() const
other->trigger = trigger; other->trigger = trigger;
for ( int i = 0; i < size; i++ ) for ( int i = 0; i < size; i++ )
other->frame[i] = frame[i] ? frame[i]->Clone().release() : nullptr; if ( frame[i] )
other->frame[i] = frame[i]->Clone();
return other; return other;
} }
static bool val_is_func(Val* v, BroFunc* func) static bool val_is_func(const IntrusivePtr<Val>& v, BroFunc* func)
{ {
if ( v->GetType()->Tag() != TYPE_FUNC ) if ( v->GetType()->Tag() != TYPE_FUNC )
return false; return false;
@ -204,17 +195,18 @@ static bool val_is_func(Val* v, BroFunc* func)
return v->AsFunc() == func; return v->AsFunc() == func;
} }
static void clone_if_not_func(Val** frame, int offset, BroFunc* func, static void clone_if_not_func(const std::unique_ptr<IntrusivePtr<Val>[]>& frame,
int offset, BroFunc* func,
Frame* other) Frame* other)
{ {
auto v = frame[offset]; const auto& v = frame[offset];
if ( ! v ) if ( ! v )
return; return;
if ( val_is_func(v, func) ) if ( val_is_func(v, func) )
{ {
other->SetElement(offset, v, true); other->SetElement(offset, v.get(), true);
return; return;
} }
@ -355,11 +347,11 @@ broker::expected<broker::data> Frame::Serialize(const Frame* target, const id_li
if (where != new_map.end()) if (where != new_map.end())
location = where->second; location = where->second;
Val* val = target->frame[location]; const auto& val = target->frame[location];
TypeTag tag = val->GetType()->Tag(); TypeTag tag = val->GetType()->Tag();
auto expected = bro_broker::val_to_data(val); auto expected = bro_broker::val_to_data(val.get());
if ( ! expected ) if ( ! expected )
return broker::ec::invalid_data; return broker::ec::invalid_data;
@ -490,7 +482,7 @@ std::pair<bool, IntrusivePtr<Frame>> Frame::Unserialize(const broker::vector& da
if ( ! val ) if ( ! val )
return std::make_pair(false, nullptr); return std::make_pair(false, nullptr);
rf->frame[i] = val.release(); rf->frame[i] = std::move(val);
} }
return std::make_pair(true, std::move(rf)); return std::make_pair(true, std::move(rf));
@ -542,9 +534,9 @@ void Frame::ClearTrigger()
void Frame::UnrefElement(int n) void Frame::UnrefElement(int n)
{ {
if ( weak_refs && weak_refs[n] ) if ( weak_refs && weak_refs[n] )
return; frame[n].release();
else
Unref(frame[n]); frame[n] = nullptr;
} }
bool Frame::IsOuterID(const ID* in) const bool Frame::IsOuterID(const ID* in) const

View file

@ -11,6 +11,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <memory>
#include <broker/data.hh> #include <broker/data.hh>
#include <broker/expected.hh> #include <broker/expected.hh>
@ -41,7 +42,7 @@ public:
* @param n the index to get. * @param n the index to get.
* @return the value at index *n* of the underlying array. * @return the value at index *n* of the underlying array.
*/ */
Val* NthElement(int n) const { return frame[n]; } Val* NthElement(int n) const { return frame[n].get(); }
/** /**
* Sets the element at index *n* of the underlying array * Sets the element at index *n* of the underlying array
@ -81,12 +82,6 @@ public:
*/ */
void Reset(int startIdx); void Reset(int startIdx);
/**
* Resets all of the values in the frame and clears out the
* underlying array.
*/
void Release();
/** /**
* Describes the frame and all of its values. * Describes the frame and all of its values.
*/ */
@ -269,7 +264,7 @@ private:
bool delayed; bool delayed;
/** Associates ID's offsets with values. */ /** Associates ID's offsets with values. */
Val** frame; std::unique_ptr<IntrusivePtr<Val>[]> frame;
/** Values that are weakly referenced by the frame. Used to /** Values that are weakly referenced by the frame. Used to
* prevent circular reference memory leaks in lambda/closures */ * prevent circular reference memory leaks in lambda/closures */