noun: first pass at memory compaction

This commit is contained in:
Philip Monk 2020-06-30 03:57:47 -07:00
parent a53e462be8
commit e8a307ae67
No known key found for this signature in database
GPG Key ID: B66E1F02604E44EC
13 changed files with 506 additions and 5 deletions

View File

@ -24,10 +24,6 @@ rec {
inherit crossenv;
};
ncurses = import ./pkgs/ncurses {
inherit crossenv;
};
pdcurses = import ./pkgs/pdcurses {
inherit crossenv;
};

View File

@ -465,6 +465,31 @@
c3_w
u3a_mark_road(FILE* fil_u);
/* u3a_rewrite_ptr(): mark a pointer as already having been rewritten
*/
c3_o
u3a_rewrite_ptr(void* ptr_v);
/* u3a_rewrite_noun(): rewrite a noun for compaction.
*/
void
u3a_rewrite_noun(u3_noun som);
/* u3a_rewritten(): rewrite a pointer for compaction.
*/
u3_post
u3a_rewritten(u3_post som_p);
/* u3a_rewritten(): rewritten noun pointer for compaction.
*/
u3_noun
u3a_rewritten_noun(u3_noun som);
/* u3a_compact(): compact (north) road.
*/
void
u3a_compact();
/* u3a_count_noun(): count size of noun.
*/
c3_w

View File

@ -139,6 +139,11 @@
c3_w
u3h_mark(u3p(u3h_root) har_p);
/* u3h_rewrite(): rewrite hashtable for compaction.
*/
void
u3h_rewrite(u3p(u3h_root) har_p);
/* u3h_count(): count hashtable for gc.
*/
c3_w

View File

@ -287,6 +287,21 @@
c3_w
u3j_mark(FILE* fil_u);
/* u3j_rite_rewrite(): rewrite u3j_rite for compaction.
*/
void
u3j_rite_rewrite(u3j_rite* rit_u);
/* u3j_site_rewrite(): rewrite u3j_site for compaction.
*/
void
u3j_site_rewrite(u3j_site* sit_u);
/* u3j_rewrite_compact(): rewrite jet state for compaction.
*/
void
u3j_rewrite_compact();
/* u3j_free_hank(): free an entry from the hank cache.
*/
void

View File

@ -117,6 +117,11 @@
c3_w
u3n_mark(FILE* fil_u);
/* u3n_rewrite_compact(): rewrite bytecode cache for compaction.
*/
void
u3n_rewrite_compact();
/* u3n_free(): free bytecode cache.
*/
void

View File

@ -103,3 +103,8 @@
*/
c3_w
u3v_mark(FILE* fil_u);
/* u3v_rewrite_compact(): rewrite arvo kernel for compaction.
*/
void
u3v_rewrite_compact();

View File

@ -1679,6 +1679,29 @@ u3a_mark_ptr(void* ptr_v)
}
}
u3_post
u3a_rewritten(u3_post ptr_v)
{
u3a_box* box_u = u3a_botox(u3a_into(ptr_v));
c3_w* box_w = (c3_w*) box_u;
return (u3_post)box_w[box_u->siz_w - 1];
}
u3_noun
u3a_rewritten_noun(u3_noun som)
{
if ( c3y == u3a_is_cat(som) ) {
return som;
}
u3_post som_p = u3a_rewritten(u3a_to_off(som));
if ( c3y == u3a_is_pug(som) ) {
return u3a_to_pug(som_p);
}
else {
return u3a_to_pom(som_p);
}
}
/* u3a_mark_mptr(): mark a malloc-allocated ptr for gc.
*/
c3_w
@ -1928,6 +1951,28 @@ u3a_mark_road(FILE* fil_u)
return u3a_maid(fil_u, "total road stuff", tot_w);
}
/* u3a_rewrite_compact(): rewrite pointers in ad-hoc persistent road structures.
*/
void
u3a_rewrite_compact()
{
u3a_rewrite_noun(u3R->ski.gul);
u3a_rewrite_noun(u3R->bug.tax);
u3a_rewrite_noun(u3R->bug.mer);
u3a_rewrite_noun(u3R->pro.don);
u3a_rewrite_noun(u3R->pro.day);
u3a_rewrite_noun(u3R->pro.trace);
u3h_rewrite(u3R->cax.har_p);
u3R->ski.gul = u3a_rewritten_noun(u3R->ski.gul);
u3R->bug.tax = u3a_rewritten_noun(u3R->bug.tax);
u3R->bug.mer = u3a_rewritten_noun(u3R->bug.mer);
u3R->pro.don = u3a_rewritten_noun(u3R->pro.don);
u3R->pro.day = u3a_rewritten_noun(u3R->pro.day);
u3R->pro.trace = u3a_rewritten_noun(u3R->pro.trace);
u3R->cax.har_p = u3a_rewritten(u3R->cax.har_p);
}
/* _ca_print_box(): heuristically print the contents of an allocation box.
*/
static c3_c*
@ -2180,6 +2225,162 @@ u3a_sweep(void)
return neg_w;
}
/* u3a_compact(): compact road.
*/
void
u3a_compact(void)
{
sleep(10);
u3m_reclaim();
assert(c3y == u3a_is_north(u3R));
u3_post box_p = _(u3a_is_north(u3R)) ? u3R->rut_p : u3R->hat_p;
u3_post end_p = _(u3a_is_north(u3R)) ? u3R->hat_p : u3R->rut_p;
/* Sweep through arena, recording new address
*
* Don't trace to preserve memory locality
*/
{
u3_post new_p = c3_wiseof(u3a_box) + 1;
c3_w* box_w = u3a_into(box_p);
c3_w* end_w = u3a_into(end_p);
while ( box_w < end_w ) {
u3a_box* box_u = (void *)box_w;
/* If not free, rewrite trailing size word to be new pointer.
*
* Another option would be to use the refcount and just
* regenerate it by tracing.
*/
if ( box_u->use_w > 0 ) {
//fprintf(stderr, "compact: found size %d at box_u %p, setting to new_p %x\r\n", box_u->siz_w, box_u, new_p);
box_w[box_u->siz_w - 1] = new_p;
new_p += box_u->siz_w;
//fprintf(stderr, "compact: adding to new_p %x\r\n", new_p);
}
box_w += box_u->siz_w;
}
}
fprintf(stderr, "compact: sweep 1 complete\r\n");
/* Trace through arena, rewriting pointers
*
* Don't sweep because it's ad-hoc polymorphic
*/
{
u3v_rewrite_compact();
u3j_rewrite_compact();
u3n_rewrite_compact();
u3a_rewrite_compact();
}
fprintf(stderr, "compact: trace complete\r\n");
c3_w* new_w = (void*)u3a_botox(u3a_into(c3_wiseof(u3a_box) + 1));
/* Sweep through arena, moving nouns
*
* Don't trace because you need to move in order
*/
{
c3_w* box_w = u3a_into(box_p);
c3_w* end_w = u3a_into(end_p);
while ( box_w < end_w ) {
u3a_box* old_u = (void *)box_w;
c3_w siz_w = old_u->siz_w; // store because we're about to overwrite
/* Unmark if marked
*/
old_u->use_w &= 0x7fffffff;
//fprintf(stderr, "compact: 364 == %d\r\n", *((c3_w*)0x200000364));
//fprintf(stderr, "compact: found size %d at old_u %p\r\n", old_u->siz_w, old_u);
/* If not free, move to new home
*/
if ( old_u->use_w > 0 ) {
//fprintf(stderr, "compact: writing to %p from %p\r\n", u3a_botox(u3a_into(box_w[siz_w - 1])), box_w);
assert(new_w == (c3_w*)u3a_botox(u3a_into(box_w[siz_w - 1])));
new_w = (c3_w*)u3a_botox(u3a_into(box_w[siz_w - 1]));
c3_w i_w;
if ( new_w > box_w ) {
fprintf(stderr, "compact: whoa new_w %p, i_w %d\r\n", new_w, i_w);
}
for ( i_w = 0; i_w < siz_w - 1; i_w++ ) {
new_w[i_w] = box_w[i_w];
}
new_w[siz_w - 1] = siz_w;
new_w += siz_w;
}
box_w += siz_w;
}
fprintf(stderr, "compact: box_w %lx new_w %lx\r\n", u3a_outa(box_w), u3a_outa(new_w));
}
fprintf(stderr, "compact: sweep 2 complete\r\n");
/* Set new end of heap.
*/
{
u3R->hat_p = u3a_outa(new_w);
c3_w i_w;
for ( i_w = 0; i_w < u3a_fbox_no; i_w++ ) {
u3R->all.fre_p[i_w] = 0;
}
u3R->all.cel_p = 0;
u3R->all.fre_w = 0;
u3n_ream();
u3m_mark(stderr);
fprintf(stderr, "compact: marked\r\n");
u3a_sweep();
fprintf(stderr, "compact: swept\r\n");
}
}
/* u3a_rewrite_ptr(): mark a pointer as already having been rewritten
*/
c3_o
u3a_rewrite_ptr(void* ptr_v)
{
u3a_box* box_u = u3a_botox(ptr_v);
if ( box_u->use_w & 0x80000000 ) {
/* Already rewritten.
*/
return c3n;
}
box_u->use_w |= 0x80000000;
return c3y;
}
void
u3a_rewrite_noun(u3_noun som)
{
if ( c3n == u3a_is_cell(som) ) {
return;
}
if ( c3n == u3a_rewrite_ptr(u3a_to_ptr((som))) ) return;
u3a_cell* cel = u3a_to_ptr(som);
u3a_rewrite_noun(cel->hed);
u3a_rewrite_noun(cel->tel);
cel->hed = u3a_rewritten_noun(cel->hed);
cel->tel = u3a_rewritten_noun(cel->tel);
}
/* u3a_slab(): create a length-bounded proto-atom.
*/
c3_w*

