mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 23:28:20 +00:00
Store weak ref boolean along with Frame element Vals
This commit is contained in:
parent
9f4eca081f
commit
198d604dde
2 changed files with 27 additions and 42 deletions
52
src/Frame.cc
52
src/Frame.cc
|
@ -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 = std::make_unique<IntrusivePtr<Val>[]>(size);
|
frame = std::make_unique<Element[]>(size);
|
||||||
function = func;
|
function = func;
|
||||||
func_args = fn_args;
|
func_args = fn_args;
|
||||||
|
|
||||||
|
@ -50,8 +50,6 @@ Frame::~Frame()
|
||||||
|
|
||||||
for ( int i = 0; i < size; ++i )
|
for ( int i = 0; i < size; ++i )
|
||||||
ClearElement(i);
|
ClearElement(i);
|
||||||
|
|
||||||
delete [] weak_refs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::AddFunctionWithClosureRef(BroFunc* func)
|
void Frame::AddFunctionWithClosureRef(BroFunc* func)
|
||||||
|
@ -70,26 +68,13 @@ void Frame::SetElement(int n, Val* v)
|
||||||
void Frame::SetElement(int n, IntrusivePtr<Val> v)
|
void Frame::SetElement(int n, IntrusivePtr<Val> v)
|
||||||
{
|
{
|
||||||
ClearElement(n);
|
ClearElement(n);
|
||||||
frame[n] = std::move(v);
|
frame[n] = {std::move(v), false};
|
||||||
|
|
||||||
if ( weak_refs )
|
|
||||||
weak_refs[n] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::SetElementWeak(int n, Val* v)
|
void Frame::SetElementWeak(int n, Val* v)
|
||||||
{
|
{
|
||||||
ClearElement(n);
|
ClearElement(n);
|
||||||
frame[n] = {AdoptRef{}, v};
|
frame[n] = {{AdoptRef{}, v}, true};
|
||||||
|
|
||||||
if ( ! weak_refs )
|
|
||||||
{
|
|
||||||
weak_refs = new bool[size];
|
|
||||||
|
|
||||||
for ( auto i = 0; i < size; ++i )
|
|
||||||
weak_refs[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
weak_refs[n] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::SetElement(const ID* id, IntrusivePtr<Val> v)
|
void Frame::SetElement(const ID* id, IntrusivePtr<Val> v)
|
||||||
|
@ -134,19 +119,16 @@ const IntrusivePtr<Val>& Frame::GetElementByID(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].val;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frame[id->Offset()];
|
return frame[id->Offset()].val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::Reset(int startIdx)
|
void Frame::Reset(int startIdx)
|
||||||
{
|
{
|
||||||
for ( int i = startIdx; i < size; ++i )
|
for ( int i = startIdx; i < size; ++i )
|
||||||
{
|
|
||||||
ClearElement(i);
|
ClearElement(i);
|
||||||
frame[i] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::Describe(ODesc* d) const
|
void Frame::Describe(ODesc* d) const
|
||||||
|
@ -160,14 +142,14 @@ void Frame::Describe(ODesc* d) const
|
||||||
|
|
||||||
for ( int i = 0; i < size; ++i )
|
for ( int i = 0; i < size; ++i )
|
||||||
{
|
{
|
||||||
d->Add(frame[i] != nullptr);
|
d->Add(frame[i].val != nullptr);
|
||||||
d->SP();
|
d->SP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = 0; i < size; ++i )
|
for ( int i = 0; i < size; ++i )
|
||||||
if ( frame[i] )
|
if ( frame[i].val )
|
||||||
frame[i]->Describe(d);
|
frame[i].val->Describe(d);
|
||||||
else if ( d->IsReadable() )
|
else if ( d->IsReadable() )
|
||||||
d->Add("<nil>");
|
d->Add("<nil>");
|
||||||
}
|
}
|
||||||
|
@ -185,8 +167,8 @@ Frame* Frame::Clone() const
|
||||||
other->trigger = trigger;
|
other->trigger = trigger;
|
||||||
|
|
||||||
for ( int i = 0; i < size; i++ )
|
for ( int i = 0; i < size; i++ )
|
||||||
if ( frame[i] )
|
if ( frame[i].val )
|
||||||
other->frame[i] = frame[i]->Clone();
|
other->frame[i].val = frame[i].val->Clone();
|
||||||
|
|
||||||
return other;
|
return other;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +183,7 @@ static bool val_is_func(const IntrusivePtr<Val>& v, BroFunc* func)
|
||||||
|
|
||||||
void Frame::CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const
|
void Frame::CloneNonFuncElement(int offset, BroFunc* func, Frame* other) const
|
||||||
{
|
{
|
||||||
const auto& v = frame[offset];
|
const auto& v = frame[offset].val;
|
||||||
|
|
||||||
if ( ! v )
|
if ( ! v )
|
||||||
return;
|
return;
|
||||||
|
@ -247,7 +229,7 @@ Frame* Frame::SelectiveClone(const id_list& selection, BroFunc* func) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! frame[id->Offset()] )
|
if ( ! frame[id->Offset()].val )
|
||||||
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
|
reporter->InternalError("Attempted to clone an id ('%s') with no associated value.", id->Name());
|
||||||
|
|
||||||
CloneNonFuncElement(id->Offset(), func, other);
|
CloneNonFuncElement(id->Offset(), func, other);
|
||||||
|
@ -349,7 +331,7 @@ 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;
|
||||||
|
|
||||||
const auto& val = target->frame[location];
|
const auto& val = target->frame[location].val;
|
||||||
|
|
||||||
TypeTag tag = val->GetType()->Tag();
|
TypeTag tag = val->GetType()->Tag();
|
||||||
|
|
||||||
|
@ -484,7 +466,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] = std::move(val);
|
rf->frame[i].val = std::move(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_pair(true, std::move(rf));
|
return std::make_pair(true, std::move(rf));
|
||||||
|
@ -535,10 +517,10 @@ void Frame::ClearTrigger()
|
||||||
|
|
||||||
void Frame::ClearElement(int n)
|
void Frame::ClearElement(int n)
|
||||||
{
|
{
|
||||||
if ( weak_refs && weak_refs[n] )
|
if ( frame[n].weak_ref )
|
||||||
frame[n].release();
|
frame[n].val.release();
|
||||||
else
|
else
|
||||||
frame[n] = nullptr;
|
frame[n] = {nullptr, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Frame::IsOuterID(const ID* in) const
|
bool Frame::IsOuterID(const ID* in) const
|
||||||
|
|
17
src/Frame.h
17
src/Frame.h
|
@ -43,10 +43,10 @@ public:
|
||||||
* @return the value at index *n* of the underlying array.
|
* @return the value at index *n* of the underlying array.
|
||||||
*/
|
*/
|
||||||
const IntrusivePtr<Val>& GetElement(int n) const
|
const IntrusivePtr<Val>& GetElement(int n) const
|
||||||
{ return frame[n]; }
|
{ return frame[n].val; }
|
||||||
|
|
||||||
[[deprecated("Remove in v4.1. Use GetElement(int).")]]
|
[[deprecated("Remove in v4.1. Use GetElement(int).")]]
|
||||||
Val* NthElement(int n) const { return frame[n].get(); }
|
Val* NthElement(int n) const { return frame[n].val.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the element at index *n* of the underlying array to *v*.
|
* Sets the element at index *n* of the underlying array to *v*.
|
||||||
|
@ -237,6 +237,13 @@ private:
|
||||||
|
|
||||||
using OffsetMap = std::unordered_map<std::string, int>;
|
using OffsetMap = std::unordered_map<std::string, int>;
|
||||||
|
|
||||||
|
struct Element {
|
||||||
|
IntrusivePtr<Val> val;
|
||||||
|
// Weak reference is used to prevent circular reference memory leaks
|
||||||
|
// in lambdas/closures.
|
||||||
|
bool weak_ref;
|
||||||
|
};
|
||||||
|
|
||||||
const IntrusivePtr<Val>& GetElementByID(const ID* id) const;
|
const IntrusivePtr<Val>& GetElementByID(const ID* id) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -290,11 +297,7 @@ private:
|
||||||
bool delayed;
|
bool delayed;
|
||||||
|
|
||||||
/** Associates ID's offsets with values. */
|
/** Associates ID's offsets with values. */
|
||||||
std::unique_ptr<IntrusivePtr<Val>[]> frame;
|
std::unique_ptr<Element[]> frame;
|
||||||
|
|
||||||
/** Values that are weakly referenced by the frame. Used to
|
|
||||||
* prevent circular reference memory leaks in lambda/closures */
|
|
||||||
bool* weak_refs = nullptr;
|
|
||||||
|
|
||||||
/** The enclosing frame of this frame. */
|
/** The enclosing frame of this frame. */
|
||||||
Frame* closure;
|
Frame* closure;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue