fix profiling leaks

This commit is contained in:
Paul Driver 2018-04-02 14:08:28 -07:00
parent e68d64f8f9
commit 03763e4817
3 changed files with 68 additions and 27 deletions

View File

@ -141,7 +141,15 @@
c3_w c3_w
u3h_mark(u3p(u3h_root) har_p); u3h_mark(u3p(u3h_root) har_p);
/* u3h_walk(): traverse hashtable with key, value fn; RETAINS. /* u3h_walk_with(): traverse hashtable with key, value fn and data
* argument; RETAINS.
*/
void
u3h_walk_with(u3p(u3h_root) har_p,
void (*fun_f)(u3_noun, void*),
void* wit);
/* u3h_walk(): u3h_walk_with, but with no data argument
*/ */
void void
u3h_walk(u3p(u3h_root) har_p, void (*fun_f)(u3_noun)); u3h_walk(u3p(u3h_root) har_p, void (*fun_f)(u3_noun));

View File

@ -767,19 +767,19 @@ u3h_free(u3p(u3h_root) har_p)
/* _ch_walk_buck(): walk bucket for gc. /* _ch_walk_buck(): walk bucket for gc.
*/ */
static void static void
_ch_walk_buck(u3h_buck* hab_u, void (*fun_f)(u3_noun)) _ch_walk_buck(u3h_buck* hab_u, void (*fun_f)(u3_noun, void*), void* wit)
{ {
c3_w i_w; c3_w i_w;
for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) { for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) {
fun_f(u3h_slot_to_noun(hab_u->sot_w[i_w])); fun_f(u3h_slot_to_noun(hab_u->sot_w[i_w]), wit);
} }
} }
/* _ch_walk_node(): walk node for gc. /* _ch_walk_node(): walk node for gc.
*/ */
static void static void
_ch_walk_node(u3h_node* han_u, c3_w lef_w, void (*fun_f)(u3_noun)) _ch_walk_node(u3h_node* han_u, c3_w lef_w, void (*fun_f)(u3_noun, void*), void* wit)
{ {
c3_w len_w = _ch_popcount(han_u->map_w); c3_w len_w = _ch_popcount(han_u->map_w);
c3_w i_w; c3_w i_w;
@ -792,24 +792,27 @@ _ch_walk_node(u3h_node* han_u, c3_w lef_w, void (*fun_f)(u3_noun))
if ( _(u3h_slot_is_noun(sot_w)) ) { if ( _(u3h_slot_is_noun(sot_w)) ) {
u3_noun kev = u3h_slot_to_noun(sot_w); u3_noun kev = u3h_slot_to_noun(sot_w);
fun_f(kev); fun_f(kev, wit);
} }
else { else {
void* hav_v = u3h_slot_to_node(sot_w); void* hav_v = u3h_slot_to_node(sot_w);
if ( 0 == lef_w ) { if ( 0 == lef_w ) {
_ch_walk_buck(hav_v, fun_f); _ch_walk_buck(hav_v, fun_f, wit);
} else { } else {
_ch_walk_node(hav_v, lef_w, fun_f); _ch_walk_node(hav_v, lef_w, fun_f, wit);
} }
} }
} }
} }
/* u3h_walk(): walk hashtable for gc. /* u3h_walk_with(): traverse hashtable with key, value fn and data
* argument; RETAINS.
*/ */
void void
u3h_walk(u3p(u3h_root) har_p, void (*fun_f)(u3_noun)) u3h_walk_with(u3p(u3h_root) har_p,
void (*fun_f)(u3_noun, void*),
void* wit)
{ {
u3h_root* har_u = u3to(u3h_root, har_p); u3h_root* har_u = u3to(u3h_root, har_p);
c3_w i_w; c3_w i_w;
@ -820,16 +823,32 @@ u3h_walk(u3p(u3h_root) har_p, void (*fun_f)(u3_noun))
if ( _(u3h_slot_is_noun(sot_w)) ) { if ( _(u3h_slot_is_noun(sot_w)) ) {
u3_noun kev = u3h_slot_to_noun(sot_w); u3_noun kev = u3h_slot_to_noun(sot_w);
fun_f(kev); fun_f(kev, wit);
} }
else if ( _(u3h_slot_is_node(sot_w)) ) { else if ( _(u3h_slot_is_node(sot_w)) ) {
u3h_node* han_u = u3h_slot_to_node(sot_w); u3h_node* han_u = u3h_slot_to_node(sot_w);
_ch_walk_node(han_u, 25, fun_f); _ch_walk_node(han_u, 25, fun_f, wit);
} }
} }
} }
/* _ch_walk_plain(): use plain u3_noun fun_f for each node
*/
static void
_ch_walk_plain(u3_noun kev, void* wit)
{
void (*fun_f)(u3_noun) = wit;
fun_f(kev);
}
/* u3h_walk(): u3h_walk_with, but with no data argument
*/
void
u3h_walk(u3p(u3h_root) har_p, void (*fun_f)(u3_noun))
{
u3h_walk_with(har_p, _ch_walk_plain, fun_f);
}
/* _ch_mark_buck(): mark bucket for gc. /* _ch_mark_buck(): mark bucket for gc.
*/ */