View File

@ -148,7 +148,7 @@ u3e_fault(void* adr_v, c3_i ser_i)
if ( 0 != (u3P.dit_w[blk_w] & (1 << bit_w)) ) {
fprintf(stderr, "strange page: %d, at %p, off %x\r\n",
pag_w, adr_w, off_w);
c3_assert(0);
// c3_assert(0);
return 0;
}

View File

@ -913,6 +913,58 @@ _ch_mark_node(u3h_node* han_u, c3_w lef_w)
return tot_w;
}
// XXX reorg
/* _ch_rewrite_buck(): rewrite buck for compaction.
*/
void
_ch_rewrite_buck(u3h_buck* hab_u)
{
if ( c3n == u3a_rewrite_ptr(hab_u) ) return;
c3_w i_w;
for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) {
u3_noun som = u3h_slot_to_noun(hab_u->sot_w[i_w]);
hab_u->sot_w[i_w] = u3h_noun_to_slot(u3a_rewritten_noun(som));
u3a_rewrite_noun(som);
}
}
/* _ch_rewrite_node(): rewrite node for compaction.
*/
void
_ch_rewrite_node(u3h_node* han_u, c3_w lef_w)
{
if ( c3n == u3a_rewrite_ptr(han_u) ) return;
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);
han_u->sot_w[i_w] = u3h_noun_to_slot(u3a_rewritten_noun(kev));
u3a_rewrite_noun(kev);
}
else {
void* hav_v = u3h_slot_to_node(sot_w);
u3h_node* nod_u = u3to(u3h_node,u3a_rewritten(u3of(u3h_node,hav_v)));
han_u->sot_w[i_w] = u3h_node_to_slot(nod_u);
if ( 0 == lef_w ) {
_ch_rewrite_buck(hav_v);
} else {
_ch_rewrite_node(hav_v, lef_w);
}
}
}
}
/* u3h_mark(): mark hashtable for gc.
*/
c3_w
@ -942,6 +994,35 @@ u3h_mark(u3p(u3h_root) har_p)
return tot_w;
}
/* u3h_rewrite(): rewrite pointers during compaction.
*/
void
u3h_rewrite(u3p(u3h_root) har_p)
{
u3h_root* har_u = u3to(u3h_root, har_p);
c3_w i_w;
if ( c3n == u3a_rewrite_ptr(har_u) ) return;
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);
har_u->sot_w[i_w] = u3h_noun_to_slot(u3a_rewritten_noun(kev));
u3a_rewrite_noun(kev);
}
else if ( _(u3h_slot_is_node(sot_w)) ) {
u3h_node* han_u = u3h_slot_to_node(sot_w);
u3h_node* nod_u = u3to(u3h_node,u3a_rewritten(u3of(u3h_node,han_u)));
har_u->sot_w[i_w] = u3h_node_to_slot(nod_u);
_ch_rewrite_node(han_u, 25);
}
}
}
/* _ch_count_buck(): count bucket for gc.
*/
c3_w

