mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
use stack-based set to prevent infinite recursion rather than a static one
This commit is contained in:
parent
f43a9f9bab
commit
15123b6768
3 changed files with 25 additions and 24 deletions
29
src/Val.cc
29
src/Val.cc
|
@ -1322,12 +1322,12 @@ ValPtr ListVal::DoClone(CloneState* state)
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ListVal::Footprint() const
|
unsigned int ListVal::Footprint(std::set<const RecordVal*>* analyzed_records) const
|
||||||
{
|
{
|
||||||
unsigned int fp = vals.size();
|
unsigned int fp = vals.size();
|
||||||
|
|
||||||
for ( const auto& val : vals )
|
for ( const auto& val : vals )
|
||||||
fp += val->Footprint();
|
fp += val->Footprint(analyzed_records);
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
@ -2683,7 +2683,7 @@ ValPtr TableVal::DoClone(CloneState* state)
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int TableVal::Footprint() const
|
unsigned int TableVal::Footprint(std::set<const RecordVal*>* analyzed_records) const
|
||||||
{
|
{
|
||||||
unsigned int fp = table_val->Length();
|
unsigned int fp = table_val->Length();
|
||||||
|
|
||||||
|
@ -2693,9 +2693,9 @@ unsigned int TableVal::Footprint() const
|
||||||
auto vl = table_hash->RecoverVals(*k);
|
auto vl = table_hash->RecoverVals(*k);
|
||||||
auto v = iter.GetValue<TableEntryVal*>()->GetVal();
|
auto v = iter.GetValue<TableEntryVal*>()->GetVal();
|
||||||
|
|
||||||
fp += vl->Footprint();
|
fp += vl->Footprint(analyzed_records);
|
||||||
if ( v )
|
if ( v )
|
||||||
fp += v->Footprint();
|
fp += v->Footprint(analyzed_records);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
|
@ -3066,18 +3066,13 @@ ValPtr RecordVal::DoClone(CloneState* state)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int RecordVal::Footprint() const
|
unsigned int RecordVal::Footprint(std::set<const RecordVal*>* analyzed_records) const
|
||||||
{
|
{
|
||||||
// Which records we're in the process of analyzing - used to
|
if ( analyzed_records->count(this) > 0 )
|
||||||
// avoid infinite recursion for circular types (which can only
|
|
||||||
// occur due to the presence of records).
|
|
||||||
static std::unordered_set<const RecordVal*> pending_records;
|
|
||||||
|
|
||||||
if ( pending_records.count(this) > 0 )
|
|
||||||
// Footprint is 1 for the RecordVal itself.
|
// Footprint is 1 for the RecordVal itself.
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
pending_records.insert(this);
|
analyzed_records->insert(this);
|
||||||
|
|
||||||
int n = NumFields();
|
int n = NumFields();
|
||||||
unsigned int fp = n;
|
unsigned int fp = n;
|
||||||
|
@ -3089,10 +3084,10 @@ unsigned int RecordVal::Footprint() const
|
||||||
|
|
||||||
auto f_i = GetField(i);
|
auto f_i = GetField(i);
|
||||||
if ( f_i )
|
if ( f_i )
|
||||||
fp += f_i->Footprint();
|
fp += f_i->Footprint(analyzed_records);
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_records.erase(this);
|
analyzed_records->erase(this);
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
@ -3620,7 +3615,7 @@ bool VectorVal::Concretize(const TypePtr& t)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int VectorVal::Footprint() const
|
unsigned int VectorVal::Footprint(std::set<const RecordVal*>* analyzed_records) const
|
||||||
{
|
{
|
||||||
auto n = vector_val->size();
|
auto n = vector_val->size();
|
||||||
unsigned int fp = n;
|
unsigned int fp = n;
|
||||||
|
@ -3629,7 +3624,7 @@ unsigned int VectorVal::Footprint() const
|
||||||
{
|
{
|
||||||
auto v = At(i);
|
auto v = At(i);
|
||||||
if ( v )
|
if ( v )
|
||||||
fp += v->Footprint();
|
fp += v->Footprint(analyzed_records);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
|
|
14
src/Val.h
14
src/Val.h
|
@ -127,9 +127,13 @@ public:
|
||||||
* The number is not meant to be precise, but rather comparable:
|
* The number is not meant to be precise, but rather comparable:
|
||||||
* larger footprint correlates with more memory consumption.
|
* larger footprint correlates with more memory consumption.
|
||||||
*
|
*
|
||||||
|
* @param analyzed_records A pointer to a set used to track which
|
||||||
|
* records have been analyzed to date, used to prevent infinite
|
||||||
|
* recursion. The set should be empty (but not nil) on the first call.
|
||||||
|
*
|
||||||
* @return The total footprint.
|
* @return The total footprint.
|
||||||
*/
|
*/
|
||||||
virtual unsigned int Footprint() const { return 1; }
|
virtual unsigned int Footprint(std::set<const RecordVal*>* analyzed_records) const { return 1; }
|
||||||
|
|
||||||
// Bytes in total value object.
|
// Bytes in total value object.
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
|
@ -676,7 +680,7 @@ public:
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
unsigned int Footprint() const override;
|
unsigned int Footprint(std::set<const RecordVal*>* analyzed_records) const override;
|
||||||
|
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] unsigned int
|
"GHI-572.")]] unsigned int
|
||||||
|
@ -953,7 +957,7 @@ public:
|
||||||
// the function in the frame allowing it to capture its closure.
|
// the function in the frame allowing it to capture its closure.
|
||||||
void InitDefaultFunc(detail::Frame* f);
|
void InitDefaultFunc(detail::Frame* f);
|
||||||
|
|
||||||
unsigned int Footprint() const override;
|
unsigned int Footprint(std::set<const RecordVal*>* analyzed_records) const override;
|
||||||
|
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] unsigned int
|
"GHI-572.")]] unsigned int
|
||||||
|
@ -1381,7 +1385,7 @@ public:
|
||||||
}
|
}
|
||||||
RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false);
|
RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false);
|
||||||
|
|
||||||
unsigned int Footprint() const override;
|
unsigned int Footprint(std::set<const RecordVal*>* analyzed_records) const override;
|
||||||
|
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] unsigned int
|
"GHI-572.")]] unsigned int
|
||||||
|
@ -1640,7 +1644,7 @@ public:
|
||||||
const auto& RawYieldType() const { return yield_type; }
|
const auto& RawYieldType() const { return yield_type; }
|
||||||
const auto& RawYieldTypes() const { return yield_types; }
|
const auto& RawYieldTypes() const { return yield_types; }
|
||||||
|
|
||||||
unsigned int Footprint() const override;
|
unsigned int Footprint(std::set<const RecordVal*>* analyzed_records) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2008,7 +2008,8 @@ function global_container_footprints%(%): var_sizes
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto id_name = zeek::make_intrusive<zeek::StringVal>(id->Name());
|
auto id_name = zeek::make_intrusive<zeek::StringVal>(id->Name());
|
||||||
auto fp = zeek::val_mgr->Count(v->Footprint());
|
std::set<const RecordVal*> analyzed_records;
|
||||||
|
auto fp = zeek::val_mgr->Count(v->Footprint(&analyzed_records));
|
||||||
sizes->Assign(std::move(id_name), std::move(fp));
|
sizes->Assign(std::move(id_name), std::move(fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2024,7 +2025,8 @@ function global_container_footprints%(%): var_sizes
|
||||||
## .. zeek:see:: global_container_footprints
|
## .. zeek:see:: global_container_footprints
|
||||||
function val_footprint%(v: any%): count
|
function val_footprint%(v: any%): count
|
||||||
%{
|
%{
|
||||||
return zeek::val_mgr->Count(v->Footprint());
|
std::set<const RecordVal*> analyzed_records;
|
||||||
|
return zeek::val_mgr->Count(v->Footprint(&analyzed_records));
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## Generates a table with information about all global identifiers. The table
|
## Generates a table with information about all global identifiers. The table
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue