Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vere: adds melt, on-loom meld #632

Draft
wants to merge 17 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions pkg/noun/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,18 +470,26 @@ u3m_mark(FILE* fil_u)
return tot_w;
}

/* _pave_jets(): build jet tables.
*/
static void
_pave_jets(void)
{
u3R->jed.bas_p = u3h_new();
u3R->jed.cod_p = u3h_new();
u3R->jed.han_p = u3h_new();
u3R->jed.war_p = u3h_new();
}

/* _pave_parts(): build internal tables.
*/
static void
_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->jed.war_p = u3h_new();
u3R->jed.cod_p = u3h_new();
u3R->jed.han_p = u3h_new();
u3R->jed.bas_p = u3h_new();
u3R->byc.har_p = u3h_new();
_pave_jets();
}

/* _pave_road(): writes road boundaries to loom mem (stored at mat_w)
Expand Down Expand Up @@ -675,6 +683,14 @@ u3m_pave(c3_o nuu_o)
}
}

/* u3m_pave_jets(): re-initialize jet dashboard hashtables.
*/
void
u3m_pave_jets(void)
{
_pave_jets();
}

#if 0
/* u3m_clear(): clear all allocated data in road.
*/
Expand Down
5 changes: 5 additions & 0 deletions pkg/noun/manage.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@
void
u3m_pave(c3_o nuu_o);

/* u3m_pave_jets(): re-initialize jet dashboard hashtables.
*/
void
u3m_pave_jets();

/* u3m_signal(): treat a nock-level exception as a signal interrupt.
*/
void
Expand Down
135 changes: 135 additions & 0 deletions pkg/noun/urth.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "imprison.h"
#include "jets.h"
#include "manage.h"
#include "options.h"
#include "retrieve.h"
#include "serial.h"
#include "ur.h"
Expand Down Expand Up @@ -460,6 +461,140 @@ u3u_meld(void)
}
#endif

/* BEGIN helper functions for u3u_melt
-------------------------------------------------------------------
*/
/* _cj_warm_tap(): tap war_p to rel
*/
static void
_cj_warm_tap(u3_noun kev, void* wit)
{
u3_noun* rel = wit;
*rel = u3nc(u3k(kev), *rel);
}

static inline u3_weak
_cu_melt_get(u3p(u3h_root) set_p, u3_noun som)
{
u3_post hav_p = u3h_git(set_p, som);

if ( u3_none == hav_p ) {
return u3_none;
}

// restore tag bits from [som]
//
return (hav_p >> u3a_vits) | (som & 0xc0000000);
}

static inline void
_cu_melt_put(u3p(u3h_root) set_p, u3_noun som)
{
// strip tag bits from [som] to skip refcounts
//
u3_post hav_p = u3a_to_off(som);
u3h_put(set_p, som, hav_p);
}

static void
_cu_melt_noun(u3p(u3h_root) set_p, u3_noun* mos)
{
u3_noun som = *mos;
u3_weak hav;

// skip direct atoms
//
if ( c3y == u3a_is_cat(som) ) {
return;
}

// [som] equals [hav], and [hav] is canonical
//
if ( u3_none != (hav = _cu_melt_get(set_p, som)) ) {
if ( hav != som ) {
u3z(som);
*mos = u3k(hav);
}
return;
}

// traverse subtrees
//
if ( c3y == u3a_is_cell(som) ) {
u3a_cell *cel_u = u3a_to_ptr(som);
_cu_melt_noun(set_p, &cel_u->hed);
_cu_melt_noun(set_p, &cel_u->tel);
}

// [som] is canonical
//
_cu_melt_put(set_p, som);
}

/* u3u_melt(): globally deduplicate memory and pack in-place.
*/
c3_w
u3u_melt(void)
{
c3_w pre_w = u3a_open(u3R);

// Verify that we're on the main road.
//
u3_assert( &(u3H->rod_u) == u3R );

// Store a cons list of the cold jet registrations in `cod`
//
u3_noun cod = u3_nul;
u3h_walk_with(u3R->jed.cod_p, _cj_warm_tap, &cod);

u3m_reclaim(); // refresh the byte-code interpreter.
u3j_free(); // free cold & warm jet state

u3h_free(u3R->cax.per_p);
u3R->cax.per_p = u3h_new_cache(u3C.per_w);

u3z(u3A->yot); // Clear the hoon run-time cache
u3A->yot = 0;

u3z(u3R->bug.mer); // Clear the "emergency" buffer.
u3R->bug.mer = 0;

u3z(u3R->bug.tax); // Clear the stack traces.
u3R->bug.tax = 0;

u3p(u3h_root) set_p = u3h_new(); // temp hashtable

_cu_melt_noun(set_p, &cod); // melt the jets
_cu_melt_noun(set_p, &u3A->roc); // melt the kernel

u3h_free(set_p); // release the temp hashtable

// re-initialize the jets
//
u3j_boot(c3y);
u3m_pave_jets();

// Put the jet registrations back. Loop over cod putting them back into the cold jet
// dashboard. Then re-run the garbage collector.
//
u3_noun codc;
codc = cod;

while(u3_nul != cod) {
u3_noun kev = u3h(cod);
u3h_put(u3R->jed.cod_p, u3h(kev), u3k(u3t(kev)));
cod = u3t(cod);
}
u3z(codc);

// remove free space
//
u3j_ream();
u3m_pack();

return (u3a_open(u3R) - pre_w);
}

