avoid allocating an atom for _cj_bash

This commit is contained in:
Paul Driver 2018-06-14 11:36:56 -07:00
parent dca55cf921
commit 07e524532f
2 changed files with 112 additions and 71 deletions

View File

@ -40,7 +40,7 @@ _jam_buf_grow(_jam_buf* buf_u, c3_w mor_w)
++new_w;
}
buf_u->wor_w = u3a_realloc(buf_u->wor_w, new_w * sizeof(c3_w));
buf_u->wor_w = u3a_wealloc(buf_u->wor_w, new_w);
memset(buf_u->wor_w + old_w, 0, (new_w - old_w) * sizeof(c3_w));
}
}
@ -70,91 +70,99 @@ _jam_buf_atom(_jam_buf* buf_u, u3_noun a)
}
}
static u3_noun
_jam_buf_top(u3_noun a)
{
u3p(u3h_root) har_p = u3h_new();
c3_o nor_o = u3a_is_north(u3R);
c3_y wis_y = c3_wiseof(u3_noun);
c3_ys mov = ( c3y == nor_o ? -wis_y : wis_y );
c3_ys off = ( c3y == nor_o ? 0 : -wis_y );
u3_noun* top, *don = u3to(u3_noun, u3R->cap_p + off);
_jam_buf buf_u;
u3_weak c;
c3_o cel_o;
c3_w* sal_w, len_w;
/* functions
*/
/* u3qe_jam_buf(): jam without atom allocation. returns
* atom-suitable words, and *bit_w will
* have the length (in bits). return should
* be freed with u3a_wfree().
*/
c3_w*
u3qe_jam_buf(u3_noun a, c3_w* bit_w)
{
u3p(u3h_root) har_p = u3h_new();
c3_o nor_o = u3a_is_north(u3R);
c3_y wis_y = c3_wiseof(u3_noun);
c3_ys mov = ( c3y == nor_o ? -wis_y : wis_y );
c3_ys off = ( c3y == nor_o ? 0 : -wis_y );
u3_noun* top, *don = u3to(u3_noun, u3R->cap_p + off);
u3_weak c;
c3_o cel_o;
c3_w len_w;
_jam_buf buf_u;
buf_u.a_w = 144; // fib(12) is small enough to be reasonably fast to allocate.
buf_u.b_w = 89; // fib(11) is needed to get fib(13).
len_w = buf_u.a_w >> 5;
if ( (len_w << 5) != buf_u.a_w ) {
++len_w;
}
buf_u.wor_w = u3a_calloc(len_w, sizeof(c3_w));
buf_u.bit_w = 0;
buf_u.a_w = 144; // fib(12) is small enough to be reasonably fast to allocate.
buf_u.b_w = 89; // fib(11) is needed to get fib(13).
len_w = buf_u.a_w >> 5;
if ( (len_w << 5) != buf_u.a_w ) {
++len_w;
}
buf_u.wor_w = u3a_walloc(len_w);
buf_u.bit_w = 0;
memset(buf_u.wor_w, 0, len_w * sizeof(c3_w));
u3R->cap_p += mov;
top = u3to(u3_noun, u3R->cap_p + off);
*top = a;
u3R->cap_p += mov;
top = u3to(u3_noun, u3R->cap_p + off);
*top = a;
while ( top != don ) {
a = *top;
cel_o = u3du(a);
c = u3h_git(har_p, a);
if ( u3_none != c ) {
if ( c3y == cel_o ) {
_jam_buf_chop(&buf_u, 2, 3);
_jam_buf_atom(&buf_u, c);
}
else {
if ( u3r_met(0, a) <= u3r_met(0, c) ) {
_jam_buf_chop(&buf_u, 1, 0);
_jam_buf_atom(&buf_u, a);
while ( top != don ) {
a = *top;
cel_o = u3du(a);
c = u3h_git(har_p, a);
if ( u3_none != c ) {
if ( c3y == cel_o ) {
_jam_buf_chop(&buf_u, 2, 3);
_jam_buf_atom(&buf_u, c);
}
else {
_jam_buf_chop(&buf_u, 2, 3);
_jam_buf_atom(&buf_u, c);
if ( u3r_met(0, a) <= u3r_met(0, c) ) {
_jam_buf_chop(&buf_u, 1, 0);
_jam_buf_atom(&buf_u, a);
}
else {
_jam_buf_chop(&buf_u, 2, 3);
_jam_buf_atom(&buf_u, c);
}
}
}
u3R->cap_p -= mov;
top = u3to(u3_noun, u3R->cap_p + off);
}
else {
u3h_put(har_p, a, buf_u.bit_w);
if ( c3n == cel_o ) {
_jam_buf_chop(&buf_u, 1, 0);
_jam_buf_atom(&buf_u, a);
u3R->cap_p -= mov;
top = u3to(u3_noun, u3R->cap_p + off);
}
else {
_jam_buf_chop(&buf_u, 2, 1);
*top = u3t(a);
u3h_put(har_p, a, buf_u.bit_w);
if ( c3n == cel_o ) {
_jam_buf_chop(&buf_u, 1, 0);
_jam_buf_atom(&buf_u, a);
u3R->cap_p -= mov;
top = u3to(u3_noun, u3R->cap_p + off);
}
else {
_jam_buf_chop(&buf_u, 2, 1);
*top = u3t(a);
u3R->cap_p += mov;
top = u3to(u3_noun, u3R->cap_p + off);
*top = u3h(a);
u3R->cap_p += mov;
top = u3to(u3_noun, u3R->cap_p + off);
*top = u3h(a);
}
}
}
}
len_w = buf_u.bit_w >> 5;
if ( (len_w << 5) != buf_u.bit_w ) {
++len_w;
*bit_w = buf_u.bit_w;
u3h_free(har_p);
return buf_u.wor_w;
}
sal_w = u3a_slab(len_w);
memcpy(sal_w, buf_u.wor_w, len_w*sizeof(c3_w));
u3a_free(buf_u.wor_w);
u3h_free(har_p);
return u3a_moot(sal_w);
}
/* functions
*/
u3_noun
u3qe_jam(u3_atom a)
{
return _jam_buf_top(a);
c3_w bit_w, *sal_w;
c3_w* wor_w = u3qe_jam_buf(a, &bit_w);
c3_w len_w = bit_w >> 5;
if ( (len_w << 5) != bit_w ) {
++len_w;
}
sal_w = u3a_slab(len_w);
memcpy(sal_w, wor_w, len_w*sizeof(c3_w));
u3a_wfree(wor_w);
return u3a_moot(sal_w);
}
u3_noun
u3we_jam(u3_noun cor)

View File

@ -3,6 +3,12 @@
*/
#include "all.h"
#if defined(U3_OS_osx)
#include <CommonCrypto/CommonDigest.h>
#else
#include <openssl/sha.h>
#endif
/** Data structures.
**/
@ -90,6 +96,9 @@ _cj_hash(c3_c* has_c)
return pro;
}
// in the jam jet file
c3_w* u3qe_jam_buf(u3_noun, c3_w* bit_w);
/* _cj_bash(): battery hash. RETAIN.
*/
static u3_noun
@ -108,10 +117,34 @@ _cj_bash(u3_noun bat)
rod_u = u3to(u3_road, rod_u->par_p);
}
else {
u3_noun jan = u3qe_jam(bat);
pro = u3qe_shax(jan);
c3_w bit_w, met_w;
c3_w* wor_w;
c3_y* fat_y;
c3_y dig_y[32];
wor_w = u3qe_jam_buf(bat, &bit_w);
met_w = bit_w >> 3;
if ( bit_w != met_w << 3 ) {
++met_w;
}
// assume little-endian
fat_y = (c3_y*) wor_w;
#if defined(U3_OS_osx)
CC_SHA256_CTX ctx_h;
CC_SHA256_Init(&ctx_h);
CC_SHA256_Update(&ctx_h, fat_y, met_w);
CC_SHA256_Final(dig_y, &ctx_h);
#else
SHA256_CTX ctx_h;
SHA256_Init(&ctx_h);
SHA256_Update(&ctx_h, fat_y, met_w);
SHA256_Final(dig_y, &ctx_h);
#endif
pro = u3i_bytes(32, dig_y);
u3h_put(u3R->jed.bas_p, bat, u3k(pro));
u3z(jan);
u3a_wfree(wor_w);
break;
}
}