Skip to content

Commit

Permalink
jets: let +bex create atoms 256MB or more (#464)
Browse files Browse the repository at this point in the history
In testing, I commonly use `=a (bex (bex 29))` as a way to use 128MB of
memory. It's been annoying that you can't do 256MB or more in this way,
because the +bex jet didn't support it. This PR raises that limit to
strictly less than 2GB. This also reduces the ephemeral memory usage of
the `+bex` jet on large numbers by half.

This was limited to strictly less than 256MB because it used a gmp
method to perform the binary exponent. I briefly looked at whether gmp
would handle double-length words for the exponent, but decided it was
simpler and more efficient anyway to write this jet directly, ie
allocate `a+1` bits and set the `a`th bit. This saves one copy of the
entire result, and allows it to function up to 2GB minus one.

This function would work correctly above this limit, but there are other
parts of the system that seem to implicitly assume that atoms cannot be
2GB or larger. The first one I ran into was `mug`, but there may be
others; after all, for a long time it was safe to assume nothing could
be larger than 2GB because that was the loom size.
  • Loading branch information
belisarius222 authored Jun 21, 2023
2 parents 132dca1 + 25505af commit f54d6de
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions pkg/noun/jets/c/bex.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,34 @@
u3_noun
u3qc_bex(u3_atom a)
{
mpz_t a_mp;
c3_d a_d;
u3i_slab sab_u;

if ( !_(u3a_is_cat(a)) ) {
return u3m_bail(c3__fail);
if ( a < 31 ) {
return 1 << a;
}

if ( c3y == u3a_is_cat(a) ) {
a_d = a;
}
else {
mpz_init_set_ui(a_mp, 1);
mpz_mul_2exp(a_mp, a_mp, a);
if ( c3n == u3r_safe_chub(a, &a_d) ) {
return u3m_bail(c3__fail);
}

return u3i_mp(a_mp);
// We don't currently support atoms 2GB or larger (fails while
// mugging). The extra term of 16 is experimentally determined.
if ( a_d >= ((c3_d)1 << (c3_d)34) - 16 ) {
u3l_log("bex: overflow");
return u3m_bail(c3__fail);
}
}

u3i_slab_init(&sab_u, 0, a_d + 1);

sab_u.buf_w[a_d >> 5] = 1 << (a_d & 31);

return u3i_slab_moot(&sab_u);
}

u3_noun
Expand Down

0 comments on commit f54d6de

Please sign in to comment.