/* _cu_rock_path(): format rock path.
*/
static c3_o
Expand Down
5 changes: 5 additions & 0 deletions pkg/noun/urth.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
c3_w
u3u_meld(void);

/* u3u_melt(): globally deduplicate memory and pack in-place.
*/
c3_w
u3u_melt(void);

/* u3u_cram(): globably deduplicate memory, and write a rock to disk.
*/
c3_o
Expand Down
92 changes: 91 additions & 1 deletion pkg/vere/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,7 @@ _cw_usage(c3_c* bin_c)
" %s grab %.*s measure memory usage:\n",
" %s info %.*s print pier info:\n",
" %s meld %.*s deduplicate snapshot:\n",
" %s melt %.*s deduplicate and minimize snapshot:\n",
" %s pack %.*s defragment snapshot:\n",
" %s play %.*s recompute events:\n",
" %s prep %.*s prepare for upgrade:\n",
Expand Down Expand Up @@ -1994,7 +1995,7 @@ _cw_queu(c3_i argc, c3_c* argv[])
}
}

/* _cw_uniq(): deduplicate persistent nouns
/* _cw_meld(): deduplicate persistent nouns
*/
static void
_cw_meld(c3_i argc, c3_c* argv[])
Expand Down Expand Up @@ -2090,6 +2091,94 @@ _cw_meld(c3_i argc, c3_c* argv[])
u3m_stop();
}

/* _cw_melt(): deduplicate persistent nouns and compress them to minimal size
*/
static void
_cw_melt(c3_i argc, c3_c* argv[])
{
c3_i ch_i, lid_i;
c3_w arg_w;

static struct option lop_u[] = {
{ "loom", required_argument, NULL, c3__loom },
{ "no-demand", no_argument, NULL, 6 },
{ "swap", no_argument, NULL, 7 },
{ "swap-to", required_argument, NULL, 8 },
{ "gc-early", no_argument, NULL, 9 },
{ NULL, 0, NULL, 0 }
};

u3_Host.dir_c = _main_pier_run(argv[0]);

while ( -1 != (ch_i=getopt_long(argc, argv, "", lop_u, &lid_i)) ) {
switch ( ch_i ) {
case c3__loom: {
if (_main_readw_loom("loom", &u3_Host.ops_u.lom_y)) {
exit(1);
}
} break;

case 6: { // no-demand
u3_Host.ops_u.map = c3n;
u3C.wag_w |= u3o_no_demand;
} break;

case 7: { // swap
u3_Host.ops_u.eph = c3y;
u3C.wag_w |= u3o_swap;
} break;

case 8: { // swap-to
u3_Host.ops_u.eph = c3y;
u3C.wag_w |= u3o_swap;
u3C.eph_c = strdup(optarg);
break;
}

case 9: { // gc-early
u3C.wag_w |= u3o_check_corrupt;
break;
}

case '?': {
fprintf(stderr, "invalid argument\r\n");
exit(1);
} break;
}
}

// argv[optind] is always "melt"
//

if ( !u3_Host.dir_c ) {
if ( optind + 1 < argc ) {
u3_Host.dir_c = argv[optind + 1];
}
else {
fprintf(stderr, "invalid command, pier required\r\n");
exit(1);
}

optind++;
}

if ( optind + 1 != argc ) {
fprintf(stderr, "invalid command\r\n");
exit(1);
}

u3C.wag_w |= u3o_hashless;

u3_Host.eve_d = u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y);
u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock

u3a_print_memory(stderr, "urbit: melt: gained", u3u_melt());

u3m_save();
u3_disk_exit(log_u);
u3m_stop();
}

/* _cw_next(): request upgrade
*/
static void
Expand Down Expand Up @@ -3124,6 +3213,7 @@ _cw_utils(c3_i argc, c3_c* argv[])

case c3__info: _cw_info(argc, argv); return 1;
case c3__meld: _cw_meld(argc, argv); return 1;
case c3__melt: _cw_melt(argc, argv); return 1;
case c3__next: _cw_next(argc, argv); return 2; // continue on
case c3__pack: _cw_pack(argc, argv); return 1;
case c3__play: _cw_play(argc, argv); return 1;
Expand Down
Loading