View File

@ -1153,13 +1153,23 @@ _n_bite(u3_noun fol)
static inline c3_y* static inline c3_y*
_n_find(u3_noun fol) _n_find(u3_noun fol)
{ {
/* check on the home road first. not only is this likely to be faster, it
* protects us from things which compile bytecode on the home road
* mid-computation (like u3t_samp())
*/
u3a_road* rod_u = u3R; u3a_road* rod_u = u3R;
u3a_road* hom_u = &(u3H->rod_u);
u3_weak byc = u3h_gut(hom_u->byc.har_p, fol);
while ( 1 ) { if ( u3_none != byc ) {
u3_weak jaw = u3h_gut(rod_u->byc.har_p, fol); return u3a_into(byc);
}
if ( u3_none != jaw ) { while ( rod_u != hom_u ) {
return u3a_into(jaw); byc = u3h_gut(rod_u->byc.har_p, fol);
if ( u3_none != byc ) {
return u3a_into(byc);
} }
if ( rod_u->par_p ) { if ( rod_u->par_p ) {
@ -1894,10 +1904,15 @@ _n_reap(u3_noun kev)
u3_noun fol = u3h(kev); u3_noun fol = u3h(kev);
u3_noun got = u3t(kev); u3_noun got = u3t(kev);
u3_noun lof = u3a_take(fol); u3_noun lof = u3a_take(fol);
c3_y* pog = u3a_into(got); u3_weak con = u3h_get(u3R->byc.har_p, lof);
c3_y* gop = _n_take_byc(pog); // u3t_samp() etc. can interrupt us while we're compiling
u3_noun tog = u3a_outa(gop); // so we need to avoid leaking any parent bytecode
u3h_put(u3R->byc.har_p, lof, tog); if ( u3_none == con ) {
c3_y* pog = u3a_into(got);
c3_y* gop = _n_take_byc(pog);
u3_noun tog = u3a_outa(gop);
u3h_put(u3R->byc.har_p, lof, tog);
}
u3z(lof); u3z(lof);
} }
@ -1950,15 +1965,14 @@ _n_mark_byc(c3_y* pog)
return tot_w; return tot_w;
} }
static c3_w bam_w; /* _n_bam(): u3h_walk_with helper for u3n_bark
/* _n_bam(): u3h_walk helper for u3n_bark
*/ */
static void static void
_n_bam(u3_noun kev) _n_bam(u3_noun kev, void* dat)
{ {
c3_y* pog = u3a_into(u3t(kev)); c3_w* bam_w = dat;
bam_w += _n_mark_byc(pog); c3_y* pog = u3a_into(u3t(kev));
*bam_w += _n_mark_byc(pog);
} }
/* u3n_bark(): mark the bytecode cache for gc. /* u3n_bark(): mark the bytecode cache for gc.
@ -1966,9 +1980,9 @@ _n_bam(u3_noun kev)
c3_w c3_w
u3n_bark() u3n_bark()
{ {
c3_w bam_w = 0;
u3p(u3h_root) har_p = u3R->byc.har_p; u3p(u3h_root) har_p = u3R->byc.har_p;
bam_w = 0; u3h_walk_with(har_p, _n_bam, &bam_w);
u3h_walk(har_p, _n_bam);
return bam_w + u3h_mark(har_p); return bam_w + u3h_mark(har_p);
} }