diff --git a/src/Val.cc b/src/Val.cc index 93f38c02cc..052e7d0ee7 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -1322,14 +1322,12 @@ ValPtr ListVal::DoClone(CloneState* state) return lv; } -unsigned int ListVal::Footprint(bool count_entries) const +unsigned int ListVal::Footprint() const { - unsigned int fp = 0; - for ( const auto& val : vals ) - fp += val->Footprint(count_entries); + unsigned int fp = vals.size(); - if ( count_entries ) - fp += vals.size(); + for ( const auto& val : vals ) + fp += val->Footprint(); return fp; } @@ -2685,9 +2683,9 @@ ValPtr TableVal::DoClone(CloneState* state) return tv; } -unsigned int TableVal::Footprint(bool count_entries) const +unsigned int TableVal::Footprint() const { - unsigned int fp = 0; + unsigned int fp = table_val->Length(); for ( const auto& iter : *table_val ) { @@ -2695,14 +2693,11 @@ unsigned int TableVal::Footprint(bool count_entries) const auto vl = table_hash->RecoverVals(*k); auto v = iter.GetValue()->GetVal(); - fp += vl->Footprint(count_entries); + fp += vl->Footprint(); if ( v ) - fp += v->Footprint(count_entries); + fp += v->Footprint(); } - if ( count_entries ) - fp += table_val->Length(); - return fp; } @@ -3071,7 +3066,7 @@ ValPtr RecordVal::DoClone(CloneState* state) return rv; } -unsigned int RecordVal::Footprint(bool count_entries) const +unsigned int RecordVal::Footprint() const { // Which records we're in the process of analyzing - used to // avoid infinite recursion for circular types (which can only @@ -3084,8 +3079,8 @@ unsigned int RecordVal::Footprint(bool count_entries) const pending_records.insert(this); - unsigned int fp = 0; int n = NumFields(); + unsigned int fp = n; for ( auto i = 0; i < n; ++i ) { @@ -3094,12 +3089,9 @@ unsigned int RecordVal::Footprint(bool count_entries) const auto f_i = GetField(i); if ( f_i ) - fp += f_i->Footprint(count_entries); + fp += f_i->Footprint(); } - if ( count_entries ) - fp += n; - pending_records.erase(this); return fp; @@ -3628,21 +3620,18 @@ bool VectorVal::Concretize(const TypePtr& t) return true; } -unsigned int VectorVal::Footprint(bool count_entries) const +unsigned int VectorVal::Footprint() const { - unsigned int fp = 0; auto n = vector_val->size(); + unsigned int fp = n; for ( auto i = 0U; i < n; ++i ) { auto v = At(i); if ( v ) - fp += v->Footprint(count_entries); + fp += v->Footprint(); } - if ( count_entries ) - fp += n; - return fp; } diff --git a/src/Val.h b/src/Val.h index 74f5295c25..d3c605022b 100644 --- a/src/Val.h +++ b/src/Val.h @@ -122,16 +122,14 @@ public: virtual ValPtr SizeVal() const; /** - * Returns the Val's "footprint", i.e., how many atomic (non-container) - * values it includes, either directly or indirectly. + * Returns the Val's "footprint", i.e., how many elements / Val + * objects the value includes, either directly or indirectly. + * The number is not meant to be precise, but rather comparable: + * larger footprint correlates with more memory consumption. * - * @param count_entries If true, (recursively) include in the - * footprint the count of the number of container elements as well - * as each element's footprint. - * - * @return The total footprint, optionally including element counts. + * @return The total footprint. */ - virtual unsigned int Footprint(bool count_entries) const { return 1; } + virtual unsigned int Footprint() const { return 1; } // Bytes in total value object. [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See " @@ -678,7 +676,7 @@ public: void Describe(ODesc* d) const override; - unsigned int Footprint(bool count_entries) const override; + unsigned int Footprint() const override; [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See " "GHI-572.")]] unsigned int @@ -955,7 +953,7 @@ public: // the function in the frame allowing it to capture its closure. void InitDefaultFunc(detail::Frame* f); - unsigned int Footprint(bool count_entries) const override; + unsigned int Footprint() const override; [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See " "GHI-572.")]] unsigned int @@ -1383,7 +1381,7 @@ public: } RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false); - unsigned int Footprint(bool count_entries) const override; + unsigned int Footprint() const override; [[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See " "GHI-572.")]] unsigned int @@ -1642,7 +1640,7 @@ public: const auto& RawYieldType() const { return yield_type; } const auto& RawYieldTypes() const { return yield_types; } - unsigned int Footprint(bool count_entries) const override; + unsigned int Footprint() const override; protected: /** diff --git a/src/zeek.bif b/src/zeek.bif index 6df100aa8a..72c18b95f2 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -1985,15 +1985,16 @@ function global_sizes%(%): var_sizes &deprecated="Remove in v5.1. MemoryAllocati return sizes; %} -## Generates a table of the footprint of all global container variables. +## Generates a table of the "footprint" of all global container variables. +## This is (approximately) the number of objects the global contains either +## directly or indirectly. The number is not meant to be precise, but +## rather comparable: larger footprint correlates with more memory consumption. ## The table index is the variable name and the value is the footprint. -## The argument specifies whether the footprint should (recursively) include -## the number of entries in each global. ## ## Returns: A table that maps variable names to their footprints. ## ## .. zeek:see:: value_footprint -function global_container_footprints%(count_entries: bool%): var_sizes +function global_container_footprints%(%): var_sizes %{ auto sizes = zeek::make_intrusive(IntrusivePtr{zeek::NewRef{}, var_sizes}); const auto& globals = zeek::detail::global_scope()->Vars(); @@ -2007,25 +2008,23 @@ function global_container_footprints%(count_entries: bool%): var_sizes continue; auto id_name = zeek::make_intrusive(id->Name()); - auto fp = zeek::val_mgr->Count(v->Footprint(count_entries)); + auto fp = zeek::val_mgr->Count(v->Footprint()); sizes->Assign(std::move(id_name), std::move(fp)); } return sizes; %} -## Computes a value's "footprint" (number of atomic elements included, either -## directly or indirectly). The argument, if true, specifies that the -## footprint should also include the number of entries in each included -## container. +## Computes a value's "footprint": the number of objects the value contains +## either directly or indirectly. The number is not meant to be precise, but +## rather comparable: larger footprint correlates with more memory consumption. ## -## Returns: the total number of atomic elements plus (optionally) the -## number of entries in included containers. +## Returns: the footprint. ## ## .. zeek:see:: global_container_footprints -function value_footprint%(v: any, count_entries: bool%): count +function value_footprint%(v: any%): count %{ - return zeek::val_mgr->Count(v->Footprint(count_entries)); + return zeek::val_mgr->Count(v->Footprint()); %} ## Generates a table with information about all global identifiers. The table diff --git a/testing/btest/Baseline/bifs.footprint/out b/testing/btest/Baseline/bifs.footprint/out index 922ae4ff7a..b2aea3b37e 100644 --- a/testing/btest/Baseline/bifs.footprint/out +++ b/testing/btest/Baseline/bifs.footprint/out @@ -1,53 +1,27 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. bool, 1 -bool, 1 -count, 1 count, 1 int, 1 -int, 1 -double, 1 double, 1 string, 1 -string, 1 -pattern, 1 pattern, 1 addr, 1 -addr, 1 -subnet, 1 subnet, 1 port, 1 -port, 1 -l1, 0 l1, 3 -l1b, 3 l1b, 6 -l2, 2 l2, 7 -l2b, 4 l2b, 9 -v1, 4 v1, 8 -v2, 8 v2, 18 -v3, 3 v3, 11 -t1, 6 t1, 12 -t2, 9 t2, 18 -t3, 20 t3, 46 -t4, 7 t4, 19 -s1, 3 s1, 9 -s2, 6 s2, 15 -s3, 8 s3, 20 -s4, 3 s4, 9 -1 3 -1 3 diff --git a/testing/btest/bifs/footprint.zeek b/testing/btest/bifs/footprint.zeek index 2f719db380..44737ac6f2 100644 --- a/testing/btest/bifs/footprint.zeek +++ b/testing/btest/bifs/footprint.zeek @@ -29,89 +29,65 @@ redef record X += { event zeek_init() { - print "bool", value_footprint(T, F); - print "bool", value_footprint(T, T); - print "count", value_footprint(3, F); - print "count", value_footprint(4, T); - print "int", value_footprint(-3, F); - print "int", value_footprint(-4, T); - print "double", value_footprint(-3.0, F); - print "double", value_footprint(4e99, T); - print "string", value_footprint("short", F); - print "string", value_footprint("longlonglong", T); - print "pattern", value_footprint(/short/, F); - print "pattern", value_footprint(/longlonglong/, T); - print "addr", value_footprint(1.2.3.4, F); - print "addr", value_footprint([ffff::ffff], T); - print "subnet", value_footprint(1.2.3.4/22, F); - print "subnet", value_footprint([ffff::ffff]/99, T); - print "port", value_footprint(123/tcp, F); - print "port", value_footprint(9999/udp, T); + print "bool", val_footprint(T); + print "count", val_footprint(4); + print "int", val_footprint(-4); + print "double", val_footprint(4e99); + print "string", val_footprint("longlonglong"); + print "pattern", val_footprint(/longlonglong/); + print "addr", val_footprint([ffff::ffff]); + print "subnet", val_footprint([ffff::ffff]/99); + print "port", val_footprint(9999/udp); local l1: r1; - print "l1", value_footprint(l1, F); - print "l1", value_footprint(l1, T); + print "l1", val_footprint(l1); local l1b = r1($a=3, $b=3.0, $c="3"); - print "l1b", value_footprint(l1b, F); - print "l1b", value_footprint(l1b, T); + print "l1b", val_footprint(l1b); local l2: r2; - print "l2", value_footprint(l2, F); - print "l2", value_footprint(l2, T); + print "l2", val_footprint(l2); local l2b = r2($a=3, $b1=99.0, $c="I'm here"); - print "l2b", value_footprint(l2b, F); - print "l2b", value_footprint(l2b, T); + print "l2b", val_footprint(l2b); local v1 = vector(9, 7, 3, 1); - print "v1", value_footprint(v1, F); - print "v1", value_footprint(v1, T); + print "v1", val_footprint(v1); local v2 = vector(v1, v1); - print "v2", value_footprint(v2, F); - print "v2", value_footprint(v2, T); + print "v2", val_footprint(v2); local v3 = vector(l1, l1b); - print "v3", value_footprint(v3, F); - print "v3", value_footprint(v3, T); + print "v3", val_footprint(v3); local t1 = table([1] = 1, [2] = 4, [3] = 9); - print "t1", value_footprint(t1, F); # Note, table and set footprint values using count_entries=T because # table indices are ListVal's, so those add their own container # entry counts into the sum. - print "t1", value_footprint(t1, T); + print "t1", val_footprint(t1); local t2 = table([1, 3] = 1, [2, 3] = 4, [3, 3] = 9); - print "t2", value_footprint(t2, F); - print "t2", value_footprint(t2, T); + print "t2", val_footprint(t2); local t3 = table([1, 3] = v2, [2, 3] = v2); - print "t3", value_footprint(t3, F); - print "t3", value_footprint(t3, T); + print "t3", val_footprint(t3); local t4 = table([1, 3] = l1, [2, 3] = l1b); - print "t4", value_footprint(t4, F); - print "t4", value_footprint(t4, T); + print "t4", val_footprint(t4); local s1 = set(1, 4, 9); - print "s1", value_footprint(s1, F); - print "s1", value_footprint(s1, T); + print "s1", val_footprint(s1); local s2 = set([1, 3], [2, 3], [3, 3]); - print "s2", value_footprint(s2, F); - print "s2", value_footprint(s2, T); + print "s2", val_footprint(s2); local s3: set[r1, count]; add s3[l1b, 9]; add s3[l1b, 12]; - print "s3", value_footprint(s3, F); - print "s3", value_footprint(s3, T); + print "s3", val_footprint(s3); local s4 = set(vector(l1b), vector(l1b), vector(l1b)); - print "s4", value_footprint(s4, F); - print "s4", value_footprint(s4, T); + print "s4", val_footprint(s4); local x: X; local y: Y; @@ -119,8 +95,6 @@ event zeek_init() x$y = y; y$x = x; - print value_footprint(x, F); - print value_footprint(x, T); - print value_footprint(y, F); - print value_footprint(y, T); + print val_footprint(x); + print val_footprint(y); }