From d2cc948831808f71ece17fda43afa89f27b920d0 Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Fri, 15 Jul 2022 16:40:25 -0400 Subject: [PATCH 01/14] fix up an outdated comment --- pkg/vere/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/vere/main.c b/pkg/vere/main.c index ec98561ea7..e7f06093f1 100644 --- a/pkg/vere/main.c +++ b/pkg/vere/main.c @@ -1888,7 +1888,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[]) From 86ed375492766e1458b5025dfee93b0590bfeccc Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Fri, 15 Jul 2022 16:41:26 -0400 Subject: [PATCH 02/14] basic `melt` runner as a copy of `meld` --- pkg/vere/main.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pkg/vere/main.c b/pkg/vere/main.c index e7f06093f1..5e2b35bff8 100644 --- a/pkg/vere/main.c +++ b/pkg/vere/main.c @@ -718,6 +718,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", @@ -1976,6 +1977,44 @@ _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[]) +{ + switch ( argc ) { + case 2: { + if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { + fprintf(stderr, "unable to find pier\r\n"); + exit (1); + } + } break; + + case 3: { + u3_Host.dir_c = argv[2]; + } break; + + default: { + fprintf(stderr, "invalid command\r\n"); + exit(1); + } break; + } + + u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock + c3_w pre_w; + + u3C.wag_w |= u3o_hashless; + u3m_boot(u3_Host.dir_c); + + pre_w = u3a_open(u3R); + u3u_melt(); + u3a_print_memory(stderr, "urbit: melt: gained", (u3a_open(u3R) - pre_w)); + + u3e_save(); + u3_disk_exit(log_u); + u3m_stop(); +} + /* _cw_next(): request upgrade */ static void @@ -2856,6 +2895,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; From 2c4a084dbd845309261c26a1523a4a6bb26c3795 Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Thu, 21 Jul 2022 08:41:24 -0400 Subject: [PATCH 03/14] pseudocode impl of u3U_melt() --- pkg/noun/urth.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 701d235637..73bc4a99a8 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -460,6 +460,66 @@ u3u_meld(void) } #endif +/* _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); +} + +/* u3u_melt(): globally deduplicate memory. +*/ +void +u3u_melt(void) +{ + c3_assert( &(u3H->rod_u) == u3R ); // Make sure we're on the main road. + + u3_noun cod = u3_nul; // cons list of cold jet registrations + u3h_walk_with(u3R->jed.cod_p, _cj_warm_tap, &cod); + + u3m_reclaim(); // Throw away what we don't need + u3j_free(); // free cold & warm jet state + + // NOTE: We are now in an invalid state. + // TODO: Free everything else we can. Joe to provide? Look at garbage collector - u3a->roc, u3a->jed, u3m_mark (mark all roots). + + u3p(u3h_root) set_p = u3h_new(); + + cod = our_traversal(cod, set_p); + u3A->roc = our_traversal(u3A->roc, set_p); + + u3h_free(set_p); + + // Put the jet registrations back. Loop over cod putting them back into the cold jet + // dashboard. Then re-run the garbage collector. + u3j_boot(c3y); + u3_noun codc; + codc = cod; + + u3R->jed.cod_p = u3h_new(); + 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); + + u3j_ream(); // re-init all the jets + u3m_pack(); // remove free space +} + +/* our_traversal +(a_noun, known_nouns) +iterate known_nouns looking at the value of each one and seeing if the value of a_noun matches. +if we find it, return the pointer to the value and decrement the ref count of a_noun if it's pointer is not. + +let foo = (get known_nouns a_noun) +if ( foo != a_noun ) { lose(a_noun); return foo; } + +*/ + /* _cu_rock_path(): format rock path. */ static c3_o From bd329e284de8b0ed3b90818ee15c512ff43dfffb Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Thu, 21 Jul 2022 16:56:06 -0400 Subject: [PATCH 04/14] initial jfb implementation --- pkg/noun/urth.c | 80 +++++++++++++++++++++++++++++++++++++++++++++---- pkg/noun/urth.h | 5 ++++ 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 73bc4a99a8..1ef674e097 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -460,6 +460,9 @@ u3u_meld(void) } #endif +/* BEGIN helper functions for u3u_meld + ------------------------------------------------------------------- +*/ /* _cj_warm_tap(): tap war_p to rel */ static void @@ -469,14 +472,78 @@ _cj_warm_tap(u3_noun kev, void* wit) *rel = u3nc(u3k(kev), *rel); } -/* u3u_melt(): globally deduplicate memory. +static inline u3_weak +_get(u3_noun som, u3p(u3h_root) set_p) +{ + 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 | ((som >> 30) << 30); +} + +static inline void +_put(u3_noun som, u3p(u3h_root) set_p) +{ + // strip tag bits from [som] to skip refcounts + // + u3_post hav_p = u3a_to_off(som); + u3h_put(set_p, u3k(som), hav_p); +} + +static u3_noun +_traverse(u3_noun som, u3p(u3h_root) set_p) +{ + u3_weak hav; + + // skip direct atoms + // + if (c3y == u3a_is_cat(som)) + { + return som; + } + + // [som] equals [hav], and [hav] is canonical + // + if (u3_none != (hav = _get(som, set_p))) + { + u3z(som); + return u3k(hav); + } + + // traverse subtrees + // + if (c3y == u3a_is_cell(som)) + { + u3a_cell *cel_u = u3a_to_ptr(som); + + cel_u->hed = _traverse(cel_u->hed, set_p); + cel_u->tel = _traverse(cel_u->tel, set_p); + } + + // [som] is canonical + // + _put(som, set_p); + return som; +} + +/* u3u_melt(): globally deduplicate memory and pack in-place. */ void u3u_melt(void) { - c3_assert( &(u3H->rod_u) == u3R ); // Make sure we're on the main road. + // Verify that we're on the main road. + // + c3_assert( &(u3H->rod_u) == u3R ); - u3_noun cod = u3_nul; // cons list of cold jet registrations + // Get a cons list of the cold jet registrations. + // + u3_noun cod = u3_nul; u3h_walk_with(u3R->jed.cod_p, _cj_warm_tap, &cod); u3m_reclaim(); // Throw away what we don't need @@ -484,16 +551,17 @@ u3u_melt(void) // NOTE: We are now in an invalid state. // TODO: Free everything else we can. Joe to provide? Look at garbage collector - u3a->roc, u3a->jed, u3m_mark (mark all roots). - + // u3p(u3h_root) set_p = u3h_new(); - cod = our_traversal(cod, set_p); - u3A->roc = our_traversal(u3A->roc, set_p); + cod = _traverse(cod, set_p); + u3A->roc = _traverse(u3A->roc, set_p); u3h_free(set_p); // Put the jet registrations back. Loop over cod putting them back into the cold jet // dashboard. Then re-run the garbage collector. + // u3j_boot(c3y); u3_noun codc; codc = cod; diff --git a/pkg/noun/urth.h b/pkg/noun/urth.h index 0dc2aa8168..28a3019c61 100644 --- a/pkg/noun/urth.h +++ b/pkg/noun/urth.h @@ -12,6 +12,11 @@ c3_w u3u_meld(void); + /* u3u_melt(): globally deduplicate memory and pack in-place. + */ + void + u3u_melt(void); + /* u3u_cram(): globably deduplicate memory, and write a rock to disk. */ c3_o From 5c229092f4fbc9df0649d45af90ea9adc0e8dffb Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Fri, 22 Jul 2022 14:23:45 -0400 Subject: [PATCH 05/14] re-pave all the necessary road parts --- pkg/noun/urth.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 1ef674e097..0bf5473f68 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -563,6 +563,7 @@ u3u_melt(void) // dashboard. Then re-run the garbage collector. // u3j_boot(c3y); + u3_noun codc; codc = cod; @@ -574,6 +575,12 @@ u3u_melt(void) } u3z(codc); + // We threw these away so we need to re-pave them before re-initialization. + // + u3R->jed.bas_p = u3h_new(); + u3R->jed.han_p = u3h_new(); + u3R->jed.war_p = u3h_new(); + u3j_ream(); // re-init all the jets u3m_pack(); // remove free space } From c0dbd9926815c54524be8378a17733573d8c6bde Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Fri, 22 Jul 2022 15:28:48 -0400 Subject: [PATCH 06/14] refactor/extract-method consolidates re-initializing the jet dashboard hashtables into a public method for reuse. --- pkg/noun/manage.c | 24 ++++++++++++++++++++---- pkg/noun/manage.h | 5 +++++ pkg/noun/urth.c | 11 ++++------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index d880a42032..c7c80cee95 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -470,6 +470,17 @@ 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 @@ -477,11 +488,8 @@ _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) @@ -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. */ diff --git a/pkg/noun/manage.h b/pkg/noun/manage.h index 14f9cc503d..0d780cda91 100644 --- a/pkg/noun/manage.h +++ b/pkg/noun/manage.h @@ -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 diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 0bf5473f68..cdbf77a92f 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -575,14 +575,11 @@ u3u_melt(void) } u3z(codc); - // We threw these away so we need to re-pave them before re-initialization. + // re-init all the jets and remove free space // - u3R->jed.bas_p = u3h_new(); - u3R->jed.han_p = u3h_new(); - u3R->jed.war_p = u3h_new(); - - u3j_ream(); // re-init all the jets - u3m_pack(); // remove free space + u3m_pave_jets(); + u3j_ream(); + u3m_pack(); } /* our_traversal From 09b850a5d702e02387a1ede3d6a804f8b0b3c563 Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Fri, 19 Aug 2022 16:43:23 -0400 Subject: [PATCH 07/14] fix a refcounting issue. reorganize a bit. --- pkg/noun/urth.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index cdbf77a92f..1b564e8c85 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -493,7 +493,7 @@ _put(u3_noun som, u3p(u3h_root) set_p) // strip tag bits from [som] to skip refcounts // u3_post hav_p = u3a_to_off(som); - u3h_put(set_p, u3k(som), hav_p); + u3h_put(set_p, som, hav_p); } static u3_noun @@ -546,12 +546,17 @@ u3u_melt(void) u3_noun cod = u3_nul; u3h_walk_with(u3R->jed.cod_p, _cj_warm_tap, &cod); - u3m_reclaim(); // Throw away what we don't need + u3m_reclaim(); // refresh the byte-code interpreter. u3j_free(); // free cold & warm jet state - // NOTE: We are now in an invalid state. - // TODO: Free everything else we can. Joe to provide? Look at garbage collector - u3a->roc, u3a->jed, u3m_mark (mark all roots). - // + u3z(u3A->yot); // Clear the hoon run-time cache + u3z(u3R->bug.mer); // Clear the "emergency" buffer. + u3z(u3R->bug.tax); // Clear the stack traces. + + u3A->yot = 0; + u3R->bug.mer = 0; + u3R->bug.tax = 0; + u3p(u3h_root) set_p = u3h_new(); cod = _traverse(cod, set_p); @@ -564,10 +569,15 @@ u3u_melt(void) // u3j_boot(c3y); + // re-init all the jets + // + u3m_pave_jets(); + + // restore the jet state + // u3_noun codc; codc = cod; - u3R->jed.cod_p = u3h_new(); while(u3_nul != cod) { u3_noun kev = u3h(cod); u3h_put(u3R->jed.cod_p, u3h(kev), u3k(u3t(kev))); @@ -575,23 +585,12 @@ u3u_melt(void) } u3z(codc); - // re-init all the jets and remove free space + // remove free space // - u3m_pave_jets(); u3j_ream(); u3m_pack(); } -/* our_traversal -(a_noun, known_nouns) -iterate known_nouns looking at the value of each one and seeing if the value of a_noun matches. -if we find it, return the pointer to the value and decrement the ref count of a_noun if it's pointer is not. - -let foo = (get known_nouns a_noun) -if ( foo != a_noun ) { lose(a_noun); return foo; } - -*/ - /* _cu_rock_path(): format rock path. */ static c3_o From b7d208896ecfbb93faebf3fda58a22800f259531 Mon Sep 17 00:00:00 2001 From: Daryl Richter Date: Wed, 12 Oct 2022 11:59:50 -0400 Subject: [PATCH 08/14] improve comments --- pkg/noun/urth.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 1b564e8c85..7d87eefa98 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -460,7 +460,7 @@ u3u_meld(void) } #endif -/* BEGIN helper functions for u3u_meld +/* BEGIN helper functions for u3u_melt ------------------------------------------------------------------- */ /* _cj_warm_tap(): tap war_p to rel @@ -541,39 +541,37 @@ u3u_melt(void) // c3_assert( &(u3H->rod_u) == u3R ); - // Get a cons list of the cold jet registrations. + // 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 - - u3z(u3A->yot); // Clear the hoon run-time cache - u3z(u3R->bug.mer); // Clear the "emergency" buffer. - u3z(u3R->bug.tax); // Clear the stack traces. + u3m_reclaim(); // refresh the byte-code interpreter. + u3j_free(); // free cold & warm jet state + 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(); + u3p(u3h_root) set_p = u3h_new(); // temp hashtable - cod = _traverse(cod, set_p); - u3A->roc = _traverse(u3A->roc, set_p); + cod = _traverse(cod, set_p); // melt the jets + u3A->roc = _traverse(u3A->roc, set_p); // melt the kernel - u3h_free(set_p); + u3h_free(set_p); // release the temp hashtable - // Put the jet registrations back. Loop over cod putting them back into the cold jet - // dashboard. Then re-run the garbage collector. + // re-initialize the jets // u3j_boot(c3y); - - // re-init all the jets - // u3m_pave_jets(); - // restore the jet state + // 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; From 20103bf017b69386ebf946376c4381989e0bb98b Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 11 Apr 2024 13:37:15 -0400 Subject: [PATCH 09/14] u3: revive melt, add cli args --- pkg/noun/urth.c | 8 +++-- pkg/noun/urth.h | 2 +- pkg/vere/main.c | 88 ++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 7d87eefa98..fa19368f2a 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -534,12 +534,14 @@ _traverse(u3_noun som, u3p(u3h_root) set_p) /* u3u_melt(): globally deduplicate memory and pack in-place. */ -void +c3_w u3u_melt(void) { + c3_w pre_w = u3a_open(u3R); + // Verify that we're on the main road. // - c3_assert( &(u3H->rod_u) == u3R ); + u3_assert( &(u3H->rod_u) == u3R ); // Store a cons list of the cold jet registrations in `cod` // @@ -587,6 +589,8 @@ u3u_melt(void) // u3j_ream(); u3m_pack(); + + return (u3a_open(u3R) - pre_w); } /* _cu_rock_path(): format rock path. diff --git a/pkg/noun/urth.h b/pkg/noun/urth.h index 28a3019c61..e2d6cdf22d 100644 --- a/pkg/noun/urth.h +++ b/pkg/noun/urth.h @@ -14,7 +14,7 @@ /* u3u_melt(): globally deduplicate memory and pack in-place. */ - void + c3_w u3u_melt(void); /* u3u_cram(): globably deduplicate memory, and write a rock to disk. diff --git a/pkg/vere/main.c b/pkg/vere/main.c index 5e2b35bff8..092042b282 100644 --- a/pkg/vere/main.c +++ b/pkg/vere/main.c @@ -1982,35 +1982,85 @@ _cw_meld(c3_i argc, c3_c* argv[]) static void _cw_melt(c3_i argc, c3_c* argv[]) { - switch ( argc ) { - case 2: { - if ( !(u3_Host.dir_c = _main_pier_run(argv[0])) ) { - fprintf(stderr, "unable to find pier\r\n"); - exit (1); + 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; } - } break; - case 3: { - u3_Host.dir_c = argv[2]; - } break; + case 9: { // gc-early + u3C.wag_w |= u3o_check_corrupt; + break; + } - default: { - fprintf(stderr, "invalid command\r\n"); + 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); - } break; + } + + optind++; } - u3_disk* log_u = _cw_disk_init(u3_Host.dir_c); // XX s/b try_aquire lock - c3_w pre_w; + if ( optind + 1 != argc ) { + fprintf(stderr, "invalid command\r\n"); + exit(1); + } u3C.wag_w |= u3o_hashless; - u3m_boot(u3_Host.dir_c); - pre_w = u3a_open(u3R); - u3u_melt(); - u3a_print_memory(stderr, "urbit: melt: gained", (u3a_open(u3R) - pre_w)); + 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 - u3e_save(); + u3a_print_memory(stderr, "urbit: melt: gained", u3u_melt()); + + u3m_save(); u3_disk_exit(log_u); u3m_stop(); } From 9d2efcbb6fc751f4557d16ba0eaa4c94c3b89525 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 11 Apr 2024 13:31:03 -0400 Subject: [PATCH 10/14] u3: updates melt to properly handle compressed noun references --- pkg/noun/urth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index fa19368f2a..06284b3e65 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -484,7 +484,7 @@ _get(u3_noun som, u3p(u3h_root) set_p) // restore tag bits from [som] // - return hav_p | ((som >> 30) << 30); + return (hav_p >> u3a_vits) | ((som >> 30) << 30); } static inline void From 0ae7e1d4b2bc2f01f0a353c219c1d0d79a093696 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 11 Apr 2024 13:37:35 -0400 Subject: [PATCH 11/14] u3: clear persistent memo cache in melt --- pkg/noun/urth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 06284b3e65..fa016950df 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -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" @@ -551,6 +552,9 @@ u3u_melt(void) 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; From 8a4d08378d3bf129d5d6d431b864cfcf52b23be2 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 11 Apr 2024 15:26:30 -0400 Subject: [PATCH 12/14] u3: more efficient tag-bits restoration in melt --- pkg/noun/urth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index fa016950df..676f63539a 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -485,7 +485,7 @@ _get(u3_noun som, u3p(u3h_root) set_p) // restore tag bits from [som] // - return (hav_p >> u3a_vits) | ((som >> 30) << 30); + return (hav_p >> u3a_vits) | (som & 0xc0000000); } static inline void From ddca8bcc4fc2df64be23be25214e9fe483a22dd7 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 11 Apr 2024 15:26:52 -0400 Subject: [PATCH 13/14] u3: avoid unnecessary refcount churn in melt --- pkg/noun/urth.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 676f63539a..8ef99d457a 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -513,6 +513,10 @@ _traverse(u3_noun som, u3p(u3h_root) set_p) // if (u3_none != (hav = _get(som, set_p))) { + if ( som == hav ) { + return som; + } + u3z(som); return u3k(hav); } From f20cfa3e884c318259e241189fb5ab218c924250 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 11 Apr 2024 18:11:48 -0400 Subject: [PATCH 14/14] u3: avoids unnecessary stores to memory in melt --- pkg/noun/urth.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/pkg/noun/urth.c b/pkg/noun/urth.c index 8ef99d457a..98f7c49f21 100644 --- a/pkg/noun/urth.c +++ b/pkg/noun/urth.c @@ -474,12 +474,11 @@ _cj_warm_tap(u3_noun kev, void* wit) } static inline u3_weak -_get(u3_noun som, u3p(u3h_root) set_p) +_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) - { + if ( u3_none == hav_p ) { return u3_none; } @@ -489,7 +488,7 @@ _get(u3_noun som, u3p(u3h_root) set_p) } static inline void -_put(u3_noun som, u3p(u3h_root) set_p) +_cu_melt_put(u3p(u3h_root) set_p, u3_noun som) { // strip tag bits from [som] to skip refcounts // @@ -497,44 +496,39 @@ _put(u3_noun som, u3p(u3h_root) set_p) u3h_put(set_p, som, hav_p); } -static u3_noun -_traverse(u3_noun som, u3p(u3h_root) set_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; + if ( c3y == u3a_is_cat(som) ) { + return; } // [som] equals [hav], and [hav] is canonical // - if (u3_none != (hav = _get(som, set_p))) - { - if ( som == hav ) { - return som; + if ( u3_none != (hav = _cu_melt_get(set_p, som)) ) { + if ( hav != som ) { + u3z(som); + *mos = u3k(hav); } - - u3z(som); - return u3k(hav); + return; } // traverse subtrees // - if (c3y == u3a_is_cell(som)) - { + if ( c3y == u3a_is_cell(som) ) { u3a_cell *cel_u = u3a_to_ptr(som); - - cel_u->hed = _traverse(cel_u->hed, set_p); - cel_u->tel = _traverse(cel_u->tel, set_p); + _cu_melt_noun(set_p, &cel_u->hed); + _cu_melt_noun(set_p, &cel_u->tel); } // [som] is canonical // - _put(som, set_p); - return som; + _cu_melt_put(set_p, som); } /* u3u_melt(): globally deduplicate memory and pack in-place. @@ -570,8 +564,8 @@ u3u_melt(void) u3p(u3h_root) set_p = u3h_new(); // temp hashtable - cod = _traverse(cod, set_p); // melt the jets - u3A->roc = _traverse(u3A->roc, set_p); // melt the kernel + _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