View File

@ -2339,6 +2339,104 @@ u3j_mark(FILE* fil_u)
return u3a_maid(fil_u, "total jet stuff", tot_w);
}
/* _cj_fink_rewrite(): rewrite a u3j_fink for compaction.
*/
static void
_cj_fink_rewrite(u3j_fink* fin_u)
{
if ( c3n == u3a_rewrite_ptr(fin_u) ) return;
c3_w i_w;
u3a_rewrite_noun(fin_u->sat);
fin_u->sat = u3a_rewritten_noun(fin_u->sat);
for ( i_w = 0; i_w < fin_u->len_w; ++i_w ) {
u3j_fist* fis_u = &(fin_u->fis_u[i_w]);
u3a_rewrite_noun(fis_u->bat);
u3a_rewrite_noun(fis_u->pax);
fis_u->bat = u3a_rewritten_noun(fis_u->bat);
fis_u->pax = u3a_rewritten_noun(fis_u->pax);
}
}
/* u3j_rite_rewrite(): rewrite u3j_rite for compaction.
*/
void
u3j_rite_rewrite(u3j_rite* rit_u)
{
if ( (c3y == rit_u->own_o) && u3_none != rit_u->clu ) {
u3a_rewrite_noun(rit_u->clu);
_cj_fink_rewrite(u3to(u3j_fink, rit_u->fin_p));
rit_u->clu = u3a_rewritten_noun(rit_u->clu);
rit_u->fin_p = u3a_rewritten(rit_u->fin_p);
}
}
/* u3j_site_rewrite(): rewrite u3j_site for compaction.
*/
void
u3j_site_rewrite(u3j_site* sit_u)
{
u3a_rewrite_noun(sit_u->axe);
sit_u->axe = u3a_rewritten_noun(sit_u->axe);
if ( u3_none != sit_u->bat ) {
u3a_rewrite_noun(sit_u->bat);
sit_u->bat = u3a_rewritten_noun(sit_u->bat);
}
if ( u3_none != sit_u->bas ) {
u3a_rewrite_noun(sit_u->bas);
sit_u->bas = u3a_rewritten_noun(sit_u->bas);
}
if ( u3_none != sit_u->loc ) {
u3a_rewrite_noun(sit_u->loc);
u3a_rewrite_noun(sit_u->lab);
sit_u->loc = u3a_rewritten_noun(sit_u->loc);
sit_u->lab = u3a_rewritten_noun(sit_u->lab);
if ( c3y == sit_u->fon_o ) {
_cj_fink_rewrite(u3to(u3j_fink, sit_u->fin_p));
sit_u->fin_p = u3a_rewritten(sit_u->fin_p);
}
}
}
/* _cj_rewrite_hank(): rewrite hank cache for compaction.
*/
static void
_cj_rewrite_hank(u3_noun kev)
{
_cj_hank* han_u = u3to(_cj_hank, u3t(kev));
if ( c3n == u3a_rewrite_ptr(han_u) ) return;
if ( u3_none != han_u->hax ) {
u3a_rewrite_noun(han_u->hax);
u3j_site_rewrite(&(han_u->sit_u));
han_u->hax = u3a_rewritten_noun(han_u->hax);
}
}
/* u3j_rewrite_compact(): rewrite jet state for compaction.
*/
void
u3j_rewrite_compact()
{
u3h_walk(u3R->jed.han_p, _cj_rewrite_hank);
u3h_rewrite(u3R->jed.war_p);
u3h_rewrite(u3R->jed.cod_p);
u3h_rewrite(u3R->jed.han_p);
u3h_rewrite(u3R->jed.bas_p);
if ( u3R == &(u3H->rod_u) ) {
u3h_rewrite(u3R->jed.hot_p);
u3R->jed.hot_p = u3a_rewritten(u3R->jed.hot_p);
}
u3R->jed.war_p = u3a_rewritten(u3R->jed.war_p);
u3R->jed.cod_p = u3a_rewritten(u3R->jed.cod_p);
u3R->jed.han_p = u3a_rewritten(u3R->jed.han_p);
u3R->jed.bas_p = u3a_rewritten(u3R->jed.bas_p);
}
/* u3j_free_hank(): free an entry from the hank cache.
*/
void

