noun: add functions to count size of noun

Adds a few functions to count the size of nouns in the current road.
Since this marks the nouns (high bit of refcount), you need to
"discount" them immediately after to unmark them.  Parallel functions
exist for the counting the size of a hashtable.

It would nice to hook this up to a hint, but these are useful to have
available to run in the debugger or by inserting callsites as necessary.
It's also possible to hook them up to the +jam jet gated on a special
value.
This commit is contained in:
Philip Monk 2020-06-22 17:21:59 -07:00
parent 4fded00005
commit d8aed4d4af
No known key found for this signature in database
GPG Key ID: B66E1F02604E44EC
4 changed files with 338 additions and 0 deletions

View File

@ -465,6 +465,24 @@
c3_w
u3a_mark_road(FILE* fil_u);
/* u3a_count_noun(): count size of noun.
*/
c3_w
u3a_count_noun(u3_noun som);
/* u3a_discount_noun(): clean up after counting a noun.
*/
c3_w
u3a_discount_noun(u3_noun som);
/* u3a_count_ptr(): count a pointer for gc. Produce size. */
c3_w
u3a_count_ptr(void* ptr_v);
/* u3a_discount_ptr(): discount a pointer for gc. Produce size. */
c3_w
u3a_discount_ptr(void* ptr_v);
/* u3a_idle(): measure free-lists in [rod_u]
*/
c3_w

View File

@ -139,6 +139,16 @@
c3_w
u3h_mark(u3p(u3h_root) har_p);
/* u3h_count(): count hashtable for gc.
*/
c3_w
u3h_count(u3p(u3h_root) har_p);
/* u3h_discount(): discount hashtable for gc.
*/
c3_w
u3h_discount(u3p(u3h_root) har_p);
/* u3h_walk_with(): traverse hashtable with key, value fn and data
* argument; RETAINS.
*/

View File

@ -1721,6 +1721,156 @@ u3a_mark_noun(u3_noun som)
}
}
/* u3a_count_noun(): count size of pointer.
*/
c3_w
u3a_count_ptr(void* ptr_v)
{
if ( _(u3a_is_north(u3R)) ) {
if ( !((ptr_v >= u3a_into(u3R->rut_p)) &&
(ptr_v < u3a_into(u3R->hat_p))) )
{
return 0;
}
}
else {
if ( !((ptr_v >= u3a_into(u3R->hat_p)) &&
(ptr_v < u3a_into(u3R->rut_p))) )
{
return 0;
}
}
{
u3a_box* box_u = u3a_botox(ptr_v);
c3_w siz_w;
c3_ws use_ws = (c3_ws)box_u->use_w;
if ( use_ws == 0 ) {
fprintf(stderr, "%p is bogus\r\n", ptr_v);
siz_w = 0;
}
else {
c3_assert(use_ws != 0);
if ( use_ws < 0 ) {
siz_w = 0;
}
else {
use_ws = -use_ws;
siz_w = box_u->siz_w;
}
box_u->use_w = (c3_w)use_ws;
}
return siz_w;
}
}
/* u3a_count_noun(): count size of noun.
*/
c3_w
u3a_count_noun(u3_noun som)
{
c3_w siz_w = 0;
while ( 1 ) {
if ( _(u3a_is_senior(u3R, som)) ) {
return siz_w;
}
else {
c3_w* dog_w = u3a_to_ptr(som);
c3_w new_w = u3a_count_ptr(dog_w);
if ( 0 == new_w ) {
return siz_w;
}
else {
siz_w += new_w;
if ( _(u3du(som)) ) {
siz_w += u3a_count_noun(u3h(som));
som = u3t(som);
}
else return siz_w;
}
}
}
}
/* u3a_discount_ptr(): clean up after counting a pointer.
*/
c3_w
u3a_discount_ptr(void* ptr_v)
{
if ( _(u3a_is_north(u3R)) ) {
if ( !((ptr_v >= u3a_into(u3R->rut_p)) &&
(ptr_v < u3a_into(u3R->hat_p))) )
{
return 0;
}
}
else {
if ( !((ptr_v >= u3a_into(u3R->hat_p)) &&
(ptr_v < u3a_into(u3R->rut_p))) )
{
return 0;
}
}
u3a_box* box_u = u3a_botox(ptr_v);
c3_w siz_w;
c3_ws use_ws = (c3_ws)box_u->use_w;
if ( use_ws == 0 ) {
fprintf(stderr, "%p is bogus\r\n", ptr_v);
siz_w = 0;
}
else {
c3_assert(use_ws != 0);
if ( use_ws < 0 ) {
use_ws = -use_ws;
siz_w = box_u->siz_w;
}
else {
siz_w = 0;
}
box_u->use_w = (c3_w)use_ws;
}
return siz_w;
}
/* u3a_discount_noun(): clean up after counting a noun.
*/
c3_w
u3a_discount_noun(u3_noun som)
{
c3_w siz_w = 0;
while ( 1 ) {
if ( _(u3a_is_senior(u3R, som)) ) {
return siz_w;
}
else {
c3_w* dog_w = u3a_to_ptr(som);
c3_w new_w = u3a_discount_ptr(dog_w);
if ( 0 == new_w ) {
return siz_w;
}
else {
siz_w += new_w;
if ( _(u3du(som)) ) {
siz_w += u3a_discount_noun(u3h(som));
som = u3t(som);
}
else return siz_w;
}
}
}
}
/* u3a_print_memory: print memory amount.
*/
void

