diff --git a/pkg/c3/motes.h b/pkg/c3/motes.h index 1075b73944..f4c57076cb 100644 --- a/pkg/c3/motes.h +++ b/pkg/c3/motes.h @@ -452,6 +452,7 @@ # define c3__fond c3_s4('f','o','n','d') # define c3__for c3_s3('f','o','r') # define c3__forb c3_s4('f','o','r','b') +# define c3__ford c3_s4('f','o','r','d') # define c3__fore c3_s4('f','o','r','e') # define c3__fork c3_s4('f','o','r','k') # define c3__form c3_s4('f','o','r','m') diff --git a/pkg/noun/allocate.c b/pkg/noun/allocate.c index 29dd06786d..68e23f3a19 100644 --- a/pkg/noun/allocate.c +++ b/pkg/noun/allocate.c @@ -1660,7 +1660,7 @@ u3a_print_quac(FILE* fil_u, c3_w den_w, u3m_quac* mas_u) u3m_quac* u3a_mark_road() { - u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 15); + u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 16); qua_u[0] = c3_calloc(sizeof(*qua_u[0])); qua_u[0]->nam_c = strdup("namespace"); @@ -1757,7 +1757,11 @@ u3a_mark_road() qua_u[13]->nam_c = strdup("timer stack"); qua_u[13]->siz_w = u3a_mark_noun(u3R->tim) * 4; - qua_u[14] = NULL; + qua_u[14] = c3_calloc(sizeof(*qua_u[14])); + qua_u[14]->nam_c = strdup("ford memoization cache"); + qua_u[14]->siz_w = u3h_mark(u3R->cax.for_p) * 4; + + qua_u[15] = NULL; c3_w sum_w = 0; for (c3_w i_w = 0; qua_u[i_w]; i_w++) { @@ -1799,6 +1803,7 @@ u3a_rewrite_compact(void) u3h_relocate(&(u3R->cax.har_p)); u3h_relocate(&(u3R->cax.per_p)); u3h_relocate(&(u3R->lop_p)); + u3h_relocate(&(u3R->cax.for_p)); } /* u3a_idle(): measure free-lists in [rod_u] diff --git a/pkg/noun/allocate.h b/pkg/noun/allocate.h index bde2774ea2..15e8883660 100644 --- a/pkg/noun/allocate.h +++ b/pkg/noun/allocate.h @@ -211,6 +211,7 @@ STATIC_ASSERT( u3a_vits <= u3a_min_log, struct { // memoization caches u3p(u3h_root) har_p; // transient u3p(u3h_root) per_p; // persistent + u3p(u3h_root) for_p; // ford } cax; } u3a_road; typedef u3a_road u3_road; @@ -219,7 +220,7 @@ STATIC_ASSERT( u3a_vits <= u3a_min_log, */ enum u3a_flag { u3a_flag_sand = 1 << 1, // bump allocation (XX not impl) - u3a_flag_cash = 1 << 2, // memo cache harvesting + u3a_flag_cash = 1 << 2, // memo cache harvesting, flows forward }; /* u3a_pile: stack control, abstracted over road direction. diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index 3269c55fb9..21823b7bb7 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -517,6 +517,7 @@ _pave_parts(void) u3R->cax.har_p = u3h_new_cache(u3C.hap_w); // transient u3R->cax.per_p = u3h_new_cache(u3C.per_w); // persistent + u3R->cax.for_p = u3h_new_cache(u3C.per_w); // ford u3R->jed.war_p = u3h_new(); u3R->jed.cod_p = u3h_new(); u3R->jed.han_p = u3h_new(); @@ -663,12 +664,11 @@ _find_home(void) u3H->pam_d = _pave_params(); } - // if lop_p is zero than it is an old pier pre %loop hint, initialize the - // HAMT + // properly initialize things from zero-initialize future proof buffer + // XX cax.for_p // - if (!u3R->lop_p) { - u3R->lop_p = u3h_new(); - } + if ( !u3R->lop_p ) u3R->lop_p = u3h_new(); + if ( !u3R->cax.for_p ) u3R->cax.for_p = u3h_new_cache(u3C.per_w); } /* u3m_pave(): instantiate or activate image. @@ -1002,6 +1002,12 @@ u3m_bail(u3_noun how) } } + // Reset the spin stack pointer + if ( NULL != u3t_Spin ) { + u3t_Spin->off_w = u3R->off_w; + u3t_Spin->fow_w = u3R->fow_w; + } + _longjmp(u3R->esc.buf, how); } @@ -1214,8 +1220,14 @@ u3m_hate(c3_w pad_w) u3_assert(0 == u3R->ear_p); u3R->ear_p = u3R->cap_p; + + c3_w fag_w = u3R->how.fag_w; u3m_leap(pad_w); + // inherit forward-flowing flags + // + u3R->how.fag_w |= (fag_w & u3a_flag_cash); + u3R->bug.mer = u3i_string( "emergency buffer with sufficient space to cons the trace and bail" ); @@ -1340,6 +1352,7 @@ u3m_love(u3_noun pro) u3p(u3h_root) byc_p = u3R->byc.har_p; u3a_jets jed_u = u3R->jed; u3p(u3h_root) per_p = u3R->cax.per_p; + u3p(u3h_root) for_p = u3R->cax.for_p; // are there any timers on the road? // @@ -1363,6 +1376,7 @@ u3m_love(u3_noun pro) jed_u = u3j_take(jed_u); byc_p = u3n_take(byc_p); per_p = u3h_take(per_p); + for_p = u3h_take(for_p); // pop the stack // @@ -1375,6 +1389,7 @@ u3m_love(u3_noun pro) u3j_reap(jed_u); u3n_reap(byc_p); u3z_reap(u3z_memo_keep, per_p); + u3z_reap(u3z_memo_ford, for_p); return pro; } @@ -1719,7 +1734,7 @@ u3m_soft_run(u3_noun gul, */ { - if ( (u3_nul == gul) || cash_t ) { + if ( (u3_nul == gul) || (u3R->how.fag_w & u3a_flag_cash) ) { u3R->ski.gul = u3_nul; } else { diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index 425b187784..f52bd024f3 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -1143,7 +1143,15 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) { u3_weak con = u3r_skip(hod); if ( (u3_none != con) && (c3y == u3du(con)) ) { - cid = u3z_memo_keep; + if ( (c3y == u3du(u3t(con))) + && (c3__clay == u3h(con)) + && (c3__ford == u3h(u3t(con))) ) + { + cid = u3z_memo_ford; + } + else { + cid = u3z_memo_keep; + } } } ++tot_w; _n_emit(ops, u3nq(op_y, cid, mem_w, u3k(nef))); @@ -2754,7 +2762,14 @@ _n_burn(u3n_prog* pog_u, u3_noun bus, c3_ys mov, c3_ys off) skim_out: o = u3k(mem_u->key); x = u3nc(x, o); - o = u3z_find_m(mem_u->cid, 144 + c3__nock, x); + switch ( mem_u->cid ) { + case u3z_memo_ford: { + o = u3z_find_m(mem_u->cid, 136 + c3__ford, x); + } break; + default: { + o = u3z_find_m(mem_u->cid, 144 + c3__nock, x); + } + } if ( u3_none == o ) { _n_push(mov, off, u3nc(mem_u->cid, x)); _n_push(mov, off, u3k(u3h(x))); @@ -2770,7 +2785,10 @@ _n_burn(u3n_prog* pog_u, u3_noun bus, c3_ys mov, c3_ys off) x = _n_pep(mov, off); // product top = _n_peek(off); o = *top; - if ( ( u3z_memo_toss == u3h(o) ) + if ( u3z_memo_ford == u3h(o) ) { + u3z_save_m(u3h(o), 136 + c3__ford, u3t(o), x); + } + else if ( ( u3z_memo_toss == u3h(o) ) ? ( &(u3H->rod_u) != u3R ) : ( 0 == u3R->ski.gul ) ) { // prevents userspace from persistence u3z_save_m(u3h(o), 144 + c3__nock, u3t(o), x); diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 91b64bb199..cf3e1da8c6 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -553,6 +553,9 @@ u3u_melt(void) u3h_free(u3R->cax.per_p); u3R->cax.per_p = u3h_new_cache(u3C.per_w); + u3h_free(u3R->cax.for_p); + u3R->cax.for_p = u3h_new_cache(u3C.per_w); + u3h_free(u3R->jed.cod_p); u3R->jed.cod_p = u3h_new(); diff --git a/pkg/noun/zave.c b/pkg/noun/zave.c index 8aeaf6aadd..ed463cac5b 100644 --- a/pkg/noun/zave.c +++ b/pkg/noun/zave.c @@ -46,6 +46,8 @@ _har(u3a_road* rod_u, u3z_cid cid) return rod_u->cax.har_p; case u3z_memo_keep: return rod_u->cax.per_p; + case u3z_memo_ford: + return rod_u->cax.for_p; // design cache key to handle arvo changes that invalidate } u3_assert(0); } diff --git a/pkg/noun/zave.h b/pkg/noun/zave.h index f7e2be9f36..823604fb2d 100644 --- a/pkg/noun/zave.h +++ b/pkg/noun/zave.h @@ -19,7 +19,7 @@ typedef enum { u3z_memo_toss = 0, u3z_memo_keep = 1, - // u3z_memo_ford = 2, + u3z_memo_ford = 2, // u3z_memo_ames = 3, // ... } u3z_cid; diff --git a/pkg/vere/mars.c b/pkg/vere/mars.c index 71269b6f6a..11d05650cf 100644 --- a/pkg/vere/mars.c +++ b/pkg/vere/mars.c @@ -737,8 +737,10 @@ _mars_post(u3_mars* mar_u) if ( mar_u->fag_w & _mars_fag_hit1 ) { if ( u3C.wag_w & u3o_verbose ) { u3l_log("mars: threshold 1: %u", u3h_wyt(u3R->cax.per_p)); + u3l_log("mars: threshold 1: %u", u3h_wyt(u3R->cax.for_p)); } u3h_trim_to(u3R->cax.per_p, u3h_wyt(u3R->cax.per_p) / 2); + u3h_trim_to(u3R->cax.for_p, u3h_wyt(u3R->cax.for_p) / 2); u3m_reclaim(); } @@ -748,6 +750,7 @@ _mars_post(u3_mars* mar_u) if ( mar_u->fag_w & _mars_fag_vega ) { u3h_trim_to(u3R->cax.per_p, u3h_wyt(u3R->cax.per_p) / 2); + u3h_trim_to(u3R->cax.for_p, u3h_wyt(u3R->cax.for_p) / 2); u3m_reclaim(); } @@ -761,9 +764,12 @@ _mars_post(u3_mars* mar_u) if ( mar_u->fag_w & _mars_fag_hit0 ) { if ( u3C.wag_w & u3o_verbose ) { u3l_log("mars: threshold 0: per_p %u", u3h_wyt(u3R->cax.per_p)); + u3l_log("mars: threshold 0: for_p %u", u3h_wyt(u3R->cax.for_p)); } u3h_free(u3R->cax.per_p); u3R->cax.per_p = u3h_new_cache(u3C.per_w); + u3h_free(u3R->cax.for_p); + u3R->cax.for_p = u3h_new_cache(u3C.per_w); u3a_print_memory(stderr, "mars: pack: gained", u3m_pack()); u3l_log(""); } diff --git a/pkg/vere/melt.c b/pkg/vere/melt.c index 01b9208cec..3145898887 100644 --- a/pkg/vere/melt.c +++ b/pkg/vere/melt.c @@ -177,6 +177,7 @@ u3_melt_all(FILE *fil_u) u3h_walk_with(u3R->jed.cod_p, _melt_walk_hamt, &can_u); u3h_walk_with(u3R->cax.per_p, _melt_walk_hamt, &can_u); + u3h_walk_with(u3R->cax.for_p, _melt_walk_hamt, &can_u); u3j_boot(c3n); u3j_ream(); @@ -204,6 +205,9 @@ u3_meld_all(FILE *fil_u) u3h_free(u3R->cax.per_p); u3R->cax.per_p = u3h_new_cache(u3C.per_w); + u3h_free(u3R->cax.for_p); + u3R->cax.for_p = u3h_new_cache(u3C.per_w); + (void)u3_melt_all(fil_u); (void)u3m_pack();