View File

@ -2597,6 +2597,51 @@ u3n_mark(FILE* fil_u)
return u3a_maid(fil_u, "total nock stuff", bam_w + har_w);
}
/* _n_prog_rewrite(): rewrite program for compaction.
*/
static void
_n_prog_rewrite(u3n_prog* pog_u)
{
c3_w i_w;
for ( i_w = 0; i_w < pog_u->lit_u.len_w; ++i_w ) {
u3a_rewrite_noun(pog_u->lit_u.non[i_w]);
}
for ( i_w = 0; i_w < pog_u->mem_u.len_w; ++i_w ) {
u3a_rewrite_noun(pog_u->mem_u.sot_u[i_w].key);
}
for ( i_w = 0; i_w < pog_u->cal_u.len_w; ++i_w ) {
u3j_site_rewrite(&(pog_u->cal_u.sit_u[i_w]));
}
for ( i_w = 0; i_w < pog_u->reg_u.len_w; ++i_w ) {
u3j_rite_rewrite(&(pog_u->reg_u.rit_u[i_w]));
}
}
/* _n_rewrite(): u3h_walk_with helper for u3n_rewrite_compact
*/
static void
_n_rewrite(u3_noun kev)
{
u3n_prog* pog = u3to(u3n_prog, u3t(kev));
_n_prog_rewrite(pog);
}
/* u3n_rewrite_compact(): rewrite the bytecode cache for compaction.
*/
void
u3n_rewrite_compact()
{
u3h_walk(u3R->byc.har_p, _n_rewrite);
u3h_rewrite(u3R->byc.har_p);
u3R->byc.har_p = u3a_rewritten(u3R->byc.har_p);
}
/* _n_feb(): u3h_walk helper for u3n_free
*/
static void

View File

@ -326,3 +326,24 @@ u3v_mark(FILE* fil_u)
tot_w += u3a_maid(fil_u, " wish cache", u3a_mark_noun(arv_u->yot));
return u3a_maid(fil_u, "total arvo stuff", tot_w);
}
/* u3v_rewrite_compact(): rewrite arvo kernel for compaction.
*/
void
u3v_rewrite_compact()
{
u3v_arvo* arv_u = &(u3H->arv_u);
u3a_rewrite_noun(arv_u->roc);
u3a_rewrite_noun(arv_u->now);
u3a_rewrite_noun(arv_u->wen);
u3a_rewrite_noun(arv_u->sen);
u3a_rewrite_noun(arv_u->yot);
arv_u->roc = u3a_rewritten_noun(arv_u->roc);
arv_u->now = u3a_rewritten_noun(arv_u->now);
arv_u->wen = u3a_rewritten_noun(arv_u->wen);
arv_u->sen = u3a_rewritten_noun(arv_u->sen);
arv_u->yot = u3a_rewritten_noun(arv_u->yot);
}

View File

@ -256,6 +256,10 @@ _serf_grab(u3_serf* sef_u)
u3z(sef_u->sac);
sef_u->sac = u3_nul;
{
u3a_compact();
}
}
}