View File

@ -941,3 +941,163 @@ u3h_mark(u3p(u3h_root) har_p)
return tot_w;
}
/* _ch_count_buck(): count bucket for gc.
*/
c3_w
_ch_count_buck(u3h_buck* hab_u)
{
c3_w tot_w = 0;
c3_w i_w;
for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) {
tot_w += u3a_count_noun(u3h_slot_to_noun(hab_u->sot_w[i_w]));
}
tot_w += u3a_count_ptr(hab_u);
return tot_w;
}
/* _ch_count_node(): count node for gc.
*/
c3_w
_ch_count_node(u3h_node* han_u, c3_w lef_w)
{
c3_w tot_w = 0;
c3_w len_w = _ch_popcount(han_u->map_w);
c3_w i_w;
lef_w -= 5;
for ( i_w = 0; i_w < len_w; i_w++ ) {
c3_w sot_w = han_u->sot_w[i_w];
if ( _(u3h_slot_is_noun(sot_w)) ) {
u3_noun kev = u3h_slot_to_noun(sot_w);
tot_w += u3a_count_noun(kev);
}
else {
void* hav_v = u3h_slot_to_node(sot_w);
if ( 0 == lef_w ) {
tot_w += _ch_count_buck(hav_v);
} else {
tot_w += _ch_count_node(hav_v, lef_w);
}
}
}
tot_w += u3a_count_ptr(han_u);
return tot_w;
}
/* u3h_count(): count hashtable for gc.
*/
c3_w
u3h_count(u3p(u3h_root) har_p)
{
c3_w tot_w = 0;
u3h_root* har_u = u3to(u3h_root, har_p);
c3_w i_w;
for ( i_w = 0; i_w < 64; i_w++ ) {
c3_w sot_w = har_u->sot_w[i_w];
if ( _(u3h_slot_is_noun(sot_w)) ) {
u3_noun kev = u3h_slot_to_noun(sot_w);
tot_w += u3a_count_noun(kev);
}
else if ( _(u3h_slot_is_node(sot_w)) ) {
u3h_node* han_u = u3h_slot_to_node(sot_w);
tot_w += _ch_count_node(han_u, 25);
}
}
tot_w += u3a_count_ptr(har_u);
return tot_w;
}
/* _ch_discount_buck(): discount bucket for gc.
*/
c3_w
_ch_discount_buck(u3h_buck* hab_u)
{
c3_w tot_w = 0;
c3_w i_w;
for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) {
tot_w += u3a_discount_noun(u3h_slot_to_noun(hab_u->sot_w[i_w]));
}
tot_w += u3a_discount_ptr(hab_u);
return tot_w;
}
/* _ch_discount_node(): discount node for gc.
*/
c3_w
_ch_discount_node(u3h_node* han_u, c3_w lef_w)
{
c3_w tot_w = 0;
c3_w len_w = _ch_popcount(han_u->map_w);
c3_w i_w;
lef_w -= 5;
for ( i_w = 0; i_w < len_w; i_w++ ) {
c3_w sot_w = han_u->sot_w[i_w];
if ( _(u3h_slot_is_noun(sot_w)) ) {
u3_noun kev = u3h_slot_to_noun(sot_w);
tot_w += u3a_discount_noun(kev);
}
else {
void* hav_v = u3h_slot_to_node(sot_w);
if ( 0 == lef_w ) {
tot_w += _ch_discount_buck(hav_v);
} else {
tot_w += _ch_discount_node(hav_v, lef_w);
}
}
}
tot_w += u3a_discount_ptr(han_u);
return tot_w;
}
/* u3h_discount(): discount hashtable for gc.
*/
c3_w
u3h_discount(u3p(u3h_root) har_p)
{
c3_w tot_w = 0;
u3h_root* har_u = u3to(u3h_root, har_p);
c3_w i_w;
for ( i_w = 0; i_w < 64; i_w++ ) {
c3_w sot_w = har_u->sot_w[i_w];
if ( _(u3h_slot_is_noun(sot_w)) ) {
u3_noun kev = u3h_slot_to_noun(sot_w);
tot_w += u3a_discount_noun(kev);
}
else if ( _(u3h_slot_is_node(sot_w)) ) {
u3h_node* han_u = u3h_slot_to_node(sot_w);
tot_w += _ch_discount_node(han_u, 25);
}
}
tot_w += u3a_discount_ptr(har_u);
return tot_w;
}