diff options
| author | polwex <polwex@sortug.com> | 2025-10-06 01:01:41 +0700 |
|---|---|---|
| committer | polwex <polwex@sortug.com> | 2025-10-06 01:01:41 +0700 |
| commit | c4b392a179048f936c062f5ffccc2bc25627e500 (patch) | |
| tree | 09be0904be8ec4d7ea52992ef7580d42ed0c28c1 /vere/pkg/noun/v2 | |
working
Diffstat (limited to 'vere/pkg/noun/v2')
| -rw-r--r-- | vere/pkg/noun/v2/allocate.c | 73 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/allocate.h | 134 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/hashtable.c | 143 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/hashtable.h | 42 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/jets.c | 54 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/jets.h | 35 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/manage.c | 174 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/manage.h | 13 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/nock.c | 92 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/nock.h | 64 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/options.h | 14 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/vortex.c | 25 | ||||
| -rw-r--r-- | vere/pkg/noun/v2/vortex.h | 40 |
13 files changed, 903 insertions, 0 deletions
diff --git a/vere/pkg/noun/v2/allocate.c b/vere/pkg/noun/v2/allocate.c new file mode 100644 index 0000000..0476f8a --- /dev/null +++ b/vere/pkg/noun/v2/allocate.c @@ -0,0 +1,73 @@ +/// @file + +#include "../allocate.h" +#include "v1/allocate.h" +#include "v2/allocate.h" + +#include "v2/hashtable.h" +#include "log.h" +#include "v2/manage.h" +#include "options.h" +#include "retrieve.h" +#include "trace.h" +#include "vortex.h" + +u3a_v2_road* u3a_v2_Road; + +u3_noun +u3a_v2_rewritten_noun(u3_noun som) +{ + if ( c3y == u3a_v2_is_cat(som) ) { + return som; + } + u3_post som_p = u3a_v2_rewritten(u3a_v1_to_off(som)); + + if ( c3y == u3a_v2_is_pug(som) ) { + som_p = u3a_v2_to_pug(som_p); + } + else { + som_p = u3a_v2_to_pom(som_p); + } + + return som_p; +} + +/* u3a_v2_mig_rewrite_compact(): rewrite pointers in ad-hoc persistent road structures. +*/ +void +u3a_v2_mig_rewrite_compact(void) +{ + u3a_v2_rewrite_noun(u3R_v2->ski.gul); + u3a_v2_rewrite_noun(u3R_v2->bug.tax); + u3a_v2_rewrite_noun(u3R_v2->bug.mer); + u3a_v2_rewrite_noun(u3R_v2->pro.don); + u3a_v2_rewrite_noun(u3R_v2->pro.day); + u3a_v2_rewrite_noun(u3R_v2->pro.trace); + u3h_v2_rewrite(u3R_v2->cax.har_p); + + u3R_v2->ski.gul = u3a_v2_rewritten_noun(u3R_v2->ski.gul); + u3R_v2->bug.tax = u3a_v2_rewritten_noun(u3R_v2->bug.tax); + u3R_v2->bug.mer = u3a_v2_rewritten_noun(u3R_v2->bug.mer); + u3R_v2->pro.don = u3a_v2_rewritten_noun(u3R_v2->pro.don); + u3R_v2->pro.day = u3a_v2_rewritten_noun(u3R_v2->pro.day); + u3R_v2->pro.trace = u3a_v2_rewritten_noun(u3R_v2->pro.trace); + u3R_v2->cax.har_p = u3a_v2_rewritten(u3R_v2->cax.har_p); +} + +void +u3a_v2_rewrite_noun(u3_noun som) +{ + if ( c3n == u3a_v2_is_cell(som) ) { + return; + } + + if ( c3n == u3a_v2_rewrite_ptr(u3a_v1_to_ptr((som))) ) return; + + u3a_v2_cell* cel = (u3a_v2_cell*) u3a_v1_to_ptr(som); + + u3a_v2_rewrite_noun(cel->hed); + u3a_v2_rewrite_noun(cel->tel); + + cel->hed = u3a_v2_rewritten_noun(cel->hed); + cel->tel = u3a_v2_rewritten_noun(cel->tel); +} diff --git a/vere/pkg/noun/v2/allocate.h b/vere/pkg/noun/v2/allocate.h new file mode 100644 index 0000000..8832977 --- /dev/null +++ b/vere/pkg/noun/v2/allocate.h @@ -0,0 +1,134 @@ +#ifndef U3_ALLOCATE_V2_H +#define U3_ALLOCATE_V2_H + +#include "../allocate.h" + +#include "v2/manage.h" +#include "options.h" + + /** Aliases. + **/ +# define u3a_v2_botox u3a_botox +# define u3a_v2_box u3a_box +# define u3a_v2_cell u3a_cell +# define u3a_v2_fbox u3a_fbox +# define u3a_v2_fbox_no u3a_fbox_no +# define u3a_v2_free u3a_free +# define u3a_v2_heap u3a_heap +# define u3a_v2_into u3a_into +# define u3a_v2_is_cat u3a_is_cat +# define u3a_v2_is_cell u3a_is_cell +# define u3a_v2_is_north u3a_is_north +# define u3a_v2_is_pom u3a_is_pom +# define u3a_v2_is_pug u3a_is_pug +# define u3a_v2_lose u3a_lose +# define u3a_v2_malloc u3a_malloc +# define u3a_v2_minimum u3a_minimum +# define u3a_v2_outa u3a_outa +# define u3a_v2_pack_seek u3a_pack_seek +# define u3a_v2_rewrite u3a_rewrite +# define u3a_v2_rewrite_ptr u3a_rewrite_ptr +# define u3a_v2_rewritten u3a_rewritten +# define u3a_v2_to_off u3a_to_off +# define u3a_v2_to_ptr u3a_to_ptr +# define u3a_v2_to_wtr u3a_to_wtr +# define u3a_v2_to_pug u3a_to_pug +# define u3a_v2_to_pom u3a_to_pom +# define u3a_v2_wfree u3a_wfree + + /** Data structures. + **/ + /* u3a_v2_road: contiguous allocation and execution context. + */ + typedef struct _u3a_v2_road { + u3p(struct _u3a_v2_road) par_p; // parent road + u3p(struct _u3a_v2_road) kid_p; // child road list + u3p(struct _u3a_v2_road) nex_p; // sibling road + + u3p(c3_w) cap_p; // top of transient region + u3p(c3_w) hat_p; // top of durable region + u3p(c3_w) mat_p; // bottom of transient region + u3p(c3_w) rut_p; // bottom of durable region + u3p(c3_w) ear_p; // original cap if kid is live + + c3_w fut_w[32]; // futureproof buffer + + struct { // escape buffer + union { + jmp_buf buf; + c3_w buf_w[256]; // futureproofing + }; + } esc; + + struct { // miscellaneous config + c3_w fag_w; // flag bits + } how; // + + struct { // allocation pools + u3p(u3a_v2_fbox) fre_p[u3a_v2_fbox_no]; // heap by node size log + u3p(u3a_fbox) cel_p; // custom cell allocator + c3_w fre_w; // number of free words + c3_w max_w; // maximum allocated + } all; + + u3a_jets jed; // jet dashboard + + struct { // bytecode state + u3p(u3h_root) har_p; // formula->post of bytecode + } byc; + + struct { // namespace + u3_noun gul; // (list $+(* (unit (unit)))) now + } ski; + + struct { // trace stack + u3_noun tax; // (list ,*) + u3_noun mer; // emergency buffer to release + } bug; + + struct { // profile stack + c3_d nox_d; // nock steps + c3_d cel_d; // cell allocations + u3_noun don; // (list batt) + u3_noun trace; // (list trace) + u3_noun day; // doss, only in u3H (moveme) + } pro; + + struct { // memoization + u3p(u3h_root) har_p; // (map (pair term noun) noun) + } cax; + } u3a_v2_road; + + /** Globals. + **/ + /// Current road (thread-local). + extern u3a_v2_road* u3a_v2_Road; +# define u3R_v2 u3a_v2_Road + + /** Functions. + **/ + /** Allocation. + **/ + /* Reference and arena control. + */ + /* u3a_v2_mig_rewrite_compact(): rewrite pointers in ad-hoc persistent road structures. + */ + void + u3a_v2_mig_rewrite_compact(void); + + /* u3a_v2_rewrite_noun(): rewrite a noun for compaction. + */ + void + u3a_v2_rewrite_noun(u3_noun som); + + /* u3a_v2_rewritten(): rewrite a pointer for compaction. + */ + u3_post + u3a_v2_rewritten(u3_post som_p); + + /* u3a_v2_rewritten(): rewritten noun pointer for compaction. + */ + u3_noun + u3a_v2_rewritten_noun(u3_noun som); + +#endif /* ifndef U3_ALLOCATE_V2_H */ diff --git a/vere/pkg/noun/v2/hashtable.c b/vere/pkg/noun/v2/hashtable.c new file mode 100644 index 0000000..a4f0291 --- /dev/null +++ b/vere/pkg/noun/v2/hashtable.c @@ -0,0 +1,143 @@ +/// @file + +#include "../hashtable.h" +#include "v1/hashtable.h" +#include "v2/hashtable.h" + +#include "../allocate.h" +#include "v1/allocate.h" +#include "v2/allocate.h" + +/* _ch_v2_popcount(): number of bits set in word. A standard intrinsic. +** NB: copy of _ch_v2_popcount in pkg/noun/hashtable.c +*/ +static c3_w +_ch_v2_popcount(c3_w num_w) +{ + return __builtin_popcount(num_w); +} + +/* _ch_v2_free_buck(): free bucket +** NB: copy of _ch_v2_free_buck in pkg/noun/hashtable.c +*/ +static void +_ch_v2_free_buck(u3h_v2_buck* hab_u) +{ + c3_w i_w; + + for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) { + u3z(u3h_v2_slot_to_noun(hab_u->sot_w[i_w])); + } + u3a_v2_wfree(hab_u); +} + +/* _ch_v2_free_node(): free node. +*/ +static void +_ch_v2_free_node(u3h_v2_node* han_u, c3_w lef_w) +{ + c3_w len_w = _ch_v2_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_v2_slot_is_noun(sot_w)) ) { + u3z(u3h_v2_slot_to_noun(sot_w)); + } + else { + // NB: u3h_v2_slot_to_node() + void* hav_v = u3h_v2_slot_to_node(sot_w); + + if ( 0 == lef_w ) { + _ch_v2_free_buck(hav_v); + } else { + _ch_v2_free_node(hav_v, lef_w); + } + } + } + u3a_v2_wfree(han_u); +} + +/* _ch_v2_rewrite_buck(): rewrite buck for compaction. +*/ +void +_ch_v2_rewrite_buck(u3h_v2_buck* hab_u) +{ + if ( c3n == u3a_v2_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_v2_slot_to_noun(hab_u->sot_w[i_w]); + hab_u->sot_w[i_w] = u3h_v2_noun_to_slot(u3a_v2_rewritten_noun(som)); + u3a_v2_rewrite_noun(som); + } +} + +/* _ch_v2_rewrite_node(): rewrite node for compaction. +*/ +void +_ch_v2_rewrite_node(u3h_v2_node* han_u, c3_w lef_w) +{ + if ( c3n == u3a_v2_rewrite_ptr(han_u) ) return; + + c3_w len_w = _ch_v2_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_v2_slot_is_noun(sot_w)) ) { + u3_noun kev = u3h_v2_slot_to_noun(sot_w); + han_u->sot_w[i_w] = u3h_v2_noun_to_slot(u3a_v2_rewritten_noun(kev)); + + u3a_v2_rewrite_noun(kev); + } + else { + void* hav_v = u3h_v1_slot_to_node(sot_w); + u3h_v2_node* nod_u = u3to(u3h_v2_node, u3a_v2_rewritten(u3of(u3h_v2_node,hav_v))); + + han_u->sot_w[i_w] = u3h_v2_node_to_slot(nod_u); + + if ( 0 == lef_w ) { + _ch_v2_rewrite_buck(hav_v); + } else { + _ch_v2_rewrite_node(hav_v, lef_w); + } + } + } +} + +/* u3h_v2_rewrite(): rewrite pointers during compaction. +*/ +void +u3h_v2_rewrite(u3p(u3h_v2_root) har_p) +{ + u3h_v2_root* har_u = u3to(u3h_v2_root, har_p); + c3_w i_w; + + if ( c3n == u3a_v2_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_v2_slot_is_noun(sot_w)) ) { + u3_noun kev = u3h_v2_slot_to_noun(sot_w); + har_u->sot_w[i_w] = u3h_v2_noun_to_slot(u3a_v2_rewritten_noun(kev)); + + u3a_v2_rewrite_noun(kev); + } + else if ( _(u3h_v2_slot_is_node(sot_w)) ) { + u3h_v2_node* han_u = (u3h_v2_node*) u3h_v1_slot_to_node(sot_w); + u3h_v2_node* nod_u = u3to(u3h_v2_node, u3a_v2_rewritten(u3of(u3h_v2_node,han_u))); + + har_u->sot_w[i_w] = u3h_v2_node_to_slot(nod_u); + + _ch_v2_rewrite_node(han_u, 25); + } + } +} diff --git a/vere/pkg/noun/v2/hashtable.h b/vere/pkg/noun/v2/hashtable.h new file mode 100644 index 0000000..2278640 --- /dev/null +++ b/vere/pkg/noun/v2/hashtable.h @@ -0,0 +1,42 @@ +#ifndef U3_HASHTABLE_V2_H +#define U3_HASHTABLE_V2_H + +#define u3h_v2_buck u3h_buck +#define u3h_v2_free u3h_free +#define u3h_v2_new u3h_new +#define u3h_v2_node u3h_node +#define u3h_v2_noun_to_slot u3h_noun_to_slot +#define u3h_v2_root u3h_root +#define u3h_v2_slot_is_node u3h_slot_is_node +#define u3h_v2_slot_is_noun u3h_slot_is_noun +#define u3h_v2_slot_to_noun u3h_slot_to_noun +#define u3h_v2_walk u3h_walk +#define u3h_v2_walk_with u3h_walk_with + +#include "../hashtable.h" + +#include "c3/c3.h" +#include "types.h" + + /** Data structures. + **/ + + /** HAMT macros. + *** + *** Coordinate with u3_noun definition! + **/ + /* u3h_v2_slot_to_node(): slot to node pointer + ** u3h_v2_node_to_slot(): node pointer to slot + */ +# define u3h_v2_slot_to_node(sot) (u3a_v2_into(((sot) & 0x3fffffff) << u3a_vits)) +# define u3h_v2_node_to_slot(ptr) ((u3a_v2_outa((ptr)) >> u3a_vits) | 0x40000000) + + /** Functions. + *** + **/ + /* u3h_v2_rewrite(): rewrite hashtable for compaction. + */ + void + u3h_v2_rewrite(u3p(u3h_root) har_p); + +#endif /* U3_HASHTABLE_V2_H */ diff --git a/vere/pkg/noun/v2/jets.c b/vere/pkg/noun/v2/jets.c new file mode 100644 index 0000000..4d5fa0f --- /dev/null +++ b/vere/pkg/noun/v2/jets.c @@ -0,0 +1,54 @@ +/// @file + +#include "../vortex.h" + +#include "../jets.h" +#include "v2/jets.h" + +#include "v2/allocate.h" +#include "v2/hashtable.h" +#include "v2/vortex.h" + +#include "v3/hashtable.h" +#include "v3/jets.h" + +/* u3j_v2_reclaim(): clear ad-hoc persistent caches to reclaim memory. +*/ +void +u3j_v2_reclaim(void) +{ + // set globals (required for aliased functions) + u3H = (u3v_home*) u3H_v2; + u3R = (u3a_road*) u3R_v2; + + // clear the jet hank cache + // + u3h_v3_walk(u3R->jed.han_p, u3j_v3_free_hank); + u3h_v3_free(u3R->jed.han_p); + u3R->jed.han_p = u3h_v3_new(); +} + +/* u3j_v2_mig_rewrite_compact(): rewrite jet state for compaction. + * + * NB: u3R_v2->jed.han_p *must* be cleared (currently via u3j_v2_reclaim above) + * since it contains hanks which are not nouns but have loom pointers. + * Alternately, rewrite the entries with u3h_v2_walk, using u3j_v2_mark as a + * template for how to walk. There's an untested attempt at this in git + * history at e8a307a. +*/ +void +u3j_v2_mig_rewrite_compact(void) +{ + u3h_v2_rewrite(u3R_v2->jed.war_p); + u3h_v2_rewrite(u3R_v2->jed.cod_p); + u3h_v2_rewrite(u3R_v2->jed.han_p); + u3h_v2_rewrite(u3R_v2->jed.bas_p); + + u3h_v2_rewrite(u3R_v2->jed.hot_p); + u3R_v2->jed.hot_p = u3a_v2_rewritten(u3R_v2->jed.hot_p); + + u3R_v2->jed.war_p = u3a_v2_rewritten(u3R_v2->jed.war_p); + u3R_v2->jed.cod_p = u3a_v2_rewritten(u3R_v2->jed.cod_p); + u3R_v2->jed.han_p = u3a_v2_rewritten(u3R_v2->jed.han_p); + u3R_v2->jed.bas_p = u3a_v2_rewritten(u3R_v2->jed.bas_p); +} diff --git a/vere/pkg/noun/v2/jets.h b/vere/pkg/noun/v2/jets.h new file mode 100644 index 0000000..33ac088 --- /dev/null +++ b/vere/pkg/noun/v2/jets.h @@ -0,0 +1,35 @@ +/// @file + +#ifndef U3_JETS_V2_H +#define U3_JETS_V2_H + +#include "../allocate.h" +#include "../jets.h" + + + /** Aliases. + **/ +# define u3j_v2_core u3j_core +# define u3j_v2_fink u3j_fink +# define u3j_v2_fist u3j_fist +# define u3j_v2_hank u3j_hank +# define u3j_v2_free_hank u3j_free_hank +# define u3j_v2_harm u3j_harm +# define u3j_v2_rite u3j_rite +# define u3j_v2_site u3j_site +# define u3j_v2_rite_lose u3j_rite_lose +# define u3j_v2_site_lose u3j_site_lose + + /** Functions. + **/ + /* u3j_v2_reclaim(): clear ad-hoc persistent caches to reclaim memory. + */ + void + u3j_v2_reclaim(void); + + /* u3j_v2_mig_rewrite_compact(): rewrite jet state for compaction. + */ + void + u3j_v2_mig_rewrite_compact(void); + +#endif /* ifndef U3_JETS_V2_H */ diff --git a/vere/pkg/noun/v2/manage.c b/vere/pkg/noun/v2/manage.c new file mode 100644 index 0000000..16981d2 --- /dev/null +++ b/vere/pkg/noun/v2/manage.c @@ -0,0 +1,174 @@ +/// @file + +#include "v2/manage.h" + +#include "v1/allocate.h" +#include "v2/allocate.h" +#include "v2/hashtable.h" +#include "v2/jets.h" +#include "v2/nock.h" +#include "v2/options.h" +#include "../vortex.h" +#include "v1/vortex.h" +#include "v2/vortex.h" + +/* _cm_pack_rewrite(): trace through arena, rewriting pointers. +*/ +static void +_cm_pack_rewrite(void) +{ + u3v_v2_mig_rewrite_compact(); + u3j_v2_mig_rewrite_compact(); + u3n_v2_mig_rewrite_compact(); + u3a_v2_mig_rewrite_compact(); +} + +static void +_migrate_reclaim(void) +{ + // XX update this and similar printfs + fprintf(stderr, "loom: migration reclaim\r\n"); + u3m_v1_reclaim(); +} + +static void +_migrate_seek(const u3a_v2_road *rod_u) +{ + /* + very much like u3a_v2_pack_seek with the following changes: + - there is no need to account for free space as |pack is performed before + the migration + - odd sized boxes will be padded by one word to achieve an even size + - rut will be moved from one word ahead of u3_Loom to two words ahead + */ + c3_w * box_w = u3a_v2_into(rod_u->rut_p); + c3_w * end_w = u3a_v2_into(rod_u->hat_p); + u3_post new_p = (rod_u->rut_p + 1 + c3_wiseof(u3a_v2_box)); + u3a_v2_box * box_u = (void *)box_w; + + fprintf(stderr, "loom: migration seek\r\n"); + + for (; box_w < end_w + ; box_w += box_u->siz_w + , box_u = (void*)box_w) + { + if (!box_u->use_w) + continue; + u3_assert(box_u->siz_w); + u3_assert(box_u->use_w); + box_w[box_u->siz_w - 1] = new_p; + new_p = c3_align(new_p + box_u->siz_w, 2, C3_ALGHI); + } +} + +static void +_migrate_rewrite(void) +{ + fprintf(stderr, "loom: migration rewrite\r\n"); + + _cm_pack_rewrite(); +} + +static void +_migrate_move(u3a_v2_road *rod_u) +{ + fprintf(stderr, "loom: migration move\r\n"); + + c3_z hiz_z = u3a_v2_heap(rod_u) * sizeof(c3_w); + + /* calculate required shift distance to prevent write head overlapping read head */ + c3_w off_w = 1; /* at least 1 word because u3R_v1->rut_p migrates from 1 to 2 */ + for (u3a_v2_box *box_u = u3a_v2_into(rod_u->rut_p) + ; (void *)box_u < u3a_v2_into(rod_u->hat_p) + ; box_u = (void *)((c3_w *)box_u + box_u->siz_w)) + off_w += box_u->siz_w & 1; /* odd-sized boxes are padded by one word */ + + /* shift */ + memmove(u3a_v2_into(u3H_v2->rod_u.rut_p + off_w), + u3a_v2_into(u3H_v2->rod_u.rut_p), + hiz_z); + /* manually zero the former rut */ + *(c3_w *)u3a_v2_into(rod_u->rut_p) = 0; + + /* relocate boxes to DWORD-aligned addresses stored in trailing size word */ + c3_w *box_w = u3a_v2_into(rod_u->rut_p + off_w); + c3_w *end_w = u3a_v2_into(rod_u->hat_p + off_w); + u3a_v2_box *old_u = (void *)box_w; + c3_w siz_w = old_u->siz_w; + u3p(c3_w) new_p = rod_u->rut_p + 1 + c3_wiseof(u3a_v2_box); + c3_w *new_w; + + for (; box_w < end_w + ; box_w += siz_w + , old_u = (void *)box_w + , siz_w = old_u->siz_w) { + old_u->use_w &= 0x7fffffff; + + if (!old_u->use_w) + continue; + + new_w = (void *)u3a_v2_botox(u3a_v2_into(new_p)); + u3_assert(box_w[siz_w - 1] == new_p); + u3_assert(new_w <= box_w); + + c3_w i_w; + for (i_w = 0; i_w < siz_w - 1; i_w++) + new_w[i_w] = box_w[i_w]; + + if (siz_w & 1) { + new_w[i_w++] = 0; /* pad odd sized boxes */ + new_w[i_w++] = siz_w + 1; /* restore trailing size word */ + new_w[0] = siz_w + 1; /* and the leading size word */ + } + else { + new_w[i_w++] = siz_w; + } + + new_p += i_w; + } + + /* restore proper heap state */ + rod_u->rut_p = 2; + rod_u->hat_p = new_p - c3_wiseof(u3a_v2_box); + + /* like |pack, clear the free lists and cell allocator */ + for (c3_w i_w = 0; i_w < u3a_v2_fbox_no; i_w++) + u3R_v1->all.fre_p[i_w] = 0; + + u3R_v1->all.fre_w = 0; + u3R_v1->all.cel_p = 0; +} + + +/* u3m_v2_migrate: perform loom migration if necessary. +*/ +void +u3m_v2_migrate(void) +{ + c3_w len_w = u3C_v2.wor_i - 1; + c3_w ver_w = *(u3_Loom + len_w); + + u3_assert( U3V_VER1 == ver_w ); + + c3_w* mem_w = u3_Loom + 1; + c3_w siz_w = c3_wiseof(u3v_v1_home); + c3_w* mat_w = (mem_w + len_w) - siz_w; + + u3H_v1 = (void *)mat_w; + u3R_v1 = &u3H_v1->rod_u; + + u3R_v1->cap_p = u3R_v1->mat_p = u3a_v1_outa(u3H_v1); + + fprintf(stderr, "loom: pointer compression migration running...\r\n"); + + /* perform the migration in a pattern similar to |pack */ + _migrate_reclaim(); + _migrate_seek(&u3H_v1->rod_u); + _migrate_rewrite(); + _migrate_move(&u3H_v1->rod_u); + + /* finally update the version and commit to disk */ + u3H_v1->ver_w = U3V_VER2; + + fprintf(stderr, "loom: pointer compression migration done\r\n"); +} diff --git a/vere/pkg/noun/v2/manage.h b/vere/pkg/noun/v2/manage.h new file mode 100644 index 0000000..623453e --- /dev/null +++ b/vere/pkg/noun/v2/manage.h @@ -0,0 +1,13 @@ +/// @file + +#ifndef U3_MANAGE_V2_H +#define U3_MANAGE_V2_H + + /** System management. + **/ + /* u3m_v2_migrate: perform pointer compression loom migration if necessary. + */ + void + u3m_v2_migrate(void); + +#endif /* ifndef U3_MANAGE_V2_H */ diff --git a/vere/pkg/noun/v2/nock.c b/vere/pkg/noun/v2/nock.c new file mode 100644 index 0000000..e42221a --- /dev/null +++ b/vere/pkg/noun/v2/nock.c @@ -0,0 +1,92 @@ +/// @file + +#include "v2/nock.h" + +#include "../vortex.h" + +#include "v2/allocate.h" +#include "v2/hashtable.h" +#include "v2/vortex.h" + +#include "v3/hashtable.h" + +/* u3n_v2_reclaim(): clear ad-hoc persistent caches to reclaim memory. +*/ +void +u3n_v2_reclaim(void) +{ + // set globals (required for aliased functions) + u3H = (u3v_home*) u3H_v2; + u3R = (u3a_road*) u3R_v2; + + // clear the bytecode cache + u3n_v2_free(); + u3R->byc.har_p = u3h_v2_new(); +} + +/* _cn_v2_prog_free(): free memory retained by program pog_u +*/ +static void +_cn_v2_prog_free(u3n_v2_prog* pog_u) +{ + // fix up pointers for loom portability + pog_u->byc_u.ops_y = (c3_y*) ((void*) pog_u) + sizeof(u3n_v2_prog); + pog_u->lit_u.non = (u3_noun*) (pog_u->byc_u.ops_y + pog_u->byc_u.len_w); + pog_u->mem_u.sot_u = (u3n_v2_memo*) (pog_u->lit_u.non + pog_u->lit_u.len_w); + pog_u->cal_u.sit_u = (u3j_v2_site*) (pog_u->mem_u.sot_u + pog_u->mem_u.len_w); + pog_u->reg_u.rit_u = (u3j_v2_rite*) (pog_u->cal_u.sit_u + pog_u->cal_u.len_w); + + c3_w dex_w; + for (dex_w = 0; dex_w < pog_u->lit_u.len_w; ++dex_w) { + u3a_v2_lose(pog_u->lit_u.non[dex_w]); + } + for (dex_w = 0; dex_w < pog_u->mem_u.len_w; ++dex_w) { + u3a_v2_lose(pog_u->mem_u.sot_u[dex_w].key); + } + for (dex_w = 0; dex_w < pog_u->cal_u.len_w; ++dex_w) { + u3j_v2_site_lose(&(pog_u->cal_u.sit_u[dex_w])); + } + for (dex_w = 0; dex_w < pog_u->reg_u.len_w; ++dex_w) { + u3j_v2_rite_lose(&(pog_u->reg_u.rit_u[dex_w])); + } + u3a_v2_free(pog_u); +} + +/* _n_v2_feb(): u3h_v2_walk helper for u3n_v2_free + */ +static void +_n_v2_feb(u3_noun kev) +{ + u3a_v2_cell *cel_u = (u3a_v2_cell*) u3a_v2_to_ptr(kev); + _cn_v2_prog_free(u3to(u3n_v2_prog, cel_u->tel)); +} + +/* u3n_v2_free(): free bytecode cache + */ +void +u3n_v2_free(void) +{ + u3p(u3h_v2_root) har_p = u3R_v2->byc.har_p; + u3h_v2_walk(har_p, _n_v2_feb); + u3h_v2_free(har_p); +} + +/* u3n_v2_mig_rewrite_compact(): rewrite the bytecode cache for compaction. + * + * NB: u3R_v2->byc.har_p *must* be cleared (currently via u3n_v2_reclaim above), + * since it contains things that look like nouns but aren't. + * Specifically, it contains "cells" where the tail is a + * pointer to a u3a_v2_malloc'ed block that contains loom pointers. + * + * You should be able to walk this with u3h_v2_walk and rewrite the + * pointers, but you need to be careful to handle that u3a_v2_malloc + * pointers can't be turned into a box by stepping back two words. You + * must step back one word to get the padding, step then step back that + * many more words (plus one?). + */ +void +u3n_v2_mig_rewrite_compact(void) +{ + u3h_v2_rewrite(u3R_v2->byc.har_p); + u3R_v2->byc.har_p = u3a_v2_rewritten(u3R_v2->byc.har_p); +} diff --git a/vere/pkg/noun/v2/nock.h b/vere/pkg/noun/v2/nock.h new file mode 100644 index 0000000..efb9121 --- /dev/null +++ b/vere/pkg/noun/v2/nock.h @@ -0,0 +1,64 @@ +/// @file + +#ifndef U3_NOCK_V2_H +#define U3_NOCK_V2_H + +#include "v3/nock.h" + +#include "v2/jets.h" + +#include "types.h" + + /** Data structures. + **/ + /* u3n_memo: %memo hint space + */ + typedef struct { + c3_l sip_l; + u3_noun key; + } u3n_v2_memo; + + /* u3n_v2_prog: program compiled from nock + */ + typedef struct _u3n_v2_prog { + struct { + c3_o own_o; // program owns ops_y? + c3_w len_w; // length of bytecode (bytes) + c3_y* ops_y; // actual array of bytes + } byc_u; // bytecode + struct { + c3_w len_w; // number of literals + u3_noun* non; // array of literals + } lit_u; // literals + struct { + c3_w len_w; // number of memo slots + u3n_v2_memo* sot_u; // array of memo slots + } mem_u; // memo slot data + struct { + c3_w len_w; // number of calls sites + u3j_v2_site* sit_u; // array of sites + } cal_u; // call site data + struct { + c3_w len_w; // number of registration sites + u3j_v2_rite* rit_u; // array of sites + } reg_u; // registration site data + } u3n_v2_prog; + + /** Functions. + **/ + /* u3n_v2_reclaim(): clear ad-hoc persistent caches to reclaim memory. + */ + void + u3n_v2_reclaim(void); + + /* u3n_v2_free(): free bytecode cache. + */ + void + u3n_v2_free(void); + + /* u3n_v2_mig_rewrite_compact(): rewrite bytecode cache for compaction. + */ + void + u3n_v2_mig_rewrite_compact(void); + +#endif /* ifndef U3_NOCK_V2_H */ diff --git a/vere/pkg/noun/v2/options.h b/vere/pkg/noun/v2/options.h new file mode 100644 index 0000000..079f766 --- /dev/null +++ b/vere/pkg/noun/v2/options.h @@ -0,0 +1,14 @@ +/// @file + +#ifndef U3_OPTIONS_V2_H +#define U3_OPTIONS_V2_H + +#include "../options.h" + + /** Globals. + **/ + /* u3_Config / u3C: global memory control. + */ +# define u3C_v2 u3C + +#endif /* ifndef U3_OPTIONS_H */ diff --git a/vere/pkg/noun/v2/vortex.c b/vere/pkg/noun/v2/vortex.c new file mode 100644 index 0000000..9b21d5c --- /dev/null +++ b/vere/pkg/noun/v2/vortex.c @@ -0,0 +1,25 @@ +/// @file + +#include "../vortex.h" +#include "v2/vortex.h" + +#include "v2/allocate.h" + +u3v_v2_home* u3v_v2_Home; + +/* u3v_v2_mig_rewrite_compact(): rewrite arvo kernel for compaction. +*/ +void +u3v_v2_mig_rewrite_compact(void) +{ + u3v_v2_arvo* arv_u = &(u3H_v2->arv_u); + + u3a_v2_rewrite_noun(arv_u->roc); + u3a_v2_rewrite_noun(arv_u->now); + u3a_v2_rewrite_noun(arv_u->yot); + + arv_u->roc = u3a_v2_rewritten_noun(arv_u->roc); + arv_u->now = u3a_v2_rewritten_noun(arv_u->now); + arv_u->yot = u3a_v2_rewritten_noun(arv_u->yot); +} + diff --git a/vere/pkg/noun/v2/vortex.h b/vere/pkg/noun/v2/vortex.h new file mode 100644 index 0000000..9e04832 --- /dev/null +++ b/vere/pkg/noun/v2/vortex.h @@ -0,0 +1,40 @@ +/// @file + +#ifndef U3_VORTEX_V2_H +#define U3_VORTEX_V2_H + +#include "../vortex.h" + +#include "v2/allocate.h" +#include "../version.h" + + /** Aliases. + **/ +# define u3v_v2_arvo u3v_arvo + + /** Data structures. + **/ + /* u3v_v2_home: all internal (within image) state. + ** NB: version must be last for discriminability in north road + */ + typedef struct _u3v_v2_home { + u3a_v2_road rod_u; // storage state + u3v_v2_arvo arv_u; // arvo state + u3v_version ver_w; // version number + } u3v_v2_home; + + /** Globals. + **/ + /// Arvo internal state. + extern u3v_v2_home* u3v_v2_Home; +# define u3H_v2 u3v_v2_Home +# define u3A_v2 (&(u3v_v2_Home->arv_u)) + + /** Functions. + **/ + /* u3v_v2_mig_rewrite_compact(): rewrite arvo kernel for compaction. + */ + void + u3v_v2_mig_rewrite_compact(void); + +#endif /* ifndef U3_VORTEX_V2_